Skip to content

Commit e481b41

Browse files
committed
Add segments
1 parent cba8195 commit e481b41

6 files changed

Lines changed: 193 additions & 1 deletion

File tree

jsonapi/action.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
package jsonapi
66

77
type Action struct {
8-
SRH string
8+
NextHop NextHop
9+
SRH SRH
910
}

jsonapi/nexthop.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
package jsonapi
6+
7+
import (
8+
"fmt"
9+
"net/netip"
10+
)
11+
12+
type NextHop struct {
13+
netip.Addr
14+
}
15+
16+
func NewNextHop(nh string) (*NextHop, error) {
17+
h, err := netip.ParseAddr(nh)
18+
if err != nil {
19+
return nil, err
20+
}
21+
if !h.Is6() {
22+
return nil, fmt.Errorf("NextHop must be an IPv6 address")
23+
}
24+
return &NextHop{h}, nil
25+
}
26+
27+
func (nh *NextHop) UnmarshalText(text []byte) error {
28+
if err := nh.Addr.UnmarshalText(text); err != nil {
29+
return err
30+
}
31+
if !nh.Addr.Is6() {
32+
return fmt.Errorf("NextHop must be an IPv6 address")
33+
}
34+
return nil
35+
}

jsonapi/segment.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
package jsonapi
6+
7+
import (
8+
"fmt"
9+
"net/netip"
10+
)
11+
12+
type Segment struct {
13+
netip.Addr
14+
}
15+
16+
func NewSegment(s string) (*Segment, error) {
17+
seg, err := netip.ParseAddr(s)
18+
if err != nil {
19+
return nil, err
20+
}
21+
if !seg.Is6() {
22+
return nil, fmt.Errorf("Segment must be an IPv6 address")
23+
}
24+
return &Segment{seg}, nil
25+
}
26+
27+
func (s *Segment) UnmarshalText(text []byte) error {
28+
if err := s.Addr.UnmarshalText(text); err != nil {
29+
return err
30+
}
31+
if !s.Addr.Is6() {
32+
return fmt.Errorf("Segment must be an IPv6 address")
33+
}
34+
return nil
35+
}

jsonapi/srh.go

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
package jsonapi
6+
7+
import "fmt"
8+
9+
type SRH []*Segment
10+
11+
func NewSRH(segments []string) (*SRH, error) {
12+
if len(segments) < 1 {
13+
return nil, fmt.Errorf("SRH should contain at least one segment")
14+
}
15+
srh := make(SRH, 0)
16+
for _, s := range segments {
17+
if seg_n, err := NewSegment(s); err == nil {
18+
srh = append(srh, seg_n)
19+
} else {
20+
return nil, err
21+
}
22+
}
23+
return &srh, nil
24+
}

jsonapi_test/segment_test.go

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
package jsonapi
6+
7+
import (
8+
"encoding/json"
9+
"testing"
10+
11+
"github.com/nextmn/json-api/jsonapi"
12+
)
13+
14+
func TestSegment(t *testing.T) {
15+
s := &jsonapi.Segment{}
16+
if err := s.UnmarshalText([]byte("192.168.0.0/24")); err == nil {
17+
t.Errorf("Segment should be an IPv6 Address, not an IPv4 Prefix")
18+
}
19+
if err := s.UnmarshalText([]byte("192.168.0.1")); err == nil {
20+
t.Errorf("Segment should be an IPv6 Address, not an IPv4 Address")
21+
}
22+
if err := s.UnmarshalText([]byte("fd00::/80")); err == nil {
23+
t.Errorf("Segment should be an IPv6 Address, not an IPv6 Prefix")
24+
}
25+
if err := s.UnmarshalText([]byte("")); err == nil {
26+
t.Errorf("Empty Segment should be rejected")
27+
}
28+
if err := s.UnmarshalText([]byte("fd00::")); err != nil {
29+
t.Errorf("Correct Segment should not be rejected")
30+
}
31+
}
32+
33+
func TestNewSegment(t *testing.T) {
34+
if seg0, err := jsonapi.NewSegment("::"); err == nil {
35+
if seg0J, err := json.Marshal(seg0); err == nil {
36+
if string(seg0J) != "\"::\"" {
37+
t.Errorf("Marshal of '::' is wrong: %s", seg0J)
38+
}
39+
} else {
40+
t.Errorf("Could not Marshal '::'")
41+
}
42+
} else {
43+
t.Errorf("Could not create segment '::'")
44+
}
45+
if seg1, err := jsonapi.NewSegment("fd00::"); err == nil {
46+
if seg1J, err := json.Marshal(seg1); err == nil {
47+
if string(seg1J) != "\"fd00::\"" {
48+
t.Errorf("Marshal of 'fd00::' is wrong: %s", seg1J)
49+
}
50+
} else {
51+
t.Errorf("Could not Marshal 'fd00::'")
52+
}
53+
} else {
54+
t.Errorf("Could not create segment 'fd00::'")
55+
}
56+
if _, err := jsonapi.NewSegment("10.0.0.0"); err == nil {
57+
t.Errorf("NewSegment should error with string '10.0.0.0'")
58+
}
59+
if _, err := jsonapi.NewSegment(""); err == nil {
60+
t.Errorf("NewSegment should error with empty string")
61+
}
62+
if _, err := jsonapi.NewSegment("fd00::/128"); err == nil {
63+
t.Errorf("NewSegment should error with IPv6 Prefix")
64+
}
65+
if _, err := jsonapi.NewSegment("10.0.0.0/32"); err == nil {
66+
t.Errorf("NewSegment should error with IPv4 Prefix")
67+
}
68+
}

jsonapi_test/srh_test.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style license that can be
3+
// found in the LICENSE file.
4+
// SPDX-License-Identifier: MIT
5+
package jsonapi
6+
7+
import (
8+
"testing"
9+
10+
"net/netip"
11+
12+
"github.com/nextmn/json-api/jsonapi"
13+
)
14+
15+
func TestNewSRH(t *testing.T) {
16+
if srh, err := jsonapi.NewSRH([]string{"::", "fd00::"}); err == nil {
17+
if len(*srh) != 2 {
18+
t.Errorf("Length of SRH should me 2, but is %d", len(*srh))
19+
}
20+
if (*srh)[0].Compare(netip.MustParseAddr("::")) != 0 {
21+
t.Errorf("First segment is not correctly created")
22+
}
23+
if (*srh)[1].Compare(netip.MustParseAddr("fd00::")) != 0 {
24+
t.Errorf("Second segment is not correctly created")
25+
}
26+
} else {
27+
t.Errorf("Could not create SRH with '::', ''fd00::'")
28+
}
29+
}

0 commit comments

Comments
 (0)