Skip to content

Commit

Permalink
iptables: support switching localOnly (IP) in proxy rule redirect
Browse files Browse the repository at this point in the history
Currently, switching the localOnly property of a proxy rule doesn't get
reflected in the iptables rules. The checks for adding iptable rules don't
include the IP of a rule. Therefore, when upgrading, the old rule remains
in the table. The same applies for the check whether an outdated rule
should be deleted from the table.

This commit fixes this, and adds support for changing the localOnly
property of a proxy rule.

Signed-off-by: Marco Hofstetter <marco.hofstetter@isovalent.com>
  • Loading branch information
mhofstetter authored and aditighag committed May 18, 2023
1 parent 60a6031 commit 11828af
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 4 deletions.
10 changes: 6 additions & 4 deletions pkg/datapath/iptables/iptables.go
Expand Up @@ -459,7 +459,8 @@ func (m *IptablesManager) iptIngressProxyRule(rules string, prog iptablesInterfa
ingressProxyMark := fmt.Sprintf("%#x", linux_defaults.MagicMarkIsToProxy)
ingressProxyPort := fmt.Sprintf("%d", proxyPort)

if strings.Contains(rules, fmt.Sprintf("CILIUM_PRE_mangle -p %s -m mark --mark %s", l4proto, ingressMarkMatch)) {
existingRuleRegex := regexp.MustCompile(fmt.Sprintf("CILIUM_PRE_mangle -p %s -m mark --mark %s.*--on-ip %s", l4proto, ingressMarkMatch, ip))
if existingRuleRegex.MatchString(rules) {
return nil
}

Expand Down Expand Up @@ -489,7 +490,8 @@ func (m *IptablesManager) iptEgressProxyRule(rules string, prog iptablesInterfac
egressProxyMark := fmt.Sprintf("%#x", linux_defaults.MagicMarkIsToProxy)
egressProxyPort := fmt.Sprintf("%d", proxyPort)

if strings.Contains(rules, fmt.Sprintf("-A CILIUM_PRE_mangle -p %s -m mark --mark %s", l4proto, egressMarkMatch)) {
existingRuleRegex := regexp.MustCompile(fmt.Sprintf("-A CILIUM_PRE_mangle -p %s -m mark --mark %s.*--on-ip %s", l4proto, egressMarkMatch, ip))
if existingRuleRegex.MatchString(rules) {
return nil
}

Expand Down Expand Up @@ -740,11 +742,11 @@ func (m *IptablesManager) addProxyRules(prog iptablesInterface, ip string, proxy

// Delete all other rules for this same proxy name
// These may accumulate if there is a bind failure on a previously used port
portMatch := fmt.Sprintf("TPROXY --on-port %d ", proxyPort)
portAndIPMatch := fmt.Sprintf("TPROXY --on-port %d --on-ip %s ", proxyPort, ip)
scanner := bufio.NewScanner(strings.NewReader(rules))
for scanner.Scan() {
rule := scanner.Text()
if !strings.Contains(rule, "-A CILIUM_PRE_mangle ") || !strings.Contains(rule, "cilium: TPROXY to host "+name) || strings.Contains(rule, portMatch) {
if !strings.Contains(rule, "-A CILIUM_PRE_mangle ") || !strings.Contains(rule, "cilium: TPROXY to host "+name) || strings.Contains(rule, portAndIPMatch) {
continue
}

Expand Down
41 changes: 41 additions & 0 deletions pkg/datapath/iptables/iptables_test.go
Expand Up @@ -297,6 +297,47 @@ func (s *iptablesTestSuite) TestAddProxyRulesv4(c *check.C) {
mockManager.addProxyRules(mockIp4tables, "0.0.0.0", 37379, false, "cilium-dns-egress")
err = mockIp4tables.checkExpectations()
c.Assert(err, check.IsNil)

mockIp4tables.expectations = []expectation{
{
args: "-t mangle -S",
out: []byte(
`-P PREROUTING ACCEPT
-P INPUT ACCEPT
-P FORWARD ACCEPT
-P OUTPUT ACCEPT
-P POSTROUTING ACCEPT
-N OLD_CILIUM_POST_mangle
-N OLD_CILIUM_PRE_mangle
-N CILIUM_POST_mangle
-N CILIUM_PRE_mangle
-N KUBE-KUBELET-CANARY
-N KUBE-PROXY-CANARY
-A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j OLD_CILIUM_PRE_mangle
-A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j OLD_CILIUM_POST_mangle
-A PREROUTING -m comment --comment "cilium-feeder: CILIUM_PRE_mangle" -j CILIUM_PRE_mangle
-A POSTROUTING -m comment --comment "cilium-feeder: CILIUM_POST_mangle" -j CILIUM_POST_mangle
-A OLD_CILIUM_PRE_mangle -m socket --transparent -m comment --comment "cilium: any->pod redirect proxied traffic to host proxy" -j MARK --set-xmark 0x200/0xffffffff
-A OLD_CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
-A OLD_CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
-A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
-A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment "cilium: TPROXY to host cilium-dns-egress proxy" -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff
`),
}, {
args: "-t mangle -A CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37379",
}, {
args: "-t mangle -A CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --tproxy-mark 0x200 --on-ip 127.0.0.1 --on-port 37379",
}, {
args: "-t mangle -D CILIUM_PRE_mangle -p tcp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff",
}, {
args: "-t mangle -D CILIUM_PRE_mangle -p udp -m mark --mark 0x3920200 -m comment --comment cilium: TPROXY to host cilium-dns-egress proxy -j TPROXY --on-port 37379 --on-ip 0.0.0.0 --tproxy-mark 0x200/0xffffffff",
},
}

// Same port number, new IP, adds new ones, deletes stale rules. Does not touch OLD_ chains
mockManager.addProxyRules(mockIp4tables, "127.0.0.1", 37379, false, "cilium-dns-egress")
err = mockIp4tables.checkExpectations()
c.Assert(err, check.IsNil)
}

func (s *iptablesTestSuite) TestGetProxyPort(c *check.C) {
Expand Down

0 comments on commit 11828af

Please sign in to comment.