github.com/osrg/gobgp/v3@v3.30.0/pkg/packet/bgp/sr_policy.go (about) 1 package bgp 2 3 import ( 4 "encoding/binary" 5 "encoding/json" 6 "fmt" 7 "net" 8 "strconv" 9 ) 10 11 type SRPolicyNLRI struct { 12 PrefixDefault 13 rf RouteFamily 14 Length uint8 15 Distinguisher uint32 16 Color uint32 17 Endpoint []byte 18 } 19 20 const ( 21 // SRPolicyIPv4NLRILen defines IPv4 SR Policy NLRI portion length in bits 22 SRPolicyIPv4NLRILen = 96 23 // SRPolicyIPv6NLRILen defines IPv6 SR Policy NLRI portion length in bits 24 SRPolicyIPv6NLRILen = 192 25 ) 26 27 func (s *SRPolicyNLRI) Flat() map[string]string { 28 return map[string]string{} 29 } 30 31 func (s *SRPolicyNLRI) decodeFromBytes(rf RouteFamily, data []byte, options ...*MarshallingOption) error { 32 if IsAddPathEnabled(true, rf, options) { 33 var err error 34 data, err = s.decodePathIdentifier(data) 35 if err != nil { 36 return err 37 } 38 } 39 switch data[0] { 40 case SRPolicyIPv4NLRILen: 41 s.rf = RF_SR_POLICY_IPv4 42 case SRPolicyIPv6NLRILen: 43 s.rf = RF_SR_POLICY_IPv6 44 default: 45 msg := fmt.Sprintf("Invalid length %d for SR Policy NLRI", len(data)) 46 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 47 } 48 p := 0 49 s.Length = data[p] / 8 50 p++ 51 s.Distinguisher = binary.BigEndian.Uint32(data[p : p+4]) 52 p += 4 53 s.Color = binary.BigEndian.Uint32(data[p : p+4]) 54 p += 4 55 s.Endpoint = data[p:] 56 57 return nil 58 } 59 60 func (s *SRPolicyNLRI) Serialize(options ...*MarshallingOption) ([]byte, error) { 61 buf := make([]byte, 1+s.Length) 62 p := 0 63 buf[0] = s.Length * 8 64 p++ 65 binary.BigEndian.PutUint32(buf[p:p+4], s.Distinguisher) 66 p += 4 67 binary.BigEndian.PutUint32(buf[p:p+4], s.Color) 68 p += 4 69 copy(buf[p:], s.Endpoint) 70 if IsAddPathEnabled(false, s.rf, options) { 71 id, err := s.serializeIdentifier() 72 if err != nil { 73 return nil, err 74 } 75 return append(id, buf...), nil 76 } 77 return buf, nil 78 } 79 80 func (s *SRPolicyNLRI) AFI() uint16 { 81 afi, _ := RouteFamilyToAfiSafi(s.rf) 82 return afi 83 } 84 85 func (s *SRPolicyNLRI) SAFI() uint8 { 86 _, safi := RouteFamilyToAfiSafi(s.rf) 87 return safi 88 } 89 90 func (s *SRPolicyNLRI) Len(options ...*MarshallingOption) int { 91 buf, _ := s.Serialize(options...) 92 return len(buf) 93 } 94 95 func (s *SRPolicyNLRI) String() string { 96 afi, _ := RouteFamilyToAfiSafi(s.rf) 97 var endp string 98 switch afi { 99 case AFI_IP: 100 endp = net.IP(s.Endpoint).To4().String() 101 case AFI_IP6: 102 endp = net.IP(s.Endpoint).To16().String() 103 default: 104 endp = "[" + string(s.Endpoint) + "]" 105 } 106 return fmt.Sprintf("{ Length: %d (bytes), Distinguisher: %d, Color %d, Endpoint: %s }", s.Length, s.Distinguisher, s.Color, endp) 107 } 108 109 func (s *SRPolicyNLRI) MarshalJSON() ([]byte, error) { 110 return json.Marshal(struct { 111 Length uint8 `json:"length"` 112 Distinguisher uint32 `json:"distinguisher"` 113 Color uint32 `json:"color"` 114 Endpoint string `json:"endpoint"` 115 }{ 116 Length: s.Length, 117 Distinguisher: s.Distinguisher, 118 Color: s.Color, 119 Endpoint: string(s.Endpoint), 120 }) 121 } 122 123 type SRPolicyIPv4 struct { 124 SRPolicyNLRI 125 } 126 127 func (s *SRPolicyIPv4) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 128 return s.decodeFromBytes(s.rf, data) 129 } 130 131 func NewSRPolicyIPv4(l uint32, d uint32, c uint32, ep []byte) *SRPolicyIPv4 { 132 return &SRPolicyIPv4{ 133 SRPolicyNLRI: SRPolicyNLRI{ 134 rf: RF_SR_POLICY_IPv4, 135 Length: uint8(l / 8), 136 Distinguisher: d, 137 Color: c, 138 Endpoint: ep, 139 }, 140 } 141 } 142 143 type SRPolicyIPv6 struct { 144 SRPolicyNLRI 145 } 146 147 func (s *SRPolicyIPv6) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { 148 return s.decodeFromBytes(s.rf, data) 149 } 150 151 func NewSRPolicyIPv6(l uint32, d uint32, c uint32, ep []byte) *SRPolicyIPv6 { 152 return &SRPolicyIPv6{ 153 SRPolicyNLRI: SRPolicyNLRI{ 154 rf: RF_SR_POLICY_IPv6, 155 Length: uint8(l / 8), 156 Distinguisher: d, 157 Color: c, 158 Endpoint: ep, 159 }, 160 } 161 } 162 163 type TunnelEncapSubTLVSRPreference struct { 164 TunnelEncapSubTLV 165 Flags uint8 166 Preference uint32 167 } 168 169 func (t *TunnelEncapSubTLVSRPreference) DecodeFromBytes(data []byte) error { 170 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 171 if err != nil { 172 return err 173 } 174 // Second byte carries the length of SR Preference SubTLV 175 if t.Length != 6 { 176 msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRPreference length: %d", t.Length) 177 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 178 } 179 t.Flags = value[0] 180 t.Preference = binary.BigEndian.Uint32(value[2:6]) 181 return nil 182 } 183 184 func (t *TunnelEncapSubTLVSRPreference) Serialize() ([]byte, error) { 185 buf := make([]byte, 6) 186 buf[0] = t.Flags 187 binary.BigEndian.PutUint32(buf[2:6], t.Preference) 188 return t.TunnelEncapSubTLV.Serialize(buf[:]) 189 } 190 191 func (t *TunnelEncapSubTLVSRPreference) String() string { 192 return fmt.Sprintf("{Flags: 0x%02x, Preference: %d}", t.Flags, t.Preference) 193 } 194 195 func (t *TunnelEncapSubTLVSRPreference) MarshalJSON() ([]byte, error) { 196 return json.Marshal(struct { 197 Type EncapSubTLVType `json:"type"` 198 Flags uint8 `json:"flags"` 199 Preference uint32 `json:"preference"` 200 }{ 201 Type: t.Type, 202 Flags: t.Flags, 203 Preference: t.Preference, 204 }) 205 } 206 207 func NewTunnelEncapSubTLVSRPreference(flags uint32, preference uint32) *TunnelEncapSubTLVSRPreference { 208 return &TunnelEncapSubTLVSRPreference{ 209 TunnelEncapSubTLV: TunnelEncapSubTLV{ 210 Type: ENCAP_SUBTLV_TYPE_SRPREFERENCE, 211 Length: 6, 212 }, 213 Flags: uint8(flags), 214 Preference: preference, 215 } 216 } 217 218 type TunnelEncapSubTLVSRPriority struct { 219 TunnelEncapSubTLV 220 Priority uint8 221 } 222 223 func (t *TunnelEncapSubTLVSRPriority) DecodeFromBytes(data []byte) error { 224 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 225 if err != nil { 226 return err 227 } 228 // Second byte carries the length of SR Preference SubTLV 229 if t.Length != 2 { 230 msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRPriority length: %d", t.Length) 231 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 232 } 233 t.Priority = value[0] 234 return nil 235 } 236 237 func (t *TunnelEncapSubTLVSRPriority) Serialize() ([]byte, error) { 238 buf := make([]byte, 1+1) 239 buf[0] = t.Priority 240 return t.TunnelEncapSubTLV.Serialize(buf[:]) 241 } 242 243 func (t *TunnelEncapSubTLVSRPriority) String() string { 244 return fmt.Sprintf("{Priority: %d}", t.Priority) 245 } 246 247 func (t *TunnelEncapSubTLVSRPriority) MarshalJSON() ([]byte, error) { 248 return json.Marshal(struct { 249 Type EncapSubTLVType `json:"type"` 250 Priority uint8 `json:"priority"` 251 }{ 252 Type: t.Type, 253 Priority: t.Priority, 254 }) 255 } 256 257 func NewTunnelEncapSubTLVSRPriority(priority uint8) *TunnelEncapSubTLVSRPriority { 258 return &TunnelEncapSubTLVSRPriority{ 259 TunnelEncapSubTLV: TunnelEncapSubTLV{ 260 Type: ENCAP_SUBTLV_TYPE_SRPRIORITY, 261 Length: 2, 262 }, 263 Priority: priority, 264 } 265 } 266 267 type TunnelEncapSubTLVSRCandidatePathName struct { 268 TunnelEncapSubTLV 269 CandidatePathName string 270 } 271 272 func (t *TunnelEncapSubTLVSRCandidatePathName) DecodeFromBytes(data []byte) error { 273 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 274 if err != nil { 275 return err 276 } 277 // Skip Reserved byte 278 t.CandidatePathName = string(value[1:t.TunnelEncapSubTLV.Len()]) 279 return nil 280 } 281 282 func (t *TunnelEncapSubTLVSRCandidatePathName) Serialize() ([]byte, error) { 283 buf := make([]byte, 1+len(t.CandidatePathName)) 284 copy(buf[1:], t.CandidatePathName) 285 return t.TunnelEncapSubTLV.Serialize(buf[:]) 286 } 287 288 func (t *TunnelEncapSubTLVSRCandidatePathName) String() string { 289 return fmt.Sprintf("{Candidate Path Name: %s}", t.CandidatePathName) 290 } 291 292 func (t *TunnelEncapSubTLVSRCandidatePathName) MarshalJSON() ([]byte, error) { 293 return json.Marshal(struct { 294 Type EncapSubTLVType `json:"type"` 295 CandidatePathName string `json:"candidate_path_name"` 296 }{ 297 Type: t.Type, 298 CandidatePathName: t.CandidatePathName, 299 }) 300 } 301 302 func NewTunnelEncapSubTLVSRCandidatePathName(cpn string) *TunnelEncapSubTLVSRCandidatePathName { 303 return &TunnelEncapSubTLVSRCandidatePathName{ 304 TunnelEncapSubTLV: TunnelEncapSubTLV{ 305 Type: ENCAP_SUBTLV_TYPE_SRCANDIDATE_PATH_NAME, 306 Length: uint16(len(cpn) + 1), // length of Candidate Path name string + 1 Reserved byte 307 }, 308 CandidatePathName: cpn, 309 } 310 } 311 312 type SRENLPValue uint8 313 314 const ( 315 // ENLPType1 Indicates to push an IPv4 Explicit NULL label on an unlabeled IPv4 316 // packet, but do not push an IPv6 Explicit NULL label on an 317 // unlabeled IPv6 packet. 318 ENLPType1 SRENLPValue = 1 319 // ENLPType2 Indicates to push an IPv6 Explicit NULL label on an unlabeled IPv6 320 // packet, but do not push an IPv4 Explicit NULL label on an 321 // unlabeled IPv4 packet. 322 ENLPType2 SRENLPValue = 2 323 // ENLPType3 Indicates to push an IPv4 Explicit NULL label on an unlabeled IPv4 324 // packet, and push an IPv6 Explicit NULL label on an unlabeled 325 // IPv6 packet. 326 ENLPType3 SRENLPValue = 3 327 // ENLPType4 Indicates to not push an Explicit NULL label. 328 ENLPType4 SRENLPValue = 4 329 ) 330 331 type TunnelEncapSubTLVSRENLP struct { 332 TunnelEncapSubTLV 333 Flags uint8 334 ENLP SRENLPValue 335 } 336 337 func (t *TunnelEncapSubTLVSRENLP) DecodeFromBytes(data []byte) error { 338 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 339 if err != nil { 340 return err 341 } 342 // Second byte carries the length of SR Preference SubTLV 343 if t.Length != 3 { 344 msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRENLP length: %d", t.Length) 345 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 346 } 347 t.Flags = value[0] 348 switch SRENLPValue(value[2]) { 349 case ENLPType1: 350 case ENLPType2: 351 case ENLPType3: 352 case ENLPType4: 353 default: 354 msg := fmt.Sprintf("Invalid ENLP Type: %d", value[2]) 355 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 356 } 357 t.ENLP = SRENLPValue(value[2]) 358 return nil 359 } 360 361 func (t *TunnelEncapSubTLVSRENLP) Serialize() ([]byte, error) { 362 buf := make([]byte, t.Length) 363 buf[0] = t.Flags 364 buf[2] = byte(t.ENLP) 365 return t.TunnelEncapSubTLV.Serialize(buf[:]) 366 } 367 368 func (t *TunnelEncapSubTLVSRENLP) String() string { 369 return fmt.Sprintf("{Flags: 0x%02x, ENLP Type: %d}", t.Flags, t.ENLP) 370 } 371 372 func (t *TunnelEncapSubTLVSRENLP) MarshalJSON() ([]byte, error) { 373 return json.Marshal(struct { 374 Type EncapSubTLVType `json:"type"` 375 Flags uint8 `json:"flags"` 376 ENLP uint8 `json:"enlp"` 377 }{ 378 Type: t.Type, 379 Flags: t.Flags, 380 ENLP: uint8(t.ENLP), 381 }) 382 } 383 384 func NewTunnelEncapSubTLVSRENLP(flags uint32, enlp SRENLPValue) *TunnelEncapSubTLVSRENLP { 385 return &TunnelEncapSubTLVSRENLP{ 386 TunnelEncapSubTLV: TunnelEncapSubTLV{ 387 Type: ENCAP_SUBTLV_TYPE_SRENLP, 388 Length: 3, 389 }, 390 Flags: uint8(flags), 391 ENLP: enlp, 392 } 393 } 394 395 type BSID struct { 396 Value []byte 397 } 398 399 func (b *BSID) String() string { 400 switch len(b.Value) { 401 case 0: 402 return "n/a" 403 case 4: 404 bsid := binary.BigEndian.Uint32(b.Value) 405 bsid >>= 12 406 return strconv.Itoa(int(bsid)) 407 case 16: 408 return net.IP(b.Value).To16().String() 409 default: 410 return "invalid" 411 } 412 } 413 414 func (b *BSID) Serialize() []byte { 415 return b.Value 416 } 417 func (b *BSID) Len() int { 418 return len(b.Value) 419 } 420 421 func NewBSID(v []byte) (*BSID, error) { 422 var bsid *BSID 423 switch len(v) { 424 case 0: 425 case 4: 426 t := binary.BigEndian.Uint32(v) 427 t <<= 12 428 bsid = &BSID{ 429 Value: make([]byte, len(v)), 430 } 431 binary.BigEndian.PutUint32(bsid.Value, t) 432 case 16: 433 bsid = &BSID{ 434 Value: make([]byte, len(v)), 435 } 436 copy(bsid.Value, v) 437 default: 438 return nil, fmt.Errorf("invalid length %d", len(v)) 439 } 440 441 return bsid, nil 442 } 443 444 type TunnelEncapSubTLVSRBSID struct { 445 TunnelEncapSubTLV 446 Flags uint8 447 BSID *BSID 448 } 449 450 func (t *TunnelEncapSubTLVSRBSID) DecodeFromBytes(data []byte) error { 451 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 452 if err != nil { 453 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 454 } 455 // Check Sub TLV length, only 3 possible length are allowed 456 switch t.Length { 457 case 2: // No BSID, do not initializing BSID struct 458 case 6: 459 fallthrough 460 case 18: 461 t.BSID = &BSID{ 462 Value: make([]byte, t.Length-2), 463 } 464 copy(t.BSID.Value, value[2:t.Length]) 465 default: 466 msg := fmt.Sprintf("Invalid TunnelEncapSubTLVSRBSID length: %d", t.Length) 467 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 468 } 469 t.Flags = value[0] 470 return nil 471 } 472 473 func (t *TunnelEncapSubTLVSRBSID) Serialize() ([]byte, error) { 474 l := 2 475 if t.BSID != nil { 476 l += t.BSID.Len() 477 } 478 buf := make([]byte, l) // 1st byte Flags, 2nd byte Reserved, 3rd+ BSID 479 buf[0] = t.Flags 480 if t.BSID != nil { 481 bsid := t.BSID.Serialize() 482 copy(buf[2:], bsid) 483 } 484 return t.TunnelEncapSubTLV.Serialize(buf[:]) 485 } 486 487 func (t *TunnelEncapSubTLVSRBSID) String() string { 488 return fmt.Sprintf("{S-Flag: %t, I-Flag: %t, BSID: %s}", t.Flags&0x80 == 0x80, t.Flags&0x40 == 0x40, t.BSID.String()) 489 } 490 491 func (t *TunnelEncapSubTLVSRBSID) MarshalJSON() ([]byte, error) { 492 return json.Marshal(struct { 493 Type EncapSubTLVType `json:"type"` 494 Flags uint8 `json:"flags"` 495 BSID string `json:"binding_sid,omitempty"` 496 }{ 497 Type: t.Type, 498 Flags: t.Flags, 499 BSID: t.BSID.String(), 500 }) 501 } 502 503 type TunnelEncapSubTLVSRv6BSID struct { 504 TunnelEncapSubTLV 505 Flags uint8 506 BSID *BSID 507 EPBAS *SRv6EndpointBehaviorStructure 508 } 509 510 func (t *TunnelEncapSubTLVSRv6BSID) DecodeFromBytes(data []byte) error { 511 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 512 if err != nil { 513 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 514 } 515 t.Flags = value[0] 516 t.BSID, err = NewBSID(value[2:t.Length]) 517 if err != nil { 518 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 519 } 520 return nil 521 } 522 523 func (t *TunnelEncapSubTLVSRv6BSID) Serialize() ([]byte, error) { 524 buf := make([]byte, t.Length) 525 buf[0] = t.Flags 526 copy(buf[2:t.BSID.Len()], t.BSID.Serialize()) 527 return t.TunnelEncapSubTLV.Serialize(buf[:]) 528 } 529 530 func (t *TunnelEncapSubTLVSRv6BSID) String() string { 531 return fmt.Sprintf("{S-Flag: %t, I-Flag: %t, B-Flag: %t, BSID: %s}", t.Flags&0x80 == 0x80, t.Flags&0x40 == 0x40, t.Flags&0x20 == 0x20, t.BSID.String()) 532 } 533 534 func (t *TunnelEncapSubTLVSRv6BSID) MarshalJSON() ([]byte, error) { 535 return json.Marshal(struct { 536 Type EncapSubTLVType `json:"type"` 537 Flags uint8 `json:"flags"` 538 BSID string `json:"binding_sid,omitempty"` 539 }{ 540 Type: t.Type, 541 Flags: t.Flags, 542 BSID: t.BSID.String(), 543 }) 544 } 545 546 // SegmentType defines a type of Segment in Segment List 547 type SegmentType int 548 549 const ( 550 // TypeA Segment Sub-TLV encodes a single SR-MPLS SID 551 TypeA SegmentType = 1 552 // TypeB Segment Sub-TLV encodes a single SRv6 SID. 553 TypeB SegmentType = 13 554 // TypeC Segment Sub-TLV encodes an IPv4 node address, SR Algorithm 555 // and an optional SR-MPLS SID 556 TypeC SegmentType = 3 557 // TypeD Segment Sub-TLV encodes an IPv6 node address, SR Algorithm 558 // and an optional SR-MPLS SID. 559 TypeD SegmentType = 4 560 // TypeE Segment Sub-TLV encodes an IPv4 node address, a local 561 // interface Identifier (Local Interface ID) and an optional SR-MPLS 562 // SID. 563 TypeE SegmentType = 5 564 // TypeF Segment Sub-TLV encodes an adjacency local address, an 565 // adjacency remote address and an optional SR-MPLS SID. 566 TypeF SegmentType = 6 567 // TypeG Segment Sub-TLV encodes an IPv6 Link Local adjacency with 568 // IPv6 local node address, a local interface identifier (Local 569 // Interface ID), IPv6 remote node address , a remote interface 570 // identifier (Remote Interface ID) and an optional SR-MPLS SID. 571 TypeG SegmentType = 7 572 // TypeH Segment Sub-TLV encodes an adjacency local address, an 573 // adjacency remote address and an optional SR-MPLS SID. 574 TypeH SegmentType = 8 575 // TypeI Segment Sub-TLV encodes an IPv6 node address, SR Algorithm 576 // and an optional SRv6 SID. 577 TypeI SegmentType = 14 578 // TypeJ Segment Sub-TLV encodes an IPv6 Link Local adjacency with 579 // local node address, a local interface identifier (Local Interface 580 // ID), remote IPv6 node address, a remote interface identifier (Remote 581 // Interface ID) and an optional SRv6 SID. 582 TypeJ SegmentType = 15 583 // TypeK Segment Sub-TLV encodes an adjacency local address, an 584 // adjacency remote address and an optional SRv6 SID. 585 TypeK SegmentType = 16 586 ) 587 588 // Weight sub-TLV specifies the weight associated to a given segment list. 589 type SegmentListWeight struct { 590 TunnelEncapSubTLV 591 Flags uint8 592 Weight uint32 593 } 594 595 func (s *SegmentListWeight) DecodeFromBytes(data []byte) error { 596 value, err := s.TunnelEncapSubTLV.DecodeFromBytes(data) 597 if err != nil { 598 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 599 } 600 s.Flags = value[0] 601 s.Weight = binary.BigEndian.Uint32(value[2:6]) 602 return nil 603 } 604 func (s *SegmentListWeight) Serialize() ([]byte, error) { 605 buf := make([]byte, 6) 606 buf[0] = s.Flags 607 binary.BigEndian.PutUint32(buf[2:6], s.Weight) 608 return s.TunnelEncapSubTLV.Serialize(buf) 609 } 610 func (s *SegmentListWeight) String() string { 611 return fmt.Sprintf("{Flags: 0x%02x, Weight: %d}", s.Flags, s.Weight) 612 } 613 614 func (s *SegmentListWeight) MarshalJSON() ([]byte, error) { 615 return json.Marshal(struct { 616 Type EncapSubTLVType `json:"type"` 617 Flags uint8 `json:"flags"` 618 Weight uint32 `json:"weight,omitempty"` 619 }{ 620 Type: s.Type, 621 Flags: s.Flags, 622 Weight: s.Weight, 623 }) 624 } 625 626 type SegmentTypeA struct { 627 TunnelEncapSubTLV 628 Flags uint8 629 Label uint32 630 } 631 632 func (s *SegmentTypeA) DecodeFromBytes(data []byte) error { 633 value, err := s.TunnelEncapSubTLV.DecodeFromBytes(data) 634 if err != nil { 635 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 636 } 637 s.Flags = value[0] 638 s.Label = binary.BigEndian.Uint32(value[2:6]) 639 return nil 640 } 641 func (s *SegmentTypeA) Serialize() ([]byte, error) { 642 buf := make([]byte, 6) 643 buf[0] = s.Flags 644 binary.BigEndian.PutUint32(buf[2:6], s.Label) 645 return s.TunnelEncapSubTLV.Serialize(buf) 646 } 647 func (s *SegmentTypeA) String() string { 648 return fmt.Sprintf("{V-flag: %t, A-flag:, %t S-flag: %t, B-flag: %t, Label: %d TC: %d S: %t TTL: %d}", 649 s.Flags&0x80 == 0x80, s.Flags&0x40 == 0x40, s.Flags&0x20 == 0x20, s.Flags&0x10 == 0x10, 650 s.Label>>12, s.Label&0x00000e00>>9, s.Label&0x00000100 == 0x00000100, s.Label&0x000000ff) 651 } 652 653 func (s *SegmentTypeA) MarshalJSON() ([]byte, error) { 654 return json.Marshal(struct { 655 Type EncapSubTLVType `json:"type"` 656 VFlag bool `json:"v_flag"` 657 AFlag bool `json:"a_flag"` 658 SFlag bool `json:"s_flag"` 659 BFlag bool `json:"b_flag"` 660 Label uint32 `json:"label"` 661 TC uint8 `json:"tc"` 662 S bool `json:"s"` 663 TTL uint8 `json:"ttl"` 664 }{ 665 Type: s.Type, 666 VFlag: s.Flags&0x80 == 0x80, 667 AFlag: s.Flags&0x40 == 0x40, 668 SFlag: s.Flags&0x20 == 0x20, 669 BFlag: s.Flags&0x10 == 0x10, 670 Label: s.Label >> 12, 671 TC: uint8(s.Label & 0x00000e00 >> 9), 672 S: s.Label&0x00000100 == 0x00000100, 673 TTL: uint8(s.Label & 0x000000ff), 674 }) 675 } 676 677 //go:generate go run internal/generate.go SRBehavior 678 //go:generate stringer -type=SRBehavior 679 type SRBehavior int32 680 681 type SRv6EndpointBehaviorStructure struct { 682 Behavior SRBehavior 683 BlockLen uint8 684 NodeLen uint8 685 FuncLen uint8 686 ArgLen uint8 687 } 688 689 func (s *SRv6EndpointBehaviorStructure) DecodeFromBytes(data []byte) error { 690 if len(data) < 8 { 691 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Malformed BGP message") 692 } 693 behavior := binary.BigEndian.Uint16(data[0:2]) 694 s.Behavior = SRBehavior(behavior) 695 s.BlockLen = data[4] 696 s.NodeLen = data[5] 697 s.FuncLen = data[6] 698 s.ArgLen = data[7] 699 return nil 700 } 701 702 func (s *SRv6EndpointBehaviorStructure) Serialize() ([]byte, error) { 703 buf := make([]byte, 8) 704 binary.BigEndian.PutUint16(buf[0:2], uint16(s.Behavior)) 705 buf[4] = s.BlockLen 706 buf[5] = s.NodeLen 707 buf[6] = s.FuncLen 708 buf[7] = s.ArgLen 709 return buf, nil 710 } 711 712 func (s *SRv6EndpointBehaviorStructure) String() string { 713 return fmt.Sprintf("{Behavior: %s, BlockLen: %d, NodeLen: %d, FuncLen: %d, ArgLen: %d}", 714 s.Behavior.String(), s.BlockLen, s.NodeLen, s.FuncLen, s.ArgLen) 715 } 716 717 func (s *SRv6EndpointBehaviorStructure) MarshalJSON() ([]byte, error) { 718 return json.Marshal(struct { 719 Behavior SRBehavior `json:"behavior"` 720 BlockLen uint8 `json:"block_Len"` 721 NodeLen uint8 `json:"node_len"` 722 FuncLen uint8 `json:"func_len"` 723 ArgLen uint8 `json:"arg_len"` 724 }{ 725 Behavior: s.Behavior, 726 BlockLen: s.BlockLen, 727 NodeLen: s.NodeLen, 728 FuncLen: s.FuncLen, 729 ArgLen: s.ArgLen, 730 }) 731 } 732 733 type SegmentTypeB struct { 734 TunnelEncapSubTLV 735 Flags uint8 736 SID []byte 737 SRv6EBS *SRv6EndpointBehaviorStructure 738 } 739 740 func (s *SegmentTypeB) DecodeFromBytes(data []byte) error { 741 value, err := s.TunnelEncapSubTLV.DecodeFromBytes(data) 742 if err != nil { 743 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 744 } 745 if len(value) < 18 { 746 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, "Malformed BGP message") 747 } 748 s.Flags = value[0] 749 s.SID = value[2:18] 750 751 if len(value) == 26 { 752 s.SRv6EBS = &SRv6EndpointBehaviorStructure{} 753 err = s.SRv6EBS.DecodeFromBytes(value[18:]) 754 if err != nil { 755 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 756 } 757 } 758 return nil 759 } 760 func (s *SegmentTypeB) Serialize() ([]byte, error) { 761 buf := make([]byte, 18) 762 buf[0] = s.Flags 763 copy(buf[2:], s.SID) 764 if s.SRv6EBS != nil { 765 if ebs, _ := s.SRv6EBS.Serialize(); ebs != nil { 766 buf = append(buf, ebs...) 767 } 768 } 769 770 return s.TunnelEncapSubTLV.Serialize(buf) 771 } 772 func (s *SegmentTypeB) String() string { 773 if s.SRv6EBS == nil { 774 return fmt.Sprintf("{V-flag: %t, A-flag:, %t S-flag: %t, B-flag: %t, Sid: %s}", 775 s.Flags&0x80 == 0x80, s.Flags&0x40 == 0x40, s.Flags&0x20 == 0x20, s.Flags&0x10 == 0x10, net.IP(s.SID).To16().String()) 776 } else { 777 return fmt.Sprintf("{V-flag: %t, A-flag:, %t S-flag: %t, B-flag: %t, Sid: %s, Ebs: %s}", 778 s.Flags&0x80 == 0x80, s.Flags&0x40 == 0x40, s.Flags&0x20 == 0x20, s.Flags&0x10 == 0x10, net.IP(s.SID).To16().String(), 779 s.SRv6EBS.String()) 780 } 781 782 } 783 784 func (s *SegmentTypeB) MarshalJSON() ([]byte, error) { 785 return json.Marshal(struct { 786 Type EncapSubTLVType `json:"type"` 787 VFlag bool `json:"v_flag"` 788 AFlag bool `json:"a_flag"` 789 SFlag bool `json:"s_flag"` 790 BFlag bool `json:"b_flag"` 791 Sid string `json:"sid"` 792 SRv6EBS *SRv6EndpointBehaviorStructure `json:"endpointBehaviorStructure"` 793 }{ 794 Type: s.Type, 795 VFlag: s.Flags&0x80 == 0x80, 796 AFlag: s.Flags&0x40 == 0x40, 797 SFlag: s.Flags&0x20 == 0x20, 798 BFlag: s.Flags&0x10 == 0x10, 799 Sid: net.IP(s.SID).To16().String(), 800 SRv6EBS: s.SRv6EBS, 801 }) 802 } 803 804 const ( 805 // SegmentListSubTLVWeight defines code for Segment List's Weight sub-TLV 806 SegmentListSubTLVWeight = 9 807 ) 808 809 type TunnelEncapSubTLVSRSegmentList struct { 810 TunnelEncapSubTLV 811 Weight *SegmentListWeight 812 Segments []TunnelEncapSubTLVInterface 813 } 814 815 func (t *TunnelEncapSubTLVSRSegmentList) DecodeFromBytes(data []byte) error { 816 value, err := t.TunnelEncapSubTLV.DecodeFromBytes(data) 817 if err != nil { 818 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 819 } 820 if len(value) < 1 { 821 return NewMessageError(BGP_ERROR_MESSAGE_HEADER_ERROR, BGP_ERROR_SUB_BAD_MESSAGE_LENGTH, nil, "Malformed BGP message") 822 } 823 // Skip reserved byte to access inner SubTLV type 824 value = value[1:] 825 var segments []TunnelEncapSubTLVInterface 826 p := 0 827 for p < t.TunnelEncapSubTLV.Len()-4 { 828 var segment TunnelEncapSubTLVInterface 829 switch SegmentType(value[0]) { 830 case SegmentListSubTLVWeight: 831 t.Weight = &SegmentListWeight{} 832 if err := t.Weight.DecodeFromBytes(value); err != nil { 833 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 834 } 835 p += t.Weight.TunnelEncapSubTLV.Len() 836 value = value[t.Weight.TunnelEncapSubTLV.Len():] 837 continue 838 case TypeA: 839 segment = &SegmentTypeA{} 840 if err := segment.DecodeFromBytes(value); err != nil { 841 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 842 } 843 case TypeB: 844 segment = &SegmentTypeB{} 845 if err := segment.DecodeFromBytes(value); err != nil { 846 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, err.Error()) 847 } 848 case TypeC: 849 fallthrough 850 case TypeD: 851 fallthrough 852 case TypeE: 853 fallthrough 854 case TypeF: 855 fallthrough 856 case TypeG: 857 fallthrough 858 case TypeH: 859 fallthrough 860 case TypeI: 861 fallthrough 862 case TypeJ: 863 fallthrough 864 case TypeK: 865 msg := fmt.Sprintf("Invalid SR Policy Segment SubTLV %d is not yet supported", value[0]) 866 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 867 default: 868 msg := fmt.Sprintf("Invalid SR Policy Segment List SubTLV %d", value[0]) 869 return NewMessageError(BGP_ERROR_UPDATE_MESSAGE_ERROR, BGP_ERROR_SUB_MALFORMED_ATTRIBUTE_LIST, nil, msg) 870 } 871 segments = append(segments, segment) 872 p += segment.Len() 873 value = value[segment.Len():] 874 } 875 if len(segments) == 0 { 876 t.Segments = nil 877 } else { 878 t.Segments = segments 879 } 880 return nil 881 } 882 883 func (t *TunnelEncapSubTLVSRSegmentList) Serialize() ([]byte, error) { 884 buf := make([]byte, 0) 885 // Add reserved byte 886 buf = append(buf, 0x0) 887 if t.Weight != nil { 888 wbuf, err := t.Weight.Serialize() 889 if err != nil { 890 return nil, err 891 } 892 buf = append(buf, wbuf...) 893 } 894 for _, s := range t.Segments { 895 sbuf, err := s.Serialize() 896 if err != nil { 897 return nil, err 898 } 899 buf = append(buf, sbuf...) 900 } 901 return t.TunnelEncapSubTLV.Serialize(buf[:]) 902 } 903 904 func (t *TunnelEncapSubTLVSRSegmentList) String() string { 905 msg := "{" 906 if t.Weight != nil { 907 msg += "Weight: " + t.Weight.String() + "," 908 } 909 msg += "Segment List: [ " 910 for _, s := range t.Segments { 911 msg += s.String() + "," 912 } 913 msg += " ] }" 914 return msg 915 } 916 917 func (t *TunnelEncapSubTLVSRSegmentList) MarshalJSON() ([]byte, error) { 918 return json.Marshal(struct { 919 Type EncapSubTLVType `json:"type"` 920 Weight *SegmentListWeight 921 Segments []TunnelEncapSubTLVInterface 922 }{ 923 Type: t.Type, 924 Weight: t.Weight, 925 Segments: t.Segments, 926 }) 927 }