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  }