Skip to content

Commit

Permalink
[NETFILTER]: nf_conntrack: reduce masks to a subset of tuples
Browse files Browse the repository at this point in the history
Since conntrack currently allows to use masks for every bit of both
helper and expectation tuples, we can't hash them and have to keep
them on two global lists that are searched for every new connection.

This patch removes the never used ability to use masks for the
destination part of the expectation tuple and completely removes
masks from helpers since the only reasonable choice is a full
match on l3num, protonum and src.u.all.

Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Patrick McHardy authored and David S. Miller committed Jul 11, 2007
1 parent df43b4e commit d4156e8
Show file tree
Hide file tree
Showing 16 changed files with 71 additions and 116 deletions.
3 changes: 2 additions & 1 deletion include/net/netfilter/nf_conntrack_expect.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ struct nf_conntrack_expect
struct list_head list;

/* We expect this tuple, with the following mask */
struct nf_conntrack_tuple tuple, mask;
struct nf_conntrack_tuple tuple;
struct nf_conntrack_tuple_mask mask;

/* Function to call after setup and insertion */
void (*expectfn)(struct nf_conn *new,
Expand Down
5 changes: 2 additions & 3 deletions include/net/netfilter/nf_conntrack_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,9 @@ struct nf_conntrack_helper
* expected connections */
unsigned int timeout; /* timeout for expecteds */

/* Mask of things we will help (compared against server response) */
/* Tuple of things we will help (compared against server response) */
struct nf_conntrack_tuple tuple;
struct nf_conntrack_tuple mask;


/* Function to call when data passes; return verdict, or -1 to
invalidate. */
int (*help)(struct sk_buff **pskb,
Expand Down
65 changes: 43 additions & 22 deletions include/net/netfilter/nf_conntrack_tuple.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ struct nf_conntrack_tuple
} dst;
};

struct nf_conntrack_tuple_mask
{
struct {
union nf_conntrack_address u3;
union nf_conntrack_man_proto u;
} src;
};

/* This is optimized opposed to a memset of the whole structure. Everything we
* really care about is the source/destination unions */
#define NF_CT_TUPLE_U_BLANK(tuple) \
Expand Down Expand Up @@ -161,31 +169,44 @@ static inline int nf_ct_tuple_equal(const struct nf_conntrack_tuple *t1,
return nf_ct_tuple_src_equal(t1, t2) && nf_ct_tuple_dst_equal(t1, t2);
}

static inline int nf_ct_tuple_mask_equal(const struct nf_conntrack_tuple_mask *m1,
const struct nf_conntrack_tuple_mask *m2)
{
return (m1->src.u3.all[0] == m2->src.u3.all[0] &&
m1->src.u3.all[1] == m2->src.u3.all[1] &&
m1->src.u3.all[2] == m2->src.u3.all[2] &&
m1->src.u3.all[3] == m2->src.u3.all[3] &&
m1->src.u.all == m2->src.u.all);
}

static inline int nf_ct_tuple_src_mask_cmp(const struct nf_conntrack_tuple *t1,
const struct nf_conntrack_tuple *t2,
const struct nf_conntrack_tuple_mask *mask)
{
int count;

for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++) {
if ((t1->src.u3.all[count] ^ t2->src.u3.all[count]) &
mask->src.u3.all[count])
return 0;
}

if ((t1->src.u.all ^ t2->src.u.all) & mask->src.u.all)
return 0;

if (t1->src.l3num != t2->src.l3num ||
t1->dst.protonum != t2->dst.protonum)
return 0;

return 1;
}

static inline int nf_ct_tuple_mask_cmp(const struct nf_conntrack_tuple *t,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_tuple *mask)
const struct nf_conntrack_tuple_mask *mask)
{
int count = 0;

for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
if ((t->src.u3.all[count] ^ tuple->src.u3.all[count]) &
mask->src.u3.all[count])
return 0;
}

for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
if ((t->dst.u3.all[count] ^ tuple->dst.u3.all[count]) &
mask->dst.u3.all[count])
return 0;
}

if ((t->src.u.all ^ tuple->src.u.all) & mask->src.u.all ||
(t->dst.u.all ^ tuple->dst.u.all) & mask->dst.u.all ||
(t->src.l3num ^ tuple->src.l3num) & mask->src.l3num ||
(t->dst.protonum ^ tuple->dst.protonum) & mask->dst.protonum)
return 0;

