diff options
-rw-r--r-- | include/linux/in6.h | 8 | ||||
-rw-r--r-- | include/net/addrconf.h | 87 | ||||
-rw-r--r-- | include/net/ip6_route.h | 6 | ||||
-rw-r--r-- | include/net/ipv6.h | 26 | ||||
-rw-r--r-- | include/net/mip6.h | 3 | ||||
-rw-r--r-- | include/net/ndisc.h | 14 | ||||
-rw-r--r-- | net/ipv6/addrconf.c | 82 | ||||
-rw-r--r-- | net/ipv6/fib6_rules.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6_input.c | 26 | ||||
-rw-r--r-- | net/ipv6/ip6_output.c | 2 | ||||
-rw-r--r-- | net/ipv6/ip6mr.c | 37 | ||||
-rw-r--r-- | net/ipv6/ipv6_sockglue.c | 81 | ||||
-rw-r--r-- | net/ipv6/mcast.c | 60 | ||||
-rw-r--r-- | net/ipv6/mip6.c | 4 | ||||
-rw-r--r-- | net/ipv6/ndisc.c | 27 | ||||
-rw-r--r-- | net/ipv6/raw.c | 20 | ||||
-rw-r--r-- | net/ipv6/route.c | 6 | ||||
-rw-r--r-- | net/ipv6/sit.c | 2 | ||||
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 4 | ||||
-rw-r--r-- | net/ipv6/udp.c | 5 |
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 } } } |
49 | extern const struct in6_addr in6addr_loopback; | 49 | extern 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__ | ||
52 | extern 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 } } } | ||
55 | extern 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 | ||
52 | struct sockaddr_in6 { | 60 | struct 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 | ||
78 | extern struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, | 78 | extern 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 | ||
83 | extern int ipv6_dev_get_saddr(struct net_device *dev, | 83 | extern 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); |
87 | extern int ipv6_get_lladdr(struct net_device *dev, | 87 | extern 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 | */ |
108 | extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, | 108 | extern int ipv6_sock_mc_join(struct sock *sk, int ifindex, |
109 | struct in6_addr *addr); | 109 | const struct in6_addr *addr); |
110 | extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, | 110 | extern int ipv6_sock_mc_drop(struct sock *sk, int ifindex, |
111 | struct in6_addr *addr); | 111 | const struct in6_addr *addr); |
112 | extern void ipv6_sock_mc_close(struct sock *sk); | 112 | extern void ipv6_sock_mc_close(struct sock *sk); |
113 | extern int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, | 113 | extern 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 | ||
116 | extern int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr); | 117 | extern int ipv6_dev_mc_inc(struct net_device *dev, const struct in6_addr *addr); |
117 | extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); | 118 | extern int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr); |
118 | extern int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr); | 119 | extern int ipv6_dev_mc_dec(struct net_device *dev, const struct in6_addr *addr); |
119 | extern void ipv6_mc_up(struct inet6_dev *idev); | 120 | extern void ipv6_mc_up(struct inet6_dev *idev); |
120 | extern void ipv6_mc_down(struct inet6_dev *idev); | 121 | extern void ipv6_mc_down(struct inet6_dev *idev); |
121 | extern void ipv6_mc_init_dev(struct inet6_dev *idev); | 122 | extern void ipv6_mc_init_dev(struct inet6_dev *idev); |
122 | extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); | 123 | extern void ipv6_mc_destroy_dev(struct inet6_dev *idev); |
123 | extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); | 124 | extern void addrconf_dad_failure(struct inet6_ifaddr *ifp); |
124 | 125 | ||
125 | extern int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, | 126 | extern 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); | ||
127 | extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); | 129 | extern int ipv6_is_mld(struct sk_buff *skb, int nexthdr); |
128 | 130 | ||
129 | extern void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len); | 131 | extern 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 | |||
196 | static __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 | |||
226 | static inline void ipv6_addr_all_nodes(struct in6_addr *addr) | ||
227 | { | ||
228 | ipv6_addr_set(addr, htonl(0xFF020000), 0, 0, htonl(0x1)); | ||
229 | } | ||
230 | |||
231 | static inline void ipv6_addr_all_routers(struct in6_addr *addr) | ||
232 | { | ||
233 | ipv6_addr_set(addr, htonl(0xFF020000), 0, 0, htonl(0x2)); | ||
234 | } | ||
235 | |||
236 | static inline int ipv6_addr_is_multicast(const struct in6_addr *addr) | 208 | static 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 | ||
241 | static inline int ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr) | 213 | static 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 | ||
249 | static inline int ipv6_addr_is_ll_all_routers(const struct in6_addr *addr) | 220 | static 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 | ||
257 | static inline int ipv6_isatap_eui64(u8 *eui, __be32 addr) | 227 | extern 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 | ||
272 | static inline int ipv6_addr_is_isatap(const struct in6_addr *addr) | 229 | static 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 *); | |||
61 | extern int ip6_del_rt(struct rt6_info *); | 61 | extern int ip6_del_rt(struct rt6_info *); |
62 | 62 | ||
63 | extern struct rt6_info *rt6_lookup(struct net *net, | 63 | extern 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 | ||
68 | extern struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | 68 | extern 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); |
71 | extern int icmp6_dst_gc(int *more); | 71 | extern int icmp6_dst_gc(int *more); |
72 | 72 | ||
73 | extern void fib6_force_start_gc(struct net *net); | 73 | extern 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 | |||
280 | ipv6_masked_addr_cmp(const struct in6_addr *a1, const struct in6_addr *m, | 280 | ipv6_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 | ||
291 | static inline void ipv6_addr_copy(struct in6_addr *a1, const struct in6_addr *a2) | 289 | static 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, | |||
320 | static inline int ipv6_addr_equal(const struct in6_addr *a1, | 318 | static 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 | ||
329 | static inline int __ipv6_prefix_equal(const __be32 *a1, const __be32 *a2, | 327 | static 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 | ||
372 | static inline int ipv6_addr_v4mapped(const struct in6_addr *a) | 370 | static 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, | |||
453 | extern int ip6_nd_hdr(struct sock *sk, | 451 | extern 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 | ||
460 | extern int ip6_find_1stfragopt(struct sk_buff *skb, u8 **nexthdr); | 458 | extern 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 | ||
95 | extern void ndisc_send_ns(struct net_device *dev, | 95 | extern 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 | ||
101 | extern void ndisc_send_rs(struct net_device *dev, | 101 | extern 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 | ||
105 | extern void ndisc_send_redirect(struct sk_buff *skb, | 105 | extern 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 | ||
109 | extern int ndisc_mc_map(struct in6_addr *addr, char *buf, struct net_device *dev, int dir); | 109 | extern 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, | |||
134 | extern void inet6_ifinfo_notify(int event, | 134 | extern void inet6_ifinfo_notify(int event, |
135 | struct inet6_dev *idev); | 135 | struct inet6_dev *idev); |
136 | 136 | ||
137 | static inline struct neighbour * ndisc_get_neigh(struct net_device *dev, struct in6_addr *addr) | 137 | static 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 */ |
223 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; | 223 | const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; |
224 | const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; | 224 | const struct in6_addr in6addr_loopback = IN6ADDR_LOOPBACK_INIT; |
225 | const struct in6_addr in6addr_linklocal_allnodes = IN6ADDR_LINKLOCAL_ALLNODES_INIT; | ||
226 | const 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 */ |
227 | static inline int addrconf_qdisc_ok(struct net_device *dev) | 229 | static inline int addrconf_qdisc_ok(struct net_device *dev) |
@@ -321,7 +323,6 @@ EXPORT_SYMBOL(in6_dev_finish_destroy); | |||
321 | static struct inet6_dev * ipv6_add_dev(struct net_device *dev) | 323 | static 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 | */ | ||
544 | static 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 | ||
546 | static struct inet6_ifaddr * | 562 | static struct inet6_ifaddr * |
@@ -921,7 +937,7 @@ struct ipv6_saddr_score { | |||
921 | }; | 937 | }; |
922 | 938 | ||
923 | struct ipv6_saddr_dst { | 939 | struct 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 | ||
1057 | int ipv6_dev_get_saddr(struct net_device *dst_dev, | 1073 | int 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 | ||
1291 | EXPORT_SYMBOL(ipv6_chk_prefix); | 1307 | EXPORT_SYMBOL(ipv6_chk_prefix); |
1292 | 1308 | ||
1293 | struct inet6_ifaddr *ipv6_get_ifaddr(struct net *net, struct in6_addr *addr, | 1309 | struct 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 | ||
1494 | int __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 | } | ||
1508 | EXPORT_SYMBOL(__ipv6_isatap_ifid); | ||
1509 | |||
1510 | static 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 | |||
1478 | static int ipv6_generate_eui64(u8 *eui, struct net_device *dev) | 1517 | static 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); |
2746 | out: | 2778 | out: |
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 | ||
317 | void fib6_rules_cleanup(void) | 317 | void 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 | ||
312 | out: | 310 | out: |
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 | } |
317 | discard: | ||
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 | ||
288 | int ip6_nd_hdr(struct sock *sk, struct sk_buff *skb, struct net_device *dev, | 288 | int 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 | ||
86 | static struct mfc6_cache *mfc6_cache_array[MFC_LINES]; /* Forwarding cache */ | 77 | static struct mfc6_cache *mfc6_cache_array[MFC6_LINES]; /* Forwarding cache */ |
87 | 78 | ||
88 | static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ | 79 | static struct mfc6_cache *mfc_unres_queue; /* Queue of unresolved entries */ |
89 | static atomic_t cache_resolve_queue_len; /* Size of unresolved */ | 80 | static atomic_t cache_resolve_queue_len; /* Size of unresolved */ |
@@ -102,7 +93,7 @@ static DEFINE_SPINLOCK(mfc_unres_lock); | |||
102 | static struct kmem_cache *mrt_cachep __read_mostly; | 93 | static struct kmem_cache *mrt_cachep __read_mostly; |
103 | 94 | ||
104 | static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); | 95 | static int ip6_mr_forward(struct sk_buff *skb, struct mfc6_cache *cache); |
105 | static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert); | 96 | static int ip6mr_cache_report(struct sk_buff *pkt, mifi_t mifi, int assert); |
106 | static int ip6mr_fill_mroute(struct sk_buff *skb, struct mfc6_cache *c, struct rtmsg *rtm); | 97 | static 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 | ||
756 | static int ip6mr_cache_report(struct sk_buff *pkt, vifi_t vifi, int assert) | 747 | static 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 | ||
850 | static int | 841 | static int |
851 | ip6mr_cache_unresolved(vifi_t vifi, struct sk_buff *skb) | 842 | ip6mr_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 */ |
128 | static DEFINE_RWLOCK(ipv6_sk_mc_lock); | 128 | static DEFINE_RWLOCK(ipv6_sk_mc_lock); |
129 | 129 | ||
130 | int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr); | ||
131 | |||
132 | static void igmp6_join_group(struct ifmcaddr6 *ma); | 130 | static void igmp6_join_group(struct ifmcaddr6 *ma); |
133 | static void igmp6_leave_group(struct ifmcaddr6 *ma); | 131 | static void igmp6_leave_group(struct ifmcaddr6 *ma); |
134 | static void igmp6_timer_handler(unsigned long data); | 132 | static 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 | ||
180 | int ipv6_sock_mc_join(struct sock *sk, int ifindex, struct in6_addr *addr) | 178 | int 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 | */ |
255 | int ipv6_sock_mc_drop(struct sock *sk, int ifindex, struct in6_addr *addr) | 253 | int 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 | ||
667 | int inet6_mc_check(struct sock *sk, struct in6_addr *mc_addr, | 665 | int 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 | */ |
874 | int ipv6_dev_mc_inc(struct net_device *dev, struct in6_addr *addr) | 872 | int 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 | */ |
945 | int __ipv6_dev_mc_dec(struct inet6_dev *idev, struct in6_addr *addr) | 943 | int __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 | ||
970 | int ipv6_dev_mc_dec(struct net_device *dev, struct in6_addr *addr) | 968 | int 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 | */ |
1015 | int ipv6_chk_mcast_addr(struct net_device *dev, struct in6_addr *group, | 1013 | int 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) | |||
2311 | void ipv6_mc_destroy_dev(struct inet6_dev *idev) | 2310 | void 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 | */ |
443 | static void __ndisc_send(struct net_device *dev, | 443 | static 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 | ||
531 | static void ndisc_send_na(struct net_device *dev, struct neighbour *neigh, | 532 | static 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 | ||
566 | void ndisc_send_ns(struct net_device *dev, struct neighbour *neigh, | 568 | void 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 | ||
587 | void ndisc_send_rs(struct net_device *dev, struct in6_addr *saddr, | 589 | void 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 | ||
1449 | void ndisc_send_redirect(struct sk_buff *skb, struct neighbour *neigh, | 1448 | void 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 | ||
559 | struct rt6_info *rt6_lookup(struct net *net, struct in6_addr *daddr, | 559 | struct 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 | ||
926 | struct dst_entry *icmp6_dst_alloc(struct net_device *dev, | 926 | struct 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; |