298 lines
7.9 KiB
Go
298 lines
7.9 KiB
Go
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
|
|
}
|