return 1;
return nf_ct_tuple_src_mask_cmp(t, tuple, mask) &&
nf_ct_tuple_dst_equal(t, tuple);
}

#endif /* _NF_CONNTRACK_TUPLE_H */
6 changes: 0 additions & 6 deletions net/ipv4/netfilter/nf_nat_snmp_basic.c
Original file line number Diff line number Diff line change
Expand Up @@ -1276,9 +1276,6 @@ static struct nf_conntrack_helper snmp_helper __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.udp.port = __constant_htons(SNMP_PORT),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
};

static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
Expand All @@ -1290,9 +1287,6 @@ static struct nf_conntrack_helper snmp_trap_helper __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.udp.port = __constant_htons(SNMP_TRAP_PORT),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
};

/*****************************************************************************
Expand Down
6 changes: 0 additions & 6 deletions net/netfilter/nf_conntrack_amanda.c
Original file line number Diff line number Diff line change
Expand Up @@ -174,9 +174,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.udp.port = __constant_htons(10080),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
},
{
.name = "amanda",
Expand All @@ -187,9 +184,6 @@ static struct nf_conntrack_helper amanda_helper[2] __read_mostly = {
.tuple.src.l3num = AF_INET6,
.tuple.src.u.udp.port = __constant_htons(10080),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
},
};

Expand Down
44 changes: 9 additions & 35 deletions net/netfilter/nf_conntrack_expect.c
Original file line number Diff line number Diff line change
Expand Up @@ -141,25 +141,16 @@ static inline int expect_clash(const struct nf_conntrack_expect *a,
{
/* Part covered by intersection of masks must be unequal,
otherwise they clash */
struct nf_conntrack_tuple intersect_mask;
struct nf_conntrack_tuple_mask intersect_mask;
int count;

intersect_mask.src.l3num = a->mask.src.l3num & b->mask.src.l3num;
intersect_mask.src.u.all = a->mask.src.u.all & b->mask.src.u.all;
intersect_mask.dst.u.all = a->mask.dst.u.all & b->mask.dst.u.all;
intersect_mask.dst.protonum = a->mask.dst.protonum
& b->mask.dst.protonum;

for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
intersect_mask.src.u3.all[count] =
a->mask.src.u3.all[count] & b->mask.src.u3.all[count];
}

for (count = 0; count < NF_CT_TUPLE_L3SIZE; count++){
intersect_mask.dst.u3.all[count] =
a->mask.dst.u3.all[count] & b->mask.dst.u3.all[count];
}

return nf_ct_tuple_mask_cmp(&a->tuple, &b->tuple, &intersect_mask);
}

