Skip to content

Commit

Permalink
Add segments
Browse files Browse the repository at this point in the history
  • Loading branch information
louisroyer committed Jun 24, 2024
1 parent cba8195 commit e481b41
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 1 deletion.
3 changes: 2 additions & 1 deletion jsonapi/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@
package jsonapi

type Action struct {
SRH string
NextHop NextHop
SRH SRH
}
35 changes: 35 additions & 0 deletions jsonapi/nexthop.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT
package jsonapi

import (
"fmt"
"net/netip"
)

type NextHop struct {
netip.Addr
}

func NewNextHop(nh string) (*NextHop, error) {
h, err := netip.ParseAddr(nh)
if err != nil {
return nil, err
}
if !h.Is6() {
return nil, fmt.Errorf("NextHop must be an IPv6 address")
}
return &NextHop{h}, nil
}

func (nh *NextHop) UnmarshalText(text []byte) error {
if err := nh.Addr.UnmarshalText(text); err != nil {
return err
}
if !nh.Addr.Is6() {
return fmt.Errorf("NextHop must be an IPv6 address")
}
return nil
}
35 changes: 35 additions & 0 deletions jsonapi/segment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT
package jsonapi

import (
"fmt"
"net/netip"
)

type Segment struct {
netip.Addr
}

func NewSegment(s string) (*Segment, error) {
seg, err := netip.ParseAddr(s)
if err != nil {
return nil, err
}
if !seg.Is6() {
return nil, fmt.Errorf("Segment must be an IPv6 address")
}
return &Segment{seg}, nil
}

func (s *Segment) UnmarshalText(text []byte) error {
if err := s.Addr.UnmarshalText(text); err != nil {
return err
}
if !s.Addr.Is6() {
return fmt.Errorf("Segment must be an IPv6 address")
}
return nil
}
24 changes: 24 additions & 0 deletions jsonapi/srh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT
package jsonapi

import "fmt"

type SRH []*Segment

func NewSRH(segments []string) (*SRH, error) {
if len(segments) < 1 {
return nil, fmt.Errorf("SRH should contain at least one segment")
}
srh := make(SRH, 0)
for _, s := range segments {
if seg_n, err := NewSegment(s); err == nil {
srh = append(srh, seg_n)
} else {
return nil, err
}
}
return &srh, nil
}
68 changes: 68 additions & 0 deletions jsonapi_test/segment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT
package jsonapi

import (
"encoding/json"
"testing"

"github.com/nextmn/json-api/jsonapi"
)

func TestSegment(t *testing.T) {
s := &jsonapi.Segment{}
if err := s.UnmarshalText([]byte("192.168.0.0/24")); err == nil {
t.Errorf("Segment should be an IPv6 Address, not an IPv4 Prefix")
}
if err := s.UnmarshalText([]byte("192.168.0.1")); err == nil {
t.Errorf("Segment should be an IPv6 Address, not an IPv4 Address")
}
if err := s.UnmarshalText([]byte("fd00::/80")); err == nil {
t.Errorf("Segment should be an IPv6 Address, not an IPv6 Prefix")
}
if err := s.UnmarshalText([]byte("")); err == nil {
t.Errorf("Empty Segment should be rejected")
}
if err := s.UnmarshalText([]byte("fd00::")); err != nil {
t.Errorf("Correct Segment should not be rejected")
}
}

func TestNewSegment(t *testing.T) {
if seg0, err := jsonapi.NewSegment("::"); err == nil {
if seg0J, err := json.Marshal(seg0); err == nil {
if string(seg0J) != "\"::\"" {
t.Errorf("Marshal of '::' is wrong: %s", seg0J)
}
} else {
t.Errorf("Could not Marshal '::'")
}
} else {
t.Errorf("Could not create segment '::'")
}
if seg1, err := jsonapi.NewSegment("fd00::"); err == nil {
if seg1J, err := json.Marshal(seg1); err == nil {
if string(seg1J) != "\"fd00::\"" {
t.Errorf("Marshal of 'fd00::' is wrong: %s", seg1J)
}
} else {
t.Errorf("Could not Marshal 'fd00::'")
}
} else {
t.Errorf("Could not create segment 'fd00::'")
}
if _, err := jsonapi.NewSegment("10.0.0.0"); err == nil {
t.Errorf("NewSegment should error with string '10.0.0.0'")
}
if _, err := jsonapi.NewSegment(""); err == nil {
t.Errorf("NewSegment should error with empty string")
}
if _, err := jsonapi.NewSegment("fd00::/128"); err == nil {
t.Errorf("NewSegment should error with IPv6 Prefix")
}
if _, err := jsonapi.NewSegment("10.0.0.0/32"); err == nil {
t.Errorf("NewSegment should error with IPv4 Prefix")
}
}
29 changes: 29 additions & 0 deletions jsonapi_test/srh_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright 2024 Louis Royer and the NextMN-json-api contributors. All rights reserved.
// Use of this source code is governed by a MIT-style license that can be
// found in the LICENSE file.
// SPDX-License-Identifier: MIT
package jsonapi

import (
"testing"

"net/netip"

"github.com/nextmn/json-api/jsonapi"
)

func TestNewSRH(t *testing.T) {
if srh, err := jsonapi.NewSRH([]string{"::", "fd00::"}); err == nil {
if len(*srh) != 2 {
t.Errorf("Length of SRH should me 2, but is %d", len(*srh))
}
if (*srh)[0].Compare(netip.MustParseAddr("::")) != 0 {
t.Errorf("First segment is not correctly created")
}
if (*srh)[1].Compare(netip.MustParseAddr("fd00::")) != 0 {
t.Errorf("Second segment is not correctly created")
}
} else {
t.Errorf("Could not create SRH with '::', ''fd00::'")
}
}

0 comments on commit e481b41

Please sign in to comment.