summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorHiroshi Yokoi <yokoi.hiroshi@po.ntts.co.jp>2015-07-01 17:43:18 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2015-07-01 21:33:39 +0900
commitd43b77e0ec0f3f51cff9317db312d97a98f1df8f (patch)
tree2e05a95be9cd4b116e53bbf418fe7437c5787517
parent1db97a53022a02ff3bf355909b54eb6be8dc286e (diff)
packet: add AS_PATH validator
-rw-r--r--packet/validate.go24
-rw-r--r--packet/validate_test.go82
-rw-r--r--server/peer.go16
3 files changed, 105 insertions, 17 deletions
diff --git a/packet/validate.go b/packet/validate.go
index 2afd53c4..e82113ee 100644
--- a/packet/validate.go
+++ b/packet/validate.go
@@ -8,7 +8,7 @@ import (
)
// Validator for BGPUpdate
-func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]bool) (bool, error) {
+func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]bool, doConfedCheck bool) (bool, error) {
eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
eSubCodeAttrList := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST)
eSubCodeMissing := uint8(BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE)
@@ -31,7 +31,7 @@ func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]bool) (bool, error) {
}
//check specific path attribute
- ok, e := ValidateAttribute(a, rfs)
+ ok, e := ValidateAttribute(a, rfs, doConfedCheck)
if !ok {
return false, e
}
@@ -58,12 +58,13 @@ func ValidateUpdateMsg(m *BGPUpdate, rfs map[RouteFamily]bool) (bool, error) {
return true, nil
}
-func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]bool) (bool, error) {
+func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]bool, doConfedCheck bool) (bool, error) {
eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR)
eSubCodeBadOrigin := uint8(BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE)
eSubCodeBadNextHop := uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE)
eSubCodeUnknown := uint8(BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE)
+ eSubCodeMalformedAspath := uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH)
checkPrefix := func(l []AddrPrefixInterface) bool {
for _, prefix := range l {
@@ -119,6 +120,23 @@ func ValidateAttribute(a PathAttributeInterface, rfs map[RouteFamily]bool) (bool
data, _ := a.Serialize()
return false, NewMessageError(eCode, eSubCodeBadNextHop, data, eMsg)
}
+ 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
+ }
+
+ if segType == BGP_ASPATH_ATTR_TYPE_CONFED_SET || segType == BGP_ASPATH_ATTR_TYPE_CONFED_SEQ {
+ return false, NewMessageError(eCode, eSubCodeMalformedAspath, nil, fmt.Sprintf("segment type confederation(%d) found", segType))
+ }
+ }
+ }
+
case *PathAttributeUnknown:
if p.getFlags()&BGP_ATTR_FLAG_OPTIONAL == 0 {
eMsg := "unrecognized well-known attribute"
diff --git a/packet/validate_test.go b/packet/validate_test.go
index 311ae031..2f007c44 100644
--- a/packet/validate_test.go
+++ b/packet/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]bool{RF_IPv6_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv6_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
- res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, 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]bool{RF_IPv6_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv6_UC: true}, false)
assert.Equal(true, res)
assert.NoError(err)
- res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, 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]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, 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]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -164,7 +164,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]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -180,7 +180,7 @@ func Test_Validate_mandatory_missing_nocheck(t *testing.T) {
message.PathAttributes = message.PathAttributes[1:]
message.NLRI = nil
- res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(true, res)
assert.NoError(err)
}
@@ -194,7 +194,7 @@ func Test_Validate_invalid_origin(t *testing.T) {
origin.DecodeFromBytes(originBytes)
message.PathAttributes[0] = origin
- res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -215,7 +215,7 @@ func Test_Validate_invalid_nexthop_zero(t *testing.T) {
nexthop.DecodeFromBytes(nexthopBytes)
message.PathAttributes[2] = nexthop
- res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -236,7 +236,7 @@ func Test_Validate_invalid_nexthop_lo(t *testing.T) {
nexthop.DecodeFromBytes(nexthopBytes)
message.PathAttributes[2] = nexthop
- res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -257,7 +257,7 @@ func Test_Validate_invalid_nexthop_de(t *testing.T) {
nexthop.DecodeFromBytes(nexthopBytes)
message.PathAttributes[2] = nexthop
- res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -277,7 +277,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]bool{RF_IPv4_UC: true})
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, false)
assert.Equal(false, res)
assert.Error(err)
e := err.(*MessageError)
@@ -285,3 +285,59 @@ func Test_Validate_unrecognized_well_known(t *testing.T) {
assert.Equal(uint8(BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode)
assert.Equal(unknownBytes, e.Data)
}
+
+func Test_Validate_aspath(t *testing.T) {
+
+ assert := assert.New(t)
+ message := bgpupdate().Body.(*BGPUpdate)
+
+ // VALID AS_PATH
+ res, err := ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: true}, true)
+ assert.Equal(true, res)
+
+ // CONFED_SET
+ newAttrs := make([]PathAttributeInterface, 0)
+ attrs := message.PathAttributes
+ for _, attr := range attrs {
+ if _, y := attr.(*PathAttributeAsPath); y {
+ aspath := []AsPathParamInterface{
+ NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65001}),
+ }
+ newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath))
+ } else {
+ newAttrs = append(newAttrs, attr)
+ }
+ }
+
+ message.PathAttributes = newAttrs
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: 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
+ for _, attr := range attrs {
+ if _, y := attr.(*PathAttributeAsPath); y {
+ aspath := []AsPathParamInterface{
+ NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65001}),
+ }
+ newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath))
+ } else {
+ newAttrs = append(newAttrs, attr)
+ }
+ }
+
+ message.PathAttributes = newAttrs
+ res, err = ValidateUpdateMsg(message, map[RouteFamily]bool{RF_IPv4_UC: 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)
+}
diff --git a/server/peer.go b/server/peer.go
index 3e5888f0..fd41563a 100644
--- a/server/peer.go
+++ b/server/peer.go
@@ -43,6 +43,8 @@ type Peer struct {
outgoing chan *bgp.BGPMessage
distPolicies []*policy.Policy
defaultDistributePolicy config.DefaultPolicyType
+ isConfederationMember bool
+ isEBGP bool
}
func NewPeer(g config.Global, config config.Neighbor) *Peer {
@@ -66,6 +68,17 @@ func NewPeer(g config.Global, config config.Neighbor) *Peer {
}
peer.adjRib = table.NewAdjRib(peer.configuredRFlist())
peer.fsm = NewFSM(&g, &config)
+
+ if config.PeerAs != g.As {
+ peer.isEBGP = true
+ for _, member := range g.Confederation.MemberAs {
+ if member == config.PeerAs {
+ peer.isConfederationMember = true
+ break
+ }
+ }
+ }
+
return peer
}
@@ -158,7 +171,8 @@ func (peer *Peer) handleBGPmessage(m *bgp.BGPMessage) ([]*table.Path, bool, []*b
update = true
peer.config.BgpNeighborCommonState.UpdateRecvTime = time.Now().Unix()
body := m.Body.(*bgp.BGPUpdate)
- _, err := bgp.ValidateUpdateMsg(body, peer.rfMap)
+ confedCheckRequired := !peer.isConfederationMember && peer.isEBGP
+ _, err := bgp.ValidateUpdateMsg(body, peer.rfMap, confedCheckRequired)
if err != nil {
log.WithFields(log.Fields{
"Topic": "Peer",