Firewall added & some fixes
This commit is contained in:
@@ -72,6 +72,13 @@ func ApplyPending() map[string]error {
|
||||
ClearPendingConfig(name)
|
||||
continue
|
||||
}
|
||||
// For VLAN interfaces ensure the kernel interface exists before ifup.
|
||||
if IsVLAN(name) {
|
||||
if err := EnsureVLANExists(name); err != nil {
|
||||
errs[name] = err
|
||||
continue
|
||||
}
|
||||
}
|
||||
_ = IfDown(name)
|
||||
if cfg := configs[name]; cfg != nil && cfg.Auto {
|
||||
if err := IfUp(name); err != nil {
|
||||
|
||||
@@ -13,6 +13,7 @@ const ConfigFile = "/etc/network/interfaces"
|
||||
// InterfaceConfig represents one stanza in /etc/network/interfaces.
|
||||
type InterfaceConfig struct {
|
||||
Name string `json:"name"`
|
||||
Label string `json:"label,omitempty"` // display name, stored in config.yaml only
|
||||
Auto bool `json:"auto"`
|
||||
Mode string `json:"mode"` // dhcp, static, loopback, manual
|
||||
Address string `json:"address,omitempty"` // static only
|
||||
@@ -154,12 +155,18 @@ func WriteConfig(configs map[string]*InterfaceConfig) error {
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
// loopback first
|
||||
// loopback first, then physical interfaces, then VLANs (sorted within each group)
|
||||
if lo, ok := configs["lo"]; ok {
|
||||
writeStanza(f, lo)
|
||||
}
|
||||
for name, cfg := range configs {
|
||||
if name == "lo" {
|
||||
if name == "lo" || IsVLAN(name) {
|
||||
continue
|
||||
}
|
||||
writeStanza(f, cfg)
|
||||
}
|
||||
for name, cfg := range configs {
|
||||
if !IsVLAN(name) {
|
||||
continue
|
||||
}
|
||||
writeStanza(f, cfg)
|
||||
@@ -188,6 +195,12 @@ func writeStanza(f *os.File, c *InterfaceConfig) {
|
||||
fmt.Fprintf(f, "\tdns-nameservers %s\n", strings.Join(c.DNS, " "))
|
||||
}
|
||||
}
|
||||
// VLAN interfaces need vlan-raw-device unless already in Extra
|
||||
if IsVLAN(c.Name) {
|
||||
if _, ok := c.Extra["vlan-raw-device"]; !ok {
|
||||
fmt.Fprintf(f, "\tvlan-raw-device %s\n", VLANParent(c.Name))
|
||||
}
|
||||
}
|
||||
for k, v := range c.Extra {
|
||||
fmt.Fprintf(f, "\t%s %s\n", k, v)
|
||||
}
|
||||
|
||||
80
network/vlan.go
Normal file
80
network/vlan.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package network
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// IsVLAN reports whether name is a VLAN interface (e.g. "eth0.100").
|
||||
func IsVLAN(name string) bool {
|
||||
idx := strings.LastIndex(name, ".")
|
||||
if idx <= 0 {
|
||||
return false
|
||||
}
|
||||
suffix := name[idx+1:]
|
||||
if suffix == "" {
|
||||
return false
|
||||
}
|
||||
_, err := strconv.Atoi(suffix)
|
||||
return err == nil
|
||||
}
|
||||
|
||||
// VLANParent returns the parent interface (e.g. "eth0.100" → "eth0").
|
||||
func VLANParent(name string) string {
|
||||
idx := strings.LastIndex(name, ".")
|
||||
if idx < 0 {
|
||||
return ""
|
||||
}
|
||||
return name[:idx]
|
||||
}
|
||||
|
||||
// VLANId returns the VLAN ID (e.g. "eth0.100" → 100).
|
||||
func VLANId(name string) int {
|
||||
idx := strings.LastIndex(name, ".")
|
||||
if idx < 0 {
|
||||
return 0
|
||||
}
|
||||
id, _ := strconv.Atoi(name[idx+1:])
|
||||
return id
|
||||
}
|
||||
|
||||
// EnsureVLANExists creates the VLAN interface in the kernel if it doesn't exist.
|
||||
func EnsureVLANExists(name string) error {
|
||||
if _, err := os.Stat("/sys/class/net/" + name); err == nil {
|
||||
return nil
|
||||
}
|
||||
parent := VLANParent(name)
|
||||
id := VLANId(name)
|
||||
if parent == "" || id == 0 {
|
||||
return fmt.Errorf("invalid VLAN name: %s", name)
|
||||
}
|
||||
out, err := exec.Command("ip", "link", "add", "link", parent,
|
||||
"name", name, "type", "vlan", "id", strconv.Itoa(id)).CombinedOutput()
|
||||
if err != nil {
|
||||
return fmt.Errorf("ip link add %s: %s", name, strings.TrimSpace(string(out)))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeleteVLAN brings down and removes a VLAN interface and its /etc/network/interfaces stanza.
|
||||
func DeleteVLAN(name string) error {
|
||||
_ = IfDown(name)
|
||||
if _, err := os.Stat("/sys/class/net/" + name); err == nil {
|
||||
out, err2 := exec.Command("ip", "link", "delete", name).CombinedOutput()
|
||||
if err2 != nil {
|
||||
return fmt.Errorf("ip link delete %s: %s", name, strings.TrimSpace(string(out)))
|
||||
}
|
||||
}
|
||||
configs, err := ParseConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, ok := configs[name]; ok {
|
||||
delete(configs, name)
|
||||
return WriteConfig(configs)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user