aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-06-12 01:33:59 -0400
committerDavid S. Miller <davem@davemloft.net>2008-06-12 01:33:59 -0400
commite6e30add6bd8115af108de2a13ec82d997a55777 (patch)
tree558b4d1c3ac369805aa9c57abca710bdf52aff75 /net/ipv6
parentd4c3c0753594adaafbcb77a086f013f1d847b3f0 (diff)
parent9501f9722922f2e80e1f9dc6682311d65c2b5690 (diff)
Merge branch 'net-next-2.6-misc-20080612a' of git://git.linux-ipv6.org/gitroot/yoshfuji/linux-2.6-next
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c22
-rw-r--r--net/ipv6/addrlabel.c106
-rw-r--r--net/ipv6/ip6mr.c2
-rw-r--r--net/ipv6/mcast.c1
-rw-r--r--net/ipv6/tcp_ipv6.c136
5 files changed, 116 insertions, 151 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index deb38bf03376..9be6be3a7ff3 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -229,6 +229,12 @@ static inline int addrconf_qdisc_ok(struct net_device *dev)
229 return (dev->qdisc != &noop_qdisc); 229 return (dev->qdisc != &noop_qdisc);
230} 230}
231 231
232/* Check if a route is valid prefix route */
233static inline int addrconf_is_prefix_route(const struct rt6_info *rt)
234{
235 return ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0);
236}
237
232static void addrconf_del_timer(struct inet6_ifaddr *ifp) 238static void addrconf_del_timer(struct inet6_ifaddr *ifp)
233{ 239{
234 if (del_timer(&ifp->timer)) 240 if (del_timer(&ifp->timer))
@@ -775,7 +781,7 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)
775 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len); 781 ipv6_addr_prefix(&prefix, &ifp->addr, ifp->prefix_len);
776 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1); 782 rt = rt6_lookup(net, &prefix, NULL, ifp->idev->dev->ifindex, 1);
777 783
778 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 784 if (rt && addrconf_is_prefix_route(rt)) {
779 if (onlink == 0) { 785 if (onlink == 0) {
780 ip6_del_rt(rt); 786 ip6_del_rt(rt);
781 rt = NULL; 787 rt = NULL;
@@ -956,7 +962,8 @@ static inline int ipv6_saddr_preferred(int type)
956 return 0; 962 return 0;
957} 963}
958 964
959static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score, 965static int ipv6_get_saddr_eval(struct net *net,
966 struct ipv6_saddr_score *score,
960 struct ipv6_saddr_dst *dst, 967 struct ipv6_saddr_dst *dst,
961 int i) 968 int i)
962{ 969{
@@ -1035,7 +1042,8 @@ static int ipv6_get_saddr_eval(struct ipv6_saddr_score *score,
1035 break; 1042 break;
1036 case IPV6_SADDR_RULE_LABEL: 1043 case IPV6_SADDR_RULE_LABEL:
1037 /* Rule 6: Prefer matching label */ 1044 /* Rule 6: Prefer matching label */
1038 ret = ipv6_addr_label(&score->ifa->addr, score->addr_type, 1045 ret = ipv6_addr_label(net,
1046 &score->ifa->addr, score->addr_type,
1039 score->ifa->idev->dev->ifindex) == dst->label; 1047 score->ifa->idev->dev->ifindex) == dst->label;
1040 break; 1048 break;
1041#ifdef CONFIG_IPV6_PRIVACY 1049#ifdef CONFIG_IPV6_PRIVACY
@@ -1089,7 +1097,7 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1089 dst.addr = daddr; 1097 dst.addr = daddr;
1090 dst.ifindex = dst_dev ? dst_dev->ifindex : 0; 1098 dst.ifindex = dst_dev ? dst_dev->ifindex : 0;
1091 dst.scope = __ipv6_addr_src_scope(dst_type); 1099 dst.scope = __ipv6_addr_src_scope(dst_type);
1092 dst.label = ipv6_addr_label(daddr, dst_type, dst.ifindex); 1100 dst.label = ipv6_addr_label(net, daddr, dst_type, dst.ifindex);
1093 dst.prefs = prefs; 1101 dst.prefs = prefs;
1094 1102
1095 hiscore->rule = -1; 1103 hiscore->rule = -1;
@@ -1157,8 +1165,8 @@ int ipv6_dev_get_saddr(struct net_device *dst_dev,
1157 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) { 1165 for (i = 0; i < IPV6_SADDR_RULE_MAX; i++) {
1158 int minihiscore, miniscore; 1166 int minihiscore, miniscore;
1159 1167
1160 minihiscore = ipv6_get_saddr_eval(hiscore, &dst, i); 1168 minihiscore = ipv6_get_saddr_eval(net, hiscore, &dst, i);
1161 miniscore = ipv6_get_saddr_eval(score, &dst, i); 1169 miniscore = ipv6_get_saddr_eval(net, score, &dst, i);
1162 1170
1163 if (minihiscore > miniscore) { 1171 if (minihiscore > miniscore) {
1164 if (i == IPV6_SADDR_RULE_SCOPE && 1172 if (i == IPV6_SADDR_RULE_SCOPE &&
@@ -1786,7 +1794,7 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
1786 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL, 1794 rt = rt6_lookup(dev_net(dev), &pinfo->prefix, NULL,
1787 dev->ifindex, 1); 1795 dev->ifindex, 1);
1788 1796
1789 if (rt && ((rt->rt6i_flags & (RTF_GATEWAY | RTF_DEFAULT)) == 0)) { 1797 if (rt && addrconf_is_prefix_route(rt)) {
1790 /* Autoconf prefix route */ 1798 /* Autoconf prefix route */
1791 if (valid_lft == 0) { 1799 if (valid_lft == 0) {
1792 ip6_del_rt(rt); 1800 ip6_del_rt(rt);
diff --git a/net/ipv6/addrlabel.c b/net/ipv6/addrlabel.c
index 9bfa8846f262..08909039d87b 100644
--- a/net/ipv6/addrlabel.c
+++ b/net/ipv6/addrlabel.c
@@ -29,6 +29,9 @@
29 */ 29 */
30struct ip6addrlbl_entry 30struct ip6addrlbl_entry
31{ 31{
32#ifdef CONFIG_NET_NS
33 struct net *lbl_net;
34#endif
32 struct in6_addr prefix; 35 struct in6_addr prefix;
33 int prefixlen; 36 int prefixlen;
34 int ifindex; 37 int ifindex;
@@ -46,6 +49,16 @@ static struct ip6addrlbl_table
46 u32 seq; 49 u32 seq;
47} ip6addrlbl_table; 50} ip6addrlbl_table;
48 51
52static inline
53struct net *ip6addrlbl_net(const struct ip6addrlbl_entry *lbl)
54{
55#ifdef CONFIG_NET_NS
56 return lbl->lbl_net;
57#else
58 return &init_net;
59#endif
60}
61
49/* 62/*
50 * Default policy table (RFC3484 + extensions) 63 * Default policy table (RFC3484 + extensions)
51 * 64 *
@@ -65,7 +78,7 @@ static struct ip6addrlbl_table
65 78
66#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL 79#define IPV6_ADDR_LABEL_DEFAULT 0xffffffffUL
67 80
68static const __initdata struct ip6addrlbl_init_table 81static const __net_initdata struct ip6addrlbl_init_table
69{ 82{
70 const struct in6_addr *prefix; 83 const struct in6_addr *prefix;
71 int prefixlen; 84 int prefixlen;
@@ -108,6 +121,9 @@ static const __initdata struct ip6addrlbl_init_table
108/* Object management */ 121/* Object management */
109static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p) 122static inline void ip6addrlbl_free(struct ip6addrlbl_entry *p)
110{ 123{
124#ifdef CONFIG_NET_NS
125 release_net(p->lbl_net);
126#endif
111 kfree(p); 127 kfree(p);
112} 128}
113 129
@@ -128,10 +144,13 @@ static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
128} 144}
129 145
130/* Find label */ 146/* Find label */
131static int __ip6addrlbl_match(struct ip6addrlbl_entry *p, 147static int __ip6addrlbl_match(struct net *net,
148 struct ip6addrlbl_entry *p,
132 const struct in6_addr *addr, 149 const struct in6_addr *addr,
133 int addrtype, int ifindex) 150 int addrtype, int ifindex)
134{ 151{
152 if (!net_eq(ip6addrlbl_net(p), net))
153 return 0;
135 if (p->ifindex && p->ifindex != ifindex) 154 if (p->ifindex && p->ifindex != ifindex)
136 return 0; 155 return 0;
137 if (p->addrtype && p->addrtype != addrtype) 156 if (p->addrtype && p->addrtype != addrtype)
@@ -141,19 +160,21 @@ static int __ip6addrlbl_match(struct ip6addrlbl_entry *p,
141 return 1; 160 return 1;
142} 161}
143 162
144static struct ip6addrlbl_entry *__ipv6_addr_label(const struct in6_addr *addr, 163static struct ip6addrlbl_entry *__ipv6_addr_label(struct net *net,
164 const struct in6_addr *addr,
145 int type, int ifindex) 165 int type, int ifindex)
146{ 166{
147 struct hlist_node *pos; 167 struct hlist_node *pos;
148 struct ip6addrlbl_entry *p; 168 struct ip6addrlbl_entry *p;
149 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 169 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
150 if (__ip6addrlbl_match(p, addr, type, ifindex)) 170 if (__ip6addrlbl_match(net, p, addr, type, ifindex))
151 return p; 171 return p;
152 } 172 }
153 return NULL; 173 return NULL;
154} 174}
155 175
156u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex) 176u32 ipv6_addr_label(struct net *net,
177 const struct in6_addr *addr, int type, int ifindex)
157{ 178{
158 u32 label; 179 u32 label;
159 struct ip6addrlbl_entry *p; 180 struct ip6addrlbl_entry *p;
@@ -161,7 +182,7 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
161 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK; 182 type &= IPV6_ADDR_MAPPED | IPV6_ADDR_COMPATv4 | IPV6_ADDR_LOOPBACK;
162 183
163 rcu_read_lock(); 184 rcu_read_lock();
164 p = __ipv6_addr_label(addr, type, ifindex); 185 p = __ipv6_addr_label(net, addr, type, ifindex);
165 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT; 186 label = p ? p->label : IPV6_ADDR_LABEL_DEFAULT;
166 rcu_read_unlock(); 187 rcu_read_unlock();
167 188
@@ -174,7 +195,8 @@ u32 ipv6_addr_label(const struct in6_addr *addr, int type, int ifindex)
174} 195}
175 196
176/* allocate one entry */ 197/* allocate one entry */
177static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix, 198static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
199 const struct in6_addr *prefix,
178 int prefixlen, int ifindex, 200 int prefixlen, int ifindex,
179 u32 label) 201 u32 label)
180{ 202{
@@ -216,6 +238,9 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(const struct in6_addr *prefix,
216 newp->addrtype = addrtype; 238 newp->addrtype = addrtype;
217 newp->label = label; 239 newp->label = label;
218 INIT_HLIST_NODE(&newp->list); 240 INIT_HLIST_NODE(&newp->list);
241#ifdef CONFIG_NET_NS
242 newp->lbl_net = hold_net(net);
243#endif
219 atomic_set(&newp->refcnt, 1); 244 atomic_set(&newp->refcnt, 1);
220 return newp; 245 return newp;
221} 246}
@@ -237,6 +262,7 @@ static int __ip6addrlbl_add(struct ip6addrlbl_entry *newp, int replace)
237 hlist_for_each_entry_safe(p, pos, n, 262 hlist_for_each_entry_safe(p, pos, n,
238 &ip6addrlbl_table.head, list) { 263 &ip6addrlbl_table.head, list) {
239 if (p->prefixlen == newp->prefixlen && 264 if (p->prefixlen == newp->prefixlen &&
265 net_eq(ip6addrlbl_net(p), ip6addrlbl_net(newp)) &&
240 p->ifindex == newp->ifindex && 266 p->ifindex == newp->ifindex &&
241 ipv6_addr_equal(&p->prefix, &newp->prefix)) { 267 ipv6_addr_equal(&p->prefix, &newp->prefix)) {
242 if (!replace) { 268 if (!replace) {
@@ -261,7 +287,8 @@ out:
261} 287}
262 288
263/* add a label */ 289/* add a label */
264static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen, 290static int ip6addrlbl_add(struct net *net,
291 const struct in6_addr *prefix, int prefixlen,
265 int ifindex, u32 label, int replace) 292 int ifindex, u32 label, int replace)
266{ 293{
267 struct ip6addrlbl_entry *newp; 294 struct ip6addrlbl_entry *newp;
@@ -274,7 +301,7 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
274 (unsigned int)label, 301 (unsigned int)label,
275 replace); 302 replace);
276 303
277 newp = ip6addrlbl_alloc(prefix, prefixlen, ifindex, label); 304 newp = ip6addrlbl_alloc(net, prefix, prefixlen, ifindex, label);
278 if (IS_ERR(newp)) 305 if (IS_ERR(newp))
279 return PTR_ERR(newp); 306 return PTR_ERR(newp);
280 spin_lock(&ip6addrlbl_table.lock); 307 spin_lock(&ip6addrlbl_table.lock);
@@ -286,7 +313,8 @@ static int ip6addrlbl_add(const struct in6_addr *prefix, int prefixlen,
286} 313}
287 314
288/* remove a label */ 315/* remove a label */
289static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 316static int __ip6addrlbl_del(struct net *net,
317 const struct in6_addr *prefix, int prefixlen,
290 int ifindex) 318 int ifindex)
291{ 319{
292 struct ip6addrlbl_entry *p = NULL; 320 struct ip6addrlbl_entry *p = NULL;
@@ -300,6 +328,7 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
300 328
301 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) { 329 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
302 if (p->prefixlen == prefixlen && 330 if (p->prefixlen == prefixlen &&
331 net_eq(ip6addrlbl_net(p), net) &&
303 p->ifindex == ifindex && 332 p->ifindex == ifindex &&
304 ipv6_addr_equal(&p->prefix, prefix)) { 333 ipv6_addr_equal(&p->prefix, prefix)) {
305 hlist_del_rcu(&p->list); 334 hlist_del_rcu(&p->list);
@@ -311,7 +340,8 @@ static int __ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
311 return ret; 340 return ret;
312} 341}
313 342
314static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen, 343static int ip6addrlbl_del(struct net *net,
344 const struct in6_addr *prefix, int prefixlen,
315 int ifindex) 345 int ifindex)
316{ 346{
317 struct in6_addr prefix_buf; 347 struct in6_addr prefix_buf;
@@ -324,13 +354,13 @@ static int ip6addrlbl_del(const struct in6_addr *prefix, int prefixlen,
324 354
325 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen); 355 ipv6_addr_prefix(&prefix_buf, prefix, prefixlen);
326 spin_lock(&ip6addrlbl_table.lock); 356 spin_lock(&ip6addrlbl_table.lock);
327 ret = __ip6addrlbl_del(&prefix_buf, prefixlen, ifindex); 357 ret = __ip6addrlbl_del(net, &prefix_buf, prefixlen, ifindex);
328 spin_unlock(&ip6addrlbl_table.lock); 358 spin_unlock(&ip6addrlbl_table.lock);
329 return ret; 359 return ret;
330} 360}
331 361
332/* add default label */ 362/* add default label */
333static __init int ip6addrlbl_init(void) 363static int __net_init ip6addrlbl_net_init(struct net *net)
334{ 364{
335 int err = 0; 365 int err = 0;
336 int i; 366 int i;
@@ -338,7 +368,8 @@ static __init int ip6addrlbl_init(void)
338 ADDRLABEL(KERN_DEBUG "%s()\n", __func__); 368 ADDRLABEL(KERN_DEBUG "%s()\n", __func__);
339 369
340 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) { 370 for (i = 0; i < ARRAY_SIZE(ip6addrlbl_init_table); i++) {
341 int ret = ip6addrlbl_add(ip6addrlbl_init_table[i].prefix, 371 int ret = ip6addrlbl_add(net,
372 ip6addrlbl_init_table[i].prefix,
342 ip6addrlbl_init_table[i].prefixlen, 373 ip6addrlbl_init_table[i].prefixlen,
343 0, 374 0,
344 ip6addrlbl_init_table[i].label, 0); 375 ip6addrlbl_init_table[i].label, 0);
@@ -349,11 +380,32 @@ static __init int ip6addrlbl_init(void)
349 return err; 380 return err;
350} 381}
351 382
383static void __net_exit ip6addrlbl_net_exit(struct net *net)
384{
385 struct ip6addrlbl_entry *p = NULL;
386 struct hlist_node *pos, *n;
387
388 /* Remove all labels belonging to the exiting net */
389 spin_lock(&ip6addrlbl_table.lock);
390 hlist_for_each_entry_safe(p, pos, n, &ip6addrlbl_table.head, list) {
391 if (net_eq(ip6addrlbl_net(p), net)) {
392 hlist_del_rcu(&p->list);
393 ip6addrlbl_put(p);
394 }
395 }
396 spin_unlock(&ip6addrlbl_table.lock);
397}
398
399static struct pernet_operations ipv6_addr_label_ops = {
400 .init = ip6addrlbl_net_init,
401 .exit = ip6addrlbl_net_exit,
402};
403
352int __init ipv6_addr_label_init(void) 404int __init ipv6_addr_label_init(void)
353{ 405{
354 spin_lock_init(&ip6addrlbl_table.lock); 406 spin_lock_init(&ip6addrlbl_table.lock);
355 407
356 return ip6addrlbl_init(); 408 return register_pernet_subsys(&ipv6_addr_label_ops);
357} 409}
358 410
359static const struct nla_policy ifal_policy[IFAL_MAX+1] = { 411static const struct nla_policy ifal_policy[IFAL_MAX+1] = {
@@ -371,9 +423,6 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
371 u32 label; 423 u32 label;
372 int err = 0; 424 int err = 0;
373 425
374 if (net != &init_net)
375 return 0;
376
377 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 426 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
378 if (err < 0) 427 if (err < 0)
379 return err; 428 return err;
@@ -385,7 +434,7 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
385 return -EINVAL; 434 return -EINVAL;
386 435
387 if (ifal->ifal_index && 436 if (ifal->ifal_index &&
388 !__dev_get_by_index(&init_net, ifal->ifal_index)) 437 !__dev_get_by_index(net, ifal->ifal_index))
389 return -EINVAL; 438 return -EINVAL;
390 439
391 if (!tb[IFAL_ADDRESS]) 440 if (!tb[IFAL_ADDRESS])
@@ -403,12 +452,12 @@ static int ip6addrlbl_newdel(struct sk_buff *skb, struct nlmsghdr *nlh,
403 452
404 switch(nlh->nlmsg_type) { 453 switch(nlh->nlmsg_type) {
405 case RTM_NEWADDRLABEL: 454 case RTM_NEWADDRLABEL:
406 err = ip6addrlbl_add(pfx, ifal->ifal_prefixlen, 455 err = ip6addrlbl_add(net, pfx, ifal->ifal_prefixlen,
407 ifal->ifal_index, label, 456 ifal->ifal_index, label,
408 nlh->nlmsg_flags & NLM_F_REPLACE); 457 nlh->nlmsg_flags & NLM_F_REPLACE);
409 break; 458 break;
410 case RTM_DELADDRLABEL: 459 case RTM_DELADDRLABEL:
411 err = ip6addrlbl_del(pfx, ifal->ifal_prefixlen, 460 err = ip6addrlbl_del(net, pfx, ifal->ifal_prefixlen,
412 ifal->ifal_index); 461 ifal->ifal_index);
413 break; 462 break;
414 default: 463 default:
@@ -458,12 +507,10 @@ static int ip6addrlbl_dump(struct sk_buff *skb, struct netlink_callback *cb)
458 int idx = 0, s_idx = cb->args[0]; 507 int idx = 0, s_idx = cb->args[0];
459 int err; 508 int err;
460 509
461 if (net != &init_net)
462 return 0;
463
464 rcu_read_lock(); 510 rcu_read_lock();
465 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) { 511 hlist_for_each_entry_rcu(p, pos, &ip6addrlbl_table.head, list) {
466 if (idx >= s_idx) { 512 if (idx >= s_idx &&
513 net_eq(ip6addrlbl_net(p), net)) {
467 if ((err = ip6addrlbl_fill(skb, p, 514 if ((err = ip6addrlbl_fill(skb, p,
468 ip6addrlbl_table.seq, 515 ip6addrlbl_table.seq,
469 NETLINK_CB(cb->skb).pid, 516 NETLINK_CB(cb->skb).pid,
@@ -499,9 +546,6 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
499 struct ip6addrlbl_entry *p; 546 struct ip6addrlbl_entry *p;
500 struct sk_buff *skb; 547 struct sk_buff *skb;
501 548
502 if (net != &init_net)
503 return 0;
504
505 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy); 549 err = nlmsg_parse(nlh, sizeof(*ifal), tb, IFAL_MAX, ifal_policy);
506 if (err < 0) 550 if (err < 0)
507 return err; 551 return err;
@@ -513,7 +557,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
513 return -EINVAL; 557 return -EINVAL;
514 558
515 if (ifal->ifal_index && 559 if (ifal->ifal_index &&
516 !__dev_get_by_index(&init_net, ifal->ifal_index)) 560 !__dev_get_by_index(net, ifal->ifal_index))
517 return -EINVAL; 561 return -EINVAL;
518 562
519 if (!tb[IFAL_ADDRESS]) 563 if (!tb[IFAL_ADDRESS])
@@ -524,7 +568,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
524 return -EINVAL; 568 return -EINVAL;
525 569
526 rcu_read_lock(); 570 rcu_read_lock();
527 p = __ipv6_addr_label(addr, ipv6_addr_type(addr), ifal->ifal_index); 571 p = __ipv6_addr_label(net, addr, ipv6_addr_type(addr), ifal->ifal_index);
528 if (p && ip6addrlbl_hold(p)) 572 if (p && ip6addrlbl_hold(p))
529 p = NULL; 573 p = NULL;
530 lseq = ip6addrlbl_table.seq; 574 lseq = ip6addrlbl_table.seq;
@@ -552,7 +596,7 @@ static int ip6addrlbl_get(struct sk_buff *in_skb, struct nlmsghdr* nlh,
552 goto out; 596 goto out;
553 } 597 }
554 598
555 err = rtnl_unicast(skb, &init_net, NETLINK_CB(in_skb).pid); 599 err = rtnl_unicast(skb, net, NETLINK_CB(in_skb).pid);
556out: 600out:
557 return err; 601 return err;
558} 602}
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index bf268b386963..0b11b378d89a 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1240,7 +1240,7 @@ int ip6_mroute_setsockopt(struct sock *sk, int optname, char __user *optval, int
1240 1240
1241#endif 1241#endif
1242 /* 1242 /*
1243 * Spurious command, or MRT_VERSION which you cannot 1243 * Spurious command, or MRT6_VERSION which you cannot
1244 * set. 1244 * set.
1245 */ 1245 */
1246 default: 1246 default:
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index fbb2d12c41bc..bd2fe4cfafa7 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -162,7 +162,6 @@ static int ip6_mc_leave_src(struct sock *sk, struct ipv6_mc_socklist *iml,
162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \ 162 ((MLDV2_MASK(value, nbmant) | (1<<(nbmant))) << \
163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp)))) 163 (MLDV2_MASK((value) >> (nbmant), nbexp) + (nbexp))))
164 164
165#define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
166#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value) 165#define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
167 166
168#define IPV6_MLD_MAX_MSF 64 167#define IPV6_MLD_MAX_MSF 64
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 155499197fc5..3fe736bead96 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -80,6 +80,12 @@ static struct inet_connection_sock_af_ops ipv6_specific;
80#ifdef CONFIG_TCP_MD5SIG 80#ifdef CONFIG_TCP_MD5SIG
81static struct tcp_sock_af_ops tcp_sock_ipv6_specific; 81static struct tcp_sock_af_ops tcp_sock_ipv6_specific;
82static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific; 82static struct tcp_sock_af_ops tcp_sock_ipv6_mapped_specific;
83#else
84static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk,
85 struct in6_addr *addr)
86{
87 return NULL;
88}
83#endif 89#endif
84 90
85static void tcp_v6_hash(struct sock *sk) 91static void tcp_v6_hash(struct sock *sk)
@@ -734,78 +740,34 @@ static int tcp_v6_parse_md5_keys (struct sock *sk, char __user *optval,
734static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key, 740static int tcp_v6_do_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
735 struct in6_addr *saddr, 741 struct in6_addr *saddr,
736 struct in6_addr *daddr, 742 struct in6_addr *daddr,
737 struct tcphdr *th, int protocol, 743 struct tcphdr *th, unsigned int tcplen)
738 unsigned int tcplen)
739{ 744{
740 struct scatterlist sg[4];
741 __u16 data_len;
742 int block = 0;
743 __sum16 cksum;
744 struct tcp_md5sig_pool *hp; 745 struct tcp_md5sig_pool *hp;
745 struct tcp6_pseudohdr *bp; 746 struct tcp6_pseudohdr *bp;
746 struct hash_desc *desc;
747 int err; 747 int err;
748 unsigned int nbytes = 0;
749 748
750 hp = tcp_get_md5sig_pool(); 749 hp = tcp_get_md5sig_pool();
751 if (!hp) { 750 if (!hp) {
752 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__); 751 printk(KERN_WARNING "%s(): hash pool not found...\n", __func__);
753 goto clear_hash_noput; 752 goto clear_hash_noput;
754 } 753 }
754
755 bp = &hp->md5_blk.ip6; 755 bp = &hp->md5_blk.ip6;
756 desc = &hp->md5_desc;
757 756
758 /* 1. TCP pseudo-header (RFC2460) */ 757 /* 1. TCP pseudo-header (RFC2460) */
759 ipv6_addr_copy(&bp->saddr, saddr); 758 ipv6_addr_copy(&bp->saddr, saddr);
760 ipv6_addr_copy(&bp->daddr, daddr); 759 ipv6_addr_copy(&bp->daddr, daddr);
761 bp->len = htonl(tcplen); 760 bp->len = htonl(tcplen);
762 bp->protocol = htonl(protocol); 761 bp->protocol = htonl(IPPROTO_TCP);
763
764 sg_init_table(sg, 4);
765 762
766 sg_set_buf(&sg[block++], bp, sizeof(*bp)); 763 err = tcp_calc_md5_hash(md5_hash, key, sizeof(*bp),
767 nbytes += sizeof(*bp); 764 th, tcplen, hp);
768 765
769 /* 2. TCP header, excluding options */ 766 if (err)
770 cksum = th->check;
771 th->check = 0;
772 sg_set_buf(&sg[block++], th, sizeof(*th));
773 nbytes += sizeof(*th);
774
775 /* 3. TCP segment data (if any) */
776 data_len = tcplen - (th->doff << 2);
777 if (data_len > 0) {
778 u8 *data = (u8 *)th + (th->doff << 2);
779 sg_set_buf(&sg[block++], data, data_len);
780 nbytes += data_len;
781 }
782
783 /* 4. shared key */
784 sg_set_buf(&sg[block++], key->key, key->keylen);
785 nbytes += key->keylen;
786
787 sg_mark_end(&sg[block - 1]);
788
789 /* Now store the hash into the packet */
790 err = crypto_hash_init(desc);
791 if (err) {
792 printk(KERN_WARNING "%s(): hash_init failed\n", __func__);
793 goto clear_hash;
794 }
795 err = crypto_hash_update(desc, sg, nbytes);
796 if (err) {
797 printk(KERN_WARNING "%s(): hash_update failed\n", __func__);
798 goto clear_hash;
799 }
800 err = crypto_hash_final(desc, md5_hash);
801 if (err) {
802 printk(KERN_WARNING "%s(): hash_final failed\n", __func__);
803 goto clear_hash; 767 goto clear_hash;
804 }
805 768
806 /* Reset header, and free up the crypto */ 769 /* Free up the crypto pool */
807 tcp_put_md5sig_pool(); 770 tcp_put_md5sig_pool();
808 th->check = cksum;
809out: 771out:
810 return 0; 772 return 0;
811clear_hash: 773clear_hash:
@@ -819,8 +781,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
819 struct sock *sk, 781 struct sock *sk,
820 struct dst_entry *dst, 782 struct dst_entry *dst,
821 struct request_sock *req, 783 struct request_sock *req,
822 struct tcphdr *th, int protocol, 784 struct tcphdr *th, unsigned int tcplen)
823 unsigned int tcplen)
824{ 785{
825 struct in6_addr *saddr, *daddr; 786 struct in6_addr *saddr, *daddr;
826 787
@@ -833,7 +794,7 @@ static int tcp_v6_calc_md5_hash(char *md5_hash, struct tcp_md5sig_key *key,
833 } 794 }
834 return tcp_v6_do_calc_md5_hash(md5_hash, key, 795 return tcp_v6_do_calc_md5_hash(md5_hash, key,
835 saddr, daddr, 796 saddr, daddr,
836 th, protocol, tcplen); 797 th, tcplen);
837} 798}
838 799
839static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb) 800static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
@@ -842,43 +803,12 @@ static int tcp_v6_inbound_md5_hash (struct sock *sk, struct sk_buff *skb)
842 struct tcp_md5sig_key *hash_expected; 803 struct tcp_md5sig_key *hash_expected;
843 struct ipv6hdr *ip6h = ipv6_hdr(skb); 804 struct ipv6hdr *ip6h = ipv6_hdr(skb);
844 struct tcphdr *th = tcp_hdr(skb); 805 struct tcphdr *th = tcp_hdr(skb);
845 int length = (th->doff << 2) - sizeof (*th);
846 int genhash; 806 int genhash;
847 u8 *ptr;
848 u8 newhash[16]; 807 u8 newhash[16];
849 808
850 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr); 809 hash_expected = tcp_v6_md5_do_lookup(sk, &ip6h->saddr);
810 hash_location = tcp_parse_md5sig_option(th);
851 811
852 /* If the TCP option is too short, we can short cut */
853 if (length < TCPOLEN_MD5SIG)
854 return hash_expected ? 1 : 0;
855
856 /* parse options */
857 ptr = (u8*)(th + 1);
858 while (length > 0) {
859 int opcode = *ptr++;
860 int opsize;
861
862 switch(opcode) {
863 case TCPOPT_EOL:
864 goto done_opts;
865 case TCPOPT_NOP:
866 length--;
867 continue;
868 default:
869 opsize = *ptr++;
870 if (opsize < 2 || opsize > length)
871 goto done_opts;
872 if (opcode == TCPOPT_MD5SIG) {
873 hash_location = ptr;
874 goto done_opts;
875 }
876 }
877 ptr += opsize - 2;
878 length -= opsize;
879 }
880
881done_opts:
882 /* do we have a hash as expected? */ 812 /* do we have a hash as expected? */
883 if (!hash_expected) { 813 if (!hash_expected) {
884 if (!hash_location) 814 if (!hash_location)
@@ -908,8 +838,7 @@ done_opts:
908 genhash = tcp_v6_do_calc_md5_hash(newhash, 838 genhash = tcp_v6_do_calc_md5_hash(newhash,
909 hash_expected, 839 hash_expected,
910 &ip6h->saddr, &ip6h->daddr, 840 &ip6h->saddr, &ip6h->daddr,
911 th, sk->sk_protocol, 841 th, skb->len);
912 skb->len);
913 if (genhash || memcmp(hash_location, newhash, 16) != 0) { 842 if (genhash || memcmp(hash_location, newhash, 16) != 0) {
914 if (net_ratelimit()) { 843 if (net_ratelimit()) {
915 printk(KERN_INFO "MD5 Hash %s for " 844 printk(KERN_INFO "MD5 Hash %s for "
@@ -1049,7 +978,7 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1049 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key, 978 tcp_v6_do_calc_md5_hash((__u8 *)&opt[1], key,
1050 &ipv6_hdr(skb)->daddr, 979 &ipv6_hdr(skb)->daddr,
1051 &ipv6_hdr(skb)->saddr, 980 &ipv6_hdr(skb)->saddr,
1052 t1, IPPROTO_TCP, tot_len); 981 t1, tot_len);
1053 } 982 }
1054#endif 983#endif
1055 984
@@ -1086,8 +1015,8 @@ static void tcp_v6_send_reset(struct sock *sk, struct sk_buff *skb)
1086 kfree_skb(buff); 1015 kfree_skb(buff);
1087} 1016}
1088 1017
1089static void tcp_v6_send_ack(struct tcp_timewait_sock *tw, 1018static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts,
1090 struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 ts) 1019 struct tcp_md5sig_key *key)
1091{ 1020{
1092 struct tcphdr *th = tcp_hdr(skb), *t1; 1021 struct tcphdr *th = tcp_hdr(skb), *t1;
1093 struct sk_buff *buff; 1022 struct sk_buff *buff;
@@ -1096,22 +1025,6 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1096 struct sock *ctl_sk = net->ipv6.tcp_sk; 1025 struct sock *ctl_sk = net->ipv6.tcp_sk;
1097 unsigned int tot_len = sizeof(struct tcphdr); 1026 unsigned int tot_len = sizeof(struct tcphdr);
1098 __be32 *topt; 1027 __be32 *topt;
1099#ifdef CONFIG_TCP_MD5SIG
1100 struct tcp_md5sig_key *key;
1101 struct tcp_md5sig_key tw_key;
1102#endif
1103
1104#ifdef CONFIG_TCP_MD5SIG
1105 if (!tw && skb->sk) {
1106 key = tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr);
1107 } else if (tw && tw->tw_md5_keylen) {
1108 tw_key.key = tw->tw_md5_key;
1109 tw_key.keylen = tw->tw_md5_keylen;
1110 key = &tw_key;
1111 } else {
1112 key = NULL;
1113 }
1114#endif
1115 1028
1116 if (ts) 1029 if (ts)
1117 tot_len += TCPOLEN_TSTAMP_ALIGNED; 1030 tot_len += TCPOLEN_TSTAMP_ALIGNED;
@@ -1155,7 +1068,7 @@ static void tcp_v6_send_ack(struct tcp_timewait_sock *tw,
1155 tcp_v6_do_calc_md5_hash((__u8 *)topt, key, 1068 tcp_v6_do_calc_md5_hash((__u8 *)topt, key,
1156 &ipv6_hdr(skb)->daddr, 1069 &ipv6_hdr(skb)->daddr,
1157 &ipv6_hdr(skb)->saddr, 1070 &ipv6_hdr(skb)->saddr,
1158 t1, IPPROTO_TCP, tot_len); 1071 t1, tot_len);
1159 } 1072 }
1160#endif 1073#endif
1161 1074
@@ -1191,16 +1104,17 @@ static void tcp_v6_timewait_ack(struct sock *sk, struct sk_buff *skb)
1191 struct inet_timewait_sock *tw = inet_twsk(sk); 1104 struct inet_timewait_sock *tw = inet_twsk(sk);
1192 struct tcp_timewait_sock *tcptw = tcp_twsk(sk); 1105 struct tcp_timewait_sock *tcptw = tcp_twsk(sk);
1193 1106
1194 tcp_v6_send_ack(tcptw, skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt, 1107 tcp_v6_send_ack(skb, tcptw->tw_snd_nxt, tcptw->tw_rcv_nxt,
1195 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale, 1108 tcptw->tw_rcv_wnd >> tw->tw_rcv_wscale,
1196 tcptw->tw_ts_recent); 1109 tcptw->tw_ts_recent, tcp_twsk_md5_key(tcptw));
1197 1110
1198 inet_twsk_put(tw); 1111 inet_twsk_put(tw);
1199} 1112}
1200 1113
1201static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req) 1114static void tcp_v6_reqsk_send_ack(struct sk_buff *skb, struct request_sock *req)
1202{ 1115{
1203 tcp_v6_send_ack(NULL, skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent); 1116 tcp_v6_send_ack(skb, tcp_rsk(req)->snt_isn + 1, tcp_rsk(req)->rcv_isn + 1, req->rcv_wnd, req->ts_recent,
1117 tcp_v6_md5_do_lookup(skb->sk, &ipv6_hdr(skb)->daddr));
1204} 1118}
1205 1119
1206 1120