Skip to content
This repository was archived by the owner on Mar 27, 2026. It is now read-only.

Commit b82ce5d

Browse files
committed
SRv6 endpoint encoding
1 parent 70a722c commit b82ce5d

File tree

1 file changed

+53
-4
lines changed

1 file changed

+53
-4
lines changed

main.go

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,14 @@ package main
22

33
import (
44
"context"
5+
"encoding/binary"
56
"fmt"
67
"golang.org/x/sync/errgroup"
78
"log"
9+
"net"
810
"os"
911
"os/signal"
12+
"strconv"
1013
"syscall"
1114

1215
"github.com/spf13/cobra"
@@ -19,6 +22,7 @@ import (
1922
var configFile string
2023

2124
func initConfig() {
25+
viper.SetDefault("srv6_net", "fc00::/56")
2226
viper.SetDefault("socket_path", "/var/run/galactic/agent.sock")
2327
viper.SetDefault("mqtt_host", "mqtt")
2428
viper.SetDefault("mqtt_port", 1883)
@@ -52,16 +56,35 @@ func main() {
5256
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
5357
defer stop() //nolint:errcheck
5458

59+
_, err := EncodeVPCToSRv6Endpoint(viper.GetString("srv6_net"), "ffffffffffff", "ffff")
60+
if err != nil {
61+
log.Fatalf("srv6_endpoint invalid: %v", err)
62+
}
63+
5564
l = local.Local{
5665
SocketPath: viper.GetString("socket_path"),
5766
RegisterHandler: func(vpc, vpcAttachment string, networks []string) error {
58-
log.Printf("REGISTER: vpc='%v', vpcattachment='%v', networks='%v'\n", vpc, vpcAttachment, networks)
59-
r.Send(fmt.Sprintf("REGISTER: vpc='%v', vpcattachment='%v', networks='%v'", vpc, vpcAttachment, networks))
67+
srv6_endpoint, err := EncodeVPCToSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
68+
if err != nil {
69+
return err
70+
}
71+
for _, n := range networks {
72+
payload := fmt.Sprintf("REGISTER: network='%s', srv6_endpoint='%s'", n, srv6_endpoint)
73+
log.Println(payload)
74+
r.Send(payload)
75+
}
6076
return nil
6177
},
6278
DeregisterHandler: func(vpc, vpcAttachment string, networks []string) error {
63-
log.Printf("DEREGISTER: vpc='%v', vpcattachment='%v', networks='%v'\n", vpc, vpcAttachment, networks)
64-
r.Send(fmt.Sprintf("DEREGISTER: vpc='%v', vpcattachment='%v', networks='%v'", vpc, vpcAttachment, networks))
79+
srv6_endpoint, err := EncodeVPCToSRv6Endpoint(viper.GetString("srv6_net"), vpc, vpcAttachment)
80+
if err != nil {
81+
return err
82+
}
83+
for _, n := range networks {
84+
payload := fmt.Sprintf("DEREGISTER: network='%s', srv6_endpoint='%s'", n, srv6_endpoint)
85+
log.Println(payload)
86+
r.Send(payload)
87+
}
6588
return nil
6689
},
6790
}
@@ -96,3 +119,29 @@ func main() {
96119
log.Fatalf("Execution failed: %v", err)
97120
}
98121
}
122+
123+
func EncodeVPCToSRv6Endpoint(srv6_net, vpc, vpcAttachment string) (string, error) {
124+
ip, ipnet, err := net.ParseCIDR(srv6_net)
125+
if err != nil {
126+
return "", err
127+
}
128+
if ip.To4() != nil {
129+
return "", fmt.Errorf("provided srv6_net is not IPv6: %s", srv6_net)
130+
}
131+
mask_len, _ := ipnet.Mask.Size()
132+
if mask_len > 64 {
133+
return "", fmt.Errorf("srv6_net must be at least 64 bits long")
134+
}
135+
136+
vpcInt, err := strconv.ParseUint(vpc, 16, 64)
137+
if err != nil {
138+
return "", fmt.Errorf("invalid vpc %q: %w", vpc, err)
139+
}
140+
vpcAttachmentInt, err := strconv.ParseUint(vpcAttachment, 16, 16)
141+
if err != nil {
142+
return "", fmt.Errorf("invalid vpcAttachment %q: %w", vpcAttachment, err)
143+
}
144+
145+
binary.BigEndian.PutUint64(ip[8:16], (vpcInt<<16)|vpcAttachmentInt)
146+
return ip.String(), nil
147+
}

0 commit comments

Comments
 (0)