summaryrefslogtreecommitdiffhomepage
path: root/pkg/packet/bgp/prefix_sid.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/packet/bgp/prefix_sid.go')
-rw-r--r--pkg/packet/bgp/prefix_sid.go270
1 files changed, 234 insertions, 36 deletions
diff --git a/pkg/packet/bgp/prefix_sid.go b/pkg/packet/bgp/prefix_sid.go
index 1642b87f..6a3f37b9 100644
--- a/pkg/packet/bgp/prefix_sid.go
+++ b/pkg/packet/bgp/prefix_sid.go
@@ -11,20 +11,6 @@ const (
prefixSIDtlvHdrLen = 4
)
-// PrefixSIDTLVInterface defines standard set of methods to handle Prefix SID attribute's TLVs
-type PrefixSIDTLVInterface interface {
- Len() int
- DecodeFromBytes([]byte) error
- Serialize() ([]byte, error)
- String() string
- MarshalJSON() ([]byte, error)
-}
-
-type PathAttributePrefixSID struct {
- PathAttribute
- TLVs []PrefixSIDTLVInterface
-}
-
type TLVType uint8
type TLV struct {
@@ -34,7 +20,7 @@ type TLV struct {
}
func (s *TLV) Len() int {
- return int(s.Length) + tlvHdrLen - 1
+ return int(s.Length) + tlvHdrLen - 1 // Extra reserved byte in the header
}
func (s *TLV) Serialize(value []byte) ([]byte, error) {
@@ -70,8 +56,21 @@ func (s *TLV) DecodeFromBytes(data []byte) ([]byte, error) {
return data[prefixSIDtlvHdrLen:s.Len()], nil
}
+// PrefixSIDTLVInterface defines standard set of methods to handle Prefix SID attribute's TLVs
+type PrefixSIDTLVInterface interface {
+ Len() int
+ DecodeFromBytes([]byte) error
+ Serialize() ([]byte, error)
+ String() string
+ MarshalJSON() ([]byte, error)
+}
+
type PrefixSIDAttribute struct {
- TLV
+ TLVs []PrefixSIDTLVInterface
+}
+
+type PathAttributePrefixSID struct {
+ PathAttribute
TLVs []PrefixSIDTLVInterface
}
@@ -91,8 +90,8 @@ func (p *PathAttributePrefixSID) DecodeFromBytes(data []byte, options ...*Marsha
var tlv PrefixSIDTLVInterface
switch t.Type {
case 5:
- tlv = &PrefixSIDType5{
- ServiceTLVs: make([]PrefixSIDTLVInterface, 0),
+ tlv = &SRv6L3ServiceAttribute{
+ SubTLVs: make([]PrefixSIDTLVInterface, 0),
}
default:
tlvs = tlvs[t.Len():]
@@ -140,24 +139,40 @@ func (p *PathAttributePrefixSID) MarshalJSON() ([]byte, error) {
}{
p.GetType(),
p.GetFlags(),
- // TODO sbezverk
- PrefixSIDAttribute{},
+ *p.Extract(),
})
}
-// PrefixSIDType5 defines the structure of
-type PrefixSIDType5 struct {
+func (p *PathAttributePrefixSID) Extract() *PrefixSIDAttribute {
+ psid := &PrefixSIDAttribute{
+ TLVs: make([]PrefixSIDTLVInterface, 0),
+ }
+
+ for _, tlv := range p.TLVs {
+ psid.TLVs = append(psid.TLVs, tlv)
+ }
+
+ return psid
+}
+
+// SRv6L3Service defines the structure of SRv6 L3 Service object
+type SRv6L3Service struct {
+ SubTLVs []PrefixSIDTLVInterface
+}
+
+// SRv6L3ServiceAttribute defines the structure of SRv6 L3 Service attribute
+type SRv6L3ServiceAttribute struct {
TLV
- ServiceTLVs []PrefixSIDTLVInterface
+ SubTLVs []PrefixSIDTLVInterface
}
-func (s *PrefixSIDType5) Len() int {
+func (s *SRv6L3ServiceAttribute) Len() int {
return int(s.Length) + prefixSIDtlvHdrLen
}
-func (s *PrefixSIDType5) Serialize() ([]byte, error) {
+func (s *SRv6L3ServiceAttribute) Serialize() ([]byte, error) {
buf := make([]byte, 0)
- for _, tlv := range s.ServiceTLVs {
+ for _, tlv := range s.SubTLVs {
s, err := tlv.Serialize()
if err != nil {
return nil, err
@@ -167,7 +182,7 @@ func (s *PrefixSIDType5) Serialize() ([]byte, error) {
return s.TLV.Serialize(buf)
}
-func (s *PrefixSIDType5) DecodeFromBytes(data []byte) error {
+func (s *SRv6L3ServiceAttribute) DecodeFromBytes(data []byte) error {
stlvs, err := s.TLV.DecodeFromBytes(data)
if err != nil {
return err
@@ -195,22 +210,42 @@ func (s *PrefixSIDType5) DecodeFromBytes(data []byte) error {
return err
}
stlvs = stlvs[t.Len():]
- s.ServiceTLVs = append(s.ServiceTLVs, stlv)
+ s.SubTLVs = append(s.SubTLVs, stlv)
}
return nil
}
-func (s *PrefixSIDType5) MarshalJSON() ([]byte, error) {
- return nil, nil
+func (s *SRv6L3ServiceAttribute) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type TLVType `json:"type"`
+ SRv6L3Service
+ }{
+ s.Type,
+ *s.Extract(),
+ })
}
-func (s *PrefixSIDType5) String() string {
- return ""
+func (s *SRv6L3ServiceAttribute) String() string {
+ var buf bytes.Buffer
+
+ for _, tlv := range s.SubTLVs {
+ buf.WriteString(fmt.Sprintf("%s ", tlv.String()))
+ }
+
+ return fmt.Sprintf("{SRv6 L3 Service Attribute: %s}", buf.String())
}
-func (s *PrefixSIDType5) Extract() string {
- return ""
+func (s *SRv6L3ServiceAttribute) Extract() *SRv6L3Service {
+ l3 := &SRv6L3Service{
+ SubTLVs: make([]PrefixSIDTLVInterface, 0),
+ }
+
+ for _, tlv := range s.SubTLVs {
+ l3.SubTLVs = append(l3.SubTLVs, tlv)
+ }
+
+ return l3
}
const (
@@ -256,6 +291,13 @@ func (s *SubTLV) DecodeFromBytes(data []byte) ([]byte, error) {
return data[subTLVHdrLen:s.Len()], nil
}
+type SRv6InformationSTLV struct {
+ SID []byte
+ Flags uint8
+ EndpointBehavior uint16
+ SubSubTLVs []PrefixSIDTLVInterface
+}
+
// SRv6InformationSubTLV defines a structure of SRv6 Information Sub TLV (type 1) object
// https://tools.ietf.org/html/draft-dawra-bess-srv6-services-02#section-2.1.1
type SRv6InformationSubTLV struct {
@@ -343,9 +385,165 @@ func (s *SRv6InformationSubTLV) DecodeFromBytes(data []byte) error {
}
func (s *SRv6InformationSubTLV) MarshalJSON() ([]byte, error) {
- return nil, nil
+ return json.Marshal(struct {
+ Type SubTLVType `json:"type"`
+ SRv6InformationSTLV
+ }{
+ s.Type,
+ *s.Extract(),
+ })
}
func (s *SRv6InformationSubTLV) String() string {
- return ""
+ var buf bytes.Buffer
+ buf.WriteString(fmt.Sprintf("SID: %s ", string(s.SID)))
+ buf.WriteString(fmt.Sprintf("Flag: %d ", s.Flags))
+ buf.WriteString(fmt.Sprintf("Endpoint Behavior: %d ", s.EndpointBehavior))
+ for _, tlv := range s.SubSubTLVs {
+ buf.WriteString(fmt.Sprintf("%s ", tlv.String()))
+ }
+
+ return fmt.Sprintf("{SRv6 Information Sub TLV: %s}", buf.String())
+}
+
+func (s *SRv6InformationSubTLV) Extract() *SRv6InformationSTLV {
+ info := &SRv6InformationSTLV{
+ SID: s.SID,
+ Flags: s.Flags,
+ EndpointBehavior: s.EndpointBehavior,
+ SubSubTLVs: make([]PrefixSIDTLVInterface, 0),
+ }
+
+ for _, tlv := range s.SubSubTLVs {
+ info.SubSubTLVs = append(info.SubSubTLVs, tlv)
+ }
+
+ return info
+}
+
+const (
+ subSubTLVHdrLen = 3
+)
+
+type SubSubTLVType uint8
+
+type SubSubTLV struct {
+ Type SubSubTLVType
+ Length uint16
+}
+
+func (s *SubSubTLV) Len() int {
+ return int(s.Length) + subSubTLVHdrLen
+}
+
+func (s *SubSubTLV) Serialize(value []byte) ([]byte, error) {
+ if len(value) != int(s.Length) {
+ return nil, malformedAttrListErr("serialization failed: Prefix SID TLV malformed")
+ }
+ // Extra byte is reserved
+ buf := make([]byte, subSubTLVHdrLen+len(value))
+ p := 0
+ buf[p] = byte(s.Type)
+ p++
+ binary.BigEndian.PutUint16(buf[p:p+2], uint16(s.Length))
+ p += 2
+ copy(buf[p:], value)
+
+ return buf, nil
+}
+
+func (s *SubSubTLV) DecodeFromBytes(data []byte) ([]byte, error) {
+ if len(data) < prefixSIDtlvHdrLen {
+ return nil, malformedAttrListErr("decoding failed: Prefix SID Sub Sub TLV malformed")
+ }
+ s.Type = SubSubTLVType(data[0])
+ s.Length = binary.BigEndian.Uint16(data[1:3])
+
+ if len(data) < s.Len() {
+ return nil, malformedAttrListErr("decoding failed: Prefix SID Sub Sub TLV malformed")
+ }
+
+ return data[prefixSIDtlvHdrLen:s.Len()], nil
+}
+
+// SRv6SIDStructureSubSubTLV defines a structure of SRv6 SID Structure Sub Sub TLV (type 1) object
+// https://tools.ietf.org/html/draft-dawra-bess-srv6-services-02#section-2.1.2.1
+type SRv6SIDStructureSubSubTLV struct {
+ SubSubTLV
+ LocalBlockLength uint8
+ LocatorNodeLength uint8
+ FunctionLength uint8
+ ArgumentLength uint8
+ TranspositionLength uint8
+ TranspositionOffset uint8
+}
+
+func (s *SRv6SIDStructureSubSubTLV) Len() int {
+ return int(s.Length) + subSubTLVHdrLen
+}
+
+func (s *SRv6SIDStructureSubSubTLV) Serialize() ([]byte, error) {
+ buf := make([]byte, s.Length)
+ p := 0
+ buf[p] = s.LocalBlockLength
+ p++
+ buf[p] = s.LocatorNodeLength
+ p++
+ buf[p] = s.FunctionLength
+ p++
+ buf[p] = s.ArgumentLength
+ p++
+ buf[p] = s.TranspositionLength
+ p++
+ buf[p] = s.TranspositionOffset
+
+ return s.SubSubTLV.Serialize(buf)
+}
+
+func (s *SRv6SIDStructureSubSubTLV) DecodeFromBytes(data []byte) error {
+ if len(data) < subSubTLVHdrLen {
+ return malformedAttrListErr("decoding failed: Prefix SID Sub Sub TLV malformed")
+ }
+ s.Type = SubSubTLVType(data[0])
+ s.Length = binary.BigEndian.Uint16(data[1:3])
+
+ s.LocalBlockLength = data[3]
+ s.LocatorNodeLength = data[4]
+ s.FunctionLength = data[5]
+ s.ArgumentLength = data[6]
+ s.TranspositionLength = data[7]
+ s.TranspositionOffset = data[8]
+
+ return nil
+}
+
+func (s *SRv6SIDStructureSubSubTLV) MarshalJSON() ([]byte, error) {
+ return json.Marshal(struct {
+ Type SubSubTLVType `json:"type"`
+ LocalBlockLength uint8 `json:"local_block_length"`
+ LocatorNodeLength uint8 `json:"locator_node_length"`
+ FunctionLength uint8 `json:"function_length"`
+ ArgumentLength uint8 `json:"argument_length"`
+ TranspositionLength uint8 `json:"transposition_length"`
+ TranspositionOffset uint8 `json:"transposition_offset"`
+ }{
+ Type: s.Type,
+ LocalBlockLength: s.LocalBlockLength,
+ LocatorNodeLength: s.LocatorNodeLength,
+ FunctionLength: s.FunctionLength,
+ ArgumentLength: s.ArgumentLength,
+ TranspositionLength: s.TranspositionLength,
+ TranspositionOffset: s.TranspositionOffset,
+ })
+}
+
+func (s *SRv6SIDStructureSubSubTLV) String() string {
+ return fmt.Sprintf("{SRv6 Structure Sub Sub TLV: [ Local Block Length: %d, Locator Node Length: %d, Function Length: %d, Argument Length: %d, Transposition Length: %d, Transposition Offset: %d] }",
+ s.LocalBlockLength,
+ s.LocatorNodeLength,
+ s.FunctionLength,
+ s.ArgumentLength,
+ s.TranspositionLength,
+ s.TranspositionOffset,
+ )
}