Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a flowtable to speed up forwarding #158

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions pkg/nftables/nftables.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,22 @@ table inet firewall {
counter drop_total { }
counter drop_ratelimit { }

{{- if gt (len .VrfIDs) 0 }}
# create a flowtable for all interfaces
flowtable f {
hook ingress priority 1; devices = { {{ StringsJoin .VrfIDs ", " }} }; counter;
}
{{- end }}

chain forward {
type filter hook forward priority 1; policy drop;

{{- if gt (len .VrfIDs) 0 }}
# offload established connections
ip protocol { tcp, udp } flow offload @f
ip6 nexthdr { tcp, udp } flow offload @f
{{- end }}

# network traffic accounting for external traffic
ip saddr != @internal_prefixes oifname {"vlan{{ .PrivateVrfID }}", "vrf{{ .PrivateVrfID }}"} counter name external_in comment "count external traffic incomming"
ip daddr != @internal_prefixes iifname {"vlan{{ .PrivateVrfID }}", "vrf{{ .PrivateVrfID }}"} counter name external_out comment "count external traffic outgoing"
Expand Down
13 changes: 13 additions & 0 deletions pkg/nftables/rendering.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type firewallRenderingData struct {
Sets []dns.RenderIPSet
InternalPrefixes string
PrivateVrfID uint
VrfIDs []string
}

func newFirewallRenderingData(f *Firewall) (*firewallRenderingData, error) {
Expand Down Expand Up @@ -60,6 +61,17 @@ func newFirewallRenderingData(f *Firewall) (*firewallRenderingData, error) {
if f.cache.IsInitialized() {
sets = f.cache.GetSetsForRendering(f.clusterwideNetworkPolicies.GetFQDNs())
}

var vrfIDs []string
for _, nw := range f.networkMap {
nw := nw
if nw.Vrf == nil {
continue
}
vrfIDs = append(vrfIDs, fmt.Sprintf("vlan%d", *nw.Vrf))
vrfIDs = append(vrfIDs, fmt.Sprintf("vrf%d", *nw.Vrf))
}

return &firewallRenderingData{
PrivateVrfID: uint(*f.primaryPrivateNet.Vrf),
InternalPrefixes: strings.Join(f.firewall.Spec.InternalPrefixes, ", "),
Expand All @@ -70,6 +82,7 @@ func newFirewallRenderingData(f *Firewall) (*firewallRenderingData, error) {
RateLimitRules: rateLimitRules(f),
SnatRules: snatRules,
Sets: sets,
VrfIDs: vrfIDs,
}, nil
}

Expand Down
27 changes: 27 additions & 0 deletions pkg/nftables/rendering_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,33 @@ func TestFirewallRenderingData_renderString(t *testing.T) {
},
wantErr: false,
},
{
name: "flowtable",
data: &firewallRenderingData{
ForwardingRules: forwardingRules{
Egress: []string{"egress rule"},
Ingress: []string{"ingress rule"},
},
InternalPrefixes: "1.2.3.4",
RateLimitRules: []string{"meta iifname \"eth0\" limit rate over 10 mbytes/second counter name drop_ratelimit drop"},
SnatRules: []string{},
PrivateVrfID: uint(42),
Sets: []dns.RenderIPSet{
{
SetName: "test",
IPs: []string{"10.0.0.1", "10.0.0.2"},
Version: dns.IPv4,
},
{
SetName: "test2",
IPs: []string{"2001:db8:85a3::8a2e:370:7334", "2001:db8:85a3::8a2e:370:7335"},
Version: dns.IPv6,
},
},
VrfIDs: []string{"vlan60", "vrf60", "vlan90", "vrf90", "vlan104009", "vrf104009"},
},
wantErr: false,
},
}
for _, tt := range tests {
tt := tt
Expand Down
81 changes: 81 additions & 0 deletions pkg/nftables/test_data/flowtable.nftable.v4
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
table inet firewall {
# internal prefixes, which are not leaving the partition or the partition interconnect
set internal_prefixes {
type ipv4_addr
flags interval
auto-merge

elements = { 1.2.3.4 }

}

# Prefixes in the cluster, typically 10.x.x.x
# FIXME Should be filled with nodeCidr
set cluster_prefixes {
type ipv4_addr
flags interval
auto-merge
elements = { 10.0.0.0/8 }
}

set test {
type ipv4_addr

elements = { 10.0.0.1, 10.0.0.2 }

}

set test2 {
type ipv6_addr

elements = { 2001:db8:85a3::8a2e:370:7334, 2001:db8:85a3::8a2e:370:7335 }

}

# counters
counter internal_in { }
counter internal_out { }
counter external_in { }
counter external_out { }
counter drop_total { }
counter drop_ratelimit { }
# create a flowtable for all interfaces
flowtable f {
hook ingress priority 1; devices = { vlan60, vrf60, vlan90, vrf90, vlan104009, vrf104009 }; counter;
}

chain forward {
type filter hook forward priority 1; policy drop;
# offload established connections
ip protocol { tcp, udp } flow offload @f
ip6 nexthdr { tcp, udp } flow offload @f

# network traffic accounting for external traffic
ip saddr != @internal_prefixes oifname {"vlan42", "vrf42"} counter name external_in comment "count external traffic incomming"
ip daddr != @internal_prefixes iifname {"vlan42", "vrf42"} counter name external_out comment "count external traffic outgoing"

# network traffic accounting for internal traffic
ip saddr @internal_prefixes oifname {"vlan42", "vrf42"} counter name internal_in comment "count internal traffic incomming"
ip daddr @internal_prefixes iifname {"vlan42", "vrf42"} counter name internal_out comment "count internal traffic outgoing"

# rate limits
meta iifname "eth0" limit rate over 10 mbytes/second counter name drop_ratelimit drop

# state dependent rules
ct state established,related counter accept comment "accept established connections"
ct state invalid counter drop comment "drop packets with invalid ct state"

# icmp
ip protocol icmp icmp type echo-request limit rate over 10/second burst 4 packets counter drop comment "drop ping floods"
ip protocol icmp icmp type { destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } counter log prefix "nftables-firewall-accepted: " accept comment "accept icmp"

# dynamic ingress rules
ingress rule

# dynamic egress rules
egress rule

counter comment "count and log dropped packets"
limit rate 10/second counter name drop_total log prefix "nftables-firewall-dropped: "
}
}
Loading