Skip to content

Commit 01e6de6

Browse files
committed
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
2 parents 8f1ead2 + d271e8b commit 01e6de6

33 files changed

+416
-210
lines changed

include/linux/netfilter/x_tables.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -437,6 +437,29 @@ extern void xt_free_table_info(struct xt_table_info *info);
437437
extern void xt_table_entry_swap_rcu(struct xt_table_info *old,
438438
struct xt_table_info *new);
439439

440+
/*
441+
* This helper is performance critical and must be inlined
442+
*/
443+
static inline unsigned long ifname_compare_aligned(const char *_a,
444+
const char *_b,
445+
const char *_mask)
446+
{
447+
const unsigned long *a = (const unsigned long *)_a;
448+
const unsigned long *b = (const unsigned long *)_b;
449+
const unsigned long *mask = (const unsigned long *)_mask;
450+
unsigned long ret;
451+
452+
ret = (a[0] ^ b[0]) & mask[0];
453+
if (IFNAMSIZ > sizeof(unsigned long))
454+
ret |= (a[1] ^ b[1]) & mask[1];
455+
if (IFNAMSIZ > 2 * sizeof(unsigned long))
456+
ret |= (a[2] ^ b[2]) & mask[2];
457+
if (IFNAMSIZ > 3 * sizeof(unsigned long))
458+
ret |= (a[3] ^ b[3]) & mask[3];
459+
BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
460+
return ret;
461+
}
462+
440463
#ifdef CONFIG_COMPAT
441464
#include <net/compat.h>
442465

