aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/route.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r--net/ipv6/route.c1059
1 files changed, 610 insertions, 449 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index d9baca062d24..d6b4b4f48d18 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -22,6 +22,8 @@
22 * routers in REACHABLE, STALE, DELAY or PROBE states). 22 * routers in REACHABLE, STALE, DELAY or PROBE states).
23 * - always select the same router if it is (probably) 23 * - always select the same router if it is (probably)
24 * reachable. otherwise, round-robin the list. 24 * reachable. otherwise, round-robin the list.
25 * Ville Nuorvala
26 * Fixed routing subtrees.
25 */ 27 */
26 28
27#include <linux/capability.h> 29#include <linux/capability.h>
@@ -35,7 +37,6 @@
35#include <linux/netdevice.h> 37#include <linux/netdevice.h>
36#include <linux/in6.h> 38#include <linux/in6.h>
37#include <linux/init.h> 39#include <linux/init.h>
38#include <linux/netlink.h>
39#include <linux/if_arp.h> 40#include <linux/if_arp.h>
40 41
41#ifdef CONFIG_PROC_FS 42#ifdef CONFIG_PROC_FS
@@ -54,6 +55,7 @@
54#include <net/dst.h> 55#include <net/dst.h>
55#include <net/xfrm.h> 56#include <net/xfrm.h>
56#include <net/netevent.h> 57#include <net/netevent.h>
58#include <net/netlink.h>
57 59
58#include <asm/uaccess.h> 60#include <asm/uaccess.h>
59 61
@@ -74,9 +76,6 @@
74 76
75#define CLONE_OFFLINK_ROUTE 0 77#define CLONE_OFFLINK_ROUTE 0
76 78
77#define RT6_SELECT_F_IFACE 0x1
78#define RT6_SELECT_F_REACHABLE 0x2
79
80static int ip6_rt_max_size = 4096; 79static int ip6_rt_max_size = 4096;
81static int ip6_rt_gc_min_interval = HZ / 2; 80static int ip6_rt_gc_min_interval = HZ / 2;
82static int ip6_rt_gc_timeout = 60*HZ; 81static int ip6_rt_gc_timeout = 60*HZ;
@@ -140,15 +139,49 @@ struct rt6_info ip6_null_entry = {
140 .rt6i_ref = ATOMIC_INIT(1), 139 .rt6i_ref = ATOMIC_INIT(1),
141}; 140};
142 141
143struct fib6_node ip6_routing_table = { 142#ifdef CONFIG_IPV6_MULTIPLE_TABLES
144 .leaf = &ip6_null_entry,
145 .fn_flags = RTN_ROOT | RTN_TL_ROOT | RTN_RTINFO,
146};
147 143
148/* Protects all the ip6 fib */ 144struct rt6_info ip6_prohibit_entry = {
145 .u = {
146 .dst = {
147 .__refcnt = ATOMIC_INIT(1),
148 .__use = 1,
149 .dev = &loopback_dev,
150 .obsolete = -1,
151 .error = -EACCES,
152 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
153 .input = ip6_pkt_discard,
154 .output = ip6_pkt_discard_out,
155 .ops = &ip6_dst_ops,
156 .path = (struct dst_entry*)&ip6_prohibit_entry,
157 }
158 },
159 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
160 .rt6i_metric = ~(u32) 0,
161 .rt6i_ref = ATOMIC_INIT(1),
162};
149 163
150DEFINE_RWLOCK(rt6_lock); 164struct rt6_info ip6_blk_hole_entry = {
165 .u = {
166 .dst = {
167 .__refcnt = ATOMIC_INIT(1),
168 .__use = 1,
169 .dev = &loopback_dev,
170 .obsolete = -1,
171 .error = -EINVAL,
172 .metrics = { [RTAX_HOPLIMIT - 1] = 255, },
173 .input = ip6_pkt_discard,
174 .output = ip6_pkt_discard_out,
175 .ops = &ip6_dst_ops,
176 .path = (struct dst_entry*)&ip6_blk_hole_entry,
177 }
178 },
179 .rt6i_flags = (RTF_REJECT | RTF_NONEXTHOP),
180 .rt6i_metric = ~(u32) 0,
181 .rt6i_ref = ATOMIC_INIT(1),
182};
151 183
184#endif
152 185
153/* allocate dst with ip6_dst_ops */ 186/* allocate dst with ip6_dst_ops */
154static __inline__ struct rt6_info *ip6_dst_alloc(void) 187static __inline__ struct rt6_info *ip6_dst_alloc(void)
@@ -188,8 +221,14 @@ static __inline__ int rt6_check_expired(const struct rt6_info *rt)
188 time_after(jiffies, rt->rt6i_expires)); 221 time_after(jiffies, rt->rt6i_expires));
189} 222}
190 223
224static inline int rt6_need_strict(struct in6_addr *daddr)
225{
226 return (ipv6_addr_type(daddr) &
227 (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL));
228}
229
191/* 230/*
192 * Route lookup. Any rt6_lock is implied. 231 * Route lookup. Any table->tb6_lock is implied.
193 */ 232 */
194 233
195static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt, 234static __inline__ struct rt6_info *rt6_device_match(struct rt6_info *rt,
@@ -298,7 +337,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
298 int m, n; 337 int m, n;
299 338
300 m = rt6_check_dev(rt, oif); 339 m = rt6_check_dev(rt, oif);
301 if (!m && (strict & RT6_SELECT_F_IFACE)) 340 if (!m && (strict & RT6_LOOKUP_F_IFACE))
302 return -1; 341 return -1;
303#ifdef CONFIG_IPV6_ROUTER_PREF 342#ifdef CONFIG_IPV6_ROUTER_PREF
304 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2; 343 m |= IPV6_DECODE_PREF(IPV6_EXTRACT_PREF(rt->rt6i_flags)) << 2;
@@ -306,7 +345,7 @@ static int rt6_score_route(struct rt6_info *rt, int oif,
306 n = rt6_check_neigh(rt); 345 n = rt6_check_neigh(rt);
307 if (n > 1) 346 if (n > 1)
308 m |= 16; 347 m |= 16;
309 else if (!n && strict & RT6_SELECT_F_REACHABLE) 348 else if (!n && strict & RT6_LOOKUP_F_REACHABLE)
310 return -1; 349 return -1;
311 return m; 350 return m;
312} 351}
@@ -346,7 +385,7 @@ static struct rt6_info *rt6_select(struct rt6_info **head, int oif,
346 } 385 }
347 386
348 if (!match && 387 if (!match &&
349 (strict & RT6_SELECT_F_REACHABLE) && 388 (strict & RT6_LOOKUP_F_REACHABLE) &&
350 last && last != rt0) { 389 last && last != rt0) {
351 /* no entries matched; do round-robin */ 390 /* no entries matched; do round-robin */
352 static DEFINE_SPINLOCK(lock); 391 static DEFINE_SPINLOCK(lock);
@@ -417,7 +456,7 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
417 rt = rt6_get_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex); 456 rt = rt6_get_route_info(prefix, rinfo->prefix_len, gwaddr, dev->ifindex);
418 457
419 if (rt && !lifetime) { 458 if (rt && !lifetime) {
420 ip6_del_rt(rt, NULL, NULL, NULL); 459 ip6_del_rt(rt);
421 rt = NULL; 460 rt = NULL;
422 } 461 }
423 462
@@ -441,44 +480,95 @@ int rt6_route_rcv(struct net_device *dev, u8 *opt, int len,
441} 480}
442#endif 481#endif
443 482
444struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr, 483#define BACKTRACK(saddr) \
445 int oif, int strict) 484do { \
485 if (rt == &ip6_null_entry) { \
486 struct fib6_node *pn; \
487 while (fn) { \
488 if (fn->fn_flags & RTN_TL_ROOT) \
489 goto out; \
490 pn = fn->parent; \
491 if (FIB6_SUBTREE(pn) && FIB6_SUBTREE(pn) != fn) \
492 fn = fib6_lookup(pn->subtree, NULL, saddr); \
493 else \
494 fn = pn; \
495 if (fn->fn_flags & RTN_RTINFO) \
496 goto restart; \
497 } \
498 } \
499} while(0)
500
501static struct rt6_info *ip6_pol_route_lookup(struct fib6_table *table,
502 struct flowi *fl, int flags)
446{ 503{
447 struct fib6_node *fn; 504 struct fib6_node *fn;
448 struct rt6_info *rt; 505 struct rt6_info *rt;
449 506
450 read_lock_bh(&rt6_lock); 507 read_lock_bh(&table->tb6_lock);
451 fn = fib6_lookup(&ip6_routing_table, daddr, saddr); 508 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
452 rt = rt6_device_match(fn->leaf, oif, strict); 509restart:
510 rt = fn->leaf;
511 rt = rt6_device_match(rt, fl->oif, flags);
512 BACKTRACK(&fl->fl6_src);
513out:
453 dst_hold(&rt->u.dst); 514 dst_hold(&rt->u.dst);
454 rt->u.dst.__use++; 515 read_unlock_bh(&table->tb6_lock);
455 read_unlock_bh(&rt6_lock);
456 516
457 rt->u.dst.lastuse = jiffies; 517 rt->u.dst.lastuse = jiffies;
458 if (rt->u.dst.error == 0) 518 rt->u.dst.__use++;
459 return rt; 519
460 dst_release(&rt->u.dst); 520 return rt;
521
522}
523
524struct rt6_info *rt6_lookup(struct in6_addr *daddr, struct in6_addr *saddr,
525 int oif, int strict)
526{
527 struct flowi fl = {
528 .oif = oif,
529 .nl_u = {
530 .ip6_u = {
531 .daddr = *daddr,
532 /* TODO: saddr */
533 },
534 },
535 };
536 struct dst_entry *dst;
537 int flags = strict ? RT6_LOOKUP_F_IFACE : 0;
538
539 dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_lookup);
540 if (dst->error == 0)
541 return (struct rt6_info *) dst;
542
543 dst_release(dst);
544
461 return NULL; 545 return NULL;
462} 546}
463 547
464/* ip6_ins_rt is called with FREE rt6_lock. 548/* ip6_ins_rt is called with FREE table->tb6_lock.
465 It takes new route entry, the addition fails by any reason the 549 It takes new route entry, the addition fails by any reason the
466 route is freed. In any case, if caller does not hold it, it may 550 route is freed. In any case, if caller does not hold it, it may
467 be destroyed. 551 be destroyed.
468 */ 552 */
469 553
470int ip6_ins_rt(struct rt6_info *rt, struct nlmsghdr *nlh, 554static int __ip6_ins_rt(struct rt6_info *rt, struct nl_info *info)
471 void *_rtattr, struct netlink_skb_parms *req)
472{ 555{
473 int err; 556 int err;
557 struct fib6_table *table;
474 558
475 write_lock_bh(&rt6_lock); 559 table = rt->rt6i_table;
476 err = fib6_add(&ip6_routing_table, rt, nlh, _rtattr, req); 560 write_lock_bh(&table->tb6_lock);
477 write_unlock_bh(&rt6_lock); 561 err = fib6_add(&table->tb6_root, rt, info);
562 write_unlock_bh(&table->tb6_lock);
478 563
479 return err; 564 return err;
480} 565}
481 566
567int ip6_ins_rt(struct rt6_info *rt)
568{
569 return __ip6_ins_rt(rt, NULL);
570}
571
482static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr, 572static struct rt6_info *rt6_alloc_cow(struct rt6_info *ort, struct in6_addr *daddr,
483 struct in6_addr *saddr) 573 struct in6_addr *saddr)
484{ 574{
@@ -532,51 +622,39 @@ static struct rt6_info *rt6_alloc_clone(struct rt6_info *ort, struct in6_addr *d
532 return rt; 622 return rt;
533} 623}
534 624
535#define BACKTRACK() \ 625static struct rt6_info *ip6_pol_route_input(struct fib6_table *table,
536if (rt == &ip6_null_entry) { \ 626 struct flowi *fl, int flags)
537 while ((fn = fn->parent) != NULL) { \
538 if (fn->fn_flags & RTN_ROOT) { \
539 goto out; \
540 } \
541 if (fn->fn_flags & RTN_RTINFO) \
542 goto restart; \
543 } \
544}
545
546
547void ip6_route_input(struct sk_buff *skb)
548{ 627{
549 struct fib6_node *fn; 628 struct fib6_node *fn;
550 struct rt6_info *rt, *nrt; 629 struct rt6_info *rt, *nrt;
551 int strict; 630 int strict = 0;
552 int attempts = 3; 631 int attempts = 3;
553 int err; 632 int err;
554 int reachable = RT6_SELECT_F_REACHABLE; 633 int reachable = RT6_LOOKUP_F_REACHABLE;
555 634
556 strict = ipv6_addr_type(&skb->nh.ipv6h->daddr) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL) ? RT6_SELECT_F_IFACE : 0; 635 strict |= flags & RT6_LOOKUP_F_IFACE;
557 636
558relookup: 637relookup:
559 read_lock_bh(&rt6_lock); 638 read_lock_bh(&table->tb6_lock);
560 639
561restart_2: 640restart_2:
562 fn = fib6_lookup(&ip6_routing_table, &skb->nh.ipv6h->daddr, 641 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
563 &skb->nh.ipv6h->saddr);
564 642
565restart: 643restart:
566 rt = rt6_select(&fn->leaf, skb->dev->ifindex, strict | reachable); 644 rt = rt6_select(&fn->leaf, fl->iif, strict | reachable);
567 BACKTRACK(); 645 BACKTRACK(&fl->fl6_src);
568 if (rt == &ip6_null_entry || 646 if (rt == &ip6_null_entry ||
569 rt->rt6i_flags & RTF_CACHE) 647 rt->rt6i_flags & RTF_CACHE)
570 goto out; 648 goto out;
571 649
572 dst_hold(&rt->u.dst); 650 dst_hold(&rt->u.dst);
573 read_unlock_bh(&rt6_lock); 651 read_unlock_bh(&table->tb6_lock);
574 652
575 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 653 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
576 nrt = rt6_alloc_cow(rt, &skb->nh.ipv6h->daddr, &skb->nh.ipv6h->saddr); 654 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
577 else { 655 else {
578#if CLONE_OFFLINK_ROUTE 656#if CLONE_OFFLINK_ROUTE
579 nrt = rt6_alloc_clone(rt, &skb->nh.ipv6h->daddr); 657 nrt = rt6_alloc_clone(rt, &fl->fl6_dst);
580#else 658#else
581 goto out2; 659 goto out2;
582#endif 660#endif
@@ -587,7 +665,7 @@ restart:
587 665
588 dst_hold(&rt->u.dst); 666 dst_hold(&rt->u.dst);
589 if (nrt) { 667 if (nrt) {
590 err = ip6_ins_rt(nrt, NULL, NULL, &NETLINK_CB(skb)); 668 err = ip6_ins_rt(nrt);
591 if (!err) 669 if (!err)
592 goto out2; 670 goto out2;
593 } 671 }
@@ -596,7 +674,7 @@ restart:
596 goto out2; 674 goto out2;
597 675
598 /* 676 /*
599 * Race condition! In the gap, when rt6_lock was 677 * Race condition! In the gap, when table->tb6_lock was
600 * released someone could insert this route. Relookup. 678 * released someone could insert this route. Relookup.
601 */ 679 */
602 dst_release(&rt->u.dst); 680 dst_release(&rt->u.dst);
@@ -608,40 +686,63 @@ out:
608 goto restart_2; 686 goto restart_2;
609 } 687 }
610 dst_hold(&rt->u.dst); 688 dst_hold(&rt->u.dst);
611 read_unlock_bh(&rt6_lock); 689 read_unlock_bh(&table->tb6_lock);
612out2: 690out2:
613 rt->u.dst.lastuse = jiffies; 691 rt->u.dst.lastuse = jiffies;
614 rt->u.dst.__use++; 692 rt->u.dst.__use++;
615 skb->dst = (struct dst_entry *) rt; 693
616 return; 694 return rt;
617} 695}
618 696
619struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl) 697void ip6_route_input(struct sk_buff *skb)
698{
699 struct ipv6hdr *iph = skb->nh.ipv6h;
700 struct flowi fl = {
701 .iif = skb->dev->ifindex,
702 .nl_u = {
703 .ip6_u = {
704 .daddr = iph->daddr,
705 .saddr = iph->saddr,
706#ifdef CONFIG_IPV6_ROUTE_FWMARK
707 .fwmark = skb->nfmark,
708#endif
709 .flowlabel = (* (u32 *) iph)&IPV6_FLOWINFO_MASK,
710 },
711 },
712 .proto = iph->nexthdr,
713 };
714 int flags = rt6_need_strict(&iph->daddr) ? RT6_LOOKUP_F_IFACE : 0;
715
716 skb->dst = fib6_rule_lookup(&fl, flags, ip6_pol_route_input);
717}
718
719static struct rt6_info *ip6_pol_route_output(struct fib6_table *table,
720 struct flowi *fl, int flags)
620{ 721{
621 struct fib6_node *fn; 722 struct fib6_node *fn;
622 struct rt6_info *rt, *nrt; 723 struct rt6_info *rt, *nrt;
623 int strict; 724 int strict = 0;
624 int attempts = 3; 725 int attempts = 3;
625 int err; 726 int err;
626 int reachable = RT6_SELECT_F_REACHABLE; 727 int reachable = RT6_LOOKUP_F_REACHABLE;
627 728
628 strict = ipv6_addr_type(&fl->fl6_dst) & (IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL) ? RT6_SELECT_F_IFACE : 0; 729 strict |= flags & RT6_LOOKUP_F_IFACE;
629 730
630relookup: 731relookup:
631 read_lock_bh(&rt6_lock); 732 read_lock_bh(&table->tb6_lock);
632 733
633restart_2: 734restart_2:
634 fn = fib6_lookup(&ip6_routing_table, &fl->fl6_dst, &fl->fl6_src); 735 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
635 736
636restart: 737restart:
637 rt = rt6_select(&fn->leaf, fl->oif, strict | reachable); 738 rt = rt6_select(&fn->leaf, fl->oif, strict | reachable);
638 BACKTRACK(); 739 BACKTRACK(&fl->fl6_src);
639 if (rt == &ip6_null_entry || 740 if (rt == &ip6_null_entry ||
640 rt->rt6i_flags & RTF_CACHE) 741 rt->rt6i_flags & RTF_CACHE)
641 goto out; 742 goto out;
642 743
643 dst_hold(&rt->u.dst); 744 dst_hold(&rt->u.dst);
644 read_unlock_bh(&rt6_lock); 745 read_unlock_bh(&table->tb6_lock);
645 746
646 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP)) 747 if (!rt->rt6i_nexthop && !(rt->rt6i_flags & RTF_NONEXTHOP))
647 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src); 748 nrt = rt6_alloc_cow(rt, &fl->fl6_dst, &fl->fl6_src);
@@ -658,7 +759,7 @@ restart:
658 759
659 dst_hold(&rt->u.dst); 760 dst_hold(&rt->u.dst);
660 if (nrt) { 761 if (nrt) {
661 err = ip6_ins_rt(nrt, NULL, NULL, NULL); 762 err = ip6_ins_rt(nrt);
662 if (!err) 763 if (!err)
663 goto out2; 764 goto out2;
664 } 765 }
@@ -667,7 +768,7 @@ restart:
667 goto out2; 768 goto out2;
668 769
669 /* 770 /*
670 * Race condition! In the gap, when rt6_lock was 771 * Race condition! In the gap, when table->tb6_lock was
671 * released someone could insert this route. Relookup. 772 * released someone could insert this route. Relookup.
672 */ 773 */
673 dst_release(&rt->u.dst); 774 dst_release(&rt->u.dst);
@@ -679,11 +780,21 @@ out:
679 goto restart_2; 780 goto restart_2;
680 } 781 }
681 dst_hold(&rt->u.dst); 782 dst_hold(&rt->u.dst);
682 read_unlock_bh(&rt6_lock); 783 read_unlock_bh(&table->tb6_lock);
683out2: 784out2:
684 rt->u.dst.lastuse = jiffies; 785 rt->u.dst.lastuse = jiffies;
685 rt->u.dst.__use++; 786 rt->u.dst.__use++;
686 return &rt->u.dst; 787 return rt;
788}
789
790struct dst_entry * ip6_route_output(struct sock *sk, struct flowi *fl)
791{
792 int flags = 0;
793
794 if (rt6_need_strict(&fl->fl6_dst))
795 flags |= RT6_LOOKUP_F_IFACE;
796
797 return fib6_rule_lookup(fl, flags, ip6_pol_route_output);
687} 798}
688 799
689 800
@@ -709,7 +820,7 @@ static struct dst_entry *ip6_negative_advice(struct dst_entry *dst)
709 820
710 if (rt) { 821 if (rt) {
711 if (rt->rt6i_flags & RTF_CACHE) 822 if (rt->rt6i_flags & RTF_CACHE)
712 ip6_del_rt(rt, NULL, NULL, NULL); 823 ip6_del_rt(rt);
713 else 824 else
714 dst_release(dst); 825 dst_release(dst);
715 } 826 }
@@ -747,8 +858,6 @@ static void ip6_rt_update_pmtu(struct dst_entry *dst, u32 mtu)
747 } 858 }
748} 859}
749 860
750/* Protected by rt6_lock. */
751static struct dst_entry *ndisc_dst_gc_list;
752static int ipv6_get_mtu(struct net_device *dev); 861static int ipv6_get_mtu(struct net_device *dev);
753 862
754static inline unsigned int ipv6_advmss(unsigned int mtu) 863static inline unsigned int ipv6_advmss(unsigned int mtu)
@@ -769,6 +878,9 @@ static inline unsigned int ipv6_advmss(unsigned int mtu)
769 return mtu; 878 return mtu;
770} 879}
771 880
881static struct dst_entry *ndisc_dst_gc_list;
882static DEFINE_SPINLOCK(ndisc_lock);
883
772struct dst_entry *ndisc_dst_alloc(struct net_device *dev, 884struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
773 struct neighbour *neigh, 885 struct neighbour *neigh,
774 struct in6_addr *addr, 886 struct in6_addr *addr,
@@ -809,10 +921,10 @@ struct dst_entry *ndisc_dst_alloc(struct net_device *dev,
809 rt->rt6i_dst.plen = 128; 921 rt->rt6i_dst.plen = 128;
810#endif 922#endif
811 923
812 write_lock_bh(&rt6_lock); 924 spin_lock_bh(&ndisc_lock);
813 rt->u.dst.next = ndisc_dst_gc_list; 925 rt->u.dst.next = ndisc_dst_gc_list;
814 ndisc_dst_gc_list = &rt->u.dst; 926 ndisc_dst_gc_list = &rt->u.dst;
815 write_unlock_bh(&rt6_lock); 927 spin_unlock_bh(&ndisc_lock);
816 928
817 fib6_force_start_gc(); 929 fib6_force_start_gc();
818 930
@@ -826,8 +938,11 @@ int ndisc_dst_gc(int *more)
826 int freed; 938 int freed;
827 939
828 next = NULL; 940 next = NULL;
941 freed = 0;
942
943 spin_lock_bh(&ndisc_lock);
829 pprev = &ndisc_dst_gc_list; 944 pprev = &ndisc_dst_gc_list;
830 freed = 0; 945
831 while ((dst = *pprev) != NULL) { 946 while ((dst = *pprev) != NULL) {
832 if (!atomic_read(&dst->__refcnt)) { 947 if (!atomic_read(&dst->__refcnt)) {
833 *pprev = dst->next; 948 *pprev = dst->next;
@@ -839,6 +954,8 @@ int ndisc_dst_gc(int *more)
839 } 954 }
840 } 955 }
841 956
957 spin_unlock_bh(&ndisc_lock);
958
842 return freed; 959 return freed;
843} 960}
844 961
@@ -899,28 +1016,24 @@ int ipv6_get_hoplimit(struct net_device *dev)
899 * 1016 *
900 */ 1017 */
901 1018
902int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, 1019int ip6_route_add(struct fib6_config *cfg)
903 void *_rtattr, struct netlink_skb_parms *req)
904{ 1020{
905 int err; 1021 int err;
906 struct rtmsg *r;
907 struct rtattr **rta;
908 struct rt6_info *rt = NULL; 1022 struct rt6_info *rt = NULL;
909 struct net_device *dev = NULL; 1023 struct net_device *dev = NULL;
910 struct inet6_dev *idev = NULL; 1024 struct inet6_dev *idev = NULL;
1025 struct fib6_table *table;
911 int addr_type; 1026 int addr_type;
912 1027
913 rta = (struct rtattr **) _rtattr; 1028 if (cfg->fc_dst_len > 128 || cfg->fc_src_len > 128)
914
915 if (rtmsg->rtmsg_dst_len > 128 || rtmsg->rtmsg_src_len > 128)
916 return -EINVAL; 1029 return -EINVAL;
917#ifndef CONFIG_IPV6_SUBTREES 1030#ifndef CONFIG_IPV6_SUBTREES
918 if (rtmsg->rtmsg_src_len) 1031 if (cfg->fc_src_len)
919 return -EINVAL; 1032 return -EINVAL;
920#endif 1033#endif
921 if (rtmsg->rtmsg_ifindex) { 1034 if (cfg->fc_ifindex) {
922 err = -ENODEV; 1035 err = -ENODEV;
923 dev = dev_get_by_index(rtmsg->rtmsg_ifindex); 1036 dev = dev_get_by_index(cfg->fc_ifindex);
924 if (!dev) 1037 if (!dev)
925 goto out; 1038 goto out;
926 idev = in6_dev_get(dev); 1039 idev = in6_dev_get(dev);
@@ -928,8 +1041,14 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
928 goto out; 1041 goto out;
929 } 1042 }
930 1043
931 if (rtmsg->rtmsg_metric == 0) 1044 if (cfg->fc_metric == 0)
932 rtmsg->rtmsg_metric = IP6_RT_PRIO_USER; 1045 cfg->fc_metric = IP6_RT_PRIO_USER;
1046
1047 table = fib6_new_table(cfg->fc_table);
1048 if (table == NULL) {
1049 err = -ENOBUFS;
1050 goto out;
1051 }
933 1052
934 rt = ip6_dst_alloc(); 1053 rt = ip6_dst_alloc();
935 1054
@@ -939,14 +1058,13 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
939 } 1058 }
940 1059
941 rt->u.dst.obsolete = -1; 1060 rt->u.dst.obsolete = -1;
942 rt->rt6i_expires = jiffies + clock_t_to_jiffies(rtmsg->rtmsg_info); 1061 rt->rt6i_expires = jiffies + clock_t_to_jiffies(cfg->fc_expires);
943 if (nlh && (r = NLMSG_DATA(nlh))) {
944 rt->rt6i_protocol = r->rtm_protocol;
945 } else {
946 rt->rt6i_protocol = RTPROT_BOOT;
947 }
948 1062
949 addr_type = ipv6_addr_type(&rtmsg->rtmsg_dst); 1063 if (cfg->fc_protocol == RTPROT_UNSPEC)
1064 cfg->fc_protocol = RTPROT_BOOT;
1065 rt->rt6i_protocol = cfg->fc_protocol;
1066
1067 addr_type = ipv6_addr_type(&cfg->fc_dst);
950 1068
951 if (addr_type & IPV6_ADDR_MULTICAST) 1069 if (addr_type & IPV6_ADDR_MULTICAST)
952 rt->u.dst.input = ip6_mc_input; 1070 rt->u.dst.input = ip6_mc_input;
@@ -955,24 +1073,22 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
955 1073
956 rt->u.dst.output = ip6_output; 1074 rt->u.dst.output = ip6_output;
957 1075
958 ipv6_addr_prefix(&rt->rt6i_dst.addr, 1076 ipv6_addr_prefix(&rt->rt6i_dst.addr, &cfg->fc_dst, cfg->fc_dst_len);
959 &rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len); 1077 rt->rt6i_dst.plen = cfg->fc_dst_len;
960 rt->rt6i_dst.plen = rtmsg->rtmsg_dst_len;
961 if (rt->rt6i_dst.plen == 128) 1078 if (rt->rt6i_dst.plen == 128)
962 rt->u.dst.flags = DST_HOST; 1079 rt->u.dst.flags = DST_HOST;
963 1080
964#ifdef CONFIG_IPV6_SUBTREES 1081#ifdef CONFIG_IPV6_SUBTREES
965 ipv6_addr_prefix(&rt->rt6i_src.addr, 1082 ipv6_addr_prefix(&rt->rt6i_src.addr, &cfg->fc_src, cfg->fc_src_len);
966 &rtmsg->rtmsg_src, rtmsg->rtmsg_src_len); 1083 rt->rt6i_src.plen = cfg->fc_src_len;
967 rt->rt6i_src.plen = rtmsg->rtmsg_src_len;
968#endif 1084#endif
969 1085
970 rt->rt6i_metric = rtmsg->rtmsg_metric; 1086 rt->rt6i_metric = cfg->fc_metric;
971 1087
972 /* We cannot add true routes via loopback here, 1088 /* We cannot add true routes via loopback here,
973 they would result in kernel looping; promote them to reject routes 1089 they would result in kernel looping; promote them to reject routes
974 */ 1090 */
975 if ((rtmsg->rtmsg_flags&RTF_REJECT) || 1091 if ((cfg->fc_flags & RTF_REJECT) ||
976 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) { 1092 (dev && (dev->flags&IFF_LOOPBACK) && !(addr_type&IPV6_ADDR_LOOPBACK))) {
977 /* hold loopback dev/idev if we haven't done so. */ 1093 /* hold loopback dev/idev if we haven't done so. */
978 if (dev != &loopback_dev) { 1094 if (dev != &loopback_dev) {
@@ -995,12 +1111,12 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
995 goto install_route; 1111 goto install_route;
996 } 1112 }
997 1113
998 if (rtmsg->rtmsg_flags & RTF_GATEWAY) { 1114 if (cfg->fc_flags & RTF_GATEWAY) {
999 struct in6_addr *gw_addr; 1115 struct in6_addr *gw_addr;
1000 int gwa_type; 1116 int gwa_type;
1001 1117
1002 gw_addr = &rtmsg->rtmsg_gateway; 1118 gw_addr = &cfg->fc_gateway;
1003 ipv6_addr_copy(&rt->rt6i_gateway, &rtmsg->rtmsg_gateway); 1119 ipv6_addr_copy(&rt->rt6i_gateway, gw_addr);
1004 gwa_type = ipv6_addr_type(gw_addr); 1120 gwa_type = ipv6_addr_type(gw_addr);
1005 1121
1006 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) { 1122 if (gwa_type != (IPV6_ADDR_LINKLOCAL|IPV6_ADDR_UNICAST)) {
@@ -1017,7 +1133,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
1017 if (!(gwa_type&IPV6_ADDR_UNICAST)) 1133 if (!(gwa_type&IPV6_ADDR_UNICAST))
1018 goto out; 1134 goto out;
1019 1135
1020 grt = rt6_lookup(gw_addr, NULL, rtmsg->rtmsg_ifindex, 1); 1136 grt = rt6_lookup(gw_addr, NULL, cfg->fc_ifindex, 1);
1021 1137
1022 err = -EHOSTUNREACH; 1138 err = -EHOSTUNREACH;
1023 if (grt == NULL) 1139 if (grt == NULL)
@@ -1049,7 +1165,7 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
1049 if (dev == NULL) 1165 if (dev == NULL)
1050 goto out; 1166 goto out;
1051 1167
1052 if (rtmsg->rtmsg_flags & (RTF_GATEWAY|RTF_NONEXTHOP)) { 1168 if (cfg->fc_flags & (RTF_GATEWAY | RTF_NONEXTHOP)) {
1053 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev); 1169 rt->rt6i_nexthop = __neigh_lookup_errno(&nd_tbl, &rt->rt6i_gateway, dev);
1054 if (IS_ERR(rt->rt6i_nexthop)) { 1170 if (IS_ERR(rt->rt6i_nexthop)) {
1055 err = PTR_ERR(rt->rt6i_nexthop); 1171 err = PTR_ERR(rt->rt6i_nexthop);
@@ -1058,24 +1174,24 @@ int ip6_route_add(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh,
1058 } 1174 }
1059 } 1175 }
1060 1176
1061 rt->rt6i_flags = rtmsg->rtmsg_flags; 1177 rt->rt6i_flags = cfg->fc_flags;
1062 1178
1063install_route: 1179install_route:
1064 if (rta && rta[RTA_METRICS-1]) { 1180 if (cfg->fc_mx) {
1065 int attrlen = RTA_PAYLOAD(rta[RTA_METRICS-1]); 1181 struct nlattr *nla;
1066 struct rtattr *attr = RTA_DATA(rta[RTA_METRICS-1]); 1182 int remaining;
1067 1183
1068 while (RTA_OK(attr, attrlen)) { 1184 nla_for_each_attr(nla, cfg->fc_mx, cfg->fc_mx_len, remaining) {
1069 unsigned flavor = attr->rta_type; 1185 int type = nla->nla_type;
1070 if (flavor) { 1186
1071 if (flavor > RTAX_MAX) { 1187 if (type) {
1188 if (type > RTAX_MAX) {
1072 err = -EINVAL; 1189 err = -EINVAL;
1073 goto out; 1190 goto out;
1074 } 1191 }
1075 rt->u.dst.metrics[flavor-1] = 1192
1076 *(u32 *)RTA_DATA(attr); 1193 rt->u.dst.metrics[type - 1] = nla_get_u32(nla);
1077 } 1194 }
1078 attr = RTA_NEXT(attr, attrlen);
1079 } 1195 }
1080 } 1196 }
1081 1197
@@ -1087,7 +1203,8 @@ install_route:
1087 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst)); 1203 rt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&rt->u.dst));
1088 rt->u.dst.dev = dev; 1204 rt->u.dst.dev = dev;
1089 rt->rt6i_idev = idev; 1205 rt->rt6i_idev = idev;
1090 return ip6_ins_rt(rt, nlh, _rtattr, req); 1206 rt->rt6i_table = table;
1207 return __ip6_ins_rt(rt, &cfg->fc_nlinfo);
1091 1208
1092out: 1209out:
1093 if (dev) 1210 if (dev)
@@ -1099,51 +1216,65 @@ out:
1099 return err; 1216 return err;
1100} 1217}
1101 1218
1102int ip6_del_rt(struct rt6_info *rt, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) 1219static int __ip6_del_rt(struct rt6_info *rt, struct nl_info *info)
1103{ 1220{
1104 int err; 1221 int err;
1222 struct fib6_table *table;
1105 1223
1106 write_lock_bh(&rt6_lock); 1224 if (rt == &ip6_null_entry)
1225 return -ENOENT;
1107 1226
1108 err = fib6_del(rt, nlh, _rtattr, req); 1227 table = rt->rt6i_table;
1228 write_lock_bh(&table->tb6_lock);
1229
1230 err = fib6_del(rt, info);
1109 dst_release(&rt->u.dst); 1231 dst_release(&rt->u.dst);
1110 1232
1111 write_unlock_bh(&rt6_lock); 1233 write_unlock_bh(&table->tb6_lock);
1112 1234
1113 return err; 1235 return err;
1114} 1236}
1115 1237
1116static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_rtattr, struct netlink_skb_parms *req) 1238int ip6_del_rt(struct rt6_info *rt)
1117{ 1239{
1240 return __ip6_del_rt(rt, NULL);
1241}
1242
1243static int ip6_route_del(struct fib6_config *cfg)
1244{
1245 struct fib6_table *table;
1118 struct fib6_node *fn; 1246 struct fib6_node *fn;
1119 struct rt6_info *rt; 1247 struct rt6_info *rt;
1120 int err = -ESRCH; 1248 int err = -ESRCH;
1121 1249
1122 read_lock_bh(&rt6_lock); 1250 table = fib6_get_table(cfg->fc_table);
1251 if (table == NULL)
1252 return err;
1123 1253
1124 fn = fib6_locate(&ip6_routing_table, 1254 read_lock_bh(&table->tb6_lock);
1125 &rtmsg->rtmsg_dst, rtmsg->rtmsg_dst_len, 1255
1126 &rtmsg->rtmsg_src, rtmsg->rtmsg_src_len); 1256 fn = fib6_locate(&table->tb6_root,
1257 &cfg->fc_dst, cfg->fc_dst_len,
1258 &cfg->fc_src, cfg->fc_src_len);
1127 1259
1128 if (fn) { 1260 if (fn) {
1129 for (rt = fn->leaf; rt; rt = rt->u.next) { 1261 for (rt = fn->leaf; rt; rt = rt->u.next) {
1130 if (rtmsg->rtmsg_ifindex && 1262 if (cfg->fc_ifindex &&
1131 (rt->rt6i_dev == NULL || 1263 (rt->rt6i_dev == NULL ||
1132 rt->rt6i_dev->ifindex != rtmsg->rtmsg_ifindex)) 1264 rt->rt6i_dev->ifindex != cfg->fc_ifindex))
1133 continue; 1265 continue;
1134 if (rtmsg->rtmsg_flags&RTF_GATEWAY && 1266 if (cfg->fc_flags & RTF_GATEWAY &&
1135 !ipv6_addr_equal(&rtmsg->rtmsg_gateway, &rt->rt6i_gateway)) 1267 !ipv6_addr_equal(&cfg->fc_gateway, &rt->rt6i_gateway))
1136 continue; 1268 continue;
1137 if (rtmsg->rtmsg_metric && 1269 if (cfg->fc_metric && cfg->fc_metric != rt->rt6i_metric)
1138 rtmsg->rtmsg_metric != rt->rt6i_metric)
1139 continue; 1270 continue;
1140 dst_hold(&rt->u.dst); 1271 dst_hold(&rt->u.dst);
1141 read_unlock_bh(&rt6_lock); 1272 read_unlock_bh(&table->tb6_lock);
1142 1273
1143 return ip6_del_rt(rt, nlh, _rtattr, req); 1274 return __ip6_del_rt(rt, &cfg->fc_nlinfo);
1144 } 1275 }
1145 } 1276 }
1146 read_unlock_bh(&rt6_lock); 1277 read_unlock_bh(&table->tb6_lock);
1147 1278
1148 return err; 1279 return err;
1149} 1280}
@@ -1151,13 +1282,18 @@ static int ip6_route_del(struct in6_rtmsg *rtmsg, struct nlmsghdr *nlh, void *_r
1151/* 1282/*
1152 * Handle redirects 1283 * Handle redirects
1153 */ 1284 */
1154void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr, 1285struct ip6rd_flowi {
1155 struct neighbour *neigh, u8 *lladdr, int on_link) 1286 struct flowi fl;
1287 struct in6_addr gateway;
1288};
1289
1290static struct rt6_info *__ip6_route_redirect(struct fib6_table *table,
1291 struct flowi *fl,
1292 int flags)
1156{ 1293{
1157 struct rt6_info *rt, *nrt = NULL; 1294 struct ip6rd_flowi *rdfl = (struct ip6rd_flowi *)fl;
1158 int strict; 1295 struct rt6_info *rt;
1159 struct fib6_node *fn; 1296 struct fib6_node *fn;
1160 struct netevent_redirect netevent;
1161 1297
1162 /* 1298 /*
1163 * Get the "current" route for this destination and 1299 * Get the "current" route for this destination and
@@ -1169,10 +1305,9 @@ void rt6_redirect(struct in6_addr *dest, struct in6_addr *saddr,
1169 * is a bit fuzzy and one might need to check all possible 1305 * is a bit fuzzy and one might need to check all possible
1170 * routes. 1306 * routes.
1171 */ 1307 */
1172 strict = ipv6_addr_type(dest) & (IPV6_ADDR_MULTICAST | IPV6_ADDR_LINKLOCAL);
1173 1308
1174 read_lock_bh(&rt6_lock); 1309 read_lock_bh(&table->tb6_lock);
1175 fn = fib6_lookup(&ip6_routing_table, dest, NULL); 1310 fn = fib6_lookup(&table->tb6_root, &fl->fl6_dst, &fl->fl6_src);
1176restart: 1311restart:
1177 for (rt = fn->leaf; rt; rt = rt->u.next) { 1312 for (rt = fn->leaf; rt; rt = rt->u.next) {
1178 /* 1313 /*
@@ -1187,29 +1322,60 @@ restart:
1187 continue; 1322 continue;
1188 if (!(rt->rt6i_flags & RTF_GATEWAY)) 1323 if (!(rt->rt6i_flags & RTF_GATEWAY))
1189 continue; 1324 continue;
1190 if (neigh->dev != rt->rt6i_dev) 1325 if (fl->oif != rt->rt6i_dev->ifindex)
1191 continue; 1326 continue;
1192 if (!ipv6_addr_equal(saddr, &rt->rt6i_gateway)) 1327 if (!ipv6_addr_equal(&rdfl->gateway, &rt->rt6i_gateway))
1193 continue; 1328 continue;
1194 break; 1329 break;
1195 } 1330 }
1196 if (rt)
1197 dst_hold(&rt->u.dst);
1198 else if (strict) {
1199 while ((fn = fn->parent) != NULL) {
1200 if (fn->fn_flags & RTN_ROOT)
1201 break;
1202 if (fn->fn_flags & RTN_RTINFO)
1203 goto restart;
1204 }
1205 }
1206 read_unlock_bh(&rt6_lock);
1207 1331
1208 if (!rt) { 1332 if (!rt)
1333 rt = &ip6_null_entry;
1334 BACKTRACK(&fl->fl6_src);
1335out:
1336 dst_hold(&rt->u.dst);
1337
1338 read_unlock_bh(&table->tb6_lock);
1339
1340 return rt;
1341};
1342
1343static struct rt6_info *ip6_route_redirect(struct in6_addr *dest,
1344 struct in6_addr *src,
1345 struct in6_addr *gateway,
1346 struct net_device *dev)
1347{
1348 struct ip6rd_flowi rdfl = {
1349 .fl = {
1350 .oif = dev->ifindex,
1351 .nl_u = {
1352 .ip6_u = {
1353 .daddr = *dest,
1354 .saddr = *src,
1355 },
1356 },
1357 },
1358 .gateway = *gateway,
1359 };
1360 int flags = rt6_need_strict(dest) ? RT6_LOOKUP_F_IFACE : 0;
1361
1362 return (struct rt6_info *)fib6_rule_lookup((struct flowi *)&rdfl, flags, __ip6_route_redirect);
1363}
1364
1365void rt6_redirect(struct in6_addr *dest, struct in6_addr *src,
1366 struct in6_addr *saddr,
1367 struct neighbour *neigh, u8 *lladdr, int on_link)
1368{
1369 struct rt6_info *rt, *nrt = NULL;
1370 struct netevent_redirect netevent;
1371
1372 rt = ip6_route_redirect(dest, src, saddr, neigh->dev);
1373
1374 if (rt == &ip6_null_entry) {
1209 if (net_ratelimit()) 1375 if (net_ratelimit())
1210 printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop " 1376 printk(KERN_DEBUG "rt6_redirect: source isn't a valid nexthop "
1211 "for redirect target\n"); 1377 "for redirect target\n");
1212 return; 1378 goto out;
1213 } 1379 }
1214 1380
1215 /* 1381 /*
@@ -1252,7 +1418,7 @@ restart:
1252 nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev); 1418 nrt->u.dst.metrics[RTAX_MTU-1] = ipv6_get_mtu(neigh->dev);
1253 nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst)); 1419 nrt->u.dst.metrics[RTAX_ADVMSS-1] = ipv6_advmss(dst_mtu(&nrt->u.dst));
1254 1420
1255 if (ip6_ins_rt(nrt, NULL, NULL, NULL)) 1421 if (ip6_ins_rt(nrt))
1256 goto out; 1422 goto out;
1257 1423
1258 netevent.old = &rt->u.dst; 1424 netevent.old = &rt->u.dst;
@@ -1260,7 +1426,7 @@ restart:
1260 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent); 1426 call_netevent_notifiers(NETEVENT_REDIRECT, &netevent);
1261 1427
1262 if (rt->rt6i_flags&RTF_CACHE) { 1428 if (rt->rt6i_flags&RTF_CACHE) {
1263 ip6_del_rt(rt, NULL, NULL, NULL); 1429 ip6_del_rt(rt);
1264 return; 1430 return;
1265 } 1431 }
1266 1432
@@ -1342,7 +1508,7 @@ void rt6_pmtu_discovery(struct in6_addr *daddr, struct in6_addr *saddr,
1342 dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires); 1508 dst_set_expires(&nrt->u.dst, ip6_rt_mtu_expires);
1343 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES; 1509 nrt->rt6i_flags |= RTF_DYNAMIC|RTF_EXPIRES;
1344 1510
1345 ip6_ins_rt(nrt, NULL, NULL, NULL); 1511 ip6_ins_rt(nrt);
1346 } 1512 }
1347out: 1513out:
1348 dst_release(&rt->u.dst); 1514 dst_release(&rt->u.dst);
@@ -1378,6 +1544,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
1378#ifdef CONFIG_IPV6_SUBTREES 1544#ifdef CONFIG_IPV6_SUBTREES
1379 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key)); 1545 memcpy(&rt->rt6i_src, &ort->rt6i_src, sizeof(struct rt6key));
1380#endif 1546#endif
1547 rt->rt6i_table = ort->rt6i_table;
1381 } 1548 }
1382 return rt; 1549 return rt;
1383} 1550}
@@ -1388,9 +1555,14 @@ static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixle
1388{ 1555{
1389 struct fib6_node *fn; 1556 struct fib6_node *fn;
1390 struct rt6_info *rt = NULL; 1557 struct rt6_info *rt = NULL;
1558 struct fib6_table *table;
1559
1560 table = fib6_get_table(RT6_TABLE_INFO);
1561 if (table == NULL)
1562 return NULL;
1391 1563
1392 write_lock_bh(&rt6_lock); 1564 write_lock_bh(&table->tb6_lock);
1393 fn = fib6_locate(&ip6_routing_table, prefix ,prefixlen, NULL, 0); 1565 fn = fib6_locate(&table->tb6_root, prefix ,prefixlen, NULL, 0);
1394 if (!fn) 1566 if (!fn)
1395 goto out; 1567 goto out;
1396 1568
@@ -1405,7 +1577,7 @@ static struct rt6_info *rt6_get_route_info(struct in6_addr *prefix, int prefixle
1405 break; 1577 break;
1406 } 1578 }
1407out: 1579out:
1408 write_unlock_bh(&rt6_lock); 1580 write_unlock_bh(&table->tb6_lock);
1409 return rt; 1581 return rt;
1410} 1582}
1411 1583
@@ -1413,21 +1585,23 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
1413 struct in6_addr *gwaddr, int ifindex, 1585 struct in6_addr *gwaddr, int ifindex,
1414 unsigned pref) 1586 unsigned pref)
1415{ 1587{
1416 struct in6_rtmsg rtmsg; 1588 struct fib6_config cfg = {
1589 .fc_table = RT6_TABLE_INFO,
1590 .fc_metric = 1024,
1591 .fc_ifindex = ifindex,
1592 .fc_dst_len = prefixlen,
1593 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO |
1594 RTF_UP | RTF_PREF(pref),
1595 };
1596
1597 ipv6_addr_copy(&cfg.fc_dst, prefix);
1598 ipv6_addr_copy(&cfg.fc_gateway, gwaddr);
1417 1599
1418 memset(&rtmsg, 0, sizeof(rtmsg));
1419 rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1420 ipv6_addr_copy(&rtmsg.rtmsg_dst, prefix);
1421 rtmsg.rtmsg_dst_len = prefixlen;
1422 ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr);
1423 rtmsg.rtmsg_metric = 1024;
1424 rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_ROUTEINFO | RTF_UP | RTF_PREF(pref);
1425 /* We should treat it as a default route if prefix length is 0. */ 1600 /* We should treat it as a default route if prefix length is 0. */
1426 if (!prefixlen) 1601 if (!prefixlen)
1427 rtmsg.rtmsg_flags |= RTF_DEFAULT; 1602 cfg.fc_flags |= RTF_DEFAULT;
1428 rtmsg.rtmsg_ifindex = ifindex;
1429 1603
1430 ip6_route_add(&rtmsg, NULL, NULL, NULL); 1604 ip6_route_add(&cfg);
1431 1605
1432 return rt6_get_route_info(prefix, prefixlen, gwaddr, ifindex); 1606 return rt6_get_route_info(prefix, prefixlen, gwaddr, ifindex);
1433} 1607}
@@ -1436,12 +1610,14 @@ static struct rt6_info *rt6_add_route_info(struct in6_addr *prefix, int prefixle
1436struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev) 1610struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *dev)
1437{ 1611{
1438 struct rt6_info *rt; 1612 struct rt6_info *rt;
1439 struct fib6_node *fn; 1613 struct fib6_table *table;
1440 1614
1441 fn = &ip6_routing_table; 1615 table = fib6_get_table(RT6_TABLE_DFLT);
1616 if (table == NULL)
1617 return NULL;
1442 1618
1443 write_lock_bh(&rt6_lock); 1619 write_lock_bh(&table->tb6_lock);
1444 for (rt = fn->leaf; rt; rt=rt->u.next) { 1620 for (rt = table->tb6_root.leaf; rt; rt=rt->u.next) {
1445 if (dev == rt->rt6i_dev && 1621 if (dev == rt->rt6i_dev &&
1446 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) && 1622 ((rt->rt6i_flags & (RTF_ADDRCONF | RTF_DEFAULT)) == (RTF_ADDRCONF | RTF_DEFAULT)) &&
1447 ipv6_addr_equal(&rt->rt6i_gateway, addr)) 1623 ipv6_addr_equal(&rt->rt6i_gateway, addr))
@@ -1449,7 +1625,7 @@ struct rt6_info *rt6_get_dflt_router(struct in6_addr *addr, struct net_device *d
1449 } 1625 }
1450 if (rt) 1626 if (rt)
1451 dst_hold(&rt->u.dst); 1627 dst_hold(&rt->u.dst);
1452 write_unlock_bh(&rt6_lock); 1628 write_unlock_bh(&table->tb6_lock);
1453 return rt; 1629 return rt;
1454} 1630}
1455 1631
@@ -1457,43 +1633,65 @@ struct rt6_info *rt6_add_dflt_router(struct in6_addr *gwaddr,
1457 struct net_device *dev, 1633 struct net_device *dev,
1458 unsigned int pref) 1634 unsigned int pref)
1459{ 1635{
1460 struct in6_rtmsg rtmsg; 1636 struct fib6_config cfg = {
1637 .fc_table = RT6_TABLE_DFLT,
1638 .fc_metric = 1024,
1639 .fc_ifindex = dev->ifindex,
1640 .fc_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT |
1641 RTF_UP | RTF_EXPIRES | RTF_PREF(pref),
1642 };
1461 1643
1462 memset(&rtmsg, 0, sizeof(struct in6_rtmsg)); 1644 ipv6_addr_copy(&cfg.fc_gateway, gwaddr);
1463 rtmsg.rtmsg_type = RTMSG_NEWROUTE;
1464 ipv6_addr_copy(&rtmsg.rtmsg_gateway, gwaddr);
1465 rtmsg.rtmsg_metric = 1024;
1466 rtmsg.rtmsg_flags = RTF_GATEWAY | RTF_ADDRCONF | RTF_DEFAULT | RTF_UP | RTF_EXPIRES |
1467 RTF_PREF(pref);
1468 1645
1469 rtmsg.rtmsg_ifindex = dev->ifindex; 1646 ip6_route_add(&cfg);
1470 1647
1471 ip6_route_add(&rtmsg, NULL, NULL, NULL);
1472 return rt6_get_dflt_router(gwaddr, dev); 1648 return rt6_get_dflt_router(gwaddr, dev);
1473} 1649}
1474 1650
1475void rt6_purge_dflt_routers(void) 1651void rt6_purge_dflt_routers(void)
1476{ 1652{
1477 struct rt6_info *rt; 1653 struct rt6_info *rt;
1654 struct fib6_table *table;
1655
1656 /* NOTE: Keep consistent with rt6_get_dflt_router */
1657 table = fib6_get_table(RT6_TABLE_DFLT);
1658 if (table == NULL)
1659 return;
1478 1660
1479restart: 1661restart:
1480 read_lock_bh(&rt6_lock); 1662 read_lock_bh(&table->tb6_lock);
1481 for (rt = ip6_routing_table.leaf; rt; rt = rt->u.next) { 1663 for (rt = table->tb6_root.leaf; rt; rt = rt->u.next) {
1482 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) { 1664 if (rt->rt6i_flags & (RTF_DEFAULT | RTF_ADDRCONF)) {
1483 dst_hold(&rt->u.dst); 1665 dst_hold(&rt->u.dst);
1484 1666 read_unlock_bh(&table->tb6_lock);
1485 read_unlock_bh(&rt6_lock); 1667 ip6_del_rt(rt);
1486
1487 ip6_del_rt(rt, NULL, NULL, NULL);
1488
1489 goto restart; 1668 goto restart;
1490 } 1669 }
1491 } 1670 }
1492 read_unlock_bh(&rt6_lock); 1671 read_unlock_bh(&table->tb6_lock);
1672}
1673
1674static void rtmsg_to_fib6_config(struct in6_rtmsg *rtmsg,
1675 struct fib6_config *cfg)
1676{
1677 memset(cfg, 0, sizeof(*cfg));
1678
1679 cfg->fc_table = RT6_TABLE_MAIN;
1680 cfg->fc_ifindex = rtmsg->rtmsg_ifindex;
1681 cfg->fc_metric = rtmsg->rtmsg_metric;
1682 cfg->fc_expires = rtmsg->rtmsg_info;
1683 cfg->fc_dst_len = rtmsg->rtmsg_dst_len;
1684 cfg->fc_src_len = rtmsg->rtmsg_src_len;
1685 cfg->fc_flags = rtmsg->rtmsg_flags;
1686
1687 ipv6_addr_copy(&cfg->fc_dst, &rtmsg->rtmsg_dst);
1688 ipv6_addr_copy(&cfg->fc_src, &rtmsg->rtmsg_src);
1689 ipv6_addr_copy(&cfg->fc_gateway, &rtmsg->rtmsg_gateway);
1493} 1690}
1494 1691
1495int ipv6_route_ioctl(unsigned int cmd, void __user *arg) 1692int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1496{ 1693{
1694 struct fib6_config cfg;
1497 struct in6_rtmsg rtmsg; 1695 struct in6_rtmsg rtmsg;
1498 int err; 1696 int err;
1499 1697
@@ -1506,14 +1704,16 @@ int ipv6_route_ioctl(unsigned int cmd, void __user *arg)
1506 sizeof(struct in6_rtmsg)); 1704 sizeof(struct in6_rtmsg));
1507 if (err) 1705 if (err)
1508 return -EFAULT; 1706 return -EFAULT;
1509 1707
1708 rtmsg_to_fib6_config(&rtmsg, &cfg);
1709
1510 rtnl_lock(); 1710 rtnl_lock();
1511 switch (cmd) { 1711 switch (cmd) {
1512 case SIOCADDRT: 1712 case SIOCADDRT:
1513 err = ip6_route_add(&rtmsg, NULL, NULL, NULL); 1713 err = ip6_route_add(&cfg);
1514 break; 1714 break;
1515 case SIOCDELRT: 1715 case SIOCDELRT:
1516 err = ip6_route_del(&rtmsg, NULL, NULL, NULL); 1716 err = ip6_route_del(&cfg);
1517 break; 1717 break;
1518 default: 1718 default:
1519 err = -EINVAL; 1719 err = -EINVAL;
@@ -1587,6 +1787,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
1587 1787
1588 ipv6_addr_copy(&rt->rt6i_dst.addr, addr); 1788 ipv6_addr_copy(&rt->rt6i_dst.addr, addr);
1589 rt->rt6i_dst.plen = 128; 1789 rt->rt6i_dst.plen = 128;
1790 rt->rt6i_table = fib6_get_table(RT6_TABLE_LOCAL);
1590 1791
1591 atomic_set(&rt->u.dst.__refcnt, 1); 1792 atomic_set(&rt->u.dst.__refcnt, 1);
1592 1793
@@ -1605,9 +1806,7 @@ static int fib6_ifdown(struct rt6_info *rt, void *arg)
1605 1806
1606void rt6_ifdown(struct net_device *dev) 1807void rt6_ifdown(struct net_device *dev)
1607{ 1808{
1608 write_lock_bh(&rt6_lock); 1809 fib6_clean_all(fib6_ifdown, 0, dev);
1609 fib6_clean_tree(&ip6_routing_table, fib6_ifdown, 0, dev);
1610 write_unlock_bh(&rt6_lock);
1611} 1810}
1612 1811
1613struct rt6_mtu_change_arg 1812struct rt6_mtu_change_arg
@@ -1657,80 +1856,114 @@ static int rt6_mtu_change_route(struct rt6_info *rt, void *p_arg)
1657 1856
1658void rt6_mtu_change(struct net_device *dev, unsigned mtu) 1857void rt6_mtu_change(struct net_device *dev, unsigned mtu)
1659{ 1858{
1660 struct rt6_mtu_change_arg arg; 1859 struct rt6_mtu_change_arg arg = {
1860 .dev = dev,
1861 .mtu = mtu,
1862 };
1661 1863
1662 arg.dev = dev; 1864 fib6_clean_all(rt6_mtu_change_route, 0, &arg);
1663 arg.mtu = mtu;
1664 read_lock_bh(&rt6_lock);
1665 fib6_clean_tree(&ip6_routing_table, rt6_mtu_change_route, 0, &arg);
1666 read_unlock_bh(&rt6_lock);
1667} 1865}
1668 1866
1669static int inet6_rtm_to_rtmsg(struct rtmsg *r, struct rtattr **rta, 1867static struct nla_policy rtm_ipv6_policy[RTA_MAX+1] __read_mostly = {
1670 struct in6_rtmsg *rtmsg) 1868 [RTA_GATEWAY] = { .len = sizeof(struct in6_addr) },
1869 [RTA_OIF] = { .type = NLA_U32 },
1870 [RTA_IIF] = { .type = NLA_U32 },
1871 [RTA_PRIORITY] = { .type = NLA_U32 },
1872 [RTA_METRICS] = { .type = NLA_NESTED },
1873};
1874
1875static int rtm_to_fib6_config(struct sk_buff *skb, struct nlmsghdr *nlh,
1876 struct fib6_config *cfg)
1671{ 1877{
1672 memset(rtmsg, 0, sizeof(*rtmsg)); 1878 struct rtmsg *rtm;
1879 struct nlattr *tb[RTA_MAX+1];
1880 int err;
1673 1881
1674 rtmsg->rtmsg_dst_len = r->rtm_dst_len; 1882 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
1675 rtmsg->rtmsg_src_len = r->rtm_src_len; 1883 if (err < 0)
1676 rtmsg->rtmsg_flags = RTF_UP; 1884 goto errout;
1677 if (r->rtm_type == RTN_UNREACHABLE)
1678 rtmsg->rtmsg_flags |= RTF_REJECT;
1679 1885
1680 if (rta[RTA_GATEWAY-1]) { 1886 err = -EINVAL;
1681 if (rta[RTA_GATEWAY-1]->rta_len != RTA_LENGTH(16)) 1887 rtm = nlmsg_data(nlh);
1682 return -EINVAL; 1888 memset(cfg, 0, sizeof(*cfg));
1683 memcpy(&rtmsg->rtmsg_gateway, RTA_DATA(rta[RTA_GATEWAY-1]), 16); 1889
1684 rtmsg->rtmsg_flags |= RTF_GATEWAY; 1890 cfg->fc_table = rtm->rtm_table;
1685 } 1891 cfg->fc_dst_len = rtm->rtm_dst_len;
1686 if (rta[RTA_DST-1]) { 1892 cfg->fc_src_len = rtm->rtm_src_len;
1687 if (RTA_PAYLOAD(rta[RTA_DST-1]) < ((r->rtm_dst_len+7)>>3)) 1893 cfg->fc_flags = RTF_UP;
1688 return -EINVAL; 1894 cfg->fc_protocol = rtm->rtm_protocol;
1689 memcpy(&rtmsg->rtmsg_dst, RTA_DATA(rta[RTA_DST-1]), ((r->rtm_dst_len+7)>>3)); 1895
1896 if (rtm->rtm_type == RTN_UNREACHABLE)
1897 cfg->fc_flags |= RTF_REJECT;
1898
1899 cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;
1900 cfg->fc_nlinfo.nlh = nlh;
1901
1902 if (tb[RTA_GATEWAY]) {
1903 nla_memcpy(&cfg->fc_gateway, tb[RTA_GATEWAY], 16);
1904 cfg->fc_flags |= RTF_GATEWAY;
1690 } 1905 }
1691 if (rta[RTA_SRC-1]) { 1906
1692 if (RTA_PAYLOAD(rta[RTA_SRC-1]) < ((r->rtm_src_len+7)>>3)) 1907 if (tb[RTA_DST]) {
1693 return -EINVAL; 1908 int plen = (rtm->rtm_dst_len + 7) >> 3;
1694 memcpy(&rtmsg->rtmsg_src, RTA_DATA(rta[RTA_SRC-1]), ((r->rtm_src_len+7)>>3)); 1909
1910 if (nla_len(tb[RTA_DST]) < plen)
1911 goto errout;
1912
1913 nla_memcpy(&cfg->fc_dst, tb[RTA_DST], plen);
1695 } 1914 }
1696 if (rta[RTA_OIF-1]) { 1915
1697 if (rta[RTA_OIF-1]->rta_len != RTA_LENGTH(sizeof(int))) 1916 if (tb[RTA_SRC]) {
1698 return -EINVAL; 1917 int plen = (rtm->rtm_src_len + 7) >> 3;
1699 memcpy(&rtmsg->rtmsg_ifindex, RTA_DATA(rta[RTA_OIF-1]), sizeof(int)); 1918
1919 if (nla_len(tb[RTA_SRC]) < plen)
1920 goto errout;
1921
1922 nla_memcpy(&cfg->fc_src, tb[RTA_SRC], plen);
1700 } 1923 }
1701 if (rta[RTA_PRIORITY-1]) { 1924
1702 if (rta[RTA_PRIORITY-1]->rta_len != RTA_LENGTH(4)) 1925 if (tb[RTA_OIF])
1703 return -EINVAL; 1926 cfg->fc_ifindex = nla_get_u32(tb[RTA_OIF]);
1704 memcpy(&rtmsg->rtmsg_metric, RTA_DATA(rta[RTA_PRIORITY-1]), 4); 1927
1928 if (tb[RTA_PRIORITY])
1929 cfg->fc_metric = nla_get_u32(tb[RTA_PRIORITY]);
1930
1931 if (tb[RTA_METRICS]) {
1932 cfg->fc_mx = nla_data(tb[RTA_METRICS]);
1933 cfg->fc_mx_len = nla_len(tb[RTA_METRICS]);
1705 } 1934 }
1706 return 0; 1935
1936 if (tb[RTA_TABLE])
1937 cfg->fc_table = nla_get_u32(tb[RTA_TABLE]);
1938
1939 err = 0;
1940errout:
1941 return err;
1707} 1942}
1708 1943
1709int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1944int inet6_rtm_delroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
1710{ 1945{
1711 struct rtmsg *r = NLMSG_DATA(nlh); 1946 struct fib6_config cfg;
1712 struct in6_rtmsg rtmsg; 1947 int err;
1713 1948
1714 if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) 1949 err = rtm_to_fib6_config(skb, nlh, &cfg);
1715 return -EINVAL; 1950 if (err < 0)
1716 return ip6_route_del(&rtmsg, nlh, arg, &NETLINK_CB(skb)); 1951 return err;
1952
1953 return ip6_route_del(&cfg);
1717} 1954}
1718 1955
1719int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1956int inet6_rtm_newroute(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
1720{ 1957{
1721 struct rtmsg *r = NLMSG_DATA(nlh); 1958 struct fib6_config cfg;
1722 struct in6_rtmsg rtmsg; 1959 int err;
1723 1960
1724 if (inet6_rtm_to_rtmsg(r, arg, &rtmsg)) 1961 err = rtm_to_fib6_config(skb, nlh, &cfg);
1725 return -EINVAL; 1962 if (err < 0)
1726 return ip6_route_add(&rtmsg, nlh, arg, &NETLINK_CB(skb)); 1963 return err;
1727}
1728 1964
1729struct rt6_rtnl_dump_arg 1965 return ip6_route_add(&cfg);
1730{ 1966}
1731 struct sk_buff *skb;
1732 struct netlink_callback *cb;
1733};
1734 1967
1735static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt, 1968static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1736 struct in6_addr *dst, struct in6_addr *src, 1969 struct in6_addr *dst, struct in6_addr *src,
@@ -1738,9 +1971,9 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1738 int prefix, unsigned int flags) 1971 int prefix, unsigned int flags)
1739{ 1972{
1740 struct rtmsg *rtm; 1973 struct rtmsg *rtm;
1741 struct nlmsghdr *nlh; 1974 struct nlmsghdr *nlh;
1742 unsigned char *b = skb->tail;
1743 struct rta_cacheinfo ci; 1975 struct rta_cacheinfo ci;
1976 u32 table;
1744 1977
1745 if (prefix) { /* user wants prefix routes only */ 1978 if (prefix) { /* user wants prefix routes only */
1746 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) { 1979 if (!(rt->rt6i_flags & RTF_PREFIX_RT)) {
@@ -1749,13 +1982,21 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1749 } 1982 }
1750 } 1983 }
1751 1984
1752 nlh = NLMSG_NEW(skb, pid, seq, type, sizeof(*rtm), flags); 1985 nlh = nlmsg_put(skb, pid, seq, type, sizeof(*rtm), flags);
1753 rtm = NLMSG_DATA(nlh); 1986 if (nlh == NULL)
1987 return -ENOBUFS;
1988
1989 rtm = nlmsg_data(nlh);
1754 rtm->rtm_family = AF_INET6; 1990 rtm->rtm_family = AF_INET6;
1755 rtm->rtm_dst_len = rt->rt6i_dst.plen; 1991 rtm->rtm_dst_len = rt->rt6i_dst.plen;
1756 rtm->rtm_src_len = rt->rt6i_src.plen; 1992 rtm->rtm_src_len = rt->rt6i_src.plen;
1757 rtm->rtm_tos = 0; 1993 rtm->rtm_tos = 0;
1758 rtm->rtm_table = RT_TABLE_MAIN; 1994 if (rt->rt6i_table)
1995 table = rt->rt6i_table->tb6_id;
1996 else
1997 table = RT6_TABLE_UNSPEC;
1998 rtm->rtm_table = table;
1999 NLA_PUT_U32(skb, RTA_TABLE, table);
1759 if (rt->rt6i_flags&RTF_REJECT) 2000 if (rt->rt6i_flags&RTF_REJECT)
1760 rtm->rtm_type = RTN_UNREACHABLE; 2001 rtm->rtm_type = RTN_UNREACHABLE;
1761 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK)) 2002 else if (rt->rt6i_dev && (rt->rt6i_dev->flags&IFF_LOOPBACK))
@@ -1776,31 +2017,35 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1776 rtm->rtm_flags |= RTM_F_CLONED; 2017 rtm->rtm_flags |= RTM_F_CLONED;
1777 2018
1778 if (dst) { 2019 if (dst) {
1779 RTA_PUT(skb, RTA_DST, 16, dst); 2020 NLA_PUT(skb, RTA_DST, 16, dst);
1780 rtm->rtm_dst_len = 128; 2021 rtm->rtm_dst_len = 128;
1781 } else if (rtm->rtm_dst_len) 2022 } else if (rtm->rtm_dst_len)
1782 RTA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr); 2023 NLA_PUT(skb, RTA_DST, 16, &rt->rt6i_dst.addr);
1783#ifdef CONFIG_IPV6_SUBTREES 2024#ifdef CONFIG_IPV6_SUBTREES
1784 if (src) { 2025 if (src) {
1785 RTA_PUT(skb, RTA_SRC, 16, src); 2026 NLA_PUT(skb, RTA_SRC, 16, src);
1786 rtm->rtm_src_len = 128; 2027 rtm->rtm_src_len = 128;
1787 } else if (rtm->rtm_src_len) 2028 } else if (rtm->rtm_src_len)
1788 RTA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr); 2029 NLA_PUT(skb, RTA_SRC, 16, &rt->rt6i_src.addr);
1789#endif 2030#endif
1790 if (iif) 2031 if (iif)
1791 RTA_PUT(skb, RTA_IIF, 4, &iif); 2032 NLA_PUT_U32(skb, RTA_IIF, iif);
1792 else if (dst) { 2033 else if (dst) {
1793 struct in6_addr saddr_buf; 2034 struct in6_addr saddr_buf;
1794 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0) 2035 if (ipv6_get_saddr(&rt->u.dst, dst, &saddr_buf) == 0)
1795 RTA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf); 2036 NLA_PUT(skb, RTA_PREFSRC, 16, &saddr_buf);
1796 } 2037 }
2038
1797 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0) 2039 if (rtnetlink_put_metrics(skb, rt->u.dst.metrics) < 0)
1798 goto rtattr_failure; 2040 goto nla_put_failure;
2041
1799 if (rt->u.dst.neighbour) 2042 if (rt->u.dst.neighbour)
1800 RTA_PUT(skb, RTA_GATEWAY, 16, &rt->u.dst.neighbour->primary_key); 2043 NLA_PUT(skb, RTA_GATEWAY, 16, &rt->u.dst.neighbour->primary_key);
2044
1801 if (rt->u.dst.dev) 2045 if (rt->u.dst.dev)
1802 RTA_PUT(skb, RTA_OIF, sizeof(int), &rt->rt6i_dev->ifindex); 2046 NLA_PUT_U32(skb, RTA_OIF, rt->rt6i_dev->ifindex);
1803 RTA_PUT(skb, RTA_PRIORITY, 4, &rt->rt6i_metric); 2047
2048 NLA_PUT_U32(skb, RTA_PRIORITY, rt->rt6i_metric);
1804 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse); 2049 ci.rta_lastuse = jiffies_to_clock_t(jiffies - rt->u.dst.lastuse);
1805 if (rt->rt6i_expires) 2050 if (rt->rt6i_expires)
1806 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies); 2051 ci.rta_expires = jiffies_to_clock_t(rt->rt6i_expires - jiffies);
@@ -1812,23 +2057,21 @@ static int rt6_fill_node(struct sk_buff *skb, struct rt6_info *rt,
1812 ci.rta_id = 0; 2057 ci.rta_id = 0;
1813 ci.rta_ts = 0; 2058 ci.rta_ts = 0;
1814 ci.rta_tsage = 0; 2059 ci.rta_tsage = 0;
1815 RTA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci); 2060 NLA_PUT(skb, RTA_CACHEINFO, sizeof(ci), &ci);
1816 nlh->nlmsg_len = skb->tail - b;
1817 return skb->len;
1818 2061
1819nlmsg_failure: 2062 return nlmsg_end(skb, nlh);
1820rtattr_failure: 2063
1821 skb_trim(skb, b - skb->data); 2064nla_put_failure:
1822 return -1; 2065 return nlmsg_cancel(skb, nlh);
1823} 2066}
1824 2067
1825static int rt6_dump_route(struct rt6_info *rt, void *p_arg) 2068int rt6_dump_route(struct rt6_info *rt, void *p_arg)
1826{ 2069{
1827 struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg; 2070 struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
1828 int prefix; 2071 int prefix;
1829 2072
1830 if (arg->cb->nlh->nlmsg_len >= NLMSG_LENGTH(sizeof(struct rtmsg))) { 2073 if (nlmsg_len(arg->cb->nlh) >= sizeof(struct rtmsg)) {
1831 struct rtmsg *rtm = NLMSG_DATA(arg->cb->nlh); 2074 struct rtmsg *rtm = nlmsg_data(arg->cb->nlh);
1832 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0; 2075 prefix = (rtm->rtm_flags & RTM_F_PREFIX) != 0;
1833 } else 2076 } else
1834 prefix = 0; 2077 prefix = 0;
@@ -1838,189 +2081,108 @@ static int rt6_dump_route(struct rt6_info *rt, void *p_arg)
1838 prefix, NLM_F_MULTI); 2081 prefix, NLM_F_MULTI);
1839} 2082}
1840 2083
1841static int fib6_dump_node(struct fib6_walker_t *w) 2084int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
1842{ 2085{
1843 int res; 2086 struct nlattr *tb[RTA_MAX+1];
1844 struct rt6_info *rt; 2087 struct rt6_info *rt;
2088 struct sk_buff *skb;
2089 struct rtmsg *rtm;
2090 struct flowi fl;
2091 int err, iif = 0;
1845 2092
1846 for (rt = w->leaf; rt; rt = rt->u.next) { 2093 err = nlmsg_parse(nlh, sizeof(*rtm), tb, RTA_MAX, rtm_ipv6_policy);
1847 res = rt6_dump_route(rt, w->args); 2094 if (err < 0)
1848 if (res < 0) { 2095 goto errout;
1849 /* Frame is full, suspend walking */
1850 w->leaf = rt;
1851 return 1;
1852 }
1853 BUG_TRAP(res!=0);
1854 }
1855 w->leaf = NULL;
1856 return 0;
1857}
1858
1859static void fib6_dump_end(struct netlink_callback *cb)
1860{
1861 struct fib6_walker_t *w = (void*)cb->args[0];
1862
1863 if (w) {
1864 cb->args[0] = 0;
1865 fib6_walker_unlink(w);
1866 kfree(w);
1867 }
1868 cb->done = (void*)cb->args[1];
1869 cb->args[1] = 0;
1870}
1871
1872static int fib6_dump_done(struct netlink_callback *cb)
1873{
1874 fib6_dump_end(cb);
1875 return cb->done ? cb->done(cb) : 0;
1876}
1877
1878int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
1879{
1880 struct rt6_rtnl_dump_arg arg;
1881 struct fib6_walker_t *w;
1882 int res;
1883 2096
1884 arg.skb = skb; 2097 err = -EINVAL;
1885 arg.cb = cb; 2098 memset(&fl, 0, sizeof(fl));
1886 2099
1887 w = (void*)cb->args[0]; 2100 if (tb[RTA_SRC]) {
1888 if (w == NULL) { 2101 if (nla_len(tb[RTA_SRC]) < sizeof(struct in6_addr))
1889 /* New dump: 2102 goto errout;
1890 *
1891 * 1. hook callback destructor.
1892 */
1893 cb->args[1] = (long)cb->done;
1894 cb->done = fib6_dump_done;
1895 2103
1896 /* 2104 ipv6_addr_copy(&fl.fl6_src, nla_data(tb[RTA_SRC]));
1897 * 2. allocate and initialize walker.
1898 */
1899 w = kzalloc(sizeof(*w), GFP_ATOMIC);
1900 if (w == NULL)
1901 return -ENOMEM;
1902 RT6_TRACE("dump<%p", w);
1903 w->root = &ip6_routing_table;
1904 w->func = fib6_dump_node;
1905 w->args = &arg;
1906 cb->args[0] = (long)w;
1907 read_lock_bh(&rt6_lock);
1908 res = fib6_walk(w);
1909 read_unlock_bh(&rt6_lock);
1910 } else {
1911 w->args = &arg;
1912 read_lock_bh(&rt6_lock);
1913 res = fib6_walk_continue(w);
1914 read_unlock_bh(&rt6_lock);
1915 } 2105 }
1916#if RT6_DEBUG >= 3
1917 if (res <= 0 && skb->len == 0)
1918 RT6_TRACE("%p>dump end\n", w);
1919#endif
1920 res = res < 0 ? res : skb->len;
1921 /* res < 0 is an error. (really, impossible)
1922 res == 0 means that dump is complete, but skb still can contain data.
1923 res > 0 dump is not complete, but frame is full.
1924 */
1925 /* Destroy walker, if dump of this table is complete. */
1926 if (res <= 0)
1927 fib6_dump_end(cb);
1928 return res;
1929}
1930
1931int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg)
1932{
1933 struct rtattr **rta = arg;
1934 int iif = 0;
1935 int err = -ENOBUFS;
1936 struct sk_buff *skb;
1937 struct flowi fl;
1938 struct rt6_info *rt;
1939 2106
1940 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); 2107 if (tb[RTA_DST]) {
1941 if (skb == NULL) 2108 if (nla_len(tb[RTA_DST]) < sizeof(struct in6_addr))
1942 goto out; 2109 goto errout;
1943 2110
1944 /* Reserve room for dummy headers, this skb can pass 2111 ipv6_addr_copy(&fl.fl6_dst, nla_data(tb[RTA_DST]));
1945 through good chunk of routing engine. 2112 }
1946 */
1947 skb->mac.raw = skb->data;
1948 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
1949 2113
1950 memset(&fl, 0, sizeof(fl)); 2114 if (tb[RTA_IIF])
1951 if (rta[RTA_SRC-1]) 2115 iif = nla_get_u32(tb[RTA_IIF]);
1952 ipv6_addr_copy(&fl.fl6_src,
1953 (struct in6_addr*)RTA_DATA(rta[RTA_SRC-1]));
1954 if (rta[RTA_DST-1])
1955 ipv6_addr_copy(&fl.fl6_dst,
1956 (struct in6_addr*)RTA_DATA(rta[RTA_DST-1]));
1957 2116
1958 if (rta[RTA_IIF-1]) 2117 if (tb[RTA_OIF])
1959 memcpy(&iif, RTA_DATA(rta[RTA_IIF-1]), sizeof(int)); 2118 fl.oif = nla_get_u32(tb[RTA_OIF]);
1960 2119
1961 if (iif) { 2120 if (iif) {
1962 struct net_device *dev; 2121 struct net_device *dev;
1963 dev = __dev_get_by_index(iif); 2122 dev = __dev_get_by_index(iif);
1964 if (!dev) { 2123 if (!dev) {
1965 err = -ENODEV; 2124 err = -ENODEV;
1966 goto out_free; 2125 goto errout;
1967 } 2126 }
1968 } 2127 }
1969 2128
1970 fl.oif = 0; 2129 skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
1971 if (rta[RTA_OIF-1]) 2130 if (skb == NULL) {
1972 memcpy(&fl.oif, RTA_DATA(rta[RTA_OIF-1]), sizeof(int)); 2131 err = -ENOBUFS;
2132 goto errout;
2133 }
1973 2134
1974 rt = (struct rt6_info*)ip6_route_output(NULL, &fl); 2135 /* Reserve room for dummy headers, this skb can pass
2136 through good chunk of routing engine.
2137 */
2138 skb->mac.raw = skb->data;
2139 skb_reserve(skb, MAX_HEADER + sizeof(struct ipv6hdr));
1975 2140
2141 rt = (struct rt6_info*) ip6_route_output(NULL, &fl);
1976 skb->dst = &rt->u.dst; 2142 skb->dst = &rt->u.dst;
1977 2143
1978 NETLINK_CB(skb).dst_pid = NETLINK_CB(in_skb).pid; 2144 err = rt6_fill_node(skb, rt, &fl.fl6_dst, &fl.fl6_src, iif,
1979 err = rt6_fill_node(skb, rt,
1980 &fl.fl6_dst, &fl.fl6_src,
1981 iif,
1982 RTM_NEWROUTE, NETLINK_CB(in_skb).pid, 2145 RTM_NEWROUTE, NETLINK_CB(in_skb).pid,
1983 nlh->nlmsg_seq, 0, 0); 2146 nlh->nlmsg_seq, 0, 0);
1984 if (err < 0) { 2147 if (err < 0) {
1985 err = -EMSGSIZE; 2148 kfree_skb(skb);
1986 goto out_free; 2149 goto errout;
1987 } 2150 }
1988 2151
1989 err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); 2152 err = rtnl_unicast(skb, NETLINK_CB(in_skb).pid);
1990 if (err > 0) 2153errout:
1991 err = 0;
1992out:
1993 return err; 2154 return err;
1994out_free:
1995 kfree_skb(skb);
1996 goto out;
1997} 2155}
1998 2156
1999void inet6_rt_notify(int event, struct rt6_info *rt, struct nlmsghdr *nlh, 2157void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info)
2000 struct netlink_skb_parms *req)
2001{ 2158{
2002 struct sk_buff *skb; 2159 struct sk_buff *skb;
2003 int size = NLMSG_SPACE(sizeof(struct rtmsg)+256); 2160 u32 pid = 0, seq = 0;
2004 u32 pid = current->pid; 2161 struct nlmsghdr *nlh = NULL;
2005 u32 seq = 0; 2162 int payload = sizeof(struct rtmsg) + 256;
2006 2163 int err = -ENOBUFS;
2007 if (req) 2164
2008 pid = req->pid; 2165 if (info) {
2009 if (nlh) 2166 pid = info->pid;
2010 seq = nlh->nlmsg_seq; 2167 nlh = info->nlh;
2011 2168 if (nlh)
2012 skb = alloc_skb(size, gfp_any()); 2169 seq = nlh->nlmsg_seq;
2013 if (!skb) {
2014 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_ROUTE, ENOBUFS);
2015 return;
2016 } 2170 }
2017 if (rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0) < 0) { 2171
2172 skb = nlmsg_new(nlmsg_total_size(payload), gfp_any());
2173 if (skb == NULL)
2174 goto errout;
2175
2176 err = rt6_fill_node(skb, rt, NULL, NULL, 0, event, pid, seq, 0, 0);
2177 if (err < 0) {
2018 kfree_skb(skb); 2178 kfree_skb(skb);
2019 netlink_set_err(rtnl, 0, RTNLGRP_IPV6_ROUTE, EINVAL); 2179 goto errout;
2020 return;
2021 } 2180 }
2022 NETLINK_CB(skb).dst_group = RTNLGRP_IPV6_ROUTE; 2181
2023 netlink_broadcast(rtnl, skb, 0, RTNLGRP_IPV6_ROUTE, gfp_any()); 2182 err = rtnl_notify(skb, pid, RTNLGRP_IPV6_ROUTE, nlh, gfp_any());
2183errout:
2184 if (err < 0)
2185 rtnl_set_sk_err(RTNLGRP_IPV6_ROUTE, err);
2024} 2186}
2025 2187
2026/* 2188/*
@@ -2096,16 +2258,13 @@ static int rt6_info_route(struct rt6_info *rt, void *p_arg)
2096 2258
2097static int rt6_proc_info(char *buffer, char **start, off_t offset, int length) 2259static int rt6_proc_info(char *buffer, char **start, off_t offset, int length)
2098{ 2260{
2099 struct rt6_proc_arg arg; 2261 struct rt6_proc_arg arg = {
2100 arg.buffer = buffer; 2262 .buffer = buffer,
2101 arg.offset = offset; 2263 .offset = offset,
2102 arg.length = length; 2264 .length = length,
2103 arg.skip = 0; 2265 };
2104 arg.len = 0;
2105 2266
2106 read_lock_bh(&rt6_lock); 2267 fib6_clean_all(rt6_info_route, 0, &arg);
2107 fib6_clean_tree(&ip6_routing_table, rt6_info_route, 0, &arg);
2108 read_unlock_bh(&rt6_lock);
2109 2268
2110 *start = buffer; 2269 *start = buffer;
2111 if (offset) 2270 if (offset)
@@ -2260,13 +2419,9 @@ void __init ip6_route_init(void)
2260{ 2419{
2261 struct proc_dir_entry *p; 2420 struct proc_dir_entry *p;
2262 2421
2263 ip6_dst_ops.kmem_cachep = kmem_cache_create("ip6_dst_cache", 2422 ip6_dst_ops.kmem_cachep =
2264 sizeof(struct rt6_info), 2423 kmem_cache_create("ip6_dst_cache", sizeof(struct rt6_info), 0,
2265 0, SLAB_HWCACHE_ALIGN, 2424 SLAB_HWCACHE_ALIGN|SLAB_PANIC, NULL, NULL);
2266 NULL, NULL);
2267 if (!ip6_dst_ops.kmem_cachep)
2268 panic("cannot create ip6_dst_cache");
2269
2270 fib6_init(); 2425 fib6_init();
2271#ifdef CONFIG_PROC_FS 2426#ifdef CONFIG_PROC_FS
2272 p = proc_net_create("ipv6_route", 0, rt6_proc_info); 2427 p = proc_net_create("ipv6_route", 0, rt6_proc_info);
@@ -2278,10 +2433,16 @@ void __init ip6_route_init(void)
2278#ifdef CONFIG_XFRM 2433#ifdef CONFIG_XFRM
2279 xfrm6_init(); 2434 xfrm6_init();
2280#endif 2435#endif
2436#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2437 fib6_rules_init();
2438#endif
2281} 2439}
2282 2440
2283void ip6_route_cleanup(void) 2441void ip6_route_cleanup(void)
2284{ 2442{
2443#ifdef CONFIG_IPV6_MULTIPLE_TABLES
2444 fib6_rules_cleanup();
2445#endif
2285#ifdef CONFIG_PROC_FS 2446#ifdef CONFIG_PROC_FS
2286 proc_net_remove("ipv6_route"); 2447 proc_net_remove("ipv6_route");
2287 proc_net_remove("rt6_stats"); 2448 proc_net_remove("rt6_stats");