Skip to content

Commit

Permalink
polad usid support
Browse files Browse the repository at this point in the history
  • Loading branch information
Motok1 committed Jun 9, 2024
1 parent 87662ab commit 76fb091
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 27 deletions.
1 change: 1 addition & 0 deletions cmd/polad/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ func main() {
GrpcAddr: c.Global.GrpcServer.Address,
GrpcPort: c.Global.GrpcServer.Port,
TedEnable: c.Global.Ted.Enable,
USidMode: c.Global.USidMode,
}
if serverErr := server.NewPce(o, logger, tedElemsChan); serverErr.Error != nil {
logger.Panic("Failed to start new server", zap.String("server", serverErr.Server), zap.Error(serverErr.Error))
Expand Down
1 change: 1 addition & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Global struct {
Log Log `yaml:"log"`
Ted Ted `yaml:"ted"`
Gobgp Gobgp `yaml:"gobgp"`
USidMode bool `yaml:"usid-mode"`
}

type Config struct {
Expand Down
34 changes: 33 additions & 1 deletion internal/pkg/table/sr_policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,14 +104,46 @@ func NewSegment(sid string) (Segment, error) {
return nil, errors.New("invalid SID")
}

const (
BEHAVIOR_RESERVED uint16 = 0x0000
BEHAVIOR_END uint16 = 0x0001
BEHAVIOR_END_X uint16 = 0x0005
BEHAVIOR_UN uint16 = 0x0030
BEHAVIOR_UA uint16 = 0x0039
)

type SegmentSRv6 struct {
Sid netip.Addr
Sid netip.Addr
LocalAddr netip.Addr
RemoteAddr netip.Addr
Structure []uint8
USid bool
}

func (seg SegmentSRv6) SidString() string {
return seg.Sid.String()
}

func (seg SegmentSRv6) Behavior() uint16 {
if seg.LocalAddr.IsValid() {
if seg.USid {
if seg.RemoteAddr.IsValid() {
return BEHAVIOR_UA
} else {
return BEHAVIOR_UN
}
} else {
if seg.RemoteAddr.IsValid() {
return BEHAVIOR_END_X
} else {
return BEHAVIOR_END
}
}
} else {
return BEHAVIOR_RESERVED
}
}

func NewSegmentSRv6(sid netip.Addr) SegmentSRv6 {
return SegmentSRv6{
Sid: sid,
Expand Down
91 changes: 71 additions & 20 deletions pkg/packet/pcep/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package pcep
import (
"encoding/binary"
"errors"
"math"
"net/netip"

"github.com/nttcom/pola/internal/pkg/table"
Expand Down Expand Up @@ -885,9 +886,7 @@ type SRv6EroSubobject struct {
TFlag bool
FFlag bool
SFlag bool
Behavior uint16
Segment table.SegmentSRv6
Nai netip.Addr
}

func (o *SRv6EroSubobject) DecodeFromBytes(subObj []uint8) error {
Expand All @@ -899,12 +898,15 @@ func (o *SRv6EroSubobject) DecodeFromBytes(subObj []uint8) error {
o.TFlag = (subObj[3] & 0x04) != 0
o.FFlag = (subObj[3] & 0x02) != 0
o.SFlag = (subObj[3] & 0x01) != 0
o.Behavior = binary.BigEndian.Uint16(subObj[6:8])

sid, _ := netip.AddrFromSlice(subObj[8:24])
o.Segment = table.NewSegmentSRv6(sid)
if o.NaiType == 2 {
o.Nai, _ = netip.AddrFromSlice(subObj[24:40])
if o.NaiType == NT_SRV6_NODE {
o.Segment.LocalAddr, _ = netip.AddrFromSlice(subObj[24:40])
}
if o.NaiType == NT_SRV6_ADJACENCY_GLOBAL {
o.Segment.LocalAddr, _ = netip.AddrFromSlice(subObj[24:40])
o.Segment.RemoteAddr, _ = netip.AddrFromSlice(subObj[40:56])
}
return nil
}
Expand All @@ -931,38 +933,87 @@ func (o *SRv6EroSubobject) Serialize() []uint8 {
}
reserved := make([]uint8, 2)
behavior := make([]uint8, 2)
binary.BigEndian.PutUint16(behavior, o.Behavior)
binary.BigEndian.PutUint16(behavior, o.Segment.Behavior())
byteSid := o.Segment.Sid.AsSlice()
byteSRv6EroSubobject := AppendByteSlices(buf, reserved, behavior, byteSid)

byteNai := []uint8{}
if o.Segment.LocalAddr.IsValid() {
byteNai = append(byteNai, o.Segment.LocalAddr.AsSlice()...)
if o.Segment.RemoteAddr.IsValid() {
byteNai = append(byteNai, o.Segment.RemoteAddr.AsSlice()...)
}
}

byteSidStructure := []uint8{}
if o.Segment.Structure != nil {
byteSidStructure = append(byteSidStructure, o.Segment.Structure...)
byteSidStructure = append(byteSidStructure, make([]uint8, 4)...)
}

byteSRv6EroSubobject := AppendByteSlices(buf, reserved, behavior, byteSid, byteNai, byteSidStructure)
return byteSRv6EroSubobject
}

func (o *SRv6EroSubobject) Len() (uint16, error) {
// The Length MUST be at least 24, and MUST be a multiple of 4.
// An SRv6-ERO subobject MUST contain at least one of a SRv6-SID or an NAI.
if o.NaiType == NT_MUST_NOT_BE_INCLUDED {
// Type, Length, Flags (4byte) + Reserved(2byte) + Behavior(2byte) + SID (16byte)
return uint16(24), nil
} else if o.NaiType == NT_IPV6_NODE {
// Type, Length, Flags (4byte) + Reserved(2byte) + Behavior(2byte) + SID (16byte) + Nai (16byte)
return uint16(40), nil
} else {
return uint16(0), errors.New("unsupported naitype")

// Type, Length, Flags (4byte) + Reserved(2byte) + Behavior(2byte)
length := uint16(8)
// SRv6-SID value in the subobject body is NOT absent
if !o.SFlag {
length += 16
}
// NAI value in the subobject body is NOT absent
if !o.FFlag {
switch o.NaiType {
case NT_IPV6_NODE:
length += 16
case NT_SRV6_ADJACENCY_GLOBAL:
length += 32
case NT_SRV6_ADJACENCY_LINKLOCAL:
length += 40
case NT_MUST_NOT_BE_INCLUDED:
return uint16(0), errors.New("when naitype is 0 then FFlag must be 1")
default:
return uint16(0), errors.New("unsupported naitype")
}
}
if o.TFlag {
length += 8
}
return length, nil
}

func NewSRv6EroSubObject(seg table.SegmentSRv6) (*SRv6EroSubobject, error) {
subo := &SRv6EroSubobject{
LFlag: false,
SubobjectType: ERO_SUBOBJECT_SRV6,
NaiType: NT_MUST_NOT_BE_INCLUDED,
VFlag: false,
TFlag: false,
FFlag: true,
SFlag: false,
Behavior: uint16(1),
SFlag: false, // SID is absent
Segment: seg,
}

if seg.Structure != nil {
subo.TFlag = true // the SID Structure value in the subobject body is present
} else {
subo.TFlag = false
}
if seg.LocalAddr.IsValid() {
subo.FFlag = false // Nai is present

if seg.RemoteAddr.IsValid() {
// End.X or uA
subo.NaiType = NT_SRV6_ADJACENCY_GLOBAL
} else {
// End or uN
subo.NaiType = NT_SRV6_NODE
}
} else {
subo.FFlag = true // SID is absent
subo.NaiType = NT_MUST_NOT_BE_INCLUDED
}

length, err := subo.Len()
if err != nil {
return subo, err
Expand Down
48 changes: 44 additions & 4 deletions pkg/server/grpc_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import (
"net"
"net/netip"
"slices"
"strconv"
"strings"

"github.com/golang/protobuf/ptypes/empty"
pb "github.com/nttcom/pola/api/grpc"
Expand All @@ -26,13 +28,15 @@ import (
type APIServer struct {
pce *Server
grpcServer *grpc.Server
usidMode bool
pb.UnimplementedPceServiceServer
}

func NewAPIServer(pce *Server, grpcServer *grpc.Server) *APIServer {
func NewAPIServer(pce *Server, grpcServer *grpc.Server, usidMode bool) *APIServer {
s := &APIServer{
pce: pce,
grpcServer: grpcServer,
usidMode: usidMode,
}
pb.RegisterPceServiceServer(grpcServer, s)
return s
Expand Down Expand Up @@ -99,9 +103,45 @@ func (s *APIServer) createSRPolicy(ctx context.Context, input *pb.CreateSRPolicy
dstAddr, _ = netip.AddrFromSlice(inputSRPolicy.GetDstAddr())

for _, segment := range inputSRPolicy.GetSegmentList() {
seg, err := table.NewSegment(segment.GetSid())
if err != nil {
return &pb.RequestStatus{IsSuccess: false}, err
var seg table.Segment
if addr, err := netip.ParseAddr(segment.GetSid()); err == nil && addr.Is6() {
segSRv6 := table.NewSegmentSRv6(addr)

// handling of related to Nai
if segment.GetLocalAddr() != "" {
if la, addrErr := netip.ParseAddr(segment.GetLocalAddr()); addrErr == nil {
segSRv6.LocalAddr = la
} else {
return &pb.RequestStatus{IsSuccess: false}, addrErr
}
if segment.GetRemoteAddr() != "" {
if ra, addrErr := netip.ParseAddr(segment.GetRemoteAddr()); addrErr == nil {
segSRv6.RemoteAddr = ra
} else {
return &pb.RequestStatus{IsSuccess: false}, addrErr
}
}
}

// handling of related to SID Structure
if ss := strings.Split(segment.GetSidStructure(), ","); len(ss) == 4 {
segSRv6.Structure = []uint8{}
for _, strElem := range ss {
elem, err := strconv.Atoi(strElem)
if err != nil {
return &pb.RequestStatus{IsSuccess: false}, errors.New("invalid SidStructure information")
}
segSRv6.Structure = append(segSRv6.Structure, uint8(elem))
}

}
// usid option
segSRv6.USid = s.usidMode
seg = segSRv6
} else if i, err := strconv.ParseUint(segment.GetSid(), 10, 32); err == nil {
seg = table.NewSegmentSRMPLS(uint32(i))
} else {
return &pb.RequestStatus{IsSuccess: false}, errors.New("invalid SID")
}
segmentList = append(segmentList, seg)
}
Expand Down
6 changes: 4 additions & 2 deletions pkg/server/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ package server
import (
"net"
"net/netip"
"strconv"

"go.uber.org/zap"
grpc "google.golang.org/grpc"
Expand All @@ -27,6 +28,7 @@ type PceOptions struct {
GrpcAddr string
GrpcPort string
TedEnable bool
USidMode bool
}

func NewPce(o *PceOptions, logger *zap.Logger, tedElemsChan chan []table.TedElem) ServerError {
Expand Down Expand Up @@ -54,7 +56,7 @@ func NewPce(o *PceOptions, logger *zap.Logger, tedElemsChan chan []table.TedElem

errChan := make(chan ServerError)
go func() {
if err := s.Serve(o.PcepAddr, o.PcepPort); err != nil {
if err := s.Serve(o.PcepAddr, o.PcepPort, o.USidMode); err != nil {
errChan <- ServerError{
Server: "pcep",
Error: err,
Expand All @@ -64,7 +66,7 @@ func NewPce(o *PceOptions, logger *zap.Logger, tedElemsChan chan []table.TedElem

go func() {
grpcServer := grpc.NewServer()
apiServer := NewAPIServer(s, grpcServer)
apiServer := NewAPIServer(s, grpcServer, o.USidMode)
if err := apiServer.Serve(o.GrpcAddr, o.GrpcPort); err != nil {
errChan <- ServerError{
Server: "grpc",
Expand Down

0 comments on commit 76fb091

Please sign in to comment.