diff options
author | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-24 13:02:28 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2015-08-24 13:02:28 +0900 |
commit | 64ddb52890451da4c9877f8b3273fb9fe35f878c (patch) | |
tree | a5f318298f23134bbba51103aafe406f5597face /table | |
parent | 67dcfd267d681012c2dcab7eaef657884e753a05 (diff) |
pack multiple NLRIs into one BGP update message
With this patch, bobgpd packs multiple NLRIs into one BGP update
message (IOW, multiple paths into one update message).
We do only with ipv4 since we could have lots of routes. If you don't
have lots, it's not worth having the complicated logic for such route
families.
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
Diffstat (limited to 'table')
-rw-r--r-- | table/message.go | 64 |
1 files changed, 37 insertions, 27 deletions
diff --git a/table/message.go b/table/message.go index b7edc383..212cf2c1 100644 --- a/table/message.go +++ b/table/message.go @@ -16,8 +16,8 @@ package table import ( - "bytes" "github.com/osrg/gobgp/packet" + "reflect" ) func UpdatePathAttrs2ByteAs(msg *bgp.BGPUpdate) error { @@ -183,47 +183,57 @@ func createUpdateMsgFromPath(path *Path, msg *bgp.BGPMessage) *bgp.BGPMessage { return nil } -func isSamePathAttrs(pList1 []bgp.PathAttributeInterface, pList2 []bgp.PathAttributeInterface) bool { - if len(pList1) != len(pList2) { +func isMergeable(p1, p2 *Path, msg *bgp.BGPMessage) bool { + if p1 == nil { return false } - for i, p1 := range pList1 { - _, y := p1.(*bgp.PathAttributeMpReachNLRI) - if y { - continue - } - b1, _ := p1.Serialize() - b2, _ := pList2[i].Serialize() - - if bytes.Compare(b1, b2) != 0 { - return false - } + if p1.GetRouteFamily() != bgp.RF_IPv4_UC || p2.GetRouteFamily() != bgp.RF_IPv4_UC { + return false } - return true -} - -func isMergeable(p1, p2 *Path) bool { - return false - if p1 == nil { + if p1.IsWithdraw || p2.IsWithdraw { return false } - if p1.GetRouteFamily() != bgp.RF_IPv4_UC { + if p1.GetSource().Address.Equal(p2.GetSource().Address) == false { return false } - if p1.GetSource().Equal(p2.GetSource()) && isSamePathAttrs(p1.GetPathAttrs(), p2.GetPathAttrs()) { - return true + if reflect.DeepEqual(p1.GetPathAttrs(), p2.GetPathAttrs()) == false { + return false + } + + u := msg.Body.(*bgp.BGPUpdate) + // arbitrary number. just avoid too many NLRIs in one message. + if len(u.NLRI) > 16 { + return false + } + + msgLen := func(u *bgp.BGPUpdate) int { + attrsLen := 0 + for _, a := range u.PathAttributes { + attrsLen += a.Len() + } + // Header + Update (WithdrawnRoutesLen + + // TotalPathAttributeLen + attributes + maxlen of + // NLRI). Note that we try to add one NLRI. + return 19 + 2 + 2 + attrsLen + (len(u.NLRI)+1)*5 + }(u) + + // 128 is arbitrary number. just avoid too tight. + if msgLen+128 > bgp.BGP_MAX_MESSAGE_LENGTH { + return false } - return false + return true } func CreateUpdateMsgFromPaths(pathList []*Path) []*bgp.BGPMessage { var pre *Path var msgs []*bgp.BGPMessage for _, path := range pathList { - y := isMergeable(pre, path) + y := false + if pre != nil { + y = isMergeable(pre, path, msgs[len(msgs)-1]) + } if y { - msg := msgs[len(msgs)-1] - createUpdateMsgFromPath(path, msg) + createUpdateMsgFromPath(path, msgs[len(msgs)-1]) } else { msg := createUpdateMsgFromPath(path, nil) pre = path |