}
type Link struct {
+ Layer3 bool
+
A struct {
Node *Node
Addrs []netip.Prefix
err = parseConfigNode(&cfg, xs[1:])
case "link":
usage = `"link" <node> <node> <net-name>`
- err = parseConfigLink(&cfg, xs[1:])
+ err = parseConfigLink(&cfg, xs[1:], false)
+ case "link-l3":
+ usage = `"link-l3" <node> <node> <net-name>`
+ err = parseConfigLink(&cfg, xs[1:], true)
case "cmd":
usage = `"cmd" <string-passed-to-sh-c>`
x := strings.TrimSpace(strings.TrimPrefix(l, "cmd"))
return nil
}
-func parseConfigLink(cfg *Config, args []string) error {
+func parseConfigLink(cfg *Config, args []string, l3 bool) error {
if len(args) != 3 {
return fmt.Errorf("invalid arguments")
}
}
var l Link
+ l.Layer3 = l3
l.A.Node = n1
l.B.Node = n2
lb = nextFreeIface(nsb, lb)
}
- ip("link", "add", "tmpa", "type", "veth", "peer", "name", "tmpb")
+ t := "veth"
+ if link.Layer3 {
+ t = "netkit" // since kernel 6.7, iproute2 6.8
+ }
+ ip("link", "add", "tmpa", "type", t, "peer", "name", "tmpb")
ip("link", "set", "tmpa", "netns", nsa)
ip("link", "set", "tmpb", "netns", nsb)
ip("-n", nsa, "link", "set", "tmpa", "name", la)