mirror of
https://github.com/openfaas/faasd.git
synced 2025-06-21 00:06:37 +00:00
The use of containerd and CNI functions has been refactored to reuse the same codebase. Added all network functionality to own directory and package. Removed netlink and weave library in favor of using CNI plugin result files. Rename containers handler to functions to clear-up functionality. Signed-off-by: Carlos de Paula <me@carlosedp.com>
155 lines
4.0 KiB
Go
155 lines
4.0 KiB
Go
package nl
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net"
|
|
)
|
|
|
|
type IPv6SrHdr struct {
|
|
nextHdr uint8
|
|
hdrLen uint8
|
|
routingType uint8
|
|
segmentsLeft uint8
|
|
firstSegment uint8
|
|
flags uint8
|
|
reserved uint16
|
|
|
|
Segments []net.IP
|
|
}
|
|
|
|
func (s1 *IPv6SrHdr) Equal(s2 IPv6SrHdr) bool {
|
|
if len(s1.Segments) != len(s2.Segments) {
|
|
return false
|
|
}
|
|
for i := range s1.Segments {
|
|
if s1.Segments[i].Equal(s2.Segments[i]) != true {
|
|
return false
|
|
}
|
|
}
|
|
return s1.nextHdr == s2.nextHdr &&
|
|
s1.hdrLen == s2.hdrLen &&
|
|
s1.routingType == s2.routingType &&
|
|
s1.segmentsLeft == s2.segmentsLeft &&
|
|
s1.firstSegment == s2.firstSegment &&
|
|
s1.flags == s2.flags
|
|
// reserved doesn't need to be identical.
|
|
}
|
|
|
|
// seg6 encap mode
|
|
const (
|
|
SEG6_IPTUN_MODE_INLINE = iota
|
|
SEG6_IPTUN_MODE_ENCAP
|
|
)
|
|
|
|
// number of nested RTATTR
|
|
// from include/uapi/linux/seg6_iptunnel.h
|
|
const (
|
|
SEG6_IPTUNNEL_UNSPEC = iota
|
|
SEG6_IPTUNNEL_SRH
|
|
__SEG6_IPTUNNEL_MAX
|
|
)
|
|
const (
|
|
SEG6_IPTUNNEL_MAX = __SEG6_IPTUNNEL_MAX - 1
|
|
)
|
|
|
|
func EncodeSEG6Encap(mode int, segments []net.IP) ([]byte, error) {
|
|
nsegs := len(segments) // nsegs: number of segments
|
|
if nsegs == 0 {
|
|
return nil, errors.New("EncodeSEG6Encap: No Segment in srh")
|
|
}
|
|
b := make([]byte, 12, 12+len(segments)*16)
|
|
native := NativeEndian()
|
|
native.PutUint32(b, uint32(mode))
|
|
b[4] = 0 // srh.nextHdr (0 when calling netlink)
|
|
b[5] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit)
|
|
b[6] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA)
|
|
b[7] = uint8(nsegs - 1) // srh.segmentsLeft
|
|
b[8] = uint8(nsegs - 1) // srh.firstSegment
|
|
b[9] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac)
|
|
// srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07
|
|
native.PutUint16(b[10:], 0) // srh.reserved
|
|
for _, netIP := range segments {
|
|
b = append(b, netIP...) // srh.Segments
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
func DecodeSEG6Encap(buf []byte) (int, []net.IP, error) {
|
|
native := NativeEndian()
|
|
mode := int(native.Uint32(buf))
|
|
srh := IPv6SrHdr{
|
|
nextHdr: buf[4],
|
|
hdrLen: buf[5],
|
|
routingType: buf[6],
|
|
segmentsLeft: buf[7],
|
|
firstSegment: buf[8],
|
|
flags: buf[9],
|
|
reserved: native.Uint16(buf[10:12]),
|
|
}
|
|
buf = buf[12:]
|
|
if len(buf)%16 != 0 {
|
|
err := fmt.Errorf("DecodeSEG6Encap: error parsing Segment List (buf len: %d)\n", len(buf))
|
|
return mode, nil, err
|
|
}
|
|
for len(buf) > 0 {
|
|
srh.Segments = append(srh.Segments, net.IP(buf[:16]))
|
|
buf = buf[16:]
|
|
}
|
|
return mode, srh.Segments, nil
|
|
}
|
|
|
|
func DecodeSEG6Srh(buf []byte) ([]net.IP, error) {
|
|
native := NativeEndian()
|
|
srh := IPv6SrHdr{
|
|
nextHdr: buf[0],
|
|
hdrLen: buf[1],
|
|
routingType: buf[2],
|
|
segmentsLeft: buf[3],
|
|
firstSegment: buf[4],
|
|
flags: buf[5],
|
|
reserved: native.Uint16(buf[6:8]),
|
|
}
|
|
buf = buf[8:]
|
|
if len(buf)%16 != 0 {
|
|
err := fmt.Errorf("DecodeSEG6Srh: error parsing Segment List (buf len: %d)", len(buf))
|
|
return nil, err
|
|
}
|
|
for len(buf) > 0 {
|
|
srh.Segments = append(srh.Segments, net.IP(buf[:16]))
|
|
buf = buf[16:]
|
|
}
|
|
return srh.Segments, nil
|
|
}
|
|
func EncodeSEG6Srh(segments []net.IP) ([]byte, error) {
|
|
nsegs := len(segments) // nsegs: number of segments
|
|
if nsegs == 0 {
|
|
return nil, errors.New("EncodeSEG6Srh: No Segments")
|
|
}
|
|
b := make([]byte, 8, 8+len(segments)*16)
|
|
native := NativeEndian()
|
|
b[0] = 0 // srh.nextHdr (0 when calling netlink)
|
|
b[1] = uint8(16 * nsegs >> 3) // srh.hdrLen (in 8-octets unit)
|
|
b[2] = IPV6_SRCRT_TYPE_4 // srh.routingType (assigned by IANA)
|
|
b[3] = uint8(nsegs - 1) // srh.segmentsLeft
|
|
b[4] = uint8(nsegs - 1) // srh.firstSegment
|
|
b[5] = 0 // srh.flags (SR6_FLAG1_HMAC for srh_hmac)
|
|
// srh.reserved: Defined as "Tag" in draft-ietf-6man-segment-routing-header-07
|
|
native.PutUint16(b[6:], 0) // srh.reserved
|
|
for _, netIP := range segments {
|
|
b = append(b, netIP...) // srh.Segments
|
|
}
|
|
return b, nil
|
|
}
|
|
|
|
// Helper functions
|
|
func SEG6EncapModeString(mode int) string {
|
|
switch mode {
|
|
case SEG6_IPTUN_MODE_INLINE:
|
|
return "inline"
|
|
case SEG6_IPTUN_MODE_ENCAP:
|
|
return "encap"
|
|
}
|
|
return "unknown"
|
|
}
|