Skip to content

Commit

Permalink
make maxclockclass and maxclockaccuracy configurable (#327)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: #327

Make abulimov happy and cut-off param configurable

Reviewed By: pmazzini

Differential Revision: D53311942

fbshipit-source-id: 8581d346e35348409a47e55f7c352b7e4676b82f
  • Loading branch information
leoleovich authored and facebook-github-bot committed Feb 1, 2024
1 parent 1996517 commit 5968f63
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 9 deletions.
6 changes: 3 additions & 3 deletions ptp/sptp/client/bmca.go
Expand Up @@ -22,7 +22,7 @@ import (
"github.com/facebook/time/ptp/sptp/bmc"
)

func bmca(msgs []*ptp.Announce, prios map[ptp.ClockIdentity]int) *ptp.Announce {
func bmca(msgs []*ptp.Announce, prios map[ptp.ClockIdentity]int, cfg *Config) *ptp.Announce {
if len(msgs) == 0 {
return nil
}
Expand All @@ -36,8 +36,8 @@ func bmca(msgs []*ptp.Announce, prios map[ptp.ClockIdentity]int) *ptp.Announce {
best = b
}
}
// Never select GM in worse than holdover status or with clock quality worse than 10 microseconds
if best.AnnounceBody.GrandmasterClockQuality.ClockClass > ptp.ClockClass7 || best.AnnounceBody.GrandmasterClockQuality.ClockAccuracy > ptp.ClockAccuracyMicrosecond10 {
// Never select GM if worse (greater) than MaxClockClass or with clock accuracy worse than MaxClockAccuracy
if best.AnnounceBody.GrandmasterClockQuality.ClockClass > cfg.MaxClockClass || best.AnnounceBody.GrandmasterClockQuality.ClockAccuracy > cfg.MaxClockAccuracy {
return nil
}
return best
Expand Down
8 changes: 4 additions & 4 deletions ptp/sptp/client/bmca_test.go
Expand Up @@ -25,27 +25,27 @@ import (
func TestBmcaProperlyUsesClockQuality(t *testing.T) {
best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass7}}}
worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass13}}}
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1})
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1}, DefaultConfig())
require.Equal(t, best, *selected)
}

func TestBmcaProperlyUsesLocalPriority(t *testing.T) {
best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterPriority1: 1}} // GrandMasterIdentity is ignored with TelcoDscmp
worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterPriority1: 2}} // GrandMasterIdentity is ignored with TelcoDscmp
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 1, 2: 2})
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 1, 2: 2}, DefaultConfig())
require.Equal(t, best, *selected)
}

func TestBmcaNoMasterForCalibrating(t *testing.T) {
best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass13}}}
worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterClockQuality: ptp.ClockQuality{ClockClass: ptp.ClockClass52}}}
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1})
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1}, DefaultConfig())
require.Empty(t, selected)
}

