summaryrefslogtreecommitdiffhomepage
path: root/packet
diff options
context:
space:
mode:
Diffstat (limited to 'packet')
-rw-r--r--packet/bgp.go73
-rw-r--r--packet/bgp_test.go4
2 files changed, 76 insertions, 1 deletions
diff --git a/packet/bgp.go b/packet/bgp.go
index f2f673e8..01de6a62 100644
--- a/packet/bgp.go
+++ b/packet/bgp.go
@@ -205,6 +205,7 @@ const (
BGP_CAP_CARRYING_LABEL_INFO BGPCapabilityCode = 4
BGP_CAP_GRACEFUL_RESTART BGPCapabilityCode = 64
BGP_CAP_FOUR_OCTET_AS_NUMBER BGPCapabilityCode = 65
+ BGP_CAP_ADD_PATH BGPCapabilityCode = 69
BGP_CAP_ENHANCED_ROUTE_REFRESH BGPCapabilityCode = 70
BGP_CAP_ROUTE_REFRESH_CISCO BGPCapabilityCode = 128
)
@@ -421,6 +422,76 @@ func NewCapFourOctetASNumber(asnum uint32) *CapFourOctetASNumber {
}
}
+type BGPAddPathMode uint8
+
+const (
+ BGP_ADD_PATH_RECEIVE BGPAddPathMode = 1
+ BGP_ADD_PATH_SEND BGPAddPathMode = 2
+ BGP_ADD_PATH_BOTH BGPAddPathMode = 3
+)
+
+func (m BGPAddPathMode) String() string {
+ switch m {
+ case BGP_ADD_PATH_RECEIVE:
+ return "receive"
+ case BGP_ADD_PATH_SEND:
+ return "send"
+ case BGP_ADD_PATH_BOTH:
+ return "receive/send"
+ default:
+ return fmt.Sprintf("unknown(%d)", m)
+ }
+}
+
+type CapAddPath struct {
+ DefaultParameterCapability
+ RouteFamily RouteFamily
+ Mode BGPAddPathMode
+}
+
+func (c *CapAddPath) DecodeFromBytes(data []byte) error {
+ c.DefaultParameterCapability.DecodeFromBytes(data)
+ data = data[2:]
+ if len(data) < 4 {
+ return fmt.Errorf("Not all CapabilityAddPath bytes available")
+ }
+ c.RouteFamily = AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2])
+ c.Mode = BGPAddPathMode(data[3])
+ return nil
+}
+
+func (c *CapAddPath) Serialize() ([]byte, error) {
+ buf := make([]byte, 4)
+ afi, safi := RouteFamilyToAfiSafi(c.RouteFamily)
+ binary.BigEndian.PutUint16(buf, afi)
+ buf[2] = safi
+ buf[3] = byte(c.Mode)
+ c.DefaultParameterCapability.CapValue = buf
+ return c.DefaultParameterCapability.Serialize()
+}
+
+func (c *CapAddPath) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Code BGPCapabilityCode `json"code"`
+ Value RouteFamily `json:"value"`
+ Mode BGPAddPathMode `json:"mode"`
+ }{
+ Code: c.Code(),
+ Value: c.RouteFamily,
+ Mode: c.Mode,
+ })
+}
+
+func NewCapAddPath(rf RouteFamily, mode BGPAddPathMode) *CapAddPath {
+ return &CapAddPath{
+ DefaultParameterCapability: DefaultParameterCapability{
+ CapCode: BGP_CAP_ADD_PATH,
+ },
+ RouteFamily: rf,
+ Mode: mode,
+ }
+}
+
type CapEnhancedRouteRefresh struct {
DefaultParameterCapability
}
@@ -465,6 +536,8 @@ func DecodeCapability(data []byte) (ParameterCapabilityInterface, error) {
c = &CapGracefulRestart{}
case BGP_CAP_FOUR_OCTET_AS_NUMBER:
c = &CapFourOctetASNumber{}
+ case BGP_CAP_ADD_PATH:
+ c = &CapAddPath{}
case BGP_CAP_ENHANCED_ROUTE_REFRESH:
c = &CapEnhancedRouteRefresh{}
case BGP_CAP_ROUTE_REFRESH_CISCO:
diff --git a/packet/bgp_test.go b/packet/bgp_test.go
index 5b0e462c..22db55b2 100644
--- a/packet/bgp_test.go
+++ b/packet/bgp_test.go
@@ -32,8 +32,10 @@ func open() *BGPMessage {
[]CapGracefulRestartTuples{g})})
p4 := NewOptionParameterCapability(
[]ParameterCapabilityInterface{NewCapFourOctetASNumber(100000)})
+ p5 := NewOptionParameterCapability(
+ []ParameterCapabilityInterface{NewCapAddPath(RF_IPv4_UC, BGP_ADD_PATH_BOTH)})
return NewBGPOpenMessage(11033, 303, "100.4.10.3",
- []OptionParameterInterface{p1, p2, p3, p4})
+ []OptionParameterInterface{p1, p2, p3, p4, p5})
}
func update() *BGPMessage {