Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions protocols/isis/packet/tlv.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ func readTLV(buf *bytes.Buffer) (TLV, error) {
tlv, err = readISNeighborsTLV(buf, tlvType, tlvLength)
case LSPEntriesTLVType:
tlv, err = readLSPEntriesTLV(buf, tlvType, tlvLength)
case RouterCapabilityTLVType:
tlv, err = readRouterCapabilityTLV(buf, tlvType, tlvLength)
default:
tlv, err = readUnknownTLV(buf, tlvType, tlvLength)
}
Expand All @@ -87,3 +89,12 @@ func readTLV(buf *bytes.Buffer) (TLV, error) {

return tlv, nil
}

func copyTLVs(tlvs []TLV) []TLV {
ret := make([]TLV, 0, len(tlvs))
for _, tlv := range tlvs {
ret = append(ret, tlv.Copy())
}

return ret
}
61 changes: 61 additions & 0 deletions protocols/isis/packet/tlv_ipv6_te_router_id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package packet

import (
"bytes"
"fmt"

"github.com/bio-routing/bio-rd/util/decode"
)

type IPv6TERouterIDTLV struct {
TLVType uint8
TLVLength uint8
RouterID [16]byte
}

const IPv6TERouterIDTLVType = 12
const IPv6TERouterIDTLVLength = 18

func readIPv6TERouterIDTLV(buf *bytes.Buffer, tlvType uint8, tlvLength uint8) (*IPv6TERouterIDTLV, error) {
pdu := &IPv6TERouterIDTLV{
TLVType: tlvType,
TLVLength: tlvLength,
}

fields := []any{
&pdu.RouterID,
}

err := decode.Decode(buf, fields)
if err != nil {
return nil, fmt.Errorf("unable to decode fields: %v", err)
}

return pdu, nil
}

func (i IPv6TERouterIDTLV) Copy() TLV {
ret := i
return &ret
}

// Type gets the type of the TLV
func (i IPv6TERouterIDTLV) Type() uint8 {
return i.TLVType
}

// Length gets the length of the TLV
func (i IPv6TERouterIDTLV) Length() uint8 {
return i.TLVLength
}

// Value returns the TLV itself
func (i *IPv6TERouterIDTLV) Value() any {
return i
}

func (i *IPv6TERouterIDTLV) Serialize(buf *bytes.Buffer) {
buf.WriteByte(i.TLVType)
buf.WriteByte(i.TLVLength)
buf.Write(i.RouterID[:])
}
77 changes: 77 additions & 0 deletions protocols/isis/packet/tlv_node_maximum_sid_depth.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package packet

import (
"bytes"
"fmt"

"github.com/bio-routing/bio-rd/util/decode"
)

const NodeMaximumSIDDepthTLVType = 23
const NodeMaximumSIDDepthTLVLen = 0

type NodeMaximumSIDDepthTLV struct {
TLVType uint8
TLVLength uint8
MSDs []MSD
}

type MSD struct {
Type uint8
Value uint8
}

func readNodeMaximumSIDDepthTLV(buf *bytes.Buffer, tlvType uint8, tlvLength uint8) (*NodeMaximumSIDDepthTLV, error) {
pdu := &NodeMaximumSIDDepthTLV{
TLVType: tlvType,
TLVLength: tlvLength,
}

for i := 0; i < int(tlvLength/2); i++ {
msd := MSD{}
fields := []any{
&msd.Type,
&msd.Value,
}

err := decode.Decode(buf, fields)
if err != nil {
return nil, fmt.Errorf("unable to decode fields: %v", err)
}
pdu.MSDs = append(pdu.MSDs, msd)
}

return pdu, nil
}

func (n NodeMaximumSIDDepthTLV) Copy() TLV {
ret := n
ret.MSDs = make([]MSD, len(n.MSDs))
copy(ret.MSDs, n.MSDs)
return &ret
}

// Type gets the type of the TLV
func (n NodeMaximumSIDDepthTLV) Type() uint8 {
return n.TLVType
}

// Length gets the length of the TLV
func (n NodeMaximumSIDDepthTLV) Length() uint8 {
return n.TLVLength
}

// Value returns the TLV itself
func (n *NodeMaximumSIDDepthTLV) Value() any {
return n
}

