diff options
| author | Patrick McHardy <kaber@coreworks.de> | 2004-09-23 00:42:59 -0700 |
|---|---|---|
| committer | David S. Miller <davem@kernel.bkbits.net> | 2004-09-23 00:42:59 -0700 |
| commit | 549499a746f144fc71a1d60adae2a65f24e261b6 (patch) | |
| tree | 5b49fd8721214137430123f121f43842b4383964 /net | |
| parent | c1041076b7abe2674f2de9dd0a46ad405eb3eb51 (diff) | |
[NETFILTER]: Keep conntrack/nat protocols in array instead of linked list
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/ipv4/netfilter/ip_conntrack_core.c | 41 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_conntrack_proto_sctp.c | 1 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_conntrack_standalone.c | 25 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_core.c | 39 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_proto_icmp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_proto_tcp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_proto_udp.c | 2 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_proto_unknown.c | 4 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_standalone.c | 15 |
9 files changed, 35 insertions, 96 deletions
diff --git a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c index d38a00225095..a5ce8ad2229e 100644 --- a/net/ipv4/netfilter/ip_conntrack_core.c +++ b/net/ipv4/netfilter/ip_conntrack_core.c @@ -66,7 +66,7 @@ EXPORT_SYMBOL(ip_conntrack_count); void (*ip_conntrack_destroyed)(struct ip_conntrack *conntrack) = NULL; LIST_HEAD(ip_conntrack_expect_list); -LIST_HEAD(protocol_list); +struct ip_conntrack_protocol *ip_ct_protos[MAX_IP_CT_PROTO]; static LIST_HEAD(helpers); unsigned int ip_conntrack_htable_size = 0; int ip_conntrack_max; @@ -77,37 +77,6 @@ struct ip_conntrack ip_conntrack_untracked; DEFINE_PER_CPU(struct ip_conntrack_stat, ip_conntrack_stat); -extern struct ip_conntrack_protocol ip_conntrack_generic_protocol; - -static inline int proto_cmpfn(const struct ip_conntrack_protocol *curr, - u_int8_t protocol) -{ - return protocol == curr->proto; -} - -struct ip_conntrack_protocol *__ip_ct_find_proto(u_int8_t protocol) -{ - struct ip_conntrack_protocol *p; - - MUST_BE_READ_LOCKED(&ip_conntrack_lock); - p = LIST_FIND(&protocol_list, proto_cmpfn, - struct ip_conntrack_protocol *, protocol); - if (!p) - p = &ip_conntrack_generic_protocol; - - return p; -} - -struct ip_conntrack_protocol *ip_ct_find_proto(u_int8_t protocol) -{ - struct ip_conntrack_protocol *p; - - READ_LOCK(&ip_conntrack_lock); - p = __ip_ct_find_proto(protocol); - READ_UNLOCK(&ip_conntrack_lock); - return p; -} - inline void ip_conntrack_put(struct ip_conntrack *ct) { @@ -1397,10 +1366,12 @@ int __init ip_conntrack_init(void) /* Don't NEED lock here, but good form anyway. */ WRITE_LOCK(&ip_conntrack_lock); + for (i = 0; i < MAX_IP_CT_PROTO; i++) + ip_ct_protos[i] = &ip_conntrack_generic_protocol; /* Sew in builtin protocols. */ - list_append(&protocol_list, &ip_conntrack_protocol_tcp); - list_append(&protocol_list, &ip_conntrack_protocol_udp); - list_append(&protocol_list, &ip_conntrack_protocol_icmp); + ip_ct_protos[IPPROTO_TCP] = &ip_conntrack_protocol_tcp; + ip_ct_protos[IPPROTO_UDP] = &ip_conntrack_protocol_udp; + ip_ct_protos[IPPROTO_ICMP] = &ip_conntrack_protocol_icmp; WRITE_UNLOCK(&ip_conntrack_lock); for (i = 0; i < ip_conntrack_htable_size; i++) diff --git a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c index 638809386107..3105e2b0149b 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_sctp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_sctp.c @@ -496,7 +496,6 @@ static int sctp_exp_matches_pkt(struct ip_conntrack_expect *exp, } struct ip_conntrack_protocol ip_conntrack_protocol_sctp = { - .list = { NULL, NULL }, .proto = IPPROTO_SCTP, .name = "sctp", .pkt_to_tuple = sctp_pkt_to_tuple, diff --git a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c index 195f7b2662e9..c9ef4ce7a04e 100644 --- a/net/ipv4/netfilter/ip_conntrack_standalone.c +++ b/net/ipv4/netfilter/ip_conntrack_standalone.c @@ -112,7 +112,7 @@ static int ct_seq_real_show(const struct ip_conntrack_tuple_hash *hash, if (DIRECTION(hash)) return 0; - proto = __ip_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] + proto = ip_ct_find_proto(conntrack->tuplehash[IP_CT_DIR_ORIGINAL] .tuple.dst.protonum); IP_NF_ASSERT(proto); @@ -242,7 +242,7 @@ static int exp_seq_show(struct seq_file *s, void *v) expect->tuple.dst.protonum); print_tuple(s, &expect->tuple, - __ip_ct_find_proto(expect->tuple.dst.protonum)); + ip_ct_find_proto(expect->tuple.dst.protonum)); return seq_putc(s, '\n'); } @@ -824,19 +824,13 @@ cleanup_proc_exp: int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) { int ret = 0; - struct list_head *i; WRITE_LOCK(&ip_conntrack_lock); - list_for_each(i, &protocol_list) { - if (((struct ip_conntrack_protocol *)i)->proto - == proto->proto) { - ret = -EBUSY; - goto out; - } + if (ip_ct_protos[proto->proto] != &ip_conntrack_generic_protocol) { + ret = -EBUSY; + goto out; } - - list_prepend(&protocol_list, proto); - + ip_ct_protos[proto->proto] = proto; out: WRITE_UNLOCK(&ip_conntrack_lock); return ret; @@ -845,10 +839,7 @@ int ip_conntrack_protocol_register(struct ip_conntrack_protocol *proto) void ip_conntrack_protocol_unregister(struct ip_conntrack_protocol *proto) { WRITE_LOCK(&ip_conntrack_lock); - - /* ip_ct_find_proto() returns proto_generic in case there is no protocol - * helper. So this should be enough - HW */ - LIST_DELETE(&protocol_list, proto); + ip_ct_protos[proto->proto] = &ip_conntrack_generic_protocol; WRITE_UNLOCK(&ip_conntrack_lock); /* Somebody could be still looking at the proto in bh. */ @@ -888,8 +879,8 @@ EXPORT_SYMBOL(ip_conntrack_helper_register); EXPORT_SYMBOL(ip_conntrack_helper_unregister); EXPORT_SYMBOL(ip_ct_selective_cleanup); EXPORT_SYMBOL(ip_ct_refresh_acct); +EXPORT_SYMBOL(ip_ct_protos); EXPORT_SYMBOL(ip_ct_find_proto); -EXPORT_SYMBOL(__ip_ct_find_proto); EXPORT_SYMBOL(ip_ct_find_helper); EXPORT_SYMBOL(ip_conntrack_expect_alloc); EXPORT_SYMBOL(ip_conntrack_expect_related); diff --git a/net/ipv4/netfilter/ip_nat_core.c b/net/ipv4/netfilter/ip_nat_core.c index d47a837990c4..49595abe2609 100644 --- a/net/ipv4/netfilter/ip_nat_core.c +++ b/net/ipv4/netfilter/ip_nat_core.c @@ -48,9 +48,8 @@ static unsigned int ip_nat_htable_size; static struct list_head *bysource; static struct list_head *byipsproto; -LIST_HEAD(protos); +struct ip_nat_protocol *ip_nat_protos[MAX_IP_NAT_PROTO]; -extern struct ip_nat_protocol unknown_nat_protocol; /* We keep extra hashes for each conntrack, for fast searching. */ static inline size_t @@ -103,23 +102,6 @@ ip_nat_cheat_check(u_int32_t oldvalinv, u_int32_t newval, u_int16_t oldcheck) oldcheck^0xFFFF)); } -static inline int cmp_proto(const struct ip_nat_protocol *i, int proto) -{ - return i->protonum == proto; -} - -struct ip_nat_protocol * -find_nat_proto(u_int16_t protonum) -{ - struct ip_nat_protocol *i; - - MUST_BE_READ_LOCKED(&ip_nat_lock); - i = LIST_FIND(&protos, cmp_proto, struct ip_nat_protocol *, protonum); - if (!i) - i = &unknown_nat_protocol; - return i; -} - /* Is this tuple already taken? (not by us) */ int ip_nat_used_tuple(const struct ip_conntrack_tuple *tuple, @@ -142,7 +124,7 @@ in_range(const struct ip_conntrack_tuple *tuple, const struct ip_conntrack_manip *manip, const struct ip_nat_multi_range *mr) { - struct ip_nat_protocol *proto = find_nat_proto(tuple->dst.protonum); + struct ip_nat_protocol *proto = ip_nat_find_proto(tuple->dst.protonum); unsigned int i; struct ip_conntrack_tuple newtuple = { *manip, tuple->dst }; @@ -394,7 +376,7 @@ get_unique_tuple(struct ip_conntrack_tuple *tuple, unsigned int hooknum) { struct ip_nat_protocol *proto - = find_nat_proto(orig_tuple->dst.protonum); + = ip_nat_find_proto(orig_tuple->dst.protonum); struct ip_nat_range *rptr; unsigned int i; int ret; @@ -705,9 +687,8 @@ manip_pkt(u_int16_t proto, iph = (void *)(*pskb)->data + iphdroff; /* Manipulate protcol part. */ - if (!find_nat_proto(proto)->manip_pkt(pskb, - iphdroff + iph->ihl*4, - manip, maniptype)) + if (!ip_nat_find_proto(proto)->manip_pkt(pskb, iphdroff + iph->ihl*4, + manip, maniptype)) return 0; iph = (void *)(*pskb)->data + iphdroff; @@ -731,7 +712,7 @@ static inline int exp_for_packet(struct ip_conntrack_expect *exp, int ret = 1; MUST_BE_READ_LOCKED(&ip_conntrack_lock); - proto = __ip_ct_find_proto(skb->nh.iph->protocol); + proto = ip_ct_find_proto(skb->nh.iph->protocol); if (proto->exp_matches_pkt) ret = proto->exp_matches_pkt(exp, skb); @@ -976,9 +957,11 @@ int __init ip_nat_init(void) /* Sew in builtin protocols. */ WRITE_LOCK(&ip_nat_lock); - list_append(&protos, &ip_nat_protocol_tcp); - list_append(&protos, &ip_nat_protocol_udp); - list_append(&protos, &ip_nat_protocol_icmp); + for (i = 0; i < MAX_IP_NAT_PROTO; i++) + ip_nat_protos[i] = &ip_nat_unknown_protocol; + ip_nat_protos[IPPROTO_TCP] = &ip_nat_protocol_tcp; + ip_nat_protos[IPPROTO_UDP] = &ip_nat_protocol_udp; + ip_nat_protos[IPPROTO_ICMP] = &ip_nat_protocol_icmp; WRITE_UNLOCK(&ip_nat_lock); for (i = 0; i < ip_nat_htable_size; i++) { diff --git a/net/ipv4/netfilter/ip_nat_proto_icmp.c b/net/ipv4/netfilter/ip_nat_proto_icmp.c index f7d31f850d79..6fb50dee520c 100644 --- a/net/ipv4/netfilter/ip_nat_proto_icmp.c +++ b/net/ipv4/netfilter/ip_nat_proto_icmp.c @@ -104,7 +104,7 @@ icmp_print_range(char *buffer, const struct ip_nat_range *range) } struct ip_nat_protocol ip_nat_protocol_icmp -= { { NULL, NULL }, "ICMP", IPPROTO_ICMP, += { "ICMP", IPPROTO_ICMP, icmp_manip_pkt, icmp_in_range, icmp_unique_tuple, diff --git a/net/ipv4/netfilter/ip_nat_proto_tcp.c b/net/ipv4/netfilter/ip_nat_proto_tcp.c index 731a12d08819..197bd01e2166 100644 --- a/net/ipv4/netfilter/ip_nat_proto_tcp.c +++ b/net/ipv4/netfilter/ip_nat_proto_tcp.c @@ -162,7 +162,7 @@ tcp_print_range(char *buffer, const struct ip_nat_range *range) } struct ip_nat_protocol ip_nat_protocol_tcp -= { { NULL, NULL }, "TCP", IPPROTO_TCP, += { "TCP", IPPROTO_TCP, tcp_manip_pkt, tcp_in_range, tcp_unique_tuple, diff --git a/net/ipv4/netfilter/ip_nat_proto_udp.c b/net/ipv4/netfilter/ip_nat_proto_udp.c index 293846556910..240004eede81 100644 --- a/net/ipv4/netfilter/ip_nat_proto_udp.c +++ b/net/ipv4/netfilter/ip_nat_proto_udp.c @@ -148,7 +148,7 @@ udp_print_range(char *buffer, const struct ip_nat_range *range) } struct ip_nat_protocol ip_nat_protocol_udp -= { { NULL, NULL }, "UDP", IPPROTO_UDP, += { "UDP", IPPROTO_UDP, udp_manip_pkt, udp_in_range, udp_unique_tuple, diff --git a/net/ipv4/netfilter/ip_nat_proto_unknown.c b/net/ipv4/netfilter/ip_nat_proto_unknown.c index 2d42a00f0bef..b57103fa907c 100644 --- a/net/ipv4/netfilter/ip_nat_proto_unknown.c +++ b/net/ipv4/netfilter/ip_nat_proto_unknown.c @@ -60,8 +60,8 @@ unknown_print_range(char *buffer, const struct ip_nat_range *range) return 0; } -struct ip_nat_protocol unknown_nat_protocol = { - { NULL, NULL }, "unknown", 0, +struct ip_nat_protocol ip_nat_unknown_protocol = { + "unknown", 0, unknown_manip_pkt, unknown_in_range, unknown_unique_tuple, diff --git a/net/ipv4/netfilter/ip_nat_standalone.c b/net/ipv4/netfilter/ip_nat_standalone.c index fcc74c0facfe..e4e961225c5f 100644 --- a/net/ipv4/netfilter/ip_nat_standalone.c +++ b/net/ipv4/netfilter/ip_nat_standalone.c @@ -283,18 +283,13 @@ static struct nf_hook_ops ip_nat_local_in_ops = { int ip_nat_protocol_register(struct ip_nat_protocol *proto) { int ret = 0; - struct list_head *i; WRITE_LOCK(&ip_nat_lock); - list_for_each(i, &protos) { - if (((struct ip_nat_protocol *)i)->protonum - == proto->protonum) { - ret = -EBUSY; - goto out; - } + if (ip_nat_protos[proto->protonum] != &ip_nat_unknown_protocol) { + ret = -EBUSY; + goto out; } - - list_prepend(&protos, proto); + ip_nat_protos[proto->protonum] = proto; out: WRITE_UNLOCK(&ip_nat_lock); return ret; @@ -304,7 +299,7 @@ int ip_nat_protocol_register(struct ip_nat_protocol *proto) void ip_nat_protocol_unregister(struct ip_nat_protocol *proto) { WRITE_LOCK(&ip_nat_lock); - LIST_DELETE(&protos, proto); + ip_nat_protos[proto->protonum] = &ip_nat_unknown_protocol; WRITE_UNLOCK(&ip_nat_lock); /* Someone could be still looking at the proto in a bh. */ |
