diff options
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 40 |
1 files changed, 32 insertions, 8 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index a58459a76684..e27383d855de 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -49,7 +49,7 @@ | |||
49 | #include <net/udp.h> | 49 | #include <net/udp.h> |
50 | #include <net/inet_common.h> | 50 | #include <net/inet_common.h> |
51 | #include <net/tcp_states.h> | 51 | #include <net/tcp_states.h> |
52 | #ifdef CONFIG_IPV6_MIP6 | 52 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
53 | #include <net/mip6.h> | 53 | #include <net/mip6.h> |
54 | #endif | 54 | #endif |
55 | 55 | ||
@@ -137,6 +137,28 @@ static __inline__ int icmpv6_filter(struct sock *sk, struct sk_buff *skb) | |||
137 | return 0; | 137 | return 0; |
138 | } | 138 | } |
139 | 139 | ||
140 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | ||
141 | static int (*mh_filter)(struct sock *sock, struct sk_buff *skb); | ||
142 | |||
143 | int rawv6_mh_filter_register(int (*filter)(struct sock *sock, | ||
144 | struct sk_buff *skb)) | ||
145 | { | ||
146 | rcu_assign_pointer(mh_filter, filter); | ||
147 | return 0; | ||
148 | } | ||
149 | EXPORT_SYMBOL(rawv6_mh_filter_register); | ||
150 | |||
151 | int rawv6_mh_filter_unregister(int (*filter)(struct sock *sock, | ||
152 | struct sk_buff *skb)) | ||
153 | { | ||
154 | rcu_assign_pointer(mh_filter, NULL); | ||
155 | synchronize_rcu(); | ||
156 | return 0; | ||
157 | } | ||
158 | EXPORT_SYMBOL(rawv6_mh_filter_unregister); | ||
159 | |||
160 | #endif | ||
161 | |||
140 | /* | 162 | /* |
141 | * demultiplex raw sockets. | 163 | * demultiplex raw sockets. |
142 | * (should consider queueing the skb in the sock receive_queue | 164 | * (should consider queueing the skb in the sock receive_queue |
@@ -178,16 +200,22 @@ int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
178 | case IPPROTO_ICMPV6: | 200 | case IPPROTO_ICMPV6: |
179 | filtered = icmpv6_filter(sk, skb); | 201 | filtered = icmpv6_filter(sk, skb); |
180 | break; | 202 | break; |
181 | #ifdef CONFIG_IPV6_MIP6 | 203 | |
204 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | ||
182 | case IPPROTO_MH: | 205 | case IPPROTO_MH: |
206 | { | ||
183 | /* XXX: To validate MH only once for each packet, | 207 | /* XXX: To validate MH only once for each packet, |
184 | * this is placed here. It should be after checking | 208 | * this is placed here. It should be after checking |
185 | * xfrm policy, however it doesn't. The checking xfrm | 209 | * xfrm policy, however it doesn't. The checking xfrm |
186 | * policy is placed in rawv6_rcv() because it is | 210 | * policy is placed in rawv6_rcv() because it is |
187 | * required for each socket. | 211 | * required for each socket. |
188 | */ | 212 | */ |
189 | filtered = mip6_mh_filter(sk, skb); | 213 | int (*filter)(struct sock *sock, struct sk_buff *skb); |
214 | |||
215 | filter = rcu_dereference(mh_filter); | ||
216 | filtered = filter ? filter(sk, skb) : 0; | ||
190 | break; | 217 | break; |
218 | } | ||
191 | #endif | 219 | #endif |
192 | default: | 220 | default: |
193 | filtered = 0; | 221 | filtered = 0; |
@@ -611,9 +639,7 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
611 | struct iovec *iov; | 639 | struct iovec *iov; |
612 | u8 __user *type = NULL; | 640 | u8 __user *type = NULL; |
613 | u8 __user *code = NULL; | 641 | u8 __user *code = NULL; |
614 | #ifdef CONFIG_IPV6_MIP6 | ||
615 | u8 len = 0; | 642 | u8 len = 0; |
616 | #endif | ||
617 | int probed = 0; | 643 | int probed = 0; |
618 | int i; | 644 | int i; |
619 | 645 | ||
@@ -646,7 +672,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
646 | probed = 1; | 672 | probed = 1; |
647 | } | 673 | } |
648 | break; | 674 | break; |
649 | #ifdef CONFIG_IPV6_MIP6 | ||
650 | case IPPROTO_MH: | 675 | case IPPROTO_MH: |
651 | if (iov->iov_base && iov->iov_len < 1) | 676 | if (iov->iov_base && iov->iov_len < 1) |
652 | break; | 677 | break; |
@@ -660,7 +685,6 @@ static int rawv6_probe_proto_opt(struct flowi *fl, struct msghdr *msg) | |||
660 | len += iov->iov_len; | 685 | len += iov->iov_len; |
661 | 686 | ||
662 | break; | 687 | break; |
663 | #endif | ||
664 | default: | 688 | default: |
665 | probed = 1; | 689 | probed = 1; |
666 | break; | 690 | break; |
@@ -1256,7 +1280,7 @@ static int raw6_seq_show(struct seq_file *seq, void *v) | |||
1256 | return 0; | 1280 | return 0; |
1257 | } | 1281 | } |
1258 | 1282 | ||
1259 | static struct seq_operations raw6_seq_ops = { | 1283 | static const struct seq_operations raw6_seq_ops = { |
1260 | .start = raw6_seq_start, | 1284 | .start = raw6_seq_start, |
1261 | .next = raw6_seq_next, | 1285 | .next = raw6_seq_next, |
1262 | .stop = raw6_seq_stop, | 1286 | .stop = raw6_seq_stop, |