@@ -2,11 +2,14 @@ package main
22
33import (
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 (
1922var configFile string
2023
2124func 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