summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--config/util.go21
-rw-r--r--packet/bgp/validate.go41
-rw-r--r--packet/bgp/validate_test.go49
-rw-r--r--server/fsm.go6
4 files changed, 70 insertions, 47 deletions
diff --git a/config/util.go b/config/util.go
index 915b55b4..3bbddca9 100644
--- a/config/util.go
+++ b/config/util.go
@@ -40,19 +40,24 @@ func detectConfigFileType(path, def string) string {
}
}
-func IsConfederationMember(g *Global, p *Neighbor) bool {
- if p.Config.PeerAs != g.Config.As {
- for _, member := range g.Confederation.Config.MemberAsList {
- if member == p.Config.PeerAs {
- return true
- }
+func (n *Neighbor) IsConfederationMember(g *Global) bool {
+ for _, member := range g.Confederation.Config.MemberAsList {
+ if member == n.Config.PeerAs {
+ return true
}
}
return false
}
-func IsEBGPPeer(g *Global, p *Neighbor) bool {
- return p.Config.PeerAs != g.Config.As
+func (n *Neighbor) IsConfederation(g *Global) bool {
+ if n.Config.PeerAs == g.Config.As {
+ return true
+ }
+ return n.IsConfederationMember(g)
+}
+
+func (n *Neighbor) IsEBGPPeer(g *Global) bool {
+ return n.Config.PeerAs != g.Config.As
}
type AfiSafis []AfiSafi
diff --git a/packet/bgp/validate.go b/packet/bgp/validate.go
index 9553d6d5..424047a5 100644
--- a/packet/bgp/validate.go
+++ b/packet/bgp/validate.go
@@ -8,7 +8,7 @@ import (
)
// Validator for BGPUpdate
-func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]BGPAddPathMode, doConfedCheck bool) (bool, error) {
+func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]BGPAddPathMode, isEBGP bool, isConfed bool) (bool, error) {
var strongestError error
eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
@@ -30,7 +30,7 @@ func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]BGPAddPathMode, doConfe
seen[a.GetType()] = a
newAttrs = append(newAttrs, a)
//check specific path attribute
- ok, err := ValidateAttribute(a, rfs, doConfedCheck)
+ ok, err := ValidateAttribute(a, rfs, isEBGP, isConfed)
if !ok {
if err.(*MessageError).ErrorHandling == ERROR_HANDLING_SESSION_RESET {
return false, err
@@ -79,7 +79,7 @@ func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]BGPAddPathMode, doConfe
return strongestError == nil, strongestError
}
-func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]BGPAddPathMode, doConfedCheck bool) (bool, error) {
+func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]BGPAddPathMode, isEBGP bool, isConfed bool) (bool, error) {
var strongestError error
eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
@@ -172,21 +172,28 @@ func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]BGPAddPathM
}
}
case *PathAttributeAsPath:
- if doConfedCheck {
- for _, paramIf := range p.Value {
- var segType uint8
- asParam, y := paramIf.(*As4PathParam)
- if y {
- segType = asParam.Type
- } else {
- segType = paramIf.(*AsPathParam).Type
+ getSegType := func(p AsPathParamInterface) uint8 {
+ asParam, y := p.(*As4PathParam)
+ if y {
+ return asParam.Type
+ } else {
+ return p.(*AsPathParam).Type
+ }
+ }
+ if isEBGP {
+ if isConfed {
+ if segType := getSegType(p.Value[0]); segType != BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
+ return false, NewMessageError(eCode, eSubCodeMalformedAspath, nil, fmt.Sprintf("segment type is not confederation seq (%d)", segType))
}
-
- if segType == BGP_ASPATH_ATTR_TYPE_CONFED_SET || segType == BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
- err := NewMessageErrorWithErrorHandling(
- eCode, eSubCodeMalformedAspath, nil, getErrorHandlingFromPathAttribute(p.GetType()), nil, fmt.Sprintf("segment type confederation(%d) found", segType))
- if err.(*MessageError).Stronger(strongestError) {
- strongestError = err
+ } else {
+ for _, paramIf := range p.Value {
+ segType := getSegType(paramIf)
+ if segType == BGP_ASPATH_ATTR_TYPE_CONFED_SET || segType == BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
+ err := NewMessageErrorWithErrorHandling(
+ eCode, eSubCodeMalformedAspath, nil, getErrorHandlingFromPathAttribute(p.GetType()), nil, fmt.Sprintf("segment type confederation(%d) found", segType))
+ if err.(*MessageError).Stronger(strongestError) {
+ strongestError = err
+ }
}
}
}
diff --git a/packet/bgp/validate_test.go b/packet/bgp/validate_test.go
index 2620fbb7..5e986300 100644
--- a/packet/bgp/validate_test.go
+++ b/packet/bgp/validate_test.go
@@ -41,29 +41,29 @@ func bgpupdateV6() *BGPMessage {
func Test_Validate_CapV4(t *testing.T) {
assert := assert.New(t)
message := bgpupdate().Body.(*BGPUpdate)
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
- res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(true, res)
}
func Test_Validate_CapV6(t *testing.T) {
assert := assert.New(t)
message := bgpupdateV6().Body.(*BGPUpdate)
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(true, res)
assert.NoError(err)
- res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
}
func Test_Validate_OK(t *testing.T) {
assert := assert.New(t)
message := bgpupdate().Body.(*BGPUpdate)
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(true, res)
assert.NoError(err)
@@ -151,7 +151,7 @@ func Test_Validate_duplicate_attribute(t *testing.T) {
origin.DecodeFromBytes(originBytes)
message.PathAttributes = append(message.PathAttributes, origin)
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -165,7 +165,7 @@ func Test_Validate_mandatory_missing(t *testing.T) {
assert := assert.New(t)
message := bgpupdate().Body.(*BGPUpdate)
message.PathAttributes = message.PathAttributes[1:]
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -182,7 +182,7 @@ func Test_Validate_mandatory_missing_nocheck(t *testing.T) {
message.PathAttributes = message.PathAttributes[1:]
message.NLRI = nil
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(true, res)
assert.NoError(err)
}
@@ -196,7 +196,7 @@ func Test_Validate_invalid_origin(t *testing.T) {
origin.DecodeFromBytes(originBytes)
message.PathAttributes[0] = origin
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -218,7 +218,7 @@ func Test_Validate_invalid_nexthop_zero(t *testing.T) {
nexthop.DecodeFromBytes(nexthopBytes)
message.PathAttributes[2] = nexthop
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -240,7 +240,7 @@ func Test_Validate_invalid_nexthop_lo(t *testing.T) {
nexthop.DecodeFromBytes(nexthopBytes)
message.PathAttributes[2] = nexthop
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -262,7 +262,7 @@ func Test_Validate_invalid_nexthop_de(t *testing.T) {
nexthop.DecodeFromBytes(nexthopBytes)
message.PathAttributes[2] = nexthop
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -283,7 +283,7 @@ func Test_Validate_unrecognized_well_known(t *testing.T) {
unknown.DecodeFromBytes(unknownBytes)
message.PathAttributes = append(message.PathAttributes, unknown)
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -299,7 +299,7 @@ func Test_Validate_aspath(t *testing.T) {
message := bgpupdate().Body.(*BGPUpdate)
// VALID AS_PATH
- res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true)
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false)
assert.Equal(true, res)
// CONFED_SET
@@ -317,7 +317,7 @@ func Test_Validate_aspath(t *testing.T) {
}
message.PathAttributes = newAttrs
- res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true)
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -326,6 +326,14 @@ func Test_Validate_aspath(t *testing.T) {
assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
assert.Nil(e.Data)
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true)
+ assert.Equal(false, res)
+ assert.Error(err)
+ e = err.(*MessageError)
+ assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode)
+ assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
+ assert.Nil(e.Data)
+
// CONFED_SEQ
newAttrs = make([]PathAttributeInterface, 0)
attrs = message.PathAttributes
@@ -341,7 +349,7 @@ func Test_Validate_aspath(t *testing.T) {
}
message.PathAttributes = newAttrs
- res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true)
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false)
assert.Equal(false, res)
assert.Error(err)
e = err.(*MessageError)
@@ -349,6 +357,9 @@ func Test_Validate_aspath(t *testing.T) {
assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode)
assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling)
assert.Nil(e.Data)
+
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true)
+ assert.Equal(true, res)
}
func Test_Validate_flowspec(t *testing.T) {
@@ -382,7 +393,7 @@ func Test_Validate_flowspec(t *testing.T) {
n1 := NewFlowSpecIPv4Unicast(cmp)
a := NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
m := map[RouteFamily]BGPAddPathMode{RF_FS_IPv4_UC: BGP_ADD_PATH_NONE}
- _, err := ValidateAttribute(a, m, false)
+ _, err := ValidateAttribute(a, m, false, false)
assert.Nil(err)
cmp = make([]FlowSpecComponentInterface, 0)
@@ -390,7 +401,7 @@ func Test_Validate_flowspec(t *testing.T) {
cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0")))
n1 = NewFlowSpecIPv4Unicast(cmp)
a = NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1})
- _, err = ValidateAttribute(a, m, false)
+ _, err = ValidateAttribute(a, m, false, false)
assert.NotNil(err)
}
@@ -404,7 +415,7 @@ func TestValidateLargeCommunities(t *testing.T) {
assert.Nil(err)
a := NewPathAttributeLargeCommunities([]*LargeCommunity{c1, c2, c3})
assert.True(len(a.Values) == 3)
- _, err = ValidateAttribute(a, nil, false)
+ _, err = ValidateAttribute(a, nil, false, false)
assert.Nil(err)
assert.True(len(a.Values) == 2)
}
diff --git a/server/fsm.go b/server/fsm.go
index e28ceee2..aaa13922 100644
--- a/server/fsm.go
+++ b/server/fsm.go
@@ -856,17 +856,17 @@ func (h *FSMHandler) recvMessageWithError() (*FsmMsg, error) {
fmsg.MsgType = FSM_MSG_ROUTE_REFRESH
case bgp.BGP_MSG_UPDATE:
body := m.Body.(*bgp.BGPUpdate)
- confedCheck := !config.IsConfederationMember(h.fsm.gConf, h.fsm.pConf) && config.IsEBGPPeer(h.fsm.gConf, h.fsm.pConf)
+ isEBGP := h.fsm.pConf.IsEBGPPeer(h.fsm.gConf)
+ isConfed := h.fsm.pConf.IsConfederationMember(h.fsm.gConf)
fmsg.payload = make([]byte, len(headerBuf)+len(bodyBuf))
copy(fmsg.payload, headerBuf)
copy(fmsg.payload[len(headerBuf):], bodyBuf)
- ok, err := bgp.ValidateUpdateMsg(body, h.fsm.rfMap, confedCheck)
+ ok, err := bgp.ValidateUpdateMsg(body, h.fsm.rfMap, isEBGP, isConfed)
if !ok {
handling = h.handlingError(m, err, useRevisedError)
}
-
if handling == bgp.ERROR_HANDLING_SESSION_RESET {
log.WithFields(log.Fields{
"Topic": "Peer",