// Serialize serializes an NodeMaximumSIDDepthTLV
func (n NodeMaximumSIDDepthTLV) Serialize(buf *bytes.Buffer) {
buf.WriteByte(n.TLVType)
buf.WriteByte(n.TLVLength)
for _, msd := range n.MSDs {
buf.WriteByte(msd.Type)
buf.WriteByte(msd.Value)
}
}
139 changes: 139 additions & 0 deletions protocols/isis/packet/tlv_router_capability.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
package packet

import (
"bytes"
"fmt"

"github.com/bio-routing/bio-rd/util/decode"
"github.com/bio-routing/tflow2/convert"
)

const RouterCapabilityTLVType = 242

type RouterCapabilityTLV struct {
TLVType uint8
TLVLength uint8
RouterID uint32
Flags uint8
SubTLVs []TLV
}

const RouterCapabilityTLVLen = 5

func readRouterCapabilityTLV(buf *bytes.Buffer, tlvType uint8, tlvLength uint8) (*RouterCapabilityTLV, error) {
pdu := &RouterCapabilityTLV{
TLVType: tlvType,
TLVLength: tlvLength,
}
fields := []interface{}{
&pdu.RouterID,
&pdu.Flags,
}

err := decode.Decode(buf, fields)
if err != nil {
return nil, fmt.Errorf("unable to decode fields: %v", err)
}

toRead := tlvLength - RouterCapabilityTLVLen
fmt.Printf("toRead: %d\n", toRead)
if toRead > 0 {
tlvsBytes := make([]byte, toRead)
_, err := buf.Read(tlvsBytes)
if err != nil {
return nil, fmt.Errorf("failed to read TLV bytes from buf: %w", err)
}

subTLVs, err := readRouterCapSubTLVs(bytes.NewBuffer(tlvsBytes))
if err != nil {
return nil, fmt.Errorf("unable to decode sub TLVs: %w", err)
}

pdu.SubTLVs = subTLVs
}

return pdu, nil
}

func (r RouterCapabilityTLV) Copy() TLV {
ret := r
ret.SubTLVs = copyTLVs(r.SubTLVs)

return &ret
}

// Type returns the type of the TLV
func (r RouterCapabilityTLV) Type() uint8 {
return r.TLVType
}

// Length returns the length of the TLV
func (r RouterCapabilityTLV) Length() uint8 {
return r.TLVLength
}

// Value returns the TLV itself
func (r RouterCapabilityTLV) Value() interface{} {
return r
}

// Serialize serializes an WriteByte into a buffer
func (r RouterCapabilityTLV) Serialize(buf *bytes.Buffer) {
buf.WriteByte(r.TLVType)
buf.WriteByte(r.TLVLength)
buf.Write(convert.Uint32Byte(r.RouterID))
buf.WriteByte(r.Flags)

for i := range r.SubTLVs {
r.SubTLVs[i].Serialize(buf)
}
}

func readRouterCapSubTLVs(buf *bytes.Buffer) ([]TLV, error) {
TLVs := make([]TLV, 0)
for buf.Len() > 0 {
tlv, err := readRouterCapSubTLV(buf)
if err != nil {
return nil, fmt.Errorf("unable to read TLV: %w", err)
}

TLVs = append(TLVs, tlv)
}

return TLVs, nil
}

func readRouterCapSubTLV(buf *bytes.Buffer) (TLV, error) {
tlvType := uint8(0)
tlvLength := uint8(0)

headFields := []any{
&tlvType,
&tlvLength,
}

err := decode.Decode(buf, headFields)
if err != nil {
return nil, fmt.Errorf("unable to decode fields: %v", err)
}

var tlv TLV
switch tlvType {
case SegmentRoutingCapabilityTLVType:
tlv, err = readSegmentRoutingCapabilityTLV(buf, tlvType, tlvLength)
case SegmentRoutingAlgorithmsTLVType:
tlv, err = readSegmentRoutingAlgorithmsTLV(buf, tlvType, tlvLength)
case NodeMaximumSIDDepthTLVType:
tlv, err = readNodeMaximumSIDDepthTLV(buf, tlvType, tlvLength)
case IPv6TERouterIDTLVType:
tlv, err = readIPv6TERouterIDTLV(buf, tlvType, tlvLength)
default:
tlv, err = readUnknownTLV(buf, tlvType, tlvLength)
}

if err != nil {
return nil, fmt.Errorf("unable to read TLV (type %d): %v", tlvType, err)
}

return tlv, nil
}
Loading