Deleted Added
full compact
nd6_rtr.c (231852) nd6_rtr.c (241686)
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $
30 */
31
32#include <sys/cdefs.h>
1/*-
2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 16 unchanged lines hidden (view full) ---

25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 * SUCH DAMAGE.
28 *
29 * $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $
30 */
31
32#include <sys/cdefs.h>
33__FBSDID("$FreeBSD: head/sys/netinet6/nd6_rtr.c 231852 2012-02-17 02:39:58Z bz $");
33__FBSDID("$FreeBSD: head/sys/netinet6/nd6_rtr.c 241686 2012-10-18 13:57:24Z andre $");
34
35#include "opt_inet.h"
36#include "opt_inet6.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/malloc.h>
41#include <sys/mbuf.h>

--- 426 unchanged lines hidden (view full) ---

468 ifa_free(ifa);
469}
470
471static void
472defrouter_addreq(struct nd_defrouter *new)
473{
474 struct sockaddr_in6 def, mask, gate;
475 struct rtentry *newrt = NULL;
34
35#include "opt_inet.h"
36#include "opt_inet6.h"
37
38#include <sys/param.h>
39#include <sys/systm.h>
40#include <sys/malloc.h>
41#include <sys/mbuf.h>

--- 426 unchanged lines hidden (view full) ---

468 ifa_free(ifa);
469}
470
471static void
472defrouter_addreq(struct nd_defrouter *new)
473{
474 struct sockaddr_in6 def, mask, gate;
475 struct rtentry *newrt = NULL;
476 int s;
477 int error;
478
479 bzero(&def, sizeof(def));
480 bzero(&mask, sizeof(mask));
481 bzero(&gate, sizeof(gate));
482
483 def.sin6_len = mask.sin6_len = gate.sin6_len =
484 sizeof(struct sockaddr_in6);
485 def.sin6_family = gate.sin6_family = AF_INET6;
486 gate.sin6_addr = new->rtaddr;
487
476 int error;
477
478 bzero(&def, sizeof(def));
479 bzero(&mask, sizeof(mask));
480 bzero(&gate, sizeof(gate));
481
482 def.sin6_len = mask.sin6_len = gate.sin6_len =
483 sizeof(struct sockaddr_in6);
484 def.sin6_family = gate.sin6_family = AF_INET6;
485 gate.sin6_addr = new->rtaddr;
486
488 s = splnet();
489 error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def,
490 (struct sockaddr *)&gate, (struct sockaddr *)&mask,
491 RTF_GATEWAY, &newrt, RT_DEFAULT_FIB);
492 if (newrt) {
493 nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
494 RTFREE(newrt);
495 }
496 if (error == 0)
497 new->installed = 1;
487 error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def,
488 (struct sockaddr *)&gate, (struct sockaddr *)&mask,
489 RTF_GATEWAY, &newrt, RT_DEFAULT_FIB);
490 if (newrt) {
491 nd6_rtmsg(RTM_ADD, newrt); /* tell user process */
492 RTFREE(newrt);
493 }
494 if (error == 0)
495 new->installed = 1;
498 splx(s);
499 return;
500}
501
502struct nd_defrouter *
503defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp)
504{
505 struct nd_defrouter *dr;
506

--- 112 unchanged lines hidden (view full) ---

619 * At this moment, we do not try to install more than one default router,
620 * even when the multipath routing is available, because we're not sure about
621 * the benefits for stub hosts comparing to the risk of making the code
622 * complicated and the possibility of introducing bugs.
623 */
624void
625defrouter_select(void)
626{
496 return;
497}
498
499struct nd_defrouter *
500defrouter_lookup(struct in6_addr *addr, struct ifnet *ifp)
501{
502 struct nd_defrouter *dr;
503

--- 112 unchanged lines hidden (view full) ---

616 * At this moment, we do not try to install more than one default router,
617 * even when the multipath routing is available, because we're not sure about
618 * the benefits for stub hosts comparing to the risk of making the code
619 * complicated and the possibility of introducing bugs.
620 */
621void
622defrouter_select(void)
623{
627 int s = splnet();
628 struct nd_defrouter *dr, *selected_dr = NULL, *installed_dr = NULL;
629 struct llentry *ln = NULL;
630
631 /*
632 * Let's handle easy case (3) first:
633 * If default router list is empty, there's nothing to be done.
634 */
624 struct nd_defrouter *dr, *selected_dr = NULL, *installed_dr = NULL;
625 struct llentry *ln = NULL;
626
627 /*
628 * Let's handle easy case (3) first:
629 * If default router list is empty, there's nothing to be done.
630 */
635 if (TAILQ_EMPTY(&V_nd_defrouter)) {
636 splx(s);
631 if (TAILQ_EMPTY(&V_nd_defrouter))
637 return;
632 return;
638 }
639
640 /*
641 * Search for a (probably) reachable router from the list.
642 * We just pick up the first reachable one (if any), assuming that
643 * the ordering rule of the list described in defrtrlist_update().
644 */
645 TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
646 IF_AFDATA_LOCK(dr->ifp);

--- 47 unchanged lines hidden (view full) ---

694 * Note that the selected router is never NULL here.
695 */
696 if (installed_dr != selected_dr) {
697 if (installed_dr)
698 defrouter_delreq(installed_dr);
699 defrouter_addreq(selected_dr);
700 }
701
633
634 /*
635 * Search for a (probably) reachable router from the list.
636 * We just pick up the first reachable one (if any), assuming that
637 * the ordering rule of the list described in defrtrlist_update().
638 */
639 TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) {
640 IF_AFDATA_LOCK(dr->ifp);

--- 47 unchanged lines hidden (view full) ---

688 * Note that the selected router is never NULL here.
689 */
690 if (installed_dr != selected_dr) {
691 if (installed_dr)
692 defrouter_delreq(installed_dr);
693 defrouter_addreq(selected_dr);
694 }
695
702 splx(s);
703 return;
704}
705
706/*
707 * for default router selection
708 * regards router-preference field as a 2-bit signed integer
709 */
710static int

--- 18 unchanged lines hidden (view full) ---

729 }
730 /* NOTREACHED */
731}
732
733static struct nd_defrouter *
734defrtrlist_update(struct nd_defrouter *new)
735{
736 struct nd_defrouter *dr, *n;
696 return;
697}
698
699/*
700 * for default router selection
701 * regards router-preference field as a 2-bit signed integer
702 */
703static int

