The following pull request was submitted through Github.
It can be accessed and reviewed at: https://github.com/lxc/lxd/pull/6826

This e-mail was sent by the LXC bot, direct replies will not reach the author
unless they happen to be subscribed to this list.

=== Description (from pull-request) ===

From 3cbe66814f206a1e09379c5207fe21018c1cc5de Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Mon, 3 Feb 2020 14:26:46 +0000
Subject: [PATCH 1/3] lxd/firewall: Moves iptables/xtables implementation into
 firewall/drivers package

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/firewall/{consts => drivers}/consts.go     | 2 +-
 lxd/{iptables => firewall/drivers}/iptables.go | 0
 lxd/{iptables => firewall/drivers}/xtables.go  | 0
 3 files changed, 1 insertion(+), 1 deletion(-)
 rename lxd/firewall/{consts => drivers}/consts.go (97%)
 rename lxd/{iptables => firewall/drivers}/iptables.go (100%)
 rename lxd/{iptables => firewall/drivers}/xtables.go (100%)

diff --git a/lxd/firewall/consts/consts.go b/lxd/firewall/drivers/consts.go
similarity index 97%
rename from lxd/firewall/consts/consts.go
rename to lxd/firewall/drivers/consts.go
index f0c1eda57e..297651d2fb 100644
--- a/lxd/firewall/consts/consts.go
+++ b/lxd/firewall/drivers/consts.go
@@ -1,4 +1,4 @@
-package consts
+package drivers
 
 // Location is used to determine whether a rule should be appended or prepended
 type Location int
diff --git a/lxd/iptables/iptables.go b/lxd/firewall/drivers/iptables.go
similarity index 100%
rename from lxd/iptables/iptables.go
rename to lxd/firewall/drivers/iptables.go
diff --git a/lxd/iptables/xtables.go b/lxd/firewall/drivers/xtables.go
similarity index 100%
rename from lxd/iptables/xtables.go
rename to lxd/firewall/drivers/xtables.go

From 4e45bbcc3e855ab9f37ecfd7b59eb660a84b7439 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Mon, 3 Feb 2020 14:29:21 +0000
Subject: [PATCH 2/3] lxd/firewall/drivers: Merges iptables helper functions
 into xtable struct

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/firewall/drivers/iptables.go | 137 ---------------------
 lxd/firewall/drivers/xtables.go  | 204 ++++++++++++++++++++++++-------
 2 files changed, 163 insertions(+), 178 deletions(-)
 delete mode 100644 lxd/firewall/drivers/iptables.go

