diff options
author | David S. Miller <davem@davemloft.net> | 2011-01-20 03:06:15 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2011-01-20 03:06:15 -0500 |
commit | a07aa004c8d814a975b1a68afdb7baaa8f1b91d5 (patch) | |
tree | 652edc2dce9732a64780b9e332034b6567631a8b /net/bridge | |
parent | cc7ec456f82da7f89a5b376e613b3ac4311b3e9a (diff) | |
parent | 5d8449286456659cdd0998e62d80df2d9e77e9e3 (diff) |
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/netfilter/ebt_ip6.c | 46 | ||||
-rw-r--r-- | net/bridge/netfilter/ebtables.c | 1 |
2 files changed, 35 insertions, 12 deletions
diff --git a/net/bridge/netfilter/ebt_ip6.c b/net/bridge/netfilter/ebt_ip6.c index 50a46afc2bcc..2ed0056a39a8 100644 --- a/net/bridge/netfilter/ebt_ip6.c +++ b/net/bridge/netfilter/ebt_ip6.c | |||
@@ -22,9 +22,15 @@ | |||
22 | #include <linux/netfilter_bridge/ebtables.h> | 22 | #include <linux/netfilter_bridge/ebtables.h> |
23 | #include <linux/netfilter_bridge/ebt_ip6.h> | 23 | #include <linux/netfilter_bridge/ebt_ip6.h> |
24 | 24 | ||
25 | struct tcpudphdr { | 25 | union pkthdr { |
26 | __be16 src; | 26 | struct { |
27 | __be16 dst; | 27 | __be16 src; |
28 | __be16 dst; | ||
29 | } tcpudphdr; | ||
30 | struct { | ||
31 | u8 type; | ||
32 | u8 code; | ||
33 | } icmphdr; | ||
28 | }; | 34 | }; |
29 | 35 | ||
30 | static bool | 36 | static bool |
@@ -33,8 +39,8 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
33 | const struct ebt_ip6_info *info = par->matchinfo; | 39 | const struct ebt_ip6_info *info = par->matchinfo; |
34 | const struct ipv6hdr *ih6; | 40 | const struct ipv6hdr *ih6; |
35 | struct ipv6hdr _ip6h; | 41 | struct ipv6hdr _ip6h; |
36 | const struct tcpudphdr *pptr; | 42 | const union pkthdr *pptr; |
37 | struct tcpudphdr _ports; | 43 | union pkthdr _pkthdr; |
38 | 44 | ||
39 | ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); | 45 | ih6 = skb_header_pointer(skb, 0, sizeof(_ip6h), &_ip6h); |
40 | if (ih6 == NULL) | 46 | if (ih6 == NULL) |
@@ -56,26 +62,34 @@ ebt_ip6_mt(const struct sk_buff *skb, struct xt_action_param *par) | |||
56 | return false; | 62 | return false; |
57 | if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) | 63 | if (FWINV(info->protocol != nexthdr, EBT_IP6_PROTO)) |
58 | return false; | 64 | return false; |
59 | if (!(info->bitmask & EBT_IP6_DPORT) && | 65 | if (!(info->bitmask & ( EBT_IP6_DPORT | |
60 | !(info->bitmask & EBT_IP6_SPORT)) | 66 | EBT_IP6_SPORT | EBT_IP6_ICMP6))) |
61 | return true; | 67 | return true; |
62 | pptr = skb_header_pointer(skb, offset_ph, sizeof(_ports), | 68 | |
63 | &_ports); | 69 | /* min icmpv6 headersize is 4, so sizeof(_pkthdr) is ok. */ |
70 | pptr = skb_header_pointer(skb, offset_ph, sizeof(_pkthdr), | ||
71 | &_pkthdr); | ||
64 | if (pptr == NULL) | 72 | if (pptr == NULL) |
65 | return false; | 73 | return false; |
66 | if (info->bitmask & EBT_IP6_DPORT) { | 74 | if (info->bitmask & EBT_IP6_DPORT) { |
67 | u32 dst = ntohs(pptr->dst); | 75 | u16 dst = ntohs(pptr->tcpudphdr.dst); |
68 | if (FWINV(dst < info->dport[0] || | 76 | if (FWINV(dst < info->dport[0] || |
69 | dst > info->dport[1], EBT_IP6_DPORT)) | 77 | dst > info->dport[1], EBT_IP6_DPORT)) |
70 | return false; | 78 | return false; |
71 | } | 79 | } |
72 | if (info->bitmask & EBT_IP6_SPORT) { | 80 | if (info->bitmask & EBT_IP6_SPORT) { |
73 | u32 src = ntohs(pptr->src); | 81 | u16 src = ntohs(pptr->tcpudphdr.src); |
74 | if (FWINV(src < info->sport[0] || | 82 | if (FWINV(src < info->sport[0] || |
75 | src > info->sport[1], EBT_IP6_SPORT)) | 83 | src > info->sport[1], EBT_IP6_SPORT)) |
76 | return false; | 84 | return false; |
77 | } | 85 | } |
78 | return true; | 86 | if ((info->bitmask & EBT_IP6_ICMP6) && |
87 | FWINV(pptr->icmphdr.type < info->icmpv6_type[0] || | ||
88 | pptr->icmphdr.type > info->icmpv6_type[1] || | ||
89 | pptr->icmphdr.code < info->icmpv6_code[0] || | ||
90 | pptr->icmphdr.code > info->icmpv6_code[1], | ||
91 | EBT_IP6_ICMP6)) | ||
92 | return false; | ||
79 | } | 93 | } |
80 | return true; | 94 | return true; |
81 | } | 95 | } |
@@ -103,6 +117,14 @@ static int ebt_ip6_mt_check(const struct xt_mtchk_param *par) | |||
103 | return -EINVAL; | 117 | return -EINVAL; |
104 | if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) | 118 | if (info->bitmask & EBT_IP6_SPORT && info->sport[0] > info->sport[1]) |
105 | return -EINVAL; | 119 | return -EINVAL; |
120 | if (info->bitmask & EBT_IP6_ICMP6) { | ||
121 | if ((info->invflags & EBT_IP6_PROTO) || | ||
122 | info->protocol != IPPROTO_ICMPV6) | ||
123 | return -EINVAL; | ||
124 | if (info->icmpv6_type[0] > info->icmpv6_type[1] || | ||
125 | info->icmpv6_code[0] > info->icmpv6_code[1]) | ||
126 | return -EINVAL; | ||
127 | } | ||
106 | return 0; | 128 | return 0; |
107 | } | 129 | } |
108 | 130 | ||
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c index 16df0532d4b9..5f1825df9dca 100644 --- a/net/bridge/netfilter/ebtables.c +++ b/net/bridge/netfilter/ebtables.c | |||
@@ -1764,6 +1764,7 @@ static int compat_table_info(const struct ebt_table_info *info, | |||
1764 | 1764 | ||
1765 | newinfo->entries_size = size; | 1765 | newinfo->entries_size = size; |
1766 | 1766 | ||
1767 | xt_compat_init_offsets(AF_INET, info->nentries); | ||
1767 | return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info, | 1768 | return EBT_ENTRY_ITERATE(entries, size, compat_calc_entry, info, |
1768 | entries, newinfo); | 1769 | entries, newinfo); |
1769 | } | 1770 | } |