Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
louisroyer committed Jun 21, 2024
1 parent a410800 commit 570a754
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 0 deletions.
15 changes: 15 additions & 0 deletions internal/ctrl/rules-registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package ctrl
import (
"fmt"
"net/http"
"net/netip"
"sync"

"github.com/gin-gonic/gin"
Expand All @@ -26,6 +27,20 @@ func NewRulesRegistry() *RulesRegistry {
}
}

func (rr *RulesRegistry) Action(dstIp netip.Addr) (jsonapi.Action, error) {
rr.RLock()
defer rr.RUnlock()
for _, r := range rr.rules {
if !r.Enabled {
continue
}
if r.Match.DstIpPrefix.Contains(dstIp) {
return r.Action, nil
}
}
return jsonapi.Action{}, fmt.Errorf("Not found")
}

func (rr *RulesRegistry) GetRule(c *gin.Context) {
id := c.Param("uuid")
iduuid, err := uuid.FromString(id)
Expand Down
60 changes: 60 additions & 0 deletions internal/netfunc/headend-encaps-ctrl.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ package netfunc

import (
"fmt"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
gopacket_srv6 "github.com/nextmn/gopacket-srv6"
"net"
"net/netip"

"github.com/nextmn/srv6/internal/ctrl"
Expand All @@ -25,5 +29,61 @@ func NewHeadendEncapsWithCtrl(prefix netip.Prefix, rr *ctrl.RulesRegistry, ttl u

// Handle a packet
func (h HeadendEncapsWithCtrl) Handle(packet []byte) ([]byte, error) {
pqt, err := NewIPv4Packet(packet)
if err != nil {
return nil, err
}
if err := h.CheckDAInPrefixRange(pqt); err != nil {
return nil, err
}
action, err := pqt.Action(h.RulesRegistry)
if err != nil {
return nil, err
}
src := net.ParseIP("::") // FIXME: don't hardcode
nextHop := net.ParseIP(action.SRH) // FIXME: allow multiple segments
ipheader := &layers.IPv6{
SrcIP: src,
// S06. Set the IPv6 DA = B
DstIP: nextHop,
Version: 6,
NextHeader: layers.IPProtocolIPv6Routing, // IPv6-Route
HopLimit: h.HopLimit(),
// TODO: Generate a FlowLabel with hash(IPv6SA + IPv6DA + policy)
TrafficClass: 0, // FIXME: put this in Action
}
// FIXME: allow multiple segments
//segList := append([]net.IP{seg0}, bsid.ReverseSegmentsList()...)
segList := []net.IP{nextHop}
srh := &gopacket_srv6.IPv6Routing{
RoutingType: 4,
// the first item on segments list is the next endpoint
SegmentsLeft: uint8(len(segList) - 1), // pointer to next segment
SourceRoutingIPs: segList,
Tag: 0, // not used
Flags: 0, // no flag defined
GopacketIpv6ExtensionBase: gopacket_srv6.GopacketIpv6ExtensionBase{
NextHeader: layers.IPProtocolIPv4,
},
}

// Encapsulate the packet into a new IPv6 header
buf := gopacket.NewSerializeBuffer()
if err := gopacket.SerializeLayers(buf,
gopacket.SerializeOptions{
FixLengths: true,
ComputeChecksums: true,
},
ipheader,
srh,
gopacket.Payload(pqt.Packet.Layers()[0].LayerContents()),
gopacket.Payload(pqt.Packet.Layers()[0].LayerPayload()),
); err != nil {
return nil, err
} else {
// Forward along the shortest path to B
return buf.Bytes(), nil
}

return nil, fmt.Errorf("Not yet implemented")
}
12 changes: 12 additions & 0 deletions internal/netfunc/packet.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import (

"github.com/google/gopacket"
"github.com/google/gopacket/layers"
json_api "github.com/nextmn/json-api/jsonapi"
"github.com/nextmn/srv6/internal/constants"
"github.com/nextmn/srv6/internal/ctrl"
)

type Packet struct {
Expand Down Expand Up @@ -72,6 +74,16 @@ func (p *Packet) CheckDAInPrefixRange(prefix netip.Prefix) error {
return nil
}

// Returns the Action related to this packet
func (p *Packet) Action(rr *ctrl.RulesRegistry) (json_api.Action, error) {
dstSlice := p.NetworkLayer().NetworkFlow().Dst().Raw()
dst, ok := netip.AddrFromSlice(dstSlice)
if !ok {
return json_api.Action{}, fmt.Errorf("Malformed packet")
}
return rr.Action(dst)
}

// Returns the first gopacket.Layer after IPv6 header / extension headers
func (p *Packet) PopIPv6Headers() (gopacket.Layer, error) {
if p.firstLayerType != layers.LayerTypeIPv6 {
Expand Down

0 comments on commit 570a754

Please sign in to comment.