diff --git a/lxd/firewall/drivers/iptables.go b/lxd/firewall/drivers/iptables.go
deleted file mode 100644
index 2ec75314d9..0000000000
--- a/lxd/firewall/drivers/iptables.go
+++ /dev/null
@@ -1,137 +0,0 @@
-package iptables
-
-import (
-       "fmt"
-       "os/exec"
-       "strings"
-
-       "github.com/lxc/lxd/shared"
-)
-
-func iptablesConfig(protocol string, comment string, table string, method 
string, chain string,
-       rule ...string) error {
-       cmd := "iptables"
-       if protocol == "ipv6" {
-               cmd = "ip6tables"
-       }
-
-       _, err := exec.LookPath(cmd)
-       if err != nil {
-               return fmt.Errorf("Asked to setup %s firewalling but %s can't 
be found", protocol, cmd)
-       }
-
-       baseArgs := []string{"-w"}
-       if table == "" {
-               table = "filter"
-       }
-       baseArgs = append(baseArgs, []string{"-t", table}...)
-
-       // Check for an existing entry
-       args := append(baseArgs, []string{"-C", chain}...)
-       args = append(args, rule...)
-       args = append(args, "-m", "comment", "--comment", 
fmt.Sprintf("generated for %s", comment))
-       _, err = shared.RunCommand(cmd, args...)
-       if err == nil {
-               return nil
-       }
-
-       args = append(baseArgs, []string{method, chain}...)
-       args = append(args, rule...)
-       args = append(args, "-m", "comment", "--comment", 
fmt.Sprintf("generated for %s", comment))
-
-       _, err = shared.TryRunCommand(cmd, args...)
-       if err != nil {
-               return err
-       }
-
-       return nil
-}
-
-func iptablesAppend(protocol string, comment string, table string, chain 
string, rule ...string) error {
-       return iptablesConfig(protocol, comment, table, "-A", chain, rule...)
-}
-
-func iptablesPrepend(protocol string, comment string, table string, chain 
string, rule ...string) error {
-       return iptablesConfig(protocol, comment, table, "-I", chain, rule...)
-}
-
-func iptablesClear(protocol string, comment string, table string) error {
-       // Detect kernels that lack IPv6 support
-       if !shared.PathExists("/proc/sys/net/ipv6") && protocol == "ipv6" {
-               return nil
-       }
-
-       cmd := "iptables"
-       if protocol == "ipv6" {
-               cmd = "ip6tables"
-       }
-
-       _, err := exec.LookPath(cmd)
-       if err != nil {
-               return nil
-       }
-
-       baseArgs := []string{"-w"}
-       if table == "" {
-               table = "filter"
-       }
-       baseArgs = append(baseArgs, []string{"-t", table}...)
-
-       // List the rules
-       args := append(baseArgs, "-S")
-       output, err := shared.TryRunCommand(cmd, args...)
-       if err != nil {
-               return fmt.Errorf("Failed to list %s rules for %s (table %s)", 
protocol, comment, table)
-       }
-
-       for _, line := range strings.Split(output, "\n") {
-               if !strings.Contains(line, fmt.Sprintf("generated for %s", 
comment)) {
-                       continue
-               }
-
-               // Remove the entry
-               fields := strings.Fields(line)
-               fields[0] = "-D"
-
-               args = append(baseArgs, fields...)
-               _, err = shared.TryRunCommand("sh", "-c", fmt.Sprintf("%s %s", 
cmd, strings.Join(args, " ")))
-               if err != nil {
-                       return err
-               }
-       }
-
-       return nil
-}
-
-// NetworkAppend adds a network rule at end of ruleset.
-func NetworkAppend(protocol string, comment string, table string, chain string,
-       rule ...string) error {
-       return iptablesAppend(protocol, fmt.Sprintf("LXD network %s", comment),
-               table, chain, rule...)
-}
-
-// NetworkPrepend adds a network rule at start of ruleset.
-func NetworkPrepend(protocol string, comment string, table string, chain 
string,
-       rule ...string) error {
-       return iptablesPrepend(protocol, fmt.Sprintf("LXD network %s", comment),
-               table, chain, rule...)
-}
-
-// NetworkClear removes network rules.
-func NetworkClear(protocol string, comment string, table string) error {
-       return iptablesClear(protocol, fmt.Sprintf("LXD network %s", comment),
-               table)
-}
-
-// ContainerPrepend adds container rule at start of ruleset.
-func ContainerPrepend(protocol string, comment string, table string,
-       chain string, rule ...string) error {
-       return iptablesPrepend(protocol, fmt.Sprintf("LXD container %s", 
comment),
-               table, chain, rule...)
-}
-
-// ContainerClear removes container rules.
-func ContainerClear(protocol string, comment string, table string) error {
-       return iptablesClear(protocol, fmt.Sprintf("LXD container %s", comment),
-               table)
-}
diff --git a/lxd/firewall/drivers/xtables.go b/lxd/firewall/drivers/xtables.go
index 5b7c86a332..b7f6bf7373 100644
--- a/lxd/firewall/drivers/xtables.go
+++ b/lxd/firewall/drivers/xtables.go
@@ -1,13 +1,13 @@
-package iptables
+package drivers
 
 import (
        "encoding/hex"
        "fmt"
        "net"
+       "os/exec"
        "strings"
 
        deviceConfig "github.com/lxc/lxd/lxd/device/config"
-       firewallConsts "github.com/lxc/lxd/lxd/firewall/consts"
        "github.com/lxc/lxd/lxd/util"
        "github.com/lxc/lxd/shared"
 )
@@ -18,17 +18,17 @@ type XTables struct{}
 // Lower-level Functions
 
 // NetworkClear removes network rules.
-func (xt XTables) NetworkClear(family firewallConsts.Family, table 
firewallConsts.Table, comment string) error {
-       return NetworkClear(fmt.Sprintf("%s", family), comment, 
fmt.Sprintf("%s", table))
+func (d XTables) NetworkClear(family Family, table Table, comment string) 
error {
+       return d.networkClear(fmt.Sprintf("%s", family), comment, 
fmt.Sprintf("%s", table))
 }
 
 // InstanceClear removes rules all rules for the given instance.
-func (xt XTables) InstanceClear(family firewallConsts.Family, table 
firewallConsts.Table, comment string) error {
-       return ContainerClear(fmt.Sprintf("%s", family), comment, 
fmt.Sprintf("%s", table))
+func (d XTables) InstanceClear(family Family, table Table, comment string) 
error {
+       return d.containerClear(fmt.Sprintf("%s", family), comment, 
fmt.Sprintf("%s", table))
 }
 
 // VerifyIPv6Module checks to see if the ipv6 kernel module is present.
-func (xt XTables) VerifyIPv6Module() error {
+func (d XTables) VerifyIPv6Module() error {
        // Check br_netfilter is loaded and enabled for IPv6.
        sysctlPath := "net/bridge/bridge-nf-call-ip6tables"
        sysctlVal, err := util.SysctlGet(sysctlPath)
@@ -46,20 +46,20 @@ func (xt XTables) VerifyIPv6Module() error {
 // Proxy Functions
 
 // InstanceProxySetupNAT creates a default NAT setup.
-func (xt XTables) InstanceProxySetupNAT(family firewallConsts.Family, 
connType, address, port string, destAddr net.IP, destPort string, comment 
string) error {
+func (d XTables) InstanceProxySetupNAT(family Family, connType, address, port 
string, destAddr net.IP, destPort string, comment string) error {
        toDest := fmt.Sprintf("%s:%s", destAddr, destPort)
        if family == "ipv6" {
                toDest = fmt.Sprintf("[%s]:%s", destAddr, destPort)
        }
 
        // outbound <-> container
-       err := ContainerPrepend(fmt.Sprintf("%s", family), comment, "nat", 
"PREROUTING", "-p", connType, "--destination", address, "--dport", port, "-j", 
"DNAT", "--to-destination", toDest)
+       err := d.containerPrepend(fmt.Sprintf("%s", family), comment, "nat", 
"PREROUTING", "-p", connType, "--destination", address, "--dport", port, "-j", 
"DNAT", "--to-destination", toDest)
        if err != nil {
                return err
        }
 
        // host <-> container
-       err = ContainerPrepend(fmt.Sprintf("%s", family), comment, "nat", 
"OUTPUT", "-p", connType, "--destination", address, "--dport", port, "-j", 
"DNAT", "--to-destination", toDest)
+       err = d.containerPrepend(fmt.Sprintf("%s", family), comment, "nat", 
"OUTPUT", "-p", connType, "--destination", address, "--dport", port, "-j", 
"DNAT", "--to-destination", toDest)
        if err != nil {
                return err
        }
@@ -70,7 +70,7 @@ func (xt XTables) InstanceProxySetupNAT(family 
firewallConsts.Family, connType,
 // NIC Bridged Functions
 
 // InstanceNicBridgedRemoveFilters removes any non-standard rules from the nic 
instance.
-func (xt XTables) InstanceNicBridgedRemoveFilters(m deviceConfig.Device, ipv4 
net.IP, ipv6 net.IP) error {
+func (d XTables) InstanceNicBridgedRemoveFilters(m deviceConfig.Device, ipv4 
net.IP, ipv6 net.IP) error {
        // Get a current list of rules active on the host.
        out, err := shared.RunCommand("ebtables", "--concurrent", "-L", 
"--Lmac2", "--Lx")
        if err != nil {
@@ -78,7 +78,7 @@ func (xt XTables) InstanceNicBridgedRemoveFilters(m 
deviceConfig.Device, ipv4 ne
        }
 
        // Get a list of rules that we would have applied on instance start.
-       rules := generateFilterEbtablesRules(m, ipv4, ipv6)
+       rules := d.generateFilterEbtablesRules(m, ipv4, ipv6)
 
        errs := []error{}
        // Iterate through each active rule on the host and try and match it to 
one the LXD rules.
@@ -94,7 +94,7 @@ func (xt XTables) InstanceNicBridgedRemoveFilters(m 
deviceConfig.Device, ipv4 ne
                        }
 
                        // Check whether active rule matches one of our rules 
to delete.
-                       if !matchEbtablesRule(fields, rule, true) {
+                       if !d.matchEbtablesRule(fields, rule, true) {
                                continue
                        }
 
@@ -115,8 +115,8 @@ func (xt XTables) InstanceNicBridgedRemoveFilters(m 
deviceConfig.Device, ipv4 ne
 }
 
 // InstanceNicBridgedSetFilters sets the nic rules to standard filtering.
-func (xt XTables) InstanceNicBridgedSetFilters(m deviceConfig.Device, ipv4 
net.IP, ipv6 net.IP, comment string) error {
-       rules := generateFilterEbtablesRules(m, ipv4, ipv6)
+func (d XTables) InstanceNicBridgedSetFilters(m deviceConfig.Device, ipv4 
net.IP, ipv6 net.IP, comment string) error {
+       rules := d.generateFilterEbtablesRules(m, ipv4, ipv6)
        for _, rule := range rules {
                _, err := shared.RunCommand(rule[0], 
append([]string{"--concurrent"}, rule[1:]...)...)
                if err != nil {
@@ -124,13 +124,13 @@ func (xt XTables) InstanceNicBridgedSetFilters(m 
deviceConfig.Device, ipv4 net.I
                }
        }
 
-       rules, err := generateFilterIptablesRules(m, ipv6)
+       rules, err := d.generateFilterIptablesRules(m, ipv6)
        if err != nil {
                return err
        }
 
        for _, rule := range rules {
-               err = ContainerPrepend(rule[0], fmt.Sprintf("%s - 
%s_filtering", comment, rule[0]), "filter", rule[1], rule[2:]...)
+               err = d.containerPrepend(rule[0], fmt.Sprintf("%s - 
%s_filtering", comment, rule[0]), "filter", rule[1], rule[2:]...)
                if err != nil {
                        return err
                }
@@ -142,20 +142,20 @@ func (xt XTables) InstanceNicBridgedSetFilters(m 
deviceConfig.Device, ipv4 net.I
 // Network Functions
 
 // NetworkSetupAllowForwarding allows forwarding dependent on boolean argument
-func (xt XTables) NetworkSetupAllowForwarding(family firewallConsts.Family, 
name string, actionType firewallConsts.Action) error {
+func (d XTables) NetworkSetupAllowForwarding(family Family, name string, 
actionType Action) error {
        forwardType := "DROP"
-       if actionType == firewallConsts.ActionAccept {
+       if actionType == ActionAccept {
                forwardType = "ACCEPT"
-       } else if actionType == firewallConsts.ActionReject {
+       } else if actionType == ActionReject {
                forwardType = "REJECT"
        }
 
-       err := NetworkPrepend(fmt.Sprintf("%s", family), name, "", "FORWARD", 
"-i", name, "-j", forwardType)
+       err := d.networkPrepend(fmt.Sprintf("%s", family), name, "", "FORWARD", 
"-i", name, "-j", forwardType)
        if err != nil {
                return err
        }
 
-       err = NetworkPrepend(fmt.Sprintf("%s", family), name, "", "FORWARD", 
"-o", name, "-j", forwardType)
+       err = d.networkPrepend(fmt.Sprintf("%s", family), name, "", "FORWARD", 
"-o", name, "-j", forwardType)
 
        if err != nil {
                return err
@@ -165,14 +165,14 @@ func (xt XTables) NetworkSetupAllowForwarding(family 
firewallConsts.Family, name
 }
 
 // NetworkSetupNAT configures NAT
-func (xt XTables) NetworkSetupNAT(family firewallConsts.Family, name string, 
location firewallConsts.Location, args ...string) error {
-       if location == firewallConsts.LocationPrepend {
-               err := NetworkPrepend(fmt.Sprintf("%s", family), name, "nat", 
"POSTROUTING", args...)
+func (d XTables) NetworkSetupNAT(family Family, name string, location 
Location, args ...string) error {
+       if location == LocationPrepend {
+               err := d.networkPrepend(fmt.Sprintf("%s", family), name, "nat", 
"POSTROUTING", args...)
                if err != nil {
                        return err
                }
-       } else if location == firewallConsts.LocationAppend {
-               err := NetworkAppend(fmt.Sprintf("%s", family), name, "nat", 
"POSTROUTING", args...)
+       } else if location == LocationAppend {
+               err := d.networkAppend(fmt.Sprintf("%s", family), name, "nat", 
"POSTROUTING", args...)
                if err != nil {
                        return err
                }
@@ -182,7 +182,7 @@ func (xt XTables) NetworkSetupNAT(family 
firewallConsts.Family, name string, loc
 }
 
 // NetworkSetupIPv4DNSOverrides sets up basic iptables overrides for DHCP/DNS
-func (xt XTables) NetworkSetupIPv4DNSOverrides(name string) error {
+func (d XTables) NetworkSetupIPv4DNSOverrides(name string) error {
        rules := [][]string{
                {"ipv4", name, "", "INPUT", "-i", name, "-p", "udp", "--dport", 
"67", "-j", "ACCEPT"},
                {"ipv4", name, "", "INPUT", "-i", name, "-p", "udp", "--dport", 
"53", "-j", "ACCEPT"},
@@ -192,7 +192,7 @@ func (xt XTables) NetworkSetupIPv4DNSOverrides(name string) 
error {
                {"ipv4", name, "", "OUTPUT", "-o", name, "-p", "tcp", 
"--sport", "53", "-j", "ACCEPT"}}
 
        for _, rule := range rules {
-               err := NetworkPrepend(rule[0], rule[1], rule[2], rule[3], 
rule[4:]...)
+               err := d.networkPrepend(rule[0], rule[1], rule[2], rule[3], 
rule[4:]...)
                if err != nil {
                        return err
                }
@@ -202,12 +202,12 @@ func (xt XTables) NetworkSetupIPv4DNSOverrides(name 
string) error {
 }
 
 // NetworkSetupIPv4DHCPWorkaround attempts a workaround for broken DHCP clients
-func (xt XTables) NetworkSetupIPv4DHCPWorkaround(name string) error {
-       return NetworkPrepend("ipv4", name, "mangle", "POSTROUTING", "-o", 
name, "-p", "udp", "--dport", "68", "-j", "CHECKSUM", "--checksum-fill")
+func (d XTables) NetworkSetupIPv4DHCPWorkaround(name string) error {
+       return d.networkPrepend("ipv4", name, "mangle", "POSTROUTING", "-o", 
name, "-p", "udp", "--dport", "68", "-j", "CHECKSUM", "--checksum-fill")
 }
 
 // NetworkSetupIPv6DNSOverrides sets up basic iptables overrides for DHCP/DNS
-func (xt XTables) NetworkSetupIPv6DNSOverrides(name string) error {
+func (d XTables) NetworkSetupIPv6DNSOverrides(name string) error {
        rules := [][]string{
                {"ipv6", name, "", "INPUT", "-i", name, "-p", "udp", "--dport", 
"547", "-j", "ACCEPT"},
                {"ipv6", name, "", "INPUT", "-i", name, "-p", "udp", "--dport", 
"53", "-j", "ACCEPT"},
@@ -217,7 +217,7 @@ func (xt XTables) NetworkSetupIPv6DNSOverrides(name string) 
error {
                {"ipv6", name, "", "OUTPUT", "-o", name, "-p", "tcp", 
"--sport", "53", "-j", "ACCEPT"}}
 
        for _, rule := range rules {
-               err := NetworkPrepend(rule[0], rule[1], rule[2], rule[3], 
rule[4:]...)
+               err := d.networkPrepend(rule[0], rule[1], rule[2], rule[3], 
rule[4:]...)
                if err != nil {
                        return err
                }
@@ -227,14 +227,14 @@ func (xt XTables) NetworkSetupIPv6DNSOverrides(name 
string) error {
 }
 
 // NetworkSetupTunnelNAT configures tunnel NAT
-func (xt XTables) NetworkSetupTunnelNAT(name string, location 
firewallConsts.Location, overlaySubnet net.IPNet) error {
-       if location == firewallConsts.LocationPrepend {
-               err := NetworkPrepend("ipv4", name, "nat", "POSTROUTING", "-s", 
overlaySubnet.String(), "!", "-d", overlaySubnet.String(), "-j", "MASQUERADE")
+func (d XTables) NetworkSetupTunnelNAT(name string, location Location, 
overlaySubnet net.IPNet) error {
+       if location == LocationPrepend {
+               err := d.networkPrepend("ipv4", name, "nat", "POSTROUTING", 
"-s", overlaySubnet.String(), "!", "-d", overlaySubnet.String(), "-j", 
"MASQUERADE")
                if err != nil {
                        return err
                }
-       } else if location == firewallConsts.LocationAppend {
-               err := NetworkAppend("ipv4", name, "nat", "POSTROUTING", "-s", 
overlaySubnet.String(), "!", "-d", overlaySubnet.String(), "-j", "MASQUERADE")
+       } else if location == LocationAppend {
+               err := d.networkAppend("ipv4", name, "nat", "POSTROUTING", 
"-s", overlaySubnet.String(), "!", "-d", overlaySubnet.String(), "-j", 
"MASQUERADE")
                if err != nil {
                        return err
                }
@@ -246,7 +246,7 @@ func (xt XTables) NetworkSetupTunnelNAT(name string, 
location firewallConsts.Loc
 // Helper Functions
 
 // generateFilterEbtablesRules returns a customised set of ebtables filter 
rules based on the device.
-func generateFilterEbtablesRules(m deviceConfig.Device, ipv4 net.IP, ipv6 
net.IP) [][]string {
+func (d XTables) generateFilterEbtablesRules(m deviceConfig.Device, ipv4 
net.IP, ipv6 net.IP) [][]string {
        // MAC source filtering rules. Blocks any packet coming from instance 
with an incorrect Ethernet source MAC.
        // This is required for IP filtering too.
        rules := [][]string{
@@ -285,7 +285,7 @@ func generateFilterEbtablesRules(m deviceConfig.Device, 
ipv4 net.IP, ipv6 net.IP
 }
 
 // generateFilterIptablesRules returns a customised set of iptables filter 
rules based on the device.
-func generateFilterIptablesRules(m deviceConfig.Device, ipv6 net.IP) (rules 
[][]string, err error) {
+func (d XTables) generateFilterIptablesRules(m deviceConfig.Device, ipv6 
net.IP) (rules [][]string, err error) {
        mac, err := net.ParseMAC(m["hwaddr"])
        if err != nil {
                return
@@ -320,7 +320,7 @@ func generateFilterIptablesRules(m deviceConfig.Device, 
ipv6 net.IP) (rules [][]
 // matchEbtablesRule compares an active rule to a supplied match rule to see 
if they match.
 // If deleteMode is true then the "-A" flag in the active rule will be 
modified to "-D" and will
 // not be part of the equality match. This allows delete commands to be 
generated from dumped add commands.
-func matchEbtablesRule(activeRule []string, matchRule []string, deleteMode 
bool) bool {
+func (d XTables) matchEbtablesRule(activeRule []string, matchRule []string, 
deleteMode bool) bool {
        for i := range matchRule {
                // Active rules will be dumped in "add" format, we need to 
detect
                // this and switch it to "delete" mode if requested. If this 
has already been
@@ -345,3 +345,125 @@ func matchEbtablesRule(activeRule []string, matchRule 
[]string, deleteMode bool)
 
        return true
 }
+
+func (d XTables) iptablesConfig(protocol string, comment string, table string, 
method string, chain string,
+       rule ...string) error {
+       cmd := "iptables"
+       if protocol == "ipv6" {
+               cmd = "ip6tables"
+       }
+
+       _, err := exec.LookPath(cmd)
+       if err != nil {
+               return fmt.Errorf("Asked to setup %s firewalling but %s can't 
be found", protocol, cmd)
+       }
+
+       baseArgs := []string{"-w"}
+       if table == "" {
+               table = "filter"
+       }
+       baseArgs = append(baseArgs, []string{"-t", table}...)
+
+       // Check for an existing entry
+       args := append(baseArgs, []string{"-C", chain}...)
+       args = append(args, rule...)
+       args = append(args, "-m", "comment", "--comment", 
fmt.Sprintf("generated for %s", comment))
+       _, err = shared.RunCommand(cmd, args...)
+       if err == nil {
+               return nil
+       }
+
+       args = append(baseArgs, []string{method, chain}...)
+       args = append(args, rule...)
+       args = append(args, "-m", "comment", "--comment", 
fmt.Sprintf("generated for %s", comment))
+
+       _, err = shared.TryRunCommand(cmd, args...)
+       if err != nil {
+               return err
+       }
+
+       return nil
+}
+
+func (d XTables) iptablesAppend(protocol string, comment string, table string, 
chain string, rule ...string) error {
+       return d.iptablesConfig(protocol, comment, table, "-A", chain, rule...)
+}
+
+func (d XTables) iptablesPrepend(protocol string, comment string, table 
string, chain string, rule ...string) error {
+       return d.iptablesConfig(protocol, comment, table, "-I", chain, rule...)
+}
+
+func (d XTables) iptablesClear(protocol string, comment string, table string) 
error {
+       // Detect kernels that lack IPv6 support
+       if !shared.PathExists("/proc/sys/net/ipv6") && protocol == "ipv6" {
+               return nil
+       }
+
+       cmd := "iptables"
+       if protocol == "ipv6" {
+               cmd = "ip6tables"
+       }
+
+       _, err := exec.LookPath(cmd)
+       if err != nil {
+               return nil
+       }
+
+       baseArgs := []string{"-w"}
+       if table == "" {
+               table = "filter"
+       }
+       baseArgs = append(baseArgs, []string{"-t", table}...)
+
+       // List the rules
+       args := append(baseArgs, "-S")
+       output, err := shared.TryRunCommand(cmd, args...)
+       if err != nil {
+               return fmt.Errorf("Failed to list %s rules for %s (table %s)", 
protocol, comment, table)
+       }
+
+       for _, line := range strings.Split(output, "\n") {
+               if !strings.Contains(line, fmt.Sprintf("generated for %s", 
comment)) {
+                       continue
+               }
+
+               // Remove the entry
+               fields := strings.Fields(line)
+               fields[0] = "-D"
+
+               args = append(baseArgs, fields...)
+               _, err = shared.TryRunCommand("sh", "-c", fmt.Sprintf("%s %s", 
cmd, strings.Join(args, " ")))
+               if err != nil {
+                       return err
+               }
+       }
+
+       return nil
+}
+
+// networkAppend adds a network rule at end of ruleset.
+func (d XTables) networkAppend(protocol string, comment string, table string, 
chain string, rule ...string) error {
+       return d.iptablesAppend(protocol, fmt.Sprintf("LXD network %s", 
comment), table, chain, rule...)
+}
+
+// networkPrepend adds a network rule at start of ruleset.
+func (d XTables) networkPrepend(protocol string, comment string, table string, 
chain string,
+       rule ...string) error {
+       return d.iptablesPrepend(protocol, fmt.Sprintf("LXD network %s", 
comment), table, chain, rule...)
+}
+
+// networkClear removes network rules.
+func (d XTables) networkClear(protocol string, comment string, table string) 
error {
+       return d.iptablesClear(protocol, fmt.Sprintf("LXD network %s", 
comment), table)
+}
+
+// containerPrepend adds container rule at start of ruleset.
+func (d XTables) containerPrepend(protocol string, comment string, table 
string,
+       chain string, rule ...string) error {
+       return d.iptablesPrepend(protocol, fmt.Sprintf("LXD container %s", 
comment), table, chain, rule...)
+}
+
+// containerClear removes container rules.
+func (d XTables) containerClear(protocol string, comment string, table string) 
error {
+       return d.iptablesClear(protocol, fmt.Sprintf("LXD container %s", 
comment), table)
+}

From 83eba4aeb83d21f223508b2a9cd515fc3ee40c05 Mon Sep 17 00:00:00 2001
From: Thomas Parrott <thomas.parr...@canonical.com>
Date: Mon, 3 Feb 2020 14:30:01 +0000
Subject: [PATCH 3/3] lxd/firewall: Updates interface and loader for new pkg

Signed-off-by: Thomas Parrott <thomas.parr...@canonical.com>
---
 lxd/firewall/interfaces.go | 17 ++++++++---------
 1 file changed, 8 insertions(+), 9 deletions(-)

diff --git a/lxd/firewall/interfaces.go b/lxd/firewall/interfaces.go
index 3e5bd8bd07..db06fedf3f 100644
--- a/lxd/firewall/interfaces.go
+++ b/lxd/firewall/interfaces.go
@@ -4,35 +4,34 @@ import (
        "net"
 
        deviceConfig "github.com/lxc/lxd/lxd/device/config"
-       firewallConsts "github.com/lxc/lxd/lxd/firewall/consts"
-       "github.com/lxc/lxd/lxd/iptables"
+       "github.com/lxc/lxd/lxd/firewall/drivers"
 )
 
 // Firewall represents an LXD firewall.
 type Firewall interface {
        // Lower-level Functions
-       NetworkClear(family firewallConsts.Family, table firewallConsts.Table, 
comment string) error
-       InstanceClear(family firewallConsts.Family, table firewallConsts.Table, 
comment string) error
+       NetworkClear(family drivers.Family, table drivers.Table, comment 
string) error
+       InstanceClear(family drivers.Family, table drivers.Table, comment 
string) error
        VerifyIPv6Module() error
 
        // Proxy Functions
-       InstanceProxySetupNAT(family firewallConsts.Family, connType, address, 
port string, destAddr net.IP, destPort string, comment string) error
+       InstanceProxySetupNAT(family drivers.Family, connType, address, port 
string, destAddr net.IP, destPort string, comment string) error
 
        // NIC Bridged Functions
        InstanceNicBridgedRemoveFilters(m deviceConfig.Device, ipv4 net.IP, 
ipv6 net.IP) error
        InstanceNicBridgedSetFilters(m deviceConfig.Device, ipv4 net.IP, ipv6 
net.IP, comment string) error
 
        // Network Functions
-       NetworkSetupAllowForwarding(family firewallConsts.Family, name string, 
actionType firewallConsts.Action) error
-       NetworkSetupNAT(family firewallConsts.Family, name string, location 
firewallConsts.Location, args ...string) error
+       NetworkSetupAllowForwarding(family drivers.Family, name string, 
actionType drivers.Action) error
+       NetworkSetupNAT(family drivers.Family, name string, location 
drivers.Location, args ...string) error
        NetworkSetupIPv4DNSOverrides(name string) error
        NetworkSetupIPv4DHCPWorkaround(name string) error
        NetworkSetupIPv6DNSOverrides(name string) error
-       NetworkSetupTunnelNAT(name string, location firewallConsts.Location, 
overlaySubnet net.IPNet) error
+       NetworkSetupTunnelNAT(name string, location drivers.Location, 
overlaySubnet net.IPNet) error
 }
 
 // New returns an appropriate firewall implementation.
 func New() Firewall {
        // TODO: Issue #6223: add startup logic to choose xtables or nftables
-       return iptables.XTables{}
+       return drivers.XTables{}
 }
_______________________________________________
lxc-devel mailing list
lxc-devel@lists.linuxcontainers.org
http://lists.linuxcontainers.org/listinfo/lxc-devel

Reply via email to