Skip to content

Commit

Permalink
netfilter: conntrack: remove l3->l4 mapping information
Browse files Browse the repository at this point in the history
l4 protocols are demuxed by l3num, l4num pair.

However, almost all l4 trackers are l3 agnostic.

Only exceptions are:
 - gre, icmp (ipv4 only)
 - icmpv6 (ipv6 only)

This commit gets rid of the l3 mapping, l4 trackers can now be looked up
by their IPPROTO_XXX value alone, which gets rid of the additional l3
indirection.

For icmp, ipcmp6 and gre, add a check on state->pf and
return -NF_ACCEPT in case we're asked to track e.g. icmpv6-in-ipv4,
this seems more fitting than using the generic tracker.

Additionally we can kill the 2nd l4proto definitions that were needed
for v4/v6 split -- they are now the same so we can use single l4proto
struct for each protocol, rather than two.

The EXPORT_SYMBOLs can be removed as all these object files are
part of nf_conntrack with no external references.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  • Loading branch information
Florian Westphal authored and Pablo Neira Ayuso committed Sep 20, 2018
1 parent ca2ca6e commit dd2934a
Show file tree
Hide file tree
Showing 20 changed files with 76 additions and 301 deletions.
13 changes: 5 additions & 8 deletions include/net/netfilter/ipv4/nf_conntrack_ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,17 @@
#ifndef _NF_CONNTRACK_IPV4_H
#define _NF_CONNTRACK_IPV4_H

extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp4;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp4;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmp;
#ifdef CONFIG_NF_CT_PROTO_DCCP
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp4;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp;
#endif
#ifdef CONFIG_NF_CT_PROTO_SCTP
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp4;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp;
#endif
#ifdef CONFIG_NF_CT_PROTO_UDPLITE
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite4;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite;
#endif

int nf_conntrack_ipv4_compat_init(void);
void nf_conntrack_ipv4_compat_fini(void);

#endif /*_NF_CONNTRACK_IPV4_H*/
13 changes: 0 additions & 13 deletions include/net/netfilter/ipv6/nf_conntrack_ipv6.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,20 +2,7 @@
#ifndef _NF_CONNTRACK_IPV6_H
#define _NF_CONNTRACK_IPV6_H

extern const struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv6;

extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_tcp6;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udp6;
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_icmpv6;
#ifdef CONFIG_NF_CT_PROTO_DCCP
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_dccp6;
#endif
#ifdef CONFIG_NF_CT_PROTO_SCTP
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_sctp6;
#endif
#ifdef CONFIG_NF_CT_PROTO_UDPLITE
extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_udplite6;
#endif

#include <linux/sysctl.h>
extern struct ctl_table nf_ct_ipv6_sysctl_table[];
Expand Down
9 changes: 2 additions & 7 deletions include/net/netfilter/nf_conntrack_l4proto.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
struct seq_file;

struct nf_conntrack_l4proto {
/* L3 Protocol number. */
u_int16_t l3proto;

/* L4 Protocol number. */
u_int8_t l4proto;

Expand Down Expand Up @@ -107,11 +104,9 @@ extern const struct nf_conntrack_l4proto nf_conntrack_l4proto_generic;

#define MAX_NF_CT_PROTO 256

const struct nf_conntrack_l4proto *__nf_ct_l4proto_find(u_int16_t l3proto,
u_int8_t l4proto);
const struct nf_conntrack_l4proto *__nf_ct_l4proto_find(u8 l4proto);

const struct nf_conntrack_l4proto *nf_ct_l4proto_find_get(u_int16_t l3proto,
u_int8_t l4proto);
const struct nf_conntrack_l4proto *nf_ct_l4proto_find_get(u8 l4proto);
void nf_ct_l4proto_put(const struct nf_conntrack_l4proto *p);

/* Protocol pernet registration. */
Expand Down
15 changes: 7 additions & 8 deletions net/netfilter/nf_conntrack_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -379,7 +379,7 @@ bool nf_ct_get_tuplepr(const struct sk_buff *skb, unsigned int nhoff,
return false;
}

l4proto = __nf_ct_l4proto_find(l3num, protonum);
l4proto = __nf_ct_l4proto_find(protonum);

ret = nf_ct_get_tuple(skb, nhoff, protoff, l3num, protonum, net, tuple,
l4proto);
Expand Down Expand Up @@ -539,7 +539,7 @@ destroy_conntrack(struct nf_conntrack *nfct)
nf_ct_tmpl_free(ct);
return;
}
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
l4proto = __nf_ct_l4proto_find(nf_ct_protonum(ct));
if (l4proto->destroy)
l4proto->destroy(ct);

