aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-11-20 01:35:57 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:54:29 -0500
commit69d6da0b0faa70249a243a14e6066c013e9294e5 (patch)
treef3678fc834f0b7ba1fc46ef2a4a240e7a937d747 /net
parent7bc54c90307b4bc3d7fb2ffd6ad8fbda0671a45e (diff)
[IPv6] RAW: Compact the API for the kernel
Same as in the previous patch for ipv4, compact the API and hide hash table and rwlock inside the raw.c file. Plus fix some "bad" places from checkpatch.pl point of view (assignments inside if()). Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r--net/ipv6/icmp.c15
-rw-r--r--net/ipv6/ip6_input.c9
-rw-r--r--net/ipv6/raw.c52
3 files changed, 48 insertions, 28 deletions
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index f1240688dc58..93c96cfd5ee1 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -555,9 +555,7 @@ out:
555 555
556static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info) 556static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
557{ 557{
558 struct in6_addr *saddr, *daddr;
559 struct inet6_protocol *ipprot; 558 struct inet6_protocol *ipprot;
560 struct sock *sk;
561 int inner_offset; 559 int inner_offset;
562 int hash; 560 int hash;
563 u8 nexthdr; 561 u8 nexthdr;
@@ -579,9 +577,6 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
579 if (!pskb_may_pull(skb, inner_offset+8)) 577 if (!pskb_may_pull(skb, inner_offset+8))
580 return; 578 return;
581 579
582 saddr = &ipv6_hdr(skb)->saddr;
583 daddr = &ipv6_hdr(skb)->daddr;
584
585 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet. 580 /* BUGGG_FUTURE: we should try to parse exthdrs in this packet.
586 Without this we will not able f.e. to make source routed 581 Without this we will not able f.e. to make source routed
587 pmtu discovery. 582 pmtu discovery.
@@ -597,15 +592,7 @@ static void icmpv6_notify(struct sk_buff *skb, int type, int code, __be32 info)
597 ipprot->err_handler(skb, NULL, type, code, inner_offset, info); 592 ipprot->err_handler(skb, NULL, type, code, inner_offset, info);
598 rcu_read_unlock(); 593 rcu_read_unlock();
599 594
600 read_lock(&raw_v6_lock); 595 raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info);
601 if ((sk = sk_head(&raw_v6_htable[hash])) != NULL) {
602 while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
603 IP6CB(skb)->iif))) {
604 rawv6_err(sk, skb, NULL, type, code, inner_offset, info);
605 sk = sk_next(sk);
606 }
607 }
608 read_unlock(&raw_v6_lock);
609} 596}
610 597
611/* 598/*
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 79610b4bad3e..178aebc0427a 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -153,9 +153,8 @@ out:
153static int ip6_input_finish(struct sk_buff *skb) 153static int ip6_input_finish(struct sk_buff *skb)
154{ 154{
155 struct inet6_protocol *ipprot; 155 struct inet6_protocol *ipprot;
156 struct sock *raw_sk;
157 unsigned int nhoff; 156 unsigned int nhoff;
158 int nexthdr; 157 int nexthdr, raw;
159 u8 hash; 158 u8 hash;
160 struct inet6_dev *idev; 159 struct inet6_dev *idev;
161 160
@@ -171,9 +170,7 @@ resubmit:
171 nhoff = IP6CB(skb)->nhoff; 170 nhoff = IP6CB(skb)->nhoff;
172 nexthdr = skb_network_header(skb)[nhoff]; 171 nexthdr = skb_network_header(skb)[nhoff];
173 172
174 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]); 173 raw = raw6_local_deliver(skb, nexthdr);
175 if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
176 raw_sk = NULL;
177 174
178 hash = nexthdr & (MAX_INET_PROTOS - 1); 175 hash = nexthdr & (MAX_INET_PROTOS - 1);
179 if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) { 176 if ((ipprot = rcu_dereference(inet6_protos[hash])) != NULL) {
@@ -206,7 +203,7 @@ resubmit:
206 else if (ret == 0) 203 else if (ret == 0)
207 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS); 204 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INDELIVERS);
208 } else { 205 } else {
209 if (!raw_sk) { 206 if (!raw) {
210 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 207 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
211 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS); 208 IP6_INC_STATS_BH(idev, IPSTATS_MIB_INUNKNOWNPROTOS);
212 icmpv6_send(skb, ICMPV6_PARAMPROB, 209 icmpv6_send(skb, ICMPV6_PARAMPROB,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index ad622cc11bda..53f01b4982c7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -60,8 +60,10 @@
60#include <linux/proc_fs.h> 60#include <linux/proc_fs.h>
61#include <linux/seq_file.h> 61#include <linux/seq_file.h>
62 62
63struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE]; 63#define RAWV6_HTABLE_SIZE MAX_INET_PROTOS
64DEFINE_RWLOCK(raw_v6_lock); 64
65static struct hlist_head raw_v6_htable[RAWV6_HTABLE_SIZE];
66static DEFINE_RWLOCK(raw_v6_lock);
65 67
66static void raw_v6_hash(struct sock *sk) 68static void raw_v6_hash(struct sock *sk)
67{ 69{
@@ -83,10 +85,8 @@ static void raw_v6_unhash(struct sock *sk)
83} 85}
84 86
85 87
86/* Grumble... icmp and ip_input want to get at this... */ 88static struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num,
87struct sock *__raw_v6_lookup(struct sock *sk, unsigned short num, 89 struct in6_addr *loc_addr, struct in6_addr *rmt_addr, int dif)
88 struct in6_addr *loc_addr, struct in6_addr *rmt_addr,
89 int dif)
90{ 90{
91 struct hlist_node *node; 91 struct hlist_node *node;
92 int is_multicast = ipv6_addr_is_multicast(loc_addr); 92 int is_multicast = ipv6_addr_is_multicast(loc_addr);
@@ -167,7 +167,7 @@ EXPORT_SYMBOL(rawv6_mh_filter_unregister);
167 * 167 *
168 * Caller owns SKB so we must make clones. 168 * Caller owns SKB so we must make clones.
169 */ 169 */
170int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) 170static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr)
171{ 171{
172 struct in6_addr *saddr; 172 struct in6_addr *saddr;
173 struct in6_addr *daddr; 173 struct in6_addr *daddr;
@@ -242,6 +242,17 @@ out:
242 return delivered; 242 return delivered;
243} 243}
244 244
245int raw6_local_deliver(struct sk_buff *skb, int nexthdr)
246{
247 struct sock *raw_sk;
248
249 raw_sk = sk_head(&raw_v6_htable[nexthdr & (MAX_INET_PROTOS - 1)]);
250 if (raw_sk && !ipv6_raw_deliver(skb, nexthdr))
251 raw_sk = NULL;
252
253 return raw_sk != NULL;
254}
255
245/* This cleans up af_inet6 a bit. -DaveM */ 256/* This cleans up af_inet6 a bit. -DaveM */
246static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) 257static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
247{ 258{
@@ -316,7 +327,7 @@ out:
316 return err; 327 return err;
317} 328}
318 329
319void rawv6_err(struct sock *sk, struct sk_buff *skb, 330static void rawv6_err(struct sock *sk, struct sk_buff *skb,
320 struct inet6_skb_parm *opt, 331 struct inet6_skb_parm *opt,
321 int type, int code, int offset, __be32 info) 332 int type, int code, int offset, __be32 info)
322{ 333{
@@ -350,6 +361,31 @@ void rawv6_err(struct sock *sk, struct sk_buff *skb,
350 } 361 }
351} 362}
352 363
364void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
365 int type, int code, int inner_offset, __be32 info)
366{
367 struct sock *sk;
368 int hash;
369 struct in6_addr *saddr, *daddr;
370
371 hash = nexthdr & (RAWV6_HTABLE_SIZE - 1);
372
373 read_lock(&raw_v6_lock);
374 sk = sk_head(&raw_v6_htable[hash]);
375 if (sk != NULL) {
376 saddr = &ipv6_hdr(skb)->saddr;
377 daddr = &ipv6_hdr(skb)->daddr;
378
379 while ((sk = __raw_v6_lookup(sk, nexthdr, saddr, daddr,
380 IP6CB(skb)->iif))) {
381 rawv6_err(sk, skb, NULL, type, code,
382 inner_offset, info);
383 sk = sk_next(sk);
384 }
385 }
386 read_unlock(&raw_v6_lock);
387}
388
353static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb) 389static inline int rawv6_rcv_skb(struct sock * sk, struct sk_buff * skb)
354{ 390{
355 if ((raw6_sk(sk)->checksum || sk->sk_filter) && 391 if ((raw6_sk(sk)->checksum || sk->sk_filter) &&