Bug fixes and misc changes
- Fix DHCP longrun using up instead of run - Fix wireguard circular dependency - Use net/netip for anything but net.HardwareAddr - Add thetford-mines.canada functional example host - Add a navigator for the structure - Add helper functions - Fix types of some elements
This commit is contained in:
parent
0bcad8a5c6
commit
0d38256c5d
|
@ -1 +0,0 @@
|
||||||
hosts/
|
|
|
@ -3,6 +3,7 @@ package s6netdev
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -128,7 +129,7 @@ func (t *S6SvcTree) NetdevIfaceProp(iface Iface, p Property) *S6Svc {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *S6SvcTree) ConfigureIfaceAddr(iface Iface, addr string) *S6Svc {
|
func (t *S6SvcTree) NetdevConfigureIfaceMAC(iface Iface, addr net.HardwareAddr) *S6Svc {
|
||||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.ether.addr", iface.Name)).Sanitize()
|
svc_name := S6SvcName(fmt.Sprintf("interface.%s.ether.addr", iface.Name)).Sanitize()
|
||||||
|
|
||||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||||
|
@ -138,7 +139,7 @@ func (t *S6SvcTree) ConfigureIfaceAddr(iface Iface, addr string) *S6Svc {
|
||||||
ExeclineXDGConfig(),
|
ExeclineXDGConfig(),
|
||||||
ExeclineXDGEnvdirConfig(l.Name),
|
ExeclineXDGEnvdirConfig(l.Name),
|
||||||
ExeclineDefine("INTERFACE", iface.Name),
|
ExeclineDefine("INTERFACE", iface.Name),
|
||||||
ExeclineImportas("ADDRESS", false, addr),
|
ExeclineImportas("ADDRESS", false, addr.String()),
|
||||||
"ip link set $INTERFACE address $ADDRESS",
|
"ip link set $INTERFACE address $ADDRESS",
|
||||||
}, "\n")
|
}, "\n")
|
||||||
|
|
||||||
|
@ -177,7 +178,7 @@ func (t *S6SvcTree) NetdevIfaceDHCP(iface Iface, ipv int) *S6Svc {
|
||||||
if ipv == 6 {
|
if ipv == 6 {
|
||||||
daemon = fmt.Sprintf("%s%d", daemon, ipv)
|
daemon = fmt.Sprintf("%s%d", daemon, ipv)
|
||||||
}
|
}
|
||||||
l.Up = strings.Join([]string{
|
l.Run = strings.Join([]string{
|
||||||
NETDEV_EXECLINE_HEADER,
|
NETDEV_EXECLINE_HEADER,
|
||||||
ExeclineDefine("INTERFACE", iface.Name),
|
ExeclineDefine("INTERFACE", iface.Name),
|
||||||
"fdmove -c 2 1",
|
"fdmove -c 2 1",
|
||||||
|
@ -191,7 +192,7 @@ func (t *S6SvcTree) NetdevIfaceDHCP(iface Iface, ipv int) *S6Svc {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *S6SvcTree) netdevIfaceAddrTemplate(action, iface string, ipv int, addr net.IP) string {
|
func (t *S6SvcTree) netdevIfaceAddrTemplate(action, iface string, ipv int, addr netip.Prefix) string {
|
||||||
return strings.Join([]string{
|
return strings.Join([]string{
|
||||||
NETDEV_EXECLINE_HEADER,
|
NETDEV_EXECLINE_HEADER,
|
||||||
ExeclineDefine("INTERFACE", iface),
|
ExeclineDefine("INTERFACE", iface),
|
||||||
|
@ -201,8 +202,8 @@ func (t *S6SvcTree) netdevIfaceAddrTemplate(action, iface string, ipv int, addr
|
||||||
}, "\n")
|
}, "\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *S6SvcTree) NetdevIfaceAddr(iface Iface, addr net.IP) *S6Svc {
|
func (t *S6SvcTree) NetdevIfaceAddr(iface Iface, addr netip.Prefix) *S6Svc {
|
||||||
ipv := NetdevIPAddrVer(addr)
|
ipv := NetdevIPAddrVer(addr.Addr())
|
||||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.ip.addr.%d.%s", iface.Name, ipv, addr)).Sanitize()
|
svc_name := S6SvcName(fmt.Sprintf("interface.%s.ip.addr.%d.%s", iface.Name, ipv, addr)).Sanitize()
|
||||||
|
|
||||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||||
|
@ -223,7 +224,7 @@ func (t *S6SvcTree) netdevRouteTemplate(iface Iface, route Route) (up, down stri
|
||||||
|
|
||||||
cmd = []string{
|
cmd = []string{
|
||||||
"ip",
|
"ip",
|
||||||
fmt.Sprintf("-%d", NetdevIPAddrVer(route.Net.IP)), // IP version
|
fmt.Sprintf("-%d", NetdevIPAddrVer(route.Net.Addr())), // IP version
|
||||||
"route",
|
"route",
|
||||||
"%s",
|
"%s",
|
||||||
}
|
}
|
||||||
|
@ -247,7 +248,7 @@ func (t *S6SvcTree) netdevRouteTemplate(iface Iface, route Route) (up, down stri
|
||||||
cmd = append(cmd, "$ROUTE")
|
cmd = append(cmd, "$ROUTE")
|
||||||
svcname = append(svcname, r)
|
svcname = append(svcname, r)
|
||||||
|
|
||||||
if route.Via != nil {
|
if route.Via.IsValid() {
|
||||||
lines = append(lines, ExeclineImportas("VIA", false, route.Via.String()))
|
lines = append(lines, ExeclineImportas("VIA", false, route.Via.String()))
|
||||||
cmd = append(cmd, "via", "$VIA")
|
cmd = append(cmd, "via", "$VIA")
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net/netip"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.redxen.eu/caskd/s6-netdev"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
l = log.New(os.Stderr, "s6-netdev: ", log.Ltime|log.Lshortfile|log.Lmsgprefix)
|
||||||
|
)
|
||||||
|
t := s6netdev.S6NewTree()
|
||||||
|
|
||||||
|
// Main VRF
|
||||||
|
main_vrf := s6netdev.Iface{
|
||||||
|
Name: "vrf-main",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vrf,
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "br-main",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Bridge,
|
||||||
|
Routes: []s6netdev.Route{
|
||||||
|
{
|
||||||
|
Net: netip.MustParsePrefix("fd00::/64"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Properties: []s6netdev.Property{
|
||||||
|
{Key: "stp_state", Value: "1", Default: "0"},
|
||||||
|
{Key: "mcast_snooping", Value: "0", Default: "1"},
|
||||||
|
},
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "enp1s0",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Phys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.NavServices(main_vrf)
|
||||||
|
|
||||||
|
for _, v := range t.S6Services() {
|
||||||
|
if s6netdev.NetdevIsDummy(v.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
l.Printf("Commiting %s\n", v.Name)
|
||||||
|
if err = t.S6CommitService(v); err != nil {
|
||||||
|
l.Fatalf("Failed to commit %s, %s\n", v.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,184 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"git.redxen.eu/caskd/s6-netdev"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
var (
|
||||||
|
err error
|
||||||
|
l = log.New(os.Stderr, "s6-netdev: ", log.Ltime|log.Lshortfile|log.Lmsgprefix)
|
||||||
|
)
|
||||||
|
t := s6netdev.S6NewTree()
|
||||||
|
|
||||||
|
// No VRF
|
||||||
|
phys := s6netdev.Iface{
|
||||||
|
Name: "phys",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Bridge,
|
||||||
|
MACAddr: net.HardwareAddr{0x52, 0x54, 0x00, 0x81, 0xcb, 0x62},
|
||||||
|
DHCP: s6netdev.DHCP_IP{V4: true},
|
||||||
|
Properties: []s6netdev.Property{
|
||||||
|
{Key: "stp_state", Value: "1", Default: "0"},
|
||||||
|
{Key: "mcast_snooping", Value: "0", Default: "1"},
|
||||||
|
},
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "enp12s0",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Phys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.NavServices(phys)
|
||||||
|
|
||||||
|
// DN42 VRF
|
||||||
|
vrf_dn42 := s6netdev.Iface{
|
||||||
|
Name: "vrf-dn42",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vrf,
|
||||||
|
Table: 20,
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "br-dn42",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Bridge,
|
||||||
|
Properties: []s6netdev.Property{
|
||||||
|
{Key: "stp_state", Value: "0", Default: "0"},
|
||||||
|
{Key: "mcast_snooping", Value: "0", Default: "1"},
|
||||||
|
},
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "enp15s0",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Phys,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "phys.42",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vlan,
|
||||||
|
VlanId: 42,
|
||||||
|
Parent: &phys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.NavServices(vrf_dn42)
|
||||||
|
|
||||||
|
// V6 VRF
|
||||||
|
vrf_v6 := s6netdev.Iface{
|
||||||
|
Name: "vrf-v6",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vrf,
|
||||||
|
Table: 10,
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "vultrbgp",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Wireguard,
|
||||||
|
Addresses: []netip.Prefix{
|
||||||
|
netip.MustParsePrefix("fe80::2/64"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "b00b",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Bridge,
|
||||||
|
MACAddr: net.HardwareAddr{0x02, 0x00, 0x00, 0x01, 0xb0, 0x0b},
|
||||||
|
Addresses: []netip.Prefix{
|
||||||
|
netip.MustParsePrefix("2a04:5b81:2060:b00b::2/64"),
|
||||||
|
},
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "phys.66",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vlan,
|
||||||
|
VlanId: 66,
|
||||||
|
Parent: &phys,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "enp9s0",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Phys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Sysctls: s6netdev.Sysctl_IP{
|
||||||
|
V6: []s6netdev.Property{
|
||||||
|
{Key: "forwarding", Value: "0", Default: "0"},
|
||||||
|
{Key: "autoconf", Value: "0", Default: "0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Properties: []s6netdev.Property{
|
||||||
|
{Key: "stp_state", Value: "0", Default: "0"},
|
||||||
|
{Key: "mcast_snooping", Value: "0", Default: "1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "f33d",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Bridge,
|
||||||
|
MACAddr: net.HardwareAddr{0x02, 0x00, 0x00, 0x01, 0xf3, 0x3d},
|
||||||
|
Addresses: []netip.Prefix{
|
||||||
|
netip.MustParsePrefix("2a04:5b81:2060:f33d::2/64"),
|
||||||
|
},
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "phys.100",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vlan,
|
||||||
|
VlanId: 100,
|
||||||
|
Parent: &phys,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "enp14s0",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Phys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Sysctls: s6netdev.Sysctl_IP{
|
||||||
|
V6: []s6netdev.Property{
|
||||||
|
{Key: "forwarding", Value: "0", Default: "0"},
|
||||||
|
{Key: "autoconf", Value: "0", Default: "0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Properties: []s6netdev.Property{
|
||||||
|
{Key: "stp_state", Value: "0", Default: "0"},
|
||||||
|
{Key: "mcast_snooping", Value: "0", Default: "1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "d00d",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Bridge,
|
||||||
|
MACAddr: net.HardwareAddr{0x02, 0x00, 0x00, 0x01, 0xd0, 0x0d},
|
||||||
|
Addresses: []netip.Prefix{
|
||||||
|
netip.MustParsePrefix("2a04:5b81:2060:d00d::2/64"),
|
||||||
|
},
|
||||||
|
Slaves: []*s6netdev.Iface{
|
||||||
|
{
|
||||||
|
Name: "phys.101",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Vlan,
|
||||||
|
VlanId: 101,
|
||||||
|
Parent: &phys,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "enp13s0",
|
||||||
|
Type: &s6netdev.NetdevIfTypes.Phys,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Sysctls: s6netdev.Sysctl_IP{
|
||||||
|
V6: []s6netdev.Property{
|
||||||
|
{Key: "forwarding", Value: "0", Default: "0"},
|
||||||
|
{Key: "autoconf", Value: "0", Default: "0"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Properties: []s6netdev.Property{
|
||||||
|
{Key: "stp_state", Value: "0", Default: "0"},
|
||||||
|
{Key: "mcast_snooping", Value: "0", Default: "1"},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
t.NavServices(vrf_v6)
|
||||||
|
|
||||||
|
for _, v := range t.S6Services() {
|
||||||
|
if s6netdev.NetdevIsDummy(v.Name) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
l.Printf("Commiting %s\n", v.Name)
|
||||||
|
if err = t.S6CommitService(v); err != nil {
|
||||||
|
l.Fatalf("Failed to commit %s, %s\n", v.Name, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
160
interfaces.go
160
interfaces.go
|
@ -2,136 +2,58 @@ package s6netdev
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"strings"
|
"net"
|
||||||
|
"net/netip"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *S6SvcTree) Services(i Iface) (r []*S6Svc) {
|
func (i *Iface) NetdevIfaceAddAddr(addr string) (err error) {
|
||||||
r = append(r, t.ConfigureServices(i)...)
|
var (
|
||||||
r = append(r, t.ReadyServices(i)...)
|
a netip.Prefix
|
||||||
|
)
|
||||||
|
if a, err = netip.ParsePrefix(addr); err != nil {
|
||||||
|
err = fmt.Errorf("Failed to parse address %s, %w", addr, err)
|
||||||
|
}
|
||||||
|
i.Addresses = append(i.Addresses, a)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *S6SvcTree) ConfigureServices(i Iface) (r []*S6Svc) {
|
func (i *Iface) NetdevIfaceAddRoute(route, r_type, via string, vrf *Iface, table *RouteTable, metric Metric) (err error) {
|
||||||
svc_create := t.CreateIfaceService(i.Name)
|
var (
|
||||||
r = append(r, svc_create)
|
r = Route{
|
||||||
|
Type: r_type,
|
||||||
|
Vrf: vrf,
|
||||||
|
Table: table,
|
||||||
|
Metric: metric,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
// Defaults to be overridden
|
if via != "" {
|
||||||
svc_create.Up = strings.Join([]string{
|
if r.Via, err = netip.ParseAddr(via); err != nil {
|
||||||
NETDEV_EXECLINE_HEADER,
|
err = fmt.Errorf("Failed to parse via %s, %w", via, err)
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
fmt.Sprintf("ip link add $INTERFACE type %s", i.Type.str),
|
|
||||||
}, "\n")
|
|
||||||
svc_create.Down = strings.Join([]string{
|
|
||||||
NETDEV_EXECLINE_HEADER,
|
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
"ip link del dev $INTERFACE",
|
|
||||||
}, "\n")
|
|
||||||
|
|
||||||
for _, v := range i.Type.deps {
|
|
||||||
// External dummy services, should be ignored at commit
|
|
||||||
cs := t.S6New(S6SvcName(v), &S6SvcTypes.Oneshot)
|
|
||||||
svc_create.S6Children(cs)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Overrides
|
|
||||||
switch i.Type {
|
|
||||||
case &NetdevIfTypes.Phys:
|
|
||||||
fallthrough
|
|
||||||
case &NetdevIfTypes.Loopback:
|
|
||||||
{
|
|
||||||
svc_create.Up = strings.Join([]string{
|
|
||||||
NETDEV_EXECLINE_HEADER,
|
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
"bcnm-waitif 1 $INTERFACE",
|
|
||||||
}, "\n")
|
|
||||||
svc_create.Down = ""
|
|
||||||
}
|
|
||||||
case &NetdevIfTypes.Vlan:
|
|
||||||
{
|
|
||||||
svc_create.Up = strings.Join([]string{
|
|
||||||
NETDEV_EXECLINE_HEADER,
|
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
ExeclineDefine("PARENT", i.Parent.Name),
|
|
||||||
ExeclineDefine("VLAN", fmt.Sprintf("%d", i.VlanId)),
|
|
||||||
fmt.Sprintf("ip link add link $PARENT name $INTERFACE type %s id $VLAN", i.Type.str),
|
|
||||||
}, "\n")
|
|
||||||
svc_create.S6Children(t.CreateIfaceService(i.Parent.Name))
|
|
||||||
}
|
|
||||||
case &NetdevIfTypes.Vrf:
|
|
||||||
{
|
|
||||||
// Default if no table defined
|
|
||||||
if i.Table == 0 {
|
|
||||||
i.Table = RouteTable(500)
|
|
||||||
}
|
|
||||||
svc_create.Up = strings.Join([]string{
|
|
||||||
NETDEV_EXECLINE_HEADER,
|
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
ExeclineDefine("TABLE", fmt.Sprintf("%d", i.Table)),
|
|
||||||
fmt.Sprintf("ip link add $INTERFACE type %s table $TABLE", i.Type.str),
|
|
||||||
}, "\n")
|
|
||||||
}
|
|
||||||
case &NetdevIfTypes.Wireguard:
|
|
||||||
{
|
|
||||||
wg_cfg := t.NetdevWireguardConfig(i)
|
|
||||||
svc_create.S6Children(wg_cfg)
|
|
||||||
r = append(r, wg_cfg)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, v := range i.Slaves {
|
i.Routes = append(i.Routes, r)
|
||||||
r = append(r, t.NetdevEnslaveInterface(v.Name, i.Name))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range i.Properties {
|
|
||||||
r = append(r, t.NetdevIfaceProp(i, v))
|
|
||||||
}
|
|
||||||
|
|
||||||
if i.DHCP.V4 {
|
|
||||||
r = append(r, t.NetdevIfaceDHCP(i, 4))
|
|
||||||
}
|
|
||||||
if i.DHCP.V6 {
|
|
||||||
r = append(r, t.NetdevIfaceDHCP(i, 6))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range i.Sysctls.V4 {
|
|
||||||
r = append(r, t.NetdevIfaceIpSysctl(i, 4, v))
|
|
||||||
}
|
|
||||||
for _, v := range i.Sysctls.V6 {
|
|
||||||
r = append(r, t.NetdevIfaceIpSysctl(i, 6, v))
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, v := range i.Addresses {
|
|
||||||
r = append(r, t.NetdevIfaceAddr(i, v))
|
|
||||||
}
|
|
||||||
for _, v := range i.Routes {
|
|
||||||
r = append(r, t.NetdevRoute(i, v))
|
|
||||||
}
|
|
||||||
|
|
||||||
bundle_configure := t.NetdevDependBundleStage(i.Name, "configure", svc_create)
|
|
||||||
r = append(r, bundle_configure)
|
|
||||||
r = append(r, svc_create.Children...)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *S6SvcTree) ReadyServices(i Iface) (r []*S6Svc) {
|
func (i *Iface) NetdevIfaceMAC(mac string) (err error) {
|
||||||
svc_link := t.S6New(S6SvcName(fmt.Sprintf("interface.%s.link", i.Name)), &S6SvcTypes.Oneshot)
|
i.MACAddr, err = net.ParseMAC(mac)
|
||||||
r = append(r, svc_link)
|
|
||||||
|
|
||||||
svc_link.Up = strings.Join([]string{
|
|
||||||
NETDEV_EXECLINE_HEADER,
|
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
"ip link set dev $INTERFACE up",
|
|
||||||
}, "\n")
|
|
||||||
svc_link.Down = strings.Join([]string{
|
|
||||||
NETDEV_EXECLINE_HEADER,
|
|
||||||
ExeclineDefine("INTERFACE", i.Name),
|
|
||||||
"ip link set dev $INTERFACE down",
|
|
||||||
}, "\n")
|
|
||||||
svc_link.S6Children(t.CreateIfaceService(i.Name))
|
|
||||||
|
|
||||||
bundle_ready := t.NetdevDependBundleStage(i.Name, "ready", svc_link)
|
|
||||||
r = append(r, bundle_ready)
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i *Iface) NetdevIfaceEnslave(s ...*Iface) {
|
||||||
|
i.Slaves = append(i.Slaves, s...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Iface) NetdevIfaceSysctl(ipv int, key, value, def string) {
|
||||||
|
l := &i.Sysctls.V4
|
||||||
|
if ipv == 6 {
|
||||||
|
l = &i.Sysctls.V6
|
||||||
|
}
|
||||||
|
*l = append(*l, Property{Key: key, Value: value, Default: def})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (i *Iface) NetdevIfaceProperty(key, value, def string) {
|
||||||
|
i.Properties = append(i.Properties, Property{Key: key, Value: value, Default: def})
|
||||||
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package s6netdev
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"net"
|
||||||
|
"net/netip"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -42,8 +43,8 @@ func (t *S6SvcTree) NetdevEnslaveInterface(iface, master string) *S6Svc {
|
||||||
return l
|
return l
|
||||||
}
|
}
|
||||||
|
|
||||||
func NetdevIPAddrVer(IP net.IP) int {
|
func NetdevIPAddrVer(IP netip.Addr) int {
|
||||||
if IP.To4() == nil {
|
if IP.Is6() {
|
||||||
return 6
|
return 6
|
||||||
}
|
}
|
||||||
return 4
|
return 4
|
||||||
|
@ -53,3 +54,7 @@ func NetdevIsDummy(s S6SvcName) (r bool) {
|
||||||
_, r = dummy_svc_blacklist[s]
|
_, r = dummy_svc_blacklist[s]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NetdevOnlyMAC(x net.HardwareAddr, _ error) net.HardwareAddr {
|
||||||
|
return x
|
||||||
|
}
|
141
services.go
141
services.go
|
@ -2,6 +2,7 @@ package s6netdev
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (t *S6SvcTree) CreateIfaceService(iface string) *S6Svc {
|
func (t *S6SvcTree) CreateIfaceService(iface string) *S6Svc {
|
||||||
|
@ -11,3 +12,143 @@ func (t *S6SvcTree) CreateIfaceService(iface string) *S6Svc {
|
||||||
func (t *S6SvcTree) LinkIfaceService(iface string) *S6Svc {
|
func (t *S6SvcTree) LinkIfaceService(iface string) *S6Svc {
|
||||||
return t.S6New(S6SvcName(fmt.Sprintf("interface.%s.link", iface)), &S6SvcTypes.Oneshot)
|
return t.S6New(S6SvcName(fmt.Sprintf("interface.%s.link", iface)), &S6SvcTypes.Oneshot)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *S6SvcTree) NavServices(i Iface) (r []*S6Svc) {
|
||||||
|
r = t.Services(i)
|
||||||
|
if i.Parent != nil {
|
||||||
|
r = append(r, t.NavServices(*i.Parent)...)
|
||||||
|
}
|
||||||
|
for _, v := range i.Slaves {
|
||||||
|
r = append(r, t.NavServices(*v)...)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *S6SvcTree) Services(i Iface) (r []*S6Svc) {
|
||||||
|
r = append(r, t.ConfigureServices(i)...)
|
||||||
|
r = append(r, t.ReadyServices(i)...)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *S6SvcTree) ConfigureServices(i Iface) (r []*S6Svc) {
|
||||||
|
svc_create := t.CreateIfaceService(i.Name)
|
||||||
|
r = append(r, svc_create)
|
||||||
|
|
||||||
|
// Defaults to be overridden
|
||||||
|
svc_create.Up = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
fmt.Sprintf("ip link add $INTERFACE type %s", i.Type.str),
|
||||||
|
}, "\n")
|
||||||
|
svc_create.Down = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
"ip link del dev $INTERFACE",
|
||||||
|
}, "\n")
|
||||||
|
|
||||||
|
for _, v := range i.Type.deps {
|
||||||
|
// External dummy services, should be ignored at commit
|
||||||
|
cs := t.S6New(S6SvcName(v), &S6SvcTypes.Oneshot)
|
||||||
|
svc_create.S6Children(cs)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Overrides
|
||||||
|
switch i.Type {
|
||||||
|
case &NetdevIfTypes.Phys:
|
||||||
|
fallthrough
|
||||||
|
case &NetdevIfTypes.Loopback:
|
||||||
|
{
|
||||||
|
svc_create.Up = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
"bcnm-waitif 1 $INTERFACE",
|
||||||
|
}, "\n")
|
||||||
|
svc_create.Down = ""
|
||||||
|
}
|
||||||
|
case &NetdevIfTypes.Vlan:
|
||||||
|
{
|
||||||
|
svc_create.Up = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
ExeclineDefine("PARENT", i.Parent.Name),
|
||||||
|
ExeclineDefine("VLAN", fmt.Sprintf("%d", i.VlanId)),
|
||||||
|
fmt.Sprintf("ip link add link $PARENT name $INTERFACE type %s id $VLAN", i.Type.str),
|
||||||
|
}, "\n")
|
||||||
|
svc_create.S6Children(t.CreateIfaceService(i.Parent.Name))
|
||||||
|
}
|
||||||
|
case &NetdevIfTypes.Vrf:
|
||||||
|
{
|
||||||
|
// Default if no table defined
|
||||||
|
if i.Table == 0 {
|
||||||
|
i.Table = RouteTable(1924)
|
||||||
|
}
|
||||||
|
svc_create.Up = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
ExeclineDefine("TABLE", fmt.Sprintf("%d", i.Table)),
|
||||||
|
fmt.Sprintf("ip link add $INTERFACE type %s table $TABLE", i.Type.str),
|
||||||
|
}, "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range i.Slaves {
|
||||||
|
r = append(r, t.NetdevEnslaveInterface(v.Name, i.Name))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range i.Properties {
|
||||||
|
r = append(r, t.NetdevIfaceProp(i, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
if i.DHCP.V4 {
|
||||||
|
r = append(r, t.NetdevIfaceDHCP(i, 4))
|
||||||
|
}
|
||||||
|
if i.DHCP.V6 {
|
||||||
|
r = append(r, t.NetdevIfaceDHCP(i, 6))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range i.Sysctls.V4 {
|
||||||
|
r = append(r, t.NetdevIfaceIpSysctl(i, 4, v))
|
||||||
|
}
|
||||||
|
for _, v := range i.Sysctls.V6 {
|
||||||
|
r = append(r, t.NetdevIfaceIpSysctl(i, 6, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, v := range i.Addresses {
|
||||||
|
r = append(r, t.NetdevIfaceAddr(i, v))
|
||||||
|
}
|
||||||
|
for _, v := range i.Routes {
|
||||||
|
r = append(r, t.NetdevRoute(i, v))
|
||||||
|
}
|
||||||
|
|
||||||
|
if i.MACAddr != nil {
|
||||||
|
r = append(r, t.NetdevConfigureIfaceMAC(i, i.MACAddr))
|
||||||
|
}
|
||||||
|
|
||||||
|
bundle_configure := t.NetdevDependBundleStage(i.Name, "configure", svc_create)
|
||||||
|
r = append(r, bundle_configure)
|
||||||
|
r = append(r, svc_create.Children...)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *S6SvcTree) ReadyServices(i Iface) (r []*S6Svc) {
|
||||||
|
svc_link := t.S6New(S6SvcName(fmt.Sprintf("interface.%s.link", i.Name)), &S6SvcTypes.Oneshot)
|
||||||
|
r = append(r, svc_link)
|
||||||
|
|
||||||
|
svc_link.Up = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
"ip link set dev $INTERFACE up",
|
||||||
|
}, "\n")
|
||||||
|
svc_link.Down = strings.Join([]string{
|
||||||
|
NETDEV_EXECLINE_HEADER,
|
||||||
|
ExeclineDefine("INTERFACE", i.Name),
|
||||||
|
"ip link set dev $INTERFACE down",
|
||||||
|
}, "\n")
|
||||||
|
svc_link.S6Children(t.netdevCreateBundleStage(i.Name, "configure"))
|
||||||
|
|
||||||
|
bundle_ready := t.NetdevDependBundleStage(i.Name, "ready", svc_link)
|
||||||
|
r = append(r, bundle_ready)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
23
types.go
23
types.go
|
@ -1,6 +1,9 @@
|
||||||
package s6netdev
|
package s6netdev
|
||||||
|
|
||||||
import "net"
|
import (
|
||||||
|
"net"
|
||||||
|
"net/netip"
|
||||||
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
RouteTable uint16
|
RouteTable uint16
|
||||||
|
@ -13,7 +16,11 @@ type Property struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Sysctl_IP struct {
|
type Sysctl_IP struct {
|
||||||
V4, V6 []Property // Should we start dhcp on this interface?
|
V4, V6 []Property
|
||||||
|
}
|
||||||
|
|
||||||
|
type DHCP_IP struct {
|
||||||
|
V4, V6 bool // Should we start dhcp on this interface?
|
||||||
}
|
}
|
||||||
|
|
||||||
type Iface struct {
|
type Iface struct {
|
||||||
|
@ -26,14 +33,12 @@ type Iface struct {
|
||||||
|
|
||||||
Table RouteTable // Routing table, for VRF
|
Table RouteTable // Routing table, for VRF
|
||||||
|
|
||||||
MACAddr []byte // MAC address of interface (only valid for physical, bridges and VLAN)
|
MACAddr net.HardwareAddr // MAC address of interface (only valid for physical, bridges and VLAN)
|
||||||
|
|
||||||
Addresses []net.IP // Addresses to be assigned to interface
|
Addresses []netip.Prefix // Addresses to be assigned to interface
|
||||||
Routes []Route // Routes to be assigned to interface
|
Routes []Route // Routes to be assigned to interface
|
||||||
|
|
||||||
DHCP struct {
|
DHCP DHCP_IP // Should we start dhcp on this interface?
|
||||||
V4, V6 bool // Should we start dhcp on this interface?
|
|
||||||
}
|
|
||||||
|
|
||||||
Properties []Property // List of properties of the interface, valid for many
|
Properties []Property // List of properties of the interface, valid for many
|
||||||
Sysctls Sysctl_IP // Sysctls associated with this interface
|
Sysctls Sysctl_IP // Sysctls associated with this interface
|
||||||
|
@ -43,8 +48,8 @@ type Route struct {
|
||||||
Default bool
|
Default bool
|
||||||
// VRF would be a field but it can be derived from parent
|
// VRF would be a field but it can be derived from parent
|
||||||
Type string // unicast default, can be others
|
Type string // unicast default, can be others
|
||||||
Net net.IPNet
|
Net netip.Prefix
|
||||||
Via *net.IP
|
Via netip.Addr
|
||||||
Vrf *Iface
|
Vrf *Iface
|
||||||
Table *RouteTable
|
Table *RouteTable
|
||||||
Metric Metric // Should be explicitly initialised to 1024
|
Metric Metric // Should be explicitly initialised to 1024
|
||||||
|
|
Loading…
Reference in New Issue