summaryrefslogtreecommitdiffhomepage
path: root/pkg
diff options
context:
space:
mode:
authorDonatas Abraitis <donatas.abraitis@gmail.com>2021-05-24 09:55:03 +0300
committerDonatas Abraitis <donatas.abraitis@gmail.com>2021-05-24 09:55:03 +0300
commit94d720ff40644d09d99829d6a1520075b9f8475a (patch)
tree4fc816ce7ad55a140e81aec21018e1bd38ce5d9a /pkg
parentcbdb752b10847163d9f942853b67cf173b6aa151 (diff)
Add FQDN capability
It's not kinda RFC (draft), but it's implemented and used in various other open-source software like FRRouting, Bird, ExaBGP. It's very handy when dealing with lots of peers. Exampe between GoBGP and FRRouting: ``` % ./cmd/gobgp/gobgp neighbor 192.168.10.123 | grep -A4 fqdn: fqdn: advertised and received Local: name: donatas-pc, domain: Remote: name: exit1-debian-9, domain: ``` ``` % vtysh -c 'show bgp neighbors 192.168.10.17 json' | jq .'"192.168.10.17".neighborCapabilities.hostName' { "advHostName": "exit1-debian-9", "advDomainName": "n/a", "rcvHostName": "donatas-pc", "rcvDomainName": "n/a" } ``` Signed-off-by: Donatas Abraitis <donatas.abraitis@gmail.com>
Diffstat (limited to 'pkg')
-rw-r--r--pkg/packet/bgp/bgp.go69
-rw-r--r--pkg/server/fsm.go4
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))
}