diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 21:02:35 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-04-18 21:02:35 -0400 |
commit | 334d094504c2fe1c44211ecb49146ae6bca8c321 (patch) | |
tree | d3c0f68e4b9f8e3d2ccc39e7dfe5de0534a5fad9 /net/ipv6/raw.c | |
parent | d1a4be630fb068f251d64b62919f143c49ca8057 (diff) | |
parent | d1643d24c61b725bef399cc1cf2944b4c9c23177 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.26
* git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-2.6.26: (1090 commits)
[NET]: Fix and allocate less memory for ->priv'less netdevices
[IPV6]: Fix dangling references on error in fib6_add().
[NETLABEL]: Fix NULL deref in netlbl_unlabel_staticlist_gen() if ifindex not found
[PKT_SCHED]: Fix datalen check in tcf_simp_init().
[INET]: Uninline the __inet_inherit_port call.
[INET]: Drop the inet_inherit_port() call.
SCTP: Initialize partial_bytes_acked to 0, when all of the data is acked.
[netdrvr] forcedeth: internal simplifications; changelog removal
phylib: factor out get_phy_id from within get_phy_device
PHY: add BCM5464 support to broadcom PHY driver
cxgb3: Fix __must_check warning with dev_dbg.
tc35815: Statistics cleanup
natsemi: fix MMIO for PPC 44x platforms
[TIPC]: Cleanup of TIPC reference table code
[TIPC]: Optimized initialization of TIPC reference table
[TIPC]: Remove inlining of reference table locking routines
e1000: convert uint16_t style integers to u16
ixgb: convert uint16_t style integers to u16
sb1000.c: make const arrays static
sb1000.c: stop inlining largish static functions
...
Diffstat (limited to 'net/ipv6/raw.c')
-rw-r--r-- | net/ipv6/raw.c | 69 |
1 files changed, 24 insertions, 45 deletions
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c index 0a6fbc1d1a50..6193b124cbc7 100644 --- a/net/ipv6/raw.c +++ b/net/ipv6/raw.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) | 53 | #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) |
54 | #include <net/mip6.h> | 54 | #include <net/mip6.h> |
55 | #endif | 55 | #endif |
56 | #include <linux/mroute6.h> | ||
56 | 57 | ||
57 | #include <net/raw.h> | 58 | #include <net/raw.h> |
58 | #include <net/rawv6.h> | 59 | #include <net/rawv6.h> |
@@ -62,20 +63,9 @@ | |||
62 | #include <linux/seq_file.h> | 63 | #include <linux/seq_file.h> |
63 | 64 | ||
64 | static struct raw_hashinfo raw_v6_hashinfo = { | 65 | static struct raw_hashinfo raw_v6_hashinfo = { |
65 | .lock = __RW_LOCK_UNLOCKED(), | 66 | .lock = __RW_LOCK_UNLOCKED(raw_v6_hashinfo.lock), |
66 | }; | 67 | }; |
67 | 68 | ||
68 | static void raw_v6_hash(struct sock *sk) | ||
69 | { | ||
70 | raw_hash_sk(sk, &raw_v6_hashinfo); | ||
71 | } | ||
72 | |||
73 | static void raw_v6_unhash(struct sock *sk) | ||
74 | { | ||
75 | raw_unhash_sk(sk, &raw_v6_hashinfo); | ||
76 | } | ||
77 | |||
78 | |||
79 | static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, | 69 | static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, |
80 | unsigned short num, struct in6_addr *loc_addr, | 70 | unsigned short num, struct in6_addr *loc_addr, |
81 | struct in6_addr *rmt_addr, int dif) | 71 | struct in6_addr *rmt_addr, int dif) |
@@ -87,7 +77,7 @@ static struct sock *__raw_v6_lookup(struct net *net, struct sock *sk, | |||
87 | if (inet_sk(sk)->num == num) { | 77 | if (inet_sk(sk)->num == num) { |
88 | struct ipv6_pinfo *np = inet6_sk(sk); | 78 | struct ipv6_pinfo *np = inet6_sk(sk); |
89 | 79 | ||
90 | if (sk->sk_net != net) | 80 | if (!net_eq(sock_net(sk), net)) |
91 | continue; | 81 | continue; |
92 | 82 | ||
93 | if (!ipv6_addr_any(&np->daddr) && | 83 | if (!ipv6_addr_any(&np->daddr) && |
@@ -179,15 +169,10 @@ static int ipv6_raw_deliver(struct sk_buff *skb, int nexthdr) | |||
179 | read_lock(&raw_v6_hashinfo.lock); | 169 | read_lock(&raw_v6_hashinfo.lock); |
180 | sk = sk_head(&raw_v6_hashinfo.ht[hash]); | 170 | sk = sk_head(&raw_v6_hashinfo.ht[hash]); |
181 | 171 | ||
182 | /* | ||
183 | * The first socket found will be delivered after | ||
184 | * delivery to transport protocols. | ||
185 | */ | ||
186 | |||
187 | if (sk == NULL) | 172 | if (sk == NULL) |
188 | goto out; | 173 | goto out; |
189 | 174 | ||
190 | net = skb->dev->nd_net; | 175 | net = dev_net(skb->dev); |
191 | sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); | 176 | sk = __raw_v6_lookup(net, sk, nexthdr, daddr, saddr, IP6CB(skb)->iif); |
192 | 177 | ||
193 | while (sk) { | 178 | while (sk) { |
@@ -291,7 +276,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
291 | if (!sk->sk_bound_dev_if) | 276 | if (!sk->sk_bound_dev_if) |
292 | goto out; | 277 | goto out; |
293 | 278 | ||
294 | dev = dev_get_by_index(sk->sk_net, sk->sk_bound_dev_if); | 279 | dev = dev_get_by_index(sock_net(sk), sk->sk_bound_dev_if); |
295 | if (!dev) { | 280 | if (!dev) { |
296 | err = -ENODEV; | 281 | err = -ENODEV; |
297 | goto out; | 282 | goto out; |
@@ -304,7 +289,7 @@ static int rawv6_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
304 | v4addr = LOOPBACK4_IPV6; | 289 | v4addr = LOOPBACK4_IPV6; |
305 | if (!(addr_type & IPV6_ADDR_MULTICAST)) { | 290 | if (!(addr_type & IPV6_ADDR_MULTICAST)) { |
306 | err = -EADDRNOTAVAIL; | 291 | err = -EADDRNOTAVAIL; |
307 | if (!ipv6_chk_addr(sk->sk_net, &addr->sin6_addr, | 292 | if (!ipv6_chk_addr(sock_net(sk), &addr->sin6_addr, |
308 | dev, 0)) { | 293 | dev, 0)) { |
309 | if (dev) | 294 | if (dev) |
310 | dev_put(dev); | 295 | dev_put(dev); |
@@ -372,11 +357,11 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr, | |||
372 | read_lock(&raw_v6_hashinfo.lock); | 357 | read_lock(&raw_v6_hashinfo.lock); |
373 | sk = sk_head(&raw_v6_hashinfo.ht[hash]); | 358 | sk = sk_head(&raw_v6_hashinfo.ht[hash]); |
374 | if (sk != NULL) { | 359 | if (sk != NULL) { |
375 | struct ipv6hdr *hdr = (struct ipv6hdr *) skb->data; | 360 | /* Note: ipv6_hdr(skb) != skb->data */ |
376 | 361 | struct ipv6hdr *ip6h = (struct ipv6hdr *)skb->data; | |
377 | saddr = &hdr->saddr; | 362 | saddr = &ip6h->saddr; |
378 | daddr = &hdr->daddr; | 363 | daddr = &ip6h->daddr; |
379 | net = skb->dev->nd_net; | 364 | net = dev_net(skb->dev); |
380 | 365 | ||
381 | while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, | 366 | while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, |
382 | IP6CB(skb)->iif))) { | 367 | IP6CB(skb)->iif))) { |
@@ -822,15 +807,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
822 | fl.fl6_flowlabel = np->flow_label; | 807 | fl.fl6_flowlabel = np->flow_label; |
823 | } | 808 | } |
824 | 809 | ||
825 | if (ipv6_addr_any(daddr)) { | ||
826 | /* | ||
827 | * unspecified destination address | ||
828 | * treated as error... is this correct ? | ||
829 | */ | ||
830 | fl6_sock_release(flowlabel); | ||
831 | return(-EINVAL); | ||
832 | } | ||
833 | |||
834 | if (fl.oif == 0) | 810 | if (fl.oif == 0) |
835 | fl.oif = sk->sk_bound_dev_if; | 811 | fl.oif = sk->sk_bound_dev_if; |
836 | 812 | ||
@@ -863,7 +839,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
863 | if (err) | 839 | if (err) |
864 | goto out; | 840 | goto out; |
865 | 841 | ||
866 | ipv6_addr_copy(&fl.fl6_dst, daddr); | 842 | if (!ipv6_addr_any(daddr)) |
843 | ipv6_addr_copy(&fl.fl6_dst, daddr); | ||
844 | else | ||
845 | fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */ | ||
867 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) | 846 | if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) |
868 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | 847 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); |
869 | 848 | ||
@@ -898,9 +877,7 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk, | |||
898 | else | 877 | else |
899 | hlimit = np->hop_limit; | 878 | hlimit = np->hop_limit; |
900 | if (hlimit < 0) | 879 | if (hlimit < 0) |
901 | hlimit = dst_metric(dst, RTAX_HOPLIMIT); | 880 | hlimit = ip6_dst_hoplimit(dst); |
902 | if (hlimit < 0) | ||
903 | hlimit = ipv6_get_hoplimit(dst->dev); | ||
904 | } | 881 | } |
905 | 882 | ||
906 | if (tclass < 0) { | 883 | if (tclass < 0) { |
@@ -1155,7 +1132,11 @@ static int rawv6_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
1155 | } | 1132 | } |
1156 | 1133 | ||
1157 | default: | 1134 | default: |
1135 | #ifdef CONFIG_IPV6_MROUTE | ||
1136 | return ip6mr_ioctl(sk, cmd, (void __user *)arg); | ||
1137 | #else | ||
1158 | return -ENOIOCTLCMD; | 1138 | return -ENOIOCTLCMD; |
1139 | #endif | ||
1159 | } | 1140 | } |
1160 | } | 1141 | } |
1161 | 1142 | ||
@@ -1163,7 +1144,7 @@ static void rawv6_close(struct sock *sk, long timeout) | |||
1163 | { | 1144 | { |
1164 | if (inet_sk(sk)->num == IPPROTO_RAW) | 1145 | if (inet_sk(sk)->num == IPPROTO_RAW) |
1165 | ip6_ra_control(sk, -1, NULL); | 1146 | ip6_ra_control(sk, -1, NULL); |
1166 | 1147 | ip6mr_sk_done(sk); | |
1167 | sk_common_release(sk); | 1148 | sk_common_release(sk); |
1168 | } | 1149 | } |
1169 | 1150 | ||
@@ -1186,8 +1167,6 @@ static int rawv6_init_sk(struct sock *sk) | |||
1186 | return(0); | 1167 | return(0); |
1187 | } | 1168 | } |
1188 | 1169 | ||
1189 | DEFINE_PROTO_INUSE(rawv6) | ||
1190 | |||
1191 | struct proto rawv6_prot = { | 1170 | struct proto rawv6_prot = { |
1192 | .name = "RAWv6", | 1171 | .name = "RAWv6", |
1193 | .owner = THIS_MODULE, | 1172 | .owner = THIS_MODULE, |
@@ -1203,14 +1182,14 @@ struct proto rawv6_prot = { | |||
1203 | .recvmsg = rawv6_recvmsg, | 1182 | .recvmsg = rawv6_recvmsg, |
1204 | .bind = rawv6_bind, | 1183 | .bind = rawv6_bind, |
1205 | .backlog_rcv = rawv6_rcv_skb, | 1184 | .backlog_rcv = rawv6_rcv_skb, |
1206 | .hash = raw_v6_hash, | 1185 | .hash = raw_hash_sk, |
1207 | .unhash = raw_v6_unhash, | 1186 | .unhash = raw_unhash_sk, |
1208 | .obj_size = sizeof(struct raw6_sock), | 1187 | .obj_size = sizeof(struct raw6_sock), |
1188 | .h.raw_hash = &raw_v6_hashinfo, | ||
1209 | #ifdef CONFIG_COMPAT | 1189 | #ifdef CONFIG_COMPAT |
1210 | .compat_setsockopt = compat_rawv6_setsockopt, | 1190 | .compat_setsockopt = compat_rawv6_setsockopt, |
1211 | .compat_getsockopt = compat_rawv6_getsockopt, | 1191 | .compat_getsockopt = compat_rawv6_getsockopt, |
1212 | #endif | 1192 | #endif |
1213 | REF_PROTO_INUSE(rawv6) | ||
1214 | }; | 1193 | }; |
1215 | 1194 | ||
1216 | #ifdef CONFIG_PROC_FS | 1195 | #ifdef CONFIG_PROC_FS |