Skip to content

Commit

Permalink
Update iptables builder (#6381)
Browse files Browse the repository at this point in the history
We add a new methods to build iptables entries:
`SetTargetDNATToDst`, which sets the DNAT destination IP and port.

We also make changes to existing methods:
- `MatchIPSetSrc` and `MatchIPSetDst` now have an ipset type parameter.
- `MatchDstPort` and `MatchSrcPort` are renamed to `MatchPortDst` and
   `MatchPortSrc` respectively, for consistency.

Signed-off-by: Hongliang Liu <lhongliang@vmware.com>
  • Loading branch information
hongliangl committed Jun 7, 2024
1 parent 2daf12a commit 676fc98
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 24 deletions.
15 changes: 9 additions & 6 deletions pkg/agent/controller/networkpolicy/node_reconciler_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import (
"antrea.io/antrea/pkg/agent/config"
"antrea.io/antrea/pkg/agent/route"
"antrea.io/antrea/pkg/agent/types"
"antrea.io/antrea/pkg/agent/util/ipset"
"antrea.io/antrea/pkg/agent/util/iptables"
"antrea.io/antrea/pkg/apis/controlplane/v1beta2"
secv1beta1 "antrea.io/antrea/pkg/apis/crd/v1beta1"
Expand All @@ -42,6 +43,8 @@ const (
ipv6Any = "::/0"
)

var ipsetTypeHashIP = ipset.HashIP

/*
Tips:
In the following, service describes a port to allow traffic on which is defined in pkg/apis/controlplane/v1beta2/types.go
Expand Down Expand Up @@ -622,7 +625,7 @@ func buildCoreIPTRule(ipProtocol iptables.Protocol,
builder := iptables.NewRuleBuilder(iptChain)
if isIngress {
if ipset != "" {
builder = builder.MatchIPSetSrc(ipset)
builder = builder.MatchIPSetSrc(ipset, ipsetTypeHashIP)
} else if ipnet != "" {
builder = builder.MatchCIDRSrc(ipnet)
} else {
Expand All @@ -631,7 +634,7 @@ func buildCoreIPTRule(ipProtocol iptables.Protocol,
}
} else {
if ipset != "" {
builder = builder.MatchIPSetDst(ipset)
builder = builder.MatchIPSetDst(ipset, ipsetTypeHashIP)
} else if ipnet != "" {
builder = builder.MatchCIDRDst(ipnet)
} else {
Expand All @@ -648,8 +651,8 @@ func buildCoreIPTRule(ipProtocol iptables.Protocol,
fallthrough
case "sctp":
builder = builder.MatchTransProtocol(transProtocol).
MatchSrcPort(service.SrcPort, service.SrcEndPort).
MatchDstPort(service.Port, service.EndPort)
MatchPortSrc(service.SrcPort, service.SrcEndPort).
MatchPortDst(service.Port, service.EndPort)
case "icmp":
builder = builder.MatchICMP(service.ICMPType, service.ICMPCode, ipProtocol)
}
Expand All @@ -673,8 +676,8 @@ func buildServiceIPTRules(ipProtocol iptables.Protocol, services []v1beta2.Servi
fallthrough
case "sctp":
copiedBuilder = copiedBuilder.MatchTransProtocol(transProtocol).
MatchSrcPort(svc.SrcPort, svc.SrcEndPort).
MatchDstPort(svc.Port, svc.EndPort)
MatchPortSrc(svc.SrcPort, svc.SrcEndPort).
MatchPortDst(svc.Port, svc.EndPort)
case "icmp":
copiedBuilder = copiedBuilder.MatchICMP(svc.ICMPType, svc.ICMPCode, ipProtocol)
}
Expand Down
51 changes: 43 additions & 8 deletions pkg/agent/util/iptables/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ import (
"strings"

"k8s.io/apimachinery/pkg/util/intstr"

"antrea.io/antrea/pkg/agent/util/ipset"
)

type iptablesRule struct {
Expand Down Expand Up @@ -67,20 +69,38 @@ func (b *iptablesRuleBuilder) MatchCIDRDst(cidr string) IPTablesRuleBuilder {
return b
}

func (b *iptablesRuleBuilder) MatchIPSetSrc(ipset string) IPTablesRuleBuilder {
if ipset == "" {
func (b *iptablesRuleBuilder) MatchIPSetSrc(ipsetName string, ipsetType ipset.SetType) IPTablesRuleBuilder {
if ipsetName == "" {
return b
}
matchStr := fmt.Sprintf("-m set --match-set %s src", ipset)
var typeStr string
switch ipsetType {
case ipset.HashNet:
fallthrough
case ipset.HashIP:
typeStr = "src"
case ipset.HashIPPort:
typeStr = "src,src"
}
matchStr := fmt.Sprintf("-m set --match-set %s %s", ipsetName, typeStr)
b.writeSpec(matchStr)
return b
}

func (b *iptablesRuleBuilder) MatchIPSetDst(ipset string) IPTablesRuleBuilder {
if ipset == "" {
func (b *iptablesRuleBuilder) MatchIPSetDst(ipsetName string, ipsetType ipset.SetType) IPTablesRuleBuilder {
if ipsetName == "" {
return b
}
matchStr := fmt.Sprintf("-m set --match-set %s dst", ipset)
var typeStr string
switch ipsetType {
case ipset.HashNet:
fallthrough
case ipset.HashIP:
typeStr = "dst"
case ipset.HashIPPort:
typeStr = "dst,dst"
}
matchStr := fmt.Sprintf("-m set --match-set %s %s", ipsetName, typeStr)
b.writeSpec(matchStr)
return b
}
Expand All @@ -94,7 +114,7 @@ func (b *iptablesRuleBuilder) MatchTransProtocol(protocol string) IPTablesRuleBu
return b
}

func (b *iptablesRuleBuilder) MatchDstPort(port *intstr.IntOrString, endPort *int32) IPTablesRuleBuilder {
func (b *iptablesRuleBuilder) MatchPortDst(port *intstr.IntOrString, endPort *int32) IPTablesRuleBuilder {
if port == nil {
return b
}
Expand All @@ -108,7 +128,7 @@ func (b *iptablesRuleBuilder) MatchDstPort(port *intstr.IntOrString, endPort *in
return b
}

func (b *iptablesRuleBuilder) MatchSrcPort(port, endPort *int32) IPTablesRuleBuilder {
func (b *iptablesRuleBuilder) MatchPortSrc(port, endPort *int32) IPTablesRuleBuilder {
if port == nil {
return b
}
Expand Down Expand Up @@ -178,6 +198,21 @@ func (b *iptablesRuleBuilder) SetTarget(target string) IPTablesRuleBuilder {
return b
}

func (b *iptablesRuleBuilder) SetTargetDNATToDst(dnatIP string, dnatPort *int32) IPTablesRuleBuilder {
if dnatIP == "" {
return b
}
var dstStr string
if dnatPort != nil {
dstStr = fmt.Sprintf("%s:%d", dnatIP, *dnatPort)
} else {
dstStr = dnatIP
}
specStr := fmt.Sprintf("--to-destination %s", dstStr)
b.writeSpec(specStr)
return b
}

func (b *iptablesRuleBuilder) SetComment(comment string) IPTablesRuleBuilder {
if comment == "" {
return b
Expand Down
28 changes: 22 additions & 6 deletions pkg/agent/util/iptables/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ import (

"github.com/stretchr/testify/assert"
"k8s.io/apimachinery/pkg/util/intstr"

"antrea.io/antrea/pkg/agent/util/ipset"
)

var (
Expand Down Expand Up @@ -50,11 +52,11 @@ func TestBuilders(t *testing.T) {
name: "Accept TCP destination 8080 in FORWARD",
chain: ForwardChain,
buildFunc: func(builder IPTablesRuleBuilder) IPTablesRule {
return builder.MatchIPSetSrc(ipsetAlfa).
MatchIPSetDst(ipsetBravo).
return builder.MatchIPSetSrc(ipsetAlfa, ipset.HashIP).
MatchIPSetDst(ipsetBravo, ipset.HashIP).
MatchInputInterface(eth0).
MatchTransProtocol(ProtocolTCP).
MatchDstPort(port8080, nil).
MatchPortDst(port8080, nil).
MatchCIDRSrc(cidr).
SetComment("Accept TCP 8080").
SetTarget(AcceptTarget).
Expand All @@ -66,10 +68,10 @@ func TestBuilders(t *testing.T) {
name: "Drop UDP destination 137-139 in INPUT",
chain: "INPUT",
buildFunc: func(builder IPTablesRuleBuilder) IPTablesRule {
return builder.MatchIPSetSrc(ipsetAlfa).
return builder.MatchIPSetSrc(ipsetAlfa, ipset.HashIP).
MatchInputInterface(eth0).
MatchTransProtocol(ProtocolUDP).
MatchDstPort(port137, &port139).
MatchPortDst(port137, &port139).
MatchCIDRDst(cidr).
SetComment("Drop UDP 137-139").
SetTarget(DropTarget).
Expand All @@ -83,7 +85,7 @@ func TestBuilders(t *testing.T) {
buildFunc: func(builder IPTablesRuleBuilder) IPTablesRule {
return builder.MatchOutputInterface(eth1).
MatchTransProtocol(ProtocolSCTP).
MatchSrcPort(&port40000, &port50000).
MatchPortSrc(&port40000, &port50000).
SetComment("Drop SCTP 40000-50000").
SetTarget(DropTarget).
Done()
Expand Down Expand Up @@ -123,6 +125,20 @@ func TestBuilders(t *testing.T) {
},
expected: `-A INPUT -p tcp -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT`,
},
{
name: "DNAT packets from specific connections",
chain: PreRoutingChain,
buildFunc: func(builder IPTablesRuleBuilder) IPTablesRule {
return builder.MatchCIDRSrc("192.168.77.100").
MatchCIDRDst("10.96.0.10").
MatchTransProtocol(ProtocolTCP).
MatchPortDst(port8080, nil).
SetTarget(DNATTarget).
SetTargetDNATToDst("10.10.0.2", &port40000).
Done()
},
expected: `-A PREROUTING -s 192.168.77.100 -d 10.96.0.10 -p tcp --dport 8080 -j DNAT --to-destination 10.10.0.2:40000`,
},
}

for _, tc := range testCases {
Expand Down
11 changes: 7 additions & 4 deletions pkg/agent/util/iptables/iptables.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
"github.com/coreos/go-iptables/iptables"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/klog/v2"

"antrea.io/antrea/pkg/agent/util/ipset"
)

const (
Expand Down Expand Up @@ -109,16 +111,17 @@ type Interface interface {
type IPTablesRuleBuilder interface {
MatchCIDRSrc(cidr string) IPTablesRuleBuilder
MatchCIDRDst(cidr string) IPTablesRuleBuilder
MatchIPSetSrc(ipset string) IPTablesRuleBuilder
MatchIPSetDst(ipset string) IPTablesRuleBuilder
MatchIPSetSrc(ipset string, ipsetType ipset.SetType) IPTablesRuleBuilder
MatchIPSetDst(ipset string, ipsetType ipset.SetType) IPTablesRuleBuilder
MatchTransProtocol(protocol string) IPTablesRuleBuilder
MatchDstPort(port *intstr.IntOrString, endPort *int32) IPTablesRuleBuilder
MatchSrcPort(port, endPort *int32) IPTablesRuleBuilder
MatchPortDst(port *intstr.IntOrString, endPort *int32) IPTablesRuleBuilder
MatchPortSrc(port, endPort *int32) IPTablesRuleBuilder
MatchICMP(icmpType, icmpCode *int32, ipProtocol Protocol) IPTablesRuleBuilder
MatchEstablishedOrRelated() IPTablesRuleBuilder
MatchInputInterface(interfaceName string) IPTablesRuleBuilder
MatchOutputInterface(interfaceName string) IPTablesRuleBuilder
SetTarget(target string) IPTablesRuleBuilder
SetTargetDNATToDst(dnatIP string, dnatPort *int32) IPTablesRuleBuilder
SetComment(comment string) IPTablesRuleBuilder
CopyBuilder() IPTablesRuleBuilder
Done() IPTablesRule
Expand Down

0 comments on commit 676fc98

Please sign in to comment.