Skip to content

Commit

Permalink
refactor: add receiver to iptables and create interface (#2421)
Browse files Browse the repository at this point in the history
* Move network utils functions with iptables to new file

* Add receiver to iptables and create interface

* Resolve conflicts from rebasing

* Add changes for building on windows

* Address linter issues

* Address windows linter issues

* Invert if condition for linter nesting

* Scope iptables interfaces to package

* Rename iptables client to avoid stuttering

* Move EnableIPForwarding to snat linux

* Rename ipTablesClientInterface to ipTablesClient

* Address linter issues from moving enable ip forwarding function

* Rename after rebase
  • Loading branch information
QxBytes authored and matmerr committed Jan 16, 2024
1 parent 244bfc0 commit 52d9efb
Show file tree
Hide file tree
Showing 20 changed files with 195 additions and 133 deletions.
21 changes: 11 additions & 10 deletions cni/network/invoker_cns.go
Original file line number Diff line number Diff line change
Expand Up @@ -227,25 +227,26 @@ func setHostOptions(ncSubnetPrefix *net.IPNet, options map[string]interface{}, i
// we need to snat IMDS traffic to node IP, this sets up snat '--to'
snatHostIPJump := fmt.Sprintf("%s --to %s", iptables.Snat, info.hostPrimaryIP)

iptablesClient := iptables.NewClient()
var iptableCmds []iptables.IPTableEntry
if !iptables.ChainExists(iptables.V4, iptables.Nat, iptables.Swift) {
iptableCmds = append(iptableCmds, iptables.GetCreateChainCmd(iptables.V4, iptables.Nat, iptables.Swift))
if !iptablesClient.ChainExists(iptables.V4, iptables.Nat, iptables.Swift) {
iptableCmds = append(iptableCmds, iptablesClient.GetCreateChainCmd(iptables.V4, iptables.Nat, iptables.Swift))
}

if !iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Postrouting, "", iptables.Swift) {
iptableCmds = append(iptableCmds, iptables.GetAppendIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Postrouting, "", iptables.Swift))
if !iptablesClient.RuleExists(iptables.V4, iptables.Nat, iptables.Postrouting, "", iptables.Swift) {
iptableCmds = append(iptableCmds, iptablesClient.GetAppendIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Postrouting, "", iptables.Swift))
}

if !iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureDNSUDPMatch, snatPrimaryIPJump) {
iptableCmds = append(iptableCmds, iptables.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureDNSUDPMatch, snatPrimaryIPJump))
if !iptablesClient.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureDNSUDPMatch, snatPrimaryIPJump) {
iptableCmds = append(iptableCmds, iptablesClient.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureDNSUDPMatch, snatPrimaryIPJump))
}

if !iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureDNSTCPMatch, snatPrimaryIPJump) {
iptableCmds = append(iptableCmds, iptables.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureDNSTCPMatch, snatPrimaryIPJump))
if !iptablesClient.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureDNSTCPMatch, snatPrimaryIPJump) {
iptableCmds = append(iptableCmds, iptablesClient.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureDNSTCPMatch, snatPrimaryIPJump))
}

if !iptables.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureIMDSMatch, snatHostIPJump) {
iptableCmds = append(iptableCmds, iptables.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureIMDSMatch, snatHostIPJump))
if !iptablesClient.RuleExists(iptables.V4, iptables.Nat, iptables.Swift, azureIMDSMatch, snatHostIPJump) {
iptableCmds = append(iptableCmds, iptablesClient.GetInsertIptableRuleCmd(iptables.V4, iptables.Nat, iptables.Swift, azureIMDSMatch, snatHostIPJump))
}