--- 18 unchanged lines hidden (view full) ---

722 }
723 /* NOTREACHED */
724}
725
726static struct nd_defrouter *
727defrtrlist_update(struct nd_defrouter *new)
728{
729 struct nd_defrouter *dr, *n;
737 int s = splnet();
738
739 if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) {
740 /* entry exists */
741 if (new->rtlifetime == 0) {
742 defrtrlist_del(dr);
743 dr = NULL;
744 } else {
745 int oldpref = rtpref(dr);
746
747 /* override */
748 dr->flags = new->flags; /* xxx flag check */
749 dr->rtlifetime = new->rtlifetime;
750 dr->expire = new->expire;
751
752 /*
753 * If the preference does not change, there's no need
754 * to sort the entries. Also make sure the selected
755 * router is still installed in the kernel.
756 */
730
731 if ((dr = defrouter_lookup(&new->rtaddr, new->ifp)) != NULL) {
732 /* entry exists */
733 if (new->rtlifetime == 0) {
734 defrtrlist_del(dr);
735 dr = NULL;
736 } else {
737 int oldpref = rtpref(dr);
738
739 /* override */
740 dr->flags = new->flags; /* xxx flag check */
741 dr->rtlifetime = new->rtlifetime;
742 dr->expire = new->expire;
743
744 /*
745 * If the preference does not change, there's no need
746 * to sort the entries. Also make sure the selected
747 * router is still installed in the kernel.
748 */
757 if (dr->installed && rtpref(new) == oldpref) {
758 splx(s);
749 if (dr->installed && rtpref(new) == oldpref)
759 return (dr);
750 return (dr);
760 }
761
762 /*
763 * preferred router may be changed, so relocate
764 * this router.
765 * XXX: calling TAILQ_REMOVE directly is a bad manner.
766 * However, since defrtrlist_del() has many side
767 * effects, we intentionally do so here.
768 * defrouter_select() below will handle routing
769 * changes later.
770 */
771 TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
772 n = dr;
773 goto insert;
774 }
751
752 /*
753 * preferred router may be changed, so relocate
754 * this router.
755 * XXX: calling TAILQ_REMOVE directly is a bad manner.
756 * However, since defrtrlist_del() has many side
757 * effects, we intentionally do so here.
758 * defrouter_select() below will handle routing
759 * changes later.
760 */
761 TAILQ_REMOVE(&V_nd_defrouter, dr, dr_entry);
762 n = dr;
763 goto insert;
764 }
775 splx(s);
776 return (dr);
777 }
778
779 /* entry does not exist */
765 return (dr);
766 }
767
768 /* entry does not exist */
780 if (new->rtlifetime == 0) {
781 splx(s);
769 if (new->rtlifetime == 0)
782 return (NULL);
770 return (NULL);
783 }
784
785 n = (struct nd_defrouter *)malloc(sizeof(*n), M_IP6NDP, M_NOWAIT);
771
772 n = (struct nd_defrouter *)malloc(sizeof(*n), M_IP6NDP, M_NOWAIT);
786 if (n == NULL) {
787 splx(s);
773 if (n == NULL)
788 return (NULL);
774 return (NULL);
789 }
790 bzero(n, sizeof(*n));
791 *n = *new;
792
793insert:
794 /*
795 * Insert the new router in the Default Router List;
796 * The Default Router List should be in the descending order
797 * of router-preferece. Routers with the same preference are

--- 7 unchanged lines hidden (view full) ---

805 }
806 if (dr)
807 TAILQ_INSERT_BEFORE(dr, n, dr_entry);
808 else
809 TAILQ_INSERT_TAIL(&V_nd_defrouter, n, dr_entry);
810
811 defrouter_select();
812
775 bzero(n, sizeof(*n));
776 *n = *new;
777
778insert:
779 /*
780 * Insert the new router in the Default Router List;
781 * The Default Router List should be in the descending order
782 * of router-preferece. Routers with the same preference are

--- 7 unchanged lines hidden (view full) ---

790 }
791 if (dr)
792 TAILQ_INSERT_BEFORE(dr, n, dr_entry);
793 else
794 TAILQ_INSERT_TAIL(&V_nd_defrouter, n, dr_entry);
795
796 defrouter_select();
797
813 splx(s);
814
815 return (n);
816}
817
818static struct nd_pfxrouter *
819pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
820{
821 struct nd_pfxrouter *search;
822

--- 46 unchanged lines hidden (view full) ---

869}
870
871int
872nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
873 struct nd_prefix **newp)
874{
875 struct nd_prefix *new = NULL;
876 int error = 0;
798 return (n);
799}
800
801static struct nd_pfxrouter *
802pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
803{
804 struct nd_pfxrouter *search;
805

--- 46 unchanged lines hidden (view full) ---

852}
853
854int
855nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
856 struct nd_prefix **newp)
857{
858 struct nd_prefix *new = NULL;
859 int error = 0;
877 int i, s;
860 int i;
878 char ip6buf[INET6_ADDRSTRLEN];
879
880 new = (struct nd_prefix *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT);
881 if (new == NULL)
882 return(ENOMEM);
883 bzero(new, sizeof(*new));
884 new->ndpr_ifp = pr->ndpr_ifp;
885 new->ndpr_prefix = pr->ndpr_prefix;

--- 12 unchanged lines hidden (view full) ---

898 /* initialization */
899 LIST_INIT(&new->ndpr_advrtrs);
900 in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen);
901 /* make prefix in the canonical form */
902 for (i = 0; i < 4; i++)
903 new->ndpr_prefix.sin6_addr.s6_addr32[i] &=
904 new->ndpr_mask.s6_addr32[i];
905
861 char ip6buf[INET6_ADDRSTRLEN];
862
863 new = (struct nd_prefix *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT);
864 if (new == NULL)
865 return(ENOMEM);
866 bzero(new, sizeof(*new));
867 new->ndpr_ifp = pr->ndpr_ifp;
868 new->ndpr_prefix = pr->ndpr_prefix;

