@@ -86,6 +86,9 @@ type ManagerConfig struct {
8686 // liveness still tracks state and metrics, but will not install or
8787 // uninstall its routes in the kernel for that session.
8888 HonorPeerAdvertisedPassive bool
89+
90+ // Client version to advertise to peers in control packets.
91+ ClientVersion string
8992}
9093
9194// Validate fills defaults and enforces constraints for ManagerConfig.
@@ -142,6 +145,9 @@ func (c *ManagerConfig) Validate() error {
142145 if c .MaxEvents < 0 {
143146 return errors .New ("maxEvents must be greater than 0" )
144147 }
148+ if c .ClientVersion == "" {
149+ return errors .New ("clientVersion is required" )
150+ }
145151 return nil
146152}
147153
@@ -203,6 +209,11 @@ func NewManager(ctx context.Context, cfg *ManagerConfig) (*manager, error) {
203209 return nil , fmt .Errorf ("error validating manager config: %v" , err )
204210 }
205211
212+ clientVersion , err := ParseClientVersion (cfg .ClientVersion )
213+ if err != nil {
214+ return nil , fmt .Errorf ("error parsing client version: %v" , err )
215+ }
216+
206217 udp := cfg .UDP
207218 if udp == nil {
208219 var err error
@@ -249,7 +260,7 @@ func NewManager(ctx context.Context, cfg *ManagerConfig) (*manager, error) {
249260
250261 // Wire up IO loops.
251262 m .recv = NewReceiver (m .log , m .udp , m .HandleRx , m .metrics )
252- m .sched = NewScheduler (m .log , m .udp , m .onSessionDown , m .cfg .MaxEvents , m .cfg .EnablePeerMetrics , m .metrics , m .cfg .PassiveMode )
263+ m .sched = NewScheduler (m .log , m .udp , m .onSessionDown , m .cfg .MaxEvents , m .cfg .EnablePeerMetrics , m .metrics , m .cfg .PassiveMode , clientVersion )
253264
254265 // Receiver goroutine: parses control packets and dispatches to HandleRx.
255266 m .wg .Add (1 )
@@ -737,7 +748,10 @@ func (m *manager) onSessionUp(sess *Session) {
737748 "peer" , peer .String (),
738749 "route" , snap .Route .String (),
739750 "convergence" , convergence .String (),
740- "upSince" , snap .UpSince .UTC ().String ())
751+ "upSince" , snap .UpSince .UTC ().String (),
752+ "peerAdvertisedMode" , snap .PeerAdvertisedMode .String (),
753+ "peerClientVersion" , snap .PeerClientVersion .String (),
754+ )
741755}
742756
743757// onSessionDown withdraws the route if currently installed (unless PassiveMode
@@ -779,7 +793,9 @@ func (m *manager) onSessionDown(sess *Session) {
779793 "peer" , peer .String (),
780794 "routePresent" , route != nil ,
781795 "downSince" , snap .DownSince .UTC ().String (),
782- "downReason" , snap .LastDownReason .String ())
796+ "downReason" , snap .LastDownReason .String (),
797+ "peerClientVersion" , snap .PeerClientVersion .String (),
798+ )
783799 return
784800 }
785801
@@ -788,7 +804,9 @@ func (m *manager) onSessionDown(sess *Session) {
788804 "peer" , peer .String (),
789805 "route" , snap .Route .String (),
790806 "downSince" , snap .DownSince .UTC ().String (),
791- "downReason" , snap .LastDownReason .String ())
807+ "downReason" , snap .LastDownReason .String (),
808+ "peerClientVersion" , snap .PeerClientVersion .String (),
809+ )
792810 return
793811 }
794812
@@ -797,7 +815,9 @@ func (m *manager) onSessionDown(sess *Session) {
797815 "peer" , peer .String (),
798816 "route" , snap .Route .String (),
799817 "downSince" , snap .DownSince .UTC ().String (),
800- "downReason" , snap .LastDownReason .String ())
818+ "downReason" , snap .LastDownReason .String (),
819+ "peerClientVersion" , snap .PeerClientVersion .String (),
820+ )
801821 return
802822 }
803823
@@ -816,7 +836,9 @@ func (m *manager) onSessionDown(sess *Session) {
816836 "route" , snap .Route .String (),
817837 "convergence" , convergence .String (),
818838 "downSince" , snap .DownSince .UTC ().String (),
819- "downReason" , snap .LastDownReason .String ())
839+ "downReason" , snap .LastDownReason .String (),
840+ "peerClientVersion" , snap .PeerClientVersion .String (),
841+ )
820842}
821843
822844// isPeerEffectivelyPassive returns true when this session should not have its
0 commit comments