options[network.IPTablesKey] = iptableCmds
Expand Down
2 changes: 1 addition & 1 deletion cni/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ func NewPlugin(name string,

nl := netlink.NewNetlink()
// Setup network manager.
nm, err := network.NewNetworkManager(nl, platform.NewExecClient(logger), &netio.NetIO{}, network.NewNamespaceClient())
nm, err := network.NewNetworkManager(nl, platform.NewExecClient(logger), &netio.NetIO{}, network.NewNamespaceClient(), iptables.NewClient())
if err != nil {
return nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion cnm/network/network.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/Azure/azure-container-networking/cnm"
cnsclient "github.com/Azure/azure-container-networking/cns/client"
"github.com/Azure/azure-container-networking/common"
"github.com/Azure/azure-container-networking/iptables"
"github.com/Azure/azure-container-networking/log"
"github.com/Azure/azure-container-networking/netio"
"github.com/Azure/azure-container-networking/netlink"
Expand Down Expand Up @@ -53,7 +54,7 @@ func NewPlugin(config *common.PluginConfig) (NetPlugin, error) {

nl := netlink.NewNetlink()
// Setup network manager.
nm, err := network.NewNetworkManager(nl, platform.NewExecClient(nil), &netio.NetIO{}, network.NewNamespaceClient())
nm, err := network.NewNetworkManager(nl, platform.NewExecClient(nil), &netio.NetIO{}, network.NewNamespaceClient(), iptables.NewClient())
if err != nil {
return nil, err
}
Expand Down
3 changes: 2 additions & 1 deletion cnms/service/networkmonitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (

cnms "github.com/Azure/azure-container-networking/cnms/cnmspackage"
acn "github.com/Azure/azure-container-networking/common"
"github.com/Azure/azure-container-networking/iptables"
"github.com/Azure/azure-container-networking/log"
"github.com/Azure/azure-container-networking/netio"
"github.com/Azure/azure-container-networking/netlink"
Expand Down Expand Up @@ -157,7 +158,7 @@ func main() {
}

nl := netlink.NewNetlink()
nm, err := network.NewNetworkManager(nl, platform.NewExecClient(nil), &netio.NetIO{}, network.NewNamespaceClient())
nm, err := network.NewNetworkManager(nl, platform.NewExecClient(nil), &netio.NetIO{}, network.NewNamespaceClient(), iptables.NewClient())
if err != nil {
log.Printf("[monitor] Failed while creating network manager")
return
Expand Down
50 changes: 28 additions & 22 deletions iptables/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,14 @@ type IPTableEntry struct {
Params string
}

type Client struct{}

func NewClient() *Client {
return &Client{}
}

// Run iptables command
func RunCmd(version, params string) error {
func (c *Client) RunCmd(version, params string) error {
var cmd string

p := platform.NewExecClient(logger)
Expand All @@ -111,29 +117,29 @@ func RunCmd(version, params string) error {
}

// check if iptable chain alreay exists
func ChainExists(version, tableName, chainName string) bool {
func (c *Client) ChainExists(version, tableName, chainName string) bool {
params := fmt.Sprintf("-t %s -L %s", tableName, chainName)
if err := RunCmd(version, params); err != nil {
if err := c.RunCmd(version, params); err != nil {
return false
}

return true
}

func GetCreateChainCmd(version, tableName, chainName string) IPTableEntry {
func (c *Client) GetCreateChainCmd(version, tableName, chainName string) IPTableEntry {
return IPTableEntry{
Version: version,
Params: fmt.Sprintf("-t %s -N %s", tableName, chainName),
}
}

// create new iptable chain under specified table name
func CreateChain(version, tableName, chainName string) error {
func (c *Client) CreateChain(version, tableName, chainName string) error {
var err error

if !ChainExists(version, tableName, chainName) {
cmd := GetCreateChainCmd(version, tableName, chainName)
err = RunCmd(version, cmd.Params)
if !c.ChainExists(version, tableName, chainName) {
cmd := c.GetCreateChainCmd(version, tableName, chainName)
err = c.RunCmd(version, cmd.Params)
} else {
logger.Info("Chain exists in table", zap.String("chainName", chainName), zap.String("tableName", tableName))
}
Expand All @@ -142,52 +148,52 @@ func CreateChain(version, tableName, chainName string) error {
}

// check if iptable rule alreay exists
func RuleExists(version, tableName, chainName, match, target string) bool {
func (c *Client) RuleExists(version, tableName, chainName, match, target string) bool {
params := fmt.Sprintf("-t %s -C %s %s -j %s", tableName, chainName, match, target)
if err := RunCmd(version, params); err != nil {
if err := c.RunCmd(version, params); err != nil {
return false
}
return true
}

func GetInsertIptableRuleCmd(version, tableName, chainName, match, target string) IPTableEntry {
func (c *Client) GetInsertIptableRuleCmd(version, tableName, chainName, match, target string) IPTableEntry {
return IPTableEntry{
Version: version,
Params: fmt.Sprintf("-t %s -I %s 1 %s -j %s", tableName, chainName, match, target),
}
}

// Insert iptable rule at beginning of iptable chain
func InsertIptableRule(version, tableName, chainName, match, target string) error {
if RuleExists(version, tableName, chainName, match, target) {
func (c *Client) InsertIptableRule(version, tableName, chainName, match, target string) error {
if c.RuleExists(version, tableName, chainName, match, target) {
logger.Info("Rule already exists")
return nil
}

cmd := GetInsertIptableRuleCmd(version, tableName, chainName, match, target)
return RunCmd(version, cmd.Params)
cmd := c.GetInsertIptableRuleCmd(version, tableName, chainName, match, target)
return c.RunCmd(version, cmd.Params)
}

func GetAppendIptableRuleCmd(version, tableName, chainName, match, target string) IPTableEntry {
func (c *Client) GetAppendIptableRuleCmd(version, tableName, chainName, match, target string) IPTableEntry {
return IPTableEntry{
Version: version,
Params: fmt.Sprintf("-t %s -A %s %s -j %s", tableName, chainName, match, target),
}
}

// Append iptable rule at end of iptable chain
func AppendIptableRule(version, tableName, chainName, match, target string) error {
if RuleExists(version, tableName, chainName, match, target) {
func (c *Client) AppendIptableRule(version, tableName, chainName, match, target string) error {
if c.RuleExists(version, tableName, chainName, match, target) {
logger.Info("Rule already exists")
return nil
}

cmd := GetAppendIptableRuleCmd(version, tableName, chainName, match, target)
return RunCmd(version, cmd.Params)
cmd := c.GetAppendIptableRuleCmd(version, tableName, chainName, match, target)
return c.RunCmd(version, cmd.Params)
}

// Delete matched iptable rule
func DeleteIptableRule(version, tableName, chainName, match, target string) error {
func (c *Client) DeleteIptableRule(version, tableName, chainName, match, target string) error {
params := fmt.Sprintf("-t %s -D %s %s -j %s", tableName, chainName, match, target)
return RunCmd(version, params)
return c.RunCmd(version, params)
}
9 changes: 6 additions & 3 deletions network/endpoint.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,7 @@ func (nw *network) newEndpoint(
plc platform.ExecClient,
netioCli netio.NetIOInterface,
nsc NamespaceClientInterface,
iptc ipTablesClient,
epInfo []*EndpointInfo,
) (*endpoint, error) {
var ep *endpoint
Expand All @@ -153,7 +154,7 @@ func (nw *network) newEndpoint(

// Call the platform implementation.
// Pass nil for epClient and will be initialized in newendpointImpl
ep, err = nw.newEndpointImpl(apipaCli, nl, plc, netioCli, nil, nsc, epInfo)
ep, err = nw.newEndpointImpl(apipaCli, nl, plc, netioCli, nil, nsc, iptc, epInfo)
if err != nil {
return nil, err
}
Expand All @@ -164,7 +165,9 @@ func (nw *network) newEndpoint(
}

// DeleteEndpoint deletes an existing endpoint from the network.
func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.ExecClient, nioc netio.NetIOInterface, nsc NamespaceClientInterface, endpointID string) error {
func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.ExecClient, nioc netio.NetIOInterface, nsc NamespaceClientInterface,
iptc ipTablesClient, endpointID string,
) error {
var err error

logger.Info("Deleting endpoint from network", zap.String("endpointID", endpointID), zap.String("id", nw.Id))
Expand All @@ -183,7 +186,7 @@ func (nw *network) deleteEndpoint(nl netlink.NetlinkInterface, plc platform.Exec

// Call the platform implementation.
// Pass nil for epClient and will be initialized in deleteEndpointImpl
err = nw.deleteEndpointImpl(nl, plc, nil, nioc, nsc, ep)
err = nw.deleteEndpointImpl(nl, plc, nil, nioc, nsc, iptc, ep)
if err != nil {
return err
}
Expand Down
14 changes: 9 additions & 5 deletions network/endpoint_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ func (nw *network) newEndpointImpl(
netioCli netio.NetIOInterface,
testEpClient EndpointClient,
nsc NamespaceClientInterface,
iptc ipTablesClient,
epInfo []*EndpointInfo,
) (*endpoint, error) {
var (
Expand Down Expand Up @@ -134,7 +135,7 @@ func (nw *network) newEndpointImpl(
if _, ok := epInfo.Data[SnatBridgeIPKey]; ok {
nw.SnatBridgeIP = epInfo.Data[SnatBridgeIPKey].(string)
}
epClient = NewTransparentVlanEndpointClient(nw, epInfo, hostIfName, contIfName, vlanid, localIP, nl, plc, nsc)
epClient = NewTransparentVlanEndpointClient(nw, epInfo, hostIfName, contIfName, vlanid, localIP, nl, plc, nsc, iptc)
} else {
logger.Info("OVS client")
if _, ok := epInfo.Data[SnatBridgeIPKey]; ok {
Expand All @@ -150,7 +151,8 @@ func (nw *network) newEndpointImpl(
localIP,
nl,
ovsctl.NewOvsctl(),
plc)
plc,
iptc)
}
} else if nw.Mode != opModeTransparent {
logger.Info("Bridge client")
Expand Down Expand Up @@ -255,7 +257,9 @@ func (nw *network) newEndpointImpl(
}

// deleteEndpointImpl deletes an existing endpoint from the network.
func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.ExecClient, epClient EndpointClient, nioc netio.NetIOInterface, nsc NamespaceClientInterface, ep *endpoint) error {
func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.ExecClient, epClient EndpointClient, nioc netio.NetIOInterface, nsc NamespaceClientInterface,
iptc ipTablesClient, ep *endpoint,
) error {
// Delete the veth pair by deleting one of the peer interfaces.
// Deleting the host interface is more convenient since it does not require
// entering the container netns and hence works both for CNI and CNM.
Expand All @@ -267,10 +271,10 @@ func (nw *network) deleteEndpointImpl(nl netlink.NetlinkInterface, plc platform.
epInfo := ep.getInfo()
if nw.Mode == opModeTransparentVlan {
logger.Info("Transparent vlan client")
epClient = NewTransparentVlanEndpointClient(nw, epInfo, ep.HostIfName, "", ep.VlanID, ep.LocalIP, nl, plc, nsc)
epClient = NewTransparentVlanEndpointClient(nw, epInfo, ep.HostIfName, "", ep.VlanID, ep.LocalIP, nl, plc, nsc, iptc)

} else {
epClient = NewOVSEndpointClient(nw, epInfo, ep.HostIfName, "", ep.VlanID, ep.LocalIP, nl, ovsctl.NewOvsctl(), plc)
epClient = NewOVSEndpointClient(nw, epInfo, ep.HostIfName, "", ep.VlanID, ep.LocalIP, nl, ovsctl.NewOvsctl(), plc, iptc)
}
} else if nw.Mode != opModeTransparent {
epClient = NewLinuxBridgeEndpointClient(nw.extIf, ep.HostIfName, "", nw.Mode, nl, plc)
Expand Down
4 changes: 1 addition & 3 deletions network/endpoint_snatroute_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"fmt"

"github.com/Azure/azure-container-networking/netlink"
"github.com/Azure/azure-container-networking/network/networkutils"
"github.com/Azure/azure-container-networking/network/snat"
"github.com/Azure/azure-container-networking/platform"
"github.com/pkg/errors"
Expand Down Expand Up @@ -36,8 +35,7 @@ func AddSnatEndpointRules(snatClient *snat.Client, hostToNC, ncToHost bool, nl n
if err := snatClient.BlockIPAddressesOnSnatBridge(); err != nil {
return errors.Wrap(err, "failed to block ip addresses on snat bridge")
}
nuc := networkutils.NewNetworkUtils(nl, plc)
if err := nuc.EnableIPForwarding(); err != nil {
if err := snatClient.EnableIPForwarding(); err != nil {
return errors.Wrap(err, "failed to enable ip forwarding")
}

Expand Down
Loading

0 comments on commit 52d9efb

Please sign in to comment.