netfilter: merge some fixes from upstream
[openwrt/openwrt.git] / target / linux / generic-2.6 / patches-2.6.28 / 120-netfilter_upstream_fixes.patch
1 --- a/net/ipv4/netfilter/arp_tables.c
2 +++ b/net/ipv4/netfilter/arp_tables.c
3 @@ -374,7 +374,9 @@ static int mark_source_chains(struct xt_
4 && unconditional(&e->arp)) || visited) {
5 unsigned int oldpos, size;
6
7 - if (t->verdict < -NF_MAX_VERDICT - 1) {
8 + if ((strcmp(t->target.u.user.name,
9 + ARPT_STANDARD_TARGET) == 0) &&
10 + t->verdict < -NF_MAX_VERDICT - 1) {
11 duprintf("mark_source_chains: bad "
12 "negative verdict (%i)\n",
13 t->verdict);
14 --- a/net/ipv4/netfilter/ip_tables.c
15 +++ b/net/ipv4/netfilter/ip_tables.c
16 @@ -74,6 +74,25 @@ do { \
17
18 Hence the start of any table is given by get_table() below. */
19
20 +static unsigned long ifname_compare(const char *_a, const char *_b,
21 + const unsigned char *_mask)
22 +{
23 + const unsigned long *a = (const unsigned long *)_a;
24 + const unsigned long *b = (const unsigned long *)_b;
25 + const unsigned long *mask = (const unsigned long *)_mask;
26 + unsigned long ret;
27 +
28 + ret = (a[0] ^ b[0]) & mask[0];
29 + if (IFNAMSIZ > sizeof(unsigned long))
30 + ret |= (a[1] ^ b[1]) & mask[1];
31 + if (IFNAMSIZ > 2 * sizeof(unsigned long))
32 + ret |= (a[2] ^ b[2]) & mask[2];
33 + if (IFNAMSIZ > 3 * sizeof(unsigned long))
34 + ret |= (a[3] ^ b[3]) & mask[3];
35 + BUILD_BUG_ON(IFNAMSIZ > 4 * sizeof(unsigned long));
36 + return ret;
37 +}
38 +
39 /* Returns whether matches rule or not. */
40 /* Performance critical - called for every packet */
41 static inline bool
42 @@ -83,7 +102,6 @@ ip_packet_match(const struct iphdr *ip,
43 const struct ipt_ip *ipinfo,
44 int isfrag)
45 {
46 - size_t i;
47 unsigned long ret;
48
49 #define FWINV(bool, invflg) ((bool) ^ !!(ipinfo->invflags & (invflg)))
50 @@ -110,12 +128,7 @@ ip_packet_match(const struct iphdr *ip,
51 return false;
52 }
53
54 - /* Look for ifname matches; this should unroll nicely. */
55 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
56 - ret |= (((const unsigned long *)indev)[i]
57 - ^ ((const unsigned long *)ipinfo->iniface)[i])
58 - & ((const unsigned long *)ipinfo->iniface_mask)[i];
59 - }
60 + ret = ifname_compare(indev, ipinfo->iniface, ipinfo->iniface_mask);
61
62 if (FWINV(ret != 0, IPT_INV_VIA_IN)) {
63 dprintf("VIA in mismatch (%s vs %s).%s\n",
64 @@ -124,11 +137,7 @@ ip_packet_match(const struct iphdr *ip,
65 return false;
66 }
67
68 - for (i = 0, ret = 0; i < IFNAMSIZ/sizeof(unsigned long); i++) {
69 - ret |= (((const unsigned long *)outdev)[i]
70 - ^ ((const unsigned long *)ipinfo->outiface)[i])
71 - & ((const unsigned long *)ipinfo->outiface_mask)[i];
72 - }
73 + ret = ifname_compare(outdev, ipinfo->outiface, ipinfo->outiface_mask);
74
75 if (FWINV(ret != 0, IPT_INV_VIA_OUT)) {
76 dprintf("VIA out mismatch (%s vs %s).%s\n",
77 @@ -523,7 +532,9 @@ mark_source_chains(struct xt_table_info
78 && unconditional(&e->ip)) || visited) {
79 unsigned int oldpos, size;
80
81 - if (t->verdict < -NF_MAX_VERDICT - 1) {
82 + if ((strcmp(t->target.u.user.name,
83 + IPT_STANDARD_TARGET) == 0) &&
84 + t->verdict < -NF_MAX_VERDICT - 1) {
85 duprintf("mark_source_chains: bad "
86 "negative verdict (%i)\n",
87 t->verdict);
88 --- a/net/ipv6/netfilter/ip6_tables.c
89 +++ b/net/ipv6/netfilter/ip6_tables.c
90 @@ -525,7 +525,9 @@ mark_source_chains(struct xt_table_info
91 && unconditional(&e->ipv6)) || visited) {
92 unsigned int oldpos, size;
93
94 - if (t->verdict < -NF_MAX_VERDICT - 1) {
95 + if ((strcmp(t->target.u.user.name,
96 + IP6T_STANDARD_TARGET) == 0) &&
97 + t->verdict < -NF_MAX_VERDICT - 1) {
98 duprintf("mark_source_chains: bad "
99 "negative verdict (%i)\n",
100 t->verdict);