diff --git a/protocols/bgp/packet/bgp.go b/protocols/bgp/packet/bgp.go index f75ce7a0c4403e8d1530c198099d2cbefa605923..c6776ace6c41f6ccbfd8e2b126f38fc5c16d4798 100644 --- a/protocols/bgp/packet/bgp.go +++ b/protocols/bgp/packet/bgp.go @@ -140,8 +140,3 @@ type PathAttribute struct { Value interface{} Next *PathAttribute } - -type Aggretator struct { - Addr uint32 - ASN uint16 -} diff --git a/protocols/bgp/packet/decoder_test.go b/protocols/bgp/packet/decoder_test.go index ba4517052083a965a9aafae7e97c0bb9312680d6..5613bbcb6c46a385492f5c38f5a837ae5e287ee7 100644 --- a/protocols/bgp/packet/decoder_test.go +++ b/protocols/bgp/packet/decoder_test.go @@ -1197,9 +1197,9 @@ func TestDecodeUpdateMsg(t *testing.T) { ExtendedLength: false, Length: 6, TypeCode: 7, - Value: Aggretator{ - ASN: uint16(258), - Addr: strAddr("10.11.12.13"), + Value: types.Aggregator{ + ASN: uint16(258), + Address: strAddr("10.11.12.13"), }, }, }, diff --git a/protocols/bgp/packet/path_attributes.go b/protocols/bgp/packet/path_attributes.go index 3b3f23d7fa9f19f0ef838143c4da7d5125bde76f..8416f972151f7f99deaf1288bf991d930172bc1f 100644 --- a/protocols/bgp/packet/path_attributes.go +++ b/protocols/bgp/packet/path_attributes.go @@ -232,7 +232,7 @@ func (pa *PathAttribute) decodeLocalPref(buf *bytes.Buffer) error { } func (pa *PathAttribute) decodeAggregator(buf *bytes.Buffer) error { - aggr := Aggretator{} + aggr := types.Aggregator{} p := uint16(0) err := decode(buf, []interface{}{&aggr.ASN}) @@ -249,7 +249,7 @@ func (pa *PathAttribute) decodeAggregator(buf *bytes.Buffer) error { if n != 4 { return fmt.Errorf("Unable to read next hop: buf.Read read %d bytes", n) } - aggr.Addr = fourBytesToUint32(addr) + aggr.Address = fourBytesToUint32(addr) pa.Value = aggr p += 4 @@ -630,33 +630,39 @@ func (pa *PathAttribute) AddOptionalPathAttributes(p *route.Path) *PathAttribute } // PathAttributes converts a path object into a linked list of path attributes -func PathAttributes(p *route.Path) (*PathAttribute, error) { +func PathAttributes(p *route.Path, iBGP bool) (*PathAttribute, error) { asPath := &PathAttribute{ TypeCode: ASPathAttr, Value: p.BGPPath.ASPath, } + last := asPath origin := &PathAttribute{ TypeCode: OriginAttr, Value: p.BGPPath.Origin, } - asPath.Next = origin + last.Next = origin + last = origin nextHop := &PathAttribute{ TypeCode: NextHopAttr, Value: p.BGPPath.NextHop, } - origin.Next = nextHop + last.Next = nextHop + last = nextHop - localPref := &PathAttribute{ - TypeCode: LocalPrefAttr, - Value: p.BGPPath.LocalPref, + if iBGP { + localPref := &PathAttribute{ + TypeCode: LocalPrefAttr, + Value: p.BGPPath.LocalPref, + } + last.Next = localPref + last = localPref } - nextHop.Next = localPref - optionals := localPref.AddOptionalPathAttributes(p) + optionals := last.AddOptionalPathAttributes(p) - last := optionals + last = optionals for _, unknownAttr := range p.BGPPath.UnknownAttributes { last.Next = &PathAttribute{ TypeCode: unknownAttr.TypeCode, diff --git a/protocols/bgp/packet/path_attributes_test.go b/protocols/bgp/packet/path_attributes_test.go index aa3f319a06599e57aee477b28f1310222303eb1c..7cd0887c2795eac3492d697e287ebbe090d8038d 100644 --- a/protocols/bgp/packet/path_attributes_test.go +++ b/protocols/bgp/packet/path_attributes_test.go @@ -564,9 +564,9 @@ func TestDecodeAggregator(t *testing.T) { wantFail: false, expected: &PathAttribute{ Length: 6, - Value: Aggretator{ - ASN: 222, - Addr: strAddr("10.20.30.40"), + Value: types.Aggregator{ + ASN: 222, + Address: strAddr("10.20.30.40"), }, }, }, diff --git a/protocols/bgp/server/fsm_established.go b/protocols/bgp/server/fsm_established.go index 9408bddf868bf2e5c43856aab5ea0919bf5a03cc..3a1379bbc654dc616c9c5a5fd2c9dae5eba23c52 100644 --- a/protocols/bgp/server/fsm_established.go +++ b/protocols/bgp/server/fsm_established.go @@ -244,6 +244,10 @@ func (s *establishedState) processAttributes(attrs *packet.PathAttribute, path * case packet.ASPathAttr: path.BGPPath.ASPath = pa.Value.(types.ASPath) path.BGPPath.ASPathLen = path.BGPPath.ASPath.Length() + case packet.AggregatorAttr: + path.BGPPath.Aggregator = pa.Value.(types.Aggregator) + case packet.AtomicAggrAttr: + path.BGPPath.AtomicAggregate = true case packet.CommunitiesAttr: path.BGPPath.Communities = pa.Value.([]uint32) case packet.LargeCommunitiesAttr: diff --git a/protocols/bgp/server/update_sender.go b/protocols/bgp/server/update_sender.go index 63c3c7eb4e57b7fe44c3df83141ce539797a05ce..a223ee1752b63775a32a4715bbbb3232575a86ab 100644 --- a/protocols/bgp/server/update_sender.go +++ b/protocols/bgp/server/update_sender.go @@ -86,7 +86,7 @@ func (u *UpdateSender) sender(aggrTime time.Duration) { for key, pathNLRIs := range u.toSend { budget = packet.MaxLen - packet.HeaderLen - packet.MinUpdateLen - int(pathNLRIs.path.BGPPath.Length()) - pathAttrs, err = packet.PathAttributes(pathNLRIs.path) + pathAttrs, err = packet.PathAttributes(pathNLRIs.path, u.iBGP) if err != nil { log.Errorf("Unable to get path attributes: %v", err) continue diff --git a/route/bgp_path.go b/route/bgp_path.go index 1ea90b4e76506a2f5144c21a817040e42b88dcfe..314c8505e93ea96bc52c475403f4495e4aa87650 100644 --- a/route/bgp_path.go +++ b/route/bgp_path.go @@ -20,6 +20,8 @@ type BGPPath struct { Origin uint8 MED uint32 EBGP bool + AtomicAggregate bool + Aggregator types.Aggregator BGPIdentifier uint32 Source bnet.IP Communities []uint32