Expand Down Expand Up @@ -840,7 +840,7 @@ static int nf_ct_resolve_clash(struct net *net, struct sk_buff *skb,
enum ip_conntrack_info oldinfo;
struct nf_conn *loser_ct = nf_ct_get(skb, &oldinfo);

l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
l4proto = __nf_ct_l4proto_find(nf_ct_protonum(ct));
if (l4proto->allow_clash &&
!nf_ct_is_dying(ct) &&
atomic_inc_not_zero(&ct->ct_general.use)) {
Expand Down Expand Up @@ -1109,7 +1109,7 @@ static bool gc_worker_can_early_drop(const struct nf_conn *ct)
if (!test_bit(IPS_ASSURED_BIT, &ct->status))
return true;

l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
l4proto = __nf_ct_l4proto_find(nf_ct_protonum(ct));
if (l4proto->can_early_drop && l4proto->can_early_drop(ct))
return true;

Expand Down Expand Up @@ -1549,7 +1549,7 @@ nf_conntrack_in(struct sk_buff *skb, const struct nf_hook_state *state)
goto out;
}

l4proto = __nf_ct_l4proto_find(state->pf, protonum);
l4proto = __nf_ct_l4proto_find(protonum);

if (protonum == IPPROTO_ICMP || protonum == IPPROTO_ICMPV6) {
ret = nf_conntrack_handle_icmp(tmpl, skb, dataoff,
Expand Down Expand Up @@ -1618,8 +1618,7 @@ bool nf_ct_invert_tuplepr(struct nf_conntrack_tuple *inverse,

rcu_read_lock();
ret = nf_ct_invert_tuple(inverse, orig,
__nf_ct_l4proto_find(orig->src.l3num,
orig->dst.protonum));
__nf_ct_l4proto_find(orig->dst.protonum));
rcu_read_unlock();
return ret;
}
Expand Down Expand Up @@ -1776,7 +1775,7 @@ static int nf_conntrack_update(struct net *net, struct sk_buff *skb)
if (dataoff <= 0)
return -1;

l4proto = nf_ct_l4proto_find_get(l3num, l4num);
l4proto = nf_ct_l4proto_find_get(l4num);

if (!nf_ct_get_tuple(skb, skb_network_offset(skb), dataoff, l3num,
l4num, net, &tuple, l4proto))
Expand Down
3 changes: 1 addition & 2 deletions net/netfilter/nf_conntrack_expect.c
Original file line number Diff line number Diff line change
Expand Up @@ -610,8 +610,7 @@ static int exp_seq_show(struct seq_file *s, void *v)
expect->tuple.src.l3num,
expect->tuple.dst.protonum);
print_tuple(s, &expect->tuple,
__nf_ct_l4proto_find(expect->tuple.src.l3num,
expect->tuple.dst.protonum));
__nf_ct_l4proto_find(expect->tuple.dst.protonum));

if (expect->flags & NF_CT_EXPECT_PERMANENT) {
seq_puts(s, "PERMANENT");
Expand Down
14 changes: 6 additions & 8 deletions net/netfilter/nf_conntrack_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,8 +135,7 @@ static int ctnetlink_dump_tuples(struct sk_buff *skb,
ret = ctnetlink_dump_tuples_ip(skb, tuple);

if (ret >= 0) {
l4proto = __nf_ct_l4proto_find(tuple->src.l3num,
tuple->dst.protonum);
l4proto = __nf_ct_l4proto_find(tuple->dst.protonum);
ret = ctnetlink_dump_tuples_proto(skb, tuple, l4proto);
}
rcu_read_unlock();
Expand Down Expand Up @@ -184,7 +183,7 @@ static int ctnetlink_dump_protoinfo(struct sk_buff *skb, struct nf_conn *ct)
struct nlattr *nest_proto;
int ret;

l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
l4proto = __nf_ct_l4proto_find(nf_ct_protonum(ct));
if (!l4proto->to_nlattr)
return 0;

Expand Down Expand Up @@ -592,7 +591,7 @@ static size_t ctnetlink_proto_size(const struct nf_conn *ct)
len = nla_policy_len(cta_ip_nla_policy, CTA_IP_MAX + 1);
len *= 3u; /* ORIG, REPLY, MASTER */

l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
l4proto = __nf_ct_l4proto_find(nf_ct_protonum(ct));
len += l4proto->nlattr_size;
if (l4proto->nlattr_tuple_size) {
len4 = l4proto->nlattr_tuple_size();
Expand Down Expand Up @@ -1054,7 +1053,7 @@ static int ctnetlink_parse_tuple_proto(struct nlattr *attr,
tuple->dst.protonum = nla_get_u8(tb[CTA_PROTO_NUM]);

rcu_read_lock();
l4proto = __nf_ct_l4proto_find(tuple->src.l3num, tuple->dst.protonum);
l4proto = __nf_ct_l4proto_find(tuple->dst.protonum);

if (likely(l4proto->nlattr_to_tuple)) {
ret = nla_validate_nested(attr, CTA_PROTO_MAX,
Expand Down Expand Up @@ -1702,7 +1701,7 @@ static int ctnetlink_change_protoinfo(struct nf_conn *ct,
return err;

rcu_read_lock();
l4proto = __nf_ct_l4proto_find(nf_ct_l3num(ct), nf_ct_protonum(ct));
l4proto = __nf_ct_l4proto_find(nf_ct_protonum(ct));
if (l4proto->from_nlattr)
err = l4proto->from_nlattr(tb, ct);
rcu_read_unlock();
Expand Down Expand Up @@ -2662,8 +2661,7 @@ static int ctnetlink_exp_dump_mask(struct sk_buff *skb,
rcu_read_lock();
ret = ctnetlink_dump_tuples_ip(skb, &m);
if (ret >= 0) {
l4proto = __nf_ct_l4proto_find(tuple->src.l3num,
tuple->dst.protonum);
l4proto = __nf_ct_l4proto_find(tuple->dst.protonum);
ret = ctnetlink_dump_tuples_proto(skb, &m, l4proto);
}
rcu_read_unlock();
Expand Down
Loading

0 comments on commit dd2934a

Please sign in to comment.