Skip to content

Commit

Permalink
Fix inbound traffic routing to Envoy
Browse files Browse the repository at this point in the history
Istio creates iptables rules with chains called with uppercase
letters, kubevirt adds rules to chains called with lowecase
letters. Since the chain names don't make a difference, we
can use uppercase letters so that when Istio adds its rules, we
don't end up with PREROUTING, prerouting, OUTPUT, output, etc.

Additionally, this commit adds two rules to OUTPUT and
KUBEVIRT_POSTINBOUND which correctly snat and dnat
inbound traffic (to the VM) that targets ports declared in the
VM interface, but undeclared in the associated service.

Envoy sends traffic that targets undeclared ports in a service
from 127.0.0.6 instead from 127.0.0.1.
Ref: istio/istio#29603

Signed-off-by: Radim Hrazdil <rhrazdil@redhat.com>
  • Loading branch information
Radim Hrazdil committed Mar 11, 2021
1 parent 7c36627 commit bd1674a
Showing 1 changed file with 66 additions and 4 deletions.
70 changes: 66 additions & 4 deletions pkg/virt-launcher/virtwrap/network/podinterface.go
Original file line number Diff line number Diff line change
Expand Up @@ -1085,6 +1085,14 @@ func getLoopbackAdrress(proto iptables.Protocol) string {
}
}

func getEnvoyInboundLoopbackAddress(proto iptables.Protocol) string {
if proto == iptables.ProtocolIPv4 {
return "127.0.0.6"
} else {
return "::6"
}
}

func (b *MasqueradeBindMechanism) createNatRulesUsingNftables(proto iptables.Protocol) error {
err := Handler.NftablesNewChain(proto, "nat", "KUBEVIRT_PREINBOUND")
if err != nil {
Expand All @@ -1096,22 +1104,57 @@ func (b *MasqueradeBindMechanism) createNatRulesUsingNftables(proto iptables.Pro
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "postrouting", Handler.GetNFTIPString(proto), "saddr", b.getVifIpByProtocol(proto), "counter", "masquerade")
err = Handler.NftablesNewChain(proto, "nat", "POSTROUTING")
if err != nil {
return err
}

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

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

err = Handler.NftablesAppendRule(proto, "nat", "prerouting", "iifname", b.podInterfaceName, "counter", "jump", "KUBEVIRT_PREINBOUND")
err = Handler.NftablesAppendRule(proto, "nat", "POSTROUTING", Handler.GetNFTIPString(proto), "saddr", b.getVifIpByProtocol(proto), "counter", "masquerade")
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "postrouting", "oifname", b.bridgeInterfaceName, "counter", "jump", "KUBEVIRT_POSTINBOUND")
err = Handler.NftablesAppendRule(proto, "nat", "PREROUTING", "iifname", b.podInterfaceName, "counter", "jump", "KUBEVIRT_PREINBOUND")
if err != nil {
return err
}

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

if len(b.iface.Ports) == 0 {
err = Handler.NftablesAppendRule(proto, "nat", "KUBEVIRT_POSTINBOUND", Handler.GetNFTIPString(proto), "saddr", getEnvoyInboundLoopbackAddress(proto), "counter", "snat", "to", b.getGatewayByProtocol(proto))
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "KUBEVIRT_POSTINBOUND", Handler.GetNFTIPString(proto), "saddr", getLoopbackAdrress(proto), "counter", "snat", "to", b.getGatewayByProtocol(proto))
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "OUTPUT", Handler.GetNFTIPString(proto), "daddr", getLoopbackAdrress(proto), "counter", "dnat", "to", b.getVifIpByProtocol(proto))
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "OUTPUT", Handler.GetNFTIPString(proto), "saddr", getEnvoyInboundLoopbackAddress(proto), "counter", "dnat", "to", b.getVifIpByProtocol(proto))
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "KUBEVIRT_PREINBOUND",
"counter", "dnat", "to", b.getVifIpByProtocol(proto))

Expand All @@ -1122,6 +1165,15 @@ func (b *MasqueradeBindMechanism) createNatRulesUsingNftables(proto iptables.Pro
if port.Protocol == "" {
port.Protocol = "tcp"
}
err = Handler.NftablesAppendRule(proto, "nat", "KUBEVIRT_POSTINBOUND",
strings.ToLower(port.Protocol),
"dport",
strconv.Itoa(int(port.Port)),
Handler.GetNFTIPString(proto), "saddr", getEnvoyInboundLoopbackAddress(proto),
"counter", "snat", "to", b.getGatewayByProtocol(proto))
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "KUBEVIRT_POSTINBOUND",
strings.ToLower(port.Protocol),
Expand All @@ -1142,7 +1194,7 @@ func (b *MasqueradeBindMechanism) createNatRulesUsingNftables(proto iptables.Pro
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "output",
err = Handler.NftablesAppendRule(proto, "nat", "OUTPUT",
Handler.GetNFTIPString(proto), "daddr", getLoopbackAdrress(proto),
strings.ToLower(port.Protocol),
"dport",
Expand All @@ -1151,6 +1203,16 @@ func (b *MasqueradeBindMechanism) createNatRulesUsingNftables(proto iptables.Pro
if err != nil {
return err
}

err = Handler.NftablesAppendRule(proto, "nat", "OUTPUT",
Handler.GetNFTIPString(proto), "saddr", getEnvoyInboundLoopbackAddress(proto),
strings.ToLower(port.Protocol),
"dport",
strconv.Itoa(int(port.Port)),
"counter", "dnat", "to", b.getVifIpByProtocol(proto))
if err != nil {
return err
}
}

return nil
Expand Down

0 comments on commit bd1674a

Please sign in to comment.