Skip to content

Commit

Permalink
Merge pull request #175 from sbezverk/issue_171
Browse files Browse the repository at this point in the history
issue #171 and SID to uint32
  • Loading branch information
sbezverk authored Aug 23, 2021
2 parents 62d7fc1 + cb56d0f commit 27cacc6
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 5 deletions.
2 changes: 1 addition & 1 deletion pkg/sr/sr-adjacencysid.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (a *AdjacencySIDTLV) MarshalJSON() ([]byte, error) {
return json.Marshal(struct {
Flags *AdjISISFlags `json:"flags,omitempty"`
Weight uint8 `json:"weight"`
SID uint32 `json:"prefix_sid,omitempty"`
SID uint32 `json:"sid,omitempty"`
}{
Flags: f,
Weight: a.Weight,
Expand Down
36 changes: 32 additions & 4 deletions pkg/sr/sr-peersid.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package sr

import (
"encoding/binary"
"encoding/json"
"fmt"

"github.com/golang/glog"
Expand Down Expand Up @@ -32,14 +34,22 @@ func UnmarshalPeerFlags(b []byte) (*PeerFlags, error) {
type PeerSID struct {
Flags *PeerFlags `json:"flags"`
Weight uint8 `json:"weight"`
SID []byte `json:"prefix_sid,omitempty"`
SID uint32 `json:"sid,omitempty"`
}

func (p *PeerSID) String() string {
s, _ := json.Marshal(p)
return string(s)
}

// UnmarshalPeerSID builds PeerSID TLV Object
func UnmarshalPeerSID(b []byte) (*PeerSID, error) {
if glog.V(6) {
glog.Infof("Peer SID TLV Raw: %s", tools.MessageHex(b))
}
if len(b) != 7 && len(b) != 8 {
return nil, fmt.Errorf("invalid length %d of data to decode peer sid tlv", len(b))
}
psid := PeerSID{}
p := 0
f, err := UnmarshalPeerFlags(b[p : p+1])
Expand All @@ -51,10 +61,28 @@ func UnmarshalPeerSID(b []byte) (*PeerSID, error) {
psid.Weight = b[p]
p++
// SID length would be Length of b - Flags 1 byte - Weight 1 byte - 2 bytes Reserved
sl := len(b) - 4
psid.SID = make([]byte, len(b)-4)
p += 2
copy(psid.SID, b[p:p+sl])
l := len(b) - 4
s := make([]byte, 4)
switch l {
case 3:
if !psid.Flags.VFlag || !psid.Flags.LFlag {
// When sid is 3 bytes, V and L flags MUST be set to "true", if not, error out
return nil, fmt.Errorf("sid length is 3 bytes but V flag is NOT set to \"true\"")
}
copy(s[1:], b[p:p+3])
// Since label uses only 20 bits for label, clear first 4 bits of s[1]
s[1] &= 0x0f
case 4:
if psid.Flags.VFlag {
// When sid is 4 bytes, V flag must NOT be set to "true", if not, error out
return nil, fmt.Errorf("sid length is 4 bytes but V flag is set to \"true\"")
}
copy(s, b[p:p+4])
default:
return nil, fmt.Errorf("software bug in peer sid processing logic, byte slice: %s", tools.MessageHex(b))
}
psid.SID = binary.BigEndian.Uint32(s)

return &psid, nil
}
45 changes: 45 additions & 0 deletions pkg/sr/sr-peersid_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package sr

import (
"reflect"
"testing"

"github.com/go-test/deep"
)

func TestUnmarshalPeerSID(t *testing.T) {
tests := []struct {
name string
input []byte
expect *PeerSID
}{
{
name: "issue 171",
input: []byte{0xD0, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xA8},
expect: &PeerSID{
Flags: &PeerFlags{
VFlag: true,
LFlag: true,
PFlag: true,
},
Weight: 0,
SID: 15016,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r, err := UnmarshalPeerSID(tt.input)
if err != nil {
t.Fatalf("failed with error: %+v", err)
}
if !reflect.DeepEqual(tt.expect, r) {
t.Logf("Diffs: %+v", deep.Equal(tt.expect, r))
t.Fatalf("expected peer sid %+v does not match to he actual %+v", tt.expect, r)
}
if err == nil {
t.Logf("Peer SID: %s", r)
}
})
}
}

0 comments on commit 27cacc6

Please sign in to comment.