From 12c075284a31434bfdbd2acd7804c9b83a1041a3 Mon Sep 17 00:00:00 2001 From: Maximilian Wilhelm <max@sdn.clinic> Date: Tue, 3 Jul 2018 00:15:43 +0200 Subject: [PATCH] Decode and store OriginatorID and ClusterList attributes. Signed-off-by: Maximilian Wilhelm <max@sdn.clinic> --- protocols/bgp/packet/bgp.go | 3 +++ protocols/bgp/packet/path_attributes.go | 32 +++++++++++++++++++++++++ protocols/bgp/server/fsm_established.go | 4 ++++ 3 files changed, 39 insertions(+) diff --git a/protocols/bgp/packet/bgp.go b/protocols/bgp/packet/bgp.go index e008205a..77b86111 100644 --- a/protocols/bgp/packet/bgp.go +++ b/protocols/bgp/packet/bgp.go @@ -14,6 +14,7 @@ const ( NLRIMaxLen = 5 CommunityLen = 4 LargeCommunityLen = 12 + ClusterIDLen = 4 OpenMsg = 1 UpdateMsg = 2 @@ -66,6 +67,8 @@ const ( AtomicAggrAttr = 6 AggregatorAttr = 7 CommunitiesAttr = 8 + OriginatorIDAttr = 9 + ClusterListAttr = 10 AS4PathAttr = 17 AS4AggregatorAttr = 18 LargeCommunitiesAttr = 32 diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go index 77025f38..8544d86b 100644 --- a/protocols/bgp/packet/path_attributes.go +++ b/protocols/bgp/packet/path_attributes.go @@ -99,6 +99,14 @@ func decodePathAttr(buf *bytes.Buffer, opt *types.Options) (pa *PathAttribute, c if err := pa.decodeCommunities(buf); err != nil { return nil, consumed, fmt.Errorf("Failed to decode Community: %v", err) } + case OriginatorIDAttr: + if err := pa.decodeOriginatorID(buf); err != nil { + return nil, consumed, fmt.Errorf("Failed to decode OriginatorID: %v", err) + } + case ClusterListAttr: + if err := pa.decodeClusterList(buf); err != nil { + return nil, consumed, fmt.Errorf("Failed to decode OriginatorID: %v", err) + } case MultiProtocolReachNLRICode: if err := pa.decodeMultiProtocolReachNLRI(buf); err != nil { return nil, consumed, fmt.Errorf("Failed to multi protocol reachable NLRI: %v", err) @@ -364,6 +372,30 @@ func (pa *PathAttribute) decodeUint32(buf *bytes.Buffer, attrName string) error return nil } +func (pa *PathAttribute) decodeOriginatorID(buf *bytes.Buffer) error { + return pa.decodeUint32(buf, "OriginatorID") +} + +func (pa *PathAttribute) decodeClusterList(buf *bytes.Buffer) error { + if pa.Length%ClusterIDLen != 0 { + return fmt.Errorf("Unable to read ClusterList path attribute. Length %d is not divisible by %d", pa.Length, ClusterIDLen) + } + + count := pa.Length / ClusterIDLen + cids := make([]uint32, count) + + for i := uint16(0); i < count; i++ { + v, err := read4BytesAsUint32(buf) + if err != nil { + return err + } + cids[i] = v + } + + pa.Value = cids + return nil +} + func (pa *PathAttribute) setLength(buf *bytes.Buffer) (int, error) { bytesRead := 0 if pa.ExtendedLength { diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go index d881fa7e..7224d4e1 100644 --- a/protocols/bgp/server/fsm_established.go +++ b/protocols/bgp/server/fsm_established.go @@ -293,6 +293,10 @@ func (s *establishedState) processAttributes(attrs *packet.PathAttribute, path * path.BGPPath.Communities = pa.Value.([]uint32) case packet.LargeCommunitiesAttr: path.BGPPath.LargeCommunities = pa.Value.([]types.LargeCommunity) + case packet.OriginatorIDAttr: + path.BGPPath.OriginatorID = pa.Value.(uint32) + case packet.ClusterListAttr: + path.BGPPath.ClusterList = pa.Value.([]uint32) default: unknownAttr := s.processUnknownAttribute(pa) if unknownAttr != nil { -- GitLab