From 539642d28791789bc52a4d23acc30fac35691fc4 Mon Sep 17 00:00:00 2001 From: Wataru Ishida Date: Mon, 7 Aug 2017 08:15:16 -0400 Subject: table: fix handling of update with both mpunreach and mpreach attribute some implementations send a mpunreach attribute piggy backed on an update message. Since it is stored in pathattrs of gobgp's path structure, we need to exclude it before sending out update messages. Signed-off-by: Wataru Ishida --- table/message.go | 7 ++++--- table/message_test.go | 26 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/table/message.go b/table/message.go index 30a75d24..a2b7f926 100644 --- a/table/message.go +++ b/table/message.go @@ -315,11 +315,12 @@ func createUpdateMsgFromPath(path *Path, msg *bgp.BGPMessage) *bgp.BGPMessage { } } else { attrs := make([]bgp.PathAttributeInterface, 0, 8) - for _, p := range path.GetPathAttrs() { - if p.GetType() == bgp.BGP_ATTR_TYPE_MP_REACH_NLRI { + switch p.GetType() { + case bgp.BGP_ATTR_TYPE_MP_REACH_NLRI: attrs = append(attrs, bgp.NewPathAttributeMpReachNLRI(path.GetNexthop().String(), []bgp.AddrPrefixInterface{path.GetNlri()})) - } else { + case bgp.BGP_ATTR_TYPE_MP_UNREACH_NLRI: + default: attrs = append(attrs, p) } } diff --git a/table/message_test.go b/table/message_test.go index 581c6aba..229ff5de 100644 --- a/table/message_test.go +++ b/table/message_test.go @@ -432,3 +432,29 @@ func TestBMP(t *testing.T) { pList := ProcessMessage(msg, peerR1(), time.Now()) CreateUpdateMsgFromPaths(pList) } + +func TestMixedMPReachMPUnreach(t *testing.T) { + aspath1 := []bgp.AsPathParamInterface{ + bgp.NewAs4PathParam(2, []uint32{100}), + } + nlri1 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(32, "2222::")} + nlri2 := []bgp.AddrPrefixInterface{bgp.NewIPv6AddrPrefix(32, "1111::")} + + p := []bgp.PathAttributeInterface{ + bgp.NewPathAttributeOrigin(0), + bgp.NewPathAttributeAsPath(aspath1), + bgp.NewPathAttributeMpReachNLRI("1::1", nlri1), + bgp.NewPathAttributeMpUnreachNLRI(nlri2), + } + msg := bgp.NewBGPUpdateMessage(nil, p, nil) + pList := ProcessMessage(msg, peerR1(), time.Now()) + assert.Equal(t, len(pList), 2) + assert.Equal(t, pList[0].IsWithdraw, false) + assert.Equal(t, pList[1].IsWithdraw, true) + msgs := CreateUpdateMsgFromPaths(pList) + assert.Equal(t, len(msgs), 2) + attrs := msgs[0].Body.(*bgp.BGPUpdate).PathAttributes + assert.Equal(t, len(attrs), 3) + attrs = msgs[1].Body.(*bgp.BGPUpdate).PathAttributes + assert.Equal(t, len(attrs), 1) +} -- cgit v1.2.3