--- 12 unchanged lines hidden (view full) ---

881 /* initialization */
882 LIST_INIT(&new->ndpr_advrtrs);
883 in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen);
884 /* make prefix in the canonical form */
885 for (i = 0; i < 4; i++)
886 new->ndpr_prefix.sin6_addr.s6_addr32[i] &=
887 new->ndpr_mask.s6_addr32[i];
888
906 s = splnet();
907 /* link ndpr_entry to nd_prefix list */
908 LIST_INSERT_HEAD(&V_nd_prefix, new, ndpr_entry);
889 /* link ndpr_entry to nd_prefix list */
890 LIST_INSERT_HEAD(&V_nd_prefix, new, ndpr_entry);
909 splx(s);
910
911 /* ND_OPT_PI_FLAG_ONLINK processing */
912 if (new->ndpr_raf_onlink) {
913 int e;
914
915 if ((e = nd6_prefix_onlink(new)) != 0) {
916 nd6log((LOG_ERR, "nd6_prelist_add: failed to make "
917 "the prefix %s/%d on-link on %s (errno=%d)\n",

--- 8 unchanged lines hidden (view full) ---

926
927 return 0;
928}
929
930void
931prelist_remove(struct nd_prefix *pr)
932{
933 struct nd_pfxrouter *pfr, *next;
891
892 /* ND_OPT_PI_FLAG_ONLINK processing */
893 if (new->ndpr_raf_onlink) {
894 int e;
895
896 if ((e = nd6_prefix_onlink(new)) != 0) {
897 nd6log((LOG_ERR, "nd6_prelist_add: failed to make "
898 "the prefix %s/%d on-link on %s (errno=%d)\n",

--- 8 unchanged lines hidden (view full) ---

907
908 return 0;
909}
910
911void
912prelist_remove(struct nd_prefix *pr)
913{
914 struct nd_pfxrouter *pfr, *next;
934 int e, s;
915 int e;
935 char ip6buf[INET6_ADDRSTRLEN];
936
937 /* make sure to invalidate the prefix until it is really freed. */
938 pr->ndpr_vltime = 0;
939 pr->ndpr_pltime = 0;
940
941 /*
942 * Though these flags are now meaningless, we'd rather keep the value

--- 8 unchanged lines hidden (view full) ---

951 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
952 pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
953 /* what should we do? */
954 }
955
956 if (pr->ndpr_refcnt > 0)
957 return; /* notice here? */
958
916 char ip6buf[INET6_ADDRSTRLEN];
917
918 /* make sure to invalidate the prefix until it is really freed. */
919 pr->ndpr_vltime = 0;
920 pr->ndpr_pltime = 0;
921
922 /*
923 * Though these flags are now meaningless, we'd rather keep the value

--- 8 unchanged lines hidden (view full) ---

932 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
933 pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
934 /* what should we do? */
935 }
936
937 if (pr->ndpr_refcnt > 0)
938 return; /* notice here? */
939
959 s = splnet();
960
961 /* unlink ndpr_entry from nd_prefix list */
962 LIST_REMOVE(pr, ndpr_entry);
963
964 /* free list of routers that adversed the prefix */
965 LIST_FOREACH_SAFE(pfr, &pr->ndpr_advrtrs, pfr_entry, next) {
966 free(pfr, M_IP6NDP);
967 }
940 /* unlink ndpr_entry from nd_prefix list */
941 LIST_REMOVE(pr, ndpr_entry);
942
943 /* free list of routers that adversed the prefix */
944 LIST_FOREACH_SAFE(pfr, &pr->ndpr_advrtrs, pfr_entry, next) {
945 free(pfr, M_IP6NDP);
946 }
968 splx(s);
969
970 free(pr, M_IP6NDP);
971
972 pfxlist_onlink_check();
973}
974
975/*
976 * dr - may be NULL
977 */
978
979static int
980prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
981 struct mbuf *m, int mcast)
982{
983 struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
984 struct ifaddr *ifa;
985 struct ifnet *ifp = new->ndpr_ifp;
986 struct nd_prefix *pr;
947 free(pr, M_IP6NDP);
948
949 pfxlist_onlink_check();
950}
951
952/*
953 * dr - may be NULL
954 */
955
956static int
957prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
958 struct mbuf *m, int mcast)
959{
960 struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
961 struct ifaddr *ifa;
962 struct ifnet *ifp = new->ndpr_ifp;
963 struct nd_prefix *pr;
987 int s = splnet();
988 int error = 0;
989 int newprefix = 0;
990 int auth;
991 struct in6_addrlifetime lt6_tmp;
992 char ip6buf[INET6_ADDRSTRLEN];
993
994 auth = 0;
995 if (m) {

--- 308 unchanged lines hidden (view full) ---

1304 pfxlist_onlink_check();
1305 } else {
1306 /* just set an error. do not bark here. */
1307 error = EADDRNOTAVAIL; /* XXX: might be unused. */
1308 }
1309 }
1310
1311 end:
964 int error = 0;
965 int newprefix = 0;
966 int auth;
967 struct in6_addrlifetime lt6_tmp;
968 char ip6buf[INET6_ADDRSTRLEN];
969
970 auth = 0;
971 if (m) {

--- 308 unchanged lines hidden (view full) ---

1280 pfxlist_onlink_check();
1281 } else {
1282 /* just set an error. do not bark here. */
1283 error = EADDRNOTAVAIL; /* XXX: might be unused. */
1284 }
1285 }
1286
1287 end:
1312 splx(s);
1313 return error;
1314}
1315
1316/*
1317 * A supplement function used in the on-link detection below;
1318 * detect if a given prefix has a (probably) reachable advertising router.
1319 * XXX: lengthy function name...
1320 */

--- 786 unchanged lines hidden (view full) ---

2107 * XXX: this function causes search through all entries of routing table, so
2108 * it shouldn't be called when acting as a router.
2109 */
2110void
2111rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
2112{
2113 struct radix_node_head *rnh;
2114 u_int fibnum;
1288 return error;
1289}
1290
1291/*
1292 * A supplement function used in the on-link detection below;
1293 * detect if a given prefix has a (probably) reachable advertising router.
1294 * XXX: lengthy function name...
1295 */

--- 786 unchanged lines hidden (view full) ---

2082 * XXX: this function causes search through all entries of routing table, so
2083 * it shouldn't be called when acting as a router.
2084 */
2085void
2086rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
2087{
2088 struct radix_node_head *rnh;
2089 u_int fibnum;
2115 int s = splnet();
2116
2117 /* We'll care only link-local addresses */
2090
2091 /* We'll care only link-local addresses */
2118 if (!IN6_IS_ADDR_LINKLOCAL(gateway)) {
2119 splx(s);
2092 if (!IN6_IS_ADDR_LINKLOCAL(gateway))
2120 return;
2093 return;
2121 }
2122
2123 /* XXX Do we really need to walk any but the default FIB? */
2124 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
2125 rnh = rt_tables_get_rnh(fibnum, AF_INET6);
2126 if (rnh == NULL)
2127 continue;
2128
2129 RADIX_NODE_HEAD_LOCK(rnh);
2130 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway);
2131 RADIX_NODE_HEAD_UNLOCK(rnh);
2132 }
2094
2095 /* XXX Do we really need to walk any but the default FIB? */
2096 for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
2097 rnh = rt_tables_get_rnh(fibnum, AF_INET6);
2098 if (rnh == NULL)
2099 continue;
2100
2101 RADIX_NODE_HEAD_LOCK(rnh);
2102 rnh->rnh_walktree(rnh, rt6_deleteroute, (void *)gateway);
2103 RADIX_NODE_HEAD_UNLOCK(rnh);
2104 }
2133 splx(s);
2134}
2135
2136static int
2137rt6_deleteroute(struct radix_node *rn, void *arg)
2138{
2139#define SIN6(s) ((struct sockaddr_in6 *)s)
2140 struct rtentry *rt = (struct rtentry *)rn;
2141 struct in6_addr *gate = (struct in6_addr *)arg;

--- 55 unchanged lines hidden ---
2105}
2106
2107static int
2108rt6_deleteroute(struct radix_node *rn, void *arg)
2109{
2110#define SIN6(s) ((struct sockaddr_in6 *)s)
2111 struct rtentry *rt = (struct rtentry *)rn;
2112 struct in6_addr *gate = (struct in6_addr *)arg;

--- 55 unchanged lines hidden ---