Skip to content

Commit

Permalink
use nftable rules for coreOS servers on masquerade
Browse files Browse the repository at this point in the history
This PR check if iptables are enable and if not use nftables to
configure rules for the masquerade interface binding.

Fixes kubevirt#2400
  • Loading branch information
SchSeba committed Jul 17, 2019
1 parent c3da8c3 commit 50fbcc6
Show file tree
Hide file tree
Showing 2 changed files with 132 additions and 1 deletion.
49 changes: 49 additions & 0 deletions pkg/virt-launcher/virtwrap/network/common.go
Expand Up @@ -25,6 +25,7 @@ import (
"crypto/rand"
"encoding/json"
"fmt"
"os/exec"

"io/ioutil"
"net"
Expand Down Expand Up @@ -81,8 +82,13 @@ type NetworkHandler interface {
GetMacDetails(iface string) (net.HardwareAddr, error)
LinkSetMaster(link netlink.Link, master *netlink.Bridge) error
StartDHCP(nic *VIF, serverAddr *netlink.Addr, bridgeInterfaceName string, dhcpOptions *v1.DHCPOptions)
UseIptables() error
IptablesNewChain(table, chain string) error
IptablesAppendRule(table, chain string, rulespec ...string) error
NftablesNewChain(table, chain string) error
NftablesAppendRule(table, chain string, rulespec ...string) error
NftablesNewTable(table string) error
NftablesLoad(fnName string) error
}

type NetworkUtilsHandler struct{}
Expand Down Expand Up @@ -122,6 +128,16 @@ func (h *NetworkUtilsHandler) AddrAdd(link netlink.Link, addr *netlink.Addr) err
func (h *NetworkUtilsHandler) LinkSetMaster(link netlink.Link, master *netlink.Bridge) error {
return netlink.LinkSetMaster(link, master)
}
func (h *NetworkUtilsHandler) UseIptables() error {
iptablesObject, err := iptables.New()
if err != nil {
return err
}

_, err = iptablesObject.List("nat", "OUTPUT")

return err
}
func (h *NetworkUtilsHandler) IptablesNewChain(table, chain string) error {
iptablesObject, err := iptables.New()
if err != nil {
Expand All @@ -138,6 +154,39 @@ func (h *NetworkUtilsHandler) IptablesAppendRule(table, chain string, rulespec .

return iptablesObject.Append(table, chain, rulespec...)
}
func (h *NetworkUtilsHandler) NftablesNewChain(table, chain string) error {
output, err := exec.Command("nft", "add", "chain", "ip", table, chain).CombinedOutput()
if err != nil {
return fmt.Errorf("%s", string(output))
}

return nil
}
func (h *NetworkUtilsHandler) NftablesAppendRule(table, chain string, rulespec ...string) error {
cmd := append([]string{"add", "rule", "ip", table, chain}, rulespec...)
output, err := exec.Command("nft", cmd...).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to apped new nfrule error %s", string(output))
}

return nil
}
func (h *NetworkUtilsHandler) NftablesNewTable(table string) error {
output, err := exec.Command("nft", "add", "table", table).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to create new nftable error %s", string(output))
}

return nil
}
func (h *NetworkUtilsHandler) NftablesLoad(fnName string) error {
output, err := exec.Command("nft", "-f", fmt.Sprintf("/etc/nftables/%s.nft", fnName)).CombinedOutput()
if err != nil {
return fmt.Errorf("failed to load nftable %s error %s", fnName, string(output))
}

return nil
}
func (h *NetworkUtilsHandler) GetHostAndGwAddressesFromCIDR(s string) (string, string, error) {
ip, ipnet, err := net.ParseCIDR(s)
if err != nil {
Expand Down
84 changes: 83 additions & 1 deletion pkg/virt-launcher/virtwrap/network/podinterface.go
Expand Up @@ -516,7 +516,13 @@ func (p *MasqueradePodInterface) createBridge() error {
}

func (p *MasqueradePodInterface) createNatRules() error {
if Handler.UseIptables() {
return p.createNatRulesUsingIptables()
}
return p.createNatRulesUsingNftable()
}

func (p *MasqueradePodInterface) createNatRulesUsingIptables() error {
err := Handler.IptablesNewChain("nat", "KUBEVIRT_PREINBOUND")
if err != nil {
return err
Expand Down Expand Up @@ -593,7 +599,83 @@ func (p *MasqueradePodInterface) createNatRules() error {
return err
}
}
return err

return nil
}

func (p *MasqueradePodInterface) createNatRulesUsingNftable() error {
err := Handler.NftablesLoad("ipv4-nat")
if err != nil {
return err
}

err = Handler.NftablesNewChain("nat", "KUBEVIRT_PREINBOUND")
if err != nil {
return err
}

err = Handler.NftablesNewChain("nat", "KUBEVIRT_POSTINBOUND")
if err != nil {
return err
}

err = Handler.NftablesAppendRule("nat", "postrouting", "ip", "saddr", p.vif.IP.IP.String(), "counter", "masquerade")
if err != nil {
return err
}

err = Handler.NftablesAppendRule("nat", "prerouting", "iifname", p.podInterfaceName, "counter", "jump", "KUBEVIRT_PREINBOUND")
if err != nil {
return err
}

err = Handler.NftablesAppendRule("nat", "postrouting", "oifname", p.bridgeInterfaceName, "counter", "jump", "KUBEVIRT_POSTINBOUND")
if err != nil {
return err
}

if len(p.iface.Ports) == 0 {
err = Handler.NftablesAppendRule("nat", "KUBEVIRT_PREINBOUND",
"counter", "dnat", "to", p.vif.IP.IP.String())

return err
}

for _, port := range p.iface.Ports {
if port.Protocol == "" {
port.Protocol = "tcp"
}

err = Handler.NftablesAppendRule("nat", "KUBEVIRT_POSTINBOUND",
strings.ToLower(port.Protocol),
"dport",
strconv.Itoa(int(port.Port)),
"counter", "snat", "to", p.gatewayAddr.IP.String())
if err != nil {
return err
}

err = Handler.NftablesAppendRule("nat", "KUBEVIRT_PREINBOUND",
strings.ToLower(port.Protocol),
"dport",
strconv.Itoa(int(port.Port)),
"counter", "dnat", "to", p.vif.IP.IP.String())
if err != nil {
return err
}

err = Handler.NftablesAppendRule("nat", "output",
"ip", "daddr", "127.0.0.1",
strings.ToLower(port.Protocol),
"dport",
strconv.Itoa(int(port.Port)),
"counter", "dnat", "to", p.vif.IP.IP.String())
if err != nil {
return err
}
}

return nil
}

type SlirpPodInterface struct {
Expand Down

0 comments on commit 50fbcc6

Please sign in to comment.