Expand All @@ -168,7 +159,7 @@ static inline int expect_matches(const struct nf_conntrack_expect *a,
{
return a->master == b->master
&& nf_ct_tuple_equal(&a->tuple, &b->tuple)
&& nf_ct_tuple_equal(&a->mask, &b->mask);
&& nf_ct_tuple_mask_equal(&a->mask, &b->mask);
}

/* Generally a bad idea to call this: could have matched already. */
Expand Down Expand Up @@ -224,8 +215,6 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
exp->helper = NULL;
exp->tuple.src.l3num = family;
exp->tuple.dst.protonum = proto;
exp->mask.src.l3num = 0xFFFF;
exp->mask.dst.protonum = 0xFF;

if (saddr) {
memcpy(&exp->tuple.src.u3, saddr, len);
Expand All @@ -242,21 +231,6 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
}

if (daddr) {
memcpy(&exp->tuple.dst.u3, daddr, len);
if (sizeof(exp->tuple.dst.u3) > len)
/* address needs to be cleared for nf_ct_tuple_equal */
memset((void *)&exp->tuple.dst.u3 + len, 0x00,
sizeof(exp->tuple.dst.u3) - len);
memset(&exp->mask.dst.u3, 0xFF, len);
if (sizeof(exp->mask.dst.u3) > len)
memset((void *)&exp->mask.dst.u3 + len, 0x00,
sizeof(exp->mask.dst.u3) - len);
} else {
memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
}

if (src) {
exp->tuple.src.u.all = (__force u16)*src;
exp->mask.src.u.all = 0xFFFF;
Expand All @@ -265,13 +239,13 @@ void nf_ct_expect_init(struct nf_conntrack_expect *exp, int family,
exp->mask.src.u.all = 0;
}

if (dst) {
exp->tuple.dst.u.all = (__force u16)*dst;
exp->mask.dst.u.all = 0xFFFF;
} else {
exp->tuple.dst.u.all = 0;
exp->mask.dst.u.all = 0;
}
memcpy(&exp->tuple.dst.u3, daddr, len);
if (sizeof(exp->tuple.dst.u3) > len)
/* address needs to be cleared for nf_ct_tuple_equal */
memset((void *)&exp->tuple.dst.u3 + len, 0x00,
sizeof(exp->tuple.dst.u3) - len);

exp->tuple.dst.u.all = (__force u16)*dst;
}
EXPORT_SYMBOL_GPL(nf_ct_expect_init);

Expand Down
3 changes: 0 additions & 3 deletions net/netfilter/nf_conntrack_ftp.c
Original file line number Diff line number Diff line change
Expand Up @@ -560,9 +560,6 @@ static int __init nf_conntrack_ftp_init(void)
for (j = 0; j < 2; j++) {
ftp[i][j].tuple.src.u.tcp.port = htons(ports[i]);
ftp[i][j].tuple.dst.protonum = IPPROTO_TCP;
ftp[i][j].mask.src.l3num = 0xFFFF;
ftp[i][j].mask.src.u.tcp.port = htons(0xFFFF);
ftp[i][j].mask.dst.protonum = 0xFF;
ftp[i][j].max_expected = 1;
ftp[i][j].timeout = 5 * 60; /* 5 Minutes */
ftp[i][j].me = THIS_MODULE;
Expand Down
14 changes: 0 additions & 14 deletions net/netfilter/nf_conntrack_h323_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -626,8 +626,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_h245 __read_mostly = {
.max_expected = H323_RTP_CHANNEL_MAX * 4 + 2 /* T.120 */,
.timeout = 240,
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
.help = h245_help
};

Expand Down Expand Up @@ -1173,9 +1171,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
.tuple.dst.protonum = IPPROTO_TCP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.tcp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
.help = q931_help
},
{
Expand All @@ -1187,9 +1182,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_q931[] __read_mostly = {
.tuple.src.l3num = AF_INET6,
.tuple.src.u.tcp.port = __constant_htons(Q931_PORT),
.tuple.dst.protonum = IPPROTO_TCP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.tcp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
.help = q931_help
},
};
Expand Down Expand Up @@ -1751,9 +1743,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.udp.port = __constant_htons(RAS_PORT),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
.help = ras_help,
},
{
Expand All @@ -1764,9 +1753,6 @@ static struct nf_conntrack_helper nf_conntrack_helper_ras[] __read_mostly = {
.tuple.src.l3num = AF_INET6,
.tuple.src.u.udp.port = __constant_htons(RAS_PORT),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
.help = ras_help,
},
};
Expand Down
3 changes: 2 additions & 1 deletion net/netfilter/nf_conntrack_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@ struct nf_conntrack_helper *
__nf_ct_helper_find(const struct nf_conntrack_tuple *tuple)
{
struct nf_conntrack_helper *h;
struct nf_conntrack_tuple_mask mask = { .src.u.all = htons(0xFFFF) };

list_for_each_entry(h, &helpers, list) {
if (nf_ct_tuple_mask_cmp(tuple, &h->tuple, &h->mask))
if (nf_ct_tuple_src_mask_cmp(tuple, &h->tuple, &mask))
return h;
}
return NULL;
Expand Down
3 changes: 0 additions & 3 deletions net/netfilter/nf_conntrack_irc.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,6 @@ static int __init nf_conntrack_irc_init(void)
irc[i].tuple.src.l3num = AF_INET;
irc[i].tuple.src.u.tcp.port = htons(ports[i]);
irc[i].tuple.dst.protonum = IPPROTO_TCP;
irc[i].mask.src.l3num = 0xFFFF;
irc[i].mask.src.u.tcp.port = htons(0xFFFF);
irc[i].mask.dst.protonum = 0xFF;
irc[i].max_expected = max_dcc_channels;
irc[i].timeout = dcc_timeout;
irc[i].me = THIS_MODULE;
Expand Down
6 changes: 0 additions & 6 deletions net/netfilter/nf_conntrack_netbios_ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,6 @@ static int help(struct sk_buff **pskb, unsigned int protoff,

exp->mask.src.u3.ip = mask;
exp->mask.src.u.udp.port = htons(0xFFFF);
exp->mask.dst.u3.ip = htonl(0xFFFFFFFF);
exp->mask.dst.u.udp.port = htons(0xFFFF);
exp->mask.dst.protonum = 0xFF;

exp->expectfn = NULL;
exp->flags = NF_CT_EXPECT_PERMANENT;
Expand All @@ -104,9 +101,6 @@ static struct nf_conntrack_helper helper __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.udp.port = __constant_htons(NMBD_PORT),
.tuple.dst.protonum = IPPROTO_UDP,
.mask.src.l3num = 0xFFFF,
.mask.src.u.udp.port = __constant_htons(0xFFFF),
.mask.dst.protonum = 0xFF,
.max_expected = 1,
.me = THIS_MODULE,
.help = help,
Expand Down
18 changes: 13 additions & 5 deletions net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1094,22 +1094,29 @@ ctnetlink_exp_dump_tuple(struct sk_buff *skb,
static inline int
ctnetlink_exp_dump_mask(struct sk_buff *skb,
const struct nf_conntrack_tuple *tuple,
const struct nf_conntrack_tuple *mask)
const struct nf_conntrack_tuple_mask *mask)
{
int ret;
struct nf_conntrack_l3proto *l3proto;
struct nf_conntrack_l4proto *l4proto;
struct nfattr *nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);
struct nf_conntrack_tuple m;
struct nfattr *nest_parms;

memset(&m, 0xFF, sizeof(m));
m.src.u.all = mask->src.u.all;
memcpy(&m.src.u3, &mask->src.u3, sizeof(m.src.u3));

nest_parms = NFA_NEST(skb, CTA_EXPECT_MASK);

l3proto = nf_ct_l3proto_find_get(tuple->src.l3num);
ret = ctnetlink_dump_tuples_ip(skb, mask, l3proto);
ret = ctnetlink_dump_tuples_ip(skb, &m, l3proto);
nf_ct_l3proto_put(l3proto);

if (unlikely(ret < 0))
goto nfattr_failure;

l4proto = nf_ct_l4proto_find_get(tuple->src.l3num, tuple->dst.protonum);
ret = ctnetlink_dump_tuples_proto(skb, mask, l4proto);
ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
nf_ct_l4proto_put(l4proto);
if (unlikely(ret < 0))
goto nfattr_failure;
Expand Down Expand Up @@ -1447,7 +1454,8 @@ ctnetlink_create_expect(struct nfattr *cda[], u_int8_t u3)
exp->master = ct;
exp->helper = NULL;
memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
memcpy(&exp->mask, &mask, sizeof(struct nf_conntrack_tuple));
memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
exp->mask.src.u.all = mask.src.u.all;

err = nf_ct_expect_related(exp);
nf_ct_expect_put(exp);
Expand Down
3 changes: 0 additions & 3 deletions net/netfilter/nf_conntrack_pptp.c
Original file line number Diff line number Diff line change
Expand Up @@ -585,9 +585,6 @@ static struct nf_conntrack_helper pptp __read_mostly = {
.tuple.src.l3num = AF_INET,
.tuple.src.u.tcp.port = __constant_htons(PPTP_CONTROL_PORT),
.tuple.dst.protonum = IPPROTO_TCP,
.mask.src.l3num = 0xffff,
.mask.src.u.tcp.port = __constant_htons(0xffff),
.mask.dst.protonum = 0xff,
.help = conntrack_pptp_help,
.destroy = pptp_destroy_siblings,
};
Expand Down
2 changes: 0 additions & 2 deletions net/netfilter/nf_conntrack_sane.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,8 +206,6 @@ static int __init nf_conntrack_sane_init(void)
for (j = 0; j < 2; j++) {
sane[i][j].tuple.src.u.tcp.port = htons(ports[i]);
sane[i][j].tuple.dst.protonum = IPPROTO_TCP;
sane[i][j].mask.src.u.tcp.port = 0xFFFF;
sane[i][j].mask.dst.protonum = 0xFF;
sane[i][j].max_expected = 1;
sane[i][j].timeout = 5 * 60; /* 5 Minutes */
sane[i][j].me = THIS_MODULE;
Expand Down
Loading

0 comments on commit d4156e8

Please sign in to comment.