diff options
Diffstat (limited to 'pkg/packet')
-rw-r--r-- | pkg/packet/bgp/prefix_sid.go | 214 | ||||
-rw-r--r-- | pkg/packet/bgp/prefix_sid_test.go | 25 |
2 files changed, 149 insertions, 90 deletions
diff --git a/pkg/packet/bgp/prefix_sid.go b/pkg/packet/bgp/prefix_sid.go index b19fcecd..f096a8de 100644 --- a/pkg/packet/bgp/prefix_sid.go +++ b/pkg/packet/bgp/prefix_sid.go @@ -62,98 +62,10 @@ func (s *PrefixSIDTLV) DecodeFromBytes(data []byte) ([]byte, error) { } type PrefixSIDAttribute struct { + PrefixSIDTLV TLVs []PrefixSIDTLVInterface } -func (p *PathAttributePrefixSID) Extract() *PrefixSIDAttribute { - s := &PrefixSIDAttribute{ - TLVs: make([]PrefixSIDTLVInterface, 0), - } - - for _, tlv := range p.TLVs { - switch v := tlv.(type) { - case *PrefixSIDType5: - glog.Infof("><SB> v: %+v", v) - o := &PrefixSIDType5{} - s.TLVs = append(s.TLVs, o) - // l.Node.Flags = v.Extract() - - // case *LsTLVOpaqueNodeAttr: - // l.Node.Opaque = &v.Attr - - // case *LsTLVNodeName: - // l.Node.Name = &v.Name - - // case *LsTLVIsisArea: - // l.Node.IsisArea = &v.Area - - // case *LsTLVLocalIPv4RouterID: - // l.Node.LocalRouterID = &v.IP - // l.Link.LocalRouterID = &v.IP - - // case *LsTLVLocalIPv6RouterID: - // l.Node.LocalRouterIDv6 = &v.IP - // l.Link.LocalRouterIDv6 = &v.IP - - // case *LsTLVSrCapabilities: - // l.Node.SrCapabilties = v.Extract() - - // case *LsTLVSrAlgorithm: - // l.Node.SrAlgorithms = &v.Algorithm - - // case *LsTLVSrLocalBlock: - // l.Node.SrLocalBlock = v.Extract() - - // case *LsTLVRemoteIPv4RouterID: - // l.Link.RemoteRouterID = &v.IP - - // case *LsTLVRemoteIPv6RouterID: - // l.Link.RemoteRouterIDv6 = &v.IP - - // case *LsTLVAdminGroup: - // l.Link.AdminGroup = &v.AdminGroup - - // case *LsTLVMaxLinkBw: - // l.Link.Bandwidth = &v.Bandwidth - - // case *LsTLVMaxReservableLinkBw: - // l.Link.ReservableBandwidth = &v.Bandwidth - - // case *LsTLVUnreservedBw: - // l.Link.UnreservedBandwidth = &v.Bandwidth - - // case *LsTLVSrlg: - // l.Link.Srlgs = &v.Srlgs - - // case *LsTLVTEDefaultMetric: - // l.Link.DefaultTEMetric = &v.Metric - - // case *LsTLVIGPMetric: - // l.Link.IGPMetric = &v.Metric - - // case *LsTLVOpaqueLinkAttr: - // l.Link.Opaque = &v.Attr - - // case *LsTLVLinkName: - // l.Link.Name = &v.Name - - // case *LsTLVAdjacencySID: - // l.Link.SrAdjacencySID = &v.SID - - // case *LsTLVIGPFlags: - // l.Prefix.IGPFlags = v.Extract() - - // case *LsTLVOpaquePrefixAttr: - // l.Prefix.Opaque = &v.Attr - - // case *LsTLVPrefixSID: - // l.Prefix.SrPrefixSID = &v.SID - } - } - - return s -} - func (p *PathAttributePrefixSID) DecodeFromBytes(data []byte, options ...*MarshallingOption) error { tlvs, err := p.PathAttribute.DecodeFromBytes(data) if err != nil { @@ -219,7 +131,7 @@ func (p *PathAttributePrefixSID) MarshalJSON() ([]byte, error) { }{ p.GetType(), p.GetFlags(), - *p.Extract(), + PrefixSIDAttribute{}, }) } @@ -257,6 +169,7 @@ func (s *PrefixSIDType5) DecodeFromBytes(data []byte) error { if len(data) < s.Len() { return malformedAttrListErr("decoding failed: Prefix SID TLV malformed") } + glog.Infof("><SB> PrefixSIDType5 %+v", data) return nil } @@ -328,6 +241,52 @@ type SRv6InformationSubTLV struct { SubSubTLV []PrefixSIDTLVInterface } +type SRv6SubSubTLV struct { + PrefixSIDTLV + TLV []PrefixSIDTLVInterface +} + +func (s *SRv6SubSubTLV) Len() int { + return int(s.Length) + tlvHdrLen +} + +func (s *SRv6SubSubTLV) Serialize() ([]byte, error) { + s. + if len(value) != int(s.Length) { + return nil, malformedAttrListErr("serialization failed: Prefix SID TLV malformed") + } + + buf := make([]byte, tlvHdrLen+len(value)) + binary.BigEndian.PutUint16(buf[:2], uint16(s.Type)) + binary.BigEndian.PutUint16(buf[2:4], uint16(s.Length)) + copy(buf[4:], value) + + return buf, nil + return nil, nil +} + +func (s *SRv6SubSubTLV) DecodeFromBytes(data []byte) error { + if len(data) < tlvHdrLen { + return malformedAttrListErr("decoding failed: Prefix SID TLV malformed") + } + s.Type = PrefixSIDTLVType(binary.BigEndian.Uint16(data[:2])) + s.Length = binary.BigEndian.Uint16(data[2:4]) + + if len(data) < s.Len() { + return malformedAttrListErr("decoding failed: Prefix SID TLV malformed") + } + + return nil +} + +func (s *SRv6SubSubTLV) MarshalJSON() ([]byte, error) { + return nil, nil +} + +func (s *SRv6SubSubTLV) String() string { + return "" +} + // 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 { @@ -339,3 +298,78 @@ type SRv6SIDStructureSubSubTLV struct { TranspositionLength uint8 `json:"transposition_length,omitempty"` TranspositionOffset uint8 `json:"transposition_offset,omitempty"` } + + + +///////////////////////////// +// type LsTLVAdjacencySID struct { +// LsTLV +// Flags uint8 +// Weight uint8 +// SID uint32 +// } + +// func (l *LsTLVAdjacencySID) DecodeFromBytes(data []byte) error { +// value, err := l.LsTLV.DecodeFromBytes(data) +// if err != nil { +// return err +// } + +// if l.Type != LS_TLV_ADJACENCY_SID { +// return malformedAttrListErr("Unexpected TLV type") +// } + +// // https://tools.ietf.org/html/draft-ietf-idr-bgp-ls-segment-routing-ext-08#section-2.2.1 +// if len(value) != 7 && len(value) != 8 { +// return malformedAttrListErr("Incorrect Adjacency SID length") +// } + +// l.Flags = value[0] +// l.Weight = value[1] + +// v := value[4:] +// if len(v) == 4 { +// l.SID = binary.BigEndian.Uint32(v) +// } else { +// buf := []byte{0, 0, 0, 0} +// for i := 1; i < len(buf); i++ { +// buf[i] = v[i-1] +// } +// // Label is represented by 20 rightmost bits. +// l.SID = binary.BigEndian.Uint32(buf) & 0xfffff +// } + +// return nil +// } + +// func (l *LsTLVAdjacencySID) Serialize() ([]byte, error) { +// buf := make([]byte, 0) +// buf = append(buf, l.Flags) +// buf = append(buf, l.Weight) +// // Reserved +// buf = append(buf, []byte{0, 0}...) + +// var b [4]byte +// binary.BigEndian.PutUint32(b[:4], l.SID) + +// if l.Length == 7 { +// return l.LsTLV.Serialize(append(buf, b[1:]...)) +// } + +// return l.LsTLV.Serialize(append(buf, b[:]...)) +// } + +// func (l *LsTLVAdjacencySID) String() string { +// return fmt.Sprintf("{Adjacency SID: %v}", l.SID) +// } + +// func (l *LsTLVAdjacencySID) MarshalJSON() ([]byte, error) { +// return json.Marshal(struct { +// Type LsTLVType `json:"type"` +// SID uint32 `json:"adjacency_sid"` +// }{ +// Type: l.Type, +// SID: l.SID, +// }) +// } +//////////////////////////////////////
\ No newline at end of file diff --git a/pkg/packet/bgp/prefix_sid_test.go b/pkg/packet/bgp/prefix_sid_test.go new file mode 100644 index 00000000..84f1312f --- /dev/null +++ b/pkg/packet/bgp/prefix_sid_test.go @@ -0,0 +1,25 @@ +package bgp + +import ( + "reflect" + "testing" +) + +func TestUnmarshalUnicastNLRI(t *testing.T) { + tests := []struct { + name string + input []byte + expect *PathAttributePrefixSID + }{} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := GetPathAttribute(tt.input) + if err != nil { + t.Fatalf("test failed with error: %+v", err) + } + if !reflect.DeepEqual(tt.expect, got) { + t.Fatalf("test failed as expected nlri %+v does not match actual nlri %+v", tt.expect, got) + } + }) + } +} |