Skip to content

Commit eff3c55

Browse files
felixhuettnerummakynes
authored andcommitted
netfilter: ctnetlink: support filtering by zone
conntrack zones are heavily used by tools like openvswitch to run multiple virtual "routers" on a single machine. In this context each conntrack zone matches to a single router, thereby preventing overlapping IPs from becoming issues. In these systems it is common to operate on all conntrack entries of a given zone, e.g. to delete them when a router is deleted. Previously this required these tools to dump the full conntrack table and filter out the relevant entries in userspace potentially causing performance issues. To do this we reuse the existing CTA_ZONE attribute. This was previous parsed but not used during dump and flush requests. Now if CTA_ZONE is set we filter these operations based on the provided zone. However this means that users that previously passed CTA_ZONE will experience a difference in functionality. Alternatively CTA_FILTER could have been used for the same functionality. However it is not yet supported during flush requests and is only available when using AF_INET or AF_INET6. Co-developed-by: Luca Czesla <[email protected]> Signed-off-by: Luca Czesla <[email protected]> Co-developed-by: Max Lamprecht <[email protected]> Signed-off-by: Max Lamprecht <[email protected]> Signed-off-by: Felix Huettner <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 08e4c8c commit eff3c55

File tree

4 files changed

+442
-5
lines changed

4 files changed

+442
-5
lines changed

net/netfilter/nf_conntrack_netlink.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -992,13 +992,13 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
992992
if (err)
993993
goto err_filter;
994994

995-
if (!cda[CTA_FILTER])
996-
return filter;
997-
998995
err = ctnetlink_parse_zone(cda[CTA_ZONE], &filter->zone);
999996
if (err < 0)
1000997
goto err_filter;
1001998

999+
if (!cda[CTA_FILTER])
1000+
return filter;
1001+
10021002
err = ctnetlink_parse_filter(cda[CTA_FILTER], filter);
10031003
if (err < 0)
10041004
goto err_filter;
@@ -1043,7 +1043,7 @@ ctnetlink_alloc_filter(const struct nlattr * const cda[], u8 family)
10431043

10441044
static bool ctnetlink_needs_filter(u8 family, const struct nlattr * const *cda)
10451045
{
1046-
return family || cda[CTA_MARK] || cda[CTA_FILTER] || cda[CTA_STATUS];
1046+
return family || cda[CTA_MARK] || cda[CTA_FILTER] || cda[CTA_STATUS] || cda[CTA_ZONE];
10471047
}
10481048

10491049
static int ctnetlink_start(struct netlink_callback *cb)
@@ -1148,6 +1148,10 @@ static int ctnetlink_filter_match(struct nf_conn *ct, void *data)
11481148
if (filter->family && nf_ct_l3num(ct) != filter->family)
11491149
goto ignore_entry;
11501150

1151+
if (filter->zone.id != NF_CT_DEFAULT_ZONE_ID &&
1152+
!nf_ct_zone_equal_any(ct, &filter->zone))
1153+
goto ignore_entry;
1154+
11511155
if (filter->orig_flags) {
11521156
tuple = nf_ct_tuple(ct, IP_CT_DIR_ORIGINAL);
11531157
if (!ctnetlink_filter_match_tuple(&filter->orig, tuple,

tools/testing/selftests/netfilter/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
nf-queue
33
connect_close
44
audit_logread
5+
conntrack_dump_flush
6+
sctp_collision

tools/testing/selftests/netfilter/Makefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ HOSTPKG_CONFIG := pkg-config
1414
CFLAGS += $(shell $(HOSTPKG_CONFIG) --cflags libmnl 2>/dev/null)
1515
LDLIBS += $(shell $(HOSTPKG_CONFIG) --libs libmnl 2>/dev/null || echo -lmnl)
1616

17-
TEST_GEN_FILES = nf-queue connect_close audit_logread sctp_collision
17+
TEST_GEN_FILES = nf-queue connect_close audit_logread sctp_collision \
18+
conntrack_dump_flush
1819

1920
include ../lib.mk

0 commit comments

Comments
 (0)