github.com/osrg/gobgp@v2.0.0+incompatible/pkg/packet/bgp/validate_test.go (about) 1 package bgp 2 3 import ( 4 "encoding/binary" 5 "net" 6 "testing" 7 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func bgpupdate() *BGPMessage { 13 aspath := []AsPathParamInterface{ 14 NewAsPathParam(2, []uint16{65001}), 15 } 16 17 p := []PathAttributeInterface{ 18 NewPathAttributeOrigin(1), 19 NewPathAttributeAsPath(aspath), 20 NewPathAttributeNextHop("192.168.1.1"), 21 } 22 23 n := []*IPAddrPrefix{NewIPAddrPrefix(24, "10.10.10.0")} 24 return NewBGPUpdateMessage(nil, p, n) 25 } 26 27 func bgpupdateV6() *BGPMessage { 28 aspath := []AsPathParamInterface{ 29 NewAsPathParam(2, []uint16{65001}), 30 } 31 32 prefixes := []AddrPrefixInterface{NewIPv6AddrPrefix(100, 33 "fe80:1234:1234:5667:8967:af12:8912:1023")} 34 35 p := []PathAttributeInterface{ 36 NewPathAttributeOrigin(1), 37 NewPathAttributeAsPath(aspath), 38 NewPathAttributeMpReachNLRI("1023::", prefixes), 39 } 40 return NewBGPUpdateMessage(nil, p, nil) 41 } 42 43 func Test_Validate_CapV4(t *testing.T) { 44 assert := assert.New(t) 45 message := bgpupdate().Body.(*BGPUpdate) 46 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false) 47 assert.Equal(false, res) 48 assert.Error(err) 49 50 res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 51 require.NoError(t, err) 52 assert.Equal(true, res) 53 } 54 55 func Test_Validate_CapV6(t *testing.T) { 56 assert := assert.New(t) 57 message := bgpupdateV6().Body.(*BGPUpdate) 58 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv6_UC: BGP_ADD_PATH_BOTH}, false, false) 59 assert.NoError(err) 60 assert.True(res) 61 62 res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 63 assert.Error(err) 64 assert.False(res) 65 } 66 67 func Test_Validate_OK(t *testing.T) { 68 assert := assert.New(t) 69 message := bgpupdate().Body.(*BGPUpdate) 70 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 71 assert.Equal(true, res) 72 assert.NoError(err) 73 74 } 75 76 // func Test_Validate_wellknown_but_nontransitive(t *testing.T) { 77 // assert := assert.New(t) 78 // message := bgpupdate().Body.(*BGPUpdate) 79 80 // originBytes := []byte{0, 1, 1, 1} // 0 means Flags 81 // origin := &PathAttributeOrigin{} 82 // origin.DecodeFromBytes(originBytes) 83 // message.PathAttributes[0] = origin 84 85 // res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,}) 86 // assert.Equal(false, res) 87 // assert.Error(err) 88 // e := err.(*MessageError) 89 // assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) 90 // assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) 91 // assert.Equal(originBytes, e.Data) 92 // } 93 94 // func Test_Validate_wellknown_but_partial(t *testing.T) { 95 // assert := assert.New(t) 96 // message := bgpupdate().Body.(*BGPUpdate) 97 98 // originBytes := []byte{BGP_ATTR_FLAG_PARTIAL, 1, 1, 1} 99 // origin := &PathAttributeOrigin{} 100 // origin.DecodeFromBytes(originBytes) 101 // message.PathAttributes[0] = origin 102 103 // res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,}) 104 // assert.Equal(false, res) 105 // assert.Error(err) 106 // e := err.(*MessageError) 107 // assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) 108 // assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) 109 // assert.Equal(originBytes, e.Data) 110 // } 111 112 // func Test_Validate_optional_nontransitive_but_partial(t *testing.T) { 113 // assert := assert.New(t) 114 // message := bgpupdate().Body.(*BGPUpdate) 115 // f := BGP_ATTR_FLAG_OPTIONAL | BGP_ATTR_FLAG_PARTIAL 116 // originBytes := []byte{byte(f), 1, 1, 1} 117 // origin := &PathAttributeOrigin{} 118 // origin.DecodeFromBytes(originBytes) 119 // message.PathAttributes[0] = origin 120 121 // res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,}) 122 // assert.Equal(false, res) 123 // assert.Error(err) 124 // e := err.(*MessageError) 125 // assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) 126 // assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) 127 // assert.Equal(originBytes, e.Data) 128 // } 129 130 // func Test_Validate_flag_mismatch(t *testing.T) { 131 // assert := assert.New(t) 132 // message := bgpupdate().Body.(*BGPUpdate) 133 // f := BGP_ATTR_FLAG_OPTIONAL 134 // // origin needs to be well-known 135 // originBytes := []byte{byte(f), 1, 1, 1} 136 // origin := &PathAttributeOrigin{} 137 // origin.DecodeFromBytes(originBytes) 138 // message.PathAttributes[0] = origin 139 140 // res, err := ValidateUpdateMsg(message, []RouteFamily{RF_IPv4_UC,}) 141 // assert.Equal(false, res) 142 // assert.Error(err) 143 // e := err.(*MessageError) 144 // assert.Equal(BGP_ERROR_UPDATE_MESSAGE_ERROR, e.TypeCode) 145 // assert.Equal(BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, e.SubTypeCode) 146 // assert.Equal(originBytes, e.Data) 147 // } 148 149 func Test_Validate_duplicate_attribute(t *testing.T) { 150 assert := assert.New(t) 151 message := bgpupdate().Body.(*BGPUpdate) 152 // duplicate origin path attribute 153 originBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_ORIGIN]), 1, 1, 1} 154 origin := &PathAttributeOrigin{} 155 origin.DecodeFromBytes(originBytes) 156 message.PathAttributes = append(message.PathAttributes, origin) 157 158 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 159 assert.Equal(false, res) 160 assert.Error(err) 161 e := err.(*MessageError) 162 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 163 assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), e.SubTypeCode) 164 assert.Equal(ERROR_HANDLING_ATTRIBUTE_DISCARD, e.ErrorHandling) 165 assert.Nil(e.Data) 166 } 167 168 func Test_Validate_mandatory_missing(t *testing.T) { 169 assert := assert.New(t) 170 message := bgpupdate().Body.(*BGPUpdate) 171 message.PathAttributes = message.PathAttributes[1:] 172 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 173 assert.Equal(false, res) 174 assert.Error(err) 175 e := err.(*MessageError) 176 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 177 assert.Equal(uint8(BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode) 178 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 179 missing, _ := binary.Uvarint(e.Data) 180 assert.Equal(uint64(1), missing) 181 } 182 183 func Test_Validate_mandatory_missing_nocheck(t *testing.T) { 184 assert := assert.New(t) 185 message := bgpupdate().Body.(*BGPUpdate) 186 message.PathAttributes = message.PathAttributes[1:] 187 message.NLRI = nil 188 189 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 190 assert.Equal(true, res) 191 assert.NoError(err) 192 } 193 194 func Test_Validate_invalid_origin(t *testing.T) { 195 assert := assert.New(t) 196 message := bgpupdate().Body.(*BGPUpdate) 197 // origin needs to be well-known 198 originBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_ORIGIN]), 1, 1, 5} 199 origin := &PathAttributeOrigin{} 200 origin.DecodeFromBytes(originBytes) 201 message.PathAttributes[0] = origin 202 203 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 204 assert.Equal(false, res) 205 assert.Error(err) 206 e := err.(*MessageError) 207 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 208 assert.Equal(uint8(BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE), e.SubTypeCode) 209 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 210 assert.Equal(originBytes, e.Data) 211 } 212 213 func Test_Validate_invalid_nexthop_zero(t *testing.T) { 214 assert := assert.New(t) 215 message := bgpupdate().Body.(*BGPUpdate) 216 217 // invalid nexthop 218 addr := net.ParseIP("0.0.0.1").To4() 219 nexthopBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP]), 3, 4} 220 nexthopBytes = append(nexthopBytes, addr...) 221 nexthop := &PathAttributeNextHop{} 222 nexthop.DecodeFromBytes(nexthopBytes) 223 message.PathAttributes[2] = nexthop 224 225 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 226 assert.Equal(false, res) 227 assert.Error(err) 228 e := err.(*MessageError) 229 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 230 assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode) 231 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 232 assert.Equal(nexthopBytes, e.Data) 233 } 234 235 func Test_Validate_invalid_nexthop_lo(t *testing.T) { 236 assert := assert.New(t) 237 message := bgpupdate().Body.(*BGPUpdate) 238 239 // invalid nexthop 240 addr := net.ParseIP("127.0.0.1").To4() 241 nexthopBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP]), 3, 4} 242 nexthopBytes = append(nexthopBytes, addr...) 243 nexthop := &PathAttributeNextHop{} 244 nexthop.DecodeFromBytes(nexthopBytes) 245 message.PathAttributes[2] = nexthop 246 247 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 248 assert.Equal(false, res) 249 assert.Error(err) 250 e := err.(*MessageError) 251 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 252 assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode) 253 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 254 assert.Equal(nexthopBytes, e.Data) 255 } 256 257 func Test_Validate_invalid_nexthop_de(t *testing.T) { 258 assert := assert.New(t) 259 message := bgpupdate().Body.(*BGPUpdate) 260 261 // invalid nexthop 262 addr := net.ParseIP("224.0.0.1").To4() 263 nexthopBytes := []byte{byte(PathAttrFlags[BGP_ATTR_TYPE_NEXT_HOP]), 3, 4} 264 nexthopBytes = append(nexthopBytes, addr...) 265 nexthop := &PathAttributeNextHop{} 266 nexthop.DecodeFromBytes(nexthopBytes) 267 message.PathAttributes[2] = nexthop 268 269 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 270 assert.Equal(false, res) 271 assert.Error(err) 272 e := err.(*MessageError) 273 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 274 assert.Equal(uint8(BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE), e.SubTypeCode) 275 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 276 assert.Equal(nexthopBytes, e.Data) 277 278 } 279 280 func Test_Validate_unrecognized_well_known(t *testing.T) { 281 282 assert := assert.New(t) 283 message := bgpupdate().Body.(*BGPUpdate) 284 f := BGP_ATTR_FLAG_TRANSITIVE 285 unknownBytes := []byte{byte(f), 30, 1, 1} 286 unknown := &PathAttributeUnknown{} 287 unknown.DecodeFromBytes(unknownBytes) 288 message.PathAttributes = append(message.PathAttributes, unknown) 289 290 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, false, false) 291 assert.Equal(false, res) 292 assert.Error(err) 293 e := err.(*MessageError) 294 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 295 assert.Equal(uint8(BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE), e.SubTypeCode) 296 assert.Equal(ERROR_HANDLING_SESSION_RESET, e.ErrorHandling) 297 assert.Equal(unknownBytes, e.Data) 298 } 299 300 func Test_Validate_aspath(t *testing.T) { 301 assert := assert.New(t) 302 message := bgpupdate().Body.(*BGPUpdate) 303 304 // VALID AS_PATH 305 res, err := ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false) 306 require.NoError(t, err) 307 assert.Equal(true, res) 308 309 // CONFED_SET 310 newAttrs := make([]PathAttributeInterface, 0) 311 attrs := message.PathAttributes 312 for _, attr := range attrs { 313 if _, y := attr.(*PathAttributeAsPath); y { 314 aspath := []AsPathParamInterface{ 315 NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SET, []uint16{65001}), 316 } 317 newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath)) 318 } else { 319 newAttrs = append(newAttrs, attr) 320 } 321 } 322 323 message.PathAttributes = newAttrs 324 res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false) 325 assert.Equal(false, res) 326 assert.Error(err) 327 e := err.(*MessageError) 328 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 329 assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode) 330 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 331 assert.Nil(e.Data) 332 333 res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true) 334 assert.Equal(false, res) 335 assert.Error(err) 336 e = err.(*MessageError) 337 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 338 assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode) 339 assert.Nil(e.Data) 340 341 // CONFED_SEQ 342 newAttrs = make([]PathAttributeInterface, 0) 343 attrs = message.PathAttributes 344 for _, attr := range attrs { 345 if _, y := attr.(*PathAttributeAsPath); y { 346 aspath := []AsPathParamInterface{ 347 NewAsPathParam(BGP_ASPATH_ATTR_TYPE_CONFED_SEQ, []uint16{65001}), 348 } 349 newAttrs = append(newAttrs, NewPathAttributeAsPath(aspath)) 350 } else { 351 newAttrs = append(newAttrs, attr) 352 } 353 } 354 355 message.PathAttributes = newAttrs 356 res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, false) 357 assert.Equal(false, res) 358 assert.Error(err) 359 e = err.(*MessageError) 360 assert.Equal(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), e.TypeCode) 361 assert.Equal(uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH), e.SubTypeCode) 362 assert.Equal(ERROR_HANDLING_TREAT_AS_WITHDRAW, e.ErrorHandling) 363 assert.Nil(e.Data) 364 365 res, err = ValidateUpdateMsg(message, map[RouteFamily]BGPAddPathMode{RF_IPv4_UC: BGP_ADD_PATH_BOTH}, true, true) 366 require.NoError(t, err) 367 assert.Equal(true, res) 368 } 369 370 func Test_Validate_flowspec(t *testing.T) { 371 assert := assert.New(t) 372 cmp := make([]FlowSpecComponentInterface, 0) 373 cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))) 374 cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0"))) 375 item1 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, TCP) 376 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_IP_PROTO, []*FlowSpecComponentItem{item1})) 377 item2 := NewFlowSpecComponentItem(DEC_NUM_OP_GT_EQ, 20) 378 item3 := NewFlowSpecComponentItem(DEC_NUM_OP_AND|DEC_NUM_OP_LT_EQ, 30) 379 item4 := NewFlowSpecComponentItem(DEC_NUM_OP_EQ, 10) 380 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_PORT, []*FlowSpecComponentItem{item2, item3, item4})) 381 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_DST_PORT, []*FlowSpecComponentItem{item2, item3, item4})) 382 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_SRC_PORT, []*FlowSpecComponentItem{item2, item3, item4})) 383 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_TYPE, []*FlowSpecComponentItem{item2, item3, item4})) 384 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_ICMP_CODE, []*FlowSpecComponentItem{item2, item3, item4})) 385 item5 := NewFlowSpecComponentItem(0, TCP_FLAG_ACK) 386 item6 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_AND|BITMASK_FLAG_OP_NOT, TCP_FLAG_URGENT) 387 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_TCP_FLAG, []*FlowSpecComponentItem{item5, item6})) 388 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_PKT_LEN, []*FlowSpecComponentItem{item2, item3, item4})) 389 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_DSCP, []*FlowSpecComponentItem{item2, item3, item4})) 390 isFragment := uint64(0x02) 391 item7 := NewFlowSpecComponentItem(BITMASK_FLAG_OP_MATCH, isFragment) 392 cmp = append(cmp, NewFlowSpecComponent(FLOW_SPEC_TYPE_FRAGMENT, []*FlowSpecComponentItem{item7})) 393 n1 := NewFlowSpecIPv4Unicast(cmp) 394 a := NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1}) 395 m := map[RouteFamily]BGPAddPathMode{RF_FS_IPv4_UC: BGP_ADD_PATH_NONE} 396 _, err := ValidateAttribute(a, m, false, false) 397 assert.Nil(err) 398 399 cmp = make([]FlowSpecComponentInterface, 0) 400 cmp = append(cmp, NewFlowSpecSourcePrefix(NewIPAddrPrefix(24, "10.0.0.0"))) 401 cmp = append(cmp, NewFlowSpecDestinationPrefix(NewIPAddrPrefix(24, "10.0.0.0"))) 402 n1 = NewFlowSpecIPv4Unicast(cmp) 403 a = NewPathAttributeMpReachNLRI("", []AddrPrefixInterface{n1}) 404 // Swaps components order to reproduce the rules order violation. 405 n1.Value[0], n1.Value[1] = n1.Value[1], n1.Value[0] 406 _, err = ValidateAttribute(a, m, false, false) 407 assert.NotNil(err) 408 } 409 410 func TestValidateLargeCommunities(t *testing.T) { 411 assert := assert.New(t) 412 c1, err := ParseLargeCommunity("10:10:10") 413 assert.Nil(err) 414 c2, err := ParseLargeCommunity("10:10:10") 415 assert.Nil(err) 416 c3, err := ParseLargeCommunity("10:10:20") 417 assert.Nil(err) 418 a := NewPathAttributeLargeCommunities([]*LargeCommunity{c1, c2, c3}) 419 assert.True(len(a.Values) == 3) 420 _, err = ValidateAttribute(a, nil, false, false) 421 assert.Nil(err) 422 assert.True(len(a.Values) == 2) 423 }