From a7cca80731d35ed4780a8e347287187504e0422b Mon Sep 17 00:00:00 2001 From: David Coles Date: Mon, 24 Jun 2024 11:17:35 +0100 Subject: [PATCH] command channel for reattaching interfaces --- cmd/config.pl | 2 ++ cmd/go.mod | 2 +- cmd/go.sum | 4 ++-- cmd/main.go | 17 ++++++++++++++++ cmd/xvs.go | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 77 insertions(+), 3 deletions(-) diff --git a/cmd/config.pl b/cmd/config.pl index 70d4866..fb84084 100755 --- a/cmd/config.pl +++ b/cmd/config.pl @@ -239,6 +239,8 @@ sub expect { my($expect) = @_; my @expect; + return [ 0 ] if $expect eq 'any'; + foreach (split(/\s+/, $expect)) { my @val; diff --git a/cmd/go.mod b/cmd/go.mod index 392efaf..928bb0a 100644 --- a/cmd/go.mod +++ b/cmd/go.mod @@ -3,7 +3,7 @@ module vc5 go 1.19 require ( - github.com/davidcoles/cue v0.1.1 + github.com/davidcoles/cue v0.1.2 github.com/davidcoles/xvs v0.1.15 github.com/elastic/go-elasticsearch/v7 v7.17.10 ) diff --git a/cmd/go.sum b/cmd/go.sum index f56cd47..dc15fe6 100644 --- a/cmd/go.sum +++ b/cmd/go.sum @@ -1,5 +1,5 @@ -github.com/davidcoles/cue v0.1.1 h1:R2hG4gSVKuCj7UmTQGhZS/ZRmfDULqmA03uXwx7rgOg= -github.com/davidcoles/cue v0.1.1/go.mod h1:26FTBytVHJ1XQWOGC+Cfnx4Q9xV8k1xr6K5uZ7s/EBw= +github.com/davidcoles/cue v0.1.2 h1:UZnjl6ezaG7WC9iFbarB/+u7rDVa4aExSCx1ugtwMIU= +github.com/davidcoles/cue v0.1.2/go.mod h1:26FTBytVHJ1XQWOGC+Cfnx4Q9xV8k1xr6K5uZ7s/EBw= github.com/davidcoles/xvs v0.1.15 h1:FJ5CN0VEqyoilK/R0Pvc51lKpLsOTqcstPilkkxgbZw= github.com/davidcoles/xvs v0.1.15/go.mod h1:NQg6Ob9zLr49qH3I6E6zqnGp4tVBu4cT/3vXUB2XA8w= github.com/elastic/go-elasticsearch/v7 v7.17.10 h1:TCQ8i4PmIJuBunvBS6bwT2ybzVFxxUhhltAs3Gyu1yo= diff --git a/cmd/main.go b/cmd/main.go index cc57c09..3c06475 100644 --- a/cmd/main.go +++ b/cmd/main.go @@ -63,6 +63,7 @@ func main() { mp := flag.Bool("M", false, "Use multiprotocol extensions on loopback BGP") // experimental - may change delay := flag.Uint("D", 0, "Delay between initialisaton of interfaces") // experimental - may change flows := flag.Uint("F", 0, "Set maximum number of flows") // experimental - may change + cmd_path := flag.String("C", "", "Command channel path") // experimental - may change // Changing number of flows will only work on some kernels // Not supported: 5.4.0-171-generic @@ -148,6 +149,18 @@ func main() { go bgpListener(l, logs.sub("bgp")) } + var cmd_sock net.Listener + + if *cmd_path != "" { + os.Remove(*cmd_path) + + cmd_sock, err = net.Listen("unix", *cmd_path) + + if err != nil { + log.Fatal(err) + } + } + for _, i := range nics { ethtool(i) } @@ -170,6 +183,10 @@ func main() { log.Fatal("Couldn't start client: ", err) } + if cmd_sock != nil { + go readCommands(cmd_sock, client, logs.sub("command")) + } + routerID := address.As4() if *asn > 0 { diff --git a/cmd/xvs.go b/cmd/xvs.go index e4156e7..ce6ca67 100644 --- a/cmd/xvs.go +++ b/cmd/xvs.go @@ -32,6 +32,7 @@ import ( "net/netip" "os" "os/exec" + "regexp" "sync/atomic" "time" @@ -367,3 +368,57 @@ func multicast_recv(c Client, address string) { } } } + +func readCommands(sock net.Listener, client Client, log *sub) { + // eg.: echo enp130s0f0 | socat - UNIX-CLIENT:/var/run/vc5 + + re := regexp.MustCompile(`\s+`) + + for { + conn, err := sock.Accept() + if err != nil { + log.ERR("accept", err.Error()) + } else { + go func() { + s := bufio.NewScanner(conn) + + for s.Scan() { + + line := s.Text() + + var cmd []string + + for _, s := range re.Split(line, -1) { + if s != "" { + cmd = append(cmd, s) + } + } + + l := len(cmd) + + if l < 1 { + continue + } + + switch cmd[0] { + case "reattach": + if l != 2 { + fmt.Println("Usage: reattach ") + continue + } + + nic := cmd[1] + if err := client.ReattachBPF(nic); err != nil { + log.ERR(cmd[0], fmt.Sprintf("%s: %s\n", nic, err.Error())) + } else { + log.NOTICE(cmd[0], fmt.Sprintf("%s: OK\n", nic)) + } + + default: + log.ERR("unknown", fmt.Sprintf("Unknown command: %s", cmd[0])) + } + } + }() + } + } +}