func TestBmcaNoMasterForLowAccuracy(t *testing.T) {
best := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 1, GrandmasterClockQuality: ptp.ClockQuality{ClockAccuracy: ptp.ClockAccuracyMicrosecond100}}}
worse := ptp.Announce{AnnounceBody: ptp.AnnounceBody{GrandmasterIdentity: 2, GrandmasterClockQuality: ptp.ClockQuality{ClockAccuracy: ptp.ClockAccuracySecond10}}}
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1})
selected := bmca([]*ptp.Announce{&best, &worse}, map[ptp.ClockIdentity]int{1: 2, 2: 1}, DefaultConfig())
require.Empty(t, selected)
}
13 changes: 12 additions & 1 deletion ptp/sptp/client/config.go
Expand Up @@ -22,6 +22,7 @@ import (
"os"
"time"

ptp "github.com/facebook/time/ptp/protocol"
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -68,7 +69,7 @@ func (c *MeasurementConfig) Validate() error {
return nil
}

// Config specifies PTPNG run options
// Config specifies SPTP run options
type Config struct {
Iface string
Timestamping string
Expand All @@ -78,6 +79,8 @@ type Config struct {
DSCP int
FirstStepThreshold time.Duration
Servers map[string]int
MaxClockClass ptp.ClockClass
MaxClockAccuracy ptp.ClockAccuracy
Measurement MeasurementConfig
MetricsAggregationWindow time.Duration
AttemptsTXTS int
Expand All @@ -93,6 +96,8 @@ func DefaultConfig() *Config {
return &Config{
Interval: time.Second,
ExchangeTimeout: 100 * time.Millisecond,
MaxClockClass: ptp.ClockClass7,
MaxClockAccuracy: ptp.ClockAccuracyMicrosecond10,
MetricsAggregationWindow: time.Duration(60) * time.Second,
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Expand All @@ -111,6 +116,12 @@ func (c *Config) Validate() error {
if c.TimeoutTXTS <= 0 {
return fmt.Errorf("timeouttxts must be greater than zero")
}
if c.MaxClockClass < ptp.ClockClass6 || c.MaxClockClass > ptp.ClockClass58 {
return fmt.Errorf("invalid range of allowed clock class")
}
if c.MaxClockAccuracy < ptp.ClockAccuracyNanosecond25 || c.MaxClockAccuracy > ptp.ClockAccuracySecondGreater10 {
return fmt.Errorf("invalid range of allowed clock accuracy")
}
if c.MetricsAggregationWindow <= 0 {
return fmt.Errorf("metricsaggregationwindow must be greater than zero")
}
Expand Down
84 changes: 84 additions & 0 deletions ptp/sptp/client/config_test.go
Expand Up @@ -42,6 +42,8 @@ func TestReadConfigDefaults(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
}
require.Equal(t, want, cfg)
}
Expand Down Expand Up @@ -92,6 +94,8 @@ measurement:
Backoff: BackoffConfig{},
SequenceIDMaskBits: 2,
SequenceIDMaskValue: 1,
MaxClockClass: 7,
MaxClockAccuracy: 37,
}
require.Equal(t, want, cfg)
mask, value := cfg.GenerateMaskAndValue()
Expand Down Expand Up @@ -236,6 +240,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -252,6 +258,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -268,6 +276,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -286,6 +296,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -304,6 +316,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -322,6 +336,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -338,6 +354,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: -10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -354,6 +372,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(-50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -370,6 +390,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -386,6 +408,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -403,6 +427,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -420,6 +446,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: "blah",
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -436,6 +464,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -452,6 +482,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -468,6 +500,8 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand All @@ -487,6 +521,50 @@ func TestConfigValidate(t *testing.T) {
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Backoff: BackoffConfig{
Mode: "fggl",
},
},
wantErr: true,
},
{
name: "bad clock class config",
in: Config{
Iface: "eth0",
Interval: time.Second,
ExchangeTimeout: 100 * time.Millisecond,
MetricsAggregationWindow: time.Duration(60) * time.Second,
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 2,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Backoff: BackoffConfig{
Mode: "fggl",
},
},
wantErr: true,
},
{
name: "bad clock accuracy config",
in: Config{
Iface: "eth0",
Interval: time.Second,
ExchangeTimeout: 100 * time.Millisecond,
MetricsAggregationWindow: time.Duration(60) * time.Second,
AttemptsTXTS: 10,
TimeoutTXTS: time.Duration(50) * time.Millisecond,
Timestamping: HWTIMESTAMP,
MaxClockClass: 7,
MaxClockAccuracy: 10,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand Down Expand Up @@ -524,6 +602,8 @@ firststepthreshold: 1s
metricsaggregationwindow: 10s
attemptstxts: 12
timeouttxts: 40ms
maxclockclass: 6
maxclockaccuracy: 32
servers:
192.168.0.10: 2
192.168.0.13: 3
Expand All @@ -546,6 +626,8 @@ measurement:
DSCP: 42,
FirstStepThreshold: time.Second,
MetricsAggregationWindow: 10 * time.Second,
MaxClockClass: 6,
MaxClockAccuracy: 32,
Servers: map[string]int{
"192.168.0.10": 2,
"192.168.0.13": 3,
Expand Down Expand Up @@ -575,6 +657,8 @@ func TestPrepareConfigDefaults(t *testing.T) {
DSCP: 42,
FirstStepThreshold: 0,
MetricsAggregationWindow: 60 * time.Second,
MaxClockClass: 7,
MaxClockAccuracy: 37,
Servers: map[string]int{
"192.168.0.10": 0,
},
Expand Down
2 changes: 1 addition & 1 deletion ptp/sptp/client/sptp.go
Expand Up @@ -388,7 +388,7 @@ func (p *SPTP) processResults(results map[string]*RunResult) {
} else {
p.stats.SetCounter("ptp.sptp.gms.available_pct", int64(0))
}
best := bmca(announces, localPrioMap)
best := bmca(announces, localPrioMap, p.cfg)
if best == nil {
log.Warningf("no Best Master selected")
p.bestGM = ""
Expand Down

0 comments on commit 5968f63

Please sign in to comment.