diff options
-rw-r--r-- | config/util.go | 21 | ||||
-rw-r--r-- | packet/bgp/validate.go | 41 | ||||
-rw-r--r-- | packet/bgp/validate_test.go | 49 | ||||
-rw-r--r-- | server/fsm.go | 6 |
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", |