aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/in6.h8
-rw-r--r--include/net/addrconf.h87
-rw-r--r--include/net/ip6_route.h6
-rw-r--r--include/net/ipv6.h26
-rw-r--r--include/net/mip6.h3
-rw-r--r--include/net/ndisc.h14
-rw-r--r--net/ipv6/addrconf.c82
-rw-r--r--net/ipv6/fib6_rules.c2
-rw-r--r--net/ipv6/ip6_input.c26
-rw-r--r--net/ipv6/ip6_output.c2
-rw-r--r--net/ipv6/ip6mr.c37
-rw-r--r--net/ipv6/ipv6_sockglue.c81
-rw-r--r--net/ipv6/mcast.c60
-rw-r--r--net/ipv6/mip6.c4
-rw-r--r--net/ipv6/ndisc.c27
-rw-r--r--net/ipv6/raw.c20
-rw-r--r--net/ipv6/route.c6
-rw-r--r--net/ipv6/sit.c2
-rw-r--r--net/ipv6/tcp_ipv6.c4
-rw-r--r--net/ipv6/udp.c5
20 files changed, 264 insertions, 238 deletions
diff --git a/include/linux/in6.h b/include/linux/in6.h
index e6aa8de2b939..bc492048c349 100644
--- a/include/linux/in6.h
+++ b/include/linux/in6.h
@@ -48,6 +48,14 @@ extern const struct in6_addr in6addr_any;
48#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } } 48#define IN6ADDR_ANY_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 } } }
49extern const struct in6_addr in6addr_loopback; 49extern const struct in6_addr in6addr_loopback;
50#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } } 50#define IN6ADDR_LOOPBACK_INIT { { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
51#ifdef __KERNEL__
52extern const struct in6_addr in6addr_linklocal_allnodes;
53#define IN6ADDR_LINKLOCAL_ALLNODES_INIT \
54 { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,1 } } }
55extern const struct in6_addr in6addr_linklocal_allrouters;
56#define IN6ADDR_LINKLOCAL_ALLROUTERS_INIT \
57 { { { 0xff,2,0,0,0,0,0,0,0,0,0,0,0,0,0,2 } } }
58#endif
51 59
52struct sockaddr_in6 { 60struct sockaddr_in6 {
53 unsigned short int sin6_family; /* AF_INET6 */ 61 unsigned short int sin6_family; /* AF_INET6 */
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index bdcc863a60a4..0a2f0372df31 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -76,12 +76,12 @@ extern int ipv6_chk_prefix(struct in6_addr *addr,
76 struct net_device *dev); 76 struct net_device *dev);
77 77
78extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, 78extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net,
79 struct in6_addr *addr, 79 const struct in6_addr *addr,
80 struct net_device *dev, 80 struct net_device *dev,
81 int strict); 81 int strict);
82 82
83extern int ipv6_dev_get_saddr(struct net_device *dev, 83extern int ipv6_dev_get_saddr(struct net_device *dev,
84 struct in6_addr *daddr, 84 const struct in6_addr *daddr,
85 unsigned int srcprefs, 85 unsigned int srcprefs,
86 struct in6_addr *saddr); 86 struct in6_addr *saddr);
87extern int ipv6_get_lladdr(struct net_device *dev, 87extern int ipv6_get_lladdr(struct net_device *dev,
@@ -105,25 +105,27 @@ extern u32 ipv6_addr_label(const struct in6_addr *addr,
105/* 105/*
106 * multicast prototypes (mcast.c) 106 * multicast prototypes (mcast.c)
107 */ 107 */
108extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, 108extern int ipv6_sock_mc_join(struct sock *sk, int ifindex,
109 struct in6_addr *addr); 109 const struct in6_addr *addr);
110extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, 110extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex,
111 struct in6_addr *addr); 111 const struct in6_addr *addr);
112extern void ipv6_sock_mc_close(struct sock *sk); 112extern void ipv6_sock_mc_close(struct sock *sk);
113extern int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, 113extern int inet6_mc_check(struct sock *sk,
114 struct in6_addr *src_addr); 114 const struct in6_addr *mc_addr,
115 const struct in6_addr *src_addr);
115 116
116extern int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr); 117extern int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr);
117extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); 118extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr);
118extern int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr); 119extern int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr);
119extern void ipv6_mc_up(struct inet6_dev *idev); 120extern void ipv6_mc_up(struct inet6_dev *idev);
120extern void ipv6_mc_down(struct inet6_dev *idev); 121extern void ipv6_mc_down(struct inet6_dev *idev);
121extern void ipv6_mc_init_dev(struct inet6_dev *idev); 122extern void ipv6_mc_init_dev(struct inet6_dev *idev);
122extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); 123extern void ipv6_mc_destroy_dev(struct inet6_dev *idev);
123extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); 124extern void addrconf_dad_failure(struct inet6_ifaddr *ifp);
124 125
125extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, 126extern int ipv6_chk_mcast_addr(struct net_device *dev,
126 struct in6_addr *src_addr); 127 const struct in6_addr *group,
128 const struct in6_addr *src_addr);
127extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); 129extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr);
128 130
129extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len); 131extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len);
@@ -189,25 +191,6 @@ static inline void in6_ifa_put(struct inet6_ifaddr *ifp)
189#define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt) 191#define in6_ifa_hold(ifp) atomic_inc(&(ifp)->refcnt)
190 192
191 193
192/*
193 * Hash function taken from net_alias.c
194 */
195
196static __inline__ u8 ipv6_addr_hash(const struct in6_addr *addr)
197{
198 __u32 word;
199
200 /*
201 * We perform the hash function over the last 64 bits of the address
202 * This will include the IEEE address token on links that support it.
203 */
204
205 word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]);
206 word ^= (word >> 16);
207 word ^= (word >> 8);
208
209 return ((word ^ (word >> 4)) & 0x0f);
210}
211 194
212/* 195/*
213 * compute link-local solicited-node multicast address 196 * compute link-local solicited-node multicast address
@@ -222,17 +205,6 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
222 htonl(0xFF000000) | addr->s6_addr32[3]); 205 htonl(0xFF000000) | addr->s6_addr32[3]);
223} 206}
224 207
225
226static inline void ipv6_addr_all_nodes(struct in6_addr *addr)
227{
228 ipv6_addr_set(addr, htonl(0xFF020000), 0, 0, htonl(0x1));
229}
230
231static inline void ipv6_addr_all_routers(struct in6_addr *addr)
232{
233 ipv6_addr_set(addr, htonl(0xFF020000), 0, 0, htonl(0x2));
234}
235
236static inline int ipv6_addr_is_multicast(const struct in6_addr *addr) 208static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
237{ 209{
238 return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000); 210 return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
@@ -240,34 +212,19 @@ static inline int ipv6_addr_is_multicast(const struct in6_addr *addr)
240 212
241static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) 213static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
242{ 214{
243 return (addr->s6_addr32[0] == htonl(0xff020000) && 215 return (((addr->s6_addr32[0] ^ htonl(0xff020000)) |
244 addr->s6_addr32[1] == 0 && 216 addr->s6_addr32[1] | addr->s6_addr32[2] |
245 addr->s6_addr32[2] == 0 && 217 (addr->s6_addr32[3] ^ htonl(0x00000001))) == 0);
246 addr->s6_addr32[3] == htonl(0x00000001));
247} 218}
248 219
249static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) 220static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr)
250{ 221{
251 return (addr->s6_addr32[0] == htonl(0xff020000) && 222 return (((addr->s6_addr32[0] ^ htonl(0xff020000)) |
252 addr->s6_addr32[1] == 0 && 223 addr->s6_addr32[1] | addr->s6_addr32[2] |
253 addr->s6_addr32[2] == 0 && 224 (addr->s6_addr32[3] ^ htonl(0x00000002))) == 0);
254 addr->s6_addr32[3] == htonl(0x00000002));
255} 225}
256 226
257static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr) 227extern int __ipv6_isatap_ifid(u8 *eui, __be32 addr);
258{
259 eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
260 ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
261 ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
262 ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) ||
263 ipv4_is_test_198(addr) || ipv4_is_multicast(addr) ||
264 ipv4_is_lbcast(addr)) ? 0x00 : 0x02;
265 eui[1] = 0;
266 eui[2] = 0x5E;
267 eui[3] = 0xFE;
268 memcpy (eui+4, &addr, 4);
269 return 0;
270}
271 228
272static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) 229static inline int ipv6_addr_is_isatap(const struct in6_addr *addr)
273{ 230{
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 9080076ce0e5..9313491e3dad 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -61,13 +61,13 @@ extern int ip6_ins_rt(struct rt6_info *);
61extern int ip6_del_rt(struct rt6_info *); 61extern int ip6_del_rt(struct rt6_info *);
62 62
63extern struct rt6_info *rt6_lookup(struct net *net, 63extern struct rt6_info *rt6_lookup(struct net *net,
64 struct in6_addr *daddr, 64 const struct in6_addr *daddr,
65 struct in6_addr *saddr, 65 const struct in6_addr *saddr,
66 int oif, int flags); 66 int oif, int flags);
67 67
68extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev, 68extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
69 struct neighbour *neigh, 69 struct neighbour *neigh,
70 struct in6_addr *addr); 70 const struct in6_addr *addr);
71extern int icmp6_dst_gc(int *more); 71extern int icmp6_dst_gc(int *more);
72 72
73extern void fib6_force_start_gc(struct net *net); 73extern void fib6_force_start_gc(struct net *net);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index 5738c1c73ac1..49c48983019f 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -280,12 +280,10 @@ static inline int
280ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, 280ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m,
281 const struct in6_addr *a2) 281 const struct in6_addr *a2)
282{ 282{
283 unsigned int i; 283 return (!!(((a1->s6_addr32[0] ^ a2->s6_addr32[0]) & m->s6_addr32[0]) |
284 284 ((a1->s6_addr32[1] ^ a2->s6_addr32[1]) & m->s6_addr32[1]) |
285 for (i = 0; i < 4; i++) 285 ((a1->s6_addr32[2] ^ a2->s6_addr32[2]) & m->s6_addr32[2]) |
286 if ((a1->s6_addr32[i] ^ a2->s6_addr32[i]) & m->s6_addr32[i]) 286 ((a1->s6_addr32[3] ^ a2->s6_addr32[3]) & m->s6_addr32[3])));
287 return 1;
288 return 0;
289} 287}
290 288
291static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) 289static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2)
@@ -320,10 +318,10 @@ static inline void ipv6_addr_set(struct in6_addr *addr,
320static inline int ipv6_addr_equal(const struct in6_addr *a1, 318static inline int ipv6_addr_equal(const struct in6_addr *a1,
321 const struct in6_addr *a2) 319 const struct in6_addr *a2)
322{ 320{
323 return (a1->s6_addr32[0] == a2->s6_addr32[0] && 321 return (((a1->s6_addr32[0] ^ a2->s6_addr32[0]) |
324 a1->s6_addr32[1] == a2->s6_addr32[1] && 322 (a1->s6_addr32[1] ^ a2->s6_addr32[1]) |
325 a1->s6_addr32[2] == a2->s6_addr32[2] && 323 (a1->s6_addr32[2] ^ a2->s6_addr32[2]) |
326 a1->s6_addr32[3] == a2->s6_addr32[3]); 324 (a1->s6_addr32[3] ^ a2->s6_addr32[3])) == 0);
327} 325}
328 326
329static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, 327static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2,
@@ -371,8 +369,8 @@ static inline int ipv6_addr_any(const struct in6_addr *a)
371 369
372static inline int ipv6_addr_v4mapped(const struct in6_addr *a) 370static inline int ipv6_addr_v4mapped(const struct in6_addr *a)
373{ 371{
374 return ((a->s6_addr32[0] | a->s6_addr32[1]) == 0 && 372 return ((a->s6_addr32[0] | a->s6_addr32[1] |
375 a->s6_addr32[2] == htonl(0x0000ffff)); 373 (a->s6_addr32[2] ^ htonl(0x0000ffff))) == 0);
376} 374}
377 375
378/* 376/*
@@ -453,8 +451,8 @@ extern int ip6_xmit(struct sock *sk,
453extern int ip6_nd_hdr(struct sock *sk, 451extern int ip6_nd_hdr(struct sock *sk,
454 struct sk_buff *skb, 452 struct sk_buff *skb,
455 struct net_device *dev, 453 struct net_device *dev,
456 struct in6_addr *saddr, 454 const struct in6_addr *saddr,
457 struct in6_addr *daddr, 455 const struct in6_addr *daddr,
458 int proto, int len); 456 int proto, int len);
459 457
460extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); 458extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr);
diff --git a/include/net/mip6.h b/include/net/mip6.h
index 63272610a24a..a83ad1982a90 100644
--- a/include/net/mip6.h
+++ b/include/net/mip6.h
@@ -28,9 +28,6 @@
28#include <linux/skbuff.h> 28#include <linux/skbuff.h>
29#include <net/sock.h> 29#include <net/sock.h>
30 30
31#define MIP6_OPT_PAD_1 0
32#define MIP6_OPT_PAD_N 1
33
34/* 31/*
35 * Mobility Header 32 * Mobility Header
36 */ 33 */
diff --git a/include/net/ndisc.h b/include/net/ndisc.h
index 16424236fe2f..9c451ff2f4f4 100644
--- a/include/net/ndisc.h
+++ b/include/net/ndisc.h
@@ -94,17 +94,17 @@ extern int ndisc_rcv(struct sk_buff *skb);
94 94
95extern void ndisc_send_ns(struct net_device *dev, 95extern void ndisc_send_ns(struct net_device *dev,
96 struct neighbour *neigh, 96 struct neighbour *neigh,
97 struct in6_addr *solicit, 97 const struct in6_addr *solicit,
98 struct in6_addr *daddr, 98 const struct in6_addr *daddr,
99 struct in6_addr *saddr); 99 const struct in6_addr *saddr);
100 100
101extern void ndisc_send_rs(struct net_device *dev, 101extern void ndisc_send_rs(struct net_device *dev,
102 struct in6_addr *saddr, 102 const struct in6_addr *saddr,
103 struct in6_addr *daddr); 103 const struct in6_addr *daddr);
104 104
105extern void ndisc_send_redirect(struct sk_buff *skb, 105extern void ndisc_send_redirect(struct sk_buff *skb,
106 struct neighbour *neigh, 106 struct neighbour *neigh,
107 struct in6_addr *target); 107 const struct in6_addr *target);
108 108
109extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir); 109extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir);
110 110
@@ -134,7 +134,7 @@ extern int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl,
134extern void inet6_ifinfo_notify(int event, 134extern void inet6_ifinfo_notify(int event,
135 struct inet6_dev *idev); 135 struct inet6_dev *idev);
136 136
137static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) 137static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, const struct in6_addr *addr)
138{ 138{
139 139
140 if (dev) 140 if (dev)
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 924158393d04..e93fa62089f8 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -222,6 +222,8 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
222/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ 222/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
223const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; 223const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT;
224const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; 224const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT;
225const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT;
226const struct in6_addr in6addr_linklocal_allrouters = IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
225 227
226/* Check if a valid qdisc is available */ 228/* Check if a valid qdisc is available */
227static inline int addrconf_qdisc_ok(struct net_device *dev) 229static inline int addrconf_qdisc_ok(struct net_device *dev)
@@ -321,7 +323,6 @@ EXPORT_SYMBOL(in6_dev_finish_destroy);
321static struct inet6_dev * ipv6_add_dev(struct net_device *dev) 323static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
322{ 324{
323 struct inet6_dev *ndev; 325 struct inet6_dev *ndev;
324 struct in6_addr maddr;
325 326
326 ASSERT_RTNL(); 327 ASSERT_RTNL();
327 328
@@ -406,8 +407,7 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev)
406 rcu_assign_pointer(dev->ip6_ptr, ndev); 407 rcu_assign_pointer(dev->ip6_ptr, ndev);
407 408
408 /* Join all-node multicast group */ 409 /* Join all-node multicast group */
409 ipv6_addr_all_nodes(&maddr); 410 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allnodes);
410 ipv6_dev_mc_inc(dev, &maddr);
411 411
412 return ndev; 412 return ndev;
413} 413}
@@ -433,18 +433,15 @@ static void dev_forward_change(struct inet6_dev *idev)
433{ 433{
434 struct net_device *dev; 434 struct net_device *dev;
435 struct inet6_ifaddr *ifa; 435 struct inet6_ifaddr *ifa;
436 struct in6_addr addr;
437 436
438 if (!idev) 437 if (!idev)
439 return; 438 return;
440 dev = idev->dev; 439 dev = idev->dev;
441 if (dev && (dev->flags & IFF_MULTICAST)) { 440 if (dev && (dev->flags & IFF_MULTICAST)) {
442 ipv6_addr_all_routers(&addr);
443
444 if (idev->cnf.forwarding) 441 if (idev->cnf.forwarding)
445 ipv6_dev_mc_inc(dev, &addr); 442 ipv6_dev_mc_inc(dev, &in6addr_linklocal_allrouters);
446 else 443 else
447 ipv6_dev_mc_dec(dev, &addr); 444 ipv6_dev_mc_dec(dev, &in6addr_linklocal_allrouters);
448 } 445 }
449 for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) { 446 for (ifa=idev->addr_list; ifa; ifa=ifa->if_next) {
450 if (ifa->flags&IFA_F_TENTATIVE) 447 if (ifa->flags&IFA_F_TENTATIVE)
@@ -541,6 +538,25 @@ ipv6_link_dev_addr(struct inet6_dev *idev, struct inet6_ifaddr *ifp)
541 *ifap = ifp; 538 *ifap = ifp;
542} 539}
543 540
541/*
542 * Hash function taken from net_alias.c
543 */
544static u8 ipv6_addr_hash(const struct in6_addr *addr)
545{
546 __u32 word;
547
548 /*
549 * We perform the hash function over the last 64 bits of the address
550 * This will include the IEEE address token on links that support it.
551 */
552
553 word = (__force u32)(addr->s6_addr32[2] ^ addr->s6_addr32[3]);
554 word ^= (word >> 16);
555 word ^= (word >> 8);
556
557 return ((word ^ (word >> 4)) & 0x0f);
558}
559
544/* On success it returns ifp with increased reference count */ 560/* On success it returns ifp with increased reference count */
545 561
546static struct inet6_ifaddr * 562static struct inet6_ifaddr *
@@ -921,7 +937,7 @@ struct ipv6_saddr_score {
921}; 937};
922 938
923struct ipv6_saddr_dst { 939struct ipv6_saddr_dst {
924 struct in6_addr *addr; 940 const struct in6_addr *addr;
925 int ifindex; 941 int ifindex;
926 int scope; 942 int scope;
927 int label; 943 int label;
@@ -1055,7 +1071,7 @@ out:
1055} 1071}
1056 1072
1057int ipv6_dev_get_saddr(struct net_device *dst_dev, 1073int ipv6_dev_get_saddr(struct net_device *dst_dev,
1058 struct in6_addr *daddr, unsigned int prefs, 1074 const struct in6_addr *daddr, unsigned int prefs,
1059 struct in6_addr *saddr) 1075 struct in6_addr *saddr)
1060{ 1076{
1061 struct ipv6_saddr_score scores[2], 1077 struct ipv6_saddr_score scores[2],
@@ -1290,7 +1306,7 @@ int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev)
1290 1306
1291EXPORT_SYMBOL(ipv6_chk_prefix); 1307EXPORT_SYMBOL(ipv6_chk_prefix);
1292 1308
1293struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, 1309struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, const struct in6_addr *addr,
1294 struct net_device *dev, int strict) 1310 struct net_device *dev, int strict)
1295{ 1311{
1296 struct inet6_ifaddr * ifp; 1312 struct inet6_ifaddr * ifp;
@@ -1475,6 +1491,29 @@ static int addrconf_ifid_infiniband(u8 *eui, struct net_device *dev)
1475 return 0; 1491 return 0;
1476} 1492}
1477 1493
1494int __ipv6_isatap_ifid(u8 *eui, __be32 addr)
1495{
1496 eui[0] = (ipv4_is_zeronet(addr) || ipv4_is_private_10(addr) ||
1497 ipv4_is_loopback(addr) || ipv4_is_linklocal_169(addr) ||
1498 ipv4_is_private_172(addr) || ipv4_is_test_192(addr) ||
1499 ipv4_is_anycast_6to4(addr) || ipv4_is_private_192(addr) ||
1500 ipv4_is_test_198(addr) || ipv4_is_multicast(addr) ||
1501 ipv4_is_lbcast(addr)) ? 0x00 : 0x02;
1502 eui[1] = 0;
1503 eui[2] = 0x5E;
1504 eui[3] = 0xFE;
1505 memcpy(eui + 4, &addr, 4);
1506 return 0;
1507}
1508EXPORT_SYMBOL(__ipv6_isatap_ifid);
1509
1510static int addrconf_ifid_sit(u8 *eui, struct net_device *dev)
1511{
1512 if (dev->priv_flags & IFF_ISATAP)
1513 return __ipv6_isatap_ifid(eui, *(__be32 *)dev->dev_addr);
1514 return -1;
1515}
1516
1478static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) 1517static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
1479{ 1518{
1480 switch (dev->type) { 1519 switch (dev->type) {
@@ -1487,8 +1526,7 @@ static int ipv6_generate_eui64(u8 *eui, struct net_device *dev)
1487 case ARPHRD_INFINIBAND: 1526 case ARPHRD_INFINIBAND:
1488 return addrconf_ifid_infiniband(eui, dev); 1527 return addrconf_ifid_infiniband(eui, dev);
1489 case ARPHRD_SIT: 1528 case ARPHRD_SIT:
1490 if (dev->priv_flags & IFF_ISATAP) 1529 return addrconf_ifid_sit(eui, dev);
1491 return ipv6_isatap_eui64(eui, *(__be32 *)dev->dev_addr);
1492 } 1530 }
1493 return -1; 1531 return -1;
1494} 1532}
@@ -2613,8 +2651,6 @@ static void addrconf_rs_timer(unsigned long data)
2613 2651
2614 spin_lock(&ifp->lock); 2652 spin_lock(&ifp->lock);
2615 if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) { 2653 if (ifp->probes++ < ifp->idev->cnf.rtr_solicits) {
2616 struct in6_addr all_routers;
2617
2618 /* The wait after the last probe can be shorter */ 2654 /* The wait after the last probe can be shorter */
2619 addrconf_mod_timer(ifp, AC_RS, 2655 addrconf_mod_timer(ifp, AC_RS,
2620 (ifp->probes == ifp->idev->cnf.rtr_solicits) ? 2656 (ifp->probes == ifp->idev->cnf.rtr_solicits) ?
@@ -2622,9 +2658,7 @@ static void addrconf_rs_timer(unsigned long data)
2622 ifp->idev->cnf.rtr_solicit_interval); 2658 ifp->idev->cnf.rtr_solicit_interval);
2623 spin_unlock(&ifp->lock); 2659 spin_unlock(&ifp->lock);
2624 2660
2625 ipv6_addr_all_routers(&all_routers); 2661 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
2626
2627 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers);
2628 } else { 2662 } else {
2629 spin_unlock(&ifp->lock); 2663 spin_unlock(&ifp->lock);
2630 /* 2664 /*
@@ -2711,7 +2745,6 @@ static void addrconf_dad_timer(unsigned long data)
2711{ 2745{
2712 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data; 2746 struct inet6_ifaddr *ifp = (struct inet6_ifaddr *) data;
2713 struct inet6_dev *idev = ifp->idev; 2747 struct inet6_dev *idev = ifp->idev;
2714 struct in6_addr unspec;
2715 struct in6_addr mcaddr; 2748 struct in6_addr mcaddr;
2716 2749
2717 read_lock_bh(&idev->lock); 2750 read_lock_bh(&idev->lock);
@@ -2740,9 +2773,8 @@ static void addrconf_dad_timer(unsigned long data)
2740 read_unlock_bh(&idev->lock); 2773 read_unlock_bh(&idev->lock);
2741 2774
2742 /* send a neighbour solicitation for our addr */ 2775 /* send a neighbour solicitation for our addr */
2743 memset(&unspec, 0, sizeof(unspec));
2744 addrconf_addr_solict_mult(&ifp->addr, &mcaddr); 2776 addrconf_addr_solict_mult(&ifp->addr, &mcaddr);
2745 ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &unspec); 2777 ndisc_send_ns(ifp->idev->dev, NULL, &ifp->addr, &mcaddr, &in6addr_any);
2746out: 2778out:
2747 in6_ifa_put(ifp); 2779 in6_ifa_put(ifp);
2748} 2780}
@@ -2765,16 +2797,12 @@ static void addrconf_dad_completed(struct inet6_ifaddr *ifp)
2765 ifp->idev->cnf.rtr_solicits > 0 && 2797 ifp->idev->cnf.rtr_solicits > 0 &&
2766 (dev->flags&IFF_LOOPBACK) == 0 && 2798 (dev->flags&IFF_LOOPBACK) == 0 &&
2767 (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) { 2799 (ipv6_addr_type(&ifp->addr) & IPV6_ADDR_LINKLOCAL)) {
2768 struct in6_addr all_routers;
2769
2770 ipv6_addr_all_routers(&all_routers);
2771
2772 /* 2800 /*
2773 * If a host as already performed a random delay 2801 * If a host as already performed a random delay
2774 * [...] as part of DAD [...] there is no need 2802 * [...] as part of DAD [...] there is no need
2775 * to delay again before sending the first RS 2803 * to delay again before sending the first RS
2776 */ 2804 */
2777 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &all_routers); 2805 ndisc_send_rs(ifp->idev->dev, &ifp->addr, &in6addr_linklocal_allrouters);
2778 2806
2779 spin_lock_bh(&ifp->lock); 2807 spin_lock_bh(&ifp->lock);
2780 ifp->probes = 1; 2808 ifp->probes = 1;
@@ -2951,7 +2979,7 @@ int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr)
2951 for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) { 2979 for (ifp = inet6_addr_lst[hash]; ifp; ifp = ifp->lst_next) {
2952 if (!net_eq(dev_net(ifp->idev->dev), net)) 2980 if (!net_eq(dev_net(ifp->idev->dev), net))
2953 continue; 2981 continue;
2954 if (ipv6_addr_cmp(&ifp->addr, addr) == 0 && 2982 if (ipv6_addr_equal(&ifp->addr, addr) &&
2955 (ifp->flags & IFA_F_HOMEADDRESS)) { 2983 (ifp->flags & IFA_F_HOMEADDRESS)) {
2956 ret = 1; 2984 ret = 1;
2957 break; 2985 break;
diff --git a/net/ipv6/fib6_rules.c b/net/ipv6/fib6_rules.c
index cac580749ebe..8d05527524e3 100644
--- a/net/ipv6/fib6_rules.c
+++ b/net/ipv6/fib6_rules.c
@@ -316,5 +316,5 @@ int __init fib6_rules_init(void)
316 316
317void fib6_rules_cleanup(void) 317void fib6_rules_cleanup(void)
318{ 318{
319 return unregister_pernet_subsys(&fib6_rules_net_ops); 319 unregister_pernet_subsys(&fib6_rules_net_ops);
320} 320}
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 09a3201e408a..4e5c8615832c 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -262,21 +262,23 @@ int ip6_mc_input(struct sk_buff *skb)
262 * is for MLD (0x0000). 262 * is for MLD (0x0000).
263 */ 263 */
264 if ((ptr[2] | ptr[3]) == 0) { 264 if ((ptr[2] | ptr[3]) == 0) {
265 deliver = 0;
266
265 if (!ipv6_ext_hdr(nexthdr)) { 267 if (!ipv6_ext_hdr(nexthdr)) {
266 /* BUG */ 268 /* BUG */
267 goto discard; 269 goto out;
268 } 270 }
269 offset = ipv6_skip_exthdr(skb, sizeof(*hdr), 271 offset = ipv6_skip_exthdr(skb, sizeof(*hdr),
270 &nexthdr); 272 &nexthdr);
271 if (offset < 0) 273 if (offset < 0)
272 goto discard; 274 goto out;
273 275
274 if (nexthdr != IPPROTO_ICMPV6) 276 if (nexthdr != IPPROTO_ICMPV6)
275 goto discard; 277 goto out;
276 278
277 if (!pskb_may_pull(skb, (skb_network_header(skb) + 279 if (!pskb_may_pull(skb, (skb_network_header(skb) +
278 offset + 1 - skb->data))) 280 offset + 1 - skb->data)))
279 goto discard; 281 goto out;
280 282
281 icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset); 283 icmp6 = (struct icmp6hdr *)(skb_network_header(skb) + offset);
282 284
@@ -285,12 +287,9 @@ int ip6_mc_input(struct sk_buff *skb)
285 case ICMPV6_MGM_REPORT: 287 case ICMPV6_MGM_REPORT:
286 case ICMPV6_MGM_REDUCTION: 288 case ICMPV6_MGM_REDUCTION:
287 case ICMPV6_MLD2_REPORT: 289 case ICMPV6_MLD2_REPORT:
290 deliver = 1;
288 break; 291 break;
289 default:
290 /* Bogus */
291 goto discard;
292 } 292 }
293 deliver = 1;
294 goto out; 293 goto out;
295 } 294 }
296 /* unknown RA - process it normally */ 295 /* unknown RA - process it normally */
@@ -308,15 +307,14 @@ int ip6_mc_input(struct sk_buff *skb)
308 ip6_mr_input(skb2); 307 ip6_mr_input(skb2);
309 } 308 }
310 } 309 }
311#endif
312out: 310out:
313 if (likely(deliver)) { 311#endif
312 if (likely(deliver))
314 ip6_input(skb); 313 ip6_input(skb);
315 return 0; 314 else {
315 /* discard */
316 kfree_skb(skb);
316 } 317 }
317discard:
318 /* discard */
319 kfree_skb(skb);
320 318
321 return 0; 319 return 0;
322} 320}
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index c0dbe549cc42..0af2e055f883 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -286,7 +286,7 @@ EXPORT_SYMBOL(ip6_xmit);
286 */ 286 */
287 287
288int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev, 288int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev,
289 struct in6_addr *saddr, struct in6_addr *daddr, 289 const struct in6_addr *saddr, const struct in6_addr *daddr,
290 int proto, int len) 290 int proto, int len)
291{ 291{
292 struct ipv6_pinfo *np = inet6_sk(sk); 292 struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index da673ef75e12..94ede696da2a 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -27,27 +27,18 @@
27#include <linux/fcntl.h> 27#include <linux/fcntl.h>
28#include <linux/stat.h> 28#include <linux/stat.h>
29#include <linux/socket.h> 29#include <linux/socket.h>
30#include <linux/in.h>
31#include <linux/inet.h> 30#include <linux/inet.h>
32#include <linux/netdevice.h> 31#include <linux/netdevice.h>
33#include <linux/inetdevice.h> 32#include <linux/inetdevice.h>
34#include <linux/igmp.h>
35#include <linux/proc_fs.h> 33#include <linux/proc_fs.h>
36#include <linux/seq_file.h> 34#include <linux/seq_file.h>
37#include <linux/mroute.h>
38#include <linux/init.h> 35#include <linux/init.h>
39#include <net/ip.h>
40#include <net/protocol.h> 36#include <net/protocol.h>
41#include <linux/skbuff.h> 37#include <linux/skbuff.h>
42#include <net/sock.h> 38#include <net/sock.h>
43#include <net/icmp.h>
44#include <net/udp.h>
45#include <net/raw.h> 39#include <net/raw.h>
46#include <net/route.h>
47#include <linux/notifier.h> 40#include <linux/notifier.h>
48#include <linux/if_arp.h> 41#include <linux/if_arp.h>
49#include <linux/netfilter_ipv4.h>
50#include <net/ipip.h>
51#include <net/checksum.h> 42#include <net/checksum.h>
52#include <net/netlink.h> 43#include <net/netlink.h>
53 44
@@ -83,7 +74,7 @@ static int mroute_do_pim;
83#define mroute_do_pim 0 74#define mroute_do_pim 0
84#endif 75#endif
85 76
86static struct mfc6_cache *mfc6_cache_array[MFC_LINES]; /* Forwarding cache */ 77static struct mfc6_cache *mfc6_cache_array[MFC6_LINES]; /* Forwarding cache */
87 78
88static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ 79static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */
89static atomic_t cache_resolve_queue_len; /* Size of unresolved */ 80static atomic_t cache_resolve_queue_len; /* Size of unresolved */
@@ -102,7 +93,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock);
102static struct kmem_cache *mrt_cachep __read_mostly; 93static struct kmem_cache *mrt_cachep __read_mostly;
103 94
104static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); 95static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache);
105static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); 96static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert);
106static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); 97static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm);
107 98
108#ifdef CONFIG_IPV6_PIMSM_V2 99#ifdef CONFIG_IPV6_PIMSM_V2
@@ -597,9 +588,9 @@ static void ip6mr_update_thresholds(struct mfc6_cache *cache, unsigned char *ttl
597{ 588{
598 int vifi; 589 int vifi;
599 590
600 cache->mfc_un.res.minvif = MAXVIFS; 591 cache->mfc_un.res.minvif = MAXMIFS;
601 cache->mfc_un.res.maxvif = 0; 592 cache->mfc_un.res.maxvif = 0;
602 memset(cache->mfc_un.res.ttls, 255, MAXVIFS); 593 memset(cache->mfc_un.res.ttls, 255, MAXMIFS);
603 594
604 for (vifi = 0; vifi < maxvif; vifi++) { 595 for (vifi = 0; vifi < maxvif; vifi++) {
605 if (MIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) { 596 if (MIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) {
@@ -700,7 +691,7 @@ static struct mfc6_cache *ip6mr_cache_alloc(void)
700 if (c == NULL) 691 if (c == NULL)
701 return NULL; 692 return NULL;
702 memset(c, 0, sizeof(*c)); 693 memset(c, 0, sizeof(*c));
703 c->mfc_un.res.minvif = MAXVIFS; 694 c->mfc_un.res.minvif = MAXMIFS;
704 return c; 695 return c;
705} 696}
706 697
@@ -753,7 +744,7 @@ static void ip6mr_cache_resolve(struct mfc6_cache *uc, struct mfc6_cache *c)
753 * Called under mrt_lock. 744 * Called under mrt_lock.
754 */ 745 */
755 746
756static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) 747static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert)
757{ 748{
758 struct sk_buff *skb; 749 struct sk_buff *skb;
759 struct mrt6msg *msg; 750 struct mrt6msg *msg;
@@ -815,7 +806,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
815 806
816 msg->im6_mbz = 0; 807 msg->im6_mbz = 0;
817 msg->im6_msgtype = assert; 808 msg->im6_msgtype = assert;
818 msg->im6_mif = vifi; 809 msg->im6_mif = mifi;
819 msg->im6_pad = 0; 810 msg->im6_pad = 0;
820 ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr); 811 ipv6_addr_copy(&msg->im6_src, &ipv6_hdr(pkt)->saddr);
821 ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr); 812 ipv6_addr_copy(&msg->im6_dst, &ipv6_hdr(pkt)->daddr);
@@ -848,7 +839,7 @@ static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert)
848 */ 839 */
849 840
850static int 841static int
851ip6mr_cache_unresolved(vifi_t vifi, struct sk_buff *skb) 842ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb)
852{ 843{
853 int err; 844 int err;
854 struct mfc6_cache *c; 845 struct mfc6_cache *c;
@@ -883,7 +874,7 @@ ip6mr_cache_unresolved(vifi_t vifi, struct sk_buff *skb)
883 /* 874 /*
884 * Reflect first query at pim6sd 875 * Reflect first query at pim6sd
885 */ 876 */
886 if ((err = ip6mr_cache_report(skb, vifi, MRT6MSG_NOCACHE)) < 0) { 877 if ((err = ip6mr_cache_report(skb, mifi, MRT6MSG_NOCACHE)) < 0) {
887 /* If the report failed throw the cache entry 878 /* If the report failed throw the cache entry
888 out - Brad Parker 879 out - Brad Parker
889 */ 880 */
@@ -992,11 +983,11 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
992{ 983{
993 int line; 984 int line;
994 struct mfc6_cache *uc, *c, **cp; 985 struct mfc6_cache *uc, *c, **cp;
995 unsigned char ttls[MAXVIFS]; 986 unsigned char ttls[MAXMIFS];
996 int i; 987 int i;
997 988
998 memset(ttls, 255, MAXVIFS); 989 memset(ttls, 255, MAXMIFS);
999 for (i = 0; i < MAXVIFS; i++) { 990 for (i = 0; i < MAXMIFS; i++) {
1000 if (IF_ISSET(i, &mfc->mf6cc_ifset)) 991 if (IF_ISSET(i, &mfc->mf6cc_ifset))
1001 ttls[i] = 1; 992 ttls[i] = 1;
1002 993
@@ -1188,7 +1179,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
1188 return -EINVAL; 1179 return -EINVAL;
1189 if (copy_from_user(&vif, optval, sizeof(vif))) 1180 if (copy_from_user(&vif, optval, sizeof(vif)))
1190 return -EFAULT; 1181 return -EFAULT;
1191 if (vif.mif6c_mifi >= MAXVIFS) 1182 if (vif.mif6c_mifi >= MAXMIFS)
1192 return -ENFILE; 1183 return -ENFILE;
1193 rtnl_lock(); 1184 rtnl_lock();
1194 ret = mif6_add(&vif, sk == mroute6_socket); 1185 ret = mif6_add(&vif, sk == mroute6_socket);
@@ -1238,7 +1229,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
1238#ifdef CONFIG_IPV6_PIMSM_V2 1229#ifdef CONFIG_IPV6_PIMSM_V2
1239 case MRT6_PIM: 1230 case MRT6_PIM:
1240 { 1231 {
1241 int v, ret; 1232 int v;
1242 if (get_user(v, (int __user *)optval)) 1233 if (get_user(v, (int __user *)optval))
1243 return -EFAULT; 1234 return -EFAULT;
1244 v = !!v; 1235 v = !!v;
diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c
index 99624109c010..2f1244dc5ebf 100644
--- a/net/ipv6/ipv6_sockglue.c
+++ b/net/ipv6/ipv6_sockglue.c
@@ -16,7 +16,6 @@
16 * 16 *
17 * FIXME: Make the setsockopt code POSIX compliant: That is 17 * FIXME: Make the setsockopt code POSIX compliant: That is
18 * 18 *
19 * o Return -EINVAL for setsockopt of short lengths
20 * o Truncate getsockopt returns 19 * o Truncate getsockopt returns
21 * o Return an optlen of the truncated length if need be 20 * o Return an optlen of the truncated length if need be
22 * 21 *
@@ -114,8 +113,13 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
114 113
115 if (optval == NULL) 114 if (optval == NULL)
116 val=0; 115 val=0;
117 else if (get_user(val, (int __user *) optval)) 116 else {
118 return -EFAULT; 117 if (optlen >= sizeof(int)) {
118 if (get_user(val, (int __user *) optval))
119 return -EFAULT;
120 } else
121 val = 0;
122 }
119 123
120 valbool = (val!=0); 124 valbool = (val!=0);
121 125
@@ -127,6 +131,8 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
127 switch (optname) { 131 switch (optname) {
128 132
129 case IPV6_ADDRFORM: 133 case IPV6_ADDRFORM:
134 if (optlen < sizeof(int))
135 goto e_inval;
130 if (val == PF_INET) { 136 if (val == PF_INET) {
131 struct ipv6_txoptions *opt; 137 struct ipv6_txoptions *opt;
132 struct sk_buff *pktopt; 138 struct sk_buff *pktopt;
@@ -159,8 +165,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
159 165
160 if (sk->sk_protocol == IPPROTO_TCP) { 166 if (sk->sk_protocol == IPPROTO_TCP) {
161 struct inet_connection_sock *icsk = inet_csk(sk); 167 struct inet_connection_sock *icsk = inet_csk(sk);
162 struct net *net = sock_net(sk);
163
164 local_bh_disable(); 168 local_bh_disable();
165 sock_prot_inuse_add(net, sk->sk_prot, -1); 169 sock_prot_inuse_add(net, sk->sk_prot, -1);
166 sock_prot_inuse_add(net, &tcp_prot, 1); 170 sock_prot_inuse_add(net, &tcp_prot, 1);
@@ -172,7 +176,6 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
172 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie); 176 tcp_sync_mss(sk, icsk->icsk_pmtu_cookie);
173 } else { 177 } else {
174 struct proto *prot = &udp_prot; 178 struct proto *prot = &udp_prot;
175 struct net *net = sock_net(sk);
176 179
177 if (sk->sk_protocol == IPPROTO_UDPLITE) 180 if (sk->sk_protocol == IPPROTO_UDPLITE)
178 prot = &udplite_prot; 181 prot = &udplite_prot;
@@ -204,63 +207,86 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
204 goto e_inval; 207 goto e_inval;
205 208
206 case IPV6_V6ONLY: 209 case IPV6_V6ONLY:
207 if (inet_sk(sk)->num) 210 if (optlen < sizeof(int) ||
211 inet_sk(sk)->num)
208 goto e_inval; 212 goto e_inval;
209 np->ipv6only = valbool; 213 np->ipv6only = valbool;
210 retv = 0; 214 retv = 0;
211 break; 215 break;
212 216
213 case IPV6_RECVPKTINFO: 217 case IPV6_RECVPKTINFO:
218 if (optlen < sizeof(int))
219 goto e_inval;
214 np->rxopt.bits.rxinfo = valbool; 220 np->rxopt.bits.rxinfo = valbool;
215 retv = 0; 221 retv = 0;
216 break; 222 break;
217 223
218 case IPV6_2292PKTINFO: 224 case IPV6_2292PKTINFO:
225 if (optlen < sizeof(int))
226 goto e_inval;
219 np->rxopt.bits.rxoinfo = valbool; 227 np->rxopt.bits.rxoinfo = valbool;
220 retv = 0; 228 retv = 0;
221 break; 229 break;
222 230
223 case IPV6_RECVHOPLIMIT: 231 case IPV6_RECVHOPLIMIT:
232 if (optlen < sizeof(int))
233 goto e_inval;
224 np->rxopt.bits.rxhlim = valbool; 234 np->rxopt.bits.rxhlim = valbool;
225 retv = 0; 235 retv = 0;
226 break; 236 break;
227 237
228 case IPV6_2292HOPLIMIT: 238 case IPV6_2292HOPLIMIT:
239 if (optlen < sizeof(int))
240 goto e_inval;
229 np->rxopt.bits.rxohlim = valbool; 241 np->rxopt.bits.rxohlim = valbool;
230 retv = 0; 242 retv = 0;
231 break; 243 break;
232 244
233 case IPV6_RECVRTHDR: 245 case IPV6_RECVRTHDR:
246 if (optlen < sizeof(int))
247 goto e_inval;
234 np->rxopt.bits.srcrt = valbool; 248 np->rxopt.bits.srcrt = valbool;
235 retv = 0; 249 retv = 0;
236 break; 250 break;
237 251
238 case IPV6_2292RTHDR: 252 case IPV6_2292RTHDR:
253 if (optlen < sizeof(int))
254 goto e_inval;
239 np->rxopt.bits.osrcrt = valbool; 255 np->rxopt.bits.osrcrt = valbool;
240 retv = 0; 256 retv = 0;
241 break; 257 break;
242 258
243 case IPV6_RECVHOPOPTS: 259 case IPV6_RECVHOPOPTS:
260 if (optlen < sizeof(int))
261 goto e_inval;
244 np->rxopt.bits.hopopts = valbool; 262 np->rxopt.bits.hopopts = valbool;
245 retv = 0; 263 retv = 0;
246 break; 264 break;
247 265
248 case IPV6_2292HOPOPTS: 266 case IPV6_2292HOPOPTS:
267 if (optlen < sizeof(int))
268 goto e_inval;
249 np->rxopt.bits.ohopopts = valbool; 269 np->rxopt.bits.ohopopts = valbool;
250 retv = 0; 270 retv = 0;
251 break; 271 break;
252 272
253 case IPV6_RECVDSTOPTS: 273 case IPV6_RECVDSTOPTS:
274 if (optlen < sizeof(int))
275 goto e_inval;
254 np->rxopt.bits.dstopts = valbool; 276 np->rxopt.bits.dstopts = valbool;
255 retv = 0; 277 retv = 0;
256 break; 278 break;
257 279
258 case IPV6_2292DSTOPTS: 280 case IPV6_2292DSTOPTS:
281 if (optlen < sizeof(int))
282 goto e_inval;
259 np->rxopt.bits.odstopts = valbool; 283 np->rxopt.bits.odstopts = valbool;
260 retv = 0; 284 retv = 0;
261 break; 285 break;
262 286
263 case IPV6_TCLASS: 287 case IPV6_TCLASS:
288 if (optlen < sizeof(int))
289 goto e_inval;
264 if (val < -1 || val > 0xff) 290 if (val < -1 || val > 0xff)
265 goto e_inval; 291 goto e_inval;
266 np->tclass = val; 292 np->tclass = val;
@@ -268,11 +294,15 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
268 break; 294 break;
269 295
270 case IPV6_RECVTCLASS: 296 case IPV6_RECVTCLASS:
297 if (optlen < sizeof(int))
298 goto e_inval;
271 np->rxopt.bits.rxtclass = valbool; 299 np->rxopt.bits.rxtclass = valbool;
272 retv = 0; 300 retv = 0;
273 break; 301 break;
274 302
275 case IPV6_FLOWINFO: 303 case IPV6_FLOWINFO:
304 if (optlen < sizeof(int))
305 goto e_inval;
276 np->rxopt.bits.rxflow = valbool; 306 np->rxopt.bits.rxflow = valbool;
277 retv = 0; 307 retv = 0;
278 break; 308 break;
@@ -291,9 +321,9 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname,
291 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW)) 321 if (optname != IPV6_RTHDR && !capable(CAP_NET_RAW))
292 break; 322 break;
293 323
294 retv = -EINVAL; 324 if (optlen < sizeof(struct ipv6_opt_hdr) ||
295 if (optlen & 0x7 || optlen > 8 * 255) 325 optlen & 0x7 || optlen > 8 * 255)
296 break; 326 goto e_inval;
297 327
298 opt = ipv6_renew_options(sk, np->opt, optname, 328 opt = ipv6_renew_options(sk, np->opt, optname,
299 (struct ipv6_opt_hdr __user *)optval, 329 (struct ipv6_opt_hdr __user *)optval,
@@ -411,6 +441,8 @@ done:
411 break; 441 break;
412 } 442 }
413 case IPV6_UNICAST_HOPS: 443 case IPV6_UNICAST_HOPS:
444 if (optlen < sizeof(int))
445 goto e_inval;
414 if (val > 255 || val < -1) 446 if (val > 255 || val < -1)
415 goto e_inval; 447 goto e_inval;
416 np->hop_limit = val; 448 np->hop_limit = val;
@@ -420,6 +452,8 @@ done:
420 case IPV6_MULTICAST_HOPS: 452 case IPV6_MULTICAST_HOPS:
421 if (sk->sk_type == SOCK_STREAM) 453 if (sk->sk_type == SOCK_STREAM)
422 goto e_inval; 454 goto e_inval;
455 if (optlen < sizeof(int))
456 goto e_inval;
423 if (val > 255 || val < -1) 457 if (val > 255 || val < -1)
424 goto e_inval; 458 goto e_inval;
425 np->mcast_hops = val; 459 np->mcast_hops = val;
@@ -427,6 +461,8 @@ done:
427 break; 461 break;
428 462
429 case IPV6_MULTICAST_LOOP: 463 case IPV6_MULTICAST_LOOP:
464 if (optlen < sizeof(int))
465 goto e_inval;
430 np->mc_loop = valbool; 466 np->mc_loop = valbool;
431 retv = 0; 467 retv = 0;
432 break; 468 break;
@@ -434,6 +470,8 @@ done:
434 case IPV6_MULTICAST_IF: 470 case IPV6_MULTICAST_IF:
435 if (sk->sk_type == SOCK_STREAM) 471 if (sk->sk_type == SOCK_STREAM)
436 goto e_inval; 472 goto e_inval;
473 if (optlen < sizeof(int))
474 goto e_inval;
437 475
438 if (val) { 476 if (val) {
439 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val) 477 if (sk->sk_bound_dev_if && sk->sk_bound_dev_if != val)
@@ -452,6 +490,9 @@ done:
452 { 490 {
453 struct ipv6_mreq mreq; 491 struct ipv6_mreq mreq;
454 492
493 if (optlen < sizeof(struct ipv6_mreq))
494 goto e_inval;
495
455 retv = -EPROTO; 496 retv = -EPROTO;
456 if (inet_sk(sk)->is_icsk) 497 if (inet_sk(sk)->is_icsk)
457 break; 498 break;
@@ -471,7 +512,7 @@ done:
471 { 512 {
472 struct ipv6_mreq mreq; 513 struct ipv6_mreq mreq;
473 514
474 if (optlen != sizeof(struct ipv6_mreq)) 515 if (optlen < sizeof(struct ipv6_mreq))
475 goto e_inval; 516 goto e_inval;
476 517
477 retv = -EFAULT; 518 retv = -EFAULT;
@@ -490,6 +531,9 @@ done:
490 struct group_req greq; 531 struct group_req greq;
491 struct sockaddr_in6 *psin6; 532 struct sockaddr_in6 *psin6;
492 533
534 if (optlen < sizeof(struct group_req))
535 goto e_inval;
536
493 retv = -EFAULT; 537 retv = -EFAULT;
494 if (copy_from_user(&greq, optval, sizeof(struct group_req))) 538 if (copy_from_user(&greq, optval, sizeof(struct group_req)))
495 break; 539 break;
@@ -514,7 +558,7 @@ done:
514 struct group_source_req greqs; 558 struct group_source_req greqs;
515 int omode, add; 559 int omode, add;
516 560
517 if (optlen != sizeof(struct group_source_req)) 561 if (optlen < sizeof(struct group_source_req))
518 goto e_inval; 562 goto e_inval;
519 if (copy_from_user(&greqs, optval, sizeof(greqs))) { 563 if (copy_from_user(&greqs, optval, sizeof(greqs))) {
520 retv = -EFAULT; 564 retv = -EFAULT;
@@ -588,27 +632,37 @@ done:
588 break; 632 break;
589 } 633 }
590 case IPV6_ROUTER_ALERT: 634 case IPV6_ROUTER_ALERT:
635 if (optlen < sizeof(int))
636 goto e_inval;
591 retv = ip6_ra_control(sk, val, NULL); 637 retv = ip6_ra_control(sk, val, NULL);
592 break; 638 break;
593 case IPV6_MTU_DISCOVER: 639 case IPV6_MTU_DISCOVER:
640 if (optlen < sizeof(int))
641 goto e_inval;
594 if (val<0 || val>3) 642 if (val<0 || val>3)
595 goto e_inval; 643 goto e_inval;
596 np->pmtudisc = val; 644 np->pmtudisc = val;
597 retv = 0; 645 retv = 0;
598 break; 646 break;
599 case IPV6_MTU: 647 case IPV6_MTU:
648 if (optlen < sizeof(int))
649 goto e_inval;
600 if (val && val < IPV6_MIN_MTU) 650 if (val && val < IPV6_MIN_MTU)
601 goto e_inval; 651 goto e_inval;
602 np->frag_size = val; 652 np->frag_size = val;
603 retv = 0; 653 retv = 0;
604 break; 654 break;
605 case IPV6_RECVERR: 655 case IPV6_RECVERR:
656 if (optlen < sizeof(int))
657 goto e_inval;
606 np->recverr = valbool; 658 np->recverr = valbool;
607 if (!val) 659 if (!val)
608 skb_queue_purge(&sk->sk_error_queue); 660 skb_queue_purge(&sk->sk_error_queue);
609 retv = 0; 661 retv = 0;
610 break; 662 break;
611 case IPV6_FLOWINFO_SEND: 663 case IPV6_FLOWINFO_SEND:
664 if (optlen < sizeof(int))
665 goto e_inval;
612 np->sndflow = valbool; 666 np->sndflow = valbool;
613 retv = 0; 667 retv = 0;
614 break; 668 break;
@@ -628,6 +682,9 @@ done:
628 unsigned int pref = 0; 682 unsigned int pref = 0;
629 unsigned int prefmask = ~0; 683 unsigned int prefmask = ~0;
630 684
685 if (optlen < sizeof(int))
686 goto e_inval;
687
631 retv = -EINVAL; 688 retv = -EINVAL;
632 689
633 /* check PUBLIC/TMP/PUBTMP_DEFAULT conflicts */ 690 /* check PUBLIC/TMP/PUBTMP_DEFAULT conflicts */
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 2e6a53f3cc38..54f91efdae58 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -127,8 +127,6 @@ static struct in6_addr mld2_all_mcr = MLD2_ALL_MCR_INIT;
127/* Big mc list lock for all the sockets */ 127/* Big mc list lock for all the sockets */
128static DEFINE_RWLOCK(ipv6_sk_mc_lock); 128static DEFINE_RWLOCK(ipv6_sk_mc_lock);
129 129
130int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr);
131
132static void igmp6_join_group(struct ifmcaddr6 *ma); 130static void igmp6_join_group(struct ifmcaddr6 *ma);
133static void igmp6_leave_group(struct ifmcaddr6 *ma); 131static void igmp6_leave_group(struct ifmcaddr6 *ma);
134static void igmp6_timer_handler(unsigned long data); 132static void igmp6_timer_handler(unsigned long data);
@@ -177,7 +175,7 @@ int sysctl_mld_max_msf __read_mostly = IPV6_MLD_MAX_MSF;
177 * socket join on multicast group 175 * socket join on multicast group
178 */ 176 */
179 177
180int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) 178int ipv6_sock_mc_join(struct sock *sk, int ifindex, const struct in6_addr *addr)
181{ 179{
182 struct net_device *dev = NULL; 180 struct net_device *dev = NULL;
183 struct ipv6_mc_socklist *mc_lst; 181 struct ipv6_mc_socklist *mc_lst;
@@ -252,7 +250,7 @@ int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr)
252/* 250/*
253 * socket leave on multicast group 251 * socket leave on multicast group
254 */ 252 */
255int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) 253int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
256{ 254{
257 struct ipv6_pinfo *np = inet6_sk(sk); 255 struct ipv6_pinfo *np = inet6_sk(sk);
258 struct ipv6_mc_socklist *mc_lst, **lnk; 256 struct ipv6_mc_socklist *mc_lst, **lnk;
@@ -664,8 +662,8 @@ done:
664 return err; 662 return err;
665} 663}
666 664
667int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, 665int inet6_mc_check(struct sock *sk, const struct in6_addr *mc_addr,
668 struct in6_addr *src_addr) 666 const struct in6_addr *src_addr)
669{ 667{
670 struct ipv6_pinfo *np = inet6_sk(sk); 668 struct ipv6_pinfo *np = inet6_sk(sk);
671 struct ipv6_mc_socklist *mc; 669 struct ipv6_mc_socklist *mc;
@@ -871,7 +869,7 @@ static void mld_clear_delrec(struct inet6_dev *idev)
871/* 869/*
872 * device multicast group inc (add if not found) 870 * device multicast group inc (add if not found)
873 */ 871 */
874int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr) 872int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr)
875{ 873{
876 struct ifmcaddr6 *mc; 874 struct ifmcaddr6 *mc;
877 struct inet6_dev *idev; 875 struct inet6_dev *idev;
@@ -942,7 +940,7 @@ int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr)
942/* 940/*
943 * device multicast group del 941 * device multicast group del
944 */ 942 */
945int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) 943int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
946{ 944{
947 struct ifmcaddr6 *ma, **map; 945 struct ifmcaddr6 *ma, **map;
948 946
@@ -967,7 +965,7 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr)
967 return -ENOENT; 965 return -ENOENT;
968} 966}
969 967
970int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) 968int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr)
971{ 969{
972 struct inet6_dev *idev = in6_dev_get(dev); 970 struct inet6_dev *idev = in6_dev_get(dev);
973 int err; 971 int err;
@@ -1012,8 +1010,8 @@ int ipv6_is_mld(struct sk_buff *skb, int nexthdr)
1012/* 1010/*
1013 * check if the interface/address pair is valid 1011 * check if the interface/address pair is valid
1014 */ 1012 */
1015int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, 1013int ipv6_chk_mcast_addr(struct net_device *dev, const struct in6_addr *group,
1016 struct in6_addr *src_addr) 1014 const struct in6_addr *src_addr)
1017{ 1015{
1018 struct inet6_dev *idev; 1016 struct inet6_dev *idev;
1019 struct ifmcaddr6 *mc; 1017 struct ifmcaddr6 *mc;
@@ -1406,6 +1404,7 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1406 struct sk_buff *skb; 1404 struct sk_buff *skb;
1407 struct mld2_report *pmr; 1405 struct mld2_report *pmr;
1408 struct in6_addr addr_buf; 1406 struct in6_addr addr_buf;
1407 const struct in6_addr *saddr;
1409 int err; 1408 int err;
1410 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1409 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1411 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1410 IPV6_TLV_ROUTERALERT, 2, 0, 0,
@@ -1424,10 +1423,11 @@ static struct sk_buff *mld_newpack(struct net_device *dev, int size)
1424 * use unspecified address as the source address 1423 * use unspecified address as the source address
1425 * when a valid link-local address is not available. 1424 * when a valid link-local address is not available.
1426 */ 1425 */
1427 memset(&addr_buf, 0, sizeof(addr_buf)); 1426 saddr = &in6addr_any;
1428 } 1427 } else
1428 saddr = &addr_buf;
1429 1429
1430 ip6_nd_hdr(sk, skb, dev, &addr_buf, &mld2_all_mcr, NEXTHDR_HOP, 0); 1430 ip6_nd_hdr(sk, skb, dev, saddr, &mld2_all_mcr, NEXTHDR_HOP, 0);
1431 1431
1432 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); 1432 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1433 1433
@@ -1768,10 +1768,9 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1768 struct inet6_dev *idev; 1768 struct inet6_dev *idev;
1769 struct sk_buff *skb; 1769 struct sk_buff *skb;
1770 struct icmp6hdr *hdr; 1770 struct icmp6hdr *hdr;
1771 struct in6_addr *snd_addr; 1771 const struct in6_addr *snd_addr, *saddr;
1772 struct in6_addr *addrp; 1772 struct in6_addr *addrp;
1773 struct in6_addr addr_buf; 1773 struct in6_addr addr_buf;
1774 struct in6_addr all_routers;
1775 int err, len, payload_len, full_len; 1774 int err, len, payload_len, full_len;
1776 u8 ra[8] = { IPPROTO_ICMPV6, 0, 1775 u8 ra[8] = { IPPROTO_ICMPV6, 0,
1777 IPV6_TLV_ROUTERALERT, 2, 0, 0, 1776 IPV6_TLV_ROUTERALERT, 2, 0, 0,
@@ -1782,11 +1781,10 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1782 IP6_INC_STATS(__in6_dev_get(dev), 1781 IP6_INC_STATS(__in6_dev_get(dev),
1783 IPSTATS_MIB_OUTREQUESTS); 1782 IPSTATS_MIB_OUTREQUESTS);
1784 rcu_read_unlock(); 1783 rcu_read_unlock();
1785 snd_addr = addr; 1784 if (type == ICMPV6_MGM_REDUCTION)
1786 if (type == ICMPV6_MGM_REDUCTION) { 1785 snd_addr = &in6addr_linklocal_allrouters;
1787 snd_addr = &all_routers; 1786 else
1788 ipv6_addr_all_routers(&all_routers); 1787 snd_addr = addr;
1789 }
1790 1788
1791 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr); 1789 len = sizeof(struct icmp6hdr) + sizeof(struct in6_addr);
1792 payload_len = len + sizeof(ra); 1790 payload_len = len + sizeof(ra);
@@ -1809,10 +1807,11 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1809 * use unspecified address as the source address 1807 * use unspecified address as the source address
1810 * when a valid link-local address is not available. 1808 * when a valid link-local address is not available.
1811 */ 1809 */
1812 memset(&addr_buf, 0, sizeof(addr_buf)); 1810 saddr = &in6addr_any;
1813 } 1811 } else
1812 saddr = &addr_buf;
1814 1813
1815 ip6_nd_hdr(sk, skb, dev, &addr_buf, snd_addr, NEXTHDR_HOP, payload_len); 1814 ip6_nd_hdr(sk, skb, dev, saddr, snd_addr, NEXTHDR_HOP, payload_len);
1816 1815
1817 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra)); 1816 memcpy(skb_put(skb, sizeof(ra)), ra, sizeof(ra));
1818 1817
@@ -1823,7 +1822,7 @@ static void igmp6_send(struct in6_addr *addr, struct net_device *dev, int type)
1823 addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr)); 1822 addrp = (struct in6_addr *) skb_put(skb, sizeof(struct in6_addr));
1824 ipv6_addr_copy(addrp, addr); 1823 ipv6_addr_copy(addrp, addr);
1825 1824
1826 hdr->icmp6_cksum = csum_ipv6_magic(&addr_buf, snd_addr, len, 1825 hdr->icmp6_cksum = csum_ipv6_magic(saddr, snd_addr, len,
1827 IPPROTO_ICMPV6, 1826 IPPROTO_ICMPV6,
1828 csum_partial((__u8 *) hdr, len, 0)); 1827 csum_partial((__u8 *) hdr, len, 0));
1829 1828
@@ -2311,24 +2310,19 @@ void ipv6_mc_init_dev(struct inet6_dev *idev)
2311void ipv6_mc_destroy_dev(struct inet6_dev *idev) 2310void ipv6_mc_destroy_dev(struct inet6_dev *idev)
2312{ 2311{
2313 struct ifmcaddr6 *i; 2312 struct ifmcaddr6 *i;
2314 struct in6_addr maddr;
2315 2313
2316 /* Deactivate timers */ 2314 /* Deactivate timers */
2317 ipv6_mc_down(idev); 2315 ipv6_mc_down(idev);
2318 2316
2319 /* Delete all-nodes address. */ 2317 /* Delete all-nodes address. */
2320 ipv6_addr_all_nodes(&maddr);
2321
2322 /* We cannot call ipv6_dev_mc_dec() directly, our caller in 2318 /* We cannot call ipv6_dev_mc_dec() directly, our caller in
2323 * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will 2319 * addrconf.c has NULL'd out dev->ip6_ptr so in6_dev_get() will
2324 * fail. 2320 * fail.
2325 */ 2321 */
2326 __ipv6_dev_mc_dec(idev, &maddr); 2322 __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allnodes);
2327 2323
2328 if (idev->cnf.forwarding) { 2324 if (idev->cnf.forwarding)
2329 ipv6_addr_all_routers(&maddr); 2325 __ipv6_dev_mc_dec(idev, &in6addr_linklocal_allrouters);
2330 __ipv6_dev_mc_dec(idev, &maddr);
2331 }
2332 2326
2333 write_lock_bh(&idev->lock); 2327 write_lock_bh(&idev->lock);
2334 while ((i = idev->mc_list) != NULL) { 2328 while ((i = idev->mc_list) != NULL) {
diff --git a/net/ipv6/mip6.c b/net/ipv6/mip6.c
index 42403c626c27..ad1cc5bbf977 100644
--- a/net/ipv6/mip6.c
+++ b/net/ipv6/mip6.c
@@ -44,9 +44,9 @@ static inline void *mip6_padn(__u8 *data, __u8 padlen)
44 if (!data) 44 if (!data)
45 return NULL; 45 return NULL;
46 if (padlen == 1) { 46 if (padlen == 1) {
47 data[0] = MIP6_OPT_PAD_1; 47 data[0] = IPV6_TLV_PAD0;
48 } else if (padlen > 1) { 48 } else if (padlen > 1) {
49 data[0] = MIP6_OPT_PAD_N; 49 data[0] = IPV6_TLV_PADN;
50 data[1] = padlen - 2; 50 data[1] = padlen - 2;
51 if (padlen > 2) 51 if (padlen > 2)
52 memset(data+2, 0, data[1]); 52 memset(data+2, 0, data[1]);
diff --git a/net/ipv6/ndisc.c b/net/ipv6/ndisc.c
index b3295d82fece..2c74885f8355 100644
--- a/net/ipv6/ndisc.c
+++ b/net/ipv6/ndisc.c
@@ -442,8 +442,9 @@ static void pndisc_destructor(struct pneigh_entry *n)
442 */ 442 */
443static void __ndisc_send(struct net_device *dev, 443static void __ndisc_send(struct net_device *dev,
444 struct neighbour *neigh, 444 struct neighbour *neigh,
445 struct in6_addr *daddr, struct in6_addr *saddr, 445 const struct in6_addr *daddr,
446 struct icmp6hdr *icmp6h, struct in6_addr *target, 446 const struct in6_addr *saddr,
447 struct icmp6hdr *icmp6h, const struct in6_addr *target,
447 int llinfo) 448 int llinfo)
448{ 449{
449 struct flowi fl; 450 struct flowi fl;
@@ -529,12 +530,13 @@ static void __ndisc_send(struct net_device *dev,
529} 530}
530 531
531static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, 532static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
532 struct in6_addr *daddr, struct in6_addr *solicited_addr, 533 const struct in6_addr *daddr,
533 int router, int solicited, int override, int inc_opt) 534 const struct in6_addr *solicited_addr,
535 int router, int solicited, int override, int inc_opt)
534{ 536{
535 struct in6_addr tmpaddr; 537 struct in6_addr tmpaddr;
536 struct inet6_ifaddr *ifp; 538 struct inet6_ifaddr *ifp;
537 struct in6_addr *src_addr; 539 const struct in6_addr *src_addr;
538 struct icmp6hdr icmp6h = { 540 struct icmp6hdr icmp6h = {
539 .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT, 541 .icmp6_type = NDISC_NEIGHBOUR_ADVERTISEMENT,
540 }; 542 };
@@ -564,8 +566,8 @@ static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh,
564} 566}
565 567
566void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, 568void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
567 struct in6_addr *solicit, 569 const struct in6_addr *solicit,
568 struct in6_addr *daddr, struct in6_addr *saddr) 570 const struct in6_addr *daddr, const struct in6_addr *saddr)
569{ 571{
570 struct in6_addr addr_buf; 572 struct in6_addr addr_buf;
571 struct icmp6hdr icmp6h = { 573 struct icmp6hdr icmp6h = {
@@ -584,8 +586,8 @@ void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh,
584 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0); 586 !ipv6_addr_any(saddr) ? ND_OPT_SOURCE_LL_ADDR : 0);
585} 587}
586 588
587void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, 589void ndisc_send_rs(struct net_device *dev, const struct in6_addr *saddr,
588 struct in6_addr *daddr) 590 const struct in6_addr *daddr)
589{ 591{
590 struct icmp6hdr icmp6h = { 592 struct icmp6hdr icmp6h = {
591 .icmp6_type = NDISC_ROUTER_SOLICITATION, 593 .icmp6_type = NDISC_ROUTER_SOLICITATION,
@@ -816,10 +818,7 @@ static void ndisc_recv_ns(struct sk_buff *skb)
816 is_router = !!idev->cnf.forwarding; 818 is_router = !!idev->cnf.forwarding;
817 819
818 if (dad) { 820 if (dad) {
819 struct in6_addr maddr; 821 ndisc_send_na(dev, NULL, &in6addr_linklocal_allnodes, &msg->target,
820
821 ipv6_addr_all_nodes(&maddr);
822 ndisc_send_na(dev, NULL, &maddr, &msg->target,
823 is_router, 0, (ifp != NULL), 1); 822 is_router, 0, (ifp != NULL), 1);
824 goto out; 823 goto out;
825 } 824 }
@@ -1447,7 +1446,7 @@ static void ndisc_redirect_rcv(struct sk_buff *skb)
1447} 1446}
1448 1447
1449void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, 1448void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh,
1450 struct in6_addr *target) 1449 const struct in6_addr *target)
1451{ 1450{
1452 struct net_device *dev = skb->dev; 1451 struct net_device *dev = skb->dev;
1453 struct net *net = dev_net(dev); 1452 struct net *net = dev_net(dev);
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 088b80b4ce74..6193b124cbc7 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -357,8 +357,10 @@ void raw6_icmp_error(struct sk_buff *skb, int nexthdr,
357 read_lock(&raw_v6_hashinfo.lock); 357 read_lock(&raw_v6_hashinfo.lock);
358 sk = sk_head(&raw_v6_hashinfo.ht[hash]); 358 sk = sk_head(&raw_v6_hashinfo.ht[hash]);
359 if (sk != NULL) { 359 if (sk != NULL) {
360 saddr = &ipv6_hdr(skb)->saddr; 360 /* Note: ipv6_hdr(skb) != skb->data */
361 daddr = &ipv6_hdr(skb)->daddr; 361 struct ipv6hdr *ip6h = (struct ipv6hdr *)skb->data;
362 saddr = &ip6h->saddr;
363 daddr = &ip6h->daddr;
362 net = dev_net(skb->dev); 364 net = dev_net(skb->dev);
363 365
364 while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr, 366 while ((sk = __raw_v6_lookup(net, sk, nexthdr, saddr, daddr,
@@ -805,15 +807,6 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
805 fl.fl6_flowlabel = np->flow_label; 807 fl.fl6_flowlabel = np->flow_label;
806 } 808 }
807 809
808 if (ipv6_addr_any(daddr)) {
809 /*
810 * unspecified destination address
811 * treated as error... is this correct ?
812 */
813 fl6_sock_release(flowlabel);
814 return(-EINVAL);
815 }
816
817 if (fl.oif == 0) 810 if (fl.oif == 0)
818 fl.oif = sk->sk_bound_dev_if; 811 fl.oif = sk->sk_bound_dev_if;
819 812
@@ -846,7 +839,10 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
846 if (err) 839 if (err)
847 goto out; 840 goto out;
848 841
849 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) */
850 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))
851 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 847 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
852 848
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index 269b76093288..6293cb91ed1d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -556,8 +556,8 @@ out:
556 556
557} 557}
558 558
559struct rt6_info *rt6_lookup(struct net *net, struct in6_addr *daddr, 559struct rt6_info *rt6_lookup(struct net *net, const struct in6_addr *daddr,
560 struct in6_addr *saddr, int oif, int strict) 560 const struct in6_addr *saddr, int oif, int strict)
561{ 561{
562 struct flowi fl = { 562 struct flowi fl = {
563 .oif = oif, 563 .oif = oif,
@@ -925,7 +925,7 @@ static DEFINE_SPINLOCK(icmp6_dst_lock);
925 925
926struct dst_entry *icmp6_dst_alloc(struct net_device *dev, 926struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
927 struct neighbour *neigh, 927 struct neighbour *neigh,
928 struct in6_addr *addr) 928 const struct in6_addr *addr)
929{ 929{
930 struct rt6_info *rt; 930 struct rt6_info *rt;
931 struct inet6_dev *idev = in6_dev_get(dev); 931 struct inet6_dev *idev = in6_dev_get(dev);
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index cc16fe07bbff..91e46fbe6ce2 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -379,7 +379,7 @@ static void ipip6_tunnel_uninit(struct net_device *dev)
379 dev_put(dev); 379 dev_put(dev);
380 } else { 380 } else {
381 ipip6_tunnel_unlink(netdev_priv(dev)); 381 ipip6_tunnel_unlink(netdev_priv(dev));
382 ipip6_tunnel_del_prl(netdev_priv(dev), 0); 382 ipip6_tunnel_del_prl(netdev_priv(dev), NULL);
383 dev_put(dev); 383 dev_put(dev);
384 } 384 }
385} 385}
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 8ebf6de29562..80eab71e77ff 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -543,7 +543,7 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
543 return NULL; 543 return NULL;
544 544
545 for (i = 0; i < tp->md5sig_info->entries6; i++) { 545 for (i = 0; i < tp->md5sig_info->entries6; i++) {
546 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, addr) == 0) 546 if (ipv6_addr_equal(&tp->md5sig_info->keys6[i].addr, addr))
547 return &tp->md5sig_info->keys6[i].base; 547 return &tp->md5sig_info->keys6[i].base;
548 } 548 }
549 return NULL; 549 return NULL;
@@ -632,7 +632,7 @@ static int tcp_v6_md5_do_del(struct sock *sk, struct in6_addr *peer)
632 int i; 632 int i;
633 633
634 for (i = 0; i < tp->md5sig_info->entries6; i++) { 634 for (i = 0; i < tp->md5sig_info->entries6; i++) {
635 if (ipv6_addr_cmp(&tp->md5sig_info->keys6[i].addr, peer) == 0) { 635 if (ipv6_addr_equal(&tp->md5sig_info->keys6[i].addr, peer)) {
636 /* Free the key */ 636 /* Free the key */
637 kfree(tp->md5sig_info->keys6[i].base.key); 637 kfree(tp->md5sig_info->keys6[i].base.key);
638 tp->md5sig_info->entries6--; 638 tp->md5sig_info->entries6--;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 30ef7dc5d403..1fd784f3e2ec 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -752,7 +752,10 @@ do_udp_sendmsg:
752 opt = ipv6_fixup_options(&opt_space, opt); 752 opt = ipv6_fixup_options(&opt_space, opt);
753 753
754 fl.proto = sk->sk_protocol; 754 fl.proto = sk->sk_protocol;
755 ipv6_addr_copy(&fl.fl6_dst, daddr); 755 if (!ipv6_addr_any(daddr))
756 ipv6_addr_copy(&fl.fl6_dst, daddr);
757 else
758 fl.fl6_dst.s6_addr[15] = 0x1; /* :: means loopback (BSD'ism) */
756 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr)) 759 if (ipv6_addr_any(&fl.fl6_src) && !ipv6_addr_any(&np->saddr))
757 ipv6_addr_copy(&fl.fl6_src, &np->saddr); 760 ipv6_addr_copy(&fl.fl6_src, &np->saddr);
758 fl.fl_ip_sport = inet->sport; 761 fl.fl_ip_sport = inet->sport;