github.com/osrg/gobgp@v2.0.0+incompatible/pkg/packet/bgp/bgp.go (about) 1 // Copyright (C) 2014 Nippon Telegraph and Telephone Corporation. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 // implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 16 package bgp 17 18 import ( 19 "bytes" 20 "encoding/binary" 21 "encoding/json" 22 "fmt" 23 "math" 24 "net" 25 "reflect" 26 "regexp" 27 "sort" 28 "strconv" 29 "strings" 30 ) 31 32 type MarshallingOption struct { 33 AddPath map[RouteFamily]BGPAddPathMode 34 } 35 36 func IsAddPathEnabled(decode bool, f RouteFamily, options []*MarshallingOption) bool { 37 for _, opt := range options { 38 if opt == nil { 39 continue 40 } 41 if o := opt.AddPath; o != nil { 42 if decode && o[f]&BGP_ADD_PATH_RECEIVE > 0 { 43 return true 44 } else if !decode && o[f]&BGP_ADD_PATH_SEND > 0 { 45 return true 46 } 47 } 48 } 49 return false 50 } 51 52 const ( 53 AFI_IP = 1 54 AFI_IP6 = 2 55 AFI_L2VPN = 25 56 AFI_OPAQUE = 16397 57 ) 58 59 const ( 60 SAFI_UNICAST = 1 61 SAFI_MULTICAST = 2 62 SAFI_MPLS_LABEL = 4 63 SAFI_ENCAPSULATION = 7 64 SAFI_VPLS = 65 65 SAFI_EVPN = 70 66 SAFI_MPLS_VPN = 128 67 SAFI_MPLS_VPN_MULTICAST = 129 68 SAFI_ROUTE_TARGET_CONSTRAINTS = 132 69 SAFI_FLOW_SPEC_UNICAST = 133 70 SAFI_FLOW_SPEC_VPN = 134 71 SAFI_KEY_VALUE = 241 72 ) 73 74 const ( 75 BGP_ORIGIN_ATTR_TYPE_IGP uint8 = 0 76 BGP_ORIGIN_ATTR_TYPE_EGP uint8 = 1 77 BGP_ORIGIN_ATTR_TYPE_INCOMPLETE uint8 = 2 78 ) 79 80 const ( 81 BGP_ASPATH_ATTR_TYPE_SET = 1 82 BGP_ASPATH_ATTR_TYPE_SEQ = 2 83 BGP_ASPATH_ATTR_TYPE_CONFED_SEQ = 3 84 BGP_ASPATH_ATTR_TYPE_CONFED_SET = 4 85 ) 86 87 // RFC7153 5.1. Registries for the "Type" Field 88 // RANGE REGISTRATION PROCEDURES 89 // 0x00-0x3F Transitive First Come First Served 90 // 0x40-0x7F Non-Transitive First Come First Served 91 // 0x80-0x8F Transitive Experimental Use 92 // 0x90-0xBF Transitive Standards Action 93 // 0xC0-0xCF Non-Transitive Experimental Use 94 // 0xD0-0xFF Non-Transitive Standards Action 95 type ExtendedCommunityAttrType uint8 96 97 const ( 98 EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC ExtendedCommunityAttrType = 0x00 99 EC_TYPE_TRANSITIVE_IP6_SPECIFIC ExtendedCommunityAttrType = 0x00 // RFC5701 100 EC_TYPE_TRANSITIVE_IP4_SPECIFIC ExtendedCommunityAttrType = 0x01 101 EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC ExtendedCommunityAttrType = 0x02 102 EC_TYPE_TRANSITIVE_OPAQUE ExtendedCommunityAttrType = 0x03 103 EC_TYPE_TRANSITIVE_QOS_MARKING ExtendedCommunityAttrType = 0x04 104 EC_TYPE_COS_CAPABILITY ExtendedCommunityAttrType = 0x05 105 EC_TYPE_EVPN ExtendedCommunityAttrType = 0x06 106 EC_TYPE_FLOWSPEC_REDIRECT_MIRROR ExtendedCommunityAttrType = 0x08 107 EC_TYPE_NON_TRANSITIVE_TWO_OCTET_AS_SPECIFIC ExtendedCommunityAttrType = 0x40 108 EC_TYPE_NON_TRANSITIVE_IP6_SPECIFIC ExtendedCommunityAttrType = 0x40 // RFC5701 109 EC_TYPE_NON_TRANSITIVE_IP4_SPECIFIC ExtendedCommunityAttrType = 0x41 110 EC_TYPE_NON_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC ExtendedCommunityAttrType = 0x42 111 EC_TYPE_NON_TRANSITIVE_OPAQUE ExtendedCommunityAttrType = 0x43 112 EC_TYPE_NON_TRANSITIVE_QOS_MARKING ExtendedCommunityAttrType = 0x44 113 EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL ExtendedCommunityAttrType = 0x80 114 EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2 ExtendedCommunityAttrType = 0x81 // RFC7674 115 EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3 ExtendedCommunityAttrType = 0x82 // RFC7674 116 ) 117 118 // RFC7153 5.2. Registries for the "Sub-Type" Field 119 // RANGE REGISTRATION PROCEDURES 120 // 0x00-0xBF First Come First Served 121 // 0xC0-0xFF IETF Review 122 type ExtendedCommunityAttrSubType uint8 123 124 const ( 125 EC_SUBTYPE_ROUTE_TARGET ExtendedCommunityAttrSubType = 0x02 // EC_TYPE: 0x00, 0x01, 0x02 126 EC_SUBTYPE_ROUTE_ORIGIN ExtendedCommunityAttrSubType = 0x03 // EC_TYPE: 0x00, 0x01, 0x02 127 EC_SUBTYPE_LINK_BANDWIDTH ExtendedCommunityAttrSubType = 0x04 // EC_TYPE: 0x40 128 EC_SUBTYPE_GENERIC ExtendedCommunityAttrSubType = 0x04 // EC_TYPE: 0x02, 0x42 129 EC_SUBTYPE_OSPF_DOMAIN_ID ExtendedCommunityAttrSubType = 0x05 // EC_TYPE: 0x00, 0x01, 0x02 130 EC_SUBTYPE_OSPF_ROUTE_ID ExtendedCommunityAttrSubType = 0x07 // EC_TYPE: 0x01 131 EC_SUBTYPE_BGP_DATA_COLLECTION ExtendedCommunityAttrSubType = 0x08 // EC_TYPE: 0x00, 0x02 132 EC_SUBTYPE_SOURCE_AS ExtendedCommunityAttrSubType = 0x09 // EC_TYPE: 0x00, 0x02 133 EC_SUBTYPE_L2VPN_ID ExtendedCommunityAttrSubType = 0x0A // EC_TYPE: 0x00, 0x01 134 EC_SUBTYPE_VRF_ROUTE_IMPORT ExtendedCommunityAttrSubType = 0x0B // EC_TYPE: 0x01 135 EC_SUBTYPE_CISCO_VPN_DISTINGUISHER ExtendedCommunityAttrSubType = 0x10 // EC_TYPE: 0x00, 0x01, 0x02 136 137 EC_SUBTYPE_OSPF_ROUTE_TYPE ExtendedCommunityAttrSubType = 0x06 // EC_TYPE: 0x03 138 EC_SUBTYPE_COLOR ExtendedCommunityAttrSubType = 0x0B // EC_TYPE: 0x03 139 EC_SUBTYPE_ENCAPSULATION ExtendedCommunityAttrSubType = 0x0C // EC_TYPE: 0x03 140 EC_SUBTYPE_DEFAULT_GATEWAY ExtendedCommunityAttrSubType = 0x0D // EC_TYPE: 0x03 141 142 EC_SUBTYPE_ORIGIN_VALIDATION ExtendedCommunityAttrSubType = 0x00 // EC_TYPE: 0x43 143 144 EC_SUBTYPE_FLOWSPEC_TRAFFIC_RATE ExtendedCommunityAttrSubType = 0x06 // EC_TYPE: 0x80 145 EC_SUBTYPE_FLOWSPEC_TRAFFIC_ACTION ExtendedCommunityAttrSubType = 0x07 // EC_TYPE: 0x80 146 EC_SUBTYPE_FLOWSPEC_REDIRECT ExtendedCommunityAttrSubType = 0x08 // EC_TYPE: 0x80 147 EC_SUBTYPE_FLOWSPEC_TRAFFIC_REMARK ExtendedCommunityAttrSubType = 0x09 // EC_TYPE: 0x80 148 EC_SUBTYPE_L2_INFO ExtendedCommunityAttrSubType = 0x0A // EC_TYPE: 0x80 149 EC_SUBTYPE_FLOWSPEC_REDIRECT_IP6 ExtendedCommunityAttrSubType = 0x0B // EC_TYPE: 0x80 150 151 EC_SUBTYPE_MAC_MOBILITY ExtendedCommunityAttrSubType = 0x00 // EC_TYPE: 0x06 152 EC_SUBTYPE_ESI_LABEL ExtendedCommunityAttrSubType = 0x01 // EC_TYPE: 0x06 153 EC_SUBTYPE_ES_IMPORT ExtendedCommunityAttrSubType = 0x02 // EC_TYPE: 0x06 154 EC_SUBTYPE_ROUTER_MAC ExtendedCommunityAttrSubType = 0x03 // EC_TYPE: 0x06 155 156 EC_SUBTYPE_UUID_BASED_RT ExtendedCommunityAttrSubType = 0x11 157 ) 158 159 type TunnelType uint16 160 161 const ( 162 TUNNEL_TYPE_L2TP3 TunnelType = 1 163 TUNNEL_TYPE_GRE TunnelType = 2 164 TUNNEL_TYPE_IP_IN_IP TunnelType = 7 165 TUNNEL_TYPE_VXLAN TunnelType = 8 166 TUNNEL_TYPE_NVGRE TunnelType = 9 167 TUNNEL_TYPE_MPLS TunnelType = 10 168 TUNNEL_TYPE_MPLS_IN_GRE TunnelType = 11 169 TUNNEL_TYPE_VXLAN_GRE TunnelType = 12 170 TUNNEL_TYPE_MPLS_IN_UDP TunnelType = 13 171 ) 172 173 func (p TunnelType) String() string { 174 switch p { 175 case TUNNEL_TYPE_L2TP3: 176 return "l2tp3" 177 case TUNNEL_TYPE_GRE: 178 return "gre" 179 case TUNNEL_TYPE_IP_IN_IP: 180 return "ip-in-ip" 181 case TUNNEL_TYPE_VXLAN: 182 return "vxlan" 183 case TUNNEL_TYPE_NVGRE: 184 return "nvgre" 185 case TUNNEL_TYPE_MPLS: 186 return "mpls" 187 case TUNNEL_TYPE_MPLS_IN_GRE: 188 return "mpls-in-gre" 189 case TUNNEL_TYPE_VXLAN_GRE: 190 return "vxlan-gre" 191 case TUNNEL_TYPE_MPLS_IN_UDP: 192 return "mpls-in-udp" 193 default: 194 return fmt.Sprintf("TunnelType(%d)", uint8(p)) 195 } 196 } 197 198 type PmsiTunnelType uint8 199 200 const ( 201 PMSI_TUNNEL_TYPE_NO_TUNNEL PmsiTunnelType = 0 202 PMSI_TUNNEL_TYPE_RSVP_TE_P2MP PmsiTunnelType = 1 203 PMSI_TUNNEL_TYPE_MLDP_P2MP PmsiTunnelType = 2 204 PMSI_TUNNEL_TYPE_PIM_SSM_TREE PmsiTunnelType = 3 205 PMSI_TUNNEL_TYPE_PIM_SM_TREE PmsiTunnelType = 4 206 PMSI_TUNNEL_TYPE_BIDIR_PIM_TREE PmsiTunnelType = 5 207 PMSI_TUNNEL_TYPE_INGRESS_REPL PmsiTunnelType = 6 208 PMSI_TUNNEL_TYPE_MLDP_MP2MP PmsiTunnelType = 7 209 ) 210 211 func (p PmsiTunnelType) String() string { 212 switch p { 213 case PMSI_TUNNEL_TYPE_NO_TUNNEL: 214 return "no-tunnel" 215 case PMSI_TUNNEL_TYPE_RSVP_TE_P2MP: 216 return "rsvp-te-p2mp" 217 case PMSI_TUNNEL_TYPE_MLDP_P2MP: 218 return "mldp-p2mp" 219 case PMSI_TUNNEL_TYPE_PIM_SSM_TREE: 220 return "pim-ssm-tree" 221 case PMSI_TUNNEL_TYPE_PIM_SM_TREE: 222 return "pim-sm-tree" 223 case PMSI_TUNNEL_TYPE_BIDIR_PIM_TREE: 224 return "bidir-pim-tree" 225 case PMSI_TUNNEL_TYPE_INGRESS_REPL: 226 return "ingress-repl" 227 case PMSI_TUNNEL_TYPE_MLDP_MP2MP: 228 return "mldp-mp2mp" 229 default: 230 return fmt.Sprintf("PmsiTunnelType(%d)", uint8(p)) 231 } 232 } 233 234 type EncapSubTLVType uint8 235 236 const ( 237 ENCAP_SUBTLV_TYPE_ENCAPSULATION EncapSubTLVType = 1 238 ENCAP_SUBTLV_TYPE_PROTOCOL EncapSubTLVType = 2 239 ENCAP_SUBTLV_TYPE_COLOR EncapSubTLVType = 4 240 ) 241 242 const ( 243 _ = iota 244 BGP_MSG_OPEN 245 BGP_MSG_UPDATE 246 BGP_MSG_NOTIFICATION 247 BGP_MSG_KEEPALIVE 248 BGP_MSG_ROUTE_REFRESH 249 ) 250 251 const ( 252 BGP_OPT_CAPABILITY = 2 253 ) 254 255 type BGPCapabilityCode uint8 256 257 const ( 258 BGP_CAP_MULTIPROTOCOL BGPCapabilityCode = 1 259 BGP_CAP_ROUTE_REFRESH BGPCapabilityCode = 2 260 BGP_CAP_CARRYING_LABEL_INFO BGPCapabilityCode = 4 261 BGP_CAP_EXTENDED_NEXTHOP BGPCapabilityCode = 5 262 BGP_CAP_GRACEFUL_RESTART BGPCapabilityCode = 64 263 BGP_CAP_FOUR_OCTET_AS_NUMBER BGPCapabilityCode = 65 264 BGP_CAP_ADD_PATH BGPCapabilityCode = 69 265 BGP_CAP_ENHANCED_ROUTE_REFRESH BGPCapabilityCode = 70 266 BGP_CAP_LONG_LIVED_GRACEFUL_RESTART BGPCapabilityCode = 71 267 BGP_CAP_ROUTE_REFRESH_CISCO BGPCapabilityCode = 128 268 ) 269 270 var CapNameMap = map[BGPCapabilityCode]string{ 271 BGP_CAP_MULTIPROTOCOL: "multiprotocol", 272 BGP_CAP_ROUTE_REFRESH: "route-refresh", 273 BGP_CAP_CARRYING_LABEL_INFO: "carrying-label-info", 274 BGP_CAP_GRACEFUL_RESTART: "graceful-restart", 275 BGP_CAP_EXTENDED_NEXTHOP: "extended-nexthop", 276 BGP_CAP_FOUR_OCTET_AS_NUMBER: "4-octet-as", 277 BGP_CAP_ADD_PATH: "add-path", 278 BGP_CAP_ENHANCED_ROUTE_REFRESH: "enhanced-route-refresh", 279 BGP_CAP_ROUTE_REFRESH_CISCO: "cisco-route-refresh", 280 BGP_CAP_LONG_LIVED_GRACEFUL_RESTART: "long-lived-graceful-restart", 281 } 282 283 func (c BGPCapabilityCode) String() string { 284 if n, y := CapNameMap[c]; y { 285 return n 286 } 287 return fmt.Sprintf("UnknownCapability(%d)", c) 288 } 289 290 var ( 291 // Used parsing RouteDistinguisher 292 _regexpRouteDistinguisher = regexp.MustCompile(`^((\d+)\.(\d+)\.(\d+)\.(\d+)|((\d+)\.)?(\d+)|([\w]+:[\w:]*:[\w]+)):(\d+)$`) 293 294 // Used for operator and value for the FlowSpec numeric type 295 // Example: 296 // re.FindStringSubmatch("&==80") 297 // >>> ["&==80" "&" "==" "80"] 298 _regexpFlowSpecNumericType = regexp.MustCompile(`(&?)(==|=|>|>=|<|<=|!|!=|=!)?(\d+|-\d|true|false)`) 299 300 // - "=!" is used in the old style format of "tcp-flags" and "fragment". 301 // - The value field should be one of the followings: 302 // * Decimal value (e.g., 80) 303 // * Combination of the small letters, decimals, "-" and "+" 304 // (e.g., tcp, ipv4, is-fragment+first-fragment) 305 // * Capital letters (e.g., SA) 306 _regexpFlowSpecOperator = regexp.MustCompile(`&|=|>|<|!|[\w\-+]+`) 307 _regexpFlowSpecOperatorValue = regexp.MustCompile(`[\w\-+]+`) 308 309 // Note: "(-*)" and "(.*)" catch the invalid flags 310 // Example: In this case, "Z" is unsupported flag type. 311 // re.FindStringSubmatch("&==-SZU") 312 // >>> ["&==-SZU" "&" "==" "-" "S" "ZU"] 313 _regexpFlowSpecTCPFlag = regexp.MustCompile("(&?)(==|=|!|!=|=!)?(-*)([FSRPAUCE]+)(.*)") 314 315 // Note: "(.*)" catches the invalid flags 316 // re.FindStringSubmatch("&!=+first-fragment+last-fragment+invalid-fragment") 317 // >>> ["&!=+first-fragment+last-fragment+invalid-fragment" "&" "!=" "+first-fragment+last-fragment" "+last-fragment" "+" "last" "+invalid-fragment"] 318 _regexpFlowSpecFragment = regexp.MustCompile(`(&?)(==|=|!|!=|=!)?(((\+)?(dont|is|first|last|not-a)-fragment)+)(.*)`) 319 320 // re.FindStringSubmatch("192.168.0.0/24") 321 // >>> ["192.168.0.0/24" "192.168.0.0" "/24" "24"] 322 // re.FindStringSubmatch("192.168.0.1") 323 // >>> ["192.168.0.1" "192.168.0.1" "" ""] 324 _regexpFindIPv4Prefix = regexp.MustCompile(`^([\d.]+)(/(\d{1,2}))?`) 325 326 // re.FindStringSubmatch("2001:dB8::/64") 327 // >>> ["2001:dB8::/64" "2001:dB8::" "/64" "64" "" ""] 328 // re.FindStringSubmatch("2001:dB8::/64/8") 329 // >>> ["2001:dB8::/64/8" "2001:dB8::" "/64" "64" "/8" "8"] 330 // re.FindStringSubmatch("2001:dB8::1") 331 // >>> ["2001:dB8::1" "2001:dB8::1" "" "" "" ""] 332 _regexpFindIPv6Prefix = regexp.MustCompile(`^([a-fA-F\d:.]+)(/(\d{1,3}))?(/(\d{1,3}))?`) 333 ) 334 335 type ParameterCapabilityInterface interface { 336 DecodeFromBytes([]byte) error 337 Serialize() ([]byte, error) 338 Len() int 339 Code() BGPCapabilityCode 340 } 341 342 type DefaultParameterCapability struct { 343 CapCode BGPCapabilityCode `json:"code"` 344 CapLen uint8 `json:"-"` 345 CapValue []byte `json:"value,omitempty"` 346 } 347 348 func (c *DefaultParameterCapability) Code() BGPCapabilityCode { 349 return c.CapCode 350 } 351 352 func (c *DefaultParameterCapability) DecodeFromBytes(data []byte) error { 353 c.CapCode = BGPCapabilityCode(data[0]) 354 c.CapLen = data[1] 355 if len(data) < 2+int(c.CapLen) { 356 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all OptionParameterCapability bytes available") 357 } 358 if c.CapLen > 0 { 359 c.CapValue = data[2 : 2+c.CapLen] 360 } 361 return nil 362 } 363 364 func (c *DefaultParameterCapability) Serialize() ([]byte, error) { 365 c.CapLen = uint8(len(c.CapValue)) 366 buf := make([]byte, 2) 367 buf[0] = uint8(c.CapCode) 368 buf[1] = c.CapLen 369 buf = append(buf, c.CapValue...) 370 return buf, nil 371 } 372 373 func (c *DefaultParameterCapability) Len() int { 374 return int(c.CapLen + 2) 375 } 376 377 type CapMultiProtocol struct { 378 DefaultParameterCapability 379 CapValue RouteFamily 380 } 381 382 func (c *CapMultiProtocol) DecodeFromBytes(data []byte) error { 383 c.DefaultParameterCapability.DecodeFromBytes(data) 384 data = data[2:] 385 if len(data) < 4 { 386 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityMultiProtocol bytes available") 387 } 388 c.CapValue = AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[0:2]), data[3]) 389 return nil 390 } 391 392 func (c *CapMultiProtocol) Serialize() ([]byte, error) { 393 buf := make([]byte, 4) 394 afi, safi := RouteFamilyToAfiSafi(c.CapValue) 395 binary.BigEndian.PutUint16(buf[0:], afi) 396 buf[3] = safi 397 c.DefaultParameterCapability.CapValue = buf 398 return c.DefaultParameterCapability.Serialize() 399 } 400 401 func (c *CapMultiProtocol) MarshalJSON() ([]byte, error) { 402 return json.Marshal(struct { 403 Code BGPCapabilityCode `json:"code"` 404 Value RouteFamily `json:"value"` 405 }{ 406 Code: c.Code(), 407 Value: c.CapValue, 408 }) 409 } 410 411 func NewCapMultiProtocol(rf RouteFamily) *CapMultiProtocol { 412 return &CapMultiProtocol{ 413 DefaultParameterCapability{ 414 CapCode: BGP_CAP_MULTIPROTOCOL, 415 }, 416 rf, 417 } 418 } 419 420 type CapRouteRefresh struct { 421 DefaultParameterCapability 422 } 423 424 func NewCapRouteRefresh() *CapRouteRefresh { 425 return &CapRouteRefresh{ 426 DefaultParameterCapability{ 427 CapCode: BGP_CAP_ROUTE_REFRESH, 428 }, 429 } 430 } 431 432 type CapCarryingLabelInfo struct { 433 DefaultParameterCapability 434 } 435 436 func NewCapCarryingLabelInfo() *CapCarryingLabelInfo { 437 return &CapCarryingLabelInfo{ 438 DefaultParameterCapability{ 439 CapCode: BGP_CAP_CARRYING_LABEL_INFO, 440 }, 441 } 442 } 443 444 type CapExtendedNexthopTuple struct { 445 NLRIAFI uint16 446 NLRISAFI uint16 447 NexthopAFI uint16 448 } 449 450 func (c *CapExtendedNexthopTuple) MarshalJSON() ([]byte, error) { 451 return json.Marshal(struct { 452 NLRIAddressFamily RouteFamily `json:"nlri_address_family"` 453 NexthopAddressFamily uint16 `json:"nexthop_address_family"` 454 }{ 455 NLRIAddressFamily: AfiSafiToRouteFamily(c.NLRIAFI, uint8(c.NLRISAFI)), 456 NexthopAddressFamily: c.NexthopAFI, 457 }) 458 } 459 460 func NewCapExtendedNexthopTuple(af RouteFamily, nexthop uint16) *CapExtendedNexthopTuple { 461 afi, safi := RouteFamilyToAfiSafi(af) 462 return &CapExtendedNexthopTuple{ 463 NLRIAFI: afi, 464 NLRISAFI: uint16(safi), 465 NexthopAFI: nexthop, 466 } 467 } 468 469 type CapExtendedNexthop struct { 470 DefaultParameterCapability 471 Tuples []*CapExtendedNexthopTuple 472 } 473 474 func (c *CapExtendedNexthop) DecodeFromBytes(data []byte) error { 475 c.DefaultParameterCapability.DecodeFromBytes(data) 476 data = data[2:] 477 if len(data) < 6 { 478 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityExtendedNexthop bytes available") 479 } 480 c.Tuples = []*CapExtendedNexthopTuple{} 481 for len(data) >= 6 { 482 t := &CapExtendedNexthopTuple{ 483 binary.BigEndian.Uint16(data[0:2]), 484 binary.BigEndian.Uint16(data[2:4]), 485 binary.BigEndian.Uint16(data[4:6]), 486 } 487 c.Tuples = append(c.Tuples, t) 488 data = data[6:] 489 } 490 return nil 491 } 492 493 func (c *CapExtendedNexthop) Serialize() ([]byte, error) { 494 buf := make([]byte, len(c.Tuples)*6) 495 for i, t := range c.Tuples { 496 binary.BigEndian.PutUint16(buf[i*6:i*6+2], t.NLRIAFI) 497 binary.BigEndian.PutUint16(buf[i*6+2:i*6+4], t.NLRISAFI) 498 binary.BigEndian.PutUint16(buf[i*6+4:i*6+6], t.NexthopAFI) 499 } 500 c.DefaultParameterCapability.CapValue = buf 501 return c.DefaultParameterCapability.Serialize() 502 } 503 504 func (c *CapExtendedNexthop) MarshalJSON() ([]byte, error) { 505 return json.Marshal(struct { 506 Code BGPCapabilityCode `json:"code"` 507 Tuples []*CapExtendedNexthopTuple `json:"tuples"` 508 }{ 509 Code: c.Code(), 510 Tuples: c.Tuples, 511 }) 512 } 513 514 func NewCapExtendedNexthop(tuples []*CapExtendedNexthopTuple) *CapExtendedNexthop { 515 return &CapExtendedNexthop{ 516 DefaultParameterCapability{ 517 CapCode: BGP_CAP_EXTENDED_NEXTHOP, 518 }, 519 tuples, 520 } 521 } 522 523 type CapGracefulRestartTuple struct { 524 AFI uint16 525 SAFI uint8 526 Flags uint8 527 } 528 529 func (c *CapGracefulRestartTuple) MarshalJSON() ([]byte, error) { 530 return json.Marshal(struct { 531 RouteFamily RouteFamily `json:"route_family"` 532 Flags uint8 `json:"flags"` 533 }{ 534 RouteFamily: AfiSafiToRouteFamily(c.AFI, c.SAFI), 535 Flags: c.Flags, 536 }) 537 } 538 539 func NewCapGracefulRestartTuple(rf RouteFamily, forward bool) *CapGracefulRestartTuple { 540 afi, safi := RouteFamilyToAfiSafi(rf) 541 flags := 0 542 if forward { 543 flags = 0x80 544 } 545 return &CapGracefulRestartTuple{ 546 AFI: afi, 547 SAFI: safi, 548 Flags: uint8(flags), 549 } 550 } 551 552 type CapGracefulRestart struct { 553 DefaultParameterCapability 554 Flags uint8 555 Time uint16 556 Tuples []*CapGracefulRestartTuple 557 } 558 559 func (c *CapGracefulRestart) DecodeFromBytes(data []byte) error { 560 c.DefaultParameterCapability.DecodeFromBytes(data) 561 data = data[2:] 562 if len(data) < 2 { 563 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityGracefulRestart bytes available") 564 } 565 restart := binary.BigEndian.Uint16(data[0:2]) 566 c.Flags = uint8(restart >> 12) 567 c.Time = restart & 0xfff 568 data = data[2:] 569 570 valueLen := int(c.CapLen) - 2 571 572 if valueLen >= 4 && len(data) >= valueLen { 573 c.Tuples = make([]*CapGracefulRestartTuple, 0, valueLen/4) 574 575 for i := valueLen; i >= 4; i -= 4 { 576 t := &CapGracefulRestartTuple{binary.BigEndian.Uint16(data[0:2]), 577 data[2], data[3]} 578 c.Tuples = append(c.Tuples, t) 579 data = data[4:] 580 } 581 } 582 return nil 583 } 584 585 func (c *CapGracefulRestart) Serialize() ([]byte, error) { 586 buf := make([]byte, 2) 587 binary.BigEndian.PutUint16(buf[0:], uint16(c.Flags)<<12|c.Time) 588 for _, t := range c.Tuples { 589 tbuf := make([]byte, 4) 590 binary.BigEndian.PutUint16(tbuf[0:2], t.AFI) 591 tbuf[2] = t.SAFI 592 tbuf[3] = t.Flags 593 buf = append(buf, tbuf...) 594 } 595 c.DefaultParameterCapability.CapValue = buf 596 return c.DefaultParameterCapability.Serialize() 597 } 598 599 func (c *CapGracefulRestart) MarshalJSON() ([]byte, error) { 600 return json.Marshal(struct { 601 Code BGPCapabilityCode `json:"code"` 602 Flags uint8 `json:"flags"` 603 Time uint16 `json:"time"` 604 Tuples []*CapGracefulRestartTuple `json:"tuples"` 605 }{ 606 Code: c.Code(), 607 Flags: c.Flags, 608 Time: c.Time, 609 Tuples: c.Tuples, 610 }) 611 } 612 613 func NewCapGracefulRestart(restarting, notification bool, time uint16, tuples []*CapGracefulRestartTuple) *CapGracefulRestart { 614 flags := 0 615 if restarting { 616 flags = 0x08 617 } 618 if notification { 619 flags |= 0x04 620 } 621 return &CapGracefulRestart{ 622 DefaultParameterCapability: DefaultParameterCapability{ 623 CapCode: BGP_CAP_GRACEFUL_RESTART, 624 }, 625 Flags: uint8(flags), 626 Time: time, 627 Tuples: tuples, 628 } 629 } 630 631 type CapFourOctetASNumber struct { 632 DefaultParameterCapability 633 CapValue uint32 634 } 635 636 func (c *CapFourOctetASNumber) DecodeFromBytes(data []byte) error { 637 c.DefaultParameterCapability.DecodeFromBytes(data) 638 data = data[2:] 639 if len(data) < 4 { 640 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityFourOctetASNumber bytes available") 641 } 642 c.CapValue = binary.BigEndian.Uint32(data[0:4]) 643 return nil 644 } 645 646 func (c *CapFourOctetASNumber) Serialize() ([]byte, error) { 647 buf := make([]byte, 4) 648 binary.BigEndian.PutUint32(buf, c.CapValue) 649 c.DefaultParameterCapability.CapValue = buf 650 return c.DefaultParameterCapability.Serialize() 651 } 652 653 func (c *CapFourOctetASNumber) MarshalJSON() ([]byte, error) { 654 return json.Marshal(struct { 655 Code BGPCapabilityCode `json:"code"` 656 Value uint32 `json:"value"` 657 }{ 658 Code: c.Code(), 659 Value: c.CapValue, 660 }) 661 } 662 663 func NewCapFourOctetASNumber(asnum uint32) *CapFourOctetASNumber { 664 return &CapFourOctetASNumber{ 665 DefaultParameterCapability{ 666 CapCode: BGP_CAP_FOUR_OCTET_AS_NUMBER, 667 }, 668 asnum, 669 } 670 } 671 672 type BGPAddPathMode uint8 673 674 const ( 675 BGP_ADD_PATH_NONE BGPAddPathMode = iota 676 BGP_ADD_PATH_RECEIVE 677 BGP_ADD_PATH_SEND 678 BGP_ADD_PATH_BOTH 679 ) 680 681 func (m BGPAddPathMode) String() string { 682 switch m { 683 case BGP_ADD_PATH_NONE: 684 return "none" 685 case BGP_ADD_PATH_RECEIVE: 686 return "receive" 687 case BGP_ADD_PATH_SEND: 688 return "send" 689 case BGP_ADD_PATH_BOTH: 690 return "receive/send" 691 default: 692 return fmt.Sprintf("unknown(%d)", m) 693 } 694 } 695 696 type CapAddPathTuple struct { 697 RouteFamily RouteFamily 698 Mode BGPAddPathMode 699 } 700 701 func (t *CapAddPathTuple) MarshalJSON() ([]byte, error) { 702 return json.Marshal(struct { 703 RouteFamily RouteFamily `json:"family"` 704 Mode uint8 `json:"mode"` 705 }{ 706 RouteFamily: t.RouteFamily, 707 Mode: uint8(t.Mode), 708 }) 709 } 710 711 func NewCapAddPathTuple(family RouteFamily, mode BGPAddPathMode) *CapAddPathTuple { 712 return &CapAddPathTuple{ 713 RouteFamily: family, 714 Mode: mode, 715 } 716 } 717 718 type CapAddPath struct { 719 DefaultParameterCapability 720 Tuples []*CapAddPathTuple 721 } 722 723 func (c *CapAddPath) DecodeFromBytes(data []byte) error { 724 c.DefaultParameterCapability.DecodeFromBytes(data) 725 data = data[2:] 726 if len(data) < 4 { 727 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all CapabilityAddPath bytes available") 728 } 729 c.Tuples = []*CapAddPathTuple{} 730 for len(data) >= 4 { 731 t := &CapAddPathTuple{ 732 RouteFamily: AfiSafiToRouteFamily(binary.BigEndian.Uint16(data[:2]), data[2]), 733 Mode: BGPAddPathMode(data[3]), 734 } 735 c.Tuples = append(c.Tuples, t) 736 data = data[4:] 737 } 738 return nil 739 } 740 741 func (c *CapAddPath) Serialize() ([]byte, error) { 742 buf := make([]byte, len(c.Tuples)*4) 743 for i, t := range c.Tuples { 744 afi, safi := RouteFamilyToAfiSafi(t.RouteFamily) 745 binary.BigEndian.PutUint16(buf[i*4:i*4+2], afi) 746 buf[i*4+2] = safi 747 buf[i*4+3] = byte(t.Mode) 748 } 749 c.DefaultParameterCapability.CapValue = buf 750 return c.DefaultParameterCapability.Serialize() 751 } 752 753 func (c *CapAddPath) MarshalJSON() ([]byte, error) { 754 return json.Marshal(struct { 755 Code BGPCapabilityCode `json:"code"` 756 Tuples []*CapAddPathTuple `json:"tuples"` 757 }{ 758 Code: c.Code(), 759 Tuples: c.Tuples, 760 }) 761 } 762 763 func NewCapAddPath(tuples []*CapAddPathTuple) *CapAddPath { 764 return &CapAddPath{ 765 DefaultParameterCapability: DefaultParameterCapability{ 766 CapCode: BGP_CAP_ADD_PATH, 767 }, 768 Tuples: tuples, 769 } 770 } 771 772 type CapEnhancedRouteRefresh struct { 773 DefaultParameterCapability 774 } 775 776 func NewCapEnhancedRouteRefresh() *CapEnhancedRouteRefresh { 777 return &CapEnhancedRouteRefresh{ 778 DefaultParameterCapability{ 779 CapCode: BGP_CAP_ENHANCED_ROUTE_REFRESH, 780 }, 781 } 782 } 783 784 type CapRouteRefreshCisco struct { 785 DefaultParameterCapability 786 } 787 788 func NewCapRouteRefreshCisco() *CapRouteRefreshCisco { 789 return &CapRouteRefreshCisco{ 790 DefaultParameterCapability{ 791 CapCode: BGP_CAP_ROUTE_REFRESH_CISCO, 792 }, 793 } 794 } 795 796 type CapLongLivedGracefulRestartTuple struct { 797 AFI uint16 798 SAFI uint8 799 Flags uint8 800 RestartTime uint32 801 } 802 803 func (c *CapLongLivedGracefulRestartTuple) MarshalJSON() ([]byte, error) { 804 return json.Marshal(struct { 805 RouteFamily RouteFamily `json:"route_family"` 806 Flags uint8 `json:"flags"` 807 RestartTime uint32 `json:"restart_time"` 808 }{ 809 RouteFamily: AfiSafiToRouteFamily(c.AFI, c.SAFI), 810 Flags: c.Flags, 811 RestartTime: c.RestartTime, 812 }) 813 } 814 815 func NewCapLongLivedGracefulRestartTuple(rf RouteFamily, forward bool, restartTime uint32) *CapLongLivedGracefulRestartTuple { 816 afi, safi := RouteFamilyToAfiSafi(rf) 817 flags := 0 818 if forward { 819 flags = 0x80 820 } 821 return &CapLongLivedGracefulRestartTuple{ 822 AFI: afi, 823 SAFI: safi, 824 Flags: uint8(flags), 825 RestartTime: restartTime, 826 } 827 } 828 829 type CapLongLivedGracefulRestart struct { 830 DefaultParameterCapability 831 Tuples []*CapLongLivedGracefulRestartTuple 832 } 833 834 func (c *CapLongLivedGracefulRestart) DecodeFromBytes(data []byte) error { 835 c.DefaultParameterCapability.DecodeFromBytes(data) 836 data = data[2:] 837 838 valueLen := int(c.CapLen) 839 if valueLen%7 != 0 || len(data) < valueLen { 840 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "invalid length of long lived graceful restart capablity") 841 } 842 for i := valueLen; i >= 7; i -= 7 { 843 t := &CapLongLivedGracefulRestartTuple{ 844 binary.BigEndian.Uint16(data), 845 data[2], 846 data[3], 847 uint32(data[4])<<16 | uint32(data[5])<<8 | uint32(data[6]), 848 } 849 c.Tuples = append(c.Tuples, t) 850 data = data[7:] 851 } 852 return nil 853 } 854 855 func (c *CapLongLivedGracefulRestart) Serialize() ([]byte, error) { 856 buf := make([]byte, 7*len(c.Tuples)) 857 for idx, t := range c.Tuples { 858 binary.BigEndian.PutUint16(buf[idx*7:], t.AFI) 859 buf[idx*7+2] = t.SAFI 860 buf[idx*7+3] = t.Flags 861 buf[idx*7+4] = uint8((t.RestartTime >> 16) & 0xff) 862 buf[idx*7+5] = uint8((t.RestartTime >> 8) & 0xff) 863 buf[idx*7+6] = uint8(t.RestartTime & 0xff) 864 } 865 c.DefaultParameterCapability.CapValue = buf 866 return c.DefaultParameterCapability.Serialize() 867 } 868 869 func (c *CapLongLivedGracefulRestart) MarshalJSON() ([]byte, error) { 870 return json.Marshal(struct { 871 Code BGPCapabilityCode `json:"code"` 872 Tuples []*CapLongLivedGracefulRestartTuple `json:"tuples"` 873 }{ 874 Code: c.Code(), 875 Tuples: c.Tuples, 876 }) 877 } 878 879 func NewCapLongLivedGracefulRestart(tuples []*CapLongLivedGracefulRestartTuple) *CapLongLivedGracefulRestart { 880 return &CapLongLivedGracefulRestart{ 881 DefaultParameterCapability: DefaultParameterCapability{ 882 CapCode: BGP_CAP_LONG_LIVED_GRACEFUL_RESTART, 883 }, 884 Tuples: tuples, 885 } 886 } 887 888 type CapUnknown struct { 889 DefaultParameterCapability 890 } 891 892 func NewCapUnknown(code BGPCapabilityCode, value []byte) *CapUnknown { 893 return &CapUnknown{ 894 DefaultParameterCapability{ 895 CapCode: code, 896 CapValue: value, 897 }, 898 } 899 } 900 901 func DecodeCapability(data []byte) (ParameterCapabilityInterface, error) { 902 if len(data) < 2 { 903 return nil, NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY, nil, "Not all ParameterCapability bytes available") 904 } 905 var c ParameterCapabilityInterface 906 switch BGPCapabilityCode(data[0]) { 907 case BGP_CAP_MULTIPROTOCOL: 908 c = &CapMultiProtocol{} 909 case BGP_CAP_ROUTE_REFRESH: 910 c = &CapRouteRefresh{} 911 case BGP_CAP_CARRYING_LABEL_INFO: 912 c = &CapCarryingLabelInfo{} 913 case BGP_CAP_EXTENDED_NEXTHOP: 914 c = &CapExtendedNexthop{} 915 case BGP_CAP_GRACEFUL_RESTART: 916 c = &CapGracefulRestart{} 917 case BGP_CAP_FOUR_OCTET_AS_NUMBER: 918 c = &CapFourOctetASNumber{} 919 case BGP_CAP_ADD_PATH: 920 c = &CapAddPath{} 921 case BGP_CAP_ENHANCED_ROUTE_REFRESH: 922 c = &CapEnhancedRouteRefresh{} 923 case BGP_CAP_ROUTE_REFRESH_CISCO: 924 c = &CapRouteRefreshCisco{} 925 case BGP_CAP_LONG_LIVED_GRACEFUL_RESTART: 926 c = &CapLongLivedGracefulRestart{} 927 default: 928 c = &CapUnknown{} 929 } 930 err := c.DecodeFromBytes(data) 931 return c, err 932 } 933 934 type OptionParameterInterface interface { 935 Serialize() ([]byte, error) 936 } 937 938 type OptionParameterCapability struct { 939 ParamType uint8 940 ParamLen uint8 941 Capability []ParameterCapabilityInterface 942 } 943 944 func (o *OptionParameterCapability) DecodeFromBytes(data []byte) error { 945 if uint8(len(data)) < o.ParamLen { 946 return NewMessageError(BGP_ERROR_OPEN_MESSAGE_ERROR, BGP_ERROR_SUB_UNSUPPORTED_OPTIONAL_PARAMETER, nil, "Not all OptionParameterCapability bytes available") 947 } 948 for len(data) >= 2 { 949 c, err := DecodeCapability(data) 950 if err != nil { 951 return err 952 } 953 o.Capability = append(o.Capability, c) 954 data = data[c.Len():] 955 } 956 return nil 957 } 958 959 func (o *OptionParameterCapability) Serialize() ([]byte, error) { 960 buf := make([]byte, 2) 961 buf[0] = o.ParamType 962 for _, p := range o.Capability { 963 pbuf, err := p.Serialize() 964 if err != nil { 965 return nil, err 966 } 967 buf = append(buf, pbuf...) 968 } 969 o.ParamLen = uint8(len(buf) - 2) 970 buf[1] = o.ParamLen 971 return buf, nil 972 } 973 974 func NewOptionParameterCapability(capability []ParameterCapabilityInterface) *OptionParameterCapability { 975 return &OptionParameterCapability{ 976 ParamType: BGP_OPT_CAPABILITY, 977 Capability: capability, 978 } 979 } 980 981 type OptionParameterUnknown struct { 982 ParamType uint8 983 ParamLen uint8 984 Value []byte 985 } 986 987 func (o *OptionParameterUnknown) Serialize() ([]byte, error) { 988 buf := make([]byte, 2) 989 buf[0] = o.ParamType 990 if o.ParamLen == 0 { 991 o.ParamLen = uint8(len(o.Value)) 992 } 993 buf[1] = o.ParamLen 994 return append(buf, o.Value...), nil 995 } 996 997 type BGPOpen struct { 998 Version uint8 999 MyAS uint16 1000 HoldTime uint16 1001 ID net.IP 1002 OptParamLen uint8 1003 OptParams []OptionParameterInterface 1004 } 1005 1006 func (msg *BGPOpen) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 1007 if len(data) < 10 { 1008 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Not all BGP Open message bytes available") 1009 } 1010 msg.Version = data[0] 1011 msg.MyAS = binary.BigEndian.Uint16(data[1:3]) 1012 msg.HoldTime = binary.BigEndian.Uint16(data[3:5]) 1013 msg.ID = net.IP(data[5:9]).To4() 1014 msg.OptParamLen = data[9] 1015 data = data[10:] 1016 if len(data) < int(msg.OptParamLen) { 1017 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Not all BGP Open message bytes available") 1018 } 1019 1020 msg.OptParams = []OptionParameterInterface{} 1021 for rest := msg.OptParamLen; rest > 0; { 1022 if rest < 2 { 1023 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Malformed BGP Open message") 1024 } 1025 paramtype := data[0] 1026 paramlen := data[1] 1027 if rest < paramlen+2 { 1028 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Malformed BGP Open message") 1029 } 1030 rest -= paramlen + 2 1031 1032 if paramtype == BGP_OPT_CAPABILITY { 1033 p := &OptionParameterCapability{} 1034 p.ParamType = paramtype 1035 p.ParamLen = paramlen 1036 p.DecodeFromBytes(data[2 : 2+paramlen]) 1037 msg.OptParams = append(msg.OptParams, p) 1038 } else { 1039 p := &OptionParameterUnknown{} 1040 p.ParamType = paramtype 1041 p.ParamLen = paramlen 1042 p.Value = data[2 : 2+paramlen] 1043 msg.OptParams = append(msg.OptParams, p) 1044 } 1045 data = data[2+paramlen:] 1046 } 1047 return nil 1048 } 1049 1050 func (msg *BGPOpen) Serialize(options ...*MarshallingOption) ([]byte, error) { 1051 buf := make([]byte, 10) 1052 buf[0] = msg.Version 1053 binary.BigEndian.PutUint16(buf[1:3], msg.MyAS) 1054 binary.BigEndian.PutUint16(buf[3:5], msg.HoldTime) 1055 copy(buf[5:9], msg.ID.To4()) 1056 pbuf := make([]byte, 0) 1057 for _, p := range msg.OptParams { 1058 onepbuf, err := p.Serialize() 1059 if err != nil { 1060 return nil, err 1061 } 1062 pbuf = append(pbuf, onepbuf...) 1063 } 1064 msg.OptParamLen = uint8(len(pbuf)) 1065 buf[9] = msg.OptParamLen 1066 return append(buf, pbuf...), nil 1067 } 1068 1069 func NewBGPOpenMessage(myas uint16, holdtime uint16, id string, optparams []OptionParameterInterface) *BGPMessage { 1070 return &BGPMessage{ 1071 Header: BGPHeader{Type: BGP_MSG_OPEN}, 1072 Body: &BGPOpen{4, myas, holdtime, net.ParseIP(id).To4(), 0, optparams}, 1073 } 1074 } 1075 1076 type AddrPrefixInterface interface { 1077 DecodeFromBytes([]byte, ...*MarshallingOption) error 1078 Serialize(...*MarshallingOption) ([]byte, error) 1079 AFI() uint16 1080 SAFI() uint8 1081 Len(...*MarshallingOption) int 1082 String() string 1083 MarshalJSON() ([]byte, error) 1084 // Create a flat map to describe attributes and their 1085 // values. This can be used to create structured outputs. 1086 Flat() map[string]string 1087 PathIdentifier() uint32 1088 SetPathIdentifier(uint32) 1089 PathLocalIdentifier() uint32 1090 SetPathLocalIdentifier(uint32) 1091 } 1092 1093 func LabelString(nlri AddrPrefixInterface) string { 1094 label := "" 1095 switch n := nlri.(type) { 1096 case *LabeledIPAddrPrefix: 1097 label = n.Labels.String() 1098 case *LabeledIPv6AddrPrefix: 1099 label = n.Labels.String() 1100 case *LabeledVPNIPAddrPrefix: 1101 label = n.Labels.String() 1102 case *LabeledVPNIPv6AddrPrefix: 1103 label = n.Labels.String() 1104 case *EVPNNLRI: 1105 switch route := n.RouteTypeData.(type) { 1106 case *EVPNEthernetAutoDiscoveryRoute: 1107 label = fmt.Sprintf("[%d]", route.Label) 1108 case *EVPNMacIPAdvertisementRoute: 1109 var l []string 1110 for _, i := range route.Labels { 1111 l = append(l, strconv.Itoa(int(i))) 1112 } 1113 label = fmt.Sprintf("[%s]", strings.Join(l, ",")) 1114 case *EVPNIPPrefixRoute: 1115 label = fmt.Sprintf("[%d]", route.Label) 1116 } 1117 } 1118 return label 1119 } 1120 1121 type PrefixDefault struct { 1122 id uint32 1123 localId uint32 1124 } 1125 1126 func (p *PrefixDefault) PathIdentifier() uint32 { 1127 return p.id 1128 } 1129 1130 func (p *PrefixDefault) SetPathIdentifier(id uint32) { 1131 p.id = id 1132 } 1133 1134 func (p *PrefixDefault) PathLocalIdentifier() uint32 { 1135 return p.localId 1136 } 1137 1138 func (p *PrefixDefault) SetPathLocalIdentifier(id uint32) { 1139 p.localId = id 1140 } 1141 1142 func (p *PrefixDefault) decodePathIdentifier(data []byte) ([]byte, error) { 1143 if len(data) < 4 { 1144 code := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 1145 subcode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 1146 return nil, NewMessageError(code, subcode, nil, "prefix misses path identifier field") 1147 } 1148 p.SetPathIdentifier(binary.BigEndian.Uint32(data[:4])) 1149 return data[4:], nil 1150 } 1151 1152 func (p *PrefixDefault) serializeIdentifier() ([]byte, error) { 1153 buf := make([]byte, 4) 1154 binary.BigEndian.PutUint32(buf, p.PathLocalIdentifier()) 1155 return buf, nil 1156 } 1157 1158 type IPAddrPrefixDefault struct { 1159 PrefixDefault 1160 Length uint8 1161 Prefix net.IP 1162 } 1163 1164 func (r *IPAddrPrefixDefault) decodePrefix(data []byte, bitlen uint8, addrlen uint8) error { 1165 bytelen := (int(bitlen) + 7) / 8 1166 if len(data) < bytelen { 1167 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 1168 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 1169 return NewMessageError(eCode, eSubCode, nil, "network bytes is short") 1170 } 1171 b := make([]byte, addrlen) 1172 copy(b, data[:bytelen]) 1173 // clear trailing bits in the last byte. rfc doesn't require 1174 // this but some bgp implementations need this... 1175 rem := bitlen % 8 1176 if rem != 0 { 1177 mask := 0xff00 >> rem 1178 lastByte := b[bytelen-1] & byte(mask) 1179 b[bytelen-1] = lastByte 1180 } 1181 r.Prefix = b 1182 return nil 1183 } 1184 1185 func (r *IPAddrPrefixDefault) serializePrefix(bitLen uint8) ([]byte, error) { 1186 byteLen := (int(bitLen) + 7) / 8 1187 buf := make([]byte, byteLen) 1188 copy(buf, r.Prefix) 1189 return buf, nil 1190 } 1191 1192 func (r *IPAddrPrefixDefault) String() string { 1193 return fmt.Sprintf("%s/%d", r.Prefix.String(), r.Length) 1194 } 1195 1196 func (r *IPAddrPrefixDefault) MarshalJSON() ([]byte, error) { 1197 return json.Marshal(struct { 1198 Prefix string `json:"prefix"` 1199 }{ 1200 Prefix: r.String(), 1201 }) 1202 } 1203 1204 type IPAddrPrefix struct { 1205 IPAddrPrefixDefault 1206 addrlen uint8 1207 } 1208 1209 func (r *IPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 1210 if r.addrlen == 0 { 1211 r.addrlen = 4 1212 } 1213 f := RF_IPv4_UC 1214 if r.addrlen == 16 { 1215 f = RF_IPv6_UC 1216 } 1217 if IsAddPathEnabled(true, f, options) { 1218 var err error 1219 data, err = r.decodePathIdentifier(data) 1220 if err != nil { 1221 return err 1222 } 1223 } 1224 if len(data) < 1 { 1225 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 1226 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 1227 return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") 1228 } 1229 r.Length = data[0] 1230 return r.decodePrefix(data[1:], r.Length, r.addrlen) 1231 } 1232 1233 func (r *IPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { 1234 f := RF_IPv4_UC 1235 if r.addrlen == 16 { 1236 f = RF_IPv6_UC 1237 } 1238 var buf []byte 1239 if IsAddPathEnabled(false, f, options) { 1240 var err error 1241 buf, err = r.serializeIdentifier() 1242 if err != nil { 1243 return nil, err 1244 } 1245 } 1246 buf = append(buf, r.Length) 1247 pbuf, err := r.serializePrefix(r.Length) 1248 if err != nil { 1249 return nil, err 1250 } 1251 return append(buf, pbuf...), nil 1252 } 1253 1254 func (r *IPAddrPrefix) AFI() uint16 { 1255 return AFI_IP 1256 } 1257 1258 func (r *IPAddrPrefix) SAFI() uint8 { 1259 return SAFI_UNICAST 1260 } 1261 1262 func (r *IPAddrPrefix) Len(options ...*MarshallingOption) int { 1263 return 1 + ((int(r.Length) + 7) / 8) 1264 } 1265 1266 func NewIPAddrPrefix(length uint8, prefix string) *IPAddrPrefix { 1267 p := &IPAddrPrefix{ 1268 IPAddrPrefixDefault{ 1269 Length: length, 1270 }, 1271 4, 1272 } 1273 p.IPAddrPrefixDefault.decodePrefix(net.ParseIP(prefix).To4(), length, 4) 1274 return p 1275 } 1276 1277 func isIPv4MappedIPv6(ip net.IP) bool { 1278 return len(ip) == net.IPv6len && ip.To4() != nil 1279 } 1280 1281 type IPv6AddrPrefix struct { 1282 IPAddrPrefix 1283 } 1284 1285 func (r *IPv6AddrPrefix) AFI() uint16 { 1286 return AFI_IP6 1287 } 1288 1289 func (r *IPv6AddrPrefix) String() string { 1290 prefix := r.Prefix.String() 1291 if isIPv4MappedIPv6(r.Prefix) { 1292 prefix = "::ffff:" + prefix 1293 } 1294 return fmt.Sprintf("%s/%d", prefix, r.Length) 1295 } 1296 1297 func NewIPv6AddrPrefix(length uint8, prefix string) *IPv6AddrPrefix { 1298 p := &IPv6AddrPrefix{ 1299 IPAddrPrefix{ 1300 IPAddrPrefixDefault{ 1301 Length: length, 1302 }, 1303 16, 1304 }, 1305 } 1306 p.IPAddrPrefixDefault.decodePrefix(net.ParseIP(prefix), length, 16) 1307 return p 1308 } 1309 1310 const ( 1311 BGP_RD_TWO_OCTET_AS = iota 1312 BGP_RD_IPV4_ADDRESS 1313 BGP_RD_FOUR_OCTET_AS 1314 ) 1315 1316 type RouteDistinguisherInterface interface { 1317 DecodeFromBytes([]byte) error 1318 Serialize() ([]byte, error) 1319 Len() int 1320 String() string 1321 MarshalJSON() ([]byte, error) 1322 } 1323 1324 type DefaultRouteDistinguisher struct { 1325 Type uint16 1326 } 1327 1328 func (rd *DefaultRouteDistinguisher) serialize(value []byte) ([]byte, error) { 1329 buf := make([]byte, 8) 1330 binary.BigEndian.PutUint16(buf, rd.Type) 1331 copy(buf[2:], value) 1332 return buf, nil 1333 } 1334 1335 func (rd *DefaultRouteDistinguisher) Len() int { 1336 return 8 1337 } 1338 1339 type RouteDistinguisherTwoOctetAS struct { 1340 DefaultRouteDistinguisher 1341 Admin uint16 1342 Assigned uint32 1343 } 1344 1345 func (rd *RouteDistinguisherTwoOctetAS) DecodeFromBytes(data []byte) error { 1346 rd.Admin = binary.BigEndian.Uint16(data[0:2]) 1347 rd.Assigned = binary.BigEndian.Uint32(data[2:6]) 1348 return nil 1349 } 1350 1351 func (rd *RouteDistinguisherTwoOctetAS) Serialize() ([]byte, error) { 1352 buf := make([]byte, 6) 1353 binary.BigEndian.PutUint16(buf[0:2], rd.Admin) 1354 binary.BigEndian.PutUint32(buf[2:6], rd.Assigned) 1355 return rd.serialize(buf) 1356 } 1357 1358 func (rd *RouteDistinguisherTwoOctetAS) String() string { 1359 return fmt.Sprintf("%d:%d", rd.Admin, rd.Assigned) 1360 } 1361 1362 func (rd *RouteDistinguisherTwoOctetAS) MarshalJSON() ([]byte, error) { 1363 return json.Marshal(struct { 1364 Type uint16 `json:"type"` 1365 Admin uint16 `json:"admin"` 1366 Assigned uint32 `json:"assigned"` 1367 }{ 1368 Type: rd.Type, 1369 Admin: rd.Admin, 1370 Assigned: rd.Assigned, 1371 }) 1372 } 1373 1374 func NewRouteDistinguisherTwoOctetAS(admin uint16, assigned uint32) *RouteDistinguisherTwoOctetAS { 1375 return &RouteDistinguisherTwoOctetAS{ 1376 DefaultRouteDistinguisher: DefaultRouteDistinguisher{ 1377 Type: BGP_RD_TWO_OCTET_AS, 1378 }, 1379 Admin: admin, 1380 Assigned: assigned, 1381 } 1382 } 1383 1384 type RouteDistinguisherIPAddressAS struct { 1385 DefaultRouteDistinguisher 1386 Admin net.IP 1387 Assigned uint16 1388 } 1389 1390 func (rd *RouteDistinguisherIPAddressAS) DecodeFromBytes(data []byte) error { 1391 rd.Admin = data[0:4] 1392 rd.Assigned = binary.BigEndian.Uint16(data[4:6]) 1393 return nil 1394 } 1395 1396 func (rd *RouteDistinguisherIPAddressAS) Serialize() ([]byte, error) { 1397 buf := make([]byte, 6) 1398 copy(buf[0:4], rd.Admin.To4()) 1399 binary.BigEndian.PutUint16(buf[4:6], rd.Assigned) 1400 return rd.serialize(buf) 1401 } 1402 1403 func (rd *RouteDistinguisherIPAddressAS) String() string { 1404 return fmt.Sprintf("%s:%d", rd.Admin.String(), rd.Assigned) 1405 } 1406 1407 func (rd *RouteDistinguisherIPAddressAS) MarshalJSON() ([]byte, error) { 1408 return json.Marshal(struct { 1409 Type uint16 `json:"type"` 1410 Admin string `json:"admin"` 1411 Assigned uint16 `json:"assigned"` 1412 }{ 1413 Type: rd.Type, 1414 Admin: rd.Admin.String(), 1415 Assigned: rd.Assigned, 1416 }) 1417 } 1418 1419 func NewRouteDistinguisherIPAddressAS(admin string, assigned uint16) *RouteDistinguisherIPAddressAS { 1420 return &RouteDistinguisherIPAddressAS{ 1421 DefaultRouteDistinguisher: DefaultRouteDistinguisher{ 1422 Type: BGP_RD_IPV4_ADDRESS, 1423 }, 1424 Admin: net.ParseIP(admin).To4(), 1425 Assigned: assigned, 1426 } 1427 } 1428 1429 type RouteDistinguisherFourOctetAS struct { 1430 DefaultRouteDistinguisher 1431 Admin uint32 1432 Assigned uint16 1433 } 1434 1435 func (rd *RouteDistinguisherFourOctetAS) DecodeFromBytes(data []byte) error { 1436 rd.Admin = binary.BigEndian.Uint32(data[0:4]) 1437 rd.Assigned = binary.BigEndian.Uint16(data[4:6]) 1438 return nil 1439 } 1440 1441 func (rd *RouteDistinguisherFourOctetAS) Serialize() ([]byte, error) { 1442 buf := make([]byte, 6) 1443 binary.BigEndian.PutUint32(buf[0:4], rd.Admin) 1444 binary.BigEndian.PutUint16(buf[4:6], rd.Assigned) 1445 return rd.serialize(buf) 1446 } 1447 1448 func (rd *RouteDistinguisherFourOctetAS) String() string { 1449 fst := rd.Admin >> 16 & 0xffff 1450 snd := rd.Admin & 0xffff 1451 return fmt.Sprintf("%d.%d:%d", fst, snd, rd.Assigned) 1452 } 1453 1454 func (rd *RouteDistinguisherFourOctetAS) MarshalJSON() ([]byte, error) { 1455 return json.Marshal(struct { 1456 Type uint16 `json:"type"` 1457 Admin uint32 `json:"admin"` 1458 Assigned uint16 `json:"assigned"` 1459 }{ 1460 Type: rd.Type, 1461 Admin: rd.Admin, 1462 Assigned: rd.Assigned, 1463 }) 1464 } 1465 1466 func NewRouteDistinguisherFourOctetAS(admin uint32, assigned uint16) *RouteDistinguisherFourOctetAS { 1467 return &RouteDistinguisherFourOctetAS{ 1468 DefaultRouteDistinguisher: DefaultRouteDistinguisher{ 1469 Type: BGP_RD_FOUR_OCTET_AS, 1470 }, 1471 Admin: admin, 1472 Assigned: assigned, 1473 } 1474 } 1475 1476 type RouteDistinguisherUnknown struct { 1477 DefaultRouteDistinguisher 1478 Value []byte 1479 } 1480 1481 func (rd *RouteDistinguisherUnknown) DecodeFromBytes(data []byte) error { 1482 rd.Value = data[0:6] 1483 return nil 1484 } 1485 1486 func (rd *RouteDistinguisherUnknown) Serialize() ([]byte, error) { 1487 return rd.DefaultRouteDistinguisher.serialize(rd.Value) 1488 } 1489 1490 func (rd *RouteDistinguisherUnknown) String() string { 1491 return fmt.Sprintf("%v", rd.Value) 1492 } 1493 1494 func (rd *RouteDistinguisherUnknown) MarshalJSON() ([]byte, error) { 1495 return json.Marshal(struct { 1496 Type uint16 `json:"type"` 1497 Value []byte `json:"value"` 1498 }{ 1499 Type: rd.Type, 1500 Value: rd.Value, 1501 }) 1502 } 1503 1504 func GetRouteDistinguisher(data []byte) RouteDistinguisherInterface { 1505 typ := binary.BigEndian.Uint16(data[0:2]) 1506 switch typ { 1507 case BGP_RD_TWO_OCTET_AS: 1508 return NewRouteDistinguisherTwoOctetAS(binary.BigEndian.Uint16(data[2:4]), binary.BigEndian.Uint32(data[4:8])) 1509 case BGP_RD_IPV4_ADDRESS: 1510 return NewRouteDistinguisherIPAddressAS(net.IP(data[2:6]).String(), binary.BigEndian.Uint16(data[6:8])) 1511 case BGP_RD_FOUR_OCTET_AS: 1512 return NewRouteDistinguisherFourOctetAS(binary.BigEndian.Uint32(data[2:6]), binary.BigEndian.Uint16(data[6:8])) 1513 } 1514 rd := &RouteDistinguisherUnknown{ 1515 DefaultRouteDistinguisher: DefaultRouteDistinguisher{ 1516 Type: typ, 1517 }, 1518 } 1519 return rd 1520 } 1521 1522 func parseRdAndRt(input string) ([]string, error) { 1523 elems := _regexpRouteDistinguisher.FindStringSubmatch(input) 1524 if len(elems) != 11 { 1525 return nil, fmt.Errorf("failed to parse") 1526 } 1527 return elems, nil 1528 } 1529 1530 func ParseRouteDistinguisher(rd string) (RouteDistinguisherInterface, error) { 1531 elems, err := parseRdAndRt(rd) 1532 if err != nil { 1533 return nil, err 1534 } 1535 assigned, _ := strconv.ParseUint(elems[10], 10, 32) 1536 ip := net.ParseIP(elems[1]) 1537 switch { 1538 case ip.To4() != nil: 1539 return NewRouteDistinguisherIPAddressAS(elems[1], uint16(assigned)), nil 1540 case elems[6] == "" && elems[7] == "": 1541 asn, _ := strconv.ParseUint(elems[8], 10, 16) 1542 return NewRouteDistinguisherTwoOctetAS(uint16(asn), uint32(assigned)), nil 1543 default: 1544 fst, _ := strconv.ParseUint(elems[7], 10, 16) 1545 snd, _ := strconv.ParseUint(elems[8], 10, 16) 1546 asn := fst<<16 | snd 1547 return NewRouteDistinguisherFourOctetAS(uint32(asn), uint16(assigned)), nil 1548 } 1549 } 1550 1551 // 1552 // RFC3107 Carrying Label Information in BGP-4 1553 // 1554 // 3. Carrying Label Mapping Information 1555 // 1556 // b) Label: 1557 // 1558 // The Label field carries one or more labels (that corresponds to 1559 // the stack of labels [MPLS-ENCAPS(RFC3032)]). Each label is encoded as 1560 // 4 octets, where the high-order 20 bits contain the label value, and 1561 // the low order bit contains "Bottom of Stack" 1562 // 1563 // RFC3032 MPLS Label Stack Encoding 1564 // 1565 // 2.1. Encoding the Label Stack 1566 // 1567 // 0 1 2 3 1568 // 0 ... 9 0 ... 9 0 1 2 3 4 ... 9 0 1 1569 // +-----+-+-+---+-+-+-+-+-+-----+-+-+-+ 1570 // | Label | Exp |S| TTL | 1571 // +-----+-+-+---+-+-+-+-+-+-----+-+-+-+ 1572 // 1573 1574 // RFC3107 Carrying Label Information in BGP-4 1575 // 1576 // 3. Carrying Label Mapping Information 1577 // 1578 // The label information carried (as part of NLRI) in the Withdrawn 1579 // Routes field should be set to 0x800000. 1580 const WITHDRAW_LABEL = uint32(0x800000) 1581 const ZERO_LABEL = uint32(0) // some platform uses this as withdraw label 1582 1583 type MPLSLabelStack struct { 1584 Labels []uint32 1585 } 1586 1587 func (l *MPLSLabelStack) DecodeFromBytes(data []byte) error { 1588 labels := []uint32{} 1589 foundBottom := false 1590 for len(data) >= 3 { 1591 label := uint32(data[0])<<16 | uint32(data[1])<<8 | uint32(data[2]) 1592 if label == WITHDRAW_LABEL || label == ZERO_LABEL { 1593 l.Labels = []uint32{label} 1594 return nil 1595 } 1596 data = data[3:] 1597 labels = append(labels, label>>4) 1598 if label&1 == 1 { 1599 foundBottom = true 1600 break 1601 } 1602 } 1603 1604 if !foundBottom { 1605 l.Labels = []uint32{} 1606 return nil 1607 } 1608 l.Labels = labels 1609 return nil 1610 } 1611 1612 func (l *MPLSLabelStack) Serialize() ([]byte, error) { 1613 buf := make([]byte, len(l.Labels)*3) 1614 for i, label := range l.Labels { 1615 if label == WITHDRAW_LABEL { 1616 return []byte{128, 0, 0}, nil 1617 } 1618 label = label << 4 1619 buf[i*3] = byte((label >> 16) & 0xff) 1620 buf[i*3+1] = byte((label >> 8) & 0xff) 1621 buf[i*3+2] = byte(label & 0xff) 1622 } 1623 buf[len(buf)-1] |= 1 1624 return buf, nil 1625 } 1626 1627 func (l *MPLSLabelStack) Len() int { return 3 * len(l.Labels) } 1628 1629 func (l *MPLSLabelStack) String() string { 1630 if len(l.Labels) == 0 { 1631 return "" 1632 } 1633 s := bytes.NewBuffer(make([]byte, 0, 64)) 1634 s.WriteString("[") 1635 ss := make([]string, 0, len(l.Labels)) 1636 for _, label := range l.Labels { 1637 ss = append(ss, fmt.Sprintf("%d", label)) 1638 } 1639 s.WriteString(strings.Join(ss, ", ")) 1640 s.WriteString("]") 1641 return s.String() 1642 } 1643 1644 func NewMPLSLabelStack(labels ...uint32) *MPLSLabelStack { 1645 if len(labels) == 0 { 1646 labels = []uint32{0} 1647 } 1648 return &MPLSLabelStack{labels} 1649 } 1650 1651 func ParseMPLSLabelStack(buf string) (*MPLSLabelStack, error) { 1652 elems := strings.Split(buf, "/") 1653 labels := make([]uint32, 0, len(elems)) 1654 if len(elems) == 0 { 1655 goto ERR 1656 } 1657 for _, elem := range elems { 1658 i, err := strconv.ParseUint(elem, 10, 32) 1659 if err != nil { 1660 goto ERR 1661 } 1662 if i > ((1 << 20) - 1) { 1663 goto ERR 1664 } 1665 labels = append(labels, uint32(i)) 1666 } 1667 return NewMPLSLabelStack(labels...), nil 1668 ERR: 1669 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "invalid mpls label stack format") 1670 } 1671 1672 // 1673 // RFC3107 Carrying Label Information in BGP-4 1674 // 1675 // 3. Carrying Label Mapping Information 1676 // 1677 // +----------------------+ 1678 // | Length (1 octet) | 1679 // +----------------------+ 1680 // | Label (3 octets) | 1681 // +----------------------+ 1682 // ....................... 1683 // +----------------------+ 1684 // | Prefix (variable) | 1685 // +----------------------+ 1686 // 1687 // RFC4364 BGP/MPLS IP VPNs 1688 // 1689 // 4.3.4. How VPN-IPv4 NLRI Is Carried in BGP 1690 // 1691 // The labeled VPN-IPv4 NLRI itself is encoded as specified in 1692 // [MPLS-BGP(RFC3107)], where the prefix consists of an 8-byte RD 1693 // followed by an IPv4 prefix. 1694 // 1695 1696 type LabeledVPNIPAddrPrefix struct { 1697 IPAddrPrefixDefault 1698 Labels MPLSLabelStack 1699 RD RouteDistinguisherInterface 1700 addrlen uint8 1701 } 1702 1703 func (l *LabeledVPNIPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 1704 f := RF_IPv4_VPN 1705 if l.addrlen == 16 { 1706 f = RF_IPv6_VPN 1707 } 1708 if IsAddPathEnabled(true, f, options) { 1709 var err error 1710 data, err = l.decodePathIdentifier(data) 1711 if err != nil { 1712 return err 1713 } 1714 } 1715 if len(data) < 1 { 1716 return NewMessageError(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), nil, "prefix misses length field") 1717 } 1718 l.Length = uint8(data[0]) 1719 data = data[1:] 1720 l.Labels.DecodeFromBytes(data) 1721 if int(l.Length)-8*(l.Labels.Len()) < 0 { 1722 l.Labels.Labels = []uint32{} 1723 } 1724 data = data[l.Labels.Len():] 1725 l.RD = GetRouteDistinguisher(data) 1726 data = data[l.RD.Len():] 1727 restbits := int(l.Length) - 8*(l.Labels.Len()+l.RD.Len()) 1728 return l.decodePrefix(data, uint8(restbits), l.addrlen) 1729 } 1730 1731 func (l *LabeledVPNIPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { 1732 f := RF_IPv4_VPN 1733 if l.addrlen == 16 { 1734 f = RF_IPv6_VPN 1735 } 1736 var buf []byte 1737 if IsAddPathEnabled(false, f, options) { 1738 var err error 1739 buf, err = l.serializeIdentifier() 1740 if err != nil { 1741 return nil, err 1742 } 1743 } 1744 buf = append(buf, l.Length) 1745 lbuf, err := l.Labels.Serialize() 1746 if err != nil { 1747 return nil, err 1748 } 1749 buf = append(buf, lbuf...) 1750 rbuf, err := l.RD.Serialize() 1751 if err != nil { 1752 return nil, err 1753 } 1754 buf = append(buf, rbuf...) 1755 restbits := int(l.Length) - 8*(l.Labels.Len()+l.RD.Len()) 1756 pbuf, err := l.serializePrefix(uint8(restbits)) 1757 if err != nil { 1758 return nil, err 1759 } 1760 buf = append(buf, pbuf...) 1761 return buf, nil 1762 } 1763 1764 func (l *LabeledVPNIPAddrPrefix) AFI() uint16 { 1765 return AFI_IP 1766 } 1767 1768 func (l *LabeledVPNIPAddrPrefix) SAFI() uint8 { 1769 return SAFI_MPLS_VPN 1770 } 1771 1772 func (l *LabeledVPNIPAddrPrefix) IPPrefixLen() uint8 { 1773 return l.Length - 8*uint8(l.Labels.Len()+l.RD.Len()) 1774 } 1775 1776 func (l *LabeledVPNIPAddrPrefix) Len(options ...*MarshallingOption) int { 1777 return 1 + l.Labels.Len() + l.RD.Len() + int((l.IPPrefixLen()+7)/8) 1778 } 1779 1780 func (l *LabeledVPNIPAddrPrefix) String() string { 1781 return fmt.Sprintf("%s:%s", l.RD, l.IPPrefix()) 1782 } 1783 1784 func (l *LabeledVPNIPAddrPrefix) IPPrefix() string { 1785 masklen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) 1786 return fmt.Sprintf("%s/%d", l.IPAddrPrefixDefault.Prefix, masklen) 1787 } 1788 1789 func (l *LabeledVPNIPAddrPrefix) MarshalJSON() ([]byte, error) { 1790 masklen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) 1791 return json.Marshal(struct { 1792 Prefix string `json:"prefix"` 1793 Labels []uint32 `json:"labels"` 1794 RD RouteDistinguisherInterface `json:"rd"` 1795 }{ 1796 Prefix: fmt.Sprintf("%s/%d", l.IPAddrPrefixDefault.Prefix, masklen), 1797 Labels: l.Labels.Labels, 1798 RD: l.RD, 1799 }) 1800 } 1801 1802 func NewLabeledVPNIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack, rd RouteDistinguisherInterface) *LabeledVPNIPAddrPrefix { 1803 rdlen := 0 1804 if rd != nil { 1805 rdlen = rd.Len() 1806 } 1807 return &LabeledVPNIPAddrPrefix{ 1808 IPAddrPrefixDefault{ 1809 Length: length + uint8(8*(label.Len()+rdlen)), 1810 Prefix: net.ParseIP(prefix).To4(), 1811 }, 1812 label, 1813 rd, 1814 4, 1815 } 1816 } 1817 1818 type LabeledVPNIPv6AddrPrefix struct { 1819 LabeledVPNIPAddrPrefix 1820 } 1821 1822 func (l *LabeledVPNIPv6AddrPrefix) AFI() uint16 { 1823 return AFI_IP6 1824 } 1825 1826 func NewLabeledVPNIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack, rd RouteDistinguisherInterface) *LabeledVPNIPv6AddrPrefix { 1827 rdlen := 0 1828 if rd != nil { 1829 rdlen = rd.Len() 1830 } 1831 return &LabeledVPNIPv6AddrPrefix{ 1832 LabeledVPNIPAddrPrefix{ 1833 IPAddrPrefixDefault{ 1834 Length: length + uint8(8*(label.Len()+rdlen)), 1835 Prefix: net.ParseIP(prefix), 1836 }, 1837 label, 1838 rd, 1839 16, 1840 }, 1841 } 1842 } 1843 1844 type LabeledIPAddrPrefix struct { 1845 IPAddrPrefixDefault 1846 Labels MPLSLabelStack 1847 addrlen uint8 1848 } 1849 1850 func (r *LabeledIPAddrPrefix) AFI() uint16 { 1851 return AFI_IP 1852 } 1853 1854 func (r *LabeledIPAddrPrefix) SAFI() uint8 { 1855 return SAFI_MPLS_LABEL 1856 } 1857 1858 func (l *LabeledIPAddrPrefix) IPPrefixLen() uint8 { 1859 return l.Length - 8*uint8(l.Labels.Len()) 1860 } 1861 1862 func (l *LabeledIPAddrPrefix) Len(options ...*MarshallingOption) int { 1863 return 1 + l.Labels.Len() + int((l.IPPrefixLen()+7)/8) 1864 } 1865 1866 func (l *LabeledIPAddrPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 1867 f := RF_IPv4_MPLS 1868 if l.addrlen == 16 { 1869 f = RF_IPv6_MPLS 1870 } 1871 if IsAddPathEnabled(true, f, options) { 1872 var err error 1873 data, err = l.decodePathIdentifier(data) 1874 if err != nil { 1875 return err 1876 } 1877 } 1878 l.Length = uint8(data[0]) 1879 data = data[1:] 1880 l.Labels.DecodeFromBytes(data) 1881 1882 if int(l.Length)-8*(l.Labels.Len()) < 0 { 1883 l.Labels.Labels = []uint32{} 1884 } 1885 restbits := int(l.Length) - 8*(l.Labels.Len()) 1886 data = data[l.Labels.Len():] 1887 return l.decodePrefix(data, uint8(restbits), l.addrlen) 1888 } 1889 1890 func (l *LabeledIPAddrPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { 1891 f := RF_IPv4_MPLS 1892 if l.addrlen == 16 { 1893 f = RF_IPv6_MPLS 1894 } 1895 var buf []byte 1896 if IsAddPathEnabled(false, f, options) { 1897 var err error 1898 buf, err = l.serializeIdentifier() 1899 if err != nil { 1900 return nil, err 1901 } 1902 } 1903 buf = append(buf, l.Length) 1904 restbits := int(l.Length) - 8*(l.Labels.Len()) 1905 lbuf, err := l.Labels.Serialize() 1906 if err != nil { 1907 return nil, err 1908 } 1909 buf = append(buf, lbuf...) 1910 pbuf, err := l.serializePrefix(uint8(restbits)) 1911 if err != nil { 1912 return nil, err 1913 } 1914 buf = append(buf, pbuf...) 1915 return buf, nil 1916 } 1917 1918 func (l *LabeledIPAddrPrefix) String() string { 1919 prefix := l.Prefix.String() 1920 if isIPv4MappedIPv6(l.Prefix) { 1921 prefix = "::ffff:" + prefix 1922 } 1923 return fmt.Sprintf("%s/%d", prefix, int(l.Length)-l.Labels.Len()*8) 1924 } 1925 1926 func (l *LabeledIPAddrPrefix) MarshalJSON() ([]byte, error) { 1927 return json.Marshal(struct { 1928 Prefix string `json:"prefix"` 1929 Labels []uint32 `json:"labels"` 1930 }{ 1931 Prefix: l.String(), 1932 Labels: l.Labels.Labels, 1933 }) 1934 } 1935 1936 func NewLabeledIPAddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPAddrPrefix { 1937 return &LabeledIPAddrPrefix{ 1938 IPAddrPrefixDefault{ 1939 Length: length + uint8(label.Len()*8), 1940 Prefix: net.ParseIP(prefix).To4(), 1941 }, 1942 label, 1943 4, 1944 } 1945 } 1946 1947 type LabeledIPv6AddrPrefix struct { 1948 LabeledIPAddrPrefix 1949 } 1950 1951 func (l *LabeledIPv6AddrPrefix) AFI() uint16 { 1952 return AFI_IP6 1953 } 1954 1955 func NewLabeledIPv6AddrPrefix(length uint8, prefix string, label MPLSLabelStack) *LabeledIPv6AddrPrefix { 1956 return &LabeledIPv6AddrPrefix{ 1957 LabeledIPAddrPrefix{ 1958 IPAddrPrefixDefault{ 1959 Length: length + uint8(label.Len()*8), 1960 Prefix: net.ParseIP(prefix), 1961 }, 1962 label, 1963 16, 1964 }, 1965 } 1966 } 1967 1968 type RouteTargetMembershipNLRI struct { 1969 PrefixDefault 1970 Length uint8 1971 AS uint32 1972 RouteTarget ExtendedCommunityInterface 1973 } 1974 1975 func (n *RouteTargetMembershipNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 1976 if IsAddPathEnabled(true, RF_RTC_UC, options) { 1977 var err error 1978 data, err = n.decodePathIdentifier(data) 1979 if err != nil { 1980 return err 1981 } 1982 } 1983 if len(data) < 1 { 1984 return NewMessageError(uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR), uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST), nil, "prefix misses length field") 1985 } 1986 n.Length = data[0] 1987 data = data[1 : n.Length/8+1] 1988 if len(data) == 0 { 1989 return nil 1990 } else if len(data) != 12 { 1991 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all RouteTargetMembershipNLRI bytes available") 1992 } 1993 n.AS = binary.BigEndian.Uint32(data[0:4]) 1994 rt, err := ParseExtended(data[4:]) 1995 n.RouteTarget = rt 1996 if err != nil { 1997 return err 1998 } 1999 return nil 2000 } 2001 2002 func (n *RouteTargetMembershipNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 2003 var buf []byte 2004 if IsAddPathEnabled(false, RF_RTC_UC, options) { 2005 var err error 2006 buf, err = n.serializeIdentifier() 2007 if err != nil { 2008 return nil, err 2009 } 2010 } 2011 if n.RouteTarget == nil { 2012 return append(buf, 0), nil 2013 } 2014 offset := len(buf) 2015 buf = append(buf, make([]byte, 5)...) 2016 buf[offset] = 96 2017 binary.BigEndian.PutUint32(buf[offset+1:], n.AS) 2018 ebuf, err := n.RouteTarget.Serialize() 2019 if err != nil { 2020 return nil, err 2021 } 2022 return append(buf, ebuf...), nil 2023 } 2024 2025 func (n *RouteTargetMembershipNLRI) AFI() uint16 { 2026 return AFI_IP 2027 } 2028 2029 func (n *RouteTargetMembershipNLRI) SAFI() uint8 { 2030 return SAFI_ROUTE_TARGET_CONSTRAINTS 2031 } 2032 2033 func (n *RouteTargetMembershipNLRI) Len(options ...*MarshallingOption) int { 2034 if n.AS == 0 && n.RouteTarget == nil { 2035 return 1 2036 } 2037 return 13 2038 } 2039 2040 func (n *RouteTargetMembershipNLRI) String() string { 2041 target := "default" 2042 if n.RouteTarget != nil { 2043 target = n.RouteTarget.String() 2044 } 2045 return fmt.Sprintf("%d:%s", n.AS, target) 2046 } 2047 2048 func (n *RouteTargetMembershipNLRI) MarshalJSON() ([]byte, error) { 2049 return json.Marshal(struct { 2050 Prefix string `json:"prefix"` 2051 }{ 2052 Prefix: n.String(), 2053 }) 2054 } 2055 2056 func NewRouteTargetMembershipNLRI(as uint32, target ExtendedCommunityInterface) *RouteTargetMembershipNLRI { 2057 l := 12 * 8 2058 if as == 0 && target == nil { 2059 l = 1 2060 } 2061 return &RouteTargetMembershipNLRI{ 2062 Length: uint8(l), 2063 AS: as, 2064 RouteTarget: target, 2065 } 2066 } 2067 2068 type ESIType uint8 2069 2070 const ( 2071 ESI_ARBITRARY ESIType = iota 2072 ESI_LACP 2073 ESI_MSTP 2074 ESI_MAC 2075 ESI_ROUTERID 2076 ESI_AS 2077 ) 2078 2079 type EthernetSegmentIdentifier struct { 2080 Type ESIType 2081 Value []byte 2082 } 2083 2084 func (esi *EthernetSegmentIdentifier) DecodeFromBytes(data []byte) error { 2085 esi.Type = ESIType(data[0]) 2086 esi.Value = data[1:10] 2087 switch esi.Type { 2088 case ESI_LACP, ESI_MSTP, ESI_ROUTERID, ESI_AS: 2089 if esi.Value[8] != 0x00 { 2090 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("invalid %s. last octet must be 0x00 (0x%02x)", esi.Type.String(), esi.Value[8])) 2091 } 2092 } 2093 return nil 2094 } 2095 2096 func (esi *EthernetSegmentIdentifier) Serialize() ([]byte, error) { 2097 buf := make([]byte, 10) 2098 buf[0] = uint8(esi.Type) 2099 copy(buf[1:], esi.Value) 2100 return buf, nil 2101 } 2102 2103 func isZeroBuf(buf []byte) bool { 2104 for _, b := range buf { 2105 if b != 0 { 2106 return false 2107 } 2108 } 2109 return true 2110 } 2111 2112 func (esi *EthernetSegmentIdentifier) String() string { 2113 toHexArray := func(data []byte) string { 2114 // Converts byte slice into the colon separated hex values and the 2115 // number of elements are 9 at most (excluding Type field). 2116 values := make([]string, 0, 9) 2117 for _, v := range data { 2118 values = append(values, fmt.Sprintf("%02x", v)) 2119 } 2120 return strings.Join(values, ":") 2121 } 2122 2123 s := bytes.NewBuffer(make([]byte, 0, 64)) 2124 s.WriteString(fmt.Sprintf("%s | ", esi.Type.String())) 2125 switch esi.Type { 2126 case ESI_LACP: 2127 s.WriteString(fmt.Sprintf("system mac %s, ", net.HardwareAddr(esi.Value[:6]).String())) 2128 s.WriteString(fmt.Sprintf("port key %d", binary.BigEndian.Uint16(esi.Value[6:8]))) 2129 case ESI_MSTP: 2130 s.WriteString(fmt.Sprintf("bridge mac %s, ", net.HardwareAddr(esi.Value[:6]).String())) 2131 s.WriteString(fmt.Sprintf("priority %d", binary.BigEndian.Uint16(esi.Value[6:8]))) 2132 case ESI_MAC: 2133 s.WriteString(fmt.Sprintf("system mac %s, ", net.HardwareAddr(esi.Value[:6]).String())) 2134 s.WriteString(fmt.Sprintf("local discriminator %d", uint32(esi.Value[6])<<16|uint32(esi.Value[7])<<8|uint32(esi.Value[8]))) 2135 case ESI_ROUTERID: 2136 s.WriteString(fmt.Sprintf("router id %s, ", net.IP(esi.Value[:4]))) 2137 s.WriteString(fmt.Sprintf("local discriminator %d", binary.BigEndian.Uint32(esi.Value[4:8]))) 2138 case ESI_AS: 2139 s.WriteString(fmt.Sprintf("as %d, ", binary.BigEndian.Uint32(esi.Value[:4]))) 2140 s.WriteString(fmt.Sprintf("local discriminator %d", binary.BigEndian.Uint32(esi.Value[4:8]))) 2141 case ESI_ARBITRARY: 2142 if isZeroBuf(esi.Value) { 2143 return "single-homed" 2144 } 2145 fallthrough 2146 default: 2147 s.WriteString(toHexArray(esi.Value)) 2148 } 2149 return s.String() 2150 } 2151 2152 // Decode Ethernet Segment Identifier (ESI) from string slice. 2153 // 2154 // The first element of args should be the Type field (e.g., "ARBITRARY", 2155 // "arbitrary", "ESI_ARBITRARY" or "esi_arbitrary") and "single-homed" is 2156 // the special keyword for all zeroed ESI. 2157 // For the "ARBITRARY" Value field (Type 0), it should be the colon separated 2158 // hex values and the number of elements should be 9 at most. 2159 // e.g.) args := []string{"ARBITRARY", "11:22:33:44:55:66:77:88:99"} 2160 // For the other types, the Value field format is the similar to the string 2161 // format of ESI. 2162 // e.g.) args := []string{"lacp", "aa:bb:cc:dd:ee:ff", "100"} 2163 func ParseEthernetSegmentIdentifier(args []string) (EthernetSegmentIdentifier, error) { 2164 esi := EthernetSegmentIdentifier{} 2165 argLen := len(args) 2166 if argLen == 0 || args[0] == "single-homed" { 2167 return esi, nil 2168 } 2169 2170 typeStr := strings.TrimPrefix(strings.ToUpper(args[0]), "ESI_") 2171 switch typeStr { 2172 case "ARBITRARY": 2173 esi.Type = ESI_ARBITRARY 2174 case "LACP": 2175 esi.Type = ESI_LACP 2176 case "MSTP": 2177 esi.Type = ESI_MSTP 2178 case "MAC": 2179 esi.Type = ESI_MAC 2180 case "ROUTERID": 2181 esi.Type = ESI_ROUTERID 2182 case "AS": 2183 esi.Type = ESI_AS 2184 default: 2185 typ, err := strconv.ParseUint(args[0], 10, 8) 2186 if err != nil { 2187 return esi, fmt.Errorf("invalid esi type: %s", args[0]) 2188 } 2189 esi.Type = ESIType(typ) 2190 } 2191 2192 invalidEsiValuesError := fmt.Errorf("invalid esi values for type %s: %s", esi.Type.String(), args[1:]) 2193 esi.Value = make([]byte, 9) 2194 switch esi.Type { 2195 case ESI_LACP: 2196 fallthrough 2197 case ESI_MSTP: 2198 if argLen < 3 { 2199 return esi, invalidEsiValuesError 2200 } 2201 // MAC 2202 mac, err := net.ParseMAC(args[1]) 2203 if err != nil { 2204 return esi, invalidEsiValuesError 2205 } 2206 copy(esi.Value[0:6], mac) 2207 // Port Key or Bridge Priority 2208 i, err := strconv.ParseUint(args[2], 10, 16) 2209 if err != nil { 2210 return esi, invalidEsiValuesError 2211 } 2212 binary.BigEndian.PutUint16(esi.Value[6:8], uint16(i)) 2213 case ESI_MAC: 2214 if argLen < 3 { 2215 return esi, invalidEsiValuesError 2216 } 2217 // MAC 2218 mac, err := net.ParseMAC(args[1]) 2219 if err != nil { 2220 return esi, invalidEsiValuesError 2221 } 2222 copy(esi.Value[0:6], mac) 2223 // Local Discriminator 2224 i, err := strconv.ParseUint(args[2], 10, 32) 2225 if err != nil { 2226 return esi, invalidEsiValuesError 2227 } 2228 iBuf := make([]byte, 4) 2229 binary.BigEndian.PutUint32(iBuf, uint32(i)) 2230 copy(esi.Value[6:9], iBuf[1:4]) 2231 case ESI_ROUTERID: 2232 if argLen < 3 { 2233 return esi, invalidEsiValuesError 2234 } 2235 // Router ID 2236 ip := net.ParseIP(args[1]) 2237 if ip == nil || ip.To4() == nil { 2238 return esi, invalidEsiValuesError 2239 } 2240 copy(esi.Value[0:4], ip.To4()) 2241 // Local Discriminator 2242 i, err := strconv.ParseUint(args[2], 10, 32) 2243 if err != nil { 2244 return esi, invalidEsiValuesError 2245 } 2246 binary.BigEndian.PutUint32(esi.Value[4:8], uint32(i)) 2247 case ESI_AS: 2248 if argLen < 3 { 2249 return esi, invalidEsiValuesError 2250 } 2251 // AS 2252 as, err := strconv.ParseUint(args[1], 10, 32) 2253 if err != nil { 2254 return esi, invalidEsiValuesError 2255 } 2256 binary.BigEndian.PutUint32(esi.Value[0:4], uint32(as)) 2257 // Local Discriminator 2258 i, err := strconv.ParseUint(args[2], 10, 32) 2259 if err != nil { 2260 return esi, invalidEsiValuesError 2261 } 2262 binary.BigEndian.PutUint32(esi.Value[4:8], uint32(i)) 2263 case ESI_ARBITRARY: 2264 fallthrough 2265 default: 2266 if argLen < 2 { 2267 // Assumes the Value field is omitted 2268 break 2269 } 2270 values := make([]byte, 0, 9) 2271 for _, e := range strings.SplitN(args[1], ":", 9) { 2272 v, err := strconv.ParseUint(e, 16, 16) 2273 if err != nil { 2274 return esi, invalidEsiValuesError 2275 } 2276 values = append(values, byte(v)) 2277 } 2278 copy(esi.Value, values) 2279 } 2280 2281 return esi, nil 2282 } 2283 2284 // 2285 // I-D bess-evpn-overlay-01 2286 // 2287 // 5.1.3 Constructing EVPN BGP Routes 2288 // 2289 // For the balance of this memo, the MPLS label field will be 2290 // referred to as the VNI/VSID field. The VNI/VSID field is used for 2291 // both local and global VNIs/VSIDs, and for either case the entire 24- 2292 // bit field is used to encode the VNI/VSID value. 2293 // 2294 // We can't use type MPLSLabelStack for EVPN NLRI, because EVPN NLRI's MPLS 2295 // field can be filled with VXLAN VNI. In that case, we must avoid modifying 2296 // bottom of stack bit. 2297 // 2298 2299 func labelDecode(data []byte) (uint32, error) { 2300 if len(data) < 3 { 2301 return 0, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all Label bytes available") 2302 } 2303 return uint32(data[0])<<16 | uint32(data[1])<<8 | uint32(data[2]), nil 2304 } 2305 2306 func labelSerialize(label uint32) ([]byte, error) { 2307 if label > 0xffffff { 2308 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Out of range Label: %d", label)) 2309 } 2310 buf := make([]byte, 3) 2311 buf[0] = byte((label >> 16) & 0xff) 2312 buf[1] = byte((label >> 8) & 0xff) 2313 buf[2] = byte(label & 0xff) 2314 return buf, nil 2315 } 2316 2317 type EVPNEthernetAutoDiscoveryRoute struct { 2318 RD RouteDistinguisherInterface 2319 ESI EthernetSegmentIdentifier 2320 ETag uint32 2321 Label uint32 2322 } 2323 2324 func (er *EVPNEthernetAutoDiscoveryRoute) Len() int { 2325 // RD(8) + ESI(10) + ETag(4) + Label(3) 2326 return 25 2327 } 2328 2329 func (er *EVPNEthernetAutoDiscoveryRoute) DecodeFromBytes(data []byte) error { 2330 er.RD = GetRouteDistinguisher(data) 2331 data = data[er.RD.Len():] 2332 err := er.ESI.DecodeFromBytes(data) 2333 if err != nil { 2334 return err 2335 } 2336 data = data[10:] 2337 er.ETag = binary.BigEndian.Uint32(data[0:4]) 2338 data = data[4:] 2339 if er.Label, err = labelDecode(data); err != nil { 2340 return err 2341 } 2342 return nil 2343 } 2344 2345 func (er *EVPNEthernetAutoDiscoveryRoute) Serialize() ([]byte, error) { 2346 var buf []byte 2347 var err error 2348 if er.RD != nil { 2349 buf, err = er.RD.Serialize() 2350 if err != nil { 2351 return nil, err 2352 } 2353 } else { 2354 buf = make([]byte, 8) 2355 } 2356 tbuf, err := er.ESI.Serialize() 2357 if err != nil { 2358 return nil, err 2359 } 2360 buf = append(buf, tbuf...) 2361 2362 tbuf = make([]byte, 4) 2363 binary.BigEndian.PutUint32(tbuf, er.ETag) 2364 buf = append(buf, tbuf...) 2365 2366 tbuf, err = labelSerialize(er.Label) 2367 if err != nil { 2368 return nil, err 2369 } 2370 buf = append(buf, tbuf...) 2371 2372 return buf, nil 2373 } 2374 2375 func (er *EVPNEthernetAutoDiscoveryRoute) String() string { 2376 // RFC7432: BGP MPLS-Based Ethernet VPN 2377 // 7.1. Ethernet Auto-discovery Route 2378 // For the purpose of BGP route key processing, only the Ethernet 2379 // Segment Identifier and the Ethernet Tag ID are considered to be part 2380 // of the prefix in the NLRI. The MPLS Label field is to be treated as 2381 // a route attribute as opposed to being part of the route. 2382 return fmt.Sprintf("[type:A-D][rd:%s][esi:%s][etag:%d]", er.RD, er.ESI.String(), er.ETag) 2383 } 2384 2385 func (er *EVPNEthernetAutoDiscoveryRoute) MarshalJSON() ([]byte, error) { 2386 return json.Marshal(struct { 2387 RD RouteDistinguisherInterface `json:"rd"` 2388 ESI string `json:"esi"` 2389 Etag uint32 `json:"etag"` 2390 Label uint32 `json:"label"` 2391 }{ 2392 RD: er.RD, 2393 ESI: er.ESI.String(), 2394 Etag: er.ETag, 2395 Label: er.Label, 2396 }) 2397 } 2398 2399 func (er *EVPNEthernetAutoDiscoveryRoute) rd() RouteDistinguisherInterface { 2400 return er.RD 2401 } 2402 2403 func NewEVPNEthernetAutoDiscoveryRoute(rd RouteDistinguisherInterface, esi EthernetSegmentIdentifier, etag uint32, label uint32) *EVPNNLRI { 2404 return NewEVPNNLRI(EVPN_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY, &EVPNEthernetAutoDiscoveryRoute{ 2405 RD: rd, 2406 ESI: esi, 2407 ETag: etag, 2408 Label: label, 2409 }) 2410 } 2411 2412 type EVPNMacIPAdvertisementRoute struct { 2413 RD RouteDistinguisherInterface 2414 ESI EthernetSegmentIdentifier 2415 ETag uint32 2416 MacAddressLength uint8 2417 MacAddress net.HardwareAddr 2418 IPAddressLength uint8 2419 IPAddress net.IP 2420 Labels []uint32 2421 } 2422 2423 func (er *EVPNMacIPAdvertisementRoute) Len() int { 2424 // RD(8) + ESI(10) + ETag(4) + MacAddressLength(1) + MacAddress(6) 2425 // + IPAddressLength(1) + IPAddress(0, 4 or 16) + Labels(3 or 6) 2426 return 30 + int(er.IPAddressLength)/8 + len(er.Labels)*3 2427 } 2428 2429 func (er *EVPNMacIPAdvertisementRoute) DecodeFromBytes(data []byte) error { 2430 er.RD = GetRouteDistinguisher(data) 2431 data = data[er.RD.Len():] 2432 err := er.ESI.DecodeFromBytes(data) 2433 if err != nil { 2434 return err 2435 } 2436 data = data[10:] 2437 er.ETag = binary.BigEndian.Uint32(data[0:4]) 2438 data = data[4:] 2439 er.MacAddressLength = data[0] 2440 er.MacAddress = net.HardwareAddr(data[1:7]) 2441 er.IPAddressLength = data[7] 2442 data = data[8:] 2443 if er.IPAddressLength == 32 || er.IPAddressLength == 128 { 2444 er.IPAddress = net.IP(data[0:((er.IPAddressLength) / 8)]) 2445 } else if er.IPAddressLength != 0 { 2446 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid IP address length: %d", er.IPAddressLength)) 2447 } 2448 data = data[(er.IPAddressLength / 8):] 2449 var label uint32 2450 if label, err = labelDecode(data); err != nil { 2451 return err 2452 } 2453 er.Labels = append(er.Labels, label) 2454 data = data[3:] 2455 if len(data) == 3 { 2456 if label, err = labelDecode(data); err != nil { 2457 return err 2458 } 2459 er.Labels = append(er.Labels, label) 2460 } 2461 return nil 2462 } 2463 2464 func (er *EVPNMacIPAdvertisementRoute) Serialize() ([]byte, error) { 2465 var buf []byte 2466 var err error 2467 if er.RD != nil { 2468 buf, err = er.RD.Serialize() 2469 if err != nil { 2470 return nil, err 2471 } 2472 } else { 2473 buf = make([]byte, 8) 2474 } 2475 2476 tbuf, err := er.ESI.Serialize() 2477 if err != nil { 2478 return nil, err 2479 } 2480 2481 buf = append(buf, tbuf...) 2482 tbuf = make([]byte, 4) 2483 binary.BigEndian.PutUint32(tbuf, er.ETag) 2484 buf = append(buf, tbuf...) 2485 tbuf = make([]byte, 7) 2486 tbuf[0] = er.MacAddressLength 2487 copy(tbuf[1:], er.MacAddress) 2488 buf = append(buf, tbuf...) 2489 2490 buf = append(buf, er.IPAddressLength) 2491 switch er.IPAddressLength { 2492 case 0: 2493 // IP address omitted 2494 case 32: 2495 buf = append(buf, []byte(er.IPAddress.To4())...) 2496 case 128: 2497 buf = append(buf, []byte(er.IPAddress.To16())...) 2498 default: 2499 return nil, fmt.Errorf("Invalid IP address length: %d", er.IPAddressLength) 2500 } 2501 2502 for _, l := range er.Labels { 2503 tbuf, err = labelSerialize(l) 2504 if err != nil { 2505 return nil, err 2506 } 2507 buf = append(buf, tbuf...) 2508 } 2509 return buf, nil 2510 } 2511 2512 func (er *EVPNMacIPAdvertisementRoute) String() string { 2513 // RFC7432: BGP MPLS-Based Ethernet VPN 2514 // 7.2. MAC/IP Advertisement Route 2515 // For the purpose of BGP route key processing, only the Ethernet Tag 2516 // ID, MAC Address Length, MAC Address, IP Address Length, and IP 2517 // Address fields are considered to be part of the prefix in the NLRI. 2518 // The Ethernet Segment Identifier, MPLS Label1, and MPLS Label2 fields 2519 // are to be treated as route attributes as opposed to being part of the 2520 // "route". 2521 return fmt.Sprintf("[type:macadv][rd:%s][etag:%d][mac:%s][ip:%s]", er.RD, er.ETag, er.MacAddress, er.IPAddress) 2522 } 2523 2524 func (er *EVPNMacIPAdvertisementRoute) MarshalJSON() ([]byte, error) { 2525 return json.Marshal(struct { 2526 RD RouteDistinguisherInterface `json:"rd"` 2527 ESI string `json:"esi"` 2528 Etag uint32 `json:"etag"` 2529 MacAddress string `json:"mac"` 2530 IPAddress string `json:"ip"` 2531 Labels []uint32 `json:"labels"` 2532 }{ 2533 RD: er.RD, 2534 ESI: er.ESI.String(), 2535 Etag: er.ETag, 2536 MacAddress: er.MacAddress.String(), 2537 IPAddress: er.IPAddress.String(), 2538 Labels: er.Labels, 2539 }) 2540 } 2541 2542 func (er *EVPNMacIPAdvertisementRoute) rd() RouteDistinguisherInterface { 2543 return er.RD 2544 } 2545 2546 func NewEVPNMacIPAdvertisementRoute(rd RouteDistinguisherInterface, esi EthernetSegmentIdentifier, etag uint32, macAddress string, ipAddress string, labels []uint32) *EVPNNLRI { 2547 mac, _ := net.ParseMAC(macAddress) 2548 var ipLen uint8 2549 ip := net.ParseIP(ipAddress) 2550 if ip != nil { 2551 if ipv4 := ip.To4(); ipv4 != nil { 2552 ipLen = 32 2553 ip = ipv4 2554 } else { 2555 ipLen = 128 2556 } 2557 } 2558 return NewEVPNNLRI(EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT, &EVPNMacIPAdvertisementRoute{ 2559 RD: rd, 2560 ESI: esi, 2561 ETag: etag, 2562 MacAddressLength: 48, 2563 MacAddress: mac, 2564 IPAddressLength: ipLen, 2565 IPAddress: ip, 2566 Labels: labels, 2567 }) 2568 } 2569 2570 type EVPNMulticastEthernetTagRoute struct { 2571 RD RouteDistinguisherInterface 2572 ETag uint32 2573 IPAddressLength uint8 2574 IPAddress net.IP 2575 } 2576 2577 func (er *EVPNMulticastEthernetTagRoute) Len() int { 2578 // RD(8) + ETag(4) + IPAddressLength(1) + IPAddress(4 or 16) 2579 return 13 + int(er.IPAddressLength)/8 2580 } 2581 2582 func (er *EVPNMulticastEthernetTagRoute) DecodeFromBytes(data []byte) error { 2583 er.RD = GetRouteDistinguisher(data) 2584 data = data[er.RD.Len():] 2585 er.ETag = binary.BigEndian.Uint32(data[0:4]) 2586 er.IPAddressLength = data[4] 2587 data = data[5:] 2588 if er.IPAddressLength == 32 || er.IPAddressLength == 128 { 2589 er.IPAddress = net.IP(data[:er.IPAddressLength/8]) 2590 } else { 2591 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid IP address length: %d", er.IPAddressLength)) 2592 } 2593 return nil 2594 } 2595 2596 func (er *EVPNMulticastEthernetTagRoute) Serialize() ([]byte, error) { 2597 var buf []byte 2598 var err error 2599 if er.RD != nil { 2600 buf, err = er.RD.Serialize() 2601 if err != nil { 2602 return nil, err 2603 } 2604 } else { 2605 buf = make([]byte, 8) 2606 } 2607 tbuf := make([]byte, 4) 2608 binary.BigEndian.PutUint32(tbuf, er.ETag) 2609 buf = append(buf, tbuf...) 2610 buf = append(buf, er.IPAddressLength) 2611 switch er.IPAddressLength { 2612 case 32: 2613 buf = append(buf, []byte(er.IPAddress.To4())...) 2614 case 128: 2615 buf = append(buf, []byte(er.IPAddress.To16())...) 2616 default: 2617 return nil, fmt.Errorf("Invalid IP address length: %d", er.IPAddressLength) 2618 } 2619 if err != nil { 2620 return nil, err 2621 } 2622 return buf, nil 2623 } 2624 2625 func (er *EVPNMulticastEthernetTagRoute) String() string { 2626 // RFC7432: BGP MPLS-Based Ethernet VPN 2627 // 7.3. Inclusive Multicast Ethernet Tag Route 2628 // ...(snip)... For the purpose of BGP route key 2629 // processing, only the Ethernet Tag ID, IP Address Length, and 2630 // Originating Router's IP Address fields are considered to be part of 2631 // the prefix in the NLRI. 2632 return fmt.Sprintf("[type:multicast][rd:%s][etag:%d][ip:%s]", er.RD, er.ETag, er.IPAddress) 2633 } 2634 2635 func (er *EVPNMulticastEthernetTagRoute) MarshalJSON() ([]byte, error) { 2636 return json.Marshal(struct { 2637 RD RouteDistinguisherInterface `json:"rd"` 2638 Etag uint32 `json:"etag"` 2639 IPAddress string `json:"ip"` 2640 }{ 2641 RD: er.RD, 2642 Etag: er.ETag, 2643 IPAddress: er.IPAddress.String(), 2644 }) 2645 } 2646 2647 func (er *EVPNMulticastEthernetTagRoute) rd() RouteDistinguisherInterface { 2648 return er.RD 2649 } 2650 2651 func NewEVPNMulticastEthernetTagRoute(rd RouteDistinguisherInterface, etag uint32, ipAddress string) *EVPNNLRI { 2652 ipLen := uint8(32) 2653 ip := net.ParseIP(ipAddress) 2654 if ipv4 := ip.To4(); ipv4 != nil { 2655 ip = ipv4 2656 } else { 2657 ipLen = 128 2658 } 2659 return NewEVPNNLRI(EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG, &EVPNMulticastEthernetTagRoute{ 2660 RD: rd, 2661 ETag: etag, 2662 IPAddressLength: ipLen, 2663 IPAddress: ip, 2664 }) 2665 } 2666 2667 type EVPNEthernetSegmentRoute struct { 2668 RD RouteDistinguisherInterface 2669 ESI EthernetSegmentIdentifier 2670 IPAddressLength uint8 2671 IPAddress net.IP 2672 } 2673 2674 func (er *EVPNEthernetSegmentRoute) Len() int { 2675 // RD(8) + ESI(10) + IPAddressLength(1) + IPAddress(4 or 16) 2676 return 19 + int(er.IPAddressLength)/8 2677 } 2678 2679 func (er *EVPNEthernetSegmentRoute) DecodeFromBytes(data []byte) error { 2680 er.RD = GetRouteDistinguisher(data) 2681 data = data[er.RD.Len():] 2682 er.ESI.DecodeFromBytes(data) 2683 data = data[10:] 2684 er.IPAddressLength = data[0] 2685 data = data[1:] 2686 if er.IPAddressLength == 32 || er.IPAddressLength == 128 { 2687 er.IPAddress = net.IP(data[:er.IPAddressLength/8]) 2688 } else { 2689 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid IP address length: %d", er.IPAddressLength)) 2690 } 2691 return nil 2692 } 2693 2694 func (er *EVPNEthernetSegmentRoute) Serialize() ([]byte, error) { 2695 var buf []byte 2696 var err error 2697 if er.RD != nil { 2698 buf, err = er.RD.Serialize() 2699 if err != nil { 2700 return nil, err 2701 } 2702 } else { 2703 buf = make([]byte, 8) 2704 } 2705 tbuf, err := er.ESI.Serialize() 2706 if err != nil { 2707 return nil, err 2708 } 2709 buf = append(buf, tbuf...) 2710 buf = append(buf, er.IPAddressLength) 2711 switch er.IPAddressLength { 2712 case 32: 2713 buf = append(buf, []byte(er.IPAddress.To4())...) 2714 case 128: 2715 buf = append(buf, []byte(er.IPAddress.To16())...) 2716 default: 2717 return nil, fmt.Errorf("Invalid IP address length: %d", er.IPAddressLength) 2718 } 2719 return buf, nil 2720 } 2721 2722 func (er *EVPNEthernetSegmentRoute) String() string { 2723 // RFC7432: BGP MPLS-Based Ethernet VPN 2724 // 7.4. Ethernet Segment Route 2725 // For the purpose of BGP route key processing, only the Ethernet 2726 // Segment ID, IP Address Length, and Originating Router's IP Address 2727 // fields are considered to be part of the prefix in the NLRI. 2728 return fmt.Sprintf("[type:esi][rd:%s][esi:%s][ip:%s]", er.RD, er.ESI.String(), er.IPAddress) 2729 } 2730 2731 func (er *EVPNEthernetSegmentRoute) MarshalJSON() ([]byte, error) { 2732 return json.Marshal(struct { 2733 RD RouteDistinguisherInterface `json:"rd"` 2734 ESI string `json:"esi"` 2735 IPAddress string `json:"ip"` 2736 }{ 2737 RD: er.RD, 2738 ESI: er.ESI.String(), 2739 IPAddress: er.IPAddress.String(), 2740 }) 2741 } 2742 2743 func (er *EVPNEthernetSegmentRoute) rd() RouteDistinguisherInterface { 2744 return er.RD 2745 } 2746 2747 func NewEVPNEthernetSegmentRoute(rd RouteDistinguisherInterface, esi EthernetSegmentIdentifier, ipAddress string) *EVPNNLRI { 2748 ipLen := uint8(32) 2749 ip := net.ParseIP(ipAddress) 2750 if ipv4 := ip.To4(); ipv4 != nil { 2751 ip = ipv4 2752 } else { 2753 ipLen = 128 2754 } 2755 return NewEVPNNLRI(EVPN_ETHERNET_SEGMENT_ROUTE, &EVPNEthernetSegmentRoute{ 2756 RD: rd, 2757 ESI: esi, 2758 IPAddressLength: ipLen, 2759 IPAddress: ip, 2760 }) 2761 } 2762 2763 type EVPNIPPrefixRoute struct { 2764 RD RouteDistinguisherInterface 2765 ESI EthernetSegmentIdentifier 2766 ETag uint32 2767 IPPrefixLength uint8 2768 IPPrefix net.IP 2769 GWIPAddress net.IP 2770 Label uint32 2771 } 2772 2773 func (er *EVPNIPPrefixRoute) Len() int { 2774 if er.IPPrefix.To4() != nil { 2775 return 34 2776 } 2777 return 58 2778 } 2779 2780 func (er *EVPNIPPrefixRoute) DecodeFromBytes(data []byte) error { 2781 addrLen := net.IPv4len 2782 switch len(data) { 2783 case 34: 2784 // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1) + IPv4 Prefix(4) + GW IPv4(4) + Label(3) 2785 case 58: 2786 // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1) + IPv6 Prefix(16) + GW IPv6(16) + Label(3) 2787 addrLen = net.IPv6len 2788 default: 2789 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPN IP Prefix Route bytes available") 2790 } 2791 2792 er.RD = GetRouteDistinguisher(data[0:8]) 2793 2794 err := er.ESI.DecodeFromBytes(data[8:18]) 2795 if err != nil { 2796 return err 2797 } 2798 2799 er.ETag = binary.BigEndian.Uint32(data[18:22]) 2800 2801 er.IPPrefixLength = data[22] 2802 2803 offset := 23 // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1) 2804 er.IPPrefix = data[offset : offset+addrLen] 2805 offset += addrLen 2806 2807 er.GWIPAddress = data[offset : offset+addrLen] 2808 offset += addrLen 2809 2810 if er.Label, err = labelDecode(data[offset : offset+3]); err != nil { 2811 return err 2812 } 2813 //offset += 3 2814 2815 return nil 2816 } 2817 2818 func (er *EVPNIPPrefixRoute) Serialize() ([]byte, error) { 2819 buf := make([]byte, 23) // RD(8) + ESI(10) + ETag(4) + IPPrefixLength(1) 2820 2821 if er.RD != nil { 2822 tbuf, err := er.RD.Serialize() 2823 if err != nil { 2824 return nil, err 2825 } 2826 copy(buf[0:8], tbuf) 2827 } 2828 2829 tbuf, err := er.ESI.Serialize() 2830 if err != nil { 2831 return nil, err 2832 } 2833 copy(buf[8:18], tbuf) 2834 2835 binary.BigEndian.PutUint32(buf[18:22], er.ETag) 2836 2837 buf[22] = er.IPPrefixLength 2838 2839 if er.IPPrefix == nil { 2840 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("IP Prefix is nil")) 2841 } else if er.IPPrefix.To4() != nil { 2842 buf = append(buf, er.IPPrefix.To4()...) 2843 if er.GWIPAddress == nil { 2844 // draft-ietf-bess-evpn-prefix-advertisement: IP Prefix Advertisement in EVPN 2845 // The GW IP field SHOULD be zero if it is not used as an Overlay Index. 2846 er.GWIPAddress = net.IPv4zero 2847 } 2848 buf = append(buf, er.GWIPAddress.To4()...) 2849 } else { 2850 buf = append(buf, er.IPPrefix.To16()...) 2851 if er.GWIPAddress == nil { 2852 er.GWIPAddress = net.IPv6zero 2853 } 2854 buf = append(buf, er.GWIPAddress.To16()...) 2855 } 2856 2857 tbuf, err = labelSerialize(er.Label) 2858 if err != nil { 2859 return nil, err 2860 } 2861 buf = append(buf, tbuf...) 2862 2863 return buf, nil 2864 } 2865 2866 func (er *EVPNIPPrefixRoute) String() string { 2867 // draft-ietf-bess-evpn-prefix-advertisement: IP Prefix Advertisement in EVPN 2868 // 3.1 IP Prefix Route Encoding 2869 // The RD, Eth-Tag ID, IP Prefix Length and IP Prefix will be part of 2870 // the route key used by BGP to compare routes. The rest of the fields 2871 // will not be part of the route key. 2872 return fmt.Sprintf("[type:Prefix][rd:%s][etag:%d][prefix:%s/%d]", er.RD, er.ETag, er.IPPrefix, er.IPPrefixLength) 2873 } 2874 2875 func (er *EVPNIPPrefixRoute) MarshalJSON() ([]byte, error) { 2876 return json.Marshal(struct { 2877 RD RouteDistinguisherInterface `json:"rd"` 2878 ESI string `json:"esi"` 2879 Etag uint32 `json:"etag"` 2880 Prefix string `json:"prefix"` 2881 Gateway string `json:"gateway"` 2882 Label uint32 `json:"label"` 2883 }{ 2884 RD: er.RD, 2885 ESI: er.ESI.String(), 2886 Etag: er.ETag, 2887 Prefix: fmt.Sprintf("%s/%d", er.IPPrefix, er.IPPrefixLength), 2888 Gateway: er.GWIPAddress.String(), 2889 Label: er.Label, 2890 }) 2891 } 2892 2893 func (er *EVPNIPPrefixRoute) rd() RouteDistinguisherInterface { 2894 return er.RD 2895 } 2896 2897 func NewEVPNIPPrefixRoute(rd RouteDistinguisherInterface, esi EthernetSegmentIdentifier, etag uint32, ipPrefixLength uint8, ipPrefix string, gateway string, label uint32) *EVPNNLRI { 2898 ip := net.ParseIP(ipPrefix) 2899 gw := net.ParseIP(gateway) 2900 if ipv4 := ip.To4(); ipv4 != nil { 2901 ip = ipv4 2902 gw = gw.To4() 2903 } 2904 return NewEVPNNLRI(EVPN_IP_PREFIX, &EVPNIPPrefixRoute{ 2905 RD: rd, 2906 ESI: esi, 2907 ETag: etag, 2908 IPPrefixLength: ipPrefixLength, 2909 IPPrefix: ip, 2910 GWIPAddress: gw, 2911 Label: label, 2912 }) 2913 } 2914 2915 type EVPNRouteTypeInterface interface { 2916 Len() int 2917 DecodeFromBytes([]byte) error 2918 Serialize() ([]byte, error) 2919 String() string 2920 rd() RouteDistinguisherInterface 2921 MarshalJSON() ([]byte, error) 2922 } 2923 2924 func getEVPNRouteType(t uint8) (EVPNRouteTypeInterface, error) { 2925 switch t { 2926 case EVPN_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY: 2927 return &EVPNEthernetAutoDiscoveryRoute{}, nil 2928 case EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT: 2929 return &EVPNMacIPAdvertisementRoute{}, nil 2930 case EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG: 2931 return &EVPNMulticastEthernetTagRoute{}, nil 2932 case EVPN_ETHERNET_SEGMENT_ROUTE: 2933 return &EVPNEthernetSegmentRoute{}, nil 2934 case EVPN_IP_PREFIX: 2935 return &EVPNIPPrefixRoute{}, nil 2936 } 2937 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Unknown EVPN Route type: %d", t)) 2938 } 2939 2940 const ( 2941 EVPN_ROUTE_TYPE_ETHERNET_AUTO_DISCOVERY = 1 2942 EVPN_ROUTE_TYPE_MAC_IP_ADVERTISEMENT = 2 2943 EVPN_INCLUSIVE_MULTICAST_ETHERNET_TAG = 3 2944 EVPN_ETHERNET_SEGMENT_ROUTE = 4 2945 EVPN_IP_PREFIX = 5 2946 ) 2947 2948 type EVPNNLRI struct { 2949 PrefixDefault 2950 RouteType uint8 2951 Length uint8 2952 RouteTypeData EVPNRouteTypeInterface 2953 } 2954 2955 func (n *EVPNNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 2956 if IsAddPathEnabled(true, RF_EVPN, options) { 2957 var err error 2958 data, err = n.decodePathIdentifier(data) 2959 if err != nil { 2960 return err 2961 } 2962 } 2963 if len(data) < 2 { 2964 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPNNLRI bytes available") 2965 } 2966 n.RouteType = data[0] 2967 n.Length = data[1] 2968 data = data[2:] 2969 if len(data) < int(n.Length) { 2970 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all EVPNNLRI Route type bytes available") 2971 } 2972 r, err := getEVPNRouteType(n.RouteType) 2973 if err != nil { 2974 return err 2975 } 2976 n.RouteTypeData = r 2977 return n.RouteTypeData.DecodeFromBytes(data[:n.Length]) 2978 } 2979 2980 func (n *EVPNNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 2981 var buf []byte 2982 if IsAddPathEnabled(false, RF_EVPN, options) { 2983 var err error 2984 buf, err = n.serializeIdentifier() 2985 if err != nil { 2986 return nil, err 2987 } 2988 } 2989 offset := len(buf) 2990 buf = append(buf, make([]byte, 2)...) 2991 buf[offset] = n.RouteType 2992 tbuf, err := n.RouteTypeData.Serialize() 2993 buf[offset+1] = n.Length 2994 if err != nil { 2995 return nil, err 2996 } 2997 return append(buf, tbuf...), nil 2998 } 2999 3000 func (n *EVPNNLRI) AFI() uint16 { 3001 return AFI_L2VPN 3002 } 3003 3004 func (n *EVPNNLRI) SAFI() uint8 { 3005 return SAFI_EVPN 3006 } 3007 3008 func (n *EVPNNLRI) Len(options ...*MarshallingOption) int { 3009 return int(n.Length) + 2 3010 } 3011 3012 func (n *EVPNNLRI) String() string { 3013 if n.RouteTypeData != nil { 3014 return n.RouteTypeData.String() 3015 } 3016 return fmt.Sprintf("%d:%d", n.RouteType, n.Length) 3017 } 3018 3019 func (n *EVPNNLRI) MarshalJSON() ([]byte, error) { 3020 return json.Marshal(struct { 3021 Type uint8 `json:"type"` 3022 Value EVPNRouteTypeInterface `json:"value"` 3023 }{ 3024 Type: n.RouteType, 3025 Value: n.RouteTypeData, 3026 }) 3027 } 3028 3029 func (n *EVPNNLRI) RD() RouteDistinguisherInterface { 3030 return n.RouteTypeData.rd() 3031 } 3032 3033 func NewEVPNNLRI(routeType uint8, routeTypeData EVPNRouteTypeInterface) *EVPNNLRI { 3034 var l uint8 3035 if routeTypeData != nil { 3036 l = uint8(routeTypeData.Len()) 3037 } 3038 return &EVPNNLRI{ 3039 RouteType: routeType, 3040 Length: l, 3041 RouteTypeData: routeTypeData, 3042 } 3043 } 3044 3045 type EncapNLRI struct { 3046 IPAddrPrefixDefault 3047 addrlen uint8 3048 } 3049 3050 func (n *EncapNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 3051 if n.addrlen == 0 { 3052 n.addrlen = 4 3053 } 3054 f := RF_IPv4_ENCAP 3055 if n.addrlen == 16 { 3056 f = RF_IPv6_ENCAP 3057 } 3058 if IsAddPathEnabled(true, f, options) { 3059 var err error 3060 data, err = n.decodePathIdentifier(data) 3061 if err != nil { 3062 return err 3063 } 3064 } 3065 if len(data) < 4 { 3066 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 3067 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 3068 return NewMessageError(eCode, eSubCode, nil, "prefix misses length field") 3069 } 3070 n.Length = data[0] 3071 if n.addrlen == 0 { 3072 n.addrlen = 4 3073 } 3074 return n.decodePrefix(data[1:], n.Length, n.addrlen) 3075 } 3076 3077 func (n *EncapNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 3078 var buf []byte 3079 f := RF_IPv4_ENCAP 3080 if n.addrlen == 16 { 3081 f = RF_IPv6_ENCAP 3082 } 3083 if IsAddPathEnabled(false, f, options) { 3084 var err error 3085 buf, err = n.serializeIdentifier() 3086 if err != nil { 3087 return nil, err 3088 } 3089 } 3090 if n.Prefix.To4() != nil { 3091 buf = append(buf, net.IPv4len*8) 3092 n.Prefix = n.Prefix.To4() 3093 } else { 3094 buf = append(buf, net.IPv6len*8) 3095 } 3096 n.Length = buf[len(buf)-1] 3097 pbuf, err := n.serializePrefix(n.Length) 3098 if err != nil { 3099 return nil, err 3100 } 3101 return append(buf, pbuf...), nil 3102 } 3103 3104 func (n *EncapNLRI) String() string { 3105 return n.Prefix.String() 3106 } 3107 3108 func (n *EncapNLRI) AFI() uint16 { 3109 return AFI_IP 3110 } 3111 3112 func (n *EncapNLRI) SAFI() uint8 { 3113 return SAFI_ENCAPSULATION 3114 } 3115 3116 func (n *EncapNLRI) Len(options ...*MarshallingOption) int { 3117 return 1 + len(n.Prefix) 3118 } 3119 3120 func NewEncapNLRI(endpoint string) *EncapNLRI { 3121 return &EncapNLRI{ 3122 IPAddrPrefixDefault{Length: 32, Prefix: net.ParseIP(endpoint).To4()}, 3123 4, 3124 } 3125 } 3126 3127 type Encapv6NLRI struct { 3128 EncapNLRI 3129 } 3130 3131 func (n *Encapv6NLRI) AFI() uint16 { 3132 return AFI_IP6 3133 } 3134 3135 func NewEncapv6NLRI(endpoint string) *Encapv6NLRI { 3136 return &Encapv6NLRI{ 3137 EncapNLRI{ 3138 IPAddrPrefixDefault{Length: 128, Prefix: net.ParseIP(endpoint)}, 3139 16, 3140 }, 3141 } 3142 } 3143 3144 type BGPFlowSpecType uint8 3145 3146 const ( 3147 FLOW_SPEC_TYPE_UNKNOWN BGPFlowSpecType = iota 3148 FLOW_SPEC_TYPE_DST_PREFIX 3149 FLOW_SPEC_TYPE_SRC_PREFIX 3150 FLOW_SPEC_TYPE_IP_PROTO 3151 FLOW_SPEC_TYPE_PORT 3152 FLOW_SPEC_TYPE_DST_PORT 3153 FLOW_SPEC_TYPE_SRC_PORT 3154 FLOW_SPEC_TYPE_ICMP_TYPE 3155 FLOW_SPEC_TYPE_ICMP_CODE 3156 FLOW_SPEC_TYPE_TCP_FLAG 3157 FLOW_SPEC_TYPE_PKT_LEN 3158 FLOW_SPEC_TYPE_DSCP 3159 FLOW_SPEC_TYPE_FRAGMENT 3160 FLOW_SPEC_TYPE_LABEL 3161 FLOW_SPEC_TYPE_ETHERNET_TYPE // 14 3162 FLOW_SPEC_TYPE_SRC_MAC 3163 FLOW_SPEC_TYPE_DST_MAC 3164 FLOW_SPEC_TYPE_LLC_DSAP 3165 FLOW_SPEC_TYPE_LLC_SSAP 3166 FLOW_SPEC_TYPE_LLC_CONTROL 3167 FLOW_SPEC_TYPE_SNAP 3168 FLOW_SPEC_TYPE_VID 3169 FLOW_SPEC_TYPE_COS 3170 FLOW_SPEC_TYPE_INNER_VID 3171 FLOW_SPEC_TYPE_INNER_COS 3172 ) 3173 3174 var FlowSpecNameMap = map[BGPFlowSpecType]string{ 3175 FLOW_SPEC_TYPE_UNKNOWN: "unknown", 3176 FLOW_SPEC_TYPE_DST_PREFIX: "destination", 3177 FLOW_SPEC_TYPE_SRC_PREFIX: "source", 3178 FLOW_SPEC_TYPE_IP_PROTO: "protocol", 3179 FLOW_SPEC_TYPE_PORT: "port", 3180 FLOW_SPEC_TYPE_DST_PORT: "destination-port", 3181 FLOW_SPEC_TYPE_SRC_PORT: "source-port", 3182 FLOW_SPEC_TYPE_ICMP_TYPE: "icmp-type", 3183 FLOW_SPEC_TYPE_ICMP_CODE: "icmp-code", 3184 FLOW_SPEC_TYPE_TCP_FLAG: "tcp-flags", 3185 FLOW_SPEC_TYPE_PKT_LEN: "packet-length", 3186 FLOW_SPEC_TYPE_DSCP: "dscp", 3187 FLOW_SPEC_TYPE_FRAGMENT: "fragment", 3188 FLOW_SPEC_TYPE_LABEL: "label", 3189 FLOW_SPEC_TYPE_ETHERNET_TYPE: "ether-type", 3190 FLOW_SPEC_TYPE_SRC_MAC: "source-mac", 3191 FLOW_SPEC_TYPE_DST_MAC: "destination-mac", 3192 FLOW_SPEC_TYPE_LLC_DSAP: "llc-dsap", 3193 FLOW_SPEC_TYPE_LLC_SSAP: "llc-ssap", 3194 FLOW_SPEC_TYPE_LLC_CONTROL: "llc-control", 3195 FLOW_SPEC_TYPE_SNAP: "snap", 3196 FLOW_SPEC_TYPE_VID: "vid", 3197 FLOW_SPEC_TYPE_COS: "cos", 3198 FLOW_SPEC_TYPE_INNER_VID: "inner-vid", 3199 FLOW_SPEC_TYPE_INNER_COS: "inner-cos", 3200 } 3201 3202 var FlowSpecValueMap = map[string]BGPFlowSpecType{ 3203 FlowSpecNameMap[FLOW_SPEC_TYPE_DST_PREFIX]: FLOW_SPEC_TYPE_DST_PREFIX, 3204 FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_PREFIX]: FLOW_SPEC_TYPE_SRC_PREFIX, 3205 FlowSpecNameMap[FLOW_SPEC_TYPE_IP_PROTO]: FLOW_SPEC_TYPE_IP_PROTO, 3206 FlowSpecNameMap[FLOW_SPEC_TYPE_PORT]: FLOW_SPEC_TYPE_PORT, 3207 FlowSpecNameMap[FLOW_SPEC_TYPE_DST_PORT]: FLOW_SPEC_TYPE_DST_PORT, 3208 FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_PORT]: FLOW_SPEC_TYPE_SRC_PORT, 3209 FlowSpecNameMap[FLOW_SPEC_TYPE_ICMP_TYPE]: FLOW_SPEC_TYPE_ICMP_TYPE, 3210 FlowSpecNameMap[FLOW_SPEC_TYPE_ICMP_CODE]: FLOW_SPEC_TYPE_ICMP_CODE, 3211 FlowSpecNameMap[FLOW_SPEC_TYPE_TCP_FLAG]: FLOW_SPEC_TYPE_TCP_FLAG, 3212 FlowSpecNameMap[FLOW_SPEC_TYPE_PKT_LEN]: FLOW_SPEC_TYPE_PKT_LEN, 3213 FlowSpecNameMap[FLOW_SPEC_TYPE_DSCP]: FLOW_SPEC_TYPE_DSCP, 3214 FlowSpecNameMap[FLOW_SPEC_TYPE_FRAGMENT]: FLOW_SPEC_TYPE_FRAGMENT, 3215 FlowSpecNameMap[FLOW_SPEC_TYPE_LABEL]: FLOW_SPEC_TYPE_LABEL, 3216 FlowSpecNameMap[FLOW_SPEC_TYPE_ETHERNET_TYPE]: FLOW_SPEC_TYPE_ETHERNET_TYPE, 3217 FlowSpecNameMap[FLOW_SPEC_TYPE_SRC_MAC]: FLOW_SPEC_TYPE_SRC_MAC, 3218 FlowSpecNameMap[FLOW_SPEC_TYPE_DST_MAC]: FLOW_SPEC_TYPE_DST_MAC, 3219 FlowSpecNameMap[FLOW_SPEC_TYPE_LLC_DSAP]: FLOW_SPEC_TYPE_LLC_DSAP, 3220 FlowSpecNameMap[FLOW_SPEC_TYPE_LLC_SSAP]: FLOW_SPEC_TYPE_LLC_SSAP, 3221 FlowSpecNameMap[FLOW_SPEC_TYPE_LLC_CONTROL]: FLOW_SPEC_TYPE_LLC_CONTROL, 3222 FlowSpecNameMap[FLOW_SPEC_TYPE_SNAP]: FLOW_SPEC_TYPE_SNAP, 3223 FlowSpecNameMap[FLOW_SPEC_TYPE_VID]: FLOW_SPEC_TYPE_VID, 3224 FlowSpecNameMap[FLOW_SPEC_TYPE_COS]: FLOW_SPEC_TYPE_COS, 3225 FlowSpecNameMap[FLOW_SPEC_TYPE_INNER_VID]: FLOW_SPEC_TYPE_INNER_VID, 3226 FlowSpecNameMap[FLOW_SPEC_TYPE_INNER_COS]: FLOW_SPEC_TYPE_INNER_COS, 3227 } 3228 3229 // Joins the given and args into a single string and normalize it. 3230 // Example: 3231 // args := []string{" & <=80", " tcp != udp ", " =! SA & =U! F", " = is-fragment+last-fragment"} 3232 // fmt.Printf("%q", normalizeFlowSpecOpValues(args)) 3233 // >>> ["<=80" "tcp" "!=udp" "=!SA" "&=U" "!F" "=is-fragment+last-fragment"] 3234 func normalizeFlowSpecOpValues(args []string) []string { 3235 // Extracts keywords from the given args. 3236 sub := "" 3237 subs := make([]string, 0) 3238 for _, s := range _regexpFlowSpecOperator.FindAllString(strings.Join(args, " "), -1) { 3239 sub += s 3240 if _regexpFlowSpecOperatorValue.MatchString(s) { 3241 subs = append(subs, sub) 3242 sub = "" 3243 } 3244 } 3245 3246 // RFC5575 says "It should be unset in the first operator byte of a 3247 // sequence". 3248 if len(subs) > 0 { 3249 subs[0] = strings.TrimPrefix(subs[0], "&") 3250 } 3251 3252 return subs 3253 } 3254 3255 // Parses the FlowSpec numeric operator using the given submatch which should be 3256 // the return value of func (*Regexp) FindStringSubmatch. 3257 func parseFlowSpecNumericOperator(submatch []string) (operator uint8, err error) { 3258 if submatch[1] == "&" { 3259 operator = DEC_NUM_OP_AND 3260 } 3261 value, ok := DECNumOpValueMap[submatch[2]] 3262 if !ok { 3263 return 0, fmt.Errorf("invalid numeric operator: %s%s", submatch[1], submatch[2]) 3264 } 3265 operator |= uint8(value) 3266 return operator, nil 3267 } 3268 3269 // Parses the pairs of operator and value for the FlowSpec numeric type. The 3270 // given validationFunc is applied to evaluate whether the parsed value is 3271 // valid or not (e.g., if exceeds range or not). 3272 // Note: Each of the args should be formatted in single pair of operator and 3273 // value before calling this function. 3274 // e.g.) "&==100", ">=200" or "&<300" 3275 func parseFlowSpecNumericOpValues(typ BGPFlowSpecType, args []string, validationFunc func(uint64) error) (FlowSpecComponentInterface, error) { 3276 argsLen := len(args) 3277 items := make([]*FlowSpecComponentItem, 0, argsLen) 3278 for idx, arg := range args { 3279 m := _regexpFlowSpecNumericType.FindStringSubmatch(arg) 3280 if len(m) < 4 { 3281 return nil, fmt.Errorf("invalid argument for %s: %s in %q", typ.String(), arg, args) 3282 } 3283 operator, err := parseFlowSpecNumericOperator(m) 3284 if err != nil { 3285 return nil, err 3286 } 3287 // "true" and "false" is operator, but here handles them as value. 3288 var value uint64 3289 switch m[3] { 3290 case "true", "false": 3291 if idx != argsLen-1 { 3292 return nil, fmt.Errorf("%s should be the last of each rule", m[3]) 3293 } 3294 operator = uint8(DECNumOpValueMap[m[3]]) 3295 default: 3296 if value, err = strconv.ParseUint(m[3], 10, 64); err != nil { 3297 return nil, fmt.Errorf("invalid numeric value: %s", m[3]) 3298 } 3299 if err = validationFunc(value); err != nil { 3300 return nil, err 3301 } 3302 } 3303 items = append(items, NewFlowSpecComponentItem(operator, value)) 3304 } 3305 3306 // Marks end-of-list bit 3307 items[argsLen-1].Op |= uint8(DEC_NUM_OP_END) 3308 3309 return NewFlowSpecComponent(typ, items), nil 3310 } 3311 3312 func flowSpecNumeric1ByteParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3313 args = normalizeFlowSpecOpValues(args) 3314 3315 f := func(i uint64) error { 3316 if i <= 0xff { // 1 byte 3317 return nil 3318 } 3319 return fmt.Errorf("%s range exceeded", typ.String()) 3320 } 3321 3322 return parseFlowSpecNumericOpValues(typ, args, f) 3323 } 3324 3325 func flowSpecNumeric2BytesParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3326 args = normalizeFlowSpecOpValues(args) 3327 3328 f := func(i uint64) error { 3329 if i <= 0xffff { // 2 bytes 3330 return nil 3331 } 3332 return fmt.Errorf("%s range exceeded", typ.String()) 3333 } 3334 3335 return parseFlowSpecNumericOpValues(typ, args, f) 3336 } 3337 3338 // Parses the FlowSpec bitmask operand using the given submatch which should be 3339 // the return value of func (*Regexp) FindStringSubmatch. 3340 func parseFlowSpecBitmaskOperand(submatch []string) (operand uint8, err error) { 3341 if submatch[1] == "&" { 3342 operand = BITMASK_FLAG_OP_AND 3343 } 3344 value, ok := BitmaskFlagOpValueMap[submatch[2]] 3345 if !ok { 3346 return 0, fmt.Errorf("invalid bitmask operand: %s%s", submatch[1], submatch[2]) 3347 } 3348 operand |= uint8(value) 3349 return operand, nil 3350 } 3351 3352 func flowSpecPrefixParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3353 // args[0]: IP Prefix or IP Address (suppose prefix length is 32) 3354 // args[1]: Offset in bit (IPv6 only) 3355 // 3356 // Example: 3357 // - IPv4 Prefix 3358 // args := []string{"192.168.0.0/24"} 3359 // - IPv4 Address 3360 // args := []string{"192.168.0.1"} 3361 // - IPv6 Prefix 3362 // args := []string{"2001:db8:1::/64"} 3363 // - IPv6 Prefix with offset 3364 // args := []string{"0:db8:1::/64/16"} 3365 // args := []string{"0:db8:1::/64", "16"} 3366 // - IPv6 Address 3367 // args := []string{"2001:db8:1::1"} 3368 // - IPv6 Address with offset 3369 // args := []string{"0:db8:1::1", "16"} 3370 afi, _ := RouteFamilyToAfiSafi(rf) 3371 switch afi { 3372 case AFI_IP: 3373 if len(args) > 1 { 3374 return nil, fmt.Errorf("cannot specify offset for ipv4 prefix") 3375 } 3376 invalidIPv4PrefixError := fmt.Errorf("invalid ipv4 prefix: %s", args[0]) 3377 m := _regexpFindIPv4Prefix.FindStringSubmatch(args[0]) 3378 if len(m) < 4 { 3379 return nil, invalidIPv4PrefixError 3380 } 3381 prefix := net.ParseIP(m[1]) 3382 if prefix.To4() == nil { 3383 return nil, invalidIPv4PrefixError 3384 } 3385 var prefixLen uint64 = 32 3386 if m[3] != "" { 3387 var err error 3388 prefixLen, err = strconv.ParseUint(m[3], 10, 8) 3389 if err != nil || prefixLen > 32 { 3390 return nil, invalidIPv4PrefixError 3391 } 3392 } 3393 switch typ { 3394 case FLOW_SPEC_TYPE_DST_PREFIX: 3395 return NewFlowSpecDestinationPrefix(NewIPAddrPrefix(uint8(prefixLen), prefix.String())), nil 3396 case FLOW_SPEC_TYPE_SRC_PREFIX: 3397 return NewFlowSpecSourcePrefix(NewIPAddrPrefix(uint8(prefixLen), prefix.String())), nil 3398 } 3399 return nil, fmt.Errorf("invalid traffic filtering rule type: %s", typ.String()) 3400 case AFI_IP6: 3401 if len(args) > 2 { 3402 return nil, fmt.Errorf("invalid arguments for ipv6 prefix: %q", args) 3403 } 3404 invalidIPv6PrefixError := fmt.Errorf("invalid ipv6 prefix: %s", args[0]) 3405 m := _regexpFindIPv6Prefix.FindStringSubmatch(args[0]) 3406 if len(m) < 4 { 3407 return nil, invalidIPv6PrefixError 3408 } 3409 prefix := net.ParseIP(m[1]) 3410 if prefix.To16() == nil { 3411 return nil, invalidIPv6PrefixError 3412 } 3413 var prefixLen uint64 = 128 3414 if m[3] != "" { 3415 var err error 3416 prefixLen, err = strconv.ParseUint(m[3], 10, 8) 3417 if err != nil || prefixLen > 128 { 3418 return nil, invalidIPv6PrefixError 3419 } 3420 } 3421 var offset uint64 3422 if len(args) == 1 && m[5] != "" { 3423 var err error 3424 offset, err = strconv.ParseUint(m[5], 10, 8) 3425 if err != nil || offset > 128 { 3426 return nil, fmt.Errorf("invalid ipv6 prefix offset: %s", m[5]) 3427 } 3428 } else if len(args) == 2 { 3429 if m[5] != "" { 3430 return nil, fmt.Errorf("multiple ipv6 prefix offset arguments detected: %q", args) 3431 } 3432 var err error 3433 offset, err = strconv.ParseUint(args[1], 10, 8) 3434 if err != nil || offset > 128 { 3435 return nil, fmt.Errorf("invalid ipv6 prefix offset: %s", args[1]) 3436 } 3437 } 3438 switch typ { 3439 case FLOW_SPEC_TYPE_DST_PREFIX: 3440 return NewFlowSpecDestinationPrefix6(NewIPv6AddrPrefix(uint8(prefixLen), prefix.String()), uint8(offset)), nil 3441 case FLOW_SPEC_TYPE_SRC_PREFIX: 3442 return NewFlowSpecSourcePrefix6(NewIPv6AddrPrefix(uint8(prefixLen), prefix.String()), uint8(offset)), nil 3443 } 3444 return nil, fmt.Errorf("invalid traffic filtering rule type: %s", typ.String()) 3445 } 3446 return nil, fmt.Errorf("invalid address family: %s", rf.String()) 3447 } 3448 3449 func flowSpecIpProtoParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3450 // args: List of pairs of Operator and IP protocol type 3451 // 3452 // Example: 3453 // - TCP or UDP 3454 // args := []string{"tcp", "==udp"} 3455 // - Not TCP and not UDP 3456 // args := []string{"!=tcp", "&!=udp"} 3457 args = normalizeFlowSpecOpValues(args) 3458 s := strings.Join(args, " ") 3459 for i, name := range ProtocolNameMap { 3460 s = strings.Replace(s, name, fmt.Sprintf("%d", i), -1) 3461 } 3462 args = strings.Split(s, " ") 3463 3464 f := func(i uint64) error { 3465 if i <= 0xff { // 1 byte 3466 return nil 3467 } 3468 return fmt.Errorf("%s range exceeded", typ.String()) 3469 } 3470 3471 return parseFlowSpecNumericOpValues(typ, args, f) 3472 } 3473 3474 func flowSpecTcpFlagParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3475 // args: List of pairs of Operand and TCP Flags 3476 // 3477 // Example: 3478 // - SYN or SYN/ACK 3479 // args := []string{"==S", "==SA"} 3480 // - Not FIN and not URG 3481 // args := []string{"!=F", "&!=U"} 3482 args = normalizeFlowSpecOpValues(args) 3483 3484 argsLen := len(args) 3485 items := make([]*FlowSpecComponentItem, 0, argsLen) 3486 3487 for _, arg := range args { 3488 m := _regexpFlowSpecTCPFlag.FindStringSubmatch(arg) 3489 if len(m) < 6 { 3490 return nil, fmt.Errorf("invalid argument for %s: %s in %q", typ.String(), arg, args) 3491 } else if mLast := m[len(m)-1]; mLast != "" || m[3] != "" { 3492 return nil, fmt.Errorf("invalid argument for %s: %s in %q", typ.String(), arg, args) 3493 } 3494 operand, err := parseFlowSpecBitmaskOperand(m) 3495 if err != nil { 3496 return nil, err 3497 } 3498 var value uint64 3499 for flag, name := range TCPFlagNameMap { 3500 if strings.Contains(m[4], name) { 3501 value |= uint64(flag) 3502 } 3503 } 3504 items = append(items, NewFlowSpecComponentItem(operand, value)) 3505 } 3506 3507 // Marks end-of-list bit 3508 items[argsLen-1].Op |= BITMASK_FLAG_OP_END 3509 3510 return NewFlowSpecComponent(typ, items), nil 3511 } 3512 3513 func flowSpecDscpParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3514 args = normalizeFlowSpecOpValues(args) 3515 3516 f := func(i uint64) error { 3517 if i < 64 { // 6 bits 3518 return nil 3519 } 3520 return fmt.Errorf("%s range exceeded", typ.String()) 3521 } 3522 3523 return parseFlowSpecNumericOpValues(typ, args, f) 3524 } 3525 3526 func flowSpecFragmentParser(_ RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3527 // args: List of pairs of Operator and Fragment flags 3528 // 3529 // Example: 3530 // - is-fragment or last-fragment 3531 // args := []string{"==is-fragment", "==last-fragment"} 3532 // - is-fragment and last-fragment (exact match) 3533 // args := []string{"==is-fragment+last-fragment"} 3534 args = normalizeFlowSpecOpValues(args) 3535 3536 argsLen := len(args) 3537 items := make([]*FlowSpecComponentItem, 0, argsLen) 3538 3539 for _, arg := range args { 3540 m := _regexpFlowSpecFragment.FindStringSubmatch(arg) 3541 if len(m) < 4 { 3542 return nil, fmt.Errorf("invalid argument for %s: %s in %q", typ.String(), arg, args) 3543 } else if mLast := m[len(m)-1]; mLast != "" { 3544 return nil, fmt.Errorf("invalid argument for %s: %s in %q", typ.String(), arg, args) 3545 } 3546 operand, err := parseFlowSpecBitmaskOperand(m) 3547 if err != nil { 3548 return nil, err 3549 } 3550 var value uint64 3551 // Example: 3552 // m[3] = "first-fragment+last-fragment" 3553 for flag, name := range FragmentFlagNameMap { 3554 if strings.Contains(m[3], name) { 3555 value |= uint64(flag) 3556 } 3557 } 3558 items = append(items, NewFlowSpecComponentItem(operand, value)) 3559 } 3560 3561 // Marks end-of-list bit 3562 items[argsLen-1].Op |= BITMASK_FLAG_OP_END 3563 3564 return NewFlowSpecComponent(typ, items), nil 3565 } 3566 3567 func flowSpecLabelParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3568 afi, _ := RouteFamilyToAfiSafi(rf) 3569 if afi == AFI_IP { 3570 return nil, fmt.Errorf("%s is not supported for ipv4", typ.String()) 3571 } 3572 3573 args = normalizeFlowSpecOpValues(args) 3574 3575 f := func(i uint64) error { 3576 if i <= 0xfffff { // 20 bits 3577 return nil 3578 } 3579 return fmt.Errorf("flow label range exceeded") 3580 } 3581 3582 return parseFlowSpecNumericOpValues(typ, args, f) 3583 } 3584 3585 func flowSpecEtherTypeParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3586 // args: List of pairs of Operator and Ether Types 3587 // 3588 // Example: 3589 // - ARP or IPv4 3590 // args := []string{"==arp", "==ipv4"} 3591 // - Not IPv4 and not IPv6 3592 // args := []string{"!=ipv4", "&!=ipv6"} 3593 if rf != RF_FS_L2_VPN { 3594 return nil, fmt.Errorf("%s is supported for only l2vpn", typ.String()) 3595 } 3596 3597 args = normalizeFlowSpecOpValues(args) 3598 s := strings.Join(args, " ") 3599 for i, name := range EthernetTypeNameMap { 3600 s = strings.Replace(s, name, fmt.Sprintf("%d", i), -1) 3601 } 3602 args = strings.Split(s, " ") 3603 3604 f := func(i uint64) error { 3605 if i <= 0xffff { // 2 bytes 3606 return nil 3607 } 3608 return fmt.Errorf("%s range exceeded", typ.String()) 3609 } 3610 3611 return parseFlowSpecNumericOpValues(typ, args, f) 3612 } 3613 3614 func flowSpecMacParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3615 // args[0]: MAC address 3616 if rf != RF_FS_L2_VPN { 3617 return nil, fmt.Errorf("%s is supported for only l2vpn", typ.String()) 3618 } 3619 3620 mac, err := net.ParseMAC(args[0]) 3621 if err != nil { 3622 return nil, fmt.Errorf("invalid mac address: %s", args[0]) 3623 } 3624 3625 switch typ { 3626 case FLOW_SPEC_TYPE_DST_MAC: 3627 return NewFlowSpecDestinationMac(mac), nil 3628 case FLOW_SPEC_TYPE_SRC_MAC: 3629 return NewFlowSpecSourceMac(mac), nil 3630 } 3631 return nil, fmt.Errorf("invalid traffic filtering rule type: %s", typ.String()) 3632 } 3633 3634 func flowSpecLlcParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3635 if rf != RF_FS_L2_VPN { 3636 return nil, fmt.Errorf("%s is supported for only l2vpn", typ.String()) 3637 } 3638 3639 return flowSpecNumeric1ByteParser(rf, typ, args) 3640 } 3641 3642 func flowSpecSnapParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3643 if rf != RF_FS_L2_VPN { 3644 return nil, fmt.Errorf("%s is supported for only l2vpn", typ.String()) 3645 } 3646 3647 args = normalizeFlowSpecOpValues(args) 3648 3649 f := func(i uint64) error { 3650 if i <= 0xffffffffff { // 5 bytes 3651 return nil 3652 } 3653 return fmt.Errorf("%s range exceeded", typ.String()) 3654 } 3655 3656 return parseFlowSpecNumericOpValues(typ, args, f) 3657 } 3658 3659 func flowSpecVlanIDParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3660 if rf != RF_FS_L2_VPN { 3661 return nil, fmt.Errorf("%s is supported for only l2vpn", typ.String()) 3662 } 3663 3664 args = normalizeFlowSpecOpValues(args) 3665 s := strings.Join(args, " ") 3666 for i, name := range EthernetTypeNameMap { 3667 s = strings.Replace(s, name, fmt.Sprintf("%d", i), -1) 3668 } 3669 args = strings.Split(s, " ") 3670 3671 f := func(i uint64) error { 3672 if i <= 4095 { // 12 bits 3673 return nil 3674 } 3675 return fmt.Errorf("%s range exceeded", typ.String()) 3676 } 3677 3678 return parseFlowSpecNumericOpValues(typ, args, f) 3679 } 3680 3681 func flowSpecVlanCosParser(rf RouteFamily, typ BGPFlowSpecType, args []string) (FlowSpecComponentInterface, error) { 3682 if rf != RF_FS_L2_VPN { 3683 return nil, fmt.Errorf("%s is supported for only l2vpn", typ.String()) 3684 } 3685 3686 args = normalizeFlowSpecOpValues(args) 3687 s := strings.Join(args, " ") 3688 for i, name := range EthernetTypeNameMap { 3689 s = strings.Replace(s, name, fmt.Sprintf("%d", i), -1) 3690 } 3691 args = strings.Split(s, " ") 3692 3693 f := func(i uint64) error { 3694 if i <= 7 { // 3 bits 3695 return nil 3696 } 3697 return fmt.Errorf("%s range exceeded", typ.String()) 3698 } 3699 3700 return parseFlowSpecNumericOpValues(typ, args, f) 3701 } 3702 3703 var flowSpecParserMap = map[BGPFlowSpecType]func(RouteFamily, BGPFlowSpecType, []string) (FlowSpecComponentInterface, error){ 3704 FLOW_SPEC_TYPE_DST_PREFIX: flowSpecPrefixParser, 3705 FLOW_SPEC_TYPE_SRC_PREFIX: flowSpecPrefixParser, 3706 FLOW_SPEC_TYPE_IP_PROTO: flowSpecIpProtoParser, 3707 FLOW_SPEC_TYPE_PORT: flowSpecNumeric2BytesParser, 3708 FLOW_SPEC_TYPE_DST_PORT: flowSpecNumeric2BytesParser, 3709 FLOW_SPEC_TYPE_SRC_PORT: flowSpecNumeric2BytesParser, 3710 FLOW_SPEC_TYPE_ICMP_TYPE: flowSpecNumeric1ByteParser, 3711 FLOW_SPEC_TYPE_ICMP_CODE: flowSpecNumeric1ByteParser, 3712 FLOW_SPEC_TYPE_TCP_FLAG: flowSpecTcpFlagParser, 3713 FLOW_SPEC_TYPE_PKT_LEN: flowSpecNumeric2BytesParser, 3714 FLOW_SPEC_TYPE_DSCP: flowSpecDscpParser, 3715 FLOW_SPEC_TYPE_FRAGMENT: flowSpecFragmentParser, 3716 FLOW_SPEC_TYPE_LABEL: flowSpecLabelParser, 3717 FLOW_SPEC_TYPE_ETHERNET_TYPE: flowSpecEtherTypeParser, 3718 FLOW_SPEC_TYPE_DST_MAC: flowSpecMacParser, 3719 FLOW_SPEC_TYPE_SRC_MAC: flowSpecMacParser, 3720 FLOW_SPEC_TYPE_LLC_DSAP: flowSpecLlcParser, 3721 FLOW_SPEC_TYPE_LLC_SSAP: flowSpecLlcParser, 3722 FLOW_SPEC_TYPE_LLC_CONTROL: flowSpecLlcParser, 3723 FLOW_SPEC_TYPE_SNAP: flowSpecSnapParser, 3724 FLOW_SPEC_TYPE_VID: flowSpecVlanIDParser, 3725 FLOW_SPEC_TYPE_COS: flowSpecVlanCosParser, 3726 FLOW_SPEC_TYPE_INNER_VID: flowSpecVlanIDParser, 3727 FLOW_SPEC_TYPE_INNER_COS: flowSpecVlanCosParser, 3728 } 3729 3730 func extractFlowSpecArgs(args []string) map[BGPFlowSpecType][]string { 3731 m := make(map[BGPFlowSpecType][]string, len(FlowSpecValueMap)) 3732 var typ BGPFlowSpecType 3733 for _, arg := range args { 3734 if t, ok := FlowSpecValueMap[arg]; ok { 3735 typ = t 3736 m[typ] = make([]string, 0) 3737 } else { 3738 m[typ] = append(m[typ], arg) 3739 } 3740 } 3741 return m 3742 } 3743 3744 func ParseFlowSpecComponents(rf RouteFamily, arg string) ([]FlowSpecComponentInterface, error) { 3745 _, safi := RouteFamilyToAfiSafi(rf) 3746 switch safi { 3747 case SAFI_FLOW_SPEC_UNICAST, SAFI_FLOW_SPEC_VPN: 3748 // Valid 3749 default: 3750 return nil, fmt.Errorf("invalid address family: %s", rf.String()) 3751 } 3752 3753 typeArgs := extractFlowSpecArgs(strings.Split(arg, " ")) 3754 rules := make([]FlowSpecComponentInterface, 0, len(typeArgs)) 3755 for typ, args := range typeArgs { 3756 parser, ok := flowSpecParserMap[typ] 3757 if !ok { 3758 return nil, fmt.Errorf("unsupported traffic filtering rule type: %s", typ.String()) 3759 } 3760 if len(args) == 0 { 3761 return nil, fmt.Errorf("specify traffic filtering rules for %s", typ.String()) 3762 } 3763 rule, err := parser(rf, typ, args) 3764 if err != nil { 3765 return nil, err 3766 } 3767 rules = append(rules, rule) 3768 } 3769 return rules, nil 3770 } 3771 3772 func (t BGPFlowSpecType) String() string { 3773 name, ok := FlowSpecNameMap[t] 3774 if !ok { 3775 return fmt.Sprintf("%s(%d)", FlowSpecNameMap[FLOW_SPEC_TYPE_UNKNOWN], t) 3776 } 3777 return name 3778 } 3779 3780 type FlowSpecComponentInterface interface { 3781 DecodeFromBytes([]byte, ...*MarshallingOption) error 3782 Serialize(...*MarshallingOption) ([]byte, error) 3783 Len(...*MarshallingOption) int 3784 Type() BGPFlowSpecType 3785 String() string 3786 } 3787 3788 type flowSpecPrefix struct { 3789 Prefix AddrPrefixInterface 3790 typ BGPFlowSpecType 3791 } 3792 3793 func (p *flowSpecPrefix) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 3794 p.typ = BGPFlowSpecType(data[0]) 3795 return p.Prefix.DecodeFromBytes(data[1:], options...) 3796 } 3797 3798 func (p *flowSpecPrefix) Serialize(options ...*MarshallingOption) ([]byte, error) { 3799 buf := []byte{byte(p.Type())} 3800 bbuf, err := p.Prefix.Serialize(options...) 3801 if err != nil { 3802 return nil, err 3803 } 3804 return append(buf, bbuf...), nil 3805 } 3806 3807 func (p *flowSpecPrefix) Len(options ...*MarshallingOption) int { 3808 buf, _ := p.Serialize(options...) 3809 return len(buf) 3810 } 3811 3812 func (p *flowSpecPrefix) Type() BGPFlowSpecType { 3813 return p.typ 3814 } 3815 3816 func (p *flowSpecPrefix) String() string { 3817 return fmt.Sprintf("[%s: %s]", p.Type(), p.Prefix.String()) 3818 } 3819 3820 func (p *flowSpecPrefix) MarshalJSON() ([]byte, error) { 3821 return json.Marshal(struct { 3822 Type BGPFlowSpecType `json:"type"` 3823 Value AddrPrefixInterface `json:"value"` 3824 }{ 3825 Type: p.Type(), 3826 Value: p.Prefix, 3827 }) 3828 } 3829 3830 type flowSpecPrefix6 struct { 3831 Prefix AddrPrefixInterface 3832 Offset uint8 3833 typ BGPFlowSpecType 3834 } 3835 3836 // draft-ietf-idr-flow-spec-v6-06 3837 // <type (1 octet), prefix length (1 octet), prefix offset(1 octet), prefix> 3838 func (p *flowSpecPrefix6) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 3839 p.typ = BGPFlowSpecType(data[0]) 3840 p.Offset = data[2] 3841 prefix := append([]byte{data[1]}, data[3:]...) 3842 return p.Prefix.DecodeFromBytes(prefix, options...) 3843 } 3844 3845 func (p *flowSpecPrefix6) Serialize(options ...*MarshallingOption) ([]byte, error) { 3846 buf := []byte{byte(p.Type())} 3847 bbuf, err := p.Prefix.Serialize(options...) 3848 if err != nil { 3849 return nil, err 3850 } 3851 buf = append(buf, bbuf[0]) 3852 buf = append(buf, p.Offset) 3853 return append(buf, bbuf[1:]...), nil 3854 } 3855 3856 func (p *flowSpecPrefix6) Len(options ...*MarshallingOption) int { 3857 buf, _ := p.Serialize(options...) 3858 return len(buf) 3859 } 3860 3861 func (p *flowSpecPrefix6) Type() BGPFlowSpecType { 3862 return p.typ 3863 } 3864 3865 func (p *flowSpecPrefix6) String() string { 3866 return fmt.Sprintf("[%s: %s/%d]", p.Type(), p.Prefix.String(), p.Offset) 3867 } 3868 3869 func (p *flowSpecPrefix6) MarshalJSON() ([]byte, error) { 3870 return json.Marshal(struct { 3871 Type BGPFlowSpecType `json:"type"` 3872 Value AddrPrefixInterface `json:"value"` 3873 Offset uint8 `json:"offset"` 3874 }{ 3875 Type: p.Type(), 3876 Value: p.Prefix, 3877 Offset: p.Offset, 3878 }) 3879 } 3880 3881 type FlowSpecDestinationPrefix struct { 3882 flowSpecPrefix 3883 } 3884 3885 func NewFlowSpecDestinationPrefix(prefix AddrPrefixInterface) *FlowSpecDestinationPrefix { 3886 return &FlowSpecDestinationPrefix{flowSpecPrefix{prefix, FLOW_SPEC_TYPE_DST_PREFIX}} 3887 } 3888 3889 type FlowSpecSourcePrefix struct { 3890 flowSpecPrefix 3891 } 3892 3893 func NewFlowSpecSourcePrefix(prefix AddrPrefixInterface) *FlowSpecSourcePrefix { 3894 return &FlowSpecSourcePrefix{flowSpecPrefix{prefix, FLOW_SPEC_TYPE_SRC_PREFIX}} 3895 } 3896 3897 type FlowSpecDestinationPrefix6 struct { 3898 flowSpecPrefix6 3899 } 3900 3901 func NewFlowSpecDestinationPrefix6(prefix AddrPrefixInterface, offset uint8) *FlowSpecDestinationPrefix6 { 3902 return &FlowSpecDestinationPrefix6{flowSpecPrefix6{prefix, offset, FLOW_SPEC_TYPE_DST_PREFIX}} 3903 } 3904 3905 type FlowSpecSourcePrefix6 struct { 3906 flowSpecPrefix6 3907 } 3908 3909 func NewFlowSpecSourcePrefix6(prefix AddrPrefixInterface, offset uint8) *FlowSpecSourcePrefix6 { 3910 return &FlowSpecSourcePrefix6{flowSpecPrefix6{prefix, offset, FLOW_SPEC_TYPE_SRC_PREFIX}} 3911 } 3912 3913 type flowSpecMac struct { 3914 Mac net.HardwareAddr 3915 typ BGPFlowSpecType 3916 } 3917 3918 func (p *flowSpecMac) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 3919 if len(data) < 2 || len(data) < 2+int(data[1]) { 3920 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all mac bits available") 3921 } 3922 p.typ = BGPFlowSpecType(data[0]) 3923 p.Mac = net.HardwareAddr(data[2 : 2+int(data[1])]) 3924 return nil 3925 } 3926 3927 func (p *flowSpecMac) Serialize(options ...*MarshallingOption) ([]byte, error) { 3928 if len(p.Mac) == 0 { 3929 return nil, fmt.Errorf("mac unset") 3930 } 3931 buf := []byte{byte(p.Type()), byte(len(p.Mac))} 3932 return append(buf, []byte(p.Mac)...), nil 3933 } 3934 3935 func (p *flowSpecMac) Len(options ...*MarshallingOption) int { 3936 return 2 + len(p.Mac) 3937 } 3938 3939 func (p *flowSpecMac) Type() BGPFlowSpecType { 3940 return p.typ 3941 } 3942 3943 func (p *flowSpecMac) String() string { 3944 return fmt.Sprintf("[%s: %s]", p.Type(), p.Mac.String()) 3945 } 3946 3947 func (p *flowSpecMac) MarshalJSON() ([]byte, error) { 3948 return json.Marshal(struct { 3949 Type BGPFlowSpecType `json:"type"` 3950 Value string `json:"value"` 3951 }{ 3952 Type: p.Type(), 3953 Value: p.Mac.String(), 3954 }) 3955 } 3956 3957 type FlowSpecSourceMac struct { 3958 flowSpecMac 3959 } 3960 3961 func NewFlowSpecSourceMac(mac net.HardwareAddr) *FlowSpecSourceMac { 3962 return &FlowSpecSourceMac{flowSpecMac{Mac: mac, typ: FLOW_SPEC_TYPE_SRC_MAC}} 3963 } 3964 3965 type FlowSpecDestinationMac struct { 3966 flowSpecMac 3967 } 3968 3969 func NewFlowSpecDestinationMac(mac net.HardwareAddr) *FlowSpecDestinationMac { 3970 return &FlowSpecDestinationMac{flowSpecMac{Mac: mac, typ: FLOW_SPEC_TYPE_DST_MAC}} 3971 } 3972 3973 type FlowSpecComponentItem struct { 3974 Op uint8 `json:"op"` 3975 Value uint64 `json:"value"` 3976 } 3977 3978 func (v *FlowSpecComponentItem) Len() int { 3979 return 1 << ((uint32(v.Op) >> 4) & 0x3) 3980 } 3981 3982 func (v *FlowSpecComponentItem) Serialize() ([]byte, error) { 3983 if v.Op > math.MaxUint8 { 3984 return nil, fmt.Errorf("invalid op size: %d", v.Op) 3985 } 3986 3987 order := uint32(math.Log2(float64(v.Len()))) 3988 buf := make([]byte, 1+(1<<order)) 3989 buf[0] = byte(uint32(v.Op) | order<<4) 3990 switch order { 3991 case 0: 3992 buf[1] = byte(v.Value) 3993 case 1: 3994 binary.BigEndian.PutUint16(buf[1:], uint16(v.Value)) 3995 case 2: 3996 binary.BigEndian.PutUint32(buf[1:], uint32(v.Value)) 3997 case 3: 3998 binary.BigEndian.PutUint64(buf[1:], uint64(v.Value)) 3999 default: 4000 return nil, fmt.Errorf("invalid value size(too big): %d", v.Value) 4001 } 4002 return buf, nil 4003 } 4004 4005 func NewFlowSpecComponentItem(op uint8, value uint64) *FlowSpecComponentItem { 4006 v := &FlowSpecComponentItem{op, value} 4007 order := uint32(math.Log2(float64(v.Len()))) 4008 // we don't know if not initialized properly or initialized to 4009 // zero... 4010 if order == 0 { 4011 order = func() uint32 { 4012 for i := 0; i < 3; i++ { 4013 if v.Value < (1 << ((1 << uint(i)) * 8)) { 4014 return uint32(i) 4015 } 4016 } 4017 // return invalid order 4018 return 4 4019 }() 4020 } 4021 if order > 3 { 4022 return nil 4023 } 4024 v.Op = uint8(uint32(v.Op) | order<<4) 4025 return v 4026 } 4027 4028 type FlowSpecComponent struct { 4029 Items []*FlowSpecComponentItem 4030 typ BGPFlowSpecType 4031 } 4032 4033 func (p *FlowSpecComponent) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4034 p.typ = BGPFlowSpecType(data[0]) 4035 data = data[1:] 4036 p.Items = make([]*FlowSpecComponentItem, 0) 4037 for { 4038 if len(data) < 2 { 4039 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all flowspec component bytes available") 4040 } 4041 op := data[0] 4042 end := op & 0x80 4043 l := 1 << ((op >> 4) & 0x3) // (min, max) = (1, 8) 4044 v := make([]byte, 8) 4045 copy(v[8-l:], data[1:1+l]) 4046 i := binary.BigEndian.Uint64(v) 4047 item := &FlowSpecComponentItem{op, i} 4048 p.Items = append(p.Items, item) 4049 if end > 0 { 4050 break 4051 } 4052 data = data[1+l:] 4053 } 4054 return nil 4055 } 4056 4057 func (p *FlowSpecComponent) Serialize(options ...*MarshallingOption) ([]byte, error) { 4058 buf := []byte{byte(p.Type())} 4059 for _, v := range p.Items { 4060 bbuf, err := v.Serialize() 4061 if err != nil { 4062 return nil, err 4063 } 4064 buf = append(buf, bbuf...) 4065 } 4066 return buf, nil 4067 } 4068 4069 func (p *FlowSpecComponent) Len(options ...*MarshallingOption) int { 4070 l := 1 4071 for _, item := range p.Items { 4072 l += item.Len() + 1 4073 } 4074 return l 4075 } 4076 4077 func (p *FlowSpecComponent) Type() BGPFlowSpecType { 4078 return p.typ 4079 } 4080 4081 func formatRaw(op uint8, value uint64) string { 4082 return fmt.Sprintf("op:%b,value:%d", op, value) 4083 } 4084 4085 func formatNumeric(op uint8, value uint64) string { 4086 cmpFlag := DECNumOp(op & 0x7) // lower 3 bits 4087 if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { 4088 // Omit value field 4089 return DECNumOp(op).String() 4090 } 4091 return fmt.Sprint(DECNumOp(op).String(), value) 4092 } 4093 4094 func formatProto(op uint8, value uint64) string { 4095 cmpFlag := DECNumOp(op & 0x7) // lower 3 bits 4096 if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { 4097 // Omit value field 4098 return DECNumOp(op).String() 4099 } 4100 return fmt.Sprint(DECNumOp(op).String(), Protocol(value).String()) 4101 } 4102 4103 func formatTCPFlag(op uint8, value uint64) string { 4104 return fmt.Sprint(BitmaskFlagOp(op).String(), TCPFlag(value).String()) 4105 } 4106 4107 func formatFragment(op uint8, value uint64) string { 4108 return fmt.Sprint(BitmaskFlagOp(op).String(), FragmentFlag(value).String()) 4109 } 4110 4111 func formatEtherType(op uint8, value uint64) string { 4112 cmpFlag := DECNumOp(op & 0x7) // lower 3 bits 4113 if cmpFlag == DEC_NUM_OP_TRUE || cmpFlag == DEC_NUM_OP_FALSE { 4114 // Omit value field 4115 return DECNumOp(op).String() 4116 } 4117 return fmt.Sprint(DECNumOp(op).String(), EthernetType(value).String()) 4118 } 4119 4120 var flowSpecFormatMap = map[BGPFlowSpecType]func(op uint8, value uint64) string{ 4121 FLOW_SPEC_TYPE_UNKNOWN: formatRaw, 4122 FLOW_SPEC_TYPE_IP_PROTO: formatProto, 4123 FLOW_SPEC_TYPE_PORT: formatNumeric, 4124 FLOW_SPEC_TYPE_DST_PORT: formatNumeric, 4125 FLOW_SPEC_TYPE_SRC_PORT: formatNumeric, 4126 FLOW_SPEC_TYPE_ICMP_TYPE: formatNumeric, 4127 FLOW_SPEC_TYPE_ICMP_CODE: formatNumeric, 4128 FLOW_SPEC_TYPE_TCP_FLAG: formatTCPFlag, 4129 FLOW_SPEC_TYPE_PKT_LEN: formatNumeric, 4130 FLOW_SPEC_TYPE_DSCP: formatNumeric, 4131 FLOW_SPEC_TYPE_FRAGMENT: formatFragment, 4132 FLOW_SPEC_TYPE_LABEL: formatNumeric, 4133 FLOW_SPEC_TYPE_ETHERNET_TYPE: formatEtherType, 4134 FLOW_SPEC_TYPE_LLC_DSAP: formatNumeric, 4135 FLOW_SPEC_TYPE_LLC_SSAP: formatNumeric, 4136 FLOW_SPEC_TYPE_LLC_CONTROL: formatNumeric, 4137 FLOW_SPEC_TYPE_SNAP: formatNumeric, 4138 FLOW_SPEC_TYPE_VID: formatNumeric, 4139 FLOW_SPEC_TYPE_COS: formatNumeric, 4140 FLOW_SPEC_TYPE_INNER_VID: formatNumeric, 4141 FLOW_SPEC_TYPE_INNER_COS: formatNumeric, 4142 } 4143 4144 func (p *FlowSpecComponent) String() string { 4145 f := flowSpecFormatMap[FLOW_SPEC_TYPE_UNKNOWN] 4146 if _, ok := flowSpecFormatMap[p.typ]; ok { 4147 f = flowSpecFormatMap[p.typ] 4148 } 4149 4150 items := make([]string, 0, len(p.Items)) 4151 for _, i := range p.Items { 4152 items = append(items, f(i.Op, i.Value)) 4153 } 4154 // Removes leading and tailing spaces 4155 value := strings.TrimSpace(strings.Join(items, "")) 4156 4157 return fmt.Sprintf("[%s: %s]", p.typ, value) 4158 } 4159 4160 func (p *FlowSpecComponent) MarshalJSON() ([]byte, error) { 4161 return json.Marshal(struct { 4162 Type BGPFlowSpecType `json:"type"` 4163 Value []*FlowSpecComponentItem `json:"value"` 4164 }{ 4165 Type: p.Type(), 4166 Value: p.Items, 4167 }) 4168 } 4169 4170 func NewFlowSpecComponent(typ BGPFlowSpecType, items []*FlowSpecComponentItem) *FlowSpecComponent { 4171 // Set end-of-list bit on the last item and unset them on the others. 4172 for i, v := range items { 4173 if i == len(items)-1 { 4174 v.Op |= 0x80 4175 } else { 4176 v.Op &^= 0x80 4177 } 4178 4179 } 4180 return &FlowSpecComponent{ 4181 Items: items, 4182 typ: typ, 4183 } 4184 } 4185 4186 type FlowSpecUnknown struct { 4187 Value []byte 4188 } 4189 4190 func (p *FlowSpecUnknown) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4191 p.Value = data 4192 return nil 4193 } 4194 4195 func (p *FlowSpecUnknown) Serialize(options ...*MarshallingOption) ([]byte, error) { 4196 return p.Value, nil 4197 } 4198 4199 func (p *FlowSpecUnknown) Len(options ...*MarshallingOption) int { 4200 return len(p.Value) 4201 } 4202 4203 func (p *FlowSpecUnknown) Type() BGPFlowSpecType { 4204 if len(p.Value) > 0 { 4205 return BGPFlowSpecType(p.Value[0]) 4206 } 4207 return FLOW_SPEC_TYPE_UNKNOWN 4208 } 4209 4210 func (p *FlowSpecUnknown) String() string { 4211 return fmt.Sprintf("[unknown:%v]", p.Value) 4212 } 4213 4214 func (p *FlowSpecUnknown) MarshalJSON() ([]byte, error) { 4215 return json.Marshal(struct { 4216 Type BGPFlowSpecType `json:"type"` 4217 Value string `json:"value"` 4218 }{ 4219 Type: p.Type(), 4220 Value: string(p.Value), 4221 }) 4222 } 4223 4224 type FlowSpecNLRI struct { 4225 PrefixDefault 4226 Value []FlowSpecComponentInterface 4227 rf RouteFamily 4228 rd RouteDistinguisherInterface 4229 } 4230 4231 func (n *FlowSpecNLRI) AFI() uint16 { 4232 afi, _ := RouteFamilyToAfiSafi(n.rf) 4233 return afi 4234 } 4235 4236 func (n *FlowSpecNLRI) SAFI() uint8 { 4237 _, safi := RouteFamilyToAfiSafi(n.rf) 4238 return safi 4239 } 4240 4241 func (n *FlowSpecNLRI) RD() RouteDistinguisherInterface { 4242 return n.rd 4243 } 4244 4245 func (n *FlowSpecNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...*MarshallingOption) error { 4246 if IsAddPathEnabled(true, rf, options) { 4247 var err error 4248 data, err = n.decodePathIdentifier(data) 4249 if err != nil { 4250 return err 4251 } 4252 } 4253 var length int 4254 if (data[0]>>4) == 0xf && len(data) > 2 { 4255 length = int(binary.BigEndian.Uint16(data[0:2])) 4256 data = data[2:] 4257 } else if len(data) > 1 { 4258 length = int(data[0]) 4259 data = data[1:] 4260 } else { 4261 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all flowspec component bytes available") 4262 } 4263 4264 n.rf = rf 4265 4266 if n.SAFI() == SAFI_FLOW_SPEC_VPN { 4267 if length < 8 { 4268 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all flowspec component bytes available") 4269 } 4270 n.rd = GetRouteDistinguisher(data[:8]) 4271 data = data[8:] 4272 length -= 8 4273 } 4274 4275 for l := length; l > 0; { 4276 if len(data) == 0 { 4277 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all flowspec component bytes available") 4278 } 4279 t := BGPFlowSpecType(data[0]) 4280 var i FlowSpecComponentInterface 4281 switch t { 4282 case FLOW_SPEC_TYPE_DST_PREFIX: 4283 switch { 4284 case rf>>16 == AFI_IP: 4285 i = NewFlowSpecDestinationPrefix(NewIPAddrPrefix(0, "")) 4286 case rf>>16 == AFI_IP6: 4287 i = NewFlowSpecDestinationPrefix6(NewIPv6AddrPrefix(0, ""), 0) 4288 default: 4289 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid address family: %v", rf)) 4290 } 4291 case FLOW_SPEC_TYPE_SRC_PREFIX: 4292 switch { 4293 case rf>>16 == AFI_IP: 4294 i = NewFlowSpecSourcePrefix(NewIPAddrPrefix(0, "")) 4295 case rf>>16 == AFI_IP6: 4296 i = NewFlowSpecSourcePrefix6(NewIPv6AddrPrefix(0, ""), 0) 4297 default: 4298 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid address family: %v", rf)) 4299 } 4300 case FLOW_SPEC_TYPE_SRC_MAC: 4301 switch rf { 4302 case RF_FS_L2_VPN: 4303 i = NewFlowSpecSourceMac(nil) 4304 default: 4305 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid address family: %v", rf)) 4306 } 4307 case FLOW_SPEC_TYPE_DST_MAC: 4308 switch rf { 4309 case RF_FS_L2_VPN: 4310 i = NewFlowSpecDestinationMac(nil) 4311 default: 4312 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Invalid address family: %v", rf)) 4313 } 4314 case FLOW_SPEC_TYPE_IP_PROTO, FLOW_SPEC_TYPE_PORT, FLOW_SPEC_TYPE_DST_PORT, FLOW_SPEC_TYPE_SRC_PORT, 4315 FLOW_SPEC_TYPE_ICMP_TYPE, FLOW_SPEC_TYPE_ICMP_CODE, FLOW_SPEC_TYPE_TCP_FLAG, FLOW_SPEC_TYPE_PKT_LEN, 4316 FLOW_SPEC_TYPE_DSCP, FLOW_SPEC_TYPE_FRAGMENT, FLOW_SPEC_TYPE_LABEL, FLOW_SPEC_TYPE_ETHERNET_TYPE, 4317 FLOW_SPEC_TYPE_LLC_DSAP, FLOW_SPEC_TYPE_LLC_SSAP, FLOW_SPEC_TYPE_LLC_CONTROL, FLOW_SPEC_TYPE_SNAP, 4318 FLOW_SPEC_TYPE_VID, FLOW_SPEC_TYPE_COS, FLOW_SPEC_TYPE_INNER_VID, FLOW_SPEC_TYPE_INNER_COS: 4319 i = NewFlowSpecComponent(t, nil) 4320 default: 4321 i = &FlowSpecUnknown{} 4322 } 4323 4324 err := i.DecodeFromBytes(data, options...) 4325 if err != nil { 4326 i = &FlowSpecUnknown{data} 4327 } 4328 l -= i.Len(options...) 4329 data = data[i.Len(options...):] 4330 n.Value = append(n.Value, i) 4331 } 4332 4333 // Sort Traffic Filtering Rules in types order to avoid the unordered rules 4334 // are determined different. 4335 sort.SliceStable(n.Value, func(i, j int) bool { return n.Value[i].Type() < n.Value[j].Type() }) 4336 4337 return nil 4338 } 4339 4340 func (n *FlowSpecNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 4341 buf := make([]byte, 0, 32) 4342 if n.SAFI() == SAFI_FLOW_SPEC_VPN { 4343 if n.rd == nil { 4344 return nil, fmt.Errorf("RD is nil") 4345 } 4346 b, err := n.rd.Serialize() 4347 if err != nil { 4348 return nil, err 4349 } 4350 buf = append(buf, b...) 4351 } 4352 for _, v := range n.Value { 4353 b, err := v.Serialize(options...) 4354 if err != nil { 4355 return nil, err 4356 } 4357 buf = append(buf, b...) 4358 } 4359 length := n.Len(options...) 4360 if length > 0xfff { 4361 return nil, fmt.Errorf("Too large: %d", length) 4362 } else if length < 0xf0 { 4363 length -= 1 4364 buf = append([]byte{byte(length)}, buf...) 4365 } else { 4366 length -= 2 4367 b := make([]byte, 2) 4368 binary.BigEndian.PutUint16(buf, uint16(length)) 4369 buf = append(b, buf...) 4370 } 4371 4372 if IsAddPathEnabled(false, n.rf, options) { 4373 id, err := n.serializeIdentifier() 4374 if err != nil { 4375 return nil, err 4376 } 4377 return append(id, buf...), nil 4378 } 4379 return buf, nil 4380 } 4381 4382 func (n *FlowSpecNLRI) Len(options ...*MarshallingOption) int { 4383 l := 0 4384 if n.SAFI() == SAFI_FLOW_SPEC_VPN { 4385 l += n.RD().Len() 4386 } 4387 for _, v := range n.Value { 4388 l += v.Len(options...) 4389 } 4390 if l < 0xf0 { 4391 return l + 1 4392 } else { 4393 return l + 2 4394 } 4395 } 4396 4397 func (n *FlowSpecNLRI) String() string { 4398 buf := bytes.NewBuffer(make([]byte, 0, 32)) 4399 if n.SAFI() == SAFI_FLOW_SPEC_VPN { 4400 buf.WriteString(fmt.Sprintf("[rd: %s]", n.rd)) 4401 } 4402 for _, v := range n.Value { 4403 buf.WriteString(v.String()) 4404 } 4405 return buf.String() 4406 } 4407 4408 func (n *FlowSpecNLRI) MarshalJSON() ([]byte, error) { 4409 if n.rd != nil { 4410 return json.Marshal(struct { 4411 RD RouteDistinguisherInterface `json:"rd"` 4412 Value []FlowSpecComponentInterface `json:"value"` 4413 }{ 4414 RD: n.rd, 4415 Value: n.Value, 4416 }) 4417 } 4418 return json.Marshal(struct { 4419 Value []FlowSpecComponentInterface `json:"value"` 4420 }{ 4421 Value: n.Value, 4422 }) 4423 4424 } 4425 4426 // 4427 // CompareFlowSpecNLRI(n, m) returns 4428 // -1 when m has precedence 4429 // 0 when n and m have same precedence 4430 // 1 when n has precedence 4431 // 4432 func CompareFlowSpecNLRI(n, m *FlowSpecNLRI) (int, error) { 4433 family := AfiSafiToRouteFamily(n.AFI(), n.SAFI()) 4434 if family != AfiSafiToRouteFamily(m.AFI(), m.SAFI()) { 4435 return 0, fmt.Errorf("address family mismatch") 4436 } 4437 longer := n.Value 4438 shorter := m.Value 4439 invert := 1 4440 if n.SAFI() == SAFI_FLOW_SPEC_VPN { 4441 k, _ := n.Serialize() 4442 l, _ := m.Serialize() 4443 if result := bytes.Compare(k, l); result != 0 { 4444 return result, nil 4445 } 4446 } 4447 if len(n.Value) < len(m.Value) { 4448 longer = m.Value 4449 shorter = n.Value 4450 invert = -1 4451 } 4452 for idx, v := range longer { 4453 if len(shorter) < idx+1 { 4454 return invert, nil 4455 } 4456 w := shorter[idx] 4457 if v.Type() < w.Type() { 4458 return invert, nil 4459 } else if v.Type() > w.Type() { 4460 return invert * -1, nil 4461 } else if v.Type() == FLOW_SPEC_TYPE_DST_PREFIX || v.Type() == FLOW_SPEC_TYPE_SRC_PREFIX { 4462 // RFC5575 5.1 4463 // 4464 // For IP prefix values (IP destination and source prefix) precedence is 4465 // given to the lowest IP value of the common prefix length; if the 4466 // common prefix is equal, then the most specific prefix has precedence. 4467 var p, q *IPAddrPrefixDefault 4468 var pCommon, qCommon uint64 4469 if n.AFI() == AFI_IP { 4470 if v.Type() == FLOW_SPEC_TYPE_DST_PREFIX { 4471 p = &v.(*FlowSpecDestinationPrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault 4472 q = &w.(*FlowSpecDestinationPrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault 4473 } else { 4474 p = &v.(*FlowSpecSourcePrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault 4475 q = &w.(*FlowSpecSourcePrefix).Prefix.(*IPAddrPrefix).IPAddrPrefixDefault 4476 } 4477 min := p.Length 4478 if q.Length < p.Length { 4479 min = q.Length 4480 } 4481 pCommon = uint64(binary.BigEndian.Uint32([]byte(p.Prefix.To4())) >> (32 - min)) 4482 qCommon = uint64(binary.BigEndian.Uint32([]byte(q.Prefix.To4())) >> (32 - min)) 4483 } else if n.AFI() == AFI_IP6 { 4484 if v.Type() == FLOW_SPEC_TYPE_DST_PREFIX { 4485 p = &v.(*FlowSpecDestinationPrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault 4486 q = &w.(*FlowSpecDestinationPrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault 4487 } else { 4488 p = &v.(*FlowSpecSourcePrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault 4489 q = &w.(*FlowSpecSourcePrefix6).Prefix.(*IPv6AddrPrefix).IPAddrPrefixDefault 4490 } 4491 min := uint(p.Length) 4492 if q.Length < p.Length { 4493 min = uint(q.Length) 4494 } 4495 var mask uint 4496 if min-64 > 0 { 4497 mask = min - 64 4498 } 4499 pCommon = binary.BigEndian.Uint64([]byte(p.Prefix.To16()[:8])) >> mask 4500 qCommon = binary.BigEndian.Uint64([]byte(q.Prefix.To16()[:8])) >> mask 4501 if pCommon == qCommon && mask == 0 { 4502 mask = 64 - min 4503 pCommon = binary.BigEndian.Uint64([]byte(p.Prefix.To16()[8:])) >> mask 4504 qCommon = binary.BigEndian.Uint64([]byte(q.Prefix.To16()[8:])) >> mask 4505 } 4506 } 4507 4508 if pCommon < qCommon { 4509 return invert, nil 4510 } else if pCommon > qCommon { 4511 return invert * -1, nil 4512 } else if p.Length > q.Length { 4513 return invert, nil 4514 } else if p.Length < q.Length { 4515 return invert * -1, nil 4516 } 4517 4518 } else { 4519 // RFC5575 5.1 4520 // 4521 // For all other component types, unless otherwise specified, the 4522 // comparison is performed by comparing the component data as a binary 4523 // string using the memcmp() function as defined by the ISO C standard. 4524 // For strings of different lengths, the common prefix is compared. If 4525 // equal, the longest string is considered to have higher precedence 4526 // than the shorter one. 4527 p, _ := v.Serialize() 4528 q, _ := w.Serialize() 4529 min := len(p) 4530 if len(q) < len(p) { 4531 min = len(q) 4532 } 4533 if result := bytes.Compare(p[:min], q[:min]); result < 0 { 4534 return invert, nil 4535 } else if result > 0 { 4536 return invert * -1, nil 4537 } else if len(p) > len(q) { 4538 return invert, nil 4539 } else if len(q) > len(p) { 4540 return invert * -1, nil 4541 } 4542 } 4543 } 4544 return 0, nil 4545 } 4546 4547 type FlowSpecIPv4Unicast struct { 4548 FlowSpecNLRI 4549 } 4550 4551 func (n *FlowSpecIPv4Unicast) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4552 return n.decodeFromBytes(AfiSafiToRouteFamily(n.AFI(), n.SAFI()), data, options...) 4553 } 4554 4555 func NewFlowSpecIPv4Unicast(value []FlowSpecComponentInterface) *FlowSpecIPv4Unicast { 4556 sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() }) 4557 return &FlowSpecIPv4Unicast{ 4558 FlowSpecNLRI: FlowSpecNLRI{ 4559 Value: value, 4560 rf: RF_FS_IPv4_UC, 4561 }, 4562 } 4563 } 4564 4565 type FlowSpecIPv4VPN struct { 4566 FlowSpecNLRI 4567 } 4568 4569 func (n *FlowSpecIPv4VPN) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4570 return n.decodeFromBytes(AfiSafiToRouteFamily(n.AFI(), n.SAFI()), data, options...) 4571 } 4572 4573 func NewFlowSpecIPv4VPN(rd RouteDistinguisherInterface, value []FlowSpecComponentInterface) *FlowSpecIPv4VPN { 4574 sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() }) 4575 return &FlowSpecIPv4VPN{ 4576 FlowSpecNLRI: FlowSpecNLRI{ 4577 Value: value, 4578 rf: RF_FS_IPv4_VPN, 4579 rd: rd, 4580 }, 4581 } 4582 } 4583 4584 type FlowSpecIPv6Unicast struct { 4585 FlowSpecNLRI 4586 } 4587 4588 func (n *FlowSpecIPv6Unicast) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4589 return n.decodeFromBytes(AfiSafiToRouteFamily(n.AFI(), n.SAFI()), data, options...) 4590 } 4591 4592 func NewFlowSpecIPv6Unicast(value []FlowSpecComponentInterface) *FlowSpecIPv6Unicast { 4593 sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() }) 4594 return &FlowSpecIPv6Unicast{ 4595 FlowSpecNLRI: FlowSpecNLRI{ 4596 Value: value, 4597 rf: RF_FS_IPv6_UC, 4598 }, 4599 } 4600 } 4601 4602 type FlowSpecIPv6VPN struct { 4603 FlowSpecNLRI 4604 } 4605 4606 func (n *FlowSpecIPv6VPN) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4607 return n.decodeFromBytes(AfiSafiToRouteFamily(n.AFI(), n.SAFI()), data, options...) 4608 } 4609 4610 func NewFlowSpecIPv6VPN(rd RouteDistinguisherInterface, value []FlowSpecComponentInterface) *FlowSpecIPv6VPN { 4611 sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() }) 4612 return &FlowSpecIPv6VPN{ 4613 FlowSpecNLRI: FlowSpecNLRI{ 4614 Value: value, 4615 rf: RF_FS_IPv6_VPN, 4616 rd: rd, 4617 }, 4618 } 4619 } 4620 4621 type FlowSpecL2VPN struct { 4622 FlowSpecNLRI 4623 } 4624 4625 func (n *FlowSpecL2VPN) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4626 return n.decodeFromBytes(AfiSafiToRouteFamily(n.AFI(), n.SAFI()), data) 4627 } 4628 4629 func NewFlowSpecL2VPN(rd RouteDistinguisherInterface, value []FlowSpecComponentInterface) *FlowSpecL2VPN { 4630 sort.SliceStable(value, func(i, j int) bool { return value[i].Type() < value[j].Type() }) 4631 return &FlowSpecL2VPN{ 4632 FlowSpecNLRI: FlowSpecNLRI{ 4633 Value: value, 4634 rf: RF_FS_L2_VPN, 4635 rd: rd, 4636 }, 4637 } 4638 } 4639 4640 type OpaqueNLRI struct { 4641 PrefixDefault 4642 Length uint16 4643 Key []byte 4644 Value []byte 4645 } 4646 4647 func (n *OpaqueNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 4648 if len(data) < 2 { 4649 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all OpaqueNLRI bytes available") 4650 } 4651 if IsAddPathEnabled(true, RF_OPAQUE, options) { 4652 var err error 4653 data, err = n.decodePathIdentifier(data) 4654 if err != nil { 4655 return err 4656 } 4657 } 4658 n.Length = binary.BigEndian.Uint16(data[0:2]) 4659 if len(data)-2 < int(n.Length) { 4660 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all OpaqueNLRI bytes available") 4661 } 4662 n.Key = data[2 : 2+n.Length] 4663 n.Value = data[2+n.Length:] 4664 return nil 4665 } 4666 4667 func (n *OpaqueNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 4668 if len(n.Key) > math.MaxUint16 { 4669 return nil, fmt.Errorf("Key length too big") 4670 } 4671 buf := make([]byte, 2) 4672 binary.BigEndian.PutUint16(buf, uint16(len(n.Key))) 4673 buf = append(buf, n.Key...) 4674 buf = append(buf, n.Value...) 4675 if IsAddPathEnabled(false, RF_OPAQUE, options) { 4676 id, err := n.serializeIdentifier() 4677 if err != nil { 4678 return nil, err 4679 } 4680 return append(id, buf...), nil 4681 } 4682 return buf, nil 4683 } 4684 4685 func (n *OpaqueNLRI) AFI() uint16 { 4686 return AFI_OPAQUE 4687 } 4688 4689 func (n *OpaqueNLRI) SAFI() uint8 { 4690 return SAFI_KEY_VALUE 4691 } 4692 4693 func (n *OpaqueNLRI) Len(options ...*MarshallingOption) int { 4694 return 2 + len(n.Key) + len(n.Value) 4695 } 4696 4697 func (n *OpaqueNLRI) String() string { 4698 return fmt.Sprintf("%s", n.Key) 4699 } 4700 4701 func (n *OpaqueNLRI) MarshalJSON() ([]byte, error) { 4702 return json.Marshal(struct { 4703 Key string `json:"key"` 4704 Value string `json:"value"` 4705 }{ 4706 Key: string(n.Key), 4707 Value: string(n.Value), 4708 }) 4709 } 4710 4711 func NewOpaqueNLRI(key, value []byte) *OpaqueNLRI { 4712 return &OpaqueNLRI{ 4713 Key: key, 4714 Value: value, 4715 } 4716 } 4717 4718 func AfiSafiToRouteFamily(afi uint16, safi uint8) RouteFamily { 4719 return RouteFamily(int(afi)<<16 | int(safi)) 4720 } 4721 4722 func RouteFamilyToAfiSafi(rf RouteFamily) (uint16, uint8) { 4723 return uint16(int(rf) >> 16), uint8(int(rf) & 0xff) 4724 } 4725 4726 type RouteFamily int 4727 4728 func (f RouteFamily) String() string { 4729 if n, y := AddressFamilyNameMap[f]; y { 4730 return n 4731 } 4732 return fmt.Sprintf("UnknownFamily(%d)", f) 4733 } 4734 4735 const ( 4736 RF_IPv4_UC RouteFamily = AFI_IP<<16 | SAFI_UNICAST 4737 RF_IPv6_UC RouteFamily = AFI_IP6<<16 | SAFI_UNICAST 4738 RF_IPv4_MC RouteFamily = AFI_IP<<16 | SAFI_MULTICAST 4739 RF_IPv6_MC RouteFamily = AFI_IP6<<16 | SAFI_MULTICAST 4740 RF_IPv4_VPN RouteFamily = AFI_IP<<16 | SAFI_MPLS_VPN 4741 RF_IPv6_VPN RouteFamily = AFI_IP6<<16 | SAFI_MPLS_VPN 4742 RF_IPv4_VPN_MC RouteFamily = AFI_IP<<16 | SAFI_MPLS_VPN_MULTICAST 4743 RF_IPv6_VPN_MC RouteFamily = AFI_IP6<<16 | SAFI_MPLS_VPN_MULTICAST 4744 RF_IPv4_MPLS RouteFamily = AFI_IP<<16 | SAFI_MPLS_LABEL 4745 RF_IPv6_MPLS RouteFamily = AFI_IP6<<16 | SAFI_MPLS_LABEL 4746 RF_VPLS RouteFamily = AFI_L2VPN<<16 | SAFI_VPLS 4747 RF_EVPN RouteFamily = AFI_L2VPN<<16 | SAFI_EVPN 4748 RF_RTC_UC RouteFamily = AFI_IP<<16 | SAFI_ROUTE_TARGET_CONSTRAINTS 4749 RF_IPv4_ENCAP RouteFamily = AFI_IP<<16 | SAFI_ENCAPSULATION 4750 RF_IPv6_ENCAP RouteFamily = AFI_IP6<<16 | SAFI_ENCAPSULATION 4751 RF_FS_IPv4_UC RouteFamily = AFI_IP<<16 | SAFI_FLOW_SPEC_UNICAST 4752 RF_FS_IPv4_VPN RouteFamily = AFI_IP<<16 | SAFI_FLOW_SPEC_VPN 4753 RF_FS_IPv6_UC RouteFamily = AFI_IP6<<16 | SAFI_FLOW_SPEC_UNICAST 4754 RF_FS_IPv6_VPN RouteFamily = AFI_IP6<<16 | SAFI_FLOW_SPEC_VPN 4755 RF_FS_L2_VPN RouteFamily = AFI_L2VPN<<16 | SAFI_FLOW_SPEC_VPN 4756 RF_OPAQUE RouteFamily = AFI_OPAQUE<<16 | SAFI_KEY_VALUE 4757 ) 4758 4759 var AddressFamilyNameMap = map[RouteFamily]string{ 4760 RF_IPv4_UC: "ipv4-unicast", 4761 RF_IPv6_UC: "ipv6-unicast", 4762 RF_IPv4_MC: "ipv4-multicast", 4763 RF_IPv6_MC: "ipv6-multicast", 4764 RF_IPv4_MPLS: "ipv4-labelled-unicast", 4765 RF_IPv6_MPLS: "ipv6-labelled-unicast", 4766 RF_IPv4_VPN: "l3vpn-ipv4-unicast", 4767 RF_IPv6_VPN: "l3vpn-ipv6-unicast", 4768 RF_IPv4_VPN_MC: "l3vpn-ipv4-multicast", 4769 RF_IPv6_VPN_MC: "l3vpn-ipv6-multicast", 4770 RF_VPLS: "l2vpn-vpls", 4771 RF_EVPN: "l2vpn-evpn", 4772 RF_RTC_UC: "rtc", 4773 RF_IPv4_ENCAP: "ipv4-encap", 4774 RF_IPv6_ENCAP: "ipv6-encap", 4775 RF_FS_IPv4_UC: "ipv4-flowspec", 4776 RF_FS_IPv4_VPN: "l3vpn-ipv4-flowspec", 4777 RF_FS_IPv6_UC: "ipv6-flowspec", 4778 RF_FS_IPv6_VPN: "l3vpn-ipv6-flowspec", 4779 RF_FS_L2_VPN: "l2vpn-flowspec", 4780 RF_OPAQUE: "opaque", 4781 } 4782 4783 var AddressFamilyValueMap = map[string]RouteFamily{ 4784 AddressFamilyNameMap[RF_IPv4_UC]: RF_IPv4_UC, 4785 AddressFamilyNameMap[RF_IPv6_UC]: RF_IPv6_UC, 4786 AddressFamilyNameMap[RF_IPv4_MC]: RF_IPv4_MC, 4787 AddressFamilyNameMap[RF_IPv6_MC]: RF_IPv6_MC, 4788 AddressFamilyNameMap[RF_IPv4_MPLS]: RF_IPv4_MPLS, 4789 AddressFamilyNameMap[RF_IPv6_MPLS]: RF_IPv6_MPLS, 4790 AddressFamilyNameMap[RF_IPv4_VPN]: RF_IPv4_VPN, 4791 AddressFamilyNameMap[RF_IPv6_VPN]: RF_IPv6_VPN, 4792 AddressFamilyNameMap[RF_IPv4_VPN_MC]: RF_IPv4_VPN_MC, 4793 AddressFamilyNameMap[RF_IPv6_VPN_MC]: RF_IPv6_VPN_MC, 4794 AddressFamilyNameMap[RF_VPLS]: RF_VPLS, 4795 AddressFamilyNameMap[RF_EVPN]: RF_EVPN, 4796 AddressFamilyNameMap[RF_RTC_UC]: RF_RTC_UC, 4797 AddressFamilyNameMap[RF_IPv4_ENCAP]: RF_IPv4_ENCAP, 4798 AddressFamilyNameMap[RF_IPv6_ENCAP]: RF_IPv6_ENCAP, 4799 AddressFamilyNameMap[RF_FS_IPv4_UC]: RF_FS_IPv4_UC, 4800 AddressFamilyNameMap[RF_FS_IPv4_VPN]: RF_FS_IPv4_VPN, 4801 AddressFamilyNameMap[RF_FS_IPv6_UC]: RF_FS_IPv6_UC, 4802 AddressFamilyNameMap[RF_FS_IPv6_VPN]: RF_FS_IPv6_VPN, 4803 AddressFamilyNameMap[RF_FS_L2_VPN]: RF_FS_L2_VPN, 4804 AddressFamilyNameMap[RF_OPAQUE]: RF_OPAQUE, 4805 } 4806 4807 func GetRouteFamily(name string) (RouteFamily, error) { 4808 if v, ok := AddressFamilyValueMap[name]; ok { 4809 return v, nil 4810 } 4811 return RouteFamily(0), fmt.Errorf("%s isn't a valid route family name", name) 4812 } 4813 4814 func NewPrefixFromRouteFamily(afi uint16, safi uint8, prefixStr ...string) (prefix AddrPrefixInterface, err error) { 4815 family := AfiSafiToRouteFamily(afi, safi) 4816 4817 f := func(s string) AddrPrefixInterface { 4818 addr, net, _ := net.ParseCIDR(s) 4819 len, _ := net.Mask.Size() 4820 switch family { 4821 case RF_IPv4_UC, RF_IPv4_MC: 4822 return NewIPAddrPrefix(uint8(len), addr.String()) 4823 } 4824 return NewIPv6AddrPrefix(uint8(len), addr.String()) 4825 } 4826 4827 switch family { 4828 case RF_IPv4_UC, RF_IPv4_MC: 4829 if len(prefixStr) > 0 { 4830 prefix = f(prefixStr[0]) 4831 } else { 4832 prefix = NewIPAddrPrefix(0, "") 4833 } 4834 case RF_IPv6_UC, RF_IPv6_MC: 4835 if len(prefixStr) > 0 { 4836 prefix = f(prefixStr[0]) 4837 } else { 4838 prefix = NewIPv6AddrPrefix(0, "") 4839 } 4840 case RF_IPv4_VPN: 4841 prefix = NewLabeledVPNIPAddrPrefix(0, "", *NewMPLSLabelStack(), nil) 4842 case RF_IPv6_VPN: 4843 prefix = NewLabeledVPNIPv6AddrPrefix(0, "", *NewMPLSLabelStack(), nil) 4844 case RF_IPv4_MPLS: 4845 prefix = NewLabeledIPAddrPrefix(0, "", *NewMPLSLabelStack()) 4846 case RF_IPv6_MPLS: 4847 prefix = NewLabeledIPv6AddrPrefix(0, "", *NewMPLSLabelStack()) 4848 case RF_EVPN: 4849 prefix = NewEVPNNLRI(0, nil) 4850 case RF_RTC_UC: 4851 prefix = &RouteTargetMembershipNLRI{} 4852 case RF_IPv4_ENCAP: 4853 prefix = NewEncapNLRI("") 4854 case RF_IPv6_ENCAP: 4855 prefix = NewEncapv6NLRI("") 4856 case RF_FS_IPv4_UC: 4857 prefix = &FlowSpecIPv4Unicast{FlowSpecNLRI{rf: RF_FS_IPv4_UC}} 4858 case RF_FS_IPv4_VPN: 4859 prefix = &FlowSpecIPv4VPN{FlowSpecNLRI{rf: RF_FS_IPv4_VPN}} 4860 case RF_FS_IPv6_UC: 4861 prefix = &FlowSpecIPv6Unicast{FlowSpecNLRI{rf: RF_FS_IPv6_UC}} 4862 case RF_FS_IPv6_VPN: 4863 prefix = &FlowSpecIPv6VPN{FlowSpecNLRI{rf: RF_FS_IPv6_VPN}} 4864 case RF_FS_L2_VPN: 4865 prefix = &FlowSpecL2VPN{FlowSpecNLRI{rf: RF_FS_L2_VPN}} 4866 case RF_OPAQUE: 4867 prefix = &OpaqueNLRI{} 4868 default: 4869 err = fmt.Errorf("unknown route family. AFI: %d, SAFI: %d", afi, safi) 4870 } 4871 return prefix, err 4872 } 4873 4874 type BGPAttrFlag uint8 4875 4876 const ( 4877 BGP_ATTR_FLAG_EXTENDED_LENGTH BGPAttrFlag = 1 << 4 4878 BGP_ATTR_FLAG_PARTIAL BGPAttrFlag = 1 << 5 4879 BGP_ATTR_FLAG_TRANSITIVE BGPAttrFlag = 1 << 6 4880 BGP_ATTR_FLAG_OPTIONAL BGPAttrFlag = 1 << 7 4881 ) 4882 4883 func (f BGPAttrFlag) String() string { 4884 strs := make([]string, 0, 4) 4885 if f&BGP_ATTR_FLAG_EXTENDED_LENGTH > 0 { 4886 strs = append(strs, "EXTENDED_LENGTH") 4887 } 4888 if f&BGP_ATTR_FLAG_PARTIAL > 0 { 4889 strs = append(strs, "PARTIAL") 4890 } 4891 if f&BGP_ATTR_FLAG_TRANSITIVE > 0 { 4892 strs = append(strs, "TRANSITIVE") 4893 } 4894 if f&BGP_ATTR_FLAG_OPTIONAL > 0 { 4895 strs = append(strs, "OPTIONAL") 4896 } 4897 return strings.Join(strs, "|") 4898 } 4899 4900 type BGPAttrType uint8 4901 4902 const ( 4903 _ BGPAttrType = iota 4904 BGP_ATTR_TYPE_ORIGIN 4905 BGP_ATTR_TYPE_AS_PATH 4906 BGP_ATTR_TYPE_NEXT_HOP 4907 BGP_ATTR_TYPE_MULTI_EXIT_DISC 4908 BGP_ATTR_TYPE_LOCAL_PREF 4909 BGP_ATTR_TYPE_ATOMIC_AGGREGATE 4910 BGP_ATTR_TYPE_AGGREGATOR 4911 BGP_ATTR_TYPE_COMMUNITIES 4912 BGP_ATTR_TYPE_ORIGINATOR_ID 4913 BGP_ATTR_TYPE_CLUSTER_LIST 4914 _ 4915 _ 4916 _ 4917 BGP_ATTR_TYPE_MP_REACH_NLRI // = 14 4918 BGP_ATTR_TYPE_MP_UNREACH_NLRI 4919 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES 4920 BGP_ATTR_TYPE_AS4_PATH 4921 BGP_ATTR_TYPE_AS4_AGGREGATOR 4922 _ 4923 _ 4924 _ 4925 BGP_ATTR_TYPE_PMSI_TUNNEL // = 22 4926 BGP_ATTR_TYPE_TUNNEL_ENCAP 4927 _ 4928 BGP_ATTR_TYPE_IP6_EXTENDED_COMMUNITIES // = 25 4929 BGP_ATTR_TYPE_AIGP // = 26 4930 BGP_ATTR_TYPE_LARGE_COMMUNITY BGPAttrType = 32 4931 ) 4932 4933 // NOTIFICATION Error Code RFC 4271 4.5. 4934 const ( 4935 _ = iota 4936 BGP_ERROR_MESSAGE_HEADER_ERROR 4937 BGP_ERROR_OPEN_MESSAGE_ERROR 4938 BGP_ERROR_UPDATE_MESSAGE_ERROR 4939 BGP_ERROR_HOLD_TIMER_EXPIRED 4940 BGP_ERROR_FSM_ERROR 4941 BGP_ERROR_CEASE 4942 BGP_ERROR_ROUTE_REFRESH_MESSAGE_ERROR 4943 ) 4944 4945 // NOTIFICATION Error Subcode for BGP_ERROR_MESSAGE_HEADER_ERROR 4946 const ( 4947 _ = iota 4948 BGP_ERROR_SUB_CONNECTION_NOT_SYNCHRONIZED 4949 BGP_ERROR_SUB_BAD_MESSAGE_LENGTH 4950 BGP_ERROR_SUB_BAD_MESSAGE_TYPE 4951 ) 4952 4953 // NOTIFICATION Error Subcode for BGP_ERROR_OPEN_MESSAGE_ERROR 4954 const ( 4955 _ = iota 4956 BGP_ERROR_SUB_UNSUPPORTED_VERSION_NUMBER 4957 BGP_ERROR_SUB_BAD_PEER_AS 4958 BGP_ERROR_SUB_BAD_BGP_IDENTIFIER 4959 BGP_ERROR_SUB_UNSUPPORTED_OPTIONAL_PARAMETER 4960 BGP_ERROR_SUB_DEPRECATED_AUTHENTICATION_FAILURE 4961 BGP_ERROR_SUB_UNACCEPTABLE_HOLD_TIME 4962 BGP_ERROR_SUB_UNSUPPORTED_CAPABILITY 4963 ) 4964 4965 // NOTIFICATION Error Subcode for BGP_ERROR_UPDATE_MESSAGE_ERROR 4966 const ( 4967 _ = iota 4968 BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST 4969 BGP_ERROR_SUB_UNRECOGNIZED_WELL_KNOWN_ATTRIBUTE 4970 BGP_ERROR_SUB_MISSING_WELL_KNOWN_ATTRIBUTE 4971 BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR 4972 BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR 4973 BGP_ERROR_SUB_INVALID_ORIGIN_ATTRIBUTE 4974 BGP_ERROR_SUB_DEPRECATED_ROUTING_LOOP 4975 BGP_ERROR_SUB_INVALID_NEXT_HOP_ATTRIBUTE 4976 BGP_ERROR_SUB_OPTIONAL_ATTRIBUTE_ERROR 4977 BGP_ERROR_SUB_INVALID_NETWORK_FIELD 4978 BGP_ERROR_SUB_MALFORMED_AS_PATH 4979 ) 4980 4981 // NOTIFICATION Error Subcode for BGP_ERROR_HOLD_TIMER_EXPIRED 4982 const ( 4983 _ = iota 4984 BGP_ERROR_SUB_HOLD_TIMER_EXPIRED 4985 ) 4986 4987 // NOTIFICATION Error Subcode for BGP_ERROR_FSM_ERROR 4988 const ( 4989 _ = iota 4990 BGP_ERROR_SUB_RECEIVE_UNEXPECTED_MESSAGE_IN_OPENSENT_STATE 4991 BGP_ERROR_SUB_RECEIVE_UNEXPECTED_MESSAGE_IN_OPENCONFIRM_STATE 4992 BGP_ERROR_SUB_RECEIVE_UNEXPECTED_MESSAGE_IN_ESTABLISHED_STATE 4993 ) 4994 4995 // NOTIFICATION Error Subcode for BGP_ERROR_CEASE (RFC 4486) 4996 const ( 4997 _ = iota 4998 BGP_ERROR_SUB_MAXIMUM_NUMBER_OF_PREFIXES_REACHED 4999 BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN 5000 BGP_ERROR_SUB_PEER_DECONFIGURED 5001 BGP_ERROR_SUB_ADMINISTRATIVE_RESET 5002 BGP_ERROR_SUB_CONNECTION_REJECTED 5003 BGP_ERROR_SUB_OTHER_CONFIGURATION_CHANGE 5004 BGP_ERROR_SUB_CONNECTION_COLLISION_RESOLUTION 5005 BGP_ERROR_SUB_OUT_OF_RESOURCES 5006 BGP_ERROR_SUB_HARD_RESET //draft-ietf-idr-bgp-gr-notification-07 5007 ) 5008 5009 // Constants for BGP_ERROR_SUB_ADMINISTRATIVE_SHUTDOWN and BGP_ERROR_SUB_ADMINISTRATIVE_RESET 5010 const ( 5011 BGP_ERROR_ADMINISTRATIVE_COMMUNICATION_MAX = 128 5012 ) 5013 5014 // NOTIFICATION Error Subcode for BGP_ERROR_ROUTE_REFRESH 5015 const ( 5016 _ = iota 5017 BGP_ERROR_SUB_INVALID_MESSAGE_LENGTH 5018 ) 5019 5020 type NotificationErrorCode uint16 5021 5022 func (c NotificationErrorCode) String() string { 5023 code := uint8(uint16(c) >> 8) 5024 subcode := uint8(uint16(c) & 0xff) 5025 UNDEFINED := "undefined" 5026 codeStr := UNDEFINED 5027 subcodeList := []string{} 5028 switch code { 5029 case BGP_ERROR_MESSAGE_HEADER_ERROR: 5030 codeStr = "header" 5031 subcodeList = []string{ 5032 UNDEFINED, 5033 "connection not synchronized", 5034 "bad message length", 5035 "bad message type"} 5036 case BGP_ERROR_OPEN_MESSAGE_ERROR: 5037 codeStr = "open" 5038 subcodeList = []string{ 5039 UNDEFINED, 5040 "unsupported version number", 5041 "bad peer as", 5042 "bad bgp identifier", 5043 "unsupported optional parameter", 5044 "deprecated authentication failure", 5045 "unacceptable hold time", 5046 "unsupported capability"} 5047 case BGP_ERROR_UPDATE_MESSAGE_ERROR: 5048 codeStr = "update" 5049 subcodeList = []string{ 5050 UNDEFINED, 5051 "malformed attribute list", 5052 "unrecognized well known attribute", 5053 "missing well known attribute", 5054 "attribute flags error", 5055 "attribute length error", 5056 "invalid origin attribute", 5057 "deprecated routing loop", 5058 "invalid next hop attribute", 5059 "optional attribute error", 5060 "invalid network field", 5061 "sub malformed as path"} 5062 case BGP_ERROR_HOLD_TIMER_EXPIRED: 5063 codeStr = "hold timer expired" 5064 subcodeList = []string{ 5065 UNDEFINED, 5066 "hold timer expired"} 5067 case BGP_ERROR_FSM_ERROR: 5068 codeStr = "fsm" 5069 subcodeList = []string{ 5070 UNDEFINED, 5071 "receive unexpected message in opensent state", 5072 "receive unexpected message in openconfirm state", 5073 "receive unexpected message in established state"} 5074 case BGP_ERROR_CEASE: 5075 codeStr = "cease" 5076 subcodeList = []string{ 5077 UNDEFINED, 5078 "maximum number of prefixes reached", 5079 "administrative shutdown", 5080 "peer deconfigured", 5081 "administrative reset", 5082 "connection rejected", 5083 "other configuration change", 5084 "connection collision resolution", 5085 "out of resources"} 5086 case BGP_ERROR_ROUTE_REFRESH_MESSAGE_ERROR: 5087 codeStr = "route refresh" 5088 subcodeList = []string{"invalid message length"} 5089 } 5090 subcodeStr := func(idx uint8, l []string) string { 5091 if len(l) == 0 || int(idx) > len(l)-1 { 5092 return UNDEFINED 5093 } 5094 return l[idx] 5095 }(subcode, subcodeList) 5096 return fmt.Sprintf("code %v(%v) subcode %v(%v)", code, codeStr, subcode, subcodeStr) 5097 } 5098 5099 func NewNotificationErrorCode(code, subcode uint8) NotificationErrorCode { 5100 return NotificationErrorCode(uint16(code)<<8 | uint16(subcode)) 5101 } 5102 5103 var PathAttrFlags map[BGPAttrType]BGPAttrFlag = map[BGPAttrType]BGPAttrFlag{ 5104 BGP_ATTR_TYPE_ORIGIN: BGP_ATTR_FLAG_TRANSITIVE, 5105 BGP_ATTR_TYPE_AS_PATH: BGP_ATTR_FLAG_TRANSITIVE, 5106 BGP_ATTR_TYPE_NEXT_HOP: BGP_ATTR_FLAG_TRANSITIVE, 5107 BGP_ATTR_TYPE_MULTI_EXIT_DISC: BGP_ATTR_FLAG_OPTIONAL, 5108 BGP_ATTR_TYPE_LOCAL_PREF: BGP_ATTR_FLAG_TRANSITIVE, 5109 BGP_ATTR_TYPE_ATOMIC_AGGREGATE: BGP_ATTR_FLAG_TRANSITIVE, 5110 BGP_ATTR_TYPE_AGGREGATOR: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5111 BGP_ATTR_TYPE_COMMUNITIES: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5112 BGP_ATTR_TYPE_ORIGINATOR_ID: BGP_ATTR_FLAG_OPTIONAL, 5113 BGP_ATTR_TYPE_CLUSTER_LIST: BGP_ATTR_FLAG_OPTIONAL, 5114 BGP_ATTR_TYPE_MP_REACH_NLRI: BGP_ATTR_FLAG_OPTIONAL, 5115 BGP_ATTR_TYPE_MP_UNREACH_NLRI: BGP_ATTR_FLAG_OPTIONAL, 5116 BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5117 BGP_ATTR_TYPE_AS4_PATH: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5118 BGP_ATTR_TYPE_AS4_AGGREGATOR: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5119 BGP_ATTR_TYPE_PMSI_TUNNEL: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5120 BGP_ATTR_TYPE_TUNNEL_ENCAP: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5121 BGP_ATTR_TYPE_IP6_EXTENDED_COMMUNITIES: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5122 BGP_ATTR_TYPE_AIGP: BGP_ATTR_FLAG_OPTIONAL, 5123 BGP_ATTR_TYPE_LARGE_COMMUNITY: BGP_ATTR_FLAG_TRANSITIVE | BGP_ATTR_FLAG_OPTIONAL, 5124 } 5125 5126 // getPathAttrFlags returns BGP Path Attribute flags value from its type and 5127 // length (byte length of value field). 5128 func getPathAttrFlags(typ BGPAttrType, length int) BGPAttrFlag { 5129 flags := PathAttrFlags[typ] 5130 if length > 255 { 5131 flags |= BGP_ATTR_FLAG_EXTENDED_LENGTH 5132 } 5133 return flags 5134 } 5135 5136 type PathAttributeInterface interface { 5137 DecodeFromBytes([]byte, ...*MarshallingOption) error 5138 Serialize(...*MarshallingOption) ([]byte, error) 5139 Len(...*MarshallingOption) int 5140 GetFlags() BGPAttrFlag 5141 GetType() BGPAttrType 5142 String() string 5143 MarshalJSON() ([]byte, error) 5144 Flat() map[string]string 5145 } 5146 5147 type PathAttribute struct { 5148 Flags BGPAttrFlag 5149 Type BGPAttrType 5150 Length uint16 // length of Value 5151 } 5152 5153 func (p *PathAttribute) Len(options ...*MarshallingOption) int { 5154 if p.Flags&BGP_ATTR_FLAG_EXTENDED_LENGTH != 0 { 5155 return 4 + int(p.Length) 5156 } 5157 return 3 + int(p.Length) 5158 } 5159 5160 func (p *PathAttribute) GetFlags() BGPAttrFlag { 5161 return p.Flags 5162 } 5163 5164 func (p *PathAttribute) GetType() BGPAttrType { 5165 return p.Type 5166 } 5167 5168 func (p *PathAttribute) DecodeFromBytes(data []byte, options ...*MarshallingOption) (value []byte, err error) { 5169 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5170 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5171 if len(data) < 2 { 5172 return nil, NewMessageError(eCode, eSubCode, data, "attribute header length is short") 5173 } 5174 p.Flags = BGPAttrFlag(data[0]) 5175 p.Type = BGPAttrType(data[1]) 5176 if eMsg := validatePathAttributeFlags(p.Type, p.Flags); eMsg != "" { 5177 return nil, NewMessageError(eCode, BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR, data, eMsg) 5178 } 5179 5180 if p.Flags&BGP_ATTR_FLAG_EXTENDED_LENGTH != 0 { 5181 if len(data) < 4 { 5182 return nil, NewMessageError(eCode, eSubCode, data, "attribute header length is short") 5183 } 5184 p.Length = binary.BigEndian.Uint16(data[2:4]) 5185 data = data[4:] 5186 } else { 5187 if len(data) < 3 { 5188 return nil, NewMessageError(eCode, eSubCode, data, "attribute header length is short") 5189 } 5190 p.Length = uint16(data[2]) 5191 data = data[3:] 5192 } 5193 if len(data) < int(p.Length) { 5194 return nil, NewMessageError(eCode, eSubCode, data, "attribute value length is short") 5195 } 5196 5197 return data[:p.Length], nil 5198 } 5199 5200 func (p *PathAttribute) Serialize(value []byte, options ...*MarshallingOption) ([]byte, error) { 5201 // Note: Do not update "p.Flags" and "p.Length" to avoid data race. 5202 flags := p.Flags 5203 length := uint16(len(value)) 5204 if flags&BGP_ATTR_FLAG_EXTENDED_LENGTH == 0 && length > 255 { 5205 flags |= BGP_ATTR_FLAG_EXTENDED_LENGTH 5206 } 5207 var buf []byte 5208 if flags&BGP_ATTR_FLAG_EXTENDED_LENGTH != 0 { 5209 buf = append(make([]byte, 4), value...) 5210 binary.BigEndian.PutUint16(buf[2:4], length) 5211 } else { 5212 buf = append(make([]byte, 3), value...) 5213 buf[2] = byte(length) 5214 } 5215 buf[0] = uint8(flags) 5216 buf[1] = uint8(p.Type) 5217 return buf, nil 5218 } 5219 5220 type PathAttributeOrigin struct { 5221 PathAttribute 5222 Value uint8 5223 } 5224 5225 func (p *PathAttributeOrigin) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5226 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5227 if err != nil { 5228 return err 5229 } 5230 if p.Length != 1 { 5231 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5232 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 5233 return NewMessageError(eCode, eSubCode, nil, "Origin attribute length is incorrect") 5234 } 5235 p.Value = value[0] 5236 return nil 5237 } 5238 5239 func (p *PathAttributeOrigin) Serialize(options ...*MarshallingOption) ([]byte, error) { 5240 return p.PathAttribute.Serialize([]byte{p.Value}, options...) 5241 } 5242 5243 func (p *PathAttributeOrigin) String() string { 5244 typ := "-" 5245 switch p.Value { 5246 case BGP_ORIGIN_ATTR_TYPE_IGP: 5247 typ = "i" 5248 case BGP_ORIGIN_ATTR_TYPE_EGP: 5249 typ = "e" 5250 case BGP_ORIGIN_ATTR_TYPE_INCOMPLETE: 5251 typ = "?" 5252 } 5253 return fmt.Sprintf("{Origin: %s}", typ) 5254 } 5255 5256 func (p *PathAttributeOrigin) MarshalJSON() ([]byte, error) { 5257 return json.Marshal(struct { 5258 Type BGPAttrType `json:"type"` 5259 Value uint8 `json:"value"` 5260 }{ 5261 Type: p.GetType(), 5262 Value: p.Value, 5263 }) 5264 } 5265 5266 func NewPathAttributeOrigin(value uint8) *PathAttributeOrigin { 5267 t := BGP_ATTR_TYPE_ORIGIN 5268 return &PathAttributeOrigin{ 5269 PathAttribute: PathAttribute{ 5270 Flags: PathAttrFlags[t], 5271 Type: t, 5272 Length: 1, 5273 }, 5274 Value: value, 5275 } 5276 } 5277 5278 type AsPathParamFormat struct { 5279 start string 5280 end string 5281 separator string 5282 } 5283 5284 var asPathParamFormatMap = map[uint8]*AsPathParamFormat{ 5285 BGP_ASPATH_ATTR_TYPE_SET: {"{", "}", ","}, 5286 BGP_ASPATH_ATTR_TYPE_SEQ: {"", "", " "}, 5287 BGP_ASPATH_ATTR_TYPE_CONFED_SET: {"(", ")", " "}, 5288 BGP_ASPATH_ATTR_TYPE_CONFED_SEQ: {"[", "]", ","}, 5289 } 5290 5291 type AsPathParamInterface interface { 5292 GetType() uint8 5293 GetAS() []uint32 5294 Serialize() ([]byte, error) 5295 DecodeFromBytes([]byte) error 5296 Len() int 5297 ASLen() int 5298 MarshalJSON() ([]byte, error) 5299 String() string 5300 } 5301 5302 func AsPathString(aspath *PathAttributeAsPath) string { 5303 s := bytes.NewBuffer(make([]byte, 0, 64)) 5304 for i, param := range aspath.Value { 5305 segType := param.GetType() 5306 asList := param.GetAS() 5307 if i != 0 { 5308 s.WriteString(" ") 5309 } 5310 5311 sep := " " 5312 switch segType { 5313 case BGP_ASPATH_ATTR_TYPE_CONFED_SEQ: 5314 s.WriteString("(") 5315 case BGP_ASPATH_ATTR_TYPE_CONFED_SET: 5316 s.WriteString("[") 5317 sep = "," 5318 case BGP_ASPATH_ATTR_TYPE_SET: 5319 s.WriteString("{") 5320 sep = "," 5321 } 5322 for j, as := range asList { 5323 s.WriteString(fmt.Sprintf("%d", as)) 5324 if j != len(asList)-1 { 5325 s.WriteString(sep) 5326 } 5327 } 5328 switch segType { 5329 case BGP_ASPATH_ATTR_TYPE_CONFED_SEQ: 5330 s.WriteString(")") 5331 case BGP_ASPATH_ATTR_TYPE_CONFED_SET: 5332 s.WriteString("]") 5333 case BGP_ASPATH_ATTR_TYPE_SET: 5334 s.WriteString("}") 5335 } 5336 } 5337 return s.String() 5338 } 5339 5340 type AsPathParam struct { 5341 Type uint8 5342 Num uint8 5343 AS []uint16 5344 } 5345 5346 func (a *AsPathParam) GetType() uint8 { 5347 return a.Type 5348 } 5349 5350 func (a *AsPathParam) GetAS() []uint32 { 5351 nums := make([]uint32, 0, len(a.AS)) 5352 for _, as := range a.AS { 5353 nums = append(nums, uint32(as)) 5354 } 5355 return nums 5356 } 5357 5358 func (a *AsPathParam) Serialize() ([]byte, error) { 5359 buf := make([]byte, 2+len(a.AS)*2) 5360 buf[0] = uint8(a.Type) 5361 buf[1] = a.Num 5362 for j, as := range a.AS { 5363 binary.BigEndian.PutUint16(buf[2+j*2:], as) 5364 } 5365 return buf, nil 5366 } 5367 5368 func (a *AsPathParam) DecodeFromBytes(data []byte) error { 5369 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5370 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH) 5371 if len(data) < 2 { 5372 return NewMessageError(eCode, eSubCode, nil, "AS param header length is short") 5373 } 5374 a.Type = data[0] 5375 a.Num = data[1] 5376 data = data[2:] 5377 if len(data) < int(a.Num*2) { 5378 return NewMessageError(eCode, eSubCode, nil, "AS param data length is short") 5379 } 5380 for i := 0; i < int(a.Num); i++ { 5381 a.AS = append(a.AS, binary.BigEndian.Uint16(data)) 5382 data = data[2:] 5383 } 5384 return nil 5385 } 5386 5387 func (a *AsPathParam) Len() int { 5388 return 2 + len(a.AS)*2 5389 } 5390 5391 func (a *AsPathParam) ASLen() int { 5392 switch a.Type { 5393 case BGP_ASPATH_ATTR_TYPE_SEQ: 5394 return len(a.AS) 5395 case BGP_ASPATH_ATTR_TYPE_SET: 5396 return 1 5397 case BGP_ASPATH_ATTR_TYPE_CONFED_SET, BGP_ASPATH_ATTR_TYPE_CONFED_SEQ: 5398 return 0 5399 } 5400 return 0 5401 } 5402 5403 func (a *AsPathParam) String() string { 5404 format, ok := asPathParamFormatMap[a.Type] 5405 if !ok { 5406 return fmt.Sprintf("%v", a.AS) 5407 } 5408 aspath := make([]string, 0, len(a.AS)) 5409 for _, asn := range a.AS { 5410 aspath = append(aspath, fmt.Sprintf("%d", asn)) 5411 } 5412 s := bytes.NewBuffer(make([]byte, 0, 32)) 5413 s.WriteString(format.start) 5414 s.WriteString(strings.Join(aspath, format.separator)) 5415 s.WriteString(format.end) 5416 return s.String() 5417 } 5418 5419 func (a *AsPathParam) MarshalJSON() ([]byte, error) { 5420 return json.Marshal(struct { 5421 Type uint8 `json:"segment_type"` 5422 Num uint8 `json:"num"` 5423 AS []uint16 `json:"asns"` 5424 }{ 5425 Type: a.Type, 5426 Num: a.Num, 5427 AS: a.AS, 5428 }) 5429 } 5430 5431 func NewAsPathParam(segType uint8, as []uint16) *AsPathParam { 5432 return &AsPathParam{ 5433 Type: segType, 5434 Num: uint8(len(as)), 5435 AS: as, 5436 } 5437 } 5438 5439 type As4PathParam struct { 5440 Type uint8 5441 Num uint8 5442 AS []uint32 5443 } 5444 5445 func (a *As4PathParam) GetType() uint8 { 5446 return a.Type 5447 } 5448 5449 func (a *As4PathParam) GetAS() []uint32 { 5450 return a.AS 5451 } 5452 5453 func (a *As4PathParam) Serialize() ([]byte, error) { 5454 buf := make([]byte, 2+len(a.AS)*4) 5455 buf[0] = a.Type 5456 buf[1] = a.Num 5457 for j, as := range a.AS { 5458 binary.BigEndian.PutUint32(buf[2+j*4:], as) 5459 } 5460 return buf, nil 5461 } 5462 5463 func (a *As4PathParam) DecodeFromBytes(data []byte) error { 5464 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5465 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_AS_PATH) 5466 if len(data) < 2 { 5467 return NewMessageError(eCode, eSubCode, nil, "AS4 param header length is short") 5468 } 5469 a.Type = data[0] 5470 a.Num = data[1] 5471 data = data[2:] 5472 if len(data) < int(a.Num)*4 { 5473 return NewMessageError(eCode, eSubCode, nil, "AS4 param data length is short") 5474 } 5475 for i := 0; i < int(a.Num); i++ { 5476 a.AS = append(a.AS, binary.BigEndian.Uint32(data)) 5477 data = data[4:] 5478 } 5479 return nil 5480 } 5481 5482 func (a *As4PathParam) Len() int { 5483 return 2 + len(a.AS)*4 5484 } 5485 5486 func (a *As4PathParam) ASLen() int { 5487 switch a.Type { 5488 case BGP_ASPATH_ATTR_TYPE_SEQ: 5489 return len(a.AS) 5490 case BGP_ASPATH_ATTR_TYPE_SET: 5491 return 1 5492 case BGP_ASPATH_ATTR_TYPE_CONFED_SET, BGP_ASPATH_ATTR_TYPE_CONFED_SEQ: 5493 return 0 5494 } 5495 return 0 5496 } 5497 5498 func (a *As4PathParam) String() string { 5499 format, ok := asPathParamFormatMap[a.Type] 5500 if !ok { 5501 return fmt.Sprintf("%v", a.AS) 5502 } 5503 aspath := make([]string, 0, len(a.AS)) 5504 for _, asn := range a.AS { 5505 aspath = append(aspath, fmt.Sprintf("%d", asn)) 5506 } 5507 s := bytes.NewBuffer(make([]byte, 0, 32)) 5508 s.WriteString(format.start) 5509 s.WriteString(strings.Join(aspath, format.separator)) 5510 s.WriteString(format.end) 5511 return s.String() 5512 } 5513 5514 func (a *As4PathParam) MarshalJSON() ([]byte, error) { 5515 return json.Marshal(struct { 5516 Type uint8 `json:"segment_type"` 5517 Num uint8 `json:"num"` 5518 AS []uint32 `json:"asns"` 5519 }{ 5520 Type: a.Type, 5521 Num: a.Num, 5522 AS: a.AS, 5523 }) 5524 } 5525 5526 func NewAs4PathParam(segType uint8, as []uint32) *As4PathParam { 5527 return &As4PathParam{ 5528 Type: segType, 5529 Num: uint8(len(as)), 5530 AS: as, 5531 } 5532 } 5533 5534 type PathAttributeAsPath struct { 5535 PathAttribute 5536 Value []AsPathParamInterface 5537 } 5538 5539 func (p *PathAttributeAsPath) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5540 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5541 if err != nil { 5542 return err 5543 } 5544 if p.Length == 0 { 5545 // ibgp or something 5546 return nil 5547 } 5548 isAs4, err := validateAsPathValueBytes(value) 5549 if err != nil { 5550 err.(*MessageError).Data, _ = p.PathAttribute.Serialize(value, options...) 5551 return err 5552 } 5553 for len(value) > 0 { 5554 var tuple AsPathParamInterface 5555 if isAs4 { 5556 tuple = &As4PathParam{} 5557 } else { 5558 tuple = &AsPathParam{} 5559 } 5560 err := tuple.DecodeFromBytes(value) 5561 if err != nil { 5562 return err 5563 } 5564 p.Value = append(p.Value, tuple) 5565 value = value[tuple.Len():] 5566 } 5567 return nil 5568 } 5569 5570 func (p *PathAttributeAsPath) Serialize(options ...*MarshallingOption) ([]byte, error) { 5571 buf := make([]byte, 0) 5572 for _, v := range p.Value { 5573 vbuf, err := v.Serialize() 5574 if err != nil { 5575 return nil, err 5576 } 5577 buf = append(buf, vbuf...) 5578 } 5579 return p.PathAttribute.Serialize(buf, options...) 5580 } 5581 5582 func (p *PathAttributeAsPath) String() string { 5583 params := make([]string, 0, len(p.Value)) 5584 for _, param := range p.Value { 5585 params = append(params, param.String()) 5586 } 5587 return strings.Join(params, " ") 5588 } 5589 5590 func (p *PathAttributeAsPath) MarshalJSON() ([]byte, error) { 5591 return json.Marshal(struct { 5592 Type BGPAttrType `json:"type"` 5593 Value []AsPathParamInterface `json:"as_paths"` 5594 }{ 5595 Type: p.GetType(), 5596 Value: p.Value, 5597 }) 5598 } 5599 5600 func NewPathAttributeAsPath(value []AsPathParamInterface) *PathAttributeAsPath { 5601 var l int 5602 for _, v := range value { 5603 l += v.Len() 5604 } 5605 t := BGP_ATTR_TYPE_AS_PATH 5606 return &PathAttributeAsPath{ 5607 PathAttribute: PathAttribute{ 5608 Flags: getPathAttrFlags(t, l), 5609 Type: t, 5610 Length: uint16(l), 5611 }, 5612 Value: value, 5613 } 5614 } 5615 5616 type PathAttributeNextHop struct { 5617 PathAttribute 5618 Value net.IP 5619 } 5620 5621 func (p *PathAttributeNextHop) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5622 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5623 if err != nil { 5624 return err 5625 } 5626 if p.Length != 4 && p.Length != 16 { 5627 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5628 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5629 return NewMessageError(eCode, eSubCode, nil, "nexthop length isn't correct") 5630 } 5631 p.Value = value 5632 return nil 5633 } 5634 5635 func (p *PathAttributeNextHop) Serialize(options ...*MarshallingOption) ([]byte, error) { 5636 return p.PathAttribute.Serialize(p.Value, options...) 5637 } 5638 5639 func (p *PathAttributeNextHop) String() string { 5640 return fmt.Sprintf("{Nexthop: %s}", p.Value) 5641 } 5642 5643 func (p *PathAttributeNextHop) MarshalJSON() ([]byte, error) { 5644 value := "0.0.0.0" 5645 if p.Value != nil { 5646 value = p.Value.String() 5647 } 5648 return json.Marshal(struct { 5649 Type BGPAttrType `json:"type"` 5650 Value string `json:"nexthop"` 5651 }{ 5652 Type: p.GetType(), 5653 Value: value, 5654 }) 5655 } 5656 5657 func NewPathAttributeNextHop(addr string) *PathAttributeNextHop { 5658 t := BGP_ATTR_TYPE_NEXT_HOP 5659 ip := net.ParseIP(addr) 5660 l := net.IPv4len 5661 if ip.To4() == nil { 5662 l = net.IPv6len 5663 } else { 5664 ip = ip.To4() 5665 } 5666 return &PathAttributeNextHop{ 5667 PathAttribute: PathAttribute{ 5668 Flags: PathAttrFlags[t], 5669 Type: t, 5670 Length: uint16(l), 5671 }, 5672 Value: ip, 5673 } 5674 } 5675 5676 type PathAttributeMultiExitDisc struct { 5677 PathAttribute 5678 Value uint32 5679 } 5680 5681 func (p *PathAttributeMultiExitDisc) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5682 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5683 if err != nil { 5684 return err 5685 } 5686 if p.Length != 4 { 5687 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5688 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5689 return NewMessageError(eCode, eSubCode, nil, "med length isn't correct") 5690 } 5691 p.Value = binary.BigEndian.Uint32(value) 5692 return nil 5693 } 5694 5695 func (p *PathAttributeMultiExitDisc) Serialize(options ...*MarshallingOption) ([]byte, error) { 5696 buf := make([]byte, 4) 5697 binary.BigEndian.PutUint32(buf, p.Value) 5698 return p.PathAttribute.Serialize(buf, options...) 5699 } 5700 5701 func (p *PathAttributeMultiExitDisc) String() string { 5702 return fmt.Sprintf("{Med: %d}", p.Value) 5703 } 5704 5705 func (p *PathAttributeMultiExitDisc) MarshalJSON() ([]byte, error) { 5706 return json.Marshal(struct { 5707 Type BGPAttrType `json:"type"` 5708 Value uint32 `json:"metric"` 5709 }{ 5710 Type: p.GetType(), 5711 Value: p.Value, 5712 }) 5713 } 5714 5715 func NewPathAttributeMultiExitDisc(value uint32) *PathAttributeMultiExitDisc { 5716 t := BGP_ATTR_TYPE_MULTI_EXIT_DISC 5717 return &PathAttributeMultiExitDisc{ 5718 PathAttribute: PathAttribute{ 5719 Flags: PathAttrFlags[t], 5720 Type: t, 5721 Length: 4, 5722 }, 5723 Value: value, 5724 } 5725 } 5726 5727 type PathAttributeLocalPref struct { 5728 PathAttribute 5729 Value uint32 5730 } 5731 5732 func (p *PathAttributeLocalPref) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5733 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5734 if err != nil { 5735 return err 5736 } 5737 if p.Length != 4 { 5738 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5739 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5740 return NewMessageError(eCode, eSubCode, nil, "local pref length isn't correct") 5741 } 5742 p.Value = binary.BigEndian.Uint32(value) 5743 return nil 5744 } 5745 5746 func (p *PathAttributeLocalPref) Serialize(options ...*MarshallingOption) ([]byte, error) { 5747 buf := make([]byte, 4) 5748 binary.BigEndian.PutUint32(buf, p.Value) 5749 return p.PathAttribute.Serialize(buf, options...) 5750 } 5751 5752 func (p *PathAttributeLocalPref) String() string { 5753 return fmt.Sprintf("{LocalPref: %d}", p.Value) 5754 } 5755 5756 func (p *PathAttributeLocalPref) MarshalJSON() ([]byte, error) { 5757 return json.Marshal(struct { 5758 Type BGPAttrType `json:"type"` 5759 Value uint32 `json:"value"` 5760 }{ 5761 Type: p.GetType(), 5762 Value: p.Value, 5763 }) 5764 } 5765 5766 func NewPathAttributeLocalPref(value uint32) *PathAttributeLocalPref { 5767 t := BGP_ATTR_TYPE_LOCAL_PREF 5768 return &PathAttributeLocalPref{ 5769 PathAttribute: PathAttribute{ 5770 Flags: PathAttrFlags[t], 5771 Type: t, 5772 Length: 4, 5773 }, 5774 Value: value, 5775 } 5776 } 5777 5778 type PathAttributeAtomicAggregate struct { 5779 PathAttribute 5780 } 5781 5782 func (p *PathAttributeAtomicAggregate) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5783 _, err := p.PathAttribute.DecodeFromBytes(data, options...) 5784 if err != nil { 5785 return err 5786 } 5787 if p.Length != 0 { 5788 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5789 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5790 return NewMessageError(eCode, eSubCode, nil, "atomic aggregate should have no value") 5791 } 5792 return nil 5793 } 5794 5795 func (p *PathAttributeAtomicAggregate) Serialize(options ...*MarshallingOption) ([]byte, error) { 5796 return p.PathAttribute.Serialize(nil, options...) 5797 } 5798 5799 func (p *PathAttributeAtomicAggregate) String() string { 5800 return "{AtomicAggregate}" 5801 } 5802 5803 func (p *PathAttributeAtomicAggregate) MarshalJSON() ([]byte, error) { 5804 return json.Marshal(struct { 5805 Type BGPAttrType `json:"type"` 5806 }{ 5807 Type: p.GetType(), 5808 }) 5809 } 5810 5811 func NewPathAttributeAtomicAggregate() *PathAttributeAtomicAggregate { 5812 t := BGP_ATTR_TYPE_ATOMIC_AGGREGATE 5813 return &PathAttributeAtomicAggregate{ 5814 PathAttribute: PathAttribute{ 5815 Flags: PathAttrFlags[t], 5816 Type: t, 5817 Length: 0, 5818 }, 5819 } 5820 } 5821 5822 type PathAttributeAggregatorParam struct { 5823 AS uint32 5824 Askind reflect.Kind 5825 Address net.IP 5826 } 5827 5828 type PathAttributeAggregator struct { 5829 PathAttribute 5830 Value PathAttributeAggregatorParam 5831 } 5832 5833 func (p *PathAttributeAggregator) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5834 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5835 if err != nil { 5836 return err 5837 } 5838 switch p.Length { 5839 case 6: 5840 p.Value.Askind = reflect.Uint16 5841 p.Value.AS = uint32(binary.BigEndian.Uint16(value[0:2])) 5842 p.Value.Address = value[2:] 5843 case 8: 5844 p.Value.Askind = reflect.Uint32 5845 p.Value.AS = binary.BigEndian.Uint32(value[0:4]) 5846 p.Value.Address = value[4:] 5847 default: 5848 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5849 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5850 return NewMessageError(eCode, eSubCode, nil, "aggregator length isn't correct") 5851 } 5852 return nil 5853 } 5854 5855 func (p *PathAttributeAggregator) Serialize(options ...*MarshallingOption) ([]byte, error) { 5856 var buf []byte 5857 switch p.Value.Askind { 5858 case reflect.Uint16: 5859 buf = make([]byte, 6) 5860 binary.BigEndian.PutUint16(buf, uint16(p.Value.AS)) 5861 copy(buf[2:], p.Value.Address) 5862 case reflect.Uint32: 5863 buf = make([]byte, 8) 5864 binary.BigEndian.PutUint32(buf, p.Value.AS) 5865 copy(buf[4:], p.Value.Address) 5866 } 5867 return p.PathAttribute.Serialize(buf, options...) 5868 } 5869 5870 func (p *PathAttributeAggregator) String() string { 5871 return fmt.Sprintf("{Aggregate: {AS: %d, Address: %s}}", p.Value.AS, p.Value.Address) 5872 } 5873 5874 func (p *PathAttributeAggregator) MarshalJSON() ([]byte, error) { 5875 return json.Marshal(struct { 5876 Type BGPAttrType `json:"type"` 5877 AS uint32 `json:"as"` 5878 Address string `json:"address"` 5879 }{ 5880 Type: p.GetType(), 5881 AS: p.Value.AS, 5882 Address: p.Value.Address.String(), 5883 }) 5884 } 5885 5886 func NewPathAttributeAggregator(as interface{}, address string) *PathAttributeAggregator { 5887 v := reflect.ValueOf(as) 5888 asKind := v.Kind() 5889 var l uint16 5890 switch asKind { 5891 case reflect.Uint16: 5892 l = 6 5893 case reflect.Uint32: 5894 l = 8 5895 default: 5896 // Invalid type 5897 return nil 5898 } 5899 t := BGP_ATTR_TYPE_AGGREGATOR 5900 return &PathAttributeAggregator{ 5901 PathAttribute: PathAttribute{ 5902 Flags: PathAttrFlags[t], 5903 Type: t, 5904 Length: l, 5905 }, 5906 Value: PathAttributeAggregatorParam{ 5907 AS: uint32(v.Uint()), 5908 Askind: asKind, 5909 Address: net.ParseIP(address).To4(), 5910 }, 5911 } 5912 } 5913 5914 type PathAttributeCommunities struct { 5915 PathAttribute 5916 Value []uint32 5917 } 5918 5919 func (p *PathAttributeCommunities) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 5920 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 5921 if err != nil { 5922 return err 5923 } 5924 if p.Length%4 != 0 { 5925 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 5926 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 5927 return NewMessageError(eCode, eSubCode, nil, "communities length isn't correct") 5928 } 5929 for len(value) >= 4 { 5930 p.Value = append(p.Value, binary.BigEndian.Uint32(value)) 5931 value = value[4:] 5932 } 5933 return nil 5934 } 5935 5936 func (p *PathAttributeCommunities) Serialize(options ...*MarshallingOption) ([]byte, error) { 5937 buf := make([]byte, len(p.Value)*4) 5938 for i, v := range p.Value { 5939 binary.BigEndian.PutUint32(buf[i*4:], v) 5940 } 5941 return p.PathAttribute.Serialize(buf, options...) 5942 } 5943 5944 type WellKnownCommunity uint32 5945 5946 const ( 5947 COMMUNITY_INTERNET WellKnownCommunity = 0x00000000 5948 COMMUNITY_PLANNED_SHUT WellKnownCommunity = 0xffff0000 5949 COMMUNITY_ACCEPT_OWN WellKnownCommunity = 0xffff0001 5950 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4 WellKnownCommunity = 0xffff0002 5951 COMMUNITY_ROUTE_FILTER_v4 WellKnownCommunity = 0xffff0003 5952 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6 WellKnownCommunity = 0xffff0004 5953 COMMUNITY_ROUTE_FILTER_v6 WellKnownCommunity = 0xffff0005 5954 COMMUNITY_LLGR_STALE WellKnownCommunity = 0xffff0006 5955 COMMUNITY_NO_LLGR WellKnownCommunity = 0xffff0007 5956 COMMUNITY_BLACKHOLE WellKnownCommunity = 0xffff029a 5957 COMMUNITY_NO_EXPORT WellKnownCommunity = 0xffffff01 5958 COMMUNITY_NO_ADVERTISE WellKnownCommunity = 0xffffff02 5959 COMMUNITY_NO_EXPORT_SUBCONFED WellKnownCommunity = 0xffffff03 5960 COMMUNITY_NO_PEER WellKnownCommunity = 0xffffff04 5961 ) 5962 5963 var WellKnownCommunityNameMap = map[WellKnownCommunity]string{ 5964 COMMUNITY_INTERNET: "internet", 5965 COMMUNITY_PLANNED_SHUT: "planned-shut", 5966 COMMUNITY_ACCEPT_OWN: "accept-own", 5967 COMMUNITY_ROUTE_FILTER_TRANSLATED_v4: "route-filter-translated-v4", 5968 COMMUNITY_ROUTE_FILTER_v4: "route-filter-v4", 5969 COMMUNITY_ROUTE_FILTER_TRANSLATED_v6: "route-filter-translated-v6", 5970 COMMUNITY_ROUTE_FILTER_v6: "route-filter-v6", 5971 COMMUNITY_LLGR_STALE: "llgr-stale", 5972 COMMUNITY_NO_LLGR: "no-llgr", 5973 COMMUNITY_BLACKHOLE: "blackhole", 5974 COMMUNITY_NO_EXPORT: "no-export", 5975 COMMUNITY_NO_ADVERTISE: "no-advertise", 5976 COMMUNITY_NO_EXPORT_SUBCONFED: "no-export-subconfed", 5977 COMMUNITY_NO_PEER: "no-peer", 5978 } 5979 5980 var WellKnownCommunityValueMap = map[string]WellKnownCommunity{ 5981 WellKnownCommunityNameMap[COMMUNITY_INTERNET]: COMMUNITY_INTERNET, 5982 WellKnownCommunityNameMap[COMMUNITY_PLANNED_SHUT]: COMMUNITY_PLANNED_SHUT, 5983 WellKnownCommunityNameMap[COMMUNITY_ACCEPT_OWN]: COMMUNITY_ACCEPT_OWN, 5984 WellKnownCommunityNameMap[COMMUNITY_ROUTE_FILTER_TRANSLATED_v4]: COMMUNITY_ROUTE_FILTER_TRANSLATED_v4, 5985 WellKnownCommunityNameMap[COMMUNITY_ROUTE_FILTER_v4]: COMMUNITY_ROUTE_FILTER_v4, 5986 WellKnownCommunityNameMap[COMMUNITY_ROUTE_FILTER_TRANSLATED_v6]: COMMUNITY_ROUTE_FILTER_TRANSLATED_v6, 5987 WellKnownCommunityNameMap[COMMUNITY_ROUTE_FILTER_v6]: COMMUNITY_ROUTE_FILTER_v6, 5988 WellKnownCommunityNameMap[COMMUNITY_LLGR_STALE]: COMMUNITY_LLGR_STALE, 5989 WellKnownCommunityNameMap[COMMUNITY_NO_LLGR]: COMMUNITY_NO_LLGR, 5990 WellKnownCommunityNameMap[COMMUNITY_NO_EXPORT]: COMMUNITY_NO_EXPORT, 5991 WellKnownCommunityNameMap[COMMUNITY_BLACKHOLE]: COMMUNITY_BLACKHOLE, 5992 WellKnownCommunityNameMap[COMMUNITY_NO_ADVERTISE]: COMMUNITY_NO_ADVERTISE, 5993 WellKnownCommunityNameMap[COMMUNITY_NO_EXPORT_SUBCONFED]: COMMUNITY_NO_EXPORT_SUBCONFED, 5994 WellKnownCommunityNameMap[COMMUNITY_NO_PEER]: COMMUNITY_NO_PEER, 5995 } 5996 5997 func (p *PathAttributeCommunities) String() string { 5998 l := []string{} 5999 for _, v := range p.Value { 6000 n, ok := WellKnownCommunityNameMap[WellKnownCommunity(v)] 6001 if ok { 6002 l = append(l, n) 6003 } else { 6004 l = append(l, fmt.Sprintf("%d:%d", (0xffff0000&v)>>16, 0xffff&v)) 6005 } 6006 } 6007 return fmt.Sprintf("{Communities: %s}", strings.Join(l, ", ")) 6008 } 6009 6010 func (p *PathAttributeCommunities) MarshalJSON() ([]byte, error) { 6011 return json.Marshal(struct { 6012 Type BGPAttrType `json:"type"` 6013 Value []uint32 `json:"communities"` 6014 }{ 6015 Type: p.GetType(), 6016 Value: p.Value, 6017 }) 6018 } 6019 6020 func NewPathAttributeCommunities(value []uint32) *PathAttributeCommunities { 6021 l := len(value) * 4 6022 t := BGP_ATTR_TYPE_COMMUNITIES 6023 return &PathAttributeCommunities{ 6024 PathAttribute: PathAttribute{ 6025 Flags: getPathAttrFlags(t, l), 6026 Type: t, 6027 Length: uint16(l), 6028 }, 6029 Value: value, 6030 } 6031 } 6032 6033 type PathAttributeOriginatorId struct { 6034 PathAttribute 6035 Value net.IP 6036 } 6037 6038 func (p *PathAttributeOriginatorId) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 6039 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 6040 if err != nil { 6041 return err 6042 } 6043 if p.Length != 4 { 6044 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 6045 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 6046 return NewMessageError(eCode, eSubCode, nil, "originator id length isn't correct") 6047 } 6048 p.Value = value 6049 return nil 6050 } 6051 6052 func (p *PathAttributeOriginatorId) String() string { 6053 return fmt.Sprintf("{Originator: %s}", p.Value) 6054 } 6055 6056 func (p *PathAttributeOriginatorId) MarshalJSON() ([]byte, error) { 6057 return json.Marshal(struct { 6058 Type BGPAttrType `json:"type"` 6059 Value string `json:"value"` 6060 }{ 6061 Type: p.GetType(), 6062 Value: p.Value.String(), 6063 }) 6064 } 6065 6066 func (p *PathAttributeOriginatorId) Serialize(options ...*MarshallingOption) ([]byte, error) { 6067 buf := make([]byte, 4) 6068 copy(buf, p.Value) 6069 return p.PathAttribute.Serialize(buf, options...) 6070 } 6071 6072 func NewPathAttributeOriginatorId(value string) *PathAttributeOriginatorId { 6073 t := BGP_ATTR_TYPE_ORIGINATOR_ID 6074 return &PathAttributeOriginatorId{ 6075 PathAttribute: PathAttribute{ 6076 Flags: PathAttrFlags[t], 6077 Type: t, 6078 Length: 4, 6079 }, 6080 Value: net.ParseIP(value).To4(), 6081 } 6082 } 6083 6084 type PathAttributeClusterList struct { 6085 PathAttribute 6086 Value []net.IP 6087 } 6088 6089 func (p *PathAttributeClusterList) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 6090 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 6091 if err != nil { 6092 return err 6093 } 6094 if p.Length%4 != 0 { 6095 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 6096 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 6097 return NewMessageError(eCode, eSubCode, nil, "clusterlist length isn't correct") 6098 } 6099 for len(value) >= 4 { 6100 p.Value = append(p.Value, value[:4]) 6101 value = value[4:] 6102 } 6103 return nil 6104 } 6105 6106 func (p *PathAttributeClusterList) Serialize(options ...*MarshallingOption) ([]byte, error) { 6107 buf := make([]byte, len(p.Value)*4) 6108 for i, v := range p.Value { 6109 copy(buf[i*4:], v) 6110 } 6111 return p.PathAttribute.Serialize(buf, options...) 6112 } 6113 6114 func (p *PathAttributeClusterList) String() string { 6115 return fmt.Sprintf("{ClusterList: %v}", p.Value) 6116 } 6117 6118 func (p *PathAttributeClusterList) MarshalJSON() ([]byte, error) { 6119 value := make([]string, 0, len(p.Value)) 6120 for _, v := range p.Value { 6121 value = append(value, v.String()) 6122 } 6123 return json.Marshal(struct { 6124 Type BGPAttrType `json:"type"` 6125 Value []string `json:"value"` 6126 }{ 6127 Type: p.GetType(), 6128 Value: value, 6129 }) 6130 } 6131 6132 func NewPathAttributeClusterList(value []string) *PathAttributeClusterList { 6133 l := len(value) * 4 6134 list := make([]net.IP, len(value)) 6135 for i, v := range value { 6136 list[i] = net.ParseIP(v).To4() 6137 } 6138 t := BGP_ATTR_TYPE_CLUSTER_LIST 6139 return &PathAttributeClusterList{ 6140 PathAttribute: PathAttribute{ 6141 Flags: getPathAttrFlags(t, l), 6142 Type: t, 6143 Length: uint16(l), 6144 }, 6145 Value: list, 6146 } 6147 } 6148 6149 type PathAttributeMpReachNLRI struct { 6150 PathAttribute 6151 Nexthop net.IP 6152 LinkLocalNexthop net.IP 6153 AFI uint16 6154 SAFI uint8 6155 Value []AddrPrefixInterface 6156 } 6157 6158 func (p *PathAttributeMpReachNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 6159 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 6160 if err != nil { 6161 return err 6162 } 6163 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 6164 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 6165 eData, _ := p.PathAttribute.Serialize(value, options...) 6166 if p.Length < 3 { 6167 return NewMessageError(eCode, eSubCode, value, "mpreach header length is short") 6168 } 6169 afi := binary.BigEndian.Uint16(value[0:2]) 6170 safi := value[2] 6171 p.AFI = afi 6172 p.SAFI = safi 6173 _, err = NewPrefixFromRouteFamily(afi, safi) 6174 if err != nil { 6175 return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, eData, err.Error()) 6176 } 6177 nexthoplen := int(value[3]) 6178 if len(value) < 4+nexthoplen { 6179 return NewMessageError(eCode, eSubCode, value, "mpreach nexthop length is short") 6180 } 6181 nexthopbin := value[4 : 4+nexthoplen] 6182 if nexthoplen > 0 { 6183 v4addrlen := 4 6184 v6addrlen := 16 6185 offset := 0 6186 if safi == SAFI_MPLS_VPN { 6187 offset = 8 6188 } 6189 switch nexthoplen { 6190 case 2 * (offset + v6addrlen): 6191 p.LinkLocalNexthop = nexthopbin[offset+v6addrlen+offset : 2*(offset+v6addrlen)] 6192 fallthrough 6193 case offset + v6addrlen: 6194 p.Nexthop = nexthopbin[offset : offset+v6addrlen] 6195 case offset + v4addrlen: 6196 p.Nexthop = nexthopbin[offset : offset+v4addrlen] 6197 default: 6198 return NewMessageError(eCode, eSubCode, value, "mpreach nexthop length is incorrect") 6199 } 6200 } 6201 value = value[4+nexthoplen:] 6202 // skip reserved 6203 if len(value) == 0 { 6204 return NewMessageError(eCode, eSubCode, value, "no skip byte") 6205 } 6206 value = value[1:] 6207 addpathLen := 0 6208 if IsAddPathEnabled(true, AfiSafiToRouteFamily(afi, safi), options) { 6209 addpathLen = 4 6210 } 6211 for len(value) > 0 { 6212 prefix, err := NewPrefixFromRouteFamily(afi, safi) 6213 if err != nil { 6214 return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, eData, err.Error()) 6215 } 6216 err = prefix.DecodeFromBytes(value, options...) 6217 if err != nil { 6218 return err 6219 } 6220 if prefix.Len(options...)+addpathLen > len(value) { 6221 return NewMessageError(eCode, eSubCode, value, "prefix length is incorrect") 6222 } 6223 value = value[prefix.Len(options...)+addpathLen:] 6224 p.Value = append(p.Value, prefix) 6225 } 6226 return nil 6227 } 6228 6229 func (p *PathAttributeMpReachNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 6230 afi := p.AFI 6231 safi := p.SAFI 6232 nexthoplen := 4 6233 if afi == AFI_IP6 || p.Nexthop.To4() == nil { 6234 nexthoplen = 16 6235 } 6236 offset := 0 6237 switch safi { 6238 case SAFI_MPLS_VPN: 6239 offset = 8 6240 nexthoplen += offset 6241 case SAFI_FLOW_SPEC_VPN, SAFI_FLOW_SPEC_UNICAST: 6242 nexthoplen = 0 6243 } 6244 if p.LinkLocalNexthop != nil { 6245 nexthoplen *= 2 6246 } 6247 buf := make([]byte, 4+nexthoplen) 6248 binary.BigEndian.PutUint16(buf[0:], afi) 6249 buf[2] = safi 6250 buf[3] = uint8(nexthoplen) 6251 if nexthoplen != 0 { 6252 if p.Nexthop.To4() == nil { 6253 copy(buf[4+offset:], p.Nexthop.To16()) 6254 if p.LinkLocalNexthop != nil { 6255 copy(buf[4+offset+16:], p.LinkLocalNexthop.To16()) 6256 } 6257 } else { 6258 copy(buf[4+offset:], p.Nexthop) 6259 } 6260 } 6261 buf = append(buf, make([]byte, 1)...) 6262 for _, prefix := range p.Value { 6263 pbuf, err := prefix.Serialize(options...) 6264 if err != nil { 6265 return nil, err 6266 } 6267 buf = append(buf, pbuf...) 6268 } 6269 return p.PathAttribute.Serialize(buf, options...) 6270 } 6271 6272 func (p *PathAttributeMpReachNLRI) MarshalJSON() ([]byte, error) { 6273 nexthop := p.Nexthop.String() 6274 if p.Nexthop == nil { 6275 switch p.AFI { 6276 case AFI_IP: 6277 nexthop = "0.0.0.0" 6278 case AFI_IP6: 6279 nexthop = "::" 6280 default: 6281 nexthop = "fictitious" 6282 } 6283 } 6284 return json.Marshal(struct { 6285 Type BGPAttrType `json:"type"` 6286 Nexthop string `json:"nexthop"` 6287 AFI uint16 `json:"afi"` 6288 SAFI uint8 `json:"safi"` 6289 Value []AddrPrefixInterface `json:"value"` 6290 }{ 6291 Type: p.GetType(), 6292 Nexthop: nexthop, 6293 AFI: p.AFI, 6294 SAFI: p.SAFI, 6295 Value: p.Value, 6296 }) 6297 } 6298 6299 func (p *PathAttributeMpReachNLRI) String() string { 6300 return fmt.Sprintf("{MpReach(%s): {Nexthop: %s, NLRIs: %s}}", AfiSafiToRouteFamily(p.AFI, p.SAFI), p.Nexthop, p.Value) 6301 } 6302 6303 func NewPathAttributeMpReachNLRI(nexthop string, nlri []AddrPrefixInterface) *PathAttributeMpReachNLRI { 6304 // AFI(2) + SAFI(1) + NexthopLength(1) + Nexthop(variable) 6305 // + Reserved(1) + NLRI(variable) 6306 l := 5 6307 var afi uint16 6308 var safi uint8 6309 if len(nlri) > 0 { 6310 afi = nlri[0].AFI() 6311 safi = nlri[0].SAFI() 6312 } 6313 nh := net.ParseIP(nexthop) 6314 if nh.To4() != nil && afi != AFI_IP6 { 6315 nh = nh.To4() 6316 switch safi { 6317 case SAFI_MPLS_VPN: 6318 l += 12 6319 case SAFI_FLOW_SPEC_VPN, SAFI_FLOW_SPEC_UNICAST: 6320 // Should not have Nexthop 6321 default: 6322 l += 4 6323 } 6324 } else { 6325 switch safi { 6326 case SAFI_MPLS_VPN: 6327 l += 24 6328 case SAFI_FLOW_SPEC_VPN, SAFI_FLOW_SPEC_UNICAST: 6329 // Should not have Nexthop 6330 default: 6331 l += 16 6332 } 6333 } 6334 var nlriLen int 6335 for _, n := range nlri { 6336 l += n.Len() 6337 nBuf, _ := n.Serialize() 6338 nlriLen += len(nBuf) 6339 } 6340 t := BGP_ATTR_TYPE_MP_REACH_NLRI 6341 return &PathAttributeMpReachNLRI{ 6342 PathAttribute: PathAttribute{ 6343 Flags: getPathAttrFlags(t, l), 6344 Type: t, 6345 Length: uint16(l), 6346 }, 6347 Nexthop: nh, 6348 AFI: afi, 6349 SAFI: safi, 6350 Value: nlri, 6351 } 6352 } 6353 6354 type PathAttributeMpUnreachNLRI struct { 6355 PathAttribute 6356 AFI uint16 6357 SAFI uint8 6358 Value []AddrPrefixInterface 6359 } 6360 6361 func (p *PathAttributeMpUnreachNLRI) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 6362 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 6363 if err != nil { 6364 return err 6365 } 6366 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 6367 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 6368 eData, _ := p.PathAttribute.Serialize(value, options...) 6369 if p.Length < 3 { 6370 return NewMessageError(eCode, eSubCode, value, "unreach header length is incorrect") 6371 } 6372 afi := binary.BigEndian.Uint16(value[0:2]) 6373 safi := value[2] 6374 _, err = NewPrefixFromRouteFamily(afi, safi) 6375 if err != nil { 6376 return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, eData, err.Error()) 6377 } 6378 value = value[3:] 6379 p.AFI = afi 6380 p.SAFI = safi 6381 addpathLen := 0 6382 if IsAddPathEnabled(true, AfiSafiToRouteFamily(afi, safi), options) { 6383 addpathLen = 4 6384 } 6385 for len(value) > 0 { 6386 prefix, err := NewPrefixFromRouteFamily(afi, safi) 6387 if err != nil { 6388 return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, eData, err.Error()) 6389 } 6390 err = prefix.DecodeFromBytes(value, options...) 6391 if err != nil { 6392 return err 6393 } 6394 if prefix.Len(options...)+addpathLen > len(value) { 6395 return NewMessageError(eCode, eSubCode, eData, "prefix length is incorrect") 6396 } 6397 value = value[prefix.Len(options...)+addpathLen:] 6398 p.Value = append(p.Value, prefix) 6399 } 6400 return nil 6401 } 6402 6403 func (p *PathAttributeMpUnreachNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 6404 buf := make([]byte, 3) 6405 binary.BigEndian.PutUint16(buf, p.AFI) 6406 buf[2] = p.SAFI 6407 for _, prefix := range p.Value { 6408 pbuf, err := prefix.Serialize(options...) 6409 if err != nil { 6410 return nil, err 6411 } 6412 buf = append(buf, pbuf...) 6413 } 6414 return p.PathAttribute.Serialize(buf, options...) 6415 } 6416 6417 func (p *PathAttributeMpUnreachNLRI) MarshalJSON() ([]byte, error) { 6418 return json.Marshal(struct { 6419 Type BGPAttrType `json:"type"` 6420 AFI uint16 `json:"afi"` 6421 SAFI uint8 `json:"safi"` 6422 Value []AddrPrefixInterface `json:"value"` 6423 }{ 6424 Type: p.GetType(), 6425 AFI: p.AFI, 6426 SAFI: p.SAFI, 6427 Value: p.Value, 6428 }) 6429 } 6430 6431 func (p *PathAttributeMpUnreachNLRI) String() string { 6432 if len(p.Value) > 0 { 6433 return fmt.Sprintf("{MpUnreach(%s): {NLRIs: %s}}", AfiSafiToRouteFamily(p.AFI, p.SAFI), p.Value) 6434 } 6435 return fmt.Sprintf("{MpUnreach(%s): End-of-Rib}", AfiSafiToRouteFamily(p.AFI, p.SAFI)) 6436 } 6437 6438 func NewPathAttributeMpUnreachNLRI(nlri []AddrPrefixInterface) *PathAttributeMpUnreachNLRI { 6439 // AFI(2) + SAFI(1) + NLRI(variable) 6440 l := 3 6441 var afi uint16 6442 var safi uint8 6443 if len(nlri) > 0 { 6444 afi = nlri[0].AFI() 6445 safi = nlri[0].SAFI() 6446 } 6447 for _, n := range nlri { 6448 l += n.Len() 6449 } 6450 t := BGP_ATTR_TYPE_MP_UNREACH_NLRI 6451 return &PathAttributeMpUnreachNLRI{ 6452 PathAttribute: PathAttribute{ 6453 Flags: getPathAttrFlags(t, l), 6454 Type: t, 6455 Length: uint16(l), 6456 }, 6457 AFI: afi, 6458 SAFI: safi, 6459 Value: nlri, 6460 } 6461 } 6462 6463 type ExtendedCommunityInterface interface { 6464 Serialize() ([]byte, error) 6465 String() string 6466 GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) 6467 MarshalJSON() ([]byte, error) 6468 Flat() map[string]string 6469 } 6470 6471 type TwoOctetAsSpecificExtended struct { 6472 SubType ExtendedCommunityAttrSubType 6473 AS uint16 6474 LocalAdmin uint32 6475 IsTransitive bool 6476 } 6477 6478 func (e *TwoOctetAsSpecificExtended) Serialize() ([]byte, error) { 6479 buf := make([]byte, 8) 6480 if e.IsTransitive { 6481 buf[0] = byte(EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC) 6482 } else { 6483 buf[0] = byte(EC_TYPE_NON_TRANSITIVE_TWO_OCTET_AS_SPECIFIC) 6484 } 6485 buf[1] = byte(e.SubType) 6486 binary.BigEndian.PutUint16(buf[2:], e.AS) 6487 binary.BigEndian.PutUint32(buf[4:], e.LocalAdmin) 6488 return buf, nil 6489 } 6490 6491 func (e *TwoOctetAsSpecificExtended) String() string { 6492 return fmt.Sprintf("%d:%d", e.AS, e.LocalAdmin) 6493 } 6494 6495 func (e *TwoOctetAsSpecificExtended) MarshalJSON() ([]byte, error) { 6496 t, s := e.GetTypes() 6497 return json.Marshal(struct { 6498 Type ExtendedCommunityAttrType `json:"type"` 6499 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 6500 Value string `json:"value"` 6501 }{ 6502 Type: t, 6503 Subtype: s, 6504 Value: e.String(), 6505 }) 6506 } 6507 6508 func (e *TwoOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6509 t := EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC 6510 if !e.IsTransitive { 6511 t = EC_TYPE_NON_TRANSITIVE_TWO_OCTET_AS_SPECIFIC 6512 } 6513 return t, e.SubType 6514 } 6515 6516 func NewTwoOctetAsSpecificExtended(subtype ExtendedCommunityAttrSubType, as uint16, localAdmin uint32, isTransitive bool) *TwoOctetAsSpecificExtended { 6517 return &TwoOctetAsSpecificExtended{ 6518 SubType: subtype, 6519 AS: as, 6520 LocalAdmin: localAdmin, 6521 IsTransitive: isTransitive, 6522 } 6523 } 6524 6525 type IPv4AddressSpecificExtended struct { 6526 SubType ExtendedCommunityAttrSubType 6527 IPv4 net.IP 6528 LocalAdmin uint16 6529 IsTransitive bool 6530 } 6531 6532 func (e *IPv4AddressSpecificExtended) Serialize() ([]byte, error) { 6533 buf := make([]byte, 8) 6534 if e.IsTransitive { 6535 buf[0] = byte(EC_TYPE_TRANSITIVE_IP4_SPECIFIC) 6536 } else { 6537 buf[0] = byte(EC_TYPE_NON_TRANSITIVE_IP4_SPECIFIC) 6538 } 6539 buf[1] = byte(e.SubType) 6540 copy(buf[2:6], e.IPv4) 6541 binary.BigEndian.PutUint16(buf[6:], e.LocalAdmin) 6542 return buf, nil 6543 } 6544 6545 func (e *IPv4AddressSpecificExtended) String() string { 6546 return fmt.Sprintf("%s:%d", e.IPv4.String(), e.LocalAdmin) 6547 } 6548 6549 func (e *IPv4AddressSpecificExtended) MarshalJSON() ([]byte, error) { 6550 t, s := e.GetTypes() 6551 return json.Marshal(struct { 6552 Type ExtendedCommunityAttrType `json:"type"` 6553 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 6554 Value string `json:"value"` 6555 }{ 6556 Type: t, 6557 Subtype: s, 6558 Value: e.String(), 6559 }) 6560 } 6561 6562 func (e *IPv4AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6563 t := EC_TYPE_TRANSITIVE_IP4_SPECIFIC 6564 if !e.IsTransitive { 6565 t = EC_TYPE_NON_TRANSITIVE_IP4_SPECIFIC 6566 } 6567 return t, e.SubType 6568 } 6569 6570 func NewIPv4AddressSpecificExtended(subtype ExtendedCommunityAttrSubType, ip string, localAdmin uint16, isTransitive bool) *IPv4AddressSpecificExtended { 6571 ipv4 := net.ParseIP(ip) 6572 if ipv4.To4() == nil { 6573 return nil 6574 } 6575 return &IPv4AddressSpecificExtended{ 6576 SubType: subtype, 6577 IPv4: ipv4.To4(), 6578 LocalAdmin: localAdmin, 6579 IsTransitive: isTransitive, 6580 } 6581 } 6582 6583 type IPv6AddressSpecificExtended struct { 6584 SubType ExtendedCommunityAttrSubType 6585 IPv6 net.IP 6586 LocalAdmin uint16 6587 IsTransitive bool 6588 } 6589 6590 func (e *IPv6AddressSpecificExtended) Serialize() ([]byte, error) { 6591 buf := make([]byte, 20) 6592 if e.IsTransitive { 6593 buf[0] = byte(EC_TYPE_TRANSITIVE_IP6_SPECIFIC) 6594 } else { 6595 buf[0] = byte(EC_TYPE_NON_TRANSITIVE_IP6_SPECIFIC) 6596 } 6597 buf[1] = byte(e.SubType) 6598 copy(buf[2:18], e.IPv6) 6599 binary.BigEndian.PutUint16(buf[18:], e.LocalAdmin) 6600 return buf, nil 6601 } 6602 6603 func (e *IPv6AddressSpecificExtended) String() string { 6604 return fmt.Sprintf("%s:%d", e.IPv6.String(), e.LocalAdmin) 6605 } 6606 6607 func (e *IPv6AddressSpecificExtended) MarshalJSON() ([]byte, error) { 6608 t, s := e.GetTypes() 6609 return json.Marshal(struct { 6610 Type ExtendedCommunityAttrType `json:"type"` 6611 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 6612 Value string `json:"value"` 6613 }{ 6614 Type: t, 6615 Subtype: s, 6616 Value: e.String(), 6617 }) 6618 } 6619 6620 func (e *IPv6AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6621 t := EC_TYPE_TRANSITIVE_IP6_SPECIFIC 6622 if !e.IsTransitive { 6623 t = EC_TYPE_NON_TRANSITIVE_IP6_SPECIFIC 6624 } 6625 return t, e.SubType 6626 } 6627 6628 func NewIPv6AddressSpecificExtended(subtype ExtendedCommunityAttrSubType, ip string, localAdmin uint16, isTransitive bool) *IPv6AddressSpecificExtended { 6629 ipv6 := net.ParseIP(ip) 6630 if ipv6.To16() == nil { 6631 return nil 6632 } 6633 return &IPv6AddressSpecificExtended{ 6634 SubType: subtype, 6635 IPv6: ipv6.To16(), 6636 LocalAdmin: localAdmin, 6637 IsTransitive: isTransitive, 6638 } 6639 } 6640 6641 type FourOctetAsSpecificExtended struct { 6642 SubType ExtendedCommunityAttrSubType 6643 AS uint32 6644 LocalAdmin uint16 6645 IsTransitive bool 6646 } 6647 6648 func (e *FourOctetAsSpecificExtended) Serialize() ([]byte, error) { 6649 buf := make([]byte, 8) 6650 if e.IsTransitive { 6651 buf[0] = byte(EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC) 6652 } else { 6653 buf[0] = byte(EC_TYPE_NON_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC) 6654 } 6655 buf[1] = byte(e.SubType) 6656 binary.BigEndian.PutUint32(buf[2:], e.AS) 6657 binary.BigEndian.PutUint16(buf[6:], e.LocalAdmin) 6658 return buf, nil 6659 } 6660 6661 func (e *FourOctetAsSpecificExtended) String() string { 6662 buf := make([]byte, 4) 6663 binary.BigEndian.PutUint32(buf, e.AS) 6664 asUpper := binary.BigEndian.Uint16(buf[0:2]) 6665 asLower := binary.BigEndian.Uint16(buf[2:]) 6666 return fmt.Sprintf("%d.%d:%d", asUpper, asLower, e.LocalAdmin) 6667 } 6668 6669 func (e *FourOctetAsSpecificExtended) MarshalJSON() ([]byte, error) { 6670 t, s := e.GetTypes() 6671 return json.Marshal(struct { 6672 Type ExtendedCommunityAttrType `json:"type"` 6673 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 6674 Value string `json:"value"` 6675 }{ 6676 Type: t, 6677 Subtype: s, 6678 Value: e.String(), 6679 }) 6680 } 6681 6682 func (e *FourOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6683 t := EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC 6684 if !e.IsTransitive { 6685 t = EC_TYPE_NON_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC 6686 } 6687 return t, e.SubType 6688 } 6689 6690 func NewFourOctetAsSpecificExtended(subtype ExtendedCommunityAttrSubType, as uint32, localAdmin uint16, isTransitive bool) *FourOctetAsSpecificExtended { 6691 return &FourOctetAsSpecificExtended{ 6692 SubType: subtype, 6693 AS: as, 6694 LocalAdmin: localAdmin, 6695 IsTransitive: isTransitive, 6696 } 6697 } 6698 6699 func ParseExtendedCommunity(subtype ExtendedCommunityAttrSubType, com string) (ExtendedCommunityInterface, error) { 6700 if subtype == EC_SUBTYPE_ORIGIN_VALIDATION { 6701 var state ValidationState 6702 switch com { 6703 case VALIDATION_STATE_VALID.String(): 6704 state = VALIDATION_STATE_VALID 6705 case VALIDATION_STATE_NOT_FOUND.String(): 6706 state = VALIDATION_STATE_NOT_FOUND 6707 case VALIDATION_STATE_INVALID.String(): 6708 state = VALIDATION_STATE_INVALID 6709 default: 6710 return nil, fmt.Errorf("invalid validation state") 6711 } 6712 return &ValidationExtended{ 6713 State: state, 6714 }, nil 6715 } 6716 elems, err := parseRdAndRt(com) 6717 if err != nil { 6718 return nil, err 6719 } 6720 localAdmin, _ := strconv.ParseUint(elems[10], 10, 32) 6721 ip := net.ParseIP(elems[1]) 6722 isTransitive := true 6723 switch { 6724 case ip.To4() != nil: 6725 return NewIPv4AddressSpecificExtended(subtype, elems[1], uint16(localAdmin), isTransitive), nil 6726 case ip.To16() != nil: 6727 return NewIPv6AddressSpecificExtended(subtype, elems[1], uint16(localAdmin), isTransitive), nil 6728 case elems[6] == "" && elems[7] == "": 6729 asn, _ := strconv.ParseUint(elems[8], 10, 16) 6730 return NewTwoOctetAsSpecificExtended(subtype, uint16(asn), uint32(localAdmin), isTransitive), nil 6731 default: 6732 fst, _ := strconv.ParseUint(elems[7], 10, 16) 6733 snd, _ := strconv.ParseUint(elems[8], 10, 16) 6734 asn := fst<<16 | snd 6735 return NewFourOctetAsSpecificExtended(subtype, uint32(asn), uint16(localAdmin), isTransitive), nil 6736 } 6737 } 6738 6739 func ParseRouteTarget(rt string) (ExtendedCommunityInterface, error) { 6740 return ParseExtendedCommunity(EC_SUBTYPE_ROUTE_TARGET, rt) 6741 } 6742 6743 func SerializeExtendedCommunities(comms []ExtendedCommunityInterface) ([][]byte, error) { 6744 var bufs [][]byte 6745 var err error 6746 for _, c := range comms { 6747 buf, err := c.Serialize() 6748 if err != nil { 6749 return nil, err 6750 } 6751 bufs = append(bufs, buf) 6752 } 6753 return bufs, err 6754 } 6755 6756 type ValidationState uint8 6757 6758 const ( 6759 VALIDATION_STATE_VALID ValidationState = 0 6760 VALIDATION_STATE_NOT_FOUND ValidationState = 1 6761 VALIDATION_STATE_INVALID ValidationState = 2 6762 ) 6763 6764 func (s ValidationState) String() string { 6765 switch s { 6766 case VALIDATION_STATE_VALID: 6767 return "valid" 6768 case VALIDATION_STATE_NOT_FOUND: 6769 return "not-found" 6770 case VALIDATION_STATE_INVALID: 6771 return "invalid" 6772 } 6773 return fmt.Sprintf("unknown validation state(%d)", s) 6774 } 6775 6776 type ValidationExtended struct { 6777 State ValidationState 6778 } 6779 6780 func (e *ValidationExtended) Serialize() ([]byte, error) { 6781 buf := make([]byte, 8) 6782 typ, subType := e.GetTypes() 6783 buf[0] = byte(typ) 6784 buf[1] = byte(subType) 6785 buf[7] = byte(e.State) 6786 return buf, nil 6787 } 6788 6789 func (e *ValidationExtended) String() string { 6790 return e.State.String() 6791 } 6792 6793 func (e *ValidationExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6794 return EC_TYPE_NON_TRANSITIVE_OPAQUE, EC_SUBTYPE_ORIGIN_VALIDATION 6795 } 6796 6797 func (e *ValidationExtended) MarshalJSON() ([]byte, error) { 6798 t, s := e.GetTypes() 6799 return json.Marshal(struct { 6800 Type ExtendedCommunityAttrType `json:"type"` 6801 SubType ExtendedCommunityAttrSubType `json:"subtype"` 6802 State ValidationState `json:"value"` 6803 }{ 6804 Type: t, 6805 SubType: s, 6806 State: e.State, 6807 }) 6808 } 6809 6810 func NewValidationExtended(state ValidationState) *ValidationExtended { 6811 return &ValidationExtended{ 6812 State: state, 6813 } 6814 } 6815 6816 type ColorExtended struct { 6817 Color uint32 6818 } 6819 6820 func (e *ColorExtended) Serialize() ([]byte, error) { 6821 buf := make([]byte, 8) 6822 typ, subType := e.GetTypes() 6823 buf[0] = byte(typ) 6824 buf[1] = byte(subType) 6825 binary.BigEndian.PutUint32(buf[4:8], uint32(e.Color)) 6826 return buf, nil 6827 } 6828 6829 func (e *ColorExtended) String() string { 6830 return fmt.Sprintf("%d", e.Color) 6831 } 6832 6833 func (e *ColorExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6834 return EC_TYPE_TRANSITIVE_OPAQUE, EC_SUBTYPE_COLOR 6835 } 6836 6837 func (e *ColorExtended) MarshalJSON() ([]byte, error) { 6838 t, s := e.GetTypes() 6839 return json.Marshal(struct { 6840 Type ExtendedCommunityAttrType `json:"type"` 6841 SubType ExtendedCommunityAttrSubType `json:"subtype"` 6842 Color uint32 `json:"color"` 6843 }{ 6844 Type: t, 6845 SubType: s, 6846 Color: e.Color, 6847 }) 6848 } 6849 6850 func NewColorExtended(color uint32) *ColorExtended { 6851 return &ColorExtended{ 6852 Color: color, 6853 } 6854 } 6855 6856 type EncapExtended struct { 6857 TunnelType TunnelType 6858 } 6859 6860 func (e *EncapExtended) Serialize() ([]byte, error) { 6861 buf := make([]byte, 8) 6862 typ, subType := e.GetTypes() 6863 buf[0] = byte(typ) 6864 buf[1] = byte(subType) 6865 binary.BigEndian.PutUint16(buf[6:8], uint16(e.TunnelType)) 6866 return buf, nil 6867 } 6868 6869 func (e *EncapExtended) String() string { 6870 switch e.TunnelType { 6871 case TUNNEL_TYPE_L2TP3: 6872 return "L2TPv3 over IP" 6873 case TUNNEL_TYPE_GRE: 6874 return "GRE" 6875 case TUNNEL_TYPE_IP_IN_IP: 6876 return "IP in IP" 6877 case TUNNEL_TYPE_VXLAN: 6878 return "VXLAN" 6879 case TUNNEL_TYPE_NVGRE: 6880 return "NVGRE" 6881 case TUNNEL_TYPE_MPLS: 6882 return "MPLS" 6883 case TUNNEL_TYPE_MPLS_IN_GRE: 6884 return "MPLS in GRE" 6885 case TUNNEL_TYPE_VXLAN_GRE: 6886 return "VXLAN GRE" 6887 case TUNNEL_TYPE_MPLS_IN_UDP: 6888 return "MPLS in UDP" 6889 default: 6890 return fmt.Sprintf("tunnel: %d", e.TunnelType) 6891 } 6892 } 6893 6894 func (e *EncapExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6895 return EC_TYPE_TRANSITIVE_OPAQUE, EC_SUBTYPE_ENCAPSULATION 6896 } 6897 6898 func (e *EncapExtended) MarshalJSON() ([]byte, error) { 6899 t, s := e.GetTypes() 6900 return json.Marshal(struct { 6901 Type ExtendedCommunityAttrType `json:"type"` 6902 SubType ExtendedCommunityAttrSubType `json:"subtype"` 6903 TunnelType TunnelType `json:"tunnel_type"` 6904 }{ 6905 Type: t, 6906 SubType: s, 6907 TunnelType: e.TunnelType, 6908 }) 6909 } 6910 6911 func NewEncapExtended(tunnelType TunnelType) *EncapExtended { 6912 return &EncapExtended{ 6913 TunnelType: tunnelType, 6914 } 6915 } 6916 6917 type DefaultGatewayExtended struct { 6918 } 6919 6920 func (e *DefaultGatewayExtended) Serialize() ([]byte, error) { 6921 buf := make([]byte, 8) 6922 typ, subType := e.GetTypes() 6923 buf[0] = byte(typ) 6924 buf[1] = byte(subType) 6925 return buf, nil 6926 } 6927 6928 func (e *DefaultGatewayExtended) String() string { 6929 return "default-gateway" 6930 } 6931 6932 func (e *DefaultGatewayExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6933 return EC_TYPE_TRANSITIVE_OPAQUE, EC_SUBTYPE_DEFAULT_GATEWAY 6934 } 6935 6936 func (e *DefaultGatewayExtended) MarshalJSON() ([]byte, error) { 6937 t, s := e.GetTypes() 6938 return json.Marshal(struct { 6939 Type ExtendedCommunityAttrType `json:"type"` 6940 SubType ExtendedCommunityAttrSubType `json:"subtype"` 6941 }{ 6942 Type: t, 6943 SubType: s, 6944 }) 6945 } 6946 6947 func NewDefaultGatewayExtended() *DefaultGatewayExtended { 6948 return &DefaultGatewayExtended{} 6949 } 6950 6951 type OpaqueExtended struct { 6952 IsTransitive bool 6953 Value []byte 6954 } 6955 6956 func (e *OpaqueExtended) Serialize() ([]byte, error) { 6957 if len(e.Value) != 7 { 6958 return nil, fmt.Errorf("invalid value length for opaque extended community: %d", len(e.Value)) 6959 } 6960 buf := make([]byte, 8) 6961 if e.IsTransitive { 6962 buf[0] = byte(EC_TYPE_TRANSITIVE_OPAQUE) 6963 } else { 6964 buf[0] = byte(EC_TYPE_NON_TRANSITIVE_OPAQUE) 6965 } 6966 copy(buf[1:], e.Value) 6967 return buf, nil 6968 } 6969 6970 func (e *OpaqueExtended) String() string { 6971 buf := make([]byte, 8) 6972 copy(buf[1:], e.Value) 6973 return fmt.Sprintf("%d", binary.BigEndian.Uint64(buf)) 6974 } 6975 6976 func (e *OpaqueExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 6977 var subType ExtendedCommunityAttrSubType 6978 if len(e.Value) > 0 { 6979 // Use the first byte of value as the sub type 6980 subType = ExtendedCommunityAttrSubType(e.Value[0]) 6981 } 6982 if e.IsTransitive { 6983 return EC_TYPE_TRANSITIVE_OPAQUE, subType 6984 } 6985 return EC_TYPE_NON_TRANSITIVE_OPAQUE, subType 6986 } 6987 6988 func (e *OpaqueExtended) MarshalJSON() ([]byte, error) { 6989 t, s := e.GetTypes() 6990 return json.Marshal(struct { 6991 Type ExtendedCommunityAttrType `json:"type"` 6992 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 6993 Value []byte `json:"value"` 6994 }{ 6995 Type: t, 6996 Subtype: s, 6997 Value: e.Value, 6998 }) 6999 } 7000 7001 func NewOpaqueExtended(isTransitive bool, value []byte) *OpaqueExtended { 7002 v := make([]byte, 7) 7003 copy(v, value) 7004 return &OpaqueExtended{ 7005 IsTransitive: isTransitive, 7006 Value: v, 7007 } 7008 } 7009 7010 func parseOpaqueExtended(data []byte) (ExtendedCommunityInterface, error) { 7011 typ := ExtendedCommunityAttrType(data[0]) 7012 isTransitive := false 7013 switch typ { 7014 case EC_TYPE_TRANSITIVE_OPAQUE: 7015 isTransitive = true 7016 case EC_TYPE_NON_TRANSITIVE_OPAQUE: 7017 // isTransitive = false 7018 default: 7019 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("invalid opaque extended community type: %d", data[0])) 7020 } 7021 subType := ExtendedCommunityAttrSubType(data[1]) 7022 7023 if isTransitive { 7024 switch subType { 7025 case EC_SUBTYPE_COLOR: 7026 return &ColorExtended{ 7027 Color: binary.BigEndian.Uint32(data[4:8]), 7028 }, nil 7029 case EC_SUBTYPE_ENCAPSULATION: 7030 return &EncapExtended{ 7031 TunnelType: TunnelType(binary.BigEndian.Uint16(data[6:8])), 7032 }, nil 7033 case EC_SUBTYPE_DEFAULT_GATEWAY: 7034 return &DefaultGatewayExtended{}, nil 7035 } 7036 } else { 7037 switch subType { 7038 case EC_SUBTYPE_ORIGIN_VALIDATION: 7039 return &ValidationExtended{ 7040 State: ValidationState(data[7]), 7041 }, nil 7042 } 7043 } 7044 return NewOpaqueExtended(isTransitive, data[1:8]), nil 7045 } 7046 7047 type ESILabelExtended struct { 7048 Label uint32 7049 IsSingleActive bool 7050 } 7051 7052 func (e *ESILabelExtended) Serialize() ([]byte, error) { 7053 buf := make([]byte, 8) 7054 buf[0] = byte(EC_TYPE_EVPN) 7055 buf[1] = byte(EC_SUBTYPE_ESI_LABEL) 7056 if e.IsSingleActive { 7057 buf[2] = byte(1) 7058 } 7059 buf[3] = 0 7060 buf[4] = 0 7061 buf[5] = byte((e.Label >> 16) & 0xff) 7062 buf[6] = byte((e.Label >> 8) & 0xff) 7063 buf[7] = byte(e.Label & 0xff) 7064 return buf, nil 7065 } 7066 7067 func (e *ESILabelExtended) String() string { 7068 buf := bytes.NewBuffer(make([]byte, 0, 32)) 7069 buf.WriteString(fmt.Sprintf("esi-label: %d", e.Label)) 7070 if e.IsSingleActive { 7071 buf.WriteString(", single-active") 7072 } 7073 return buf.String() 7074 } 7075 7076 func (e *ESILabelExtended) MarshalJSON() ([]byte, error) { 7077 t, s := e.GetTypes() 7078 return json.Marshal(struct { 7079 Type ExtendedCommunityAttrType `json:"type"` 7080 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7081 Label uint32 `json:"label"` 7082 IsSingleActive bool `json:"is_single_active"` 7083 }{ 7084 Type: t, 7085 Subtype: s, 7086 Label: e.Label, 7087 IsSingleActive: e.IsSingleActive, 7088 }) 7089 } 7090 7091 func (e *ESILabelExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7092 return EC_TYPE_EVPN, EC_SUBTYPE_ESI_LABEL 7093 } 7094 7095 func NewESILabelExtended(label uint32, isSingleActive bool) *ESILabelExtended { 7096 return &ESILabelExtended{ 7097 Label: label, 7098 IsSingleActive: isSingleActive, 7099 } 7100 } 7101 7102 type ESImportRouteTarget struct { 7103 ESImport net.HardwareAddr 7104 } 7105 7106 func (e *ESImportRouteTarget) Serialize() ([]byte, error) { 7107 buf := make([]byte, 8) 7108 buf[0] = byte(EC_TYPE_EVPN) 7109 buf[1] = byte(EC_SUBTYPE_ES_IMPORT) 7110 copy(buf[2:], e.ESImport) 7111 return buf, nil 7112 } 7113 7114 func (e *ESImportRouteTarget) String() string { 7115 return fmt.Sprintf("es-import rt: %s", e.ESImport.String()) 7116 } 7117 7118 func (e *ESImportRouteTarget) MarshalJSON() ([]byte, error) { 7119 t, s := e.GetTypes() 7120 return json.Marshal(struct { 7121 Type ExtendedCommunityAttrType `json:"type"` 7122 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7123 Value string `json:"value"` 7124 }{ 7125 Type: t, 7126 Subtype: s, 7127 Value: e.ESImport.String(), 7128 }) 7129 } 7130 7131 func (e *ESImportRouteTarget) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7132 return EC_TYPE_EVPN, EC_SUBTYPE_ES_IMPORT 7133 } 7134 7135 func NewESImportRouteTarget(mac string) *ESImportRouteTarget { 7136 esImport, err := net.ParseMAC(mac) 7137 if err != nil { 7138 return nil 7139 } 7140 return &ESImportRouteTarget{ 7141 ESImport: esImport, 7142 } 7143 } 7144 7145 type MacMobilityExtended struct { 7146 Sequence uint32 7147 IsSticky bool 7148 } 7149 7150 func (e *MacMobilityExtended) Serialize() ([]byte, error) { 7151 buf := make([]byte, 8) 7152 buf[0] = byte(EC_TYPE_EVPN) 7153 buf[1] = byte(EC_SUBTYPE_MAC_MOBILITY) 7154 if e.IsSticky { 7155 buf[2] = byte(1) 7156 } 7157 binary.BigEndian.PutUint32(buf[4:], e.Sequence) 7158 return buf, nil 7159 } 7160 7161 func (e *MacMobilityExtended) String() string { 7162 buf := bytes.NewBuffer(make([]byte, 0, 32)) 7163 buf.WriteString(fmt.Sprintf("mac-mobility: %d", e.Sequence)) 7164 if e.IsSticky { 7165 buf.WriteString(", sticky") 7166 } 7167 return buf.String() 7168 } 7169 7170 func (e *MacMobilityExtended) MarshalJSON() ([]byte, error) { 7171 t, s := e.GetTypes() 7172 return json.Marshal(struct { 7173 Type ExtendedCommunityAttrType `json:"type"` 7174 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7175 Sequence uint32 `json:"sequence"` 7176 IsSticky bool `json:"is_sticky"` 7177 }{ 7178 Type: t, 7179 Subtype: s, 7180 Sequence: e.Sequence, 7181 IsSticky: e.IsSticky, 7182 }) 7183 } 7184 7185 func (e *MacMobilityExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7186 return EC_TYPE_EVPN, EC_SUBTYPE_MAC_MOBILITY 7187 } 7188 7189 func NewMacMobilityExtended(seq uint32, isSticky bool) *MacMobilityExtended { 7190 return &MacMobilityExtended{ 7191 Sequence: seq, 7192 IsSticky: isSticky, 7193 } 7194 } 7195 7196 type RouterMacExtended struct { 7197 Mac net.HardwareAddr 7198 } 7199 7200 func (e *RouterMacExtended) Serialize() ([]byte, error) { 7201 buf := make([]byte, 2, 8) 7202 buf[0] = byte(EC_TYPE_EVPN) 7203 buf[1] = byte(EC_SUBTYPE_ROUTER_MAC) 7204 buf = append(buf, e.Mac...) 7205 return buf, nil 7206 } 7207 7208 func (e *RouterMacExtended) String() string { 7209 return fmt.Sprintf("router's mac: %s", e.Mac.String()) 7210 } 7211 7212 func (e *RouterMacExtended) MarshalJSON() ([]byte, error) { 7213 t, s := e.GetTypes() 7214 return json.Marshal(struct { 7215 Type ExtendedCommunityAttrType `json:"type"` 7216 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7217 Mac string `json:"mac"` 7218 }{ 7219 Type: t, 7220 Subtype: s, 7221 Mac: e.Mac.String(), 7222 }) 7223 } 7224 7225 func (e *RouterMacExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7226 return EC_TYPE_EVPN, EC_SUBTYPE_ROUTER_MAC 7227 } 7228 7229 func NewRoutersMacExtended(mac string) *RouterMacExtended { 7230 hw, err := net.ParseMAC(mac) 7231 if err != nil { 7232 return nil 7233 } 7234 return &RouterMacExtended{ 7235 Mac: hw, 7236 } 7237 } 7238 7239 func parseEvpnExtended(data []byte) (ExtendedCommunityInterface, error) { 7240 if ExtendedCommunityAttrType(data[0]) != EC_TYPE_EVPN { 7241 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("ext comm type is not EC_TYPE_EVPN: %d", data[0])) 7242 } 7243 subType := ExtendedCommunityAttrSubType(data[1]) 7244 switch subType { 7245 case EC_SUBTYPE_ESI_LABEL: 7246 var isSingleActive bool 7247 if data[2] > 0 { 7248 isSingleActive = true 7249 } 7250 label := uint32(data[5])<<16 | uint32(data[6])<<8 | uint32(data[7]) 7251 return &ESILabelExtended{ 7252 IsSingleActive: isSingleActive, 7253 Label: label, 7254 }, nil 7255 case EC_SUBTYPE_ES_IMPORT: 7256 return &ESImportRouteTarget{ 7257 ESImport: net.HardwareAddr(data[2:8]), 7258 }, nil 7259 case EC_SUBTYPE_MAC_MOBILITY: 7260 var isSticky bool 7261 if data[2] > 0 { 7262 isSticky = true 7263 } 7264 seq := binary.BigEndian.Uint32(data[4:8]) 7265 return &MacMobilityExtended{ 7266 Sequence: seq, 7267 IsSticky: isSticky, 7268 }, nil 7269 case EC_SUBTYPE_ROUTER_MAC: 7270 return &RouterMacExtended{ 7271 Mac: net.HardwareAddr(data[2:8]), 7272 }, nil 7273 } 7274 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("unknown evpn subtype: %d", subType)) 7275 } 7276 7277 type TrafficRateExtended struct { 7278 AS uint16 7279 Rate float32 7280 } 7281 7282 func (e *TrafficRateExtended) Serialize() ([]byte, error) { 7283 buf := make([]byte, 8) 7284 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL) 7285 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_TRAFFIC_RATE) 7286 binary.BigEndian.PutUint16(buf[2:4], e.AS) 7287 binary.BigEndian.PutUint32(buf[4:8], math.Float32bits(e.Rate)) 7288 return buf, nil 7289 } 7290 7291 func (e *TrafficRateExtended) String() string { 7292 buf := bytes.NewBuffer(make([]byte, 0, 32)) 7293 if e.Rate == 0 { 7294 buf.WriteString("discard") 7295 } else { 7296 buf.WriteString(fmt.Sprintf("rate: %f", e.Rate)) 7297 } 7298 if e.AS != 0 { 7299 buf.WriteString(fmt.Sprintf("(as: %d)", e.AS)) 7300 } 7301 return buf.String() 7302 } 7303 7304 func (e *TrafficRateExtended) MarshalJSON() ([]byte, error) { 7305 t, s := e.GetTypes() 7306 return json.Marshal(struct { 7307 Type ExtendedCommunityAttrType `json:"type"` 7308 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7309 As uint16 `json:"as"` 7310 Rate float32 `json:"rate"` 7311 }{t, s, e.AS, e.Rate}) 7312 } 7313 7314 func (e *TrafficRateExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7315 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL, EC_SUBTYPE_FLOWSPEC_TRAFFIC_RATE 7316 } 7317 7318 func NewTrafficRateExtended(as uint16, rate float32) *TrafficRateExtended { 7319 return &TrafficRateExtended{ 7320 AS: as, 7321 Rate: rate, 7322 } 7323 } 7324 7325 type TrafficActionExtended struct { 7326 Terminal bool 7327 Sample bool 7328 } 7329 7330 func (e *TrafficActionExtended) Serialize() ([]byte, error) { 7331 buf := make([]byte, 8) 7332 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL) 7333 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_TRAFFIC_ACTION) 7334 if e.Terminal { 7335 buf[7] = 0x01 7336 } 7337 if e.Sample { 7338 buf[7] = buf[7] | 0x2 7339 } 7340 return buf, nil 7341 } 7342 7343 func (e *TrafficActionExtended) String() string { 7344 ss := make([]string, 0, 2) 7345 if e.Terminal { 7346 ss = append(ss, "terminal") 7347 } 7348 if e.Sample { 7349 ss = append(ss, "sample") 7350 } 7351 return fmt.Sprintf("action: %s", strings.Join(ss, "-")) 7352 } 7353 7354 func (e *TrafficActionExtended) MarshalJSON() ([]byte, error) { 7355 t, s := e.GetTypes() 7356 return json.Marshal(struct { 7357 Type ExtendedCommunityAttrType `json:"type"` 7358 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7359 Terminal bool `json:"terminal"` 7360 Sample bool `json:"sample"` 7361 }{t, s, e.Terminal, e.Sample}) 7362 } 7363 7364 func (e *TrafficActionExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7365 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL, EC_SUBTYPE_FLOWSPEC_TRAFFIC_ACTION 7366 } 7367 7368 func NewTrafficActionExtended(terminal bool, sample bool) *TrafficActionExtended { 7369 return &TrafficActionExtended{ 7370 Terminal: terminal, 7371 Sample: sample, 7372 } 7373 } 7374 7375 type RedirectTwoOctetAsSpecificExtended struct { 7376 TwoOctetAsSpecificExtended 7377 } 7378 7379 func (e *RedirectTwoOctetAsSpecificExtended) Serialize() ([]byte, error) { 7380 buf, err := e.TwoOctetAsSpecificExtended.Serialize() 7381 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL) 7382 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_REDIRECT) 7383 return buf, err 7384 } 7385 7386 func (e *RedirectTwoOctetAsSpecificExtended) String() string { 7387 return fmt.Sprintf("redirect: %s", e.TwoOctetAsSpecificExtended.String()) 7388 } 7389 7390 func (e *RedirectTwoOctetAsSpecificExtended) MarshalJSON() ([]byte, error) { 7391 t, s := e.GetTypes() 7392 return json.Marshal(struct { 7393 Type ExtendedCommunityAttrType `json:"type"` 7394 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7395 Value string `json:"value"` 7396 }{t, s, e.TwoOctetAsSpecificExtended.String()}) 7397 } 7398 7399 func (e *RedirectTwoOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7400 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL, EC_SUBTYPE_FLOWSPEC_REDIRECT 7401 } 7402 7403 func NewRedirectTwoOctetAsSpecificExtended(as uint16, localAdmin uint32) *RedirectTwoOctetAsSpecificExtended { 7404 return &RedirectTwoOctetAsSpecificExtended{*NewTwoOctetAsSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, as, localAdmin, false)} 7405 } 7406 7407 type RedirectIPv4AddressSpecificExtended struct { 7408 IPv4AddressSpecificExtended 7409 } 7410 7411 func (e *RedirectIPv4AddressSpecificExtended) Serialize() ([]byte, error) { 7412 buf, err := e.IPv4AddressSpecificExtended.Serialize() 7413 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2) 7414 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_REDIRECT) 7415 return buf, err 7416 } 7417 7418 func (e *RedirectIPv4AddressSpecificExtended) String() string { 7419 return fmt.Sprintf("redirect: %s", e.IPv4AddressSpecificExtended.String()) 7420 } 7421 7422 func (e *RedirectIPv4AddressSpecificExtended) MarshalJSON() ([]byte, error) { 7423 t, s := e.GetTypes() 7424 return json.Marshal(struct { 7425 Type ExtendedCommunityAttrType `json:"type"` 7426 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7427 Value string `json:"value"` 7428 }{t, s, e.IPv4AddressSpecificExtended.String()}) 7429 } 7430 7431 func (e *RedirectIPv4AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7432 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2, EC_SUBTYPE_FLOWSPEC_REDIRECT 7433 } 7434 7435 func NewRedirectIPv4AddressSpecificExtended(ipv4 string, localAdmin uint16) *RedirectIPv4AddressSpecificExtended { 7436 e := NewIPv4AddressSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, ipv4, localAdmin, false) 7437 if e == nil { 7438 return nil 7439 } 7440 return &RedirectIPv4AddressSpecificExtended{*e} 7441 } 7442 7443 type RedirectIPv6AddressSpecificExtended struct { 7444 IPv6AddressSpecificExtended 7445 } 7446 7447 func (e *RedirectIPv6AddressSpecificExtended) Serialize() ([]byte, error) { 7448 buf, err := e.IPv6AddressSpecificExtended.Serialize() 7449 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL) 7450 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_REDIRECT_IP6) 7451 return buf, err 7452 } 7453 7454 func (e *RedirectIPv6AddressSpecificExtended) String() string { 7455 return fmt.Sprintf("redirect: %s", e.IPv6AddressSpecificExtended.String()) 7456 } 7457 7458 func (e *RedirectIPv6AddressSpecificExtended) MarshalJSON() ([]byte, error) { 7459 t, s := e.GetTypes() 7460 return json.Marshal(struct { 7461 Type ExtendedCommunityAttrType `json:"type"` 7462 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7463 Value string `json:"value"` 7464 }{t, s, e.IPv6AddressSpecificExtended.String()}) 7465 } 7466 7467 func (e *RedirectIPv6AddressSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7468 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL, EC_SUBTYPE_FLOWSPEC_REDIRECT_IP6 7469 } 7470 7471 func NewRedirectIPv6AddressSpecificExtended(ipv6 string, localAdmin uint16) *RedirectIPv6AddressSpecificExtended { 7472 e := NewIPv6AddressSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, ipv6, localAdmin, false) 7473 if e == nil { 7474 return nil 7475 } 7476 return &RedirectIPv6AddressSpecificExtended{*e} 7477 } 7478 7479 type RedirectFourOctetAsSpecificExtended struct { 7480 FourOctetAsSpecificExtended 7481 } 7482 7483 func (e *RedirectFourOctetAsSpecificExtended) Serialize() ([]byte, error) { 7484 buf, err := e.FourOctetAsSpecificExtended.Serialize() 7485 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3) 7486 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_REDIRECT) 7487 return buf, err 7488 } 7489 7490 func (e *RedirectFourOctetAsSpecificExtended) String() string { 7491 return fmt.Sprintf("redirect: %s", e.FourOctetAsSpecificExtended.String()) 7492 } 7493 7494 func (e *RedirectFourOctetAsSpecificExtended) MarshalJSON() ([]byte, error) { 7495 t, s := e.GetTypes() 7496 return json.Marshal(struct { 7497 Type ExtendedCommunityAttrType `json:"type"` 7498 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7499 Value string `json:"value"` 7500 }{t, s, e.FourOctetAsSpecificExtended.String()}) 7501 } 7502 7503 func (e *RedirectFourOctetAsSpecificExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7504 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3, EC_SUBTYPE_FLOWSPEC_REDIRECT 7505 } 7506 7507 func NewRedirectFourOctetAsSpecificExtended(as uint32, localAdmin uint16) *RedirectFourOctetAsSpecificExtended { 7508 return &RedirectFourOctetAsSpecificExtended{*NewFourOctetAsSpecificExtended(EC_SUBTYPE_ROUTE_TARGET, as, localAdmin, false)} 7509 } 7510 7511 type TrafficRemarkExtended struct { 7512 DSCP uint8 7513 } 7514 7515 func (e *TrafficRemarkExtended) Serialize() ([]byte, error) { 7516 buf := make([]byte, 8) 7517 buf[0] = byte(EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL) 7518 buf[1] = byte(EC_SUBTYPE_FLOWSPEC_TRAFFIC_REMARK) 7519 buf[7] = byte(e.DSCP) 7520 return buf, nil 7521 } 7522 7523 func (e *TrafficRemarkExtended) String() string { 7524 return fmt.Sprintf("remark: %d", e.DSCP) 7525 } 7526 7527 func (e *TrafficRemarkExtended) MarshalJSON() ([]byte, error) { 7528 t, s := e.GetTypes() 7529 return json.Marshal(struct { 7530 Type ExtendedCommunityAttrType `json:"type"` 7531 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7532 Value uint8 `json:"value"` 7533 }{t, s, e.DSCP}) 7534 } 7535 7536 func (e *TrafficRemarkExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7537 return EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL, EC_SUBTYPE_FLOWSPEC_TRAFFIC_REMARK 7538 } 7539 7540 func NewTrafficRemarkExtended(dscp uint8) *TrafficRemarkExtended { 7541 return &TrafficRemarkExtended{ 7542 DSCP: dscp, 7543 } 7544 } 7545 7546 func parseFlowSpecExtended(data []byte) (ExtendedCommunityInterface, error) { 7547 typ := ExtendedCommunityAttrType(data[0]) 7548 if typ != EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL && typ != EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2 && typ != EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3 { 7549 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("ext comm type is not EC_TYPE_FLOWSPEC: %d", data[0])) 7550 } 7551 subType := ExtendedCommunityAttrSubType(data[1]) 7552 switch subType { 7553 case EC_SUBTYPE_FLOWSPEC_TRAFFIC_RATE: 7554 asn := binary.BigEndian.Uint16(data[2:4]) 7555 bits := binary.BigEndian.Uint32(data[4:8]) 7556 rate := math.Float32frombits(bits) 7557 return NewTrafficRateExtended(asn, rate), nil 7558 case EC_SUBTYPE_FLOWSPEC_TRAFFIC_ACTION: 7559 terminal := data[7]&0x1 == 1 7560 sample := (data[7]>>1)&0x1 == 1 7561 return NewTrafficActionExtended(terminal, sample), nil 7562 case EC_SUBTYPE_FLOWSPEC_REDIRECT: 7563 // RFC7674 7564 switch typ { 7565 case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL: 7566 as := binary.BigEndian.Uint16(data[2:4]) 7567 localAdmin := binary.BigEndian.Uint32(data[4:8]) 7568 return NewRedirectTwoOctetAsSpecificExtended(as, localAdmin), nil 7569 case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2: 7570 ipv4 := net.IP(data[2:6]).String() 7571 localAdmin := binary.BigEndian.Uint16(data[6:8]) 7572 return NewRedirectIPv4AddressSpecificExtended(ipv4, localAdmin), nil 7573 case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3: 7574 as := binary.BigEndian.Uint32(data[2:6]) 7575 localAdmin := binary.BigEndian.Uint16(data[6:8]) 7576 return NewRedirectFourOctetAsSpecificExtended(as, localAdmin), nil 7577 } 7578 case EC_SUBTYPE_FLOWSPEC_TRAFFIC_REMARK: 7579 dscp := data[7] 7580 return NewTrafficRemarkExtended(dscp), nil 7581 case EC_SUBTYPE_FLOWSPEC_REDIRECT_IP6: 7582 ipv6 := net.IP(data[2:18]).String() 7583 localAdmin := binary.BigEndian.Uint16(data[18:20]) 7584 return NewRedirectIPv6AddressSpecificExtended(ipv6, localAdmin), nil 7585 } 7586 return &UnknownExtended{ 7587 Type: ExtendedCommunityAttrType(data[0]), 7588 Value: data[1:8], 7589 }, nil 7590 } 7591 7592 func parseIP6FlowSpecExtended(data []byte) (ExtendedCommunityInterface, error) { 7593 typ := ExtendedCommunityAttrType(data[0]) 7594 if typ != EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL && typ != EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2 && typ != EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3 { 7595 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("ext comm type is not EC_TYPE_FLOWSPEC: %d", data[0])) 7596 } 7597 subType := ExtendedCommunityAttrSubType(data[1]) 7598 switch subType { 7599 case EC_SUBTYPE_FLOWSPEC_REDIRECT_IP6: 7600 // RFC7674 7601 switch typ { 7602 case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL: 7603 ipv6 := net.IP(data[2:18]).String() 7604 localAdmin := binary.BigEndian.Uint16(data[18:20]) 7605 return NewRedirectIPv6AddressSpecificExtended(ipv6, localAdmin), nil 7606 } 7607 } 7608 return &UnknownExtended{ 7609 Type: ExtendedCommunityAttrType(data[0]), 7610 Value: data[1:20], 7611 }, nil 7612 } 7613 7614 type UnknownExtended struct { 7615 Type ExtendedCommunityAttrType 7616 Value []byte 7617 } 7618 7619 func (e *UnknownExtended) Serialize() ([]byte, error) { 7620 if len(e.Value) != 7 { 7621 return nil, fmt.Errorf("invalid value length for unknown extended community: %d", len(e.Value)) 7622 } 7623 buf := make([]byte, 8) 7624 buf[0] = uint8(e.Type) 7625 copy(buf[1:], e.Value) 7626 return buf, nil 7627 } 7628 7629 func (e *UnknownExtended) String() string { 7630 buf := make([]byte, 8) 7631 copy(buf[1:], e.Value) 7632 return fmt.Sprintf("%d", binary.BigEndian.Uint64(buf)) 7633 } 7634 7635 func (e *UnknownExtended) MarshalJSON() ([]byte, error) { 7636 t, s := e.GetTypes() 7637 return json.Marshal(struct { 7638 Type ExtendedCommunityAttrType `json:"type"` 7639 Subtype ExtendedCommunityAttrSubType `json:"subtype"` 7640 Value []byte `json:"value"` 7641 }{ 7642 Type: t, 7643 Subtype: s, 7644 Value: e.Value, 7645 }) 7646 } 7647 7648 func (e *UnknownExtended) GetTypes() (ExtendedCommunityAttrType, ExtendedCommunityAttrSubType) { 7649 var subType ExtendedCommunityAttrSubType 7650 if len(e.Value) > 0 { 7651 // Use the first byte of value as the sub type 7652 subType = ExtendedCommunityAttrSubType(e.Value[0]) 7653 } 7654 return e.Type, subType 7655 } 7656 7657 func NewUnknownExtended(typ ExtendedCommunityAttrType, value []byte) *UnknownExtended { 7658 v := make([]byte, 7) 7659 copy(v, value) 7660 return &UnknownExtended{ 7661 Type: typ, 7662 Value: v, 7663 } 7664 } 7665 7666 type PathAttributeExtendedCommunities struct { 7667 PathAttribute 7668 Value []ExtendedCommunityInterface 7669 } 7670 7671 func ParseExtended(data []byte) (ExtendedCommunityInterface, error) { 7672 if len(data) < 8 { 7673 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all extended community bytes are available") 7674 } 7675 attrType := ExtendedCommunityAttrType(data[0]) 7676 subtype := ExtendedCommunityAttrSubType(data[1]) 7677 transitive := false 7678 switch attrType { 7679 case EC_TYPE_TRANSITIVE_TWO_OCTET_AS_SPECIFIC: 7680 transitive = true 7681 fallthrough 7682 case EC_TYPE_NON_TRANSITIVE_TWO_OCTET_AS_SPECIFIC: 7683 as := binary.BigEndian.Uint16(data[2:4]) 7684 localAdmin := binary.BigEndian.Uint32(data[4:8]) 7685 return NewTwoOctetAsSpecificExtended(subtype, as, localAdmin, transitive), nil 7686 case EC_TYPE_TRANSITIVE_IP4_SPECIFIC: 7687 transitive = true 7688 fallthrough 7689 case EC_TYPE_NON_TRANSITIVE_IP4_SPECIFIC: 7690 ipv4 := net.IP(data[2:6]).String() 7691 localAdmin := binary.BigEndian.Uint16(data[6:8]) 7692 return NewIPv4AddressSpecificExtended(subtype, ipv4, localAdmin, transitive), nil 7693 case EC_TYPE_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC: 7694 transitive = true 7695 fallthrough 7696 case EC_TYPE_NON_TRANSITIVE_FOUR_OCTET_AS_SPECIFIC: 7697 as := binary.BigEndian.Uint32(data[2:6]) 7698 localAdmin := binary.BigEndian.Uint16(data[6:8]) 7699 return NewFourOctetAsSpecificExtended(subtype, as, localAdmin, transitive), nil 7700 case EC_TYPE_TRANSITIVE_OPAQUE: 7701 transitive = true 7702 fallthrough 7703 case EC_TYPE_NON_TRANSITIVE_OPAQUE: 7704 return parseOpaqueExtended(data) 7705 case EC_TYPE_EVPN: 7706 return parseEvpnExtended(data) 7707 case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL, EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL2, EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL3: 7708 return parseFlowSpecExtended(data) 7709 default: 7710 return &UnknownExtended{ 7711 Type: ExtendedCommunityAttrType(data[0]), 7712 Value: data[1:8], 7713 }, nil 7714 } 7715 } 7716 7717 func (p *PathAttributeExtendedCommunities) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 7718 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 7719 if err != nil { 7720 return err 7721 } 7722 if p.Length%8 != 0 { 7723 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 7724 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 7725 return NewMessageError(eCode, eSubCode, nil, "extendedcommunities length isn't correct") 7726 } 7727 for len(value) >= 8 { 7728 e, err := ParseExtended(value) 7729 if err != nil { 7730 return err 7731 } 7732 p.Value = append(p.Value, e) 7733 value = value[8:] 7734 } 7735 return nil 7736 } 7737 7738 func (p *PathAttributeExtendedCommunities) Serialize(options ...*MarshallingOption) ([]byte, error) { 7739 buf := make([]byte, 0) 7740 for _, p := range p.Value { 7741 ebuf, err := p.Serialize() 7742 if err != nil { 7743 return nil, err 7744 } 7745 buf = append(buf, ebuf...) 7746 } 7747 return p.PathAttribute.Serialize(buf, options...) 7748 } 7749 7750 func (p *PathAttributeExtendedCommunities) String() string { 7751 buf := bytes.NewBuffer(make([]byte, 0, 32)) 7752 for idx, v := range p.Value { 7753 buf.WriteString("[") 7754 buf.WriteString(v.String()) 7755 buf.WriteString("]") 7756 if idx < len(p.Value)-1 { 7757 buf.WriteString(", ") 7758 } 7759 } 7760 return fmt.Sprintf("{Extcomms: %s}", buf.String()) 7761 } 7762 7763 func (p *PathAttributeExtendedCommunities) MarshalJSON() ([]byte, error) { 7764 return json.Marshal(struct { 7765 Type BGPAttrType `json:"type"` 7766 Value []ExtendedCommunityInterface `json:"value"` 7767 }{ 7768 Type: p.GetType(), 7769 Value: p.Value, 7770 }) 7771 } 7772 7773 func NewPathAttributeExtendedCommunities(value []ExtendedCommunityInterface) *PathAttributeExtendedCommunities { 7774 l := len(value) * 8 7775 t := BGP_ATTR_TYPE_EXTENDED_COMMUNITIES 7776 return &PathAttributeExtendedCommunities{ 7777 PathAttribute: PathAttribute{ 7778 Flags: getPathAttrFlags(t, l), 7779 Type: t, 7780 Length: uint16(l), 7781 }, 7782 Value: value, 7783 } 7784 } 7785 7786 type PathAttributeAs4Path struct { 7787 PathAttribute 7788 Value []*As4PathParam 7789 } 7790 7791 func (p *PathAttributeAs4Path) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 7792 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 7793 if err != nil { 7794 return err 7795 } 7796 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 7797 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 7798 isAs4, err := validateAsPathValueBytes(value) 7799 if err != nil { 7800 return err 7801 } 7802 7803 if !isAs4 { 7804 return NewMessageError(eCode, eSubCode, nil, "AS4 PATH param is malformed") 7805 } 7806 7807 for len(value) > 0 { 7808 tuple := &As4PathParam{} 7809 tuple.DecodeFromBytes(value) 7810 p.Value = append(p.Value, tuple) 7811 if len(value) < tuple.Len() { 7812 return NewMessageError(eCode, eSubCode, nil, "AS4 PATH param is malformed") 7813 } 7814 value = value[tuple.Len():] 7815 } 7816 return nil 7817 } 7818 7819 func (p *PathAttributeAs4Path) Serialize(options ...*MarshallingOption) ([]byte, error) { 7820 buf := make([]byte, 0) 7821 for _, v := range p.Value { 7822 vbuf, err := v.Serialize() 7823 if err != nil { 7824 return nil, err 7825 } 7826 buf = append(buf, vbuf...) 7827 } 7828 return p.PathAttribute.Serialize(buf, options...) 7829 } 7830 7831 func (p *PathAttributeAs4Path) String() string { 7832 params := make([]string, 0, len(p.Value)) 7833 for _, param := range p.Value { 7834 params = append(params, param.String()) 7835 } 7836 return strings.Join(params, " ") 7837 } 7838 7839 func (p *PathAttributeAs4Path) MarshalJSON() ([]byte, error) { 7840 return json.Marshal(struct { 7841 Type BGPAttrType `json:"type"` 7842 Value []*As4PathParam `json:"as_paths"` 7843 }{ 7844 Type: p.GetType(), 7845 Value: p.Value, 7846 }) 7847 } 7848 7849 func NewPathAttributeAs4Path(value []*As4PathParam) *PathAttributeAs4Path { 7850 var l int 7851 for _, v := range value { 7852 l += v.Len() 7853 } 7854 t := BGP_ATTR_TYPE_AS4_PATH 7855 return &PathAttributeAs4Path{ 7856 PathAttribute: PathAttribute{ 7857 Flags: getPathAttrFlags(t, l), 7858 Type: t, 7859 Length: uint16(l), 7860 }, 7861 Value: value, 7862 } 7863 } 7864 7865 type PathAttributeAs4Aggregator struct { 7866 PathAttribute 7867 Value PathAttributeAggregatorParam 7868 } 7869 7870 func (p *PathAttributeAs4Aggregator) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 7871 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 7872 if err != nil { 7873 return err 7874 } 7875 if p.Length != 8 { 7876 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 7877 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 7878 return NewMessageError(eCode, eSubCode, nil, "AS4 Aggregator length is incorrect") 7879 } 7880 p.Value.AS = binary.BigEndian.Uint32(value[0:4]) 7881 p.Value.Address = value[4:] 7882 return nil 7883 } 7884 7885 func (p *PathAttributeAs4Aggregator) Serialize(options ...*MarshallingOption) ([]byte, error) { 7886 buf := make([]byte, 8) 7887 binary.BigEndian.PutUint32(buf[0:], p.Value.AS) 7888 copy(buf[4:], p.Value.Address.To4()) 7889 return p.PathAttribute.Serialize(buf, options...) 7890 } 7891 7892 func (p *PathAttributeAs4Aggregator) String() string { 7893 return fmt.Sprintf("{As4Aggregator: {AS: %d, Address: %s}}", p.Value.AS, p.Value.Address) 7894 } 7895 7896 func (p *PathAttributeAs4Aggregator) MarshalJSON() ([]byte, error) { 7897 return json.Marshal(struct { 7898 Type BGPAttrType `json:"type"` 7899 AS uint32 `json:"as"` 7900 Address string `json:"address"` 7901 }{ 7902 Type: p.GetType(), 7903 AS: p.Value.AS, 7904 Address: p.Value.Address.String(), 7905 }) 7906 } 7907 7908 func NewPathAttributeAs4Aggregator(as uint32, address string) *PathAttributeAs4Aggregator { 7909 t := BGP_ATTR_TYPE_AS4_AGGREGATOR 7910 return &PathAttributeAs4Aggregator{ 7911 PathAttribute: PathAttribute{ 7912 Flags: PathAttrFlags[t], 7913 Type: t, 7914 Length: 8, 7915 }, 7916 Value: PathAttributeAggregatorParam{ 7917 AS: as, 7918 Address: net.ParseIP(address).To4(), 7919 }, 7920 } 7921 } 7922 7923 type TunnelEncapSubTLVInterface interface { 7924 Len() int 7925 DecodeFromBytes([]byte) error 7926 Serialize() ([]byte, error) 7927 String() string 7928 MarshalJSON() ([]byte, error) 7929 } 7930 7931 type TunnelEncapSubTLV struct { 7932 Type EncapSubTLVType 7933 Length uint16 7934 } 7935 7936 func (t *TunnelEncapSubTLV) Len() int { 7937 if t.Type >= 0x80 { 7938 return 3 + int(t.Length) 7939 } 7940 return 2 + int(t.Length) 7941 } 7942 7943 func (t *TunnelEncapSubTLV) DecodeFromBytes(data []byte) (value []byte, err error) { 7944 t.Type = EncapSubTLVType(data[0]) 7945 if t.Type >= 0x80 { 7946 t.Length = binary.BigEndian.Uint16(data[1:3]) 7947 data = data[3:] 7948 } else { 7949 t.Length = uint16(data[1]) 7950 data = data[2:] 7951 } 7952 if len(data) < int(t.Length) { 7953 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLV bytes available") 7954 } 7955 return data, nil 7956 } 7957 7958 func (t *TunnelEncapSubTLV) Serialize(value []byte) (buf []byte, err error) { 7959 t.Length = uint16(len(value)) 7960 if t.Type >= 0x80 { 7961 buf = append(make([]byte, 3), value...) 7962 binary.BigEndian.PutUint16(buf[1:3], t.Length) 7963 } else { 7964 buf = append(make([]byte, 2), value...) 7965 buf[1] = uint8(t.Length) 7966 } 7967 buf[0] = uint8(t.Type) 7968 return buf, nil 7969 } 7970 7971 type TunnelEncapSubTLVUnknown struct { 7972 TunnelEncapSubTLV 7973 Value []byte 7974 } 7975 7976 func (t *TunnelEncapSubTLVUnknown) DecodeFromBytes(data []byte) error { 7977 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 7978 if err != nil { 7979 return err 7980 } 7981 t.Value = value 7982 return nil 7983 } 7984 7985 func (t *TunnelEncapSubTLVUnknown) Serialize() ([]byte, error) { 7986 return t.TunnelEncapSubTLV.Serialize(t.Value) 7987 } 7988 7989 func (t *TunnelEncapSubTLVUnknown) String() string { 7990 return fmt.Sprintf("{Type: %d, Value: %x}", t.Type, t.Value) 7991 } 7992 7993 func (t *TunnelEncapSubTLVUnknown) MarshalJSON() ([]byte, error) { 7994 return json.Marshal(struct { 7995 Type EncapSubTLVType `json:"type"` 7996 Value []byte `json:"value"` 7997 }{ 7998 Type: t.Type, 7999 Value: t.Value, 8000 }) 8001 } 8002 8003 func NewTunnelEncapSubTLVUnknown(typ EncapSubTLVType, value []byte) *TunnelEncapSubTLVUnknown { 8004 return &TunnelEncapSubTLVUnknown{ 8005 TunnelEncapSubTLV: TunnelEncapSubTLV{ 8006 Type: typ, 8007 }, 8008 Value: value, 8009 } 8010 } 8011 8012 type TunnelEncapSubTLVEncapsulation struct { 8013 TunnelEncapSubTLV 8014 Key uint32 // this represent both SessionID for L2TPv3 case and GRE-key for GRE case (RFC5512 4.) 8015 Cookie []byte 8016 } 8017 8018 func (t *TunnelEncapSubTLVEncapsulation) DecodeFromBytes(data []byte) error { 8019 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 8020 if err != nil { 8021 return err 8022 } 8023 if t.Length < 4 { 8024 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLVEncapsulation bytes available") 8025 } 8026 t.Key = binary.BigEndian.Uint32(value[0:4]) 8027 t.Cookie = value[4:] 8028 return nil 8029 } 8030 8031 func (t *TunnelEncapSubTLVEncapsulation) Serialize() ([]byte, error) { 8032 buf := make([]byte, 4) 8033 binary.BigEndian.PutUint32(buf, t.Key) 8034 buf = append(buf, t.Cookie...) 8035 return t.TunnelEncapSubTLV.Serialize(buf) 8036 } 8037 8038 func (t *TunnelEncapSubTLVEncapsulation) String() string { 8039 return fmt.Sprintf("{Key: %d, Cookie: %x}", t.Key, t.Cookie) 8040 } 8041 8042 func (t *TunnelEncapSubTLVEncapsulation) MarshalJSON() ([]byte, error) { 8043 return json.Marshal(struct { 8044 Type EncapSubTLVType `json:"type"` 8045 Key uint32 `json:"key"` 8046 Cookie []byte `json:"cookie"` 8047 }{ 8048 Type: t.Type, 8049 Key: t.Key, 8050 Cookie: t.Cookie, 8051 }) 8052 } 8053 8054 func NewTunnelEncapSubTLVEncapsulation(key uint32, cookie []byte) *TunnelEncapSubTLVEncapsulation { 8055 return &TunnelEncapSubTLVEncapsulation{ 8056 TunnelEncapSubTLV: TunnelEncapSubTLV{ 8057 Type: ENCAP_SUBTLV_TYPE_ENCAPSULATION, 8058 }, 8059 Key: key, 8060 Cookie: cookie, 8061 } 8062 } 8063 8064 type TunnelEncapSubTLVProtocol struct { 8065 TunnelEncapSubTLV 8066 Protocol uint16 8067 } 8068 8069 func (t *TunnelEncapSubTLVProtocol) DecodeFromBytes(data []byte) error { 8070 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 8071 if err != nil { 8072 return err 8073 } 8074 if t.Length < 2 { 8075 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Not all TunnelEncapSubTLVProtocol bytes available") 8076 } 8077 t.Protocol = binary.BigEndian.Uint16(value[0:2]) 8078 return nil 8079 } 8080 8081 func (t *TunnelEncapSubTLVProtocol) Serialize() ([]byte, error) { 8082 buf := make([]byte, 2) 8083 binary.BigEndian.PutUint16(buf, t.Protocol) 8084 return t.TunnelEncapSubTLV.Serialize(buf) 8085 } 8086 8087 func (t *TunnelEncapSubTLVProtocol) String() string { 8088 return fmt.Sprintf("{Protocol: %d}", t.Protocol) 8089 } 8090 8091 func (t *TunnelEncapSubTLVProtocol) MarshalJSON() ([]byte, error) { 8092 return json.Marshal(struct { 8093 Type EncapSubTLVType `json:"type"` 8094 Protocol uint16 `json:"protocol"` 8095 }{ 8096 Type: t.Type, 8097 Protocol: t.Protocol, 8098 }) 8099 } 8100 8101 func NewTunnelEncapSubTLVProtocol(protocol uint16) *TunnelEncapSubTLVProtocol { 8102 return &TunnelEncapSubTLVProtocol{ 8103 TunnelEncapSubTLV: TunnelEncapSubTLV{ 8104 Type: ENCAP_SUBTLV_TYPE_PROTOCOL, 8105 }, 8106 Protocol: protocol, 8107 } 8108 } 8109 8110 type TunnelEncapSubTLVColor struct { 8111 TunnelEncapSubTLV 8112 Color uint32 8113 } 8114 8115 func (t *TunnelEncapSubTLVColor) DecodeFromBytes(data []byte) error { 8116 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 8117 if err != nil { 8118 return err 8119 } 8120 if t.Length != 8 { 8121 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Invalid TunnelEncapSubTLVColor length") 8122 } 8123 t.Color = binary.BigEndian.Uint32(value[4:8]) 8124 return nil 8125 } 8126 8127 func (t *TunnelEncapSubTLVColor) Serialize() ([]byte, error) { 8128 buf := make([]byte, 8) 8129 buf[0] = byte(EC_TYPE_TRANSITIVE_OPAQUE) 8130 buf[1] = byte(EC_SUBTYPE_COLOR) 8131 binary.BigEndian.PutUint32(buf[4:8], t.Color) 8132 return t.TunnelEncapSubTLV.Serialize(buf) 8133 } 8134 8135 func (t *TunnelEncapSubTLVColor) String() string { 8136 return fmt.Sprintf("{Color: %d}", t.Color) 8137 } 8138 8139 func (t *TunnelEncapSubTLVColor) MarshalJSON() ([]byte, error) { 8140 return json.Marshal(struct { 8141 Type EncapSubTLVType `json:"type"` 8142 Color uint32 `json:"color"` 8143 }{ 8144 Type: t.Type, 8145 Color: t.Color, 8146 }) 8147 } 8148 8149 func NewTunnelEncapSubTLVColor(color uint32) *TunnelEncapSubTLVColor { 8150 return &TunnelEncapSubTLVColor{ 8151 TunnelEncapSubTLV: TunnelEncapSubTLV{ 8152 Type: ENCAP_SUBTLV_TYPE_COLOR, 8153 }, 8154 Color: color, 8155 } 8156 } 8157 8158 type TunnelEncapTLV struct { 8159 Type TunnelType 8160 Length uint16 8161 Value []TunnelEncapSubTLVInterface 8162 } 8163 8164 func (t *TunnelEncapTLV) Len() int { 8165 var l int 8166 for _, v := range t.Value { 8167 l += v.Len() 8168 } 8169 return 4 + l // Type(2) + Length(2) + Value(variable) 8170 } 8171 8172 func (t *TunnelEncapTLV) DecodeFromBytes(data []byte) error { 8173 t.Type = TunnelType(binary.BigEndian.Uint16(data[0:2])) 8174 t.Length = binary.BigEndian.Uint16(data[2:4]) 8175 data = data[4:] 8176 if len(data) < int(t.Length) { 8177 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, fmt.Sprintf("Not all TunnelEncapTLV bytes available")) 8178 } 8179 value := data[:t.Length] 8180 for len(value) > 2 { 8181 subType := EncapSubTLVType(value[0]) 8182 var subTlv TunnelEncapSubTLVInterface 8183 switch subType { 8184 case ENCAP_SUBTLV_TYPE_ENCAPSULATION: 8185 subTlv = &TunnelEncapSubTLVEncapsulation{} 8186 case ENCAP_SUBTLV_TYPE_PROTOCOL: 8187 subTlv = &TunnelEncapSubTLVProtocol{} 8188 case ENCAP_SUBTLV_TYPE_COLOR: 8189 subTlv = &TunnelEncapSubTLVColor{} 8190 default: 8191 subTlv = &TunnelEncapSubTLVUnknown{ 8192 TunnelEncapSubTLV: TunnelEncapSubTLV{ 8193 Type: subType, 8194 }, 8195 } 8196 } 8197 err := subTlv.DecodeFromBytes(value) 8198 if err != nil { 8199 return err 8200 } 8201 t.Value = append(t.Value, subTlv) 8202 value = value[subTlv.Len():] 8203 } 8204 return nil 8205 } 8206 8207 func (p *TunnelEncapTLV) Serialize() ([]byte, error) { 8208 buf := make([]byte, 4) 8209 for _, t := range p.Value { 8210 tBuf, err := t.Serialize() 8211 if err != nil { 8212 return nil, err 8213 } 8214 buf = append(buf, tBuf...) 8215 } 8216 binary.BigEndian.PutUint16(buf, uint16(p.Type)) 8217 binary.BigEndian.PutUint16(buf[2:], uint16(len(buf)-4)) 8218 return buf, nil 8219 } 8220 8221 func (p *TunnelEncapTLV) String() string { 8222 tlvList := make([]string, len(p.Value)) 8223 for i, v := range p.Value { 8224 tlvList[i] = v.String() 8225 } 8226 return fmt.Sprintf("{%s: %s}", p.Type, strings.Join(tlvList, ", ")) 8227 } 8228 8229 func (p *TunnelEncapTLV) MarshalJSON() ([]byte, error) { 8230 return json.Marshal(struct { 8231 Type TunnelType `json:"type"` 8232 Value []TunnelEncapSubTLVInterface `json:"value"` 8233 }{ 8234 Type: p.Type, 8235 Value: p.Value, 8236 }) 8237 } 8238 8239 func NewTunnelEncapTLV(typ TunnelType, value []TunnelEncapSubTLVInterface) *TunnelEncapTLV { 8240 return &TunnelEncapTLV{ 8241 Type: typ, 8242 Value: value, 8243 } 8244 } 8245 8246 type PathAttributeTunnelEncap struct { 8247 PathAttribute 8248 Value []*TunnelEncapTLV 8249 } 8250 8251 func (p *PathAttributeTunnelEncap) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 8252 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 8253 if err != nil { 8254 return err 8255 } 8256 for len(value) > 4 { 8257 tlv := &TunnelEncapTLV{} 8258 err = tlv.DecodeFromBytes(value) 8259 if err != nil { 8260 return err 8261 } 8262 p.Value = append(p.Value, tlv) 8263 value = value[4+tlv.Length:] 8264 } 8265 return nil 8266 } 8267 8268 func (p *PathAttributeTunnelEncap) Serialize(options ...*MarshallingOption) ([]byte, error) { 8269 buf := make([]byte, 0) 8270 for _, t := range p.Value { 8271 bbuf, err := t.Serialize() 8272 if err != nil { 8273 return nil, err 8274 } 8275 buf = append(buf, bbuf...) 8276 } 8277 return p.PathAttribute.Serialize(buf, options...) 8278 } 8279 8280 func (p *PathAttributeTunnelEncap) String() string { 8281 tlvList := make([]string, len(p.Value)) 8282 for i, v := range p.Value { 8283 tlvList[i] = v.String() 8284 } 8285 return fmt.Sprintf("{TunnelEncap: %s}", strings.Join(tlvList, ", ")) 8286 } 8287 8288 func (p *PathAttributeTunnelEncap) MarshalJSON() ([]byte, error) { 8289 return json.Marshal(struct { 8290 Type BGPAttrType `json:"type"` 8291 Value []*TunnelEncapTLV `json:"value"` 8292 }{ 8293 Type: p.Type, 8294 Value: p.Value, 8295 }) 8296 } 8297 8298 func NewPathAttributeTunnelEncap(value []*TunnelEncapTLV) *PathAttributeTunnelEncap { 8299 var l int 8300 for _, v := range value { 8301 l += v.Len() 8302 } 8303 t := BGP_ATTR_TYPE_TUNNEL_ENCAP 8304 return &PathAttributeTunnelEncap{ 8305 PathAttribute: PathAttribute{ 8306 Flags: getPathAttrFlags(t, l), 8307 Type: t, 8308 Length: uint16(l), 8309 }, 8310 Value: value, 8311 } 8312 } 8313 8314 type PmsiTunnelIDInterface interface { 8315 Len() int 8316 Serialize() ([]byte, error) 8317 String() string 8318 } 8319 8320 type DefaultPmsiTunnelID struct { 8321 Value []byte 8322 } 8323 8324 func (i *DefaultPmsiTunnelID) Len() int { 8325 return len(i.Value) 8326 } 8327 8328 func (i *DefaultPmsiTunnelID) Serialize() ([]byte, error) { 8329 return i.Value, nil 8330 } 8331 8332 func (i *DefaultPmsiTunnelID) String() string { 8333 return string(i.Value) 8334 } 8335 8336 func NewDefaultPmsiTunnelID(value []byte) *DefaultPmsiTunnelID { 8337 return &DefaultPmsiTunnelID{ 8338 Value: value, 8339 } 8340 } 8341 8342 type IngressReplTunnelID struct { 8343 Value net.IP 8344 } 8345 8346 func (i *IngressReplTunnelID) Len() int { 8347 return len(i.Value) 8348 } 8349 8350 func (i *IngressReplTunnelID) Serialize() ([]byte, error) { 8351 if i.Value.To4() != nil { 8352 return []byte(i.Value.To4()), nil 8353 } 8354 return []byte(i.Value), nil 8355 } 8356 8357 func (i *IngressReplTunnelID) String() string { 8358 return i.Value.String() 8359 } 8360 8361 func NewIngressReplTunnelID(value string) *IngressReplTunnelID { 8362 ip := net.ParseIP(value) 8363 if ip == nil { 8364 return nil 8365 } 8366 return &IngressReplTunnelID{ 8367 Value: ip, 8368 } 8369 } 8370 8371 type PathAttributePmsiTunnel struct { 8372 PathAttribute 8373 IsLeafInfoRequired bool 8374 TunnelType PmsiTunnelType 8375 Label uint32 8376 TunnelID PmsiTunnelIDInterface 8377 } 8378 8379 func (p *PathAttributePmsiTunnel) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 8380 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 8381 if err != nil { 8382 return err 8383 } 8384 if p.Length < 5 { 8385 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 8386 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 8387 return NewMessageError(eCode, eSubCode, nil, "PMSI Tunnel length is incorrect") 8388 } 8389 8390 if (value[0] & 0x01) > 0 { 8391 p.IsLeafInfoRequired = true 8392 } 8393 p.TunnelType = PmsiTunnelType(value[1]) 8394 if p.Label, err = labelDecode(value[2:5]); err != nil { 8395 return err 8396 } 8397 8398 switch p.TunnelType { 8399 case PMSI_TUNNEL_TYPE_INGRESS_REPL: 8400 p.TunnelID = &IngressReplTunnelID{net.IP(value[5:])} 8401 default: 8402 p.TunnelID = &DefaultPmsiTunnelID{value[5:]} 8403 } 8404 return nil 8405 } 8406 8407 func (p *PathAttributePmsiTunnel) Serialize(options ...*MarshallingOption) ([]byte, error) { 8408 buf := make([]byte, 2) 8409 if p.IsLeafInfoRequired { 8410 buf[0] = 0x01 8411 } 8412 buf[1] = byte(p.TunnelType) 8413 tbuf, err := labelSerialize(p.Label) 8414 if err != nil { 8415 return nil, err 8416 } 8417 buf = append(buf, tbuf...) 8418 tbuf, err = p.TunnelID.Serialize() 8419 if err != nil { 8420 return nil, err 8421 } 8422 buf = append(buf, tbuf...) 8423 return p.PathAttribute.Serialize(buf, options...) 8424 } 8425 8426 func (p *PathAttributePmsiTunnel) String() string { 8427 buf := bytes.NewBuffer(make([]byte, 0, 32)) 8428 buf.WriteString(fmt.Sprintf("{Pmsi: type: %s,", p.TunnelType)) 8429 if p.IsLeafInfoRequired { 8430 buf.WriteString(" leaf-info-required,") 8431 } 8432 buf.WriteString(fmt.Sprintf(" label: %d, tunnel-id: %s}", p.Label, p.TunnelID)) 8433 return buf.String() 8434 } 8435 8436 func (p *PathAttributePmsiTunnel) MarshalJSON() ([]byte, error) { 8437 return json.Marshal(struct { 8438 Type BGPAttrType `json:"type"` 8439 IsLeafInfoRequired bool `json:"is-leaf-info-required"` 8440 TunnelType uint8 `json:"tunnel-type"` 8441 Label uint32 `json:"label"` 8442 TunnelID string `json:"tunnel-id"` 8443 }{ 8444 Type: p.Type, 8445 IsLeafInfoRequired: p.IsLeafInfoRequired, 8446 TunnelType: uint8(p.TunnelType), 8447 Label: p.Label, 8448 TunnelID: p.TunnelID.String(), 8449 }) 8450 } 8451 8452 func NewPathAttributePmsiTunnel(typ PmsiTunnelType, isLeafInfoRequired bool, label uint32, id PmsiTunnelIDInterface) *PathAttributePmsiTunnel { 8453 if id == nil { 8454 return nil 8455 } 8456 // Flags(1) + TunnelType(1) + Label(3) + TunnelID(variable) 8457 l := 5 + id.Len() 8458 t := BGP_ATTR_TYPE_PMSI_TUNNEL 8459 return &PathAttributePmsiTunnel{ 8460 PathAttribute: PathAttribute{ 8461 Flags: getPathAttrFlags(t, l), 8462 Type: t, 8463 Length: uint16(l), 8464 }, 8465 IsLeafInfoRequired: isLeafInfoRequired, 8466 TunnelType: typ, 8467 Label: label, 8468 TunnelID: id, 8469 } 8470 } 8471 8472 func ParsePmsiTunnel(args []string) (*PathAttributePmsiTunnel, error) { 8473 // Format: 8474 // "<type>" ["leaf-info-required"] "<label>" "<tunnel-id>" 8475 if len(args) < 3 { 8476 return nil, fmt.Errorf("invalid pmsi tunnel arguments: %s", args) 8477 } 8478 8479 var tunnelType PmsiTunnelType 8480 var isLeafInfoRequired bool 8481 switch args[0] { 8482 case "ingress-repl": 8483 tunnelType = PMSI_TUNNEL_TYPE_INGRESS_REPL 8484 default: 8485 typ, err := strconv.ParseUint(args[0], 10, 8) 8486 if err != nil { 8487 return nil, fmt.Errorf("invalid pmsi tunnel type: %s", args[0]) 8488 } 8489 tunnelType = PmsiTunnelType(typ) 8490 } 8491 8492 indx := 1 8493 if args[indx] == "leaf-info-required" { 8494 isLeafInfoRequired = true 8495 indx++ 8496 } 8497 8498 label, err := strconv.ParseUint(args[indx], 10, 32) 8499 if err != nil { 8500 return nil, fmt.Errorf("invalid pmsi tunnel label: %s", args[indx]) 8501 } 8502 indx++ 8503 8504 var id PmsiTunnelIDInterface 8505 switch tunnelType { 8506 case PMSI_TUNNEL_TYPE_INGRESS_REPL: 8507 ip := net.ParseIP(args[indx]) 8508 if ip == nil { 8509 return nil, fmt.Errorf("invalid pmsi tunnel identifier: %s", args[indx]) 8510 } 8511 id = &IngressReplTunnelID{Value: ip} 8512 default: 8513 id = &DefaultPmsiTunnelID{Value: []byte(args[indx])} 8514 } 8515 8516 return NewPathAttributePmsiTunnel(tunnelType, isLeafInfoRequired, uint32(label), id), nil 8517 } 8518 8519 type PathAttributeIP6ExtendedCommunities struct { 8520 PathAttribute 8521 Value []ExtendedCommunityInterface 8522 } 8523 8524 func ParseIP6Extended(data []byte) (ExtendedCommunityInterface, error) { 8525 if len(data) < 8 { 8526 return nil, NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "not all extended community bytes are available") 8527 } 8528 attrType := ExtendedCommunityAttrType(data[0]) 8529 subtype := ExtendedCommunityAttrSubType(data[1]) 8530 transitive := false 8531 switch attrType { 8532 case EC_TYPE_TRANSITIVE_IP6_SPECIFIC: 8533 transitive = true 8534 fallthrough 8535 case EC_TYPE_NON_TRANSITIVE_IP6_SPECIFIC: 8536 ipv6 := net.IP(data[2:18]).String() 8537 localAdmin := binary.BigEndian.Uint16(data[18:20]) 8538 return NewIPv6AddressSpecificExtended(subtype, ipv6, localAdmin, transitive), nil 8539 case EC_TYPE_GENERIC_TRANSITIVE_EXPERIMENTAL: 8540 return parseIP6FlowSpecExtended(data) 8541 default: 8542 return &UnknownExtended{ 8543 Type: ExtendedCommunityAttrType(data[0]), 8544 Value: data[1:8], 8545 }, nil 8546 } 8547 } 8548 8549 func (p *PathAttributeIP6ExtendedCommunities) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 8550 value, err := p.PathAttribute.DecodeFromBytes(data) 8551 if err != nil { 8552 return err 8553 } 8554 if p.Length%20 != 0 { 8555 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 8556 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 8557 return NewMessageError(eCode, eSubCode, nil, "extendedcommunities length isn't correct") 8558 } 8559 for len(value) >= 20 { 8560 e, err := ParseIP6Extended(value) 8561 if err != nil { 8562 return err 8563 } 8564 p.Value = append(p.Value, e) 8565 value = value[20:] 8566 } 8567 return nil 8568 } 8569 8570 func (p *PathAttributeIP6ExtendedCommunities) Serialize(options ...*MarshallingOption) ([]byte, error) { 8571 buf := make([]byte, 0) 8572 for _, p := range p.Value { 8573 ebuf, err := p.Serialize() 8574 if err != nil { 8575 return nil, err 8576 } 8577 buf = append(buf, ebuf...) 8578 } 8579 return p.PathAttribute.Serialize(buf, options...) 8580 } 8581 8582 func (p *PathAttributeIP6ExtendedCommunities) String() string { 8583 var buf []string 8584 for _, v := range p.Value { 8585 buf = append(buf, fmt.Sprintf("[%s]", v.String())) 8586 } 8587 return fmt.Sprintf("{Extcomms: %s}", strings.Join(buf, ",")) 8588 } 8589 8590 func (p *PathAttributeIP6ExtendedCommunities) MarshalJSON() ([]byte, error) { 8591 return json.Marshal(struct { 8592 Type BGPAttrType `json:"type"` 8593 Value []ExtendedCommunityInterface `json:"value"` 8594 }{ 8595 Type: p.GetType(), 8596 Value: p.Value, 8597 }) 8598 } 8599 8600 func NewPathAttributeIP6ExtendedCommunities(value []ExtendedCommunityInterface) *PathAttributeIP6ExtendedCommunities { 8601 l := len(value) * 20 8602 t := BGP_ATTR_TYPE_IP6_EXTENDED_COMMUNITIES 8603 return &PathAttributeIP6ExtendedCommunities{ 8604 PathAttribute: PathAttribute{ 8605 Flags: getPathAttrFlags(t, l), 8606 Type: t, 8607 Length: uint16(l), 8608 }, 8609 Value: value, 8610 } 8611 } 8612 8613 type AigpTLVType uint8 8614 8615 const ( 8616 AIGP_TLV_UNKNOWN AigpTLVType = iota 8617 AIGP_TLV_IGP_METRIC 8618 ) 8619 8620 type AigpTLVInterface interface { 8621 Serialize() ([]byte, error) 8622 String() string 8623 MarshalJSON() ([]byte, error) 8624 Type() AigpTLVType 8625 Len() int 8626 } 8627 8628 type AigpTLVDefault struct { 8629 typ AigpTLVType 8630 Value []byte 8631 } 8632 8633 func (t *AigpTLVDefault) Serialize() ([]byte, error) { 8634 buf := make([]byte, 3+len(t.Value)) 8635 buf[0] = uint8(t.Type()) 8636 binary.BigEndian.PutUint16(buf[1:], uint16(3+len(t.Value))) 8637 copy(buf[3:], t.Value) 8638 return buf, nil 8639 } 8640 8641 func (t *AigpTLVDefault) String() string { 8642 return fmt.Sprintf("{Type: %d, Value: %v}", t.Type(), t.Value) 8643 } 8644 8645 func (t *AigpTLVDefault) MarshalJSON() ([]byte, error) { 8646 return json.Marshal(struct { 8647 Type AigpTLVType `json:"type"` 8648 Value []byte `json:"value"` 8649 }{ 8650 Type: t.Type(), 8651 Value: t.Value, 8652 }) 8653 } 8654 8655 func (t *AigpTLVDefault) Type() AigpTLVType { 8656 return t.typ 8657 } 8658 8659 func (t *AigpTLVDefault) Len() int { 8660 return 3 + len(t.Value) // Type(1) + Length(2) + Value(variable) 8661 } 8662 8663 func NewAigpTLVDefault(typ AigpTLVType, value []byte) *AigpTLVDefault { 8664 return &AigpTLVDefault{ 8665 typ: typ, 8666 Value: value, 8667 } 8668 } 8669 8670 type AigpTLVIgpMetric struct { 8671 Metric uint64 8672 } 8673 8674 func (t *AigpTLVIgpMetric) Serialize() ([]byte, error) { 8675 buf := make([]byte, 11) 8676 buf[0] = uint8(AIGP_TLV_IGP_METRIC) 8677 binary.BigEndian.PutUint16(buf[1:], uint16(11)) 8678 binary.BigEndian.PutUint64(buf[3:], t.Metric) 8679 return buf, nil 8680 } 8681 8682 func (t *AigpTLVIgpMetric) String() string { 8683 return fmt.Sprintf("{Metric: %d}", t.Metric) 8684 } 8685 8686 func (t *AigpTLVIgpMetric) MarshalJSON() ([]byte, error) { 8687 return json.Marshal(struct { 8688 Type AigpTLVType `json:"type"` 8689 Metric uint64 `json:"metric"` 8690 }{ 8691 Type: AIGP_TLV_IGP_METRIC, 8692 Metric: t.Metric, 8693 }) 8694 } 8695 8696 func NewAigpTLVIgpMetric(metric uint64) *AigpTLVIgpMetric { 8697 return &AigpTLVIgpMetric{ 8698 Metric: metric, 8699 } 8700 } 8701 8702 func (t *AigpTLVIgpMetric) Type() AigpTLVType { 8703 return AIGP_TLV_IGP_METRIC 8704 } 8705 8706 func (t *AigpTLVIgpMetric) Len() int { 8707 return 11 8708 } 8709 8710 type PathAttributeAigp struct { 8711 PathAttribute 8712 Values []AigpTLVInterface 8713 } 8714 8715 func (p *PathAttributeAigp) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 8716 value, err := p.PathAttribute.DecodeFromBytes(data, options...) 8717 if err != nil { 8718 return err 8719 } 8720 for len(value) > 3 { 8721 typ := value[0] 8722 length := binary.BigEndian.Uint16(value[1:3]) 8723 if len(value) < int(length) { 8724 break 8725 } 8726 v := value[3:length] 8727 switch AigpTLVType(typ) { 8728 case AIGP_TLV_IGP_METRIC: 8729 if len(v) < 8 { 8730 break 8731 } 8732 metric := binary.BigEndian.Uint64(v) 8733 p.Values = append(p.Values, NewAigpTLVIgpMetric(metric)) 8734 default: 8735 p.Values = append(p.Values, NewAigpTLVDefault(AigpTLVType(typ), v)) 8736 } 8737 value = value[length:] 8738 } 8739 if len(value) != 0 { 8740 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 8741 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 8742 return NewMessageError(eCode, eSubCode, nil, "Aigp length is incorrect") 8743 } 8744 return nil 8745 } 8746 8747 func (p *PathAttributeAigp) Serialize(options ...*MarshallingOption) ([]byte, error) { 8748 buf := make([]byte, 0) 8749 for _, t := range p.Values { 8750 bbuf, err := t.Serialize() 8751 if err != nil { 8752 return nil, err 8753 } 8754 buf = append(buf, bbuf...) 8755 } 8756 return p.PathAttribute.Serialize(buf, options...) 8757 } 8758 8759 func (p *PathAttributeAigp) String() string { 8760 buf := bytes.NewBuffer(make([]byte, 0, 32)) 8761 buf.WriteString("{Aigp: [") 8762 for _, v := range p.Values { 8763 buf.WriteString(v.String()) 8764 } 8765 buf.WriteString("]}") 8766 return buf.String() 8767 } 8768 8769 func (p *PathAttributeAigp) MarshalJSON() ([]byte, error) { 8770 return json.Marshal(struct { 8771 Type BGPAttrType `json:"type"` 8772 Value []AigpTLVInterface `json:"value"` 8773 }{ 8774 Type: p.GetType(), 8775 Value: p.Values, 8776 }) 8777 } 8778 8779 func NewPathAttributeAigp(values []AigpTLVInterface) *PathAttributeAigp { 8780 var l int 8781 for _, v := range values { 8782 l += v.Len() 8783 } 8784 t := BGP_ATTR_TYPE_AIGP 8785 return &PathAttributeAigp{ 8786 PathAttribute: PathAttribute{ 8787 Flags: getPathAttrFlags(t, l), 8788 Type: t, 8789 Length: uint16(l), 8790 }, 8791 Values: values, 8792 } 8793 } 8794 8795 type LargeCommunity struct { 8796 ASN uint32 8797 LocalData1 uint32 8798 LocalData2 uint32 8799 } 8800 8801 func (c *LargeCommunity) Serialize() ([]byte, error) { 8802 buf := make([]byte, 12) 8803 binary.BigEndian.PutUint32(buf, c.ASN) 8804 binary.BigEndian.PutUint32(buf[4:], c.LocalData1) 8805 binary.BigEndian.PutUint32(buf[8:], c.LocalData2) 8806 return buf, nil 8807 } 8808 8809 func (c *LargeCommunity) String() string { 8810 return fmt.Sprintf("%d:%d:%d", c.ASN, c.LocalData1, c.LocalData2) 8811 } 8812 8813 func NewLargeCommunity(asn, data1, data2 uint32) *LargeCommunity { 8814 return &LargeCommunity{ 8815 ASN: asn, 8816 LocalData1: data1, 8817 LocalData2: data2, 8818 } 8819 } 8820 8821 func ParseLargeCommunity(value string) (*LargeCommunity, error) { 8822 elems := strings.Split(value, ":") 8823 if len(elems) != 3 { 8824 return nil, fmt.Errorf("invalid large community format") 8825 } 8826 v := make([]uint32, 0, 3) 8827 for _, elem := range elems { 8828 e, err := strconv.ParseUint(elem, 10, 32) 8829 if err != nil { 8830 return nil, fmt.Errorf("invalid large community format") 8831 } 8832 v = append(v, uint32(e)) 8833 } 8834 return NewLargeCommunity(v[0], v[1], v[2]), nil 8835 } 8836 8837 type PathAttributeLargeCommunities struct { 8838 PathAttribute 8839 Values []*LargeCommunity 8840 } 8841 8842 func (p *PathAttributeLargeCommunities) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 8843 value, err := p.PathAttribute.DecodeFromBytes(data) 8844 if err != nil { 8845 return err 8846 } 8847 if p.Length%12 != 0 { 8848 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 8849 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 8850 return NewMessageError(eCode, eSubCode, nil, "large communities length isn't correct") 8851 } 8852 p.Values = make([]*LargeCommunity, 0, p.Length/12) 8853 for len(value) >= 12 { 8854 asn := binary.BigEndian.Uint32(value[:4]) 8855 data1 := binary.BigEndian.Uint32(value[4:8]) 8856 data2 := binary.BigEndian.Uint32(value[8:12]) 8857 p.Values = append(p.Values, NewLargeCommunity(asn, data1, data2)) 8858 value = value[12:] 8859 } 8860 return nil 8861 } 8862 8863 func (p *PathAttributeLargeCommunities) Serialize(options ...*MarshallingOption) ([]byte, error) { 8864 buf := make([]byte, 0, len(p.Values)*12) 8865 for _, t := range p.Values { 8866 bbuf, err := t.Serialize() 8867 if err != nil { 8868 return nil, err 8869 } 8870 buf = append(buf, bbuf...) 8871 } 8872 return p.PathAttribute.Serialize(buf, options...) 8873 } 8874 8875 func (p *PathAttributeLargeCommunities) String() string { 8876 buf := bytes.NewBuffer(make([]byte, 0, 32)) 8877 buf.WriteString("{LargeCommunity: [ ") 8878 ss := []string{} 8879 for _, v := range p.Values { 8880 ss = append(ss, v.String()) 8881 } 8882 buf.WriteString(strings.Join(ss, ", ")) 8883 buf.WriteString("]}") 8884 return buf.String() 8885 } 8886 8887 func (p *PathAttributeLargeCommunities) MarshalJSON() ([]byte, error) { 8888 return json.Marshal(struct { 8889 Type BGPAttrType `json:"type"` 8890 Value []*LargeCommunity `json:"value"` 8891 }{ 8892 Type: p.GetType(), 8893 Value: p.Values, 8894 }) 8895 } 8896 8897 func NewPathAttributeLargeCommunities(values []*LargeCommunity) *PathAttributeLargeCommunities { 8898 l := len(values) * 12 8899 t := BGP_ATTR_TYPE_LARGE_COMMUNITY 8900 return &PathAttributeLargeCommunities{ 8901 PathAttribute: PathAttribute{ 8902 Flags: getPathAttrFlags(t, l), 8903 Type: t, 8904 Length: uint16(l), 8905 }, 8906 Values: values, 8907 } 8908 } 8909 8910 type PathAttributeUnknown struct { 8911 PathAttribute 8912 Value []byte 8913 } 8914 8915 func (p *PathAttributeUnknown) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 8916 value, err := p.PathAttribute.DecodeFromBytes(data) 8917 if err != nil { 8918 return err 8919 } 8920 p.Value = value 8921 return nil 8922 } 8923 8924 func (p *PathAttributeUnknown) Serialize(options ...*MarshallingOption) ([]byte, error) { 8925 return p.PathAttribute.Serialize(p.Value, options...) 8926 } 8927 8928 func (p *PathAttributeUnknown) String() string { 8929 return fmt.Sprintf("{Flags: %s, Type: %s, Value: %s}", p.Flags, p.Type, p.Value) 8930 } 8931 8932 func (p *PathAttributeUnknown) MarshalJSON() ([]byte, error) { 8933 return json.Marshal(struct { 8934 Flags BGPAttrFlag `json:"flags"` 8935 Type BGPAttrType `json:"type"` 8936 Value []byte `json:"value"` 8937 }{ 8938 Flags: p.GetFlags(), 8939 Type: p.GetType(), 8940 Value: p.Value, 8941 }) 8942 } 8943 8944 func NewPathAttributeUnknown(flags BGPAttrFlag, typ BGPAttrType, value []byte) *PathAttributeUnknown { 8945 l := len(value) 8946 if l > 255 { 8947 flags |= BGP_ATTR_FLAG_EXTENDED_LENGTH 8948 } 8949 return &PathAttributeUnknown{ 8950 PathAttribute: PathAttribute{ 8951 Flags: flags, 8952 Type: typ, 8953 Length: uint16(l), 8954 }, 8955 Value: value, 8956 } 8957 } 8958 8959 func GetPathAttribute(data []byte) (PathAttributeInterface, error) { 8960 if len(data) < 2 { 8961 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 8962 eSubCode := uint8(BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR) 8963 return nil, NewMessageError(eCode, eSubCode, data, "attribute type length is short") 8964 } 8965 switch BGPAttrType(data[1]) { 8966 case BGP_ATTR_TYPE_ORIGIN: 8967 return &PathAttributeOrigin{}, nil 8968 case BGP_ATTR_TYPE_AS_PATH: 8969 return &PathAttributeAsPath{}, nil 8970 case BGP_ATTR_TYPE_NEXT_HOP: 8971 return &PathAttributeNextHop{}, nil 8972 case BGP_ATTR_TYPE_MULTI_EXIT_DISC: 8973 return &PathAttributeMultiExitDisc{}, nil 8974 case BGP_ATTR_TYPE_LOCAL_PREF: 8975 return &PathAttributeLocalPref{}, nil 8976 case BGP_ATTR_TYPE_ATOMIC_AGGREGATE: 8977 return &PathAttributeAtomicAggregate{}, nil 8978 case BGP_ATTR_TYPE_AGGREGATOR: 8979 return &PathAttributeAggregator{}, nil 8980 case BGP_ATTR_TYPE_COMMUNITIES: 8981 return &PathAttributeCommunities{}, nil 8982 case BGP_ATTR_TYPE_ORIGINATOR_ID: 8983 return &PathAttributeOriginatorId{}, nil 8984 case BGP_ATTR_TYPE_CLUSTER_LIST: 8985 return &PathAttributeClusterList{}, nil 8986 case BGP_ATTR_TYPE_MP_REACH_NLRI: 8987 return &PathAttributeMpReachNLRI{}, nil 8988 case BGP_ATTR_TYPE_MP_UNREACH_NLRI: 8989 return &PathAttributeMpUnreachNLRI{}, nil 8990 case BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: 8991 return &PathAttributeExtendedCommunities{}, nil 8992 case BGP_ATTR_TYPE_AS4_PATH: 8993 return &PathAttributeAs4Path{}, nil 8994 case BGP_ATTR_TYPE_AS4_AGGREGATOR: 8995 return &PathAttributeAs4Aggregator{}, nil 8996 case BGP_ATTR_TYPE_TUNNEL_ENCAP: 8997 return &PathAttributeTunnelEncap{}, nil 8998 case BGP_ATTR_TYPE_PMSI_TUNNEL: 8999 return &PathAttributePmsiTunnel{}, nil 9000 case BGP_ATTR_TYPE_IP6_EXTENDED_COMMUNITIES: 9001 return &PathAttributeIP6ExtendedCommunities{}, nil 9002 case BGP_ATTR_TYPE_AIGP: 9003 return &PathAttributeAigp{}, nil 9004 case BGP_ATTR_TYPE_LARGE_COMMUNITY: 9005 return &PathAttributeLargeCommunities{}, nil 9006 } 9007 return &PathAttributeUnknown{}, nil 9008 } 9009 9010 type BGPUpdate struct { 9011 WithdrawnRoutesLen uint16 9012 WithdrawnRoutes []*IPAddrPrefix 9013 TotalPathAttributeLen uint16 9014 PathAttributes []PathAttributeInterface 9015 NLRI []*IPAddrPrefix 9016 } 9017 9018 func (msg *BGPUpdate) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 9019 var strongestError error 9020 9021 // cache error codes 9022 eCode := uint8(BGP_ERROR_UPDATE_MESSAGE_ERROR) 9023 eSubCode := uint8(BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST) 9024 9025 // check withdrawn route length 9026 if len(data) < 2 { 9027 return NewMessageError(eCode, eSubCode, nil, "message length isn't enough for withdrawn route length") 9028 } 9029 9030 msg.WithdrawnRoutesLen = binary.BigEndian.Uint16(data[0:2]) 9031 data = data[2:] 9032 9033 // check withdrawn route 9034 if len(data) < int(msg.WithdrawnRoutesLen) { 9035 return NewMessageError(eCode, eSubCode, nil, "withdrawn route length exceeds message length") 9036 } 9037 9038 addpathLen := 0 9039 if IsAddPathEnabled(true, RF_IPv4_UC, options) { 9040 addpathLen = 4 9041 } 9042 9043 msg.WithdrawnRoutes = make([]*IPAddrPrefix, 0, msg.WithdrawnRoutesLen) 9044 for routelen := msg.WithdrawnRoutesLen; routelen > 0; { 9045 w := &IPAddrPrefix{} 9046 err := w.DecodeFromBytes(data, options...) 9047 if err != nil { 9048 return err 9049 } 9050 routelen -= uint16(w.Len(options...) + addpathLen) 9051 if len(data) < w.Len(options...)+addpathLen { 9052 return NewMessageError(eCode, eSubCode, nil, "Withdrawn route length is short") 9053 } 9054 data = data[w.Len(options...)+addpathLen:] 9055 msg.WithdrawnRoutes = append(msg.WithdrawnRoutes, w) 9056 } 9057 9058 // check path total attribute length 9059 if len(data) < 2 { 9060 return NewMessageError(eCode, eSubCode, nil, "message length isn't enough for path total attribute length") 9061 } 9062 9063 msg.TotalPathAttributeLen = binary.BigEndian.Uint16(data[0:2]) 9064 data = data[2:] 9065 9066 // check path attribute 9067 if len(data) < int(msg.TotalPathAttributeLen) { 9068 return NewMessageError(eCode, eSubCode, nil, "path total attribute length exceeds message length") 9069 } 9070 9071 msg.PathAttributes = []PathAttributeInterface{} 9072 for pathlen := msg.TotalPathAttributeLen; pathlen > 0; { 9073 var e error 9074 if pathlen < 3 { 9075 e = NewMessageErrorWithErrorHandling( 9076 eCode, BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR, data, ERROR_HANDLING_TREAT_AS_WITHDRAW, nil, "insufficient data to decode") 9077 if e.(*MessageError).Stronger(strongestError) { 9078 strongestError = e 9079 } 9080 data = data[pathlen:] 9081 break 9082 } 9083 p, err := GetPathAttribute(data) 9084 if err != nil { 9085 return err 9086 } 9087 9088 err = p.DecodeFromBytes(data, options...) 9089 if err != nil { 9090 e = err.(*MessageError) 9091 if e.(*MessageError).SubTypeCode == BGP_ERROR_SUB_ATTRIBUTE_FLAGS_ERROR { 9092 e.(*MessageError).ErrorHandling = ERROR_HANDLING_TREAT_AS_WITHDRAW 9093 } else { 9094 e.(*MessageError).ErrorHandling = getErrorHandlingFromPathAttribute(p.GetType()) 9095 e.(*MessageError).ErrorAttribute = &p 9096 } 9097 if e.(*MessageError).Stronger(strongestError) { 9098 strongestError = e 9099 } 9100 } 9101 pathlen -= uint16(p.Len(options...)) 9102 if len(data) < p.Len(options...) { 9103 e = NewMessageErrorWithErrorHandling( 9104 eCode, BGP_ERROR_SUB_ATTRIBUTE_LENGTH_ERROR, data, ERROR_HANDLING_TREAT_AS_WITHDRAW, nil, "attribute length is short") 9105 if e.(*MessageError).Stronger(strongestError) { 9106 strongestError = e 9107 } 9108 } 9109 data = data[p.Len(options...):] 9110 if e == nil || e.(*MessageError).ErrorHandling != ERROR_HANDLING_ATTRIBUTE_DISCARD { 9111 msg.PathAttributes = append(msg.PathAttributes, p) 9112 } 9113 } 9114 9115 msg.NLRI = make([]*IPAddrPrefix, 0) 9116 for restlen := len(data); restlen > 0; { 9117 n := &IPAddrPrefix{} 9118 err := n.DecodeFromBytes(data, options...) 9119 if err != nil { 9120 return err 9121 } 9122 restlen -= n.Len(options...) + addpathLen 9123 if len(data) < n.Len(options...)+addpathLen { 9124 return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, nil, "NLRI length is short") 9125 } 9126 if n.Len(options...) > 32 { 9127 return NewMessageError(eCode, BGP_ERROR_SUB_INVALID_NETWORK_FIELD, nil, "NLRI length is too long") 9128 } 9129 data = data[n.Len(options...)+addpathLen:] 9130 msg.NLRI = append(msg.NLRI, n) 9131 } 9132 9133 return strongestError 9134 } 9135 9136 func (msg *BGPUpdate) Serialize(options ...*MarshallingOption) ([]byte, error) { 9137 wbuf := make([]byte, 2) 9138 for _, w := range msg.WithdrawnRoutes { 9139 onewbuf, err := w.Serialize(options...) 9140 if err != nil { 9141 return nil, err 9142 } 9143 wbuf = append(wbuf, onewbuf...) 9144 } 9145 msg.WithdrawnRoutesLen = uint16(len(wbuf) - 2) 9146 binary.BigEndian.PutUint16(wbuf, msg.WithdrawnRoutesLen) 9147 9148 pbuf := make([]byte, 2) 9149 for _, p := range msg.PathAttributes { 9150 onepbuf, err := p.Serialize(options...) 9151 if err != nil { 9152 return nil, err 9153 } 9154 pbuf = append(pbuf, onepbuf...) 9155 } 9156 msg.TotalPathAttributeLen = uint16(len(pbuf) - 2) 9157 binary.BigEndian.PutUint16(pbuf, msg.TotalPathAttributeLen) 9158 9159 buf := append(wbuf, pbuf...) 9160 for _, n := range msg.NLRI { 9161 nbuf, err := n.Serialize(options...) 9162 if err != nil { 9163 return nil, err 9164 } 9165 buf = append(buf, nbuf...) 9166 } 9167 return buf, nil 9168 } 9169 9170 func (msg *BGPUpdate) IsEndOfRib() (bool, RouteFamily) { 9171 if len(msg.WithdrawnRoutes) == 0 && len(msg.NLRI) == 0 { 9172 if len(msg.PathAttributes) == 0 { 9173 return true, RF_IPv4_UC 9174 } else if len(msg.PathAttributes) == 1 && msg.PathAttributes[0].GetType() == BGP_ATTR_TYPE_MP_UNREACH_NLRI { 9175 unreach := msg.PathAttributes[0].(*PathAttributeMpUnreachNLRI) 9176 if len(unreach.Value) == 0 { 9177 return true, AfiSafiToRouteFamily(unreach.AFI, unreach.SAFI) 9178 } 9179 } 9180 } 9181 return false, RouteFamily(0) 9182 } 9183 9184 func TreatAsWithdraw(msg *BGPUpdate) *BGPUpdate { 9185 withdraw := &BGPUpdate{ 9186 WithdrawnRoutesLen: 0, 9187 WithdrawnRoutes: []*IPAddrPrefix{}, 9188 TotalPathAttributeLen: 0, 9189 PathAttributes: make([]PathAttributeInterface, 0, len(msg.PathAttributes)), 9190 NLRI: []*IPAddrPrefix{}, 9191 } 9192 withdraw.WithdrawnRoutes = append(msg.WithdrawnRoutes, msg.NLRI...) 9193 var unreach []AddrPrefixInterface 9194 9195 for _, p := range msg.PathAttributes { 9196 switch nlri := p.(type) { 9197 case *PathAttributeMpReachNLRI: 9198 unreach = append(unreach, nlri.Value...) 9199 case *PathAttributeMpUnreachNLRI: 9200 unreach = append(unreach, nlri.Value...) 9201 } 9202 } 9203 if len(unreach) != 0 { 9204 withdraw.PathAttributes = append(withdraw.PathAttributes, NewPathAttributeMpUnreachNLRI(unreach)) 9205 } 9206 return withdraw 9207 } 9208 9209 func NewBGPUpdateMessage(withdrawnRoutes []*IPAddrPrefix, pathattrs []PathAttributeInterface, nlri []*IPAddrPrefix) *BGPMessage { 9210 return &BGPMessage{ 9211 Header: BGPHeader{Type: BGP_MSG_UPDATE}, 9212 Body: &BGPUpdate{0, withdrawnRoutes, 0, pathattrs, nlri}, 9213 } 9214 } 9215 9216 func NewEndOfRib(family RouteFamily) *BGPMessage { 9217 if family == RF_IPv4_UC { 9218 return NewBGPUpdateMessage(nil, nil, nil) 9219 } else { 9220 afi, safi := RouteFamilyToAfiSafi(family) 9221 t := BGP_ATTR_TYPE_MP_UNREACH_NLRI 9222 unreach := &PathAttributeMpUnreachNLRI{ 9223 PathAttribute: PathAttribute{ 9224 Flags: PathAttrFlags[t], 9225 Type: t, 9226 }, 9227 AFI: afi, 9228 SAFI: safi, 9229 } 9230 return NewBGPUpdateMessage(nil, []PathAttributeInterface{unreach}, nil) 9231 } 9232 } 9233 9234 type BGPNotification struct { 9235 ErrorCode uint8 9236 ErrorSubcode uint8 9237 Data []byte 9238 } 9239 9240 func (msg *BGPNotification) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 9241 if len(data) < 2 { 9242 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Not all Notificaiton bytes available") 9243 } 9244 msg.ErrorCode = data[0] 9245 msg.ErrorSubcode = data[1] 9246 if len(data) > 2 { 9247 msg.Data = data[2:] 9248 } 9249 return nil 9250 } 9251 9252 func (msg *BGPNotification) Serialize(options ...*MarshallingOption) ([]byte, error) { 9253 buf := make([]byte, 2) 9254 buf[0] = msg.ErrorCode 9255 buf[1] = msg.ErrorSubcode 9256 buf = append(buf, msg.Data...) 9257 return buf, nil 9258 } 9259 9260 func NewBGPNotificationMessage(errcode uint8, errsubcode uint8, data []byte) *BGPMessage { 9261 return &BGPMessage{ 9262 Header: BGPHeader{Type: BGP_MSG_NOTIFICATION}, 9263 Body: &BGPNotification{errcode, errsubcode, data}, 9264 } 9265 } 9266 9267 type BGPKeepAlive struct { 9268 } 9269 9270 func (msg *BGPKeepAlive) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 9271 return nil 9272 } 9273 9274 func (msg *BGPKeepAlive) Serialize(options ...*MarshallingOption) ([]byte, error) { 9275 return nil, nil 9276 } 9277 9278 func NewBGPKeepAliveMessage() *BGPMessage { 9279 return &BGPMessage{ 9280 Header: BGPHeader{Len: 19, Type: BGP_MSG_KEEPALIVE}, 9281 Body: &BGPKeepAlive{}, 9282 } 9283 } 9284 9285 type BGPRouteRefresh struct { 9286 AFI uint16 9287 Demarcation uint8 9288 SAFI uint8 9289 } 9290 9291 func (msg *BGPRouteRefresh) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 9292 if len(data) < 4 { 9293 return NewMessageError(BGP_ERROR_ROUTE_REFRESH_MESSAGE_ERROR, BGP_ERROR_SUB_INVALID_MESSAGE_LENGTH, nil, "Not all RouteRefresh bytes available") 9294 } 9295 msg.AFI = binary.BigEndian.Uint16(data[0:2]) 9296 msg.Demarcation = data[2] 9297 msg.SAFI = data[3] 9298 return nil 9299 } 9300 9301 func (msg *BGPRouteRefresh) Serialize(options ...*MarshallingOption) ([]byte, error) { 9302 buf := make([]byte, 4) 9303 binary.BigEndian.PutUint16(buf[0:2], msg.AFI) 9304 buf[2] = msg.Demarcation 9305 buf[3] = msg.SAFI 9306 return buf, nil 9307 } 9308 9309 func NewBGPRouteRefreshMessage(afi uint16, demarcation uint8, safi uint8) *BGPMessage { 9310 return &BGPMessage{ 9311 Header: BGPHeader{Type: BGP_MSG_ROUTE_REFRESH}, 9312 Body: &BGPRouteRefresh{afi, demarcation, safi}, 9313 } 9314 } 9315 9316 type BGPBody interface { 9317 DecodeFromBytes([]byte, ...*MarshallingOption) error 9318 Serialize(...*MarshallingOption) ([]byte, error) 9319 } 9320 9321 const ( 9322 BGP_HEADER_LENGTH = 19 9323 BGP_MAX_MESSAGE_LENGTH = 4096 9324 ) 9325 9326 type BGPHeader struct { 9327 Marker []byte 9328 Len uint16 9329 Type uint8 9330 } 9331 9332 func (msg *BGPHeader) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 9333 // minimum BGP message length 9334 if uint16(len(data)) < BGP_HEADER_LENGTH { 9335 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "not all BGP message header") 9336 } 9337 9338 msg.Len = binary.BigEndian.Uint16(data[16:18]) 9339 if int(msg.Len) < BGP_HEADER_LENGTH { 9340 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "unknown message type") 9341 } 9342 9343 msg.Type = data[18] 9344 return nil 9345 } 9346 9347 func (msg *BGPHeader) Serialize(options ...*MarshallingOption) ([]byte, error) { 9348 buf := make([]byte, 19) 9349 for i := range buf[:16] { 9350 buf[i] = 0xff 9351 } 9352 binary.BigEndian.PutUint16(buf[16:18], msg.Len) 9353 buf[18] = msg.Type 9354 return buf, nil 9355 } 9356 9357 type BGPMessage struct { 9358 Header BGPHeader 9359 Body BGPBody 9360 } 9361 9362 func parseBody(h *BGPHeader, data []byte, options ...*MarshallingOption) (*BGPMessage, error) { 9363 if len(data) < int(h.Len)-BGP_HEADER_LENGTH { 9364 return nil, NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Not all BGP message bytes available") 9365 } 9366 msg := &BGPMessage{Header: *h} 9367 9368 switch msg.Header.Type { 9369 case BGP_MSG_OPEN: 9370 msg.Body = &BGPOpen{} 9371 case BGP_MSG_UPDATE: 9372 msg.Body = &BGPUpdate{} 9373 case BGP_MSG_NOTIFICATION: 9374 msg.Body = &BGPNotification{} 9375 case BGP_MSG_KEEPALIVE: 9376 msg.Body = &BGPKeepAlive{} 9377 case BGP_MSG_ROUTE_REFRESH: 9378 msg.Body = &BGPRouteRefresh{} 9379 default: 9380 return nil, NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_TYPE, nil, "unknown message type") 9381 } 9382 err := msg.Body.DecodeFromBytes(data, options...) 9383 return msg, err 9384 } 9385 9386 func ParseBGPMessage(data []byte, options ...*MarshallingOption) (*BGPMessage, error) { 9387 h := &BGPHeader{} 9388 err := h.DecodeFromBytes(data, options...) 9389 if err != nil { 9390 return nil, err 9391 } 9392 9393 if int(h.Len) > len(data) { 9394 return nil, NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "unknown message type") 9395 } 9396 9397 return parseBody(h, data[19:h.Len], options...) 9398 } 9399 9400 func ParseBGPBody(h *BGPHeader, data []byte, options ...*MarshallingOption) (*BGPMessage, error) { 9401 return parseBody(h, data, options...) 9402 } 9403 9404 func (msg *BGPMessage) Serialize(options ...*MarshallingOption) ([]byte, error) { 9405 b, err := msg.Body.Serialize(options...) 9406 if err != nil { 9407 return nil, err 9408 } 9409 if msg.Header.Len == 0 { 9410 if 19+len(b) > BGP_MAX_MESSAGE_LENGTH { 9411 return nil, NewMessageError(0, 0, nil, fmt.Sprintf("too long message length %d", 19+len(b))) 9412 } 9413 msg.Header.Len = 19 + uint16(len(b)) 9414 } 9415 h, err := msg.Header.Serialize(options...) 9416 if err != nil { 9417 return nil, err 9418 } 9419 return append(h, b...), nil 9420 } 9421 9422 type ErrorHandling int 9423 9424 const ( 9425 ERROR_HANDLING_NONE ErrorHandling = iota 9426 ERROR_HANDLING_ATTRIBUTE_DISCARD 9427 ERROR_HANDLING_TREAT_AS_WITHDRAW 9428 ERROR_HANDLING_AFISAFI_DISABLE 9429 ERROR_HANDLING_SESSION_RESET 9430 ) 9431 9432 func getErrorHandlingFromPathAttribute(t BGPAttrType) ErrorHandling { 9433 switch t { 9434 case BGP_ATTR_TYPE_ORIGIN: 9435 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9436 case BGP_ATTR_TYPE_AS_PATH: 9437 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9438 case BGP_ATTR_TYPE_AS4_PATH: 9439 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9440 case BGP_ATTR_TYPE_NEXT_HOP: 9441 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9442 case BGP_ATTR_TYPE_MULTI_EXIT_DISC: 9443 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9444 case BGP_ATTR_TYPE_LOCAL_PREF: 9445 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9446 case BGP_ATTR_TYPE_ATOMIC_AGGREGATE: 9447 return ERROR_HANDLING_ATTRIBUTE_DISCARD 9448 case BGP_ATTR_TYPE_AGGREGATOR: 9449 return ERROR_HANDLING_ATTRIBUTE_DISCARD 9450 case BGP_ATTR_TYPE_AS4_AGGREGATOR: 9451 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9452 case BGP_ATTR_TYPE_COMMUNITIES: 9453 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9454 case BGP_ATTR_TYPE_ORIGINATOR_ID: 9455 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9456 case BGP_ATTR_TYPE_CLUSTER_LIST: 9457 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9458 case BGP_ATTR_TYPE_MP_REACH_NLRI: 9459 return ERROR_HANDLING_AFISAFI_DISABLE 9460 case BGP_ATTR_TYPE_MP_UNREACH_NLRI: 9461 return ERROR_HANDLING_AFISAFI_DISABLE 9462 case BGP_ATTR_TYPE_EXTENDED_COMMUNITIES: 9463 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9464 case BGP_ATTR_TYPE_IP6_EXTENDED_COMMUNITIES: 9465 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9466 case BGP_ATTR_TYPE_PMSI_TUNNEL: 9467 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9468 case BGP_ATTR_TYPE_LARGE_COMMUNITY: 9469 return ERROR_HANDLING_TREAT_AS_WITHDRAW 9470 case BGP_ATTR_TYPE_TUNNEL_ENCAP: 9471 return ERROR_HANDLING_ATTRIBUTE_DISCARD 9472 case BGP_ATTR_TYPE_AIGP: 9473 return ERROR_HANDLING_ATTRIBUTE_DISCARD 9474 default: 9475 return ERROR_HANDLING_ATTRIBUTE_DISCARD 9476 } 9477 } 9478 9479 type MessageError struct { 9480 TypeCode uint8 9481 SubTypeCode uint8 9482 Data []byte 9483 Message string 9484 ErrorHandling ErrorHandling 9485 ErrorAttribute *PathAttributeInterface 9486 } 9487 9488 func NewMessageError(typeCode, subTypeCode uint8, data []byte, msg string) error { 9489 return &MessageError{ 9490 TypeCode: typeCode, 9491 SubTypeCode: subTypeCode, 9492 Data: data, 9493 ErrorHandling: ERROR_HANDLING_SESSION_RESET, 9494 ErrorAttribute: nil, 9495 Message: msg, 9496 } 9497 } 9498 9499 func NewMessageErrorWithErrorHandling(typeCode, subTypeCode uint8, data []byte, errorHandling ErrorHandling, errorAttribute *PathAttributeInterface, msg string) error { 9500 return &MessageError{ 9501 TypeCode: typeCode, 9502 SubTypeCode: subTypeCode, 9503 Data: data, 9504 ErrorHandling: errorHandling, 9505 ErrorAttribute: errorAttribute, 9506 Message: msg, 9507 } 9508 } 9509 9510 func (e *MessageError) Error() string { 9511 return e.Message 9512 } 9513 9514 func (e *MessageError) Stronger(err error) bool { 9515 if err == nil { 9516 return true 9517 } 9518 if msgErr, ok := err.(*MessageError); ok { 9519 return e.ErrorHandling > msgErr.ErrorHandling 9520 } 9521 return false 9522 } 9523 9524 func (e *TwoOctetAsSpecificExtended) Flat() map[string]string { 9525 if e.SubType == EC_SUBTYPE_ROUTE_TARGET { 9526 return map[string]string{"routeTarget": e.String()} 9527 } 9528 return map[string]string{} 9529 } 9530 9531 func (e *ColorExtended) Flat() map[string]string { 9532 return map[string]string{} 9533 } 9534 9535 func (e *EncapExtended) Flat() map[string]string { 9536 return map[string]string{"encaspulation": e.TunnelType.String()} 9537 } 9538 9539 func (e *DefaultGatewayExtended) Flat() map[string]string { 9540 return map[string]string{} 9541 } 9542 9543 func (e *ValidationExtended) Flat() map[string]string { 9544 return map[string]string{} 9545 } 9546 9547 func (e *OpaqueExtended) Flat() map[string]string { 9548 return map[string]string{} 9549 } 9550 9551 func (e *IPv4AddressSpecificExtended) Flat() map[string]string { 9552 return map[string]string{} 9553 } 9554 9555 func (e *IPv6AddressSpecificExtended) Flat() map[string]string { 9556 return map[string]string{} 9557 } 9558 9559 func (e *FourOctetAsSpecificExtended) Flat() map[string]string { 9560 return map[string]string{} 9561 } 9562 9563 func (e *ESILabelExtended) Flat() map[string]string { 9564 return map[string]string{} 9565 } 9566 9567 func (e *ESImportRouteTarget) Flat() map[string]string { 9568 return map[string]string{} 9569 } 9570 9571 func (e *MacMobilityExtended) Flat() map[string]string { 9572 return map[string]string{} 9573 } 9574 9575 func (e *RouterMacExtended) Flat() map[string]string { 9576 return map[string]string{} 9577 } 9578 9579 func (e *TrafficRateExtended) Flat() map[string]string { 9580 return map[string]string{} 9581 } 9582 9583 func (e *TrafficRemarkExtended) Flat() map[string]string { 9584 return map[string]string{} 9585 } 9586 9587 func (e *RedirectIPv4AddressSpecificExtended) Flat() map[string]string { 9588 return map[string]string{} 9589 } 9590 9591 func (e *RedirectIPv6AddressSpecificExtended) Flat() map[string]string { 9592 return map[string]string{} 9593 } 9594 9595 func (e *RedirectFourOctetAsSpecificExtended) Flat() map[string]string { 9596 return map[string]string{} 9597 } 9598 9599 func (e *UnknownExtended) Flat() map[string]string { 9600 return map[string]string{} 9601 } 9602 9603 func (e *TrafficActionExtended) Flat() map[string]string { 9604 return map[string]string{} 9605 } 9606 9607 func (p *PathAttributeExtendedCommunities) Flat() map[string]string { 9608 flat := map[string]string{} 9609 for _, ec := range p.Value { 9610 FlatUpdate(flat, ec.Flat()) 9611 } 9612 return flat 9613 } 9614 9615 func (p *PathAttribute) Flat() map[string]string { 9616 return map[string]string{} 9617 } 9618 9619 func (l *LabeledVPNIPAddrPrefix) Flat() map[string]string { 9620 prefixLen := l.IPAddrPrefixDefault.Length - uint8(8*(l.Labels.Len()+l.RD.Len())) 9621 return map[string]string{ 9622 "Prefix": l.IPAddrPrefixDefault.Prefix.String(), 9623 "PrefixLen": fmt.Sprintf("%d", prefixLen), 9624 "NLRI": l.String(), 9625 "Label": l.Labels.String(), 9626 } 9627 } 9628 9629 func (p *IPAddrPrefixDefault) Flat() map[string]string { 9630 l := strings.Split(p.String(), "/") 9631 if len(l) == 2 { 9632 return map[string]string{ 9633 "Prefix": l[0], 9634 "PrefixLen": l[1], 9635 } 9636 } 9637 return map[string]string{} 9638 } 9639 9640 func (l *EVPNNLRI) Flat() map[string]string { 9641 return map[string]string{} 9642 } 9643 func (l *RouteTargetMembershipNLRI) Flat() map[string]string { 9644 return map[string]string{} 9645 } 9646 func (l *FlowSpecIPv4Unicast) Flat() map[string]string { 9647 return map[string]string{} 9648 } 9649 func (l *FlowSpecIPv4VPN) Flat() map[string]string { 9650 return map[string]string{} 9651 } 9652 func (l *FlowSpecIPv6Unicast) Flat() map[string]string { 9653 return map[string]string{} 9654 } 9655 func (l *FlowSpecIPv6VPN) Flat() map[string]string { 9656 return map[string]string{} 9657 } 9658 func (l *FlowSpecL2VPN) Flat() map[string]string { 9659 return map[string]string{} 9660 } 9661 func (l *OpaqueNLRI) Flat() map[string]string { 9662 return map[string]string{} 9663 } 9664 9665 // Update a Flat representation by adding elements of the second 9666 // one. If two elements use same keys, values are separated with 9667 // ';'. In this case, it returns an error but the update has been 9668 // realized. 9669 func FlatUpdate(f1, f2 map[string]string) error { 9670 conflict := false 9671 for k2, v2 := range f2 { 9672 if v1, ok := f1[k2]; ok { 9673 f1[k2] = v1 + ";" + v2 9674 conflict = true 9675 } else { 9676 f1[k2] = v2 9677 } 9678 } 9679 if conflict { 9680 return fmt.Errorf("Keys conflict") 9681 } else { 9682 return nil 9683 } 9684 }