Switch to golang version
This commit is contained in:
parent
f4043a1a9b
commit
0bcad8a5c6
|
@ -0,0 +1 @@
|
|||
hosts/
|
|
@ -0,0 +1,7 @@
|
|||
Copyright 2024 Alex Denes
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
4
NOTES.md
4
NOTES.md
|
@ -1,4 +0,0 @@
|
|||
# KNOWN BUGS
|
||||
|
||||
- Currently the static address adds don't check if interface is a wireguard interface
|
||||
- wg tool doesn't lock the interface when it loads the config and the static address gets swallowed away without any error message
|
|
@ -0,0 +1,3 @@
|
|||
# s6-netdev
|
||||
|
||||
This is a project which can generate s6 service definitions based on a structured definition. It's intended to be used together with nnd but can be adapted to be used with any other distribution based on s6.
|
|
@ -0,0 +1,30 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (t *S6SvcTree) netdevCreateBundleAll(ifsvc *S6Svc) *S6Svc {
|
||||
bundle_name := S6SvcName("bundle.s6netdev")
|
||||
b := t.S6New(bundle_name, &S6SvcTypes.Bundle)
|
||||
b.S6Children(ifsvc)
|
||||
return b
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) netdevCreateBundleStage(iface, stage string) *S6Svc {
|
||||
bundle_name := S6SvcName(fmt.Sprintf("bundle.interface.%s", iface))
|
||||
stage_name := S6SvcName(fmt.Sprintf("%s.%s", bundle_name, stage))
|
||||
|
||||
b := t.S6New(bundle_name, &S6SvcTypes.Bundle)
|
||||
t.netdevCreateBundleAll(b)
|
||||
|
||||
s := t.S6New(stage_name, &S6SvcTypes.Bundle)
|
||||
b.S6Children(s)
|
||||
return s
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevDependBundleStage(iface, stage string, svcs ...*S6Svc) *S6Svc {
|
||||
b := t.netdevCreateBundleStage(iface, stage)
|
||||
b.S6Children(svcs...)
|
||||
return b
|
||||
}
|
|
@ -0,0 +1,297 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func (t *S6SvcTree) NetdevIfaceCreate(iface Iface, iftype *NetdevIfType) *S6Svc {
|
||||
l := t.CreateIfaceService(iface.Name)
|
||||
|
||||
// Defaults to be overridden
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
fmt.Sprintf("ip link add $INTERFACE type %s", iface.Type.str),
|
||||
}, "\n")
|
||||
l.Down = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
"ip link del dev $INTERFACE",
|
||||
}, "\n")
|
||||
|
||||
for _, v := range iftype.deps {
|
||||
// External dummy services, should be ignored at commit
|
||||
cs := t.S6New(S6SvcName(v), &S6SvcTypes.Oneshot)
|
||||
l.S6Children(cs)
|
||||
}
|
||||
|
||||
// Overrides
|
||||
switch iftype {
|
||||
case &NetdevIfTypes.Phys:
|
||||
{
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
"bcnm-waitif 1 $INTERFACE",
|
||||
}, "\n")
|
||||
l.Down = ""
|
||||
}
|
||||
case &NetdevIfTypes.Vlan:
|
||||
{
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
ExeclineDefine("PARENT", iface.Parent.Name),
|
||||
ExeclineDefine("VLAN", fmt.Sprintf("%d", iface.VlanId)),
|
||||
fmt.Sprintf("ip link add link $PARENT name $INTERFACE type %s id $VLAN", iface.Type.str),
|
||||
}, "\n")
|
||||
l.S6Children(t.CreateIfaceService(iface.Parent.Name))
|
||||
}
|
||||
case &NetdevIfTypes.Vrf:
|
||||
{
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
ExeclineDefine("TABLE", fmt.Sprintf("%d", iface.Table)),
|
||||
fmt.Sprintf("ip link add $INTERFACE type %s table $TABLE", iface.Type.str),
|
||||
}, "\n")
|
||||
}
|
||||
}
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevIfaceIpSysctl(iface Iface, ipv int, p Property) *S6Svc {
|
||||
svc_name := S6SvcName(fmt.Sprintf("sysctl.net-ipv%d-conf-%s-%s", ipv, iface.Name, p.Key)).Sanitize()
|
||||
sysctl_path := fmt.Sprintf("net/ipv%d/conf/%s/%s", ipv, iface.Name, p.Key)
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||
l.S6Children(t.S6New("mount.proc", &S6SvcTypes.Oneshot))
|
||||
if ipv == 6 {
|
||||
l.S6Children(t.S6New("module.ipv6", &S6SvcTypes.Oneshot))
|
||||
}
|
||||
|
||||
for _, v := range []struct {
|
||||
prop *string
|
||||
val string
|
||||
}{
|
||||
{&l.Up, p.Value},
|
||||
{&l.Down, p.Default},
|
||||
} {
|
||||
*v.prop = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineXDGConfig(),
|
||||
ExeclineXDGEnvdirConfig(l.Name),
|
||||
ExeclineExport("SYSCTL", sysctl_path),
|
||||
// Set default if not exported
|
||||
ExeclineImportas("VAL", false, v.val),
|
||||
ExeclineExport("VAL", "$VAL"),
|
||||
NNDLibExec("sysctl"),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
l.S6Children(t.CreateIfaceService(iface.Name))
|
||||
t.NetdevDependBundleStage(iface.Name, "configure", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevIfaceProp(iface Iface, p Property) *S6Svc {
|
||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.property.%s", iface.Name, p.Key)).Sanitize()
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||
|
||||
for _, v := range []struct {
|
||||
prop *string
|
||||
val string
|
||||
}{
|
||||
{&l.Up, p.Value},
|
||||
{&l.Down, p.Default},
|
||||
} {
|
||||
*v.prop = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineXDGConfig(),
|
||||
ExeclineXDGEnvdirConfig(l.Name),
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
ExeclineDefine("PROP", p.Key),
|
||||
ExeclineImportas("TYPE", false, iface.Type.str),
|
||||
ExeclineImportas("VAL", false, v.val),
|
||||
"ip link set dev $INTERFACE type $TYPE $PROP $VAL",
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
l.S6Children(t.CreateIfaceService(iface.Name))
|
||||
t.NetdevDependBundleStage(iface.Name, "configure", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) ConfigureIfaceAddr(iface Iface, addr string) *S6Svc {
|
||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.ether.addr", iface.Name)).Sanitize()
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineXDGConfig(),
|
||||
ExeclineXDGEnvdirConfig(l.Name),
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
ExeclineImportas("ADDRESS", false, addr),
|
||||
"ip link set $INTERFACE address $ADDRESS",
|
||||
}, "\n")
|
||||
|
||||
l.S6Children(t.CreateIfaceService(iface.Name))
|
||||
t.NetdevDependBundleStage(iface.Name, "configure", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevWireguardConfig(iface Iface) *S6Svc {
|
||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.wg.config", iface.Name)).Sanitize()
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineXDGConfig(),
|
||||
ExeclineXDGEnvdirConfig(l.Name),
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
ExeclineImportas("CONFIG", false, "/etc/wireguard/${INTERFACE}"),
|
||||
"wg setconf $INTERFACE $CONFIG",
|
||||
}, "\n")
|
||||
|
||||
l.S6Children(t.CreateIfaceService(iface.Name))
|
||||
t.NetdevDependBundleStage(iface.Name, "configure", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevIfaceDHCP(iface Iface, ipv int) *S6Svc {
|
||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.dhcp", iface.Name)).Sanitize()
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Longrun)
|
||||
|
||||
var daemon = "udhcpc"
|
||||
if ipv == 6 {
|
||||
daemon = fmt.Sprintf("%s%d", daemon, ipv)
|
||||
}
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface.Name),
|
||||
"fdmove -c 2 1",
|
||||
fmt.Sprintf("%s -i $INTERFACE -f -S", daemon),
|
||||
}, "\n")
|
||||
l.ProducerFor = t.S6New("logger.udhcpc", &S6SvcTypes.Longrun)
|
||||
|
||||
l.S6Children(t.LinkIfaceService(iface.Name))
|
||||
t.NetdevDependBundleStage(iface.Name, "ready", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) netdevIfaceAddrTemplate(action, iface string, ipv int, addr net.IP) string {
|
||||
return strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface),
|
||||
ExeclineDefine("ADDRESS", addr.String()),
|
||||
ExeclineDefine("FAMILY", fmt.Sprintf("%d", ipv)),
|
||||
fmt.Sprintf("ip -${FAMILY} address %s $ADDRESS dev $INTERFACE", action),
|
||||
}, "\n")
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevIfaceAddr(iface Iface, addr net.IP) *S6Svc {
|
||||
ipv := NetdevIPAddrVer(addr)
|
||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.ip.addr.%d.%s", iface.Name, ipv, addr)).Sanitize()
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||
|
||||
l.Up = t.netdevIfaceAddrTemplate("add", iface.Name, ipv, addr)
|
||||
l.Down = t.netdevIfaceAddrTemplate("del", iface.Name, ipv, addr)
|
||||
|
||||
l.S6Children(t.LinkIfaceService(iface.Name))
|
||||
t.NetdevDependBundleStage(iface.Name, "ready", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) netdevRouteTemplate(iface Iface, route Route) (up, down string, name S6SvcName) {
|
||||
var (
|
||||
lines []string
|
||||
svcname = []string{"interface", iface.Name, "route"}
|
||||
|
||||
cmd = []string{
|
||||
"ip",
|
||||
fmt.Sprintf("-%d", NetdevIPAddrVer(route.Net.IP)), // IP version
|
||||
"route",
|
||||
"%s",
|
||||
}
|
||||
header = []string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineXDGConfig(),
|
||||
}
|
||||
)
|
||||
|
||||
if route.Type != "" {
|
||||
lines = append(lines, ExeclineDefine("TYPE", route.Type))
|
||||
cmd = append(cmd, "$TYPE")
|
||||
svcname = append(svcname, route.Type)
|
||||
}
|
||||
|
||||
var r = "default"
|
||||
if !route.Default {
|
||||
r = route.Net.String()
|
||||
}
|
||||
lines = append(lines, ExeclineDefine("ROUTE", r))
|
||||
cmd = append(cmd, "$ROUTE")
|
||||
svcname = append(svcname, r)
|
||||
|
||||
if route.Via != nil {
|
||||
lines = append(lines, ExeclineImportas("VIA", false, route.Via.String()))
|
||||
cmd = append(cmd, "via", "$VIA")
|
||||
}
|
||||
|
||||
lines = append(lines, ExeclineDefine("DEV", iface.Name))
|
||||
cmd = append(cmd, "dev", "$DEV")
|
||||
|
||||
if route.Metric != 0 {
|
||||
lines = append(lines, ExeclineImportas("METRIC", false, fmt.Sprintf("%d", route.Metric)))
|
||||
cmd = append(cmd, "metric", "$METRIC")
|
||||
}
|
||||
|
||||
if route.Vrf != nil && route.Vrf.Type == &NetdevIfTypes.Vrf {
|
||||
// Parent is VRF
|
||||
lines = append(lines, ExeclineImportas("VRF", false, route.Vrf.Name))
|
||||
cmd = append(cmd, "vrf", "$VRF")
|
||||
}
|
||||
|
||||
name = S6SvcName(strings.Join(svcname, "."))
|
||||
// Merge
|
||||
header = append(header, ExeclineXDGEnvdirConfig(name))
|
||||
|
||||
lines = append(lines, strings.Join(cmd, " "))
|
||||
full := append(header, lines...)
|
||||
|
||||
up = fmt.Sprintf(strings.Join(full, "\n"), "add")
|
||||
down = fmt.Sprintf(strings.Join(full, "\n"), "del")
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) NetdevRoute(iface Iface, route Route) *S6Svc {
|
||||
up, down, name := t.netdevRouteTemplate(iface, route)
|
||||
|
||||
l := t.S6New(name.Sanitize(), &S6SvcTypes.Oneshot)
|
||||
|
||||
l.Up = up
|
||||
l.Down = down
|
||||
|
||||
l.S6Children(t.LinkIfaceService(iface.Name))
|
||||
if route.Vrf != nil {
|
||||
l.S6Children(t.LinkIfaceService(route.Vrf.Name))
|
||||
}
|
||||
t.NetdevDependBundleStage(iface.Name, "ready", l)
|
||||
|
||||
return l
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
NETDEV_EXECLINE_HEADER = "#!/bin/execlineb -P"
|
||||
)
|
||||
|
||||
func ExeclineDefine(param, value string) string {
|
||||
return fmt.Sprintf("define %s %s", param, value)
|
||||
}
|
||||
|
||||
func ExeclineExport(param, value string) string {
|
||||
return fmt.Sprintf("export %s %s", param, value)
|
||||
}
|
||||
|
||||
func ExeclineXDGEnvdirConfig(name S6SvcName) string {
|
||||
return fmt.Sprintf("s6-envdir -I ${XDG_CONFIG_HOME}/env/%s", name.Sanitize())
|
||||
}
|
||||
|
||||
func ExeclineImportas(name string, strict bool, def string) string {
|
||||
var s = []string{
|
||||
"importas",
|
||||
}
|
||||
if strict {
|
||||
s = append(s, "-i")
|
||||
}
|
||||
if def != "" {
|
||||
s = append(s, "-D", def)
|
||||
}
|
||||
// Always assume we import to same name
|
||||
s = append(s, name, name)
|
||||
return strings.Join(s, " ")
|
||||
}
|
||||
|
||||
func ExeclineXDGConfig() string {
|
||||
return ExeclineImportas("XDG_CONFIG_HOME", true, "")
|
||||
}
|
25
generic.sh
25
generic.sh
|
@ -1,25 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/netdev.sh"
|
||||
|
||||
# Handle loopback specially
|
||||
# - addresses are assigned automatically when brought up
|
||||
# - interface is created automatically by the kernel
|
||||
IFACE="lo"
|
||||
new_if_phys "$IFACE"
|
||||
#if_ip_addr "$IFACE" '127.0.0.1/8'
|
||||
#if_ip_addr "$IFACE" '::1/128'
|
||||
|
||||
|
||||
BRIDGE="br0"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
if_dhcpv6 "$BRIDGE"
|
||||
|
||||
IFACE="eth0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
|
@ -1,27 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
BRIDGE="br-main"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
|
||||
IFACE="enp1s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
BRIDGE="br-home"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
if_accept_ra "$BRIDGE" '0' # Disable IPv6 on home net, only ipv4
|
||||
|
||||
IFACE="enp11s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
|
@ -1,42 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
IFACE="home-66"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
VRF="vrf-home"
|
||||
new_if_vrf "$VRF" 20
|
||||
if_route_vrf_default_unreach "$VRF"
|
||||
|
||||
BRIDGE="home"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'priority' "$BRIDGE" '16384' '32768'
|
||||
if_bridge_property 'stp_state' "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
|
||||
IFACE="enp2s0f0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
IFACE="enp8s0f0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
IFACE="enp4s0f0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
IFACE="enp4s0f1"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
# Wireguard
|
||||
IFACE="wg-tunnel"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "172.22.12.7/32"
|
||||
if_ip_addr "$IFACE" "fd42:42:42::2:7/128"
|
||||
if_route_addr "$IFACE" "172.22.12.0/24"
|
||||
if_route_addr "$IFACE" "fd42:42:42::2:0/120"
|
|
@ -1,151 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
# VRFs
|
||||
VRF="vrf-dn42"
|
||||
new_if_vrf "$VRF" 20
|
||||
if_route_vrf_default_unreach "$VRF"
|
||||
|
||||
BRIDGE="br-dn42"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
|
||||
IFACE="home-42"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
IFACE="enp2s0"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
|
||||
IFACE="famfo"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::1422:1/64"
|
||||
|
||||
IFACE="mark22k"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::4546/64"
|
||||
|
||||
IFACE="highdef"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
|
||||
IFACE="kioubit"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
|
||||
IFACE="lare"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
|
||||
IFACE="haktron"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
|
||||
VRF="vrf-v6"
|
||||
new_if_vrf "$VRF" 10
|
||||
if_route_vrf_sink_unreach "$VRF" "2a04:5b81:2060::/44"
|
||||
|
||||
IFACE="intersix"
|
||||
#if_route_vrf_default_interface "$VRF" "$IFACE"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
if_ip_addr "$IFACE" "2a04:5b80:ffff:ff0b::2/64"
|
||||
|
||||
IFACE="vultrbgp"
|
||||
if_route_vrf_default_interface "$VRF" "$IFACE"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
|
||||
BRIDGE="b00b"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_stats_enabled' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_ether_address "$BRIDGE" '02:00:00:00:b0:0b'
|
||||
if_ip_addr "$BRIDGE" "2a04:5b81:2060:b00b::1/64"
|
||||
|
||||
IFACE="enp16s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="home-66"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
BRIDGE="f33d"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_ether_address "$BRIDGE" '02:00:00:00:f3:3d'
|
||||
if_ip_addr "$BRIDGE" "2a04:5b81:2060:f33d::1/64"
|
||||
|
||||
IFACE="enp17s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="home-100"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
BRIDGE="d00d"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_ether_address "$BRIDGE" '02:00:00:00:d0:0d'
|
||||
if_ip_addr "$BRIDGE" "2a04:5b81:2060:d00d::1/64"
|
||||
|
||||
IFACE="enp18s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="home-101"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
|
||||
# NO-vrf
|
||||
BRIDGE="home"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
if_forward "$BRIDGE"
|
||||
|
||||
IFACE="enp13s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
|
@ -1,32 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
VRF="vrf-v6"
|
||||
new_if_vrf "$VRF" 20
|
||||
if_route_vrf_default_unreach "$VRF"
|
||||
|
||||
BRIDGE="br-v6"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
|
||||
IFACE="enp1s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
BRIDGE="br-home"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
|
||||
IFACE="enp9s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
|
@ -1,65 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
# VRFs
|
||||
VRF="vrf-wgate"
|
||||
new_if_vrf "$VRF" 20
|
||||
if_route_vrf_sink_unreach "$VRF" "2a04:5b81:2060::/44"
|
||||
if_route_vrf_sink_unreach "$VRF" "2a04:5b81:2010::/44"
|
||||
if_route_vrf_default_unreach "$VRF"
|
||||
|
||||
# Bridges
|
||||
IFACE="br-uplink"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_bridge "$IFACE"
|
||||
if_bridge_property 'stp_state' "$IFACE"
|
||||
if_bridge_property 'forward_delay' "$IFACE" '400' # 4 seconds, 8 seconds total (listen>learn)
|
||||
if_bridge_property 'hello_time' "$IFACE" '100' # every 1 second
|
||||
if_bridge_property 'mcast_router' "$IFACE"
|
||||
if_bridge_property 'mcast_snooping' "$IFACE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$IFACE"
|
||||
if_bridge_property 'mcast_mld_version' "$IFACE" '2' ''
|
||||
if_forward "$IFACE"
|
||||
if_accept_ra "$IFACE"
|
||||
if_dhcp "$IFACE"
|
||||
|
||||
if_slave "$IFACE" "enp1s0"
|
||||
new_if_phys "enp1s0"
|
||||
|
||||
|
||||
# Wireguard
|
||||
IFACE="tristan"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_forward "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::1/64"
|
||||
if_route_vrf_addr "$VRF" "$IFACE" "2a04:5b81:2010::/48"
|
||||
|
||||
IFACE="tristan-travel"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_forward "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::1/64"
|
||||
if_route_vrf_addr "$VRF" "$IFACE" "2a04:5b81:201f::/48"
|
||||
|
||||
IFACE="gustav"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_forward "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::1/64"
|
||||
if_route_vrf_addr "$VRF" "$IFACE" "2a04:5b81:2011::/48"
|
||||
|
||||
IFACE="caskd-lakewood"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_forward "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::1/64"
|
||||
if_route_vrf_addr "$VRF" "$IFACE" "2a04:5b81:2060::/48"
|
||||
|
||||
IFACE="caskd-thetford"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_forward "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::1/64"
|
||||
if_route_vrf_addr "$VRF" "$IFACE" "2a04:5b81:2060::/48"
|
|
@ -1,22 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
BRIDGE="br-v6"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
|
||||
IFACE="enp1s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="wg-tunnel"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "172.22.12.8/32"
|
||||
if_ip_addr "$IFACE" "fd42:42:42::2:8/128"
|
||||
if_route_addr "$IFACE" "172.22.12.0/24"
|
||||
if_route_addr "$IFACE" "fd42:42:42::2:0/120"
|
|
@ -1,39 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
IFACE="home-66"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
VRF="vrf-home"
|
||||
new_if_vrf "$VRF" 20
|
||||
if_route_vrf_default_unreach "$VRF"
|
||||
|
||||
BRIDGE="home"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'priority' "$BRIDGE" '16384' '32768'
|
||||
if_bridge_property 'stp_state' "$BRIDGE"
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
|
||||
IFACE="eno1"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
IFACE="enp129s0f0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
IFACE="enp129s0f1"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
# Wireguard
|
||||
IFACE="wg-tunnel"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "172.22.12.5/32"
|
||||
if_ip_addr "$IFACE" "fd42:42:42::2:5/128"
|
||||
if_route_addr "$IFACE" "172.22.12.0/24"
|
||||
if_route_addr "$IFACE" "fd42:42:42::2:0/120"
|
|
@ -1,113 +0,0 @@
|
|||
#!/bin/sh
|
||||
|
||||
. "$(dirname -- "$0")/../netdev.sh"
|
||||
|
||||
VRF="vrf-dn42"
|
||||
new_if_vrf "$VRF" 20
|
||||
if_route_vrf_default_unreach "$VRF"
|
||||
|
||||
BRIDGE="br-dn42"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
|
||||
IFACE="enp15s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="phys-42"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
VRF="vrf-v6"
|
||||
new_if_vrf "$VRF" 10
|
||||
#if_route_vrf_sink_unreach "$VRF" "2a04:5b81:2060::/44"
|
||||
|
||||
IFACE="vultrbgp"
|
||||
#if_route_vrf_default_interface "$VRF" "$IFACE"
|
||||
if_slave "$VRF" "$IFACE"
|
||||
new_if_wg "$IFACE"
|
||||
if_ip_addr "$IFACE" "fe80::2/64"
|
||||
|
||||
BRIDGE="b00b"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
if_sysctl "$BRIDGE" 'forwarding' '0'
|
||||
if_sysctl "$BRIDGE" 'autoconf' '0'
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' ''
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_stats_enabled' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_ether_address "$BRIDGE" '02:00:00:01:b0:0b'
|
||||
if_ip_addr "$BRIDGE" "2a04:5b81:2060:b00b::2/64"
|
||||
|
||||
IFACE="enp9s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="phys-66"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
BRIDGE="f33d"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_ether_address "$BRIDGE" '02:00:00:01:f3:3d'
|
||||
if_ip_addr "$BRIDGE" "2a04:5b81:2060:f33d::2/64"
|
||||
|
||||
IFACE="enp14s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="phys-100"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
BRIDGE="d00d"
|
||||
if_slave "$VRF" "$BRIDGE"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE" '0'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_ether_address "$BRIDGE" '02:00:00:01:d0:0d'
|
||||
if_ip_addr "$BRIDGE" "2a04:5b81:2060:d00d::2/64"
|
||||
|
||||
IFACE="enp13s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
||||
|
||||
IFACE="phys-101"
|
||||
if_linkdepend "$IFACE" "${IFACE%-*}"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_vlan "$IFACE"
|
||||
|
||||
BRIDGE="phys"
|
||||
new_if_bridge "$BRIDGE"
|
||||
if_bridge_property 'stp_state' "$BRIDGE"
|
||||
if_ether_address "$BRIDGE" '52:54:00:81:cb:62'
|
||||
if_bridge_property 'mcast_router' "$BRIDGE"
|
||||
if_bridge_property 'mcast_snooping' "$BRIDGE" '0' '' # TODO: Remove such entries when bridges play well with multicasting
|
||||
if_bridge_property 'mcast_querier' "$BRIDGE"
|
||||
if_bridge_property 'mcast_mld_version' "$BRIDGE" '2' ''
|
||||
if_dhcp "$BRIDGE"
|
||||
if_forward "$BRIDGE"
|
||||
|
||||
IFACE="enp12s0"
|
||||
if_slave "$BRIDGE" "$IFACE"
|
||||
new_if_phys "$IFACE"
|
|
@ -0,0 +1,137 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
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(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 {
|
||||
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
|
||||
}
|
||||
|
||||
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.CreateIfaceService(i.Name))
|
||||
|
||||
bundle_ready := t.NetdevDependBundleStage(i.Name, "ready", svc_link)
|
||||
r = append(r, bundle_ready)
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var (
|
||||
dummy_svc_blacklist = map[S6SvcName]interface{}{
|
||||
"bundle.hw-coldplug": nil,
|
||||
"module.8021q": nil,
|
||||
"module.bonding": nil,
|
||||
"module.bridge": nil,
|
||||
"module.vrf": nil,
|
||||
"module.ipv6": nil,
|
||||
"module.wireguard": nil,
|
||||
"mount.proc": nil,
|
||||
"logger.udhcpc": nil,
|
||||
}
|
||||
)
|
||||
|
||||
func (t *S6SvcTree) NetdevEnslaveInterface(iface, master string) *S6Svc {
|
||||
svc_name := S6SvcName(fmt.Sprintf("interface.%s.master.%s", iface, master))
|
||||
|
||||
l := t.S6New(svc_name, &S6SvcTypes.Oneshot)
|
||||
l.Up = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface),
|
||||
ExeclineDefine("MASTER", master),
|
||||
"ip link set dev $INTERFACE master $MASTER",
|
||||
}, "\n")
|
||||
l.Down = strings.Join([]string{
|
||||
NETDEV_EXECLINE_HEADER,
|
||||
ExeclineDefine("INTERFACE", iface),
|
||||
"ip link set dev $INTERFACE nomaster",
|
||||
}, "\n")
|
||||
|
||||
l.S6Children(t.CreateIfaceService(iface), t.CreateIfaceService(master))
|
||||
t.NetdevDependBundleStage(iface, "configure", l)
|
||||
|
||||
return l
|
||||
}
|
||||
|
||||
func NetdevIPAddrVer(IP net.IP) int {
|
||||
if IP.To4() == nil {
|
||||
return 6
|
||||
}
|
||||
return 4
|
||||
}
|
||||
|
||||
func NetdevIsDummy(s S6SvcName) (r bool) {
|
||||
_, r = dummy_svc_blacklist[s]
|
||||
return
|
||||
}
|
719
netdev.sh
719
netdev.sh
|
@ -1,719 +0,0 @@
|
|||
#!/bin/sh
|
||||
#
|
||||
# Generate s6 network definitions
|
||||
|
||||
set -ex
|
||||
|
||||
header_eb() {
|
||||
echo '#!/bin/execlineb -P'
|
||||
}
|
||||
|
||||
header_if() {
|
||||
local if="${1:?missing if}"
|
||||
echo "define INTERFACE $if"
|
||||
}
|
||||
|
||||
header_addr() {
|
||||
local addr="${1:?missing addr}"
|
||||
echo "define ADDR $addr"
|
||||
}
|
||||
|
||||
header_fam() {
|
||||
local fam="${1:?missing family}"
|
||||
echo "define FAMILY $fam"
|
||||
}
|
||||
|
||||
header_vlan() {
|
||||
local vlan="${1:?missing vlan}"
|
||||
local parent="${2:?missing parent}"
|
||||
echo "define VLAN $vlan"
|
||||
echo "define PARENT $parent"
|
||||
}
|
||||
|
||||
header_vrf() {
|
||||
local vrf="${1:?missing vrf}"
|
||||
echo "define VRF $vrf"
|
||||
}
|
||||
|
||||
header_prop() {
|
||||
local prop="${1:?missing prop}"
|
||||
echo "define PROP $prop"
|
||||
}
|
||||
|
||||
addrfam() {
|
||||
# Use ipv6 if cannot autodetect of if no semicolons are present
|
||||
local addr="$1"
|
||||
local fam='6'
|
||||
if which grep >/dev/null 2>&1 && echo "$addr" | grep -v ':' >/dev/null 2>&1; then
|
||||
fam='4'
|
||||
fi
|
||||
echo "$fam"
|
||||
}
|
||||
|
||||
linkdel() {
|
||||
local if="${1:?missing if}"
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link del $INTERFACE'
|
||||
}
|
||||
|
||||
depends() {
|
||||
echo "$@"
|
||||
local svcname="${1:?missing sname}"
|
||||
|
||||
shift 1
|
||||
local sname # God i fucking hate global contexts by default
|
||||
for sname in $@; do
|
||||
install -Dm644 /dev/null rc/"$svcname"/dependencies.d/"$sname"
|
||||
done
|
||||
}
|
||||
|
||||
contains() {
|
||||
local svcname="${1:?missing sname}"
|
||||
|
||||
shift 1
|
||||
local sname # God i fucking hate global contexts by default
|
||||
for sname in $@; do
|
||||
install -Dm644 /dev/null rc/"$svcname"/contents.d/"$sname"
|
||||
done
|
||||
}
|
||||
|
||||
#
|
||||
# Bundle management
|
||||
#
|
||||
|
||||
bundle_deps() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local svcname="bundle.interface.$if"
|
||||
[ -r "rc/$svcname/type" ] || install -Dm644 <(echo bundle) rc/"$svcname"/type
|
||||
|
||||
shift 1
|
||||
contains "$svcname" $@
|
||||
}
|
||||
|
||||
# Currently used stages
|
||||
# > configure
|
||||
# - create
|
||||
# - enslave
|
||||
# - configure (anything that must be configured before interface is up)
|
||||
# > ready
|
||||
# - link
|
||||
# - configure (anything that may be configured after interface is up)
|
||||
bundle_stage_create() {
|
||||
local if="${1:?missing if}"
|
||||
local stage="${2:?missing stage}"
|
||||
|
||||
local svcname="bundle.interface.$if.$stage"
|
||||
[ -r "rc/$svcname/type" ] || install -Dm644 <(echo bundle) rc/"$svcname"/type
|
||||
|
||||
# Add to parent bundle
|
||||
bundle_deps "$if" "$svcname"
|
||||
|
||||
shift 2
|
||||
contains "$svcname" $@
|
||||
}
|
||||
|
||||
bundle_stage_depend_on() {
|
||||
local if="${1:?missing if}"
|
||||
local stage="${2:?missing stage}"
|
||||
|
||||
local svcname="bundle.interface.$if.$stage"
|
||||
|
||||
shift 2
|
||||
local sname
|
||||
for sname in $@; do
|
||||
depends "$sname" "$svcname"
|
||||
done
|
||||
}
|
||||
|
||||
bundle_stage_step_configure() {
|
||||
local if="$1"
|
||||
local stage="configure"
|
||||
|
||||
shift 1
|
||||
bundle_stage_create "$if" "$stage" $@
|
||||
}
|
||||
|
||||
bundle_stage_step_ready() {
|
||||
local if="$1"
|
||||
local stage="ready"
|
||||
|
||||
shift 1
|
||||
bundle_stage_create "$if" "$stage" $@
|
||||
}
|
||||
|
||||
#
|
||||
# Interface creation
|
||||
#
|
||||
|
||||
new_link() {
|
||||
local if="${1:?missing if}"
|
||||
shift 1
|
||||
|
||||
local sname="interface.$if.link"
|
||||
bundle_stage_step_ready "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link set dev $INTERFACE up'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link set dev $INTERFACE down'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
bundle_stage_depend_on "$if" "configure" "$sname"
|
||||
}
|
||||
|
||||
new_if_bridge() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
new_link "$if"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link add $INTERFACE type bridge'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(linkdel "$if") rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" module.bridge
|
||||
}
|
||||
|
||||
new_if_phys() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
new_link "$if"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'bcnm-waitif 1 $INTERFACE'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" bundle.hw-coldplug
|
||||
}
|
||||
|
||||
new_if_lo() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
new_link "$if"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link add $INTERFACE type loopback'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(linkdel "$if") rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
}
|
||||
|
||||
new_if_wg() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
# Main service for creating interface
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link add $INTERFACE type wireguard'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(linkdel "$if") rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" module.wireguard
|
||||
|
||||
new_link "$if"
|
||||
# Secondary service for loading config
|
||||
if_wg_conf "$if"
|
||||
}
|
||||
|
||||
new_if_vrf() {
|
||||
local if="${1:?missing if}"
|
||||
local table="${2:?missing table}"
|
||||
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
cat <<EOF
|
||||
s6-envdir -i /etc/s6/env/interface.\${INTERFACE}
|
||||
importas -i TABLE TABLE
|
||||
EOF
|
||||
echo 'ip link add $INTERFACE type vrf table $TABLE'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(linkdel "$if") rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
install -Dm644 <(echo "$table") env/interface."$if"/TABLE
|
||||
|
||||
depends "$sname" module.vrf sysctl.net-ipv6-conf-all-keep_addr_on_down
|
||||
|
||||
new_link "$if"
|
||||
}
|
||||
|
||||
new_if_vlan() {
|
||||
local if="${1:?missing if}"
|
||||
local vlan="$(echo $if | cut -d'-' -f2)"
|
||||
local parent="$(echo $if | cut -d'-' -f1)"
|
||||
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_vlan "$vlan" "$parent"
|
||||
echo 'ip link add link $PARENT name $INTERFACE type vlan id $VLAN'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(linkdel "$if") rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" module.8021q interface."$parent".create
|
||||
|
||||
new_link "$if"
|
||||
}
|
||||
|
||||
new_if_bond() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.create"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
echo 'ip link add name $INTERFACE type bond'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(linkdel "$if") rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" module.bonding interface."$parent".create
|
||||
|
||||
new_link "$if"
|
||||
}
|
||||
|
||||
#
|
||||
# Interface configuration and properties
|
||||
#
|
||||
|
||||
if_slave() {
|
||||
local master="${1:?missing master}"
|
||||
local slave="${2:?missing slave}"
|
||||
|
||||
local sname="interface.$master.slave.$slave"
|
||||
bundle_stage_step_configure "$master" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
cat <<EOF
|
||||
define MASTERIF $master
|
||||
define SLAVEIF $slave
|
||||
EOF
|
||||
echo 'ip link set dev $SLAVEIF master $MASTERIF'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
cat <<EOF
|
||||
define SLAVEIF $slave
|
||||
EOF
|
||||
echo 'ip link set dev $SLAVEIF nomaster'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$master".create interface."$slave".create
|
||||
}
|
||||
|
||||
if_forward() {
|
||||
local if="${1:?missing if}"
|
||||
local fam="${2:-6}"
|
||||
local val="${3:-1}"
|
||||
|
||||
if_sysctl "$if" "forwarding" "$val" '0' "$fam"
|
||||
}
|
||||
|
||||
if_accept_ra() {
|
||||
local if="${1:?missing if}"
|
||||
local fam="6"
|
||||
local val="${2:-2}"
|
||||
|
||||
if_sysctl "$if" "accept_ra" "$val" '0' "$fam"
|
||||
}
|
||||
|
||||
if_sysctl() {
|
||||
local if="${1:?missing if}"
|
||||
local prop="${2:?missing property}"
|
||||
local val_e="${3:-1}"
|
||||
local val_d="${4:-0}"
|
||||
local fam="${5:-6}"
|
||||
|
||||
local sname="sysctl.net-ipv$fam-conf-$if-$prop"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_fam "$fam"
|
||||
header_prop "$prop"
|
||||
cat <<EOF
|
||||
export VAL $val_e
|
||||
s6-envdir -I /etc/s6/env/sysctl.net-ipv\${FAMILY}-conf-\${INTERFACE}-\${PROP}
|
||||
export SYSCTL net/ipv\${FAMILY}/conf/\${INTERFACE}/\${PROP}
|
||||
/usr/libexec/nnd/s6/sysctl
|
||||
EOF
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_fam "$fam"
|
||||
header_prop "$prop"
|
||||
cat <<EOF
|
||||
export SYSCTL net/ipv\${FAMILY}/conf/\${INTERFACE}/\${PROP}
|
||||
export VAL $val_d
|
||||
/usr/libexec/nnd/s6/sysctl
|
||||
EOF
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
[ "$fam" = '6' ] && depends "$sname" module.ipv6
|
||||
depends "$sname" mount.proc interface."$if".create
|
||||
}
|
||||
|
||||
if_bridge_property() {
|
||||
local prop="${1:?missing prop}"
|
||||
local if="${2:?missing if}"
|
||||
local state="${3:-1}"
|
||||
local downstate="${4-0}"
|
||||
|
||||
local sname="interface.$if.bridge.$prop"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
cat <<EOF
|
||||
define PROP $prop
|
||||
define STATE $state
|
||||
EOF
|
||||
echo 'ip link set $INTERFACE type bridge $PROP $STATE'
|
||||
) rc/"$sname"/up
|
||||
[ -z "$downstate" ] || install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
cat <<EOF
|
||||
define PROP $prop
|
||||
define STATE $downstate
|
||||
EOF
|
||||
echo 'ip link set $INTERFACE type bridge $PROP $STATE'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
# Might not be a requirement since STP is probably a hard dependency of bridges
|
||||
[ "$prop" == 'stp_state' ] && depends "$sname" module.stp
|
||||
depends "$sname" interface."$if".create
|
||||
}
|
||||
|
||||
if_ether_address() {
|
||||
local if="${1:?missing if}"
|
||||
local addr="${2:?missing addr}"
|
||||
|
||||
local sname="interface.$if.ether.addr"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
echo 'ip link set $INTERFACE address $ADDR'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".create
|
||||
}
|
||||
|
||||
if_wg_conf() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.wg.config"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
cat <<EOF
|
||||
s6-envdir -I /etc/s6/env/interface.\${INTERFACE}.wg-config
|
||||
importas -D /etc/wireguard/\${INTERFACE} CONFIG CONFIG
|
||||
EOF
|
||||
echo 'wg setconf $INTERFACE $CONFIG'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".create
|
||||
}
|
||||
|
||||
if_dhcp() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.dhcp"
|
||||
bundle_stage_step_ready "$if" "$sname"
|
||||
|
||||
install -Dm755 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
cat <<EOF
|
||||
fdmove -c 2 1
|
||||
udhcpc -i \$INTERFACE -f -S
|
||||
EOF
|
||||
) rc/"$sname"/run
|
||||
install -Dm644 <(echo longrun) rc/"$sname"/type
|
||||
install -Dm644 <(echo logger.udhcpc) rc/"$sname"/producer-for
|
||||
|
||||
depends "$sname" interface."$if".link syslogd
|
||||
}
|
||||
|
||||
if_dhcpv6() {
|
||||
local if="${1:?missing if}"
|
||||
|
||||
local sname="interface.$if.dhcpv6"
|
||||
bundle_stage_step_ready "$if" "$sname"
|
||||
|
||||
install -Dm755 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
cat <<EOF
|
||||
fdmove -c 2 1
|
||||
udhcpc6 -i \$INTERFACE -f -S
|
||||
EOF
|
||||
) rc/"$sname"/run
|
||||
install -Dm644 <(echo longrun) rc/"$sname"/type
|
||||
install -Dm644 <(echo logger.udhcpc) rc/"$sname"/producer-for
|
||||
|
||||
depends "$sname" interface."$if".link syslogd
|
||||
}
|
||||
|
||||
if_ip_addr() {
|
||||
local if="${1:?missing if}"
|
||||
local addr="${2:?missing addr}"
|
||||
local fam="${3:-$(addrfam "$addr")}"
|
||||
local addrn="$(echo "$addr" | sed 's/\//_/g')"
|
||||
|
||||
local sname="interface.$if.ip.addr.$fam.$addrn"
|
||||
bundle_stage_step_ready "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} address add $ADDR dev $INTERFACE'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} address del $ADDR dev $INTERFACE'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".link
|
||||
}
|
||||
|
||||
if_route_addr() {
|
||||
local if="${1:?missing if}"
|
||||
local addr="${2:?missing addr}"
|
||||
local fam="${3:-$(addrfam "$addr")}"
|
||||
local addrn="$(echo "$addr" | sed 's/\//_/g')"
|
||||
|
||||
local sname="interface.$if.route.$fam.$addrn"
|
||||
bundle_stage_step_ready "$if" "$sname" # Interface route may be added only if it's up
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route add to $ADDR dev $INTERFACE'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route del to $ADDR dev $INTERFACE'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".link
|
||||
}
|
||||
|
||||
if_route_vrf_addr() {
|
||||
local vrf="${1:?missing vrf}"
|
||||
local if="${2:?missing if}"
|
||||
local addr="${3:?missing addr}"
|
||||
local fam="${4:-$(addrfam "$addr")}"
|
||||
local addrn="$(echo "$addr" | sed 's/\//_/g')"
|
||||
|
||||
local sname="interface.$if.route.$vrf.$fam.$addrn"
|
||||
bundle_stage_step_ready "$if" "$sname" # Interface route may be added only if it's up
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_vrf "$vrf"
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route add to $ADDR dev $INTERFACE vrf $VRF'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_vrf "$vrf"
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route del to $ADDR dev $INTERFACE vrf $VRF'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".link interface."$vrf".create
|
||||
}
|
||||
|
||||
if_route_vrf_addr_gateway() {
|
||||
local vrf="${1:?missing vrf}"
|
||||
local if="${2:?missing if}"
|
||||
local gateway="${3:?missing gw}"
|
||||
local addr="${4:?missing addr}"
|
||||
local fam="${5:-$(addrfam "$addr")}"
|
||||
local gatewayn="$(echo "$gateway" | sed 's/\//_/g')"
|
||||
local addrn="$(echo "$addr" | sed 's/\//_/g')"
|
||||
|
||||
local sname="interface.$if.gateway.$vrf.$fam.$gatewayn"
|
||||
bundle_stage_step_ready "$if" "$sname" # Interface route may be added only if it's up
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_vrf "$vrf"
|
||||
header_if "$if"
|
||||
header_addr "$gateway"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route add default via $ADDR dev $INTERFACE vrf $VRF'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_vrf "$vrf"
|
||||
header_if "$if"
|
||||
header_addr "$gateway"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route del default via $ADDR dev $INTERFACE vrf $VRF'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" "interface.$if.route.$vrf.$fam.$addrn" interface."$if".link interface."$vrf".create
|
||||
}
|
||||
|
||||
if_route_vrf_default_interface() {
|
||||
local vrf="${1:?missing vrf}"
|
||||
local if="${2:?missing if}"
|
||||
local fam="${3:-6}"
|
||||
|
||||
local sname="interface.$vrf.route.$fam.default"
|
||||
bundle_stage_step_configure "$vrf" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_vrf "$vrf"
|
||||
header_if "$if"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route add default dev $INTERFACE vrf $VRF'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_vrf "$vrf"
|
||||
header_if "$if"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route del default dev $INTERFACE vrf $VRF'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".link interface."$vrf".create
|
||||
}
|
||||
|
||||
if_route_vrf_default_unreach() {
|
||||
local if="${1:?missing if}"
|
||||
local fam="${2:-6}"
|
||||
|
||||
local sname="interface.$if.route.$fam.unreach"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route add unreachable default metric 4096 vrf $INTERFACE'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route del unreachable default metric 4096 vrf $INTERFACE'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".create
|
||||
}
|
||||
|
||||
if_route_vrf_sink_unreach() {
|
||||
local if="${1:?missing if}"
|
||||
local addr="${2:?missing addr}"
|
||||
local fam="${3:-$(addrfam "$addr")}"
|
||||
local addrn="$(echo "$addr" | sed 's/\//_/g')"
|
||||
|
||||
local sname="interface.$if.route.$fam.sink.$addrn"
|
||||
bundle_stage_step_configure "$if" "$sname"
|
||||
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route add unreachable $ADDR vrf $INTERFACE'
|
||||
) rc/"$sname"/up
|
||||
install -Dm644 <(
|
||||
header_eb
|
||||
header_if "$if"
|
||||
header_addr "$addr"
|
||||
header_fam "$fam"
|
||||
echo 'ip -${FAMILY} route del unreachable $ADDR vrf $INTERFACE'
|
||||
) rc/"$sname"/down
|
||||
install -Dm644 <(echo oneshot) rc/"$sname"/type
|
||||
|
||||
depends "$sname" interface."$if".create
|
||||
}
|
||||
|
||||
#
|
||||
# Misc functionality
|
||||
#
|
||||
|
||||
if_linkdepend() {
|
||||
local master="${1:?missing master}"
|
||||
local slave="${2:?missing slave}"
|
||||
|
||||
local sname="interface.$master.link"
|
||||
|
||||
depends "$sname" interface."$slave".link
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func NNDLibExec(name string) string {
|
||||
return fmt.Sprintf("/usr/libexec/nnd/s6/%s", name)
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type S6SvcTree struct {
|
||||
s map[S6SvcName]*S6Svc
|
||||
rcdir, envdir string
|
||||
root string
|
||||
}
|
||||
|
||||
type kv_file struct {
|
||||
name, value string
|
||||
perm int
|
||||
}
|
||||
|
||||
type S6Svc struct {
|
||||
Name S6SvcName
|
||||
Type S6SvcType
|
||||
Children []*S6Svc // Either dependencies or contents depending on type
|
||||
ProducerFor, ConsumerFor *S6Svc
|
||||
NotifFd int
|
||||
FlagEssential bool
|
||||
Up, Down, Run string
|
||||
env map[string]string
|
||||
}
|
||||
|
||||
type S6SvcName string
|
||||
|
||||
func (s S6SvcName) Sanitize() S6SvcName {
|
||||
// Only sanitize slashes for now
|
||||
return S6SvcName(strings.ReplaceAll(string(s), "/", "_"))
|
||||
}
|
||||
|
||||
type S6SvcType *string
|
||||
|
||||
var S6SvcTypes = struct {
|
||||
Oneshot, Longrun, Bundle string
|
||||
}{
|
||||
Oneshot: "oneshot",
|
||||
Longrun: "longrun",
|
||||
Bundle: "bundle",
|
||||
}
|
||||
|
||||
func S6NewTree() *S6SvcTree {
|
||||
t := new(S6SvcTree)
|
||||
t.s = make(map[S6SvcName]*S6Svc)
|
||||
t.root = "/etc/s6"
|
||||
t.rcdir = "rc"
|
||||
t.envdir = "env"
|
||||
return t
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) S6New(name S6SvcName, svc_type S6SvcType) *S6Svc {
|
||||
if name == "" || svc_type == nil {
|
||||
return nil
|
||||
}
|
||||
if e, ok := t.s[name]; ok && e.Type == svc_type {
|
||||
return e
|
||||
}
|
||||
s := new(S6Svc)
|
||||
s.Name = name
|
||||
s.Type = svc_type
|
||||
t.s[name] = s
|
||||
return s
|
||||
}
|
||||
func S6Pipe(src, dst *S6Svc) {
|
||||
src.ProducerFor = dst
|
||||
dst.ConsumerFor = src
|
||||
}
|
||||
|
||||
func (s *S6Svc) S6Children(children ...*S6Svc) {
|
||||
s.Children = append(s.Children, children...)
|
||||
}
|
||||
|
||||
func (s *S6Svc) S6AddEnv(key, value string) {
|
||||
s.env[key] = value
|
||||
}
|
||||
|
||||
func (s *S6Svc) S6DelEnv(key string) {
|
||||
delete(s.env, key)
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) S6AddSvc(s *S6Svc) {
|
||||
t.s[s.Name] = s
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) S6GetSvc(name S6SvcName) *S6Svc {
|
||||
return t.s[name]
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) S6Services() (r []*S6Svc) {
|
||||
for _, v := range t.s {
|
||||
r = append(r, v)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) S6CommitService(s *S6Svc) (err error) {
|
||||
if err = os.Mkdir(t.rcdir, fs.ModeDir|0777); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return
|
||||
}
|
||||
|
||||
sdir := filepath.Join(t.rcdir, string(s.Name))
|
||||
if err = os.Mkdir(sdir, fs.ModeDir|0777); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var kvfiles []kv_file
|
||||
kvfiles = append(kvfiles, kv_file{"type", *s.Type, 0666})
|
||||
if s.FlagEssential {
|
||||
kvfiles = append(kvfiles, kv_file{"flag-essential", "", 0666})
|
||||
}
|
||||
if s.ProducerFor != nil {
|
||||
kvfiles = append(kvfiles, kv_file{"producer-for", string(s.ProducerFor.Name), 0666})
|
||||
}
|
||||
if s.ConsumerFor != nil {
|
||||
kvfiles = append(kvfiles, kv_file{"consumer-for", string(s.ConsumerFor.Name), 0666})
|
||||
}
|
||||
if s.NotifFd != 0 {
|
||||
kvfiles = append(kvfiles, kv_file{"notification-fd", fmt.Sprintf("%d", s.NotifFd), 0666})
|
||||
}
|
||||
|
||||
// Scripts
|
||||
switch s.Type {
|
||||
case &S6SvcTypes.Longrun:
|
||||
{
|
||||
if s.Run != "" {
|
||||
kvfiles = append(kvfiles, kv_file{"run", s.Run, 0777})
|
||||
}
|
||||
}
|
||||
case &S6SvcTypes.Oneshot:
|
||||
{
|
||||
if s.Up != "" {
|
||||
kvfiles = append(kvfiles, kv_file{"up", s.Up, 0777})
|
||||
}
|
||||
if s.Down != "" {
|
||||
kvfiles = append(kvfiles, kv_file{"down", s.Down, 0777})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for _, v := range kvfiles {
|
||||
var f *os.File
|
||||
if f, err = os.OpenFile(filepath.Join(sdir, v.name), os.O_CREATE|os.O_RDWR, fs.FileMode(v.perm)); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return
|
||||
}
|
||||
_, err = fmt.Fprintln(f, v.value)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Children
|
||||
var dirname string
|
||||
switch s.Type {
|
||||
case &S6SvcTypes.Bundle:
|
||||
dirname = "contents.d"
|
||||
default:
|
||||
dirname = "dependencies.d"
|
||||
}
|
||||
cdir := filepath.Join(sdir, dirname)
|
||||
if err = os.Mkdir(cdir, fs.ModeDir|0777); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for _, v := range s.Children {
|
||||
var f *os.File
|
||||
if f, err = os.Create(filepath.Join(cdir, string(v.Name))); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return
|
||||
}
|
||||
f.Close()
|
||||
}
|
||||
|
||||
if len(s.env) != 0 {
|
||||
if err = os.Mkdir(t.envdir, fs.ModeDir|0777); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return
|
||||
}
|
||||
sdir := filepath.Join(t.envdir, string(s.Name))
|
||||
if err = os.Mkdir(sdir, fs.ModeDir|0777); err != nil {
|
||||
return
|
||||
}
|
||||
for k, v := range s.env {
|
||||
var f *os.File
|
||||
if f, err = os.Create(filepath.Join(sdir, string(k))); err != nil && !errors.Is(err, os.ErrExist) {
|
||||
return
|
||||
}
|
||||
_, err = fmt.Fprintln(f, v)
|
||||
f.Close()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
package s6netdev
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
)
|
||||
|
||||
func (t *S6SvcTree) CreateIfaceService(iface string) *S6Svc {
|
||||
return t.S6New(S6SvcName(fmt.Sprintf("interface.%s.create", iface)), &S6SvcTypes.Oneshot)
|
||||
}
|
||||
|
||||
func (t *S6SvcTree) LinkIfaceService(iface string) *S6Svc {
|
||||
return t.S6New(S6SvcName(fmt.Sprintf("interface.%s.link", iface)), &S6SvcTypes.Oneshot)
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
package s6netdev
|
||||
|
||||
import "net"
|
||||
|
||||
type (
|
||||
RouteTable uint16
|
||||
Metric uint16
|
||||
VLAN uint16
|
||||
)
|
||||
|
||||
type Property struct {
|
||||
Key, Value, Default string
|
||||
}
|
||||
|
||||
type Sysctl_IP struct {
|
||||
V4, V6 []Property // Should we start dhcp on this interface?
|
||||
}
|
||||
|
||||
type Iface struct {
|
||||
Name string // Interface name
|
||||
Type *NetdevIfType // Type of interface
|
||||
Slaves []*Iface // Slaves for VRFs, Bridges and Bonds etc...
|
||||
|
||||
VlanId VLAN // VLAN id for VLAN interfaces
|
||||
Parent *Iface // Parent interface for VLAN interfaces
|
||||
|
||||
Table RouteTable // Routing table, for VRF
|
||||
|
||||
MACAddr []byte // MAC address of interface (only valid for physical, bridges and VLAN)
|
||||
|
||||
Addresses []net.IP // Addresses to be assigned to interface
|
||||
Routes []Route // Routes to be assigned to interface
|
||||
|
||||
DHCP struct {
|
||||
V4, V6 bool // Should we start dhcp on this interface?
|
||||
}
|
||||
|
||||
Properties []Property // List of properties of the interface, valid for many
|
||||
Sysctls Sysctl_IP // Sysctls associated with this interface
|
||||
}
|
||||
|
||||
type Route struct {
|
||||
Default bool
|
||||
// VRF would be a field but it can be derived from parent
|
||||
Type string // unicast default, can be others
|
||||
Net net.IPNet
|
||||
Via *net.IP
|
||||
Vrf *Iface
|
||||
Table *RouteTable
|
||||
Metric Metric // Should be explicitly initialised to 1024
|
||||
}
|
||||
|
||||
type NetdevIfType struct {
|
||||
str string
|
||||
deps []S6SvcName
|
||||
}
|
||||
|
||||
var NetdevIfTypes = struct {
|
||||
Phys, Loopback, Bridge, Vlan, Wireguard, Bond, Vrf NetdevIfType
|
||||
}{
|
||||
Phys: NetdevIfType{"", []S6SvcName{"bundle.hw-coldplug"}},
|
||||
Loopback: NetdevIfType{"loopback", []S6SvcName{}},
|
||||
Bridge: NetdevIfType{"bridge", []S6SvcName{"module.bridge"}},
|
||||
Vlan: NetdevIfType{"vlan", []S6SvcName{"module.8021q"}},
|
||||
Wireguard: NetdevIfType{"wireguard", []S6SvcName{"module.wireguard"}},
|
||||
Bond: NetdevIfType{"bond", []S6SvcName{"module.bonding"}},
|
||||
Vrf: NetdevIfType{"vrf", []S6SvcName{"module.vrf"}},
|
||||
}
|
Loading…
Reference in New Issue