diff options
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/packet/bgp/bgp.go | 69 | ||||
-rw-r--r-- | pkg/server/fsm.go | 4 |
2 files changed, 73 insertions, 0 deletions
diff --git a/pkg/packet/bgp/bgp.go b/pkg/packet/bgp/bgp.go index 15e15362..5403a5f3 100644 --- a/pkg/packet/bgp/bgp.go +++ b/pkg/packet/bgp/bgp.go @@ -295,6 +295,7 @@ const ( BGP_CAP_ADD_PATH BGPCapabilityCode = 69 BGP_CAP_ENHANCED_ROUTE_REFRESH BGPCapabilityCode = 70 BGP_CAP_LONG_LIVED_GRACEFUL_RESTART BGPCapabilityCode = 71 + BGP_CAP_FQDN BGPCapabilityCode = 73 BGP_CAP_ROUTE_REFRESH_CISCO BGPCapabilityCode = 128 ) @@ -309,6 +310,7 @@ var CapNameMap = map[BGPCapabilityCode]string{ BGP_CAP_ENHANCED_ROUTE_REFRESH: "enhanced-route-refresh", BGP_CAP_ROUTE_REFRESH_CISCO: "cisco-route-refresh", BGP_CAP_LONG_LIVED_GRACEFUL_RESTART: "long-lived-graceful-restart", + BGP_CAP_FQDN: "fqdn", } func (c BGPCapabilityCode) String() string { @@ -916,6 +918,71 @@ func NewCapLongLivedGracefulRestart(tuples []*CapLongLivedGracefulRestartTuple) } } +type CapFQDN struct { + DefaultParameterCapability + HostNameLen uint8 + HostName string + DomainNameLen uint8 + DomainName string +} + +func (c *CapFQDN) DecodeFromBytes(data []byte) error { + c.DefaultParameterCapability.DecodeFromBytes(data) + data = data[2:] + if len(data) < 2 { + return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityFQDN bytes allowed") + } + hostNameLen := uint8(data[0]) + c.HostNameLen = hostNameLen + c.HostName = string(data[1 : c.HostNameLen+1]) + domainNameLen := uint8(data[c.HostNameLen+1]) + c.DomainNameLen = domainNameLen + c.DomainName = string(data[c.HostNameLen+2:]) + return nil +} + +func (c *CapFQDN) Serialize() ([]byte, error) { + buf := make([]byte, c.HostNameLen+c.DomainNameLen+2) + buf[0] = c.HostNameLen + copy(buf[1:c.HostNameLen+1], c.HostName) + buf[c.HostNameLen+1] = c.DomainNameLen + copy(buf[c.HostNameLen+2:], c.DomainName) + c.DefaultParameterCapability.CapValue = buf + return c.DefaultParameterCapability.Serialize() +} + +func (c *CapFQDN) MarshalJSON() ([]byte, error) { + return json.Marshal(struct { + HostNameLen uint8 `json:"hostname_len"` + HostName string `json:"hostname"` + DomainNameLen uint8 `json:"domainname_len"` + DomainName string `json:"domainname"` + }{ + HostNameLen: c.HostNameLen, + HostName: c.HostName, + DomainNameLen: c.DomainNameLen, + DomainName: c.DomainName, + }) +} + +func NewCapFQDN(hostname string, domainname string) *CapFQDN { + if len(hostname) > 64 { + hostname = hostname[:64] + } + if len(domainname) > 64 { + domainname = domainname[:64] + } + return &CapFQDN{ + DefaultParameterCapability{ + CapCode: BGP_CAP_FQDN, + }, + uint8(len(hostname)), + hostname, + uint8(len(domainname)), + domainname, + } +} + type CapUnknown struct { DefaultParameterCapability } @@ -955,6 +1022,8 @@ func DecodeCapability(data []byte) (ParameterCapabilityInterface, error) { c = &CapRouteRefreshCisco{} case BGP_CAP_LONG_LIVED_GRACEFUL_RESTART: c = &CapLongLivedGracefulRestart{} + case BGP_CAP_FQDN: + c = &CapFQDN{} default: c = &CapUnknown{} } diff --git a/pkg/server/fsm.go b/pkg/server/fsm.go index b024cf3e..abd94ed9 100644 --- a/pkg/server/fsm.go +++ b/pkg/server/fsm.go @@ -21,6 +21,7 @@ import ( "io" "math/rand" "net" + "os" "strconv" "sync" "syscall" @@ -714,8 +715,11 @@ func capAddPathFromConfig(pConf *config.Neighbor) bgp.ParameterCapabilityInterfa } func capabilitiesFromConfig(pConf *config.Neighbor) []bgp.ParameterCapabilityInterface { + fqdn, _ := os.Hostname() caps := make([]bgp.ParameterCapabilityInterface, 0, 4) caps = append(caps, bgp.NewCapRouteRefresh()) + caps = append(caps, bgp.NewCapFQDN(fqdn, "")) + for _, af := range pConf.AfiSafis { caps = append(caps, bgp.NewCapMultiProtocol(af.State.Family)) } |