include/net/netfilter/nf_conntrack.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,8 +91,7 @@ struct nf_conn_help {
9191
#include <net/netfilter/ipv4/nf_conntrack_ipv4.h>
9292
#include <net/netfilter/ipv6/nf_conntrack_ipv6.h>
9393

94-
struct nf_conn
95-
{
94+
struct nf_conn {
9695
/* Usage count in here is 1 for hash table/destruct timer, 1 per skb,
9796
plus 1 for any connection(s) we are `master' for */
9897
struct nf_conntrack ct_general;
@@ -126,7 +125,6 @@ struct nf_conn
126125
#ifdef CONFIG_NET_NS
127126
struct net *ct_net;
128127
#endif
129-
struct rcu_head rcu;
130128
};
131129

132130
static inline struct nf_conn *
@@ -190,9 +188,13 @@ static inline void nf_ct_put(struct nf_conn *ct)
190188
extern int nf_ct_l3proto_try_module_get(unsigned short l3proto);
191189
extern void nf_ct_l3proto_module_put(unsigned short l3proto);
192190

193-
extern struct hlist_head *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced);
194-
extern void nf_ct_free_hashtable(struct hlist_head *hash, int vmalloced,
195-
unsigned int size);
191+
/*
192+
* Allocate a hashtable of hlist_head (if nulls == 0),
193+
* or hlist_nulls_head (if nulls == 1)
194+
*/
195+
extern void *nf_ct_alloc_hashtable(unsigned int *sizep, int *vmalloced, int nulls);
196+
197+
extern void nf_ct_free_hashtable(void *hash, int vmalloced, unsigned int size);
196198

197199
extern struct nf_conntrack_tuple_hash *
198200
__nf_conntrack_find(struct net *net, const struct nf_conntrack_tuple *tuple);

include/net/netfilter/nf_conntrack_helper.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414

1515
struct module;
1616

17+
#define NF_CT_HELPER_NAME_LEN 16
18+
1719
struct nf_conntrack_helper
1820
{
1921
struct hlist_node hnode; /* Internal use. */

include/net/netfilter/nf_conntrack_l3proto.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,17 @@ struct nf_conntrack_l3proto
5353
int (*tuple_to_nlattr)(struct sk_buff *skb,
5454
const struct nf_conntrack_tuple *t);
5555

56+
/*
57+
* Calculate size of tuple nlattr
58+
*/
59+
int (*nlattr_tuple_size)(void);
60+
5661
int (*nlattr_to_tuple)(struct nlattr *tb[],
5762
struct nf_conntrack_tuple *t);
5863
const struct nla_policy *nla_policy;
5964

65+
size_t nla_size;
66+
6067
#ifdef CONFIG_SYSCTL
6168
struct ctl_table_header *ctl_table_header;
6269
struct ctl_path *ctl_table_path;

include/net/netfilter/nf_conntrack_l4proto.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,22 @@ struct nf_conntrack_l4proto
6464
/* convert protoinfo to nfnetink attributes */
6565
int (*to_nlattr)(struct sk_buff *skb, struct nlattr *nla,
6666
const struct nf_conn *ct);
67+
/* Calculate protoinfo nlattr size */
68+
int (*nlattr_size)(void);
6769

6870
/* convert nfnetlink attributes to protoinfo */
6971
int (*from_nlattr)(struct nlattr *tb[], struct nf_conn *ct);
7072

7173
int (*tuple_to_nlattr)(struct sk_buff *skb,
7274
const struct nf_conntrack_tuple *t);
75+
/* Calculate tuple nlattr size */
76+
int (*nlattr_tuple_size)(void);
7377
int (*nlattr_to_tuple)(struct nlattr *tb[],
7478
struct nf_conntrack_tuple *t);
7579
const struct nla_policy *nla_policy;
7680

81+
size_t nla_size;
82+
7783
#ifdef CONFIG_SYSCTL
7884
struct ctl_table_header **ctl_table_header;
7985
struct ctl_table *ctl_table;
@@ -107,6 +113,7 @@ extern int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb,
107113
const struct nf_conntrack_tuple *tuple);
108114
extern int nf_ct_port_nlattr_to_tuple(struct nlattr *tb[],
109115
struct nf_conntrack_tuple *t);
116+
extern int nf_ct_port_nlattr_tuple_size(void);
110117
extern const struct nla_policy nf_ct_port_nla_policy[];
111118

112119
#ifdef CONFIG_SYSCTL

include/net/netfilter/nf_conntrack_tuple.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
#include <linux/netfilter/x_tables.h>
1414
#include <linux/netfilter/nf_conntrack_tuple_common.h>
15+
#include <linux/list_nulls.h>
1516

1617
/* A `tuple' is a structure containing the information to uniquely
1718
identify a connection. ie. if two packets have the same tuple, they
@@ -146,9 +147,8 @@ static inline void nf_ct_dump_tuple(const struct nf_conntrack_tuple *t)
146147
((enum ip_conntrack_dir)(h)->tuple.dst.dir)
147148

148149
/* Connections have two entries in the hash table: one for each way */
149-
struct nf_conntrack_tuple_hash
150-
{
151-
struct hlist_node hnode;
150+
struct nf_conntrack_tuple_hash {
151+
struct hlist_nulls_node hnnode;
152152
struct nf_conntrack_tuple tuple;
153153
};
154154

include/net/netlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ extern int nla_validate(struct nlattr *head, int len, int maxtype,
230230
extern int nla_parse(struct nlattr *tb[], int maxtype,
231231
struct nlattr *head, int len,
232232
const struct nla_policy *policy);
233+
extern int nla_policy_len(const struct nla_policy *, int);
233234
extern struct nlattr * nla_find(struct nlattr *head, int len, int attrtype);
234235
extern size_t nla_strlcpy(char *dst, const struct nlattr *nla,
235236
size_t dstsize);

include/net/netns/conntrack.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define __NETNS_CONNTRACK_H
33

44
#include <linux/list.h>
5+
#include <linux/list_nulls.h>
56
#include <asm/atomic.h>
67

78
struct ctl_table_header;
@@ -10,9 +11,9 @@ struct nf_conntrack_ecache;
1011
struct netns_ct {
1112
atomic_t count;
1213
unsigned int expect_count;
13-
struct hlist_head *hash;
14+
struct hlist_nulls_head *hash;
1415
struct hlist_head *expect_hash;
15-
struct hlist_head unconfirmed;
16+
struct hlist_nulls_head unconfirmed;
1617
struct ip_conntrack_stat *stat;
1718
#ifdef CONFIG_NF_CONNTRACK_EVENTS
1819
struct nf_conntrack_ecache *ecache;

lib/nlattr.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,32 @@ int nla_validate(struct nlattr *head, int len, int maxtype,
132132
return err;
133133
}
134134

135+
/**
136+
* nla_policy_len - Determin the max. length of a policy
137+
* @policy: policy to use
138+
* @n: number of policies
139+
*
140+
* Determines the max. length of the policy. It is currently used
141+
* to allocated Netlink buffers roughly the size of the actual
142+
* message.
143+
*
144+
* Returns 0 on success or a negative error code.
145+
*/
146+
int
147+
nla_policy_len(const struct nla_policy *p, int n)
148+
{
149+
int i, len = 0;
150+
151+
for (i = 0; i < n; i++) {
152+
if (p->len)
153+
len += nla_total_size(p->len);
154+
else if (nla_attr_minlen[p->type])
155+
len += nla_total_size(nla_attr_minlen[p->type]);
156+
}
157+
158+
return len;
159+
}
160+
135161
/**
136162
* nla_parse - Parse a stream of attributes into a tb buffer
137163
* @tb: destination array with maxtype+1 elements
@@ -467,6 +493,7 @@ EXPORT_SYMBOL(nla_append);
467493
#endif
468494

469495
EXPORT_SYMBOL(nla_validate);
496+
EXPORT_SYMBOL(nla_policy_len);
470497
EXPORT_SYMBOL(nla_parse);
471498
EXPORT_SYMBOL(nla_find);
472499
EXPORT_SYMBOL(nla_strlcpy);

net/ipv4/netfilter/arp_tables.c

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -81,19 +81,7 @@ static inline int arp_devaddr_compare(const struct arpt_devaddr_info *ap,
8181
static unsigned long ifname_compare(const char *_a, const char *_b, const char *_mask)
8282
{
8383
#ifdef CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS
84-
const unsigned long *a = (const unsigned long *)_a;
85-
const unsigned long *b = (const unsigned long *)_b;
86-
const unsigned long *mask = (const unsigned long *)_mask;
87-
unsigned long ret;
88-
89-
ret = (a[0] ^ b[0]) & mask[0];
90-
if (IFNAMSIZ > sizeof(unsigned long))
91-
ret |= (a[1] ^ b[1]) & mask[1];
92-
if (IFNAMSIZ > 2 * sizeof(unsigned long))
93-
ret |= (a[2] ^ b[2]) & mask[2];
94-
if (IFNAMSIZ > 3 * sizeof(unsigned long))
95-
ret |= (a[3] ^ b[3]) & mask[3];
96-
BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
84+
unsigned long ret = ifname_compare_aligned(_a, _b, _mask);
9785
#else
9886
unsigned long ret = 0;
9987
const u16 *a = (const u16 *)_a;
@@ -404,7 +392,9 @@ static int mark_source_chains(struct xt_table_info *newinfo,
404392
&& unconditional(&e->arp)) || visited) {
405393
unsigned int oldpos, size;
406394

407-
if (t->verdict < -NF_MAX_VERDICT - 1) {
395+
if ((strcmp(t->target.u.user.name,
396+
ARPT_STANDARD_TARGET) == 0) &&
397+
t->verdict < -NF_MAX_VERDICT - 1) {
408398
duprintf("mark_source_chains: bad "
409399
"negative verdict (%i)\n",
410400
t->verdict);

net/ipv4/netfilter/ip_tables.c

Lines changed: 5 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -74,25 +74,6 @@ do { \
7474
7575
Hence the start of any table is given by get_table() below. */
7676

77-
static unsigned long ifname_compare(const char *_a, const char *_b,
78-
const unsigned char *_mask)
79-
{
80-
const unsigned long *a = (const unsigned long *)_a;
81-
const unsigned long *b = (const unsigned long *)_b;
82-
const unsigned long *mask = (const unsigned long *)_mask;
83-
unsigned long ret;
84-
85-
ret = (a[0] ^ b[0]) & mask[0];
86-
if (IFNAMSIZ > sizeof(unsigned long))
87-
ret |= (a[1] ^ b[1]) & mask[1];
88-
if (IFNAMSIZ > 2 * sizeof(unsigned long))
89-
ret |= (a[2] ^ b[2]) & mask[2];
90-
if (IFNAMSIZ > 3 * sizeof(unsigned long))
91-
ret |= (a[3] ^ b[3]) & mask[3];
92-
BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
93-
return ret;
94-
}
95-
9677
/* Returns whether matches rule or not. */
9778
/* Performance critical - called for every packet */
9879
static inline bool
@@ -121,7 +102,7 @@ ip_packet_match(const struct iphdr *ip,
121102
return false;
122103
}
123104

124-
ret = ifname_compare(indev, ipinfo->iniface, ipinfo->iniface_mask);
105+
ret = ifname_compare_aligned(indev, ipinfo->iniface, ipinfo->iniface_mask);
125106

126107
if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
127108
dprintf("VIA in mismatch (%s vs %s).%s\n",
@@ -130,7 +111,7 @@ ip_packet_match(const struct iphdr *ip,
130111
return false;
131112
}
132113

133-
ret = ifname_compare(outdev, ipinfo->outiface, ipinfo->outiface_mask);
114+
ret = ifname_compare_aligned(outdev, ipinfo->outiface, ipinfo->outiface_mask);
134115

135116
if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
136117
dprintf("VIA out mismatch (%s vs %s).%s\n",
@@ -507,7 +488,9 @@ mark_source_chains(struct xt_table_info *newinfo,
507488
&& unconditional(&e->ip)) || visited) {
508489
unsigned int oldpos, size;
509490

510-
if (t->verdict < -NF_MAX_VERDICT - 1) {
491+
if ((strcmp(t->target.u.user.name,
492+
IPT_STANDARD_TARGET) == 0) &&
493+
t->verdict < -NF_MAX_VERDICT - 1) {
511494
duprintf("mark_source_chains: bad "
512495
"negative verdict (%i)\n",
513496
t->verdict);

net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,11 @@ static int ipv4_nlattr_to_tuple(struct nlattr *tb[],
328328

329329
return 0;
330330
}
331+
332+
static int ipv4_nlattr_tuple_size(void)
333+
{
334+
return nla_policy_len(ipv4_nla_policy, CTA_IP_MAX + 1);
335+
}
331336
#endif
332337

333338
static struct nf_sockopt_ops so_getorigdst = {
@@ -347,6 +352,7 @@ struct nf_conntrack_l3proto nf_conntrack_l3proto_ipv4 __read_mostly = {
347352
.get_l4proto = ipv4_get_l4proto,
348353
#if defined(CONFIG_NF_CT_NETLINK) || defined(CONFIG_NF_CT_NETLINK_MODULE)
349354
.tuple_to_nlattr = ipv4_tuple_to_nlattr,
355+
.nlattr_tuple_size = ipv4_nlattr_tuple_size,
350356
.nlattr_to_tuple = ipv4_nlattr_to_tuple,
351357
.nla_policy = ipv4_nla_policy,
352358
#endif

0 commit comments

Comments
 (0)