Commit 54dd43a6 authored by Harald Welte's avatar Harald Welte Committed by David S. Miller

`cat msg`

parent e024ba4b
...@@ -39,6 +39,22 @@ ...@@ -39,6 +39,22 @@
(type)__i; \ (type)__i; \
}) })
/* Just like LIST_FIND but we search backwards */
#define LIST_FIND_B(head, cmpfn, type, args...) \
({ \
const struct list_head *__i = (head); \
\
ASSERT_READ_LOCK(head); \
do { \
__i = __i->prev; \
if (__i == (head)) { \
__i = NULL; \
break; \
} \
} while (!cmpfn((const type)__i , ## args)); \
(type)__i; \
})
static inline int static inline int
__list_cmp_same(const void *p1, const void *p2) { return p1 == p2; } __list_cmp_same(const void *p1, const void *p2) { return p1 == p2; }
......
...@@ -42,22 +42,22 @@ do { if (atomic_read(&(l)->locked_by) == smp_processor_id()) \ ...@@ -42,22 +42,22 @@ do { if (atomic_read(&(l)->locked_by) == smp_processor_id()) \
printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l); \ printk("ASSERT %s:%u %s locked\n", __FILE__, __LINE__, #l); \
} while(0) } while(0)
/* Write locked OK as well. */ \ /* Write locked OK as well. */
#define MUST_BE_READ_LOCKED(l) \ #define MUST_BE_READ_LOCKED(l) \
do { if (!((l)->read_locked_map & (1 << smp_processor_id())) \ do { if (!((l)->read_locked_map & (1UL << smp_processor_id())) \
&& !((l)->write_locked_map & (1 << smp_processor_id()))) \ && !((l)->write_locked_map & (1UL << smp_processor_id()))) \
printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \ printk("ASSERT %s:%u %s not readlocked\n", __FILE__, __LINE__, #l); \
} while(0) } while(0)
#define MUST_BE_WRITE_LOCKED(l) \ #define MUST_BE_WRITE_LOCKED(l) \
do { if (!((l)->write_locked_map & (1 << smp_processor_id()))) \ do { if (!((l)->write_locked_map & (1UL << smp_processor_id()))) \
printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \ printk("ASSERT %s:%u %s not writelocked\n", __FILE__, __LINE__, #l); \
} while(0) } while(0)
#define MUST_BE_READ_WRITE_UNLOCKED(l) \ #define MUST_BE_READ_WRITE_UNLOCKED(l) \
do { if ((l)->read_locked_map & (1 << smp_processor_id())) \ do { if ((l)->read_locked_map & (1UL << smp_processor_id())) \
printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l); \ printk("ASSERT %s:%u %s readlocked\n", __FILE__, __LINE__, #l); \
else if ((l)->write_locked_map & (1 << smp_processor_id())) \ else if ((l)->write_locked_map & (1UL << smp_processor_id())) \
printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \ printk("ASSERT %s:%u %s writelocked\n", __FILE__, __LINE__, #l); \
} while(0) } while(0)
...@@ -91,7 +91,7 @@ do { \ ...@@ -91,7 +91,7 @@ do { \
#define READ_UNLOCK(lk) \ #define READ_UNLOCK(lk) \
do { \ do { \
if (!((lk)->read_locked_map & (1 << smp_processor_id()))) \ if (!((lk)->read_locked_map & (1UL << smp_processor_id()))) \
printk("ASSERT: %s:%u %s not readlocked\n", \ printk("ASSERT: %s:%u %s not readlocked\n", \
__FILE__, __LINE__, #lk); \ __FILE__, __LINE__, #lk); \
clear_bit(smp_processor_id(), &(lk)->read_locked_map); \ clear_bit(smp_processor_id(), &(lk)->read_locked_map); \
......
...@@ -168,8 +168,8 @@ static inline int expect_cmp(const struct ip_conntrack_expect *i, ...@@ -168,8 +168,8 @@ static inline int expect_cmp(const struct ip_conntrack_expect *i,
static void static void
destroy_expect(struct ip_conntrack_expect *exp) destroy_expect(struct ip_conntrack_expect *exp)
{ {
DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(exp->use)); DEBUGP("destroy_expect(%p) use=%d\n", exp, atomic_read(&exp->use));
IP_NF_ASSERT(atomic_read(exp->use)); IP_NF_ASSERT(atomic_read(&exp->use));
IP_NF_ASSERT(!timer_pending(&exp->timeout)); IP_NF_ASSERT(!timer_pending(&exp->timeout));
kfree(exp); kfree(exp);
...@@ -576,7 +576,7 @@ static int early_drop(struct list_head *chain) ...@@ -576,7 +576,7 @@ static int early_drop(struct list_head *chain)
int dropped = 0; int dropped = 0;
READ_LOCK(&ip_conntrack_lock); READ_LOCK(&ip_conntrack_lock);
h = LIST_FIND(chain, unreplied, struct ip_conntrack_tuple_hash *); h = LIST_FIND_B(chain, unreplied, struct ip_conntrack_tuple_hash *);
if (h) if (h)
atomic_inc(&h->ctrack->ct_general.use); atomic_inc(&h->ctrack->ct_general.use);
READ_UNLOCK(&ip_conntrack_lock); READ_UNLOCK(&ip_conntrack_lock);
...@@ -685,6 +685,14 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -685,6 +685,14 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
struct ip_conntrack_expect *, tuple); struct ip_conntrack_expect *, tuple);
READ_UNLOCK(&ip_conntrack_expect_tuple_lock); READ_UNLOCK(&ip_conntrack_expect_tuple_lock);
/* If master is not in hash table yet (ie. packet hasn't left
this machine yet), how can other end know about expected?
Hence these are not the droids you are looking for (if
master ct never got confirmed, we'd hold a reference to it
and weird things would happen to future packets). */
if (expected && !is_confirmed(expected->expectant))
expected = NULL;
/* Look up the conntrack helper for master connections only */ /* Look up the conntrack helper for master connections only */
if (!expected) if (!expected)
conntrack->helper = ip_ct_find_helper(&repl_tuple); conntrack->helper = ip_ct_find_helper(&repl_tuple);
...@@ -695,12 +703,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple, ...@@ -695,12 +703,7 @@ init_conntrack(const struct ip_conntrack_tuple *tuple,
&& ! del_timer(&expected->timeout)) && ! del_timer(&expected->timeout))
expected = NULL; expected = NULL;
/* If master is not in hash table yet (ie. packet hasn't left if (expected) {
this machine yet), how can other end know about expected?
Hence these are not the droids you are looking for (if
master ct never got confirmed, we'd hold a reference to it
and weird things would happen to future packets). */
if (expected && is_confirmed(expected->expectant)) {
DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n", DEBUGP("conntrack: expectation arrives ct=%p exp=%p\n",
conntrack, expected); conntrack, expected);
/* Welcome, Mr. Bond. We've been expecting you... */ /* Welcome, Mr. Bond. We've been expecting you... */
...@@ -1282,9 +1285,9 @@ getorigdst(struct sock *sk, int optval, void *user, int *len) ...@@ -1282,9 +1285,9 @@ getorigdst(struct sock *sk, int optval, void *user, int *len)
struct inet_opt *inet = inet_sk(sk); struct inet_opt *inet = inet_sk(sk);
struct ip_conntrack_tuple_hash *h; struct ip_conntrack_tuple_hash *h;
struct ip_conntrack_tuple tuple = { { inet->rcv_saddr, struct ip_conntrack_tuple tuple = { { inet->rcv_saddr,
{ inet->sport } }, { .tcp = { inet->sport } } },
{ inet->daddr, { inet->daddr,
{ inet->dport }, { .tcp = { inet->dport } },
IPPROTO_TCP } }; IPPROTO_TCP } };
/* We only do TCP at the moment: is there a better way? */ /* We only do TCP at the moment: is there a better way? */
......
...@@ -367,11 +367,11 @@ static int help(struct sk_buff *skb, ...@@ -367,11 +367,11 @@ static int help(struct sk_buff *skb,
{ 0 } }, { 0 } },
{ htonl((array[0] << 24) | (array[1] << 16) { htonl((array[0] << 24) | (array[1] << 16)
| (array[2] << 8) | array[3]), | (array[2] << 8) | array[3]),
{ htons(array[4] << 8 | array[5]) }, { .tcp = { htons(array[4] << 8 | array[5]) } },
IPPROTO_TCP }}); IPPROTO_TCP }});
exp->mask = ((struct ip_conntrack_tuple) exp->mask = ((struct ip_conntrack_tuple)
{ { 0xFFFFFFFF, { 0 } }, { { 0xFFFFFFFF, { 0 } },
{ 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
exp->expectfn = NULL; exp->expectfn = NULL;
......
...@@ -192,11 +192,11 @@ static int help(struct sk_buff *skb, ...@@ -192,11 +192,11 @@ static int help(struct sk_buff *skb,
exp->tuple = ((struct ip_conntrack_tuple) exp->tuple = ((struct ip_conntrack_tuple)
{ { 0, { 0 } }, { { 0, { 0 } },
{ htonl(dcc_ip), { htons(dcc_port) }, { htonl(dcc_ip), { .tcp = { htons(dcc_port) } },
IPPROTO_TCP }}); IPPROTO_TCP }});
exp->mask = ((struct ip_conntrack_tuple) exp->mask = ((struct ip_conntrack_tuple)
{ { 0, { 0 } }, { { 0, { 0 } },
{ 0xFFFFFFFF, { 0xFFFF }, 0xFFFF }}); { 0xFFFFFFFF, { .tcp = { 0xFFFF } }, 0xFFFF }});
exp->expectfn = NULL; exp->expectfn = NULL;
......
...@@ -84,7 +84,7 @@ amanda_nat_expected(struct sk_buff **pskb, ...@@ -84,7 +84,7 @@ amanda_nat_expected(struct sk_buff **pskb,
mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
mr.range[0].min = mr.range[0].max mr.range[0].min = mr.range[0].max
= ((union ip_conntrack_manip_proto) = ((union ip_conntrack_manip_proto)
{ htons(port) }); { .udp = { htons(port) } });
} }
return ip_nat_setup_info(ct, &mr, hooknum); return ip_nat_setup_info(ct, &mr, hooknum);
......
...@@ -763,6 +763,11 @@ do_bindings(struct ip_conntrack *ct, ...@@ -763,6 +763,11 @@ do_bindings(struct ip_conntrack *ct,
enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo); enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
int proto = (*pskb)->nh.iph->protocol; int proto = (*pskb)->nh.iph->protocol;
/* Skip everything and don't call helpers if there are no
* manips for this connection */
if (info->num_manips == 0)
return NF_ACCEPT;
/* Need nat lock to protect against modification, but neither /* Need nat lock to protect against modification, but neither
conntrack (referenced) and helper (deleted with conntrack (referenced) and helper (deleted with
synchronize_bh()) can vanish. */ synchronize_bh()) can vanish. */
...@@ -791,6 +796,7 @@ do_bindings(struct ip_conntrack *ct, ...@@ -791,6 +796,7 @@ do_bindings(struct ip_conntrack *ct,
struct ip_conntrack_expect *exp = NULL; struct ip_conntrack_expect *exp = NULL;
struct list_head *cur_item; struct list_head *cur_item;
int ret = NF_ACCEPT; int ret = NF_ACCEPT;
int helper_called = 0;
DEBUGP("do_bindings: helper existing for (%p)\n", ct); DEBUGP("do_bindings: helper existing for (%p)\n", ct);
...@@ -809,19 +815,21 @@ do_bindings(struct ip_conntrack *ct, ...@@ -809,19 +815,21 @@ do_bindings(struct ip_conntrack *ct,
continue; continue;
if (exp_for_packet(exp, *pskb)) { if (exp_for_packet(exp, *pskb)) {
/* FIXME: May be true multiple times in the case of UDP!! */ /* FIXME: May be true multiple times in the
DEBUGP("calling nat helper (exp=%p) for packet\n", * case of UDP!! */
exp); DEBUGP("calling nat helper (exp=%p) for packet\n", exp);
ret = helper->help(ct, exp, info, ctinfo, ret = helper->help(ct, exp, info, ctinfo,
hooknum, pskb); hooknum, pskb);
if (ret != NF_ACCEPT) { if (ret != NF_ACCEPT) {
READ_UNLOCK(&ip_conntrack_lock); READ_UNLOCK(&ip_conntrack_lock);
return ret; return ret;
} }
helper_called = 1;
} }
} }
/* Helper might want to manip the packet even when there is no expectation */ /* Helper might want to manip the packet even when there is no
if (!exp && helper->flags & IP_NAT_HELPER_F_ALWAYS) { * matching expectation for this packet */
if (!helper_called && helper->flags & IP_NAT_HELPER_F_ALWAYS) {
DEBUGP("calling nat helper for packet without expectation\n"); DEBUGP("calling nat helper for packet without expectation\n");
ret = helper->help(ct, NULL, info, ctinfo, ret = helper->help(ct, NULL, info, ctinfo,
hooknum, pskb); hooknum, pskb);
......
...@@ -84,7 +84,7 @@ ftp_nat_expected(struct sk_buff **pskb, ...@@ -84,7 +84,7 @@ ftp_nat_expected(struct sk_buff **pskb,
mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED; mr.range[0].flags |= IP_NAT_RANGE_PROTO_SPECIFIED;
mr.range[0].min = mr.range[0].max mr.range[0].min = mr.range[0].max
= ((union ip_conntrack_manip_proto) = ((union ip_conntrack_manip_proto)
{ htons(exp_ftp_info->port) }); { .tcp = { htons(exp_ftp_info->port) } });
} }
return ip_nat_setup_info(ct, &mr, hooknum); return ip_nat_setup_info(ct, &mr, hooknum);
} }
......
...@@ -1308,9 +1308,9 @@ static struct ip_nat_helper snmp = { ...@@ -1308,9 +1308,9 @@ static struct ip_nat_helper snmp = {
"snmp", "snmp",
0, 0,
THIS_MODULE, THIS_MODULE,
{ { 0, { __constant_htons(SNMP_PORT) } }, { { 0, { .udp = { __constant_htons(SNMP_PORT) } } },
{ 0, { 0 }, IPPROTO_UDP } }, { 0, { 0 }, IPPROTO_UDP } },
{ { 0, { 0xFFFF } }, { { 0, { .udp = { 0xFFFF } } },
{ 0, { 0 }, 0xFFFF } }, { 0, { 0 }, 0xFFFF } },
nat_help, NULL }; nat_help, NULL };
...@@ -1319,9 +1319,9 @@ static struct ip_nat_helper snmp_trap = { ...@@ -1319,9 +1319,9 @@ static struct ip_nat_helper snmp_trap = {
"snmp_trap", "snmp_trap",
0, 0,
THIS_MODULE, THIS_MODULE,
{ { 0, { __constant_htons(SNMP_TRAP_PORT) } }, { { 0, { .udp = { __constant_htons(SNMP_TRAP_PORT) } } },
{ 0, { 0 }, IPPROTO_UDP } }, { 0, { 0 }, IPPROTO_UDP } },
{ { 0, { 0xFFFF } }, { { 0, { .udp = { 0xFFFF } } },
{ 0, { 0 }, 0xFFFF } }, { 0, { 0 }, 0xFFFF } },
nat_help, NULL }; nat_help, NULL };
......
...@@ -101,10 +101,8 @@ struct ip6t_table_info ...@@ -101,10 +101,8 @@ struct ip6t_table_info
unsigned int hook_entry[NF_IP6_NUMHOOKS]; unsigned int hook_entry[NF_IP6_NUMHOOKS];
unsigned int underflow[NF_IP6_NUMHOOKS]; unsigned int underflow[NF_IP6_NUMHOOKS];
char padding[SMP_ALIGN((NF_IP6_NUMHOOKS*2+2)*sizeof(unsigned int))];
/* ip6t_entry tables: one per CPU */ /* ip6t_entry tables: one per CPU */
char entries[0]; char entries[0] ____cacheline_aligned;
}; };
static LIST_HEAD(ip6t_target); static LIST_HEAD(ip6t_target);
...@@ -1451,7 +1449,7 @@ int ip6t_register_table(struct ip6t_table *table) ...@@ -1451,7 +1449,7 @@ int ip6t_register_table(struct ip6t_table *table)
int ret; int ret;
struct ip6t_table_info *newinfo; struct ip6t_table_info *newinfo;
static struct ip6t_table_info bootstrap static struct ip6t_table_info bootstrap
= { 0, 0, 0, { 0 }, { 0 }, { }, { } }; = { 0, 0, 0, { 0 }, { 0 }, { } };
newinfo = vmalloc(sizeof(struct ip6t_table_info) newinfo = vmalloc(sizeof(struct ip6t_table_info)
+ SMP_ALIGN(table->table->size) * NR_CPUS); + SMP_ALIGN(table->table->size) * NR_CPUS);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment