summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-11-23 21:43:50 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2017-11-23 21:43:50 +0900
commitab756c89379a9353663e5b18402ea2205ff86877 (patch)
tree0c8422185d91d3ef648f3cdbf0207333a6deb3d3
parentaf72360f71ebd91de3c0e4548cb9d39367d7eba9 (diff)
table: fix merging of v4 paths with addpath enabled
V4 NLRI needs more 4 bytes with addpath enabled. Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r--packet/bgp/bgp.go40
-rw-r--r--server/fsm.go2
-rw-r--r--table/message.go19
3 files changed, 32 insertions, 29 deletions
diff --git a/packet/bgp/bgp.go b/packet/bgp/bgp.go
index 49a276b1..ef31817c 100644
--- a/packet/bgp/bgp.go
+++ b/packet/bgp/bgp.go
@@ -33,7 +33,7 @@ type MarshallingOption struct {
AddPath map[RouteFamily]BGPAddPathMode
}
-func handleAddPath(decode bool, f RouteFamily, options []*MarshallingOption) bool {
+func IsAddPathEnabled(decode bool, f RouteFamily, options []*MarshallingOption) bool {
for _, opt := range options {
if opt == nil {
continue
@@ -1102,7 +1102,7 @@ func (r *IPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOptio
if r.addrlen == 16 {
f = RF_IPv6_UC
}
- if handleAddPath(true, f, options) {
+ if IsAddPathEnabled(true, f, options) {
var err error
data, err = r.decodePathIdentifier(data)
if err != nil {
@@ -1124,7 +1124,7 @@ func (r *IPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error)
f = RF_IPv6_UC
}
var buf []byte
- if handleAddPath(false, f, options) {
+ if IsAddPathEnabled(false, f, options) {
var err error
buf, err = r.serializeIdentifier()
if err != nil {
@@ -1564,7 +1564,7 @@ func (l *LabeledVPNIPAddrPrefix) DecodeFromBytes(data []byte, options ...*Marsha
if l.addrlen == 16 {
f = RF_IPv6_VPN
}
- if handleAddPath(true, f, options) {
+ if IsAddPathEnabled(true, f, options) {
var err error
data, err = l.decodePathIdentifier(data)
if err != nil {
@@ -1593,7 +1593,7 @@ func (l *LabeledVPNIPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byt
f = RF_IPv6_VPN
}
var buf []byte
- if handleAddPath(false, f, options) {
+ if IsAddPathEnabled(false, f, options) {
var err error
buf, err = l.serializeIdentifier()
if err != nil {
@@ -1711,7 +1711,7 @@ func (l *LabeledIPAddrPrefix) DecodeFromBytes(data []byte, options ...*Marshalli
if l.addrlen == 16 {
f = RF_IPv6_MPLS
}
- if handleAddPath(true, f, options) {
+ if IsAddPathEnabled(true, f, options) {
var err error
data, err = l.decodePathIdentifier(data)
if err != nil {
@@ -1736,7 +1736,7 @@ func (l *LabeledIPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte,
f = RF_IPv6_MPLS
}
var buf []byte
- if handleAddPath(false, f, options) {
+ if IsAddPathEnabled(false, f, options) {
var err error
buf, err = l.serializeIdentifier()
if err != nil {
@@ -1816,7 +1816,7 @@ type RouteTargetMembershipNLRI struct {
}
func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
- if handleAddPath(true, RF_RTC_UC, options) {
+ if IsAddPathEnabled(true, RF_RTC_UC, options) {
var err error
data, err = n.decodePathIdentifier(data)
if err != nil {
@@ -1844,7 +1844,7 @@ func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte, options ...*Mar
func (n *RouteTargetMembershipNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) {
var buf []byte
- if handleAddPath(false, RF_RTC_UC, options) {
+ if IsAddPathEnabled(false, RF_RTC_UC, options) {
var err error
buf, err = n.serializeIdentifier()
if err != nil {
@@ -2684,7 +2684,7 @@ type EVPNNLRI struct {
}
func (n *EVPNNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error {
- if handleAddPath(true, RF_EVPN, options) {
+ if IsAddPathEnabled(true, RF_EVPN, options) {
var err error
data, err = n.decodePathIdentifier(data)
if err != nil {
@@ -2710,7 +2710,7 @@ func (n *EVPNNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) e
func (n *EVPNNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) {
var buf []byte
- if handleAddPath(false, RF_EVPN, options) {
+ if IsAddPathEnabled(false, RF_EVPN, options) {
var err error
buf, err = n.serializeIdentifier()
if err != nil {
@@ -2783,7 +2783,7 @@ func (n *EncapNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption)
if n.addrlen == 16 {
f = RF_IPv6_ENCAP
}
- if handleAddPath(true, f, options) {
+ if IsAddPathEnabled(true, f, options) {
var err error
data, err = n.decodePathIdentifier(data)
if err != nil {
@@ -2808,7 +2808,7 @@ func (n *EncapNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) {
if n.addrlen == 16 {
f = RF_IPv6_ENCAP
}
- if handleAddPath(false, f, options) {
+ if IsAddPathEnabled(false, f, options) {
var err error
buf, err = n.serializeIdentifier()
if err != nil {
@@ -3940,7 +3940,7 @@ func (n *FlowSpecNLRI) RD() RouteDistinguisherInterface {
}
func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...*MarshallingOption) error {
- if handleAddPath(true, rf, options) {
+ if IsAddPathEnabled(true, rf, options) {
var err error
data, err = n.decodePathIdentifier(data)
if err != nil {
@@ -4062,7 +4062,7 @@ func (n *FlowSpecNLRI) Serialize(options ...*MarshallingOption) ([]byte, error)
buf = append(b, buf...)
}
- if handleAddPath(false, n.rf, options) {
+ if IsAddPathEnabled(false, n.rf, options) {
id, err := n.serializeIdentifier()
if err != nil {
return nil, err
@@ -4319,7 +4319,7 @@ func (n *OpaqueNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption)
if len(data) < 2 {
return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all OpaqueNLRI bytes available")
}
- if handleAddPath(true, RF_OPAQUE, options) {
+ if IsAddPathEnabled(true, RF_OPAQUE, options) {
var err error
data, err = n.decodePathIdentifier(data)
if err != nil {
@@ -4343,7 +4343,7 @@ func (n *OpaqueNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) {
binary.BigEndian.PutUint16(buf, uint16(len(n.Key)))
buf = append(buf, n.Key...)
buf = append(buf, n.Value...)
- if handleAddPath(false, RF_OPAQUE, options) {
+ if IsAddPathEnabled(false, RF_OPAQUE, options) {
id, err := n.serializeIdentifier()
if err != nil {
return nil, err
@@ -5811,7 +5811,7 @@ func (p *PathAttributeMpReachNLRI) DecodeFromBytes(data []byte, options ...*Mars
}
value = value[1:]
addpathLen := 0
- if handleAddPath(true, AfiSafiToRouteFamily(afi, safi), options) {
+ if IsAddPathEnabled(true, AfiSafiToRouteFamily(afi, safi), options) {
addpathLen = 4
}
for len(value) > 0 {
@@ -5957,7 +5957,7 @@ func (p *PathAttributeMpUnreachNLRI) DecodeFromBytes(data []byte, options ...*Ma
p.AFI = afi
p.SAFI = safi
addpathLen := 0
- if handleAddPath(true, AfiSafiToRouteFamily(afi, safi), options) {
+ if IsAddPathEnabled(true, AfiSafiToRouteFamily(afi, safi), options) {
addpathLen = 4
}
for len(value) > 0 {
@@ -8109,7 +8109,7 @@ func (msg *BGPUpdate) DecodeFromBytes(data []byte, options ...*MarshallingOption
}
addpathLen := 0
- if handleAddPath(true, RF_IPv4_UC, options) {
+ if IsAddPathEnabled(true, RF_IPv4_UC, options) {
addpathLen = 4
}
diff --git a/server/fsm.go b/server/fsm.go
index aaa13922..556e1029 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -1445,7 +1445,7 @@ func (h *FSMHandler) sendMessageloop() error {
return nil
case o := <-h.outgoing.Out():
m := o.(*FsmOutgoingMsg)
- for _, msg := range table.CreateUpdateMsgFromPaths(m.Paths) {
+ for _, msg := range table.CreateUpdateMsgFromPaths(m.Paths, h.fsm.marshallingOptions) {
if err := send(msg); err != nil {
return nil
}
diff --git a/table/message.go b/table/message.go
index 4f49e36f..0e4acc7d 100644
--- a/table/message.go
+++ b/table/message.go
@@ -270,7 +270,7 @@ func newCage(b []byte, path *Path) *cage {
type packerInterface interface {
add(*Path)
- pack() []*bgp.BGPMessage
+ pack(options ...*bgp.MarshallingOption) []*bgp.BGPMessage
}
type packer struct {
@@ -314,7 +314,7 @@ func createMPReachMessage(path *Path) *bgp.BGPMessage {
return bgp.NewBGPUpdateMessage(nil, attrs, nil)
}
-func (p *packerMP) pack() []*bgp.BGPMessage {
+func (p *packerMP) pack(options ...*bgp.MarshallingOption) []*bgp.BGPMessage {
msgs := make([]*bgp.BGPMessage, 0, p.packer.total)
for _, path := range p.withdrawals {
@@ -392,7 +392,7 @@ func (p *packerV4) add(path *Path) {
}
}
-func (p *packerV4) pack() []*bgp.BGPMessage {
+func (p *packerV4) pack(options ...*bgp.MarshallingOption) []*bgp.BGPMessage {
split := func(max int, paths []*Path) ([]*bgp.IPAddrPrefix, []*Path) {
nlris := make([]*bgp.IPAddrPrefix, 0, max)
i := 0
@@ -404,12 +404,15 @@ func (p *packerV4) pack() []*bgp.BGPMessage {
}
return nlris, paths[i:]
}
+ addpathNLRILen := 0
+ if bgp.IsAddPathEnabled(false, p.packer.family, options) {
+ addpathNLRILen = 4
+ }
// Header + Update (WithdrawnRoutesLen +
// TotalPathAttributeLen + attributes + maxlen of NLRI).
- // the max size of NLRI is 5bytes
- // TODO: addpath needs 4 bytes per NLRI
+ // the max size of NLRI is 5bytes (plus 4bytes with addpath enabled)
maxNLRIs := func(attrsLen int) int {
- return (bgp.BGP_MAX_MESSAGE_LENGTH - (19 + 2 + 2 + attrsLen)) / 5
+ return (bgp.BGP_MAX_MESSAGE_LENGTH - (19 + 2 + 2 + attrsLen)) / (5 + addpathNLRILen)
}
loop := func(attrsLen int, paths []*Path, cb func([]*bgp.IPAddrPrefix)) {
@@ -476,7 +479,7 @@ func newPacker(f bgp.RouteFamily) packerInterface {
}
}
-func CreateUpdateMsgFromPaths(pathList []*Path) []*bgp.BGPMessage {
+func CreateUpdateMsgFromPaths(pathList []*Path, options ...*bgp.MarshallingOption) []*bgp.BGPMessage {
msgs := make([]*bgp.BGPMessage, 0, len(pathList))
m := make(map[bgp.RouteFamily]packerInterface)
@@ -489,7 +492,7 @@ func CreateUpdateMsgFromPaths(pathList []*Path) []*bgp.BGPMessage {
}
for _, p := range m {
- msgs = append(msgs, p.pack()...)
+ msgs = append(msgs, p.pack(options...)...)
}
return msgs
}