nd6_rtr.c (160981) | nd6_rtr.c (165118) |
---|---|
1/* $FreeBSD: head/sys/netinet6/nd6_rtr.c 160981 2006-08-04 21:27:40Z brooks $ */ | 1/* $FreeBSD: head/sys/netinet6/nd6_rtr.c 165118 2006-12-12 12:17:58Z bz $ */ |
2/* $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 110 unchanged lines hidden (view full) --- 120{ 121 struct ifnet *ifp = m->m_pkthdr.rcvif; 122 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 123 struct nd_router_solicit *nd_rs; 124 struct in6_addr saddr6 = ip6->ip6_src; 125 char *lladdr = NULL; 126 int lladdrlen = 0; 127 union nd_opts ndopts; | 2/* $KAME: nd6_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $ */ 3 4/*- 5 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 6 * All rights reserved. 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions --- 110 unchanged lines hidden (view full) --- 120{ 121 struct ifnet *ifp = m->m_pkthdr.rcvif; 122 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 123 struct nd_router_solicit *nd_rs; 124 struct in6_addr saddr6 = ip6->ip6_src; 125 char *lladdr = NULL; 126 int lladdrlen = 0; 127 union nd_opts ndopts; |
128 char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; |
|
128 129 /* If I'm not a router, ignore it. */ 130 if (ip6_accept_rtadv != 0 || ip6_forwarding != 1) 131 goto freeit; 132 133 /* Sanity checks */ 134 if (ip6->ip6_hlim != 255) { 135 nd6log((LOG_ERR, 136 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n", | 129 130 /* If I'm not a router, ignore it. */ 131 if (ip6_accept_rtadv != 0 || ip6_forwarding != 1) 132 goto freeit; 133 134 /* Sanity checks */ 135 if (ip6->ip6_hlim != 255) { 136 nd6log((LOG_ERR, 137 "nd6_rs_input: invalid hlim (%d) from %s to %s on %s\n", |
137 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 138 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); | 138 ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src), 139 ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp))); |
139 goto bad; 140 } 141 142 /* 143 * Don't update the neighbor cache, if src = ::. 144 * This indicates that the src has no IP address assigned yet. 145 */ 146 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) --- 23 unchanged lines hidden (view full) --- 170 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 171 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 172 } 173 174 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 175 nd6log((LOG_INFO, 176 "nd6_rs_input: lladdrlen mismatch for %s " 177 "(if %d, RS packet %d)\n", | 140 goto bad; 141 } 142 143 /* 144 * Don't update the neighbor cache, if src = ::. 145 * This indicates that the src has no IP address assigned yet. 146 */ 147 if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) --- 23 unchanged lines hidden (view full) --- 171 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 172 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 173 } 174 175 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 176 nd6log((LOG_INFO, 177 "nd6_rs_input: lladdrlen mismatch for %s " 178 "(if %d, RS packet %d)\n", |
178 ip6_sprintf(&saddr6), | 179 ip6_sprintf(ip6bufs, &saddr6), |
179 ifp->if_addrlen, lladdrlen - 2)); 180 goto bad; 181 } 182 183 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0); 184 185 freeit: 186 m_freem(m); --- 19 unchanged lines hidden (view full) --- 206 struct ifnet *ifp = m->m_pkthdr.rcvif; 207 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 208 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 209 struct nd_router_advert *nd_ra; 210 struct in6_addr saddr6 = ip6->ip6_src; 211 int mcast = 0; 212 union nd_opts ndopts; 213 struct nd_defrouter *dr; | 180 ifp->if_addrlen, lladdrlen - 2)); 181 goto bad; 182 } 183 184 nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0); 185 186 freeit: 187 m_freem(m); --- 19 unchanged lines hidden (view full) --- 207 struct ifnet *ifp = m->m_pkthdr.rcvif; 208 struct nd_ifinfo *ndi = ND_IFINFO(ifp); 209 struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); 210 struct nd_router_advert *nd_ra; 211 struct in6_addr saddr6 = ip6->ip6_src; 212 int mcast = 0; 213 union nd_opts ndopts; 214 struct nd_defrouter *dr; |
215 char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN]; |
|
214 215 /* 216 * We only accept RAs only when 217 * the system-wide variable allows the acceptance, and 218 * per-interface variable allows RAs on the receiving interface. 219 */ 220 if (ip6_accept_rtadv == 0) 221 goto freeit; 222 if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV)) 223 goto freeit; 224 225 if (ip6->ip6_hlim != 255) { 226 nd6log((LOG_ERR, 227 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n", | 216 217 /* 218 * We only accept RAs only when 219 * the system-wide variable allows the acceptance, and 220 * per-interface variable allows RAs on the receiving interface. 221 */ 222 if (ip6_accept_rtadv == 0) 223 goto freeit; 224 if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV)) 225 goto freeit; 226 227 if (ip6->ip6_hlim != 255) { 228 nd6log((LOG_ERR, 229 "nd6_ra_input: invalid hlim (%d) from %s to %s on %s\n", |
228 ip6->ip6_hlim, ip6_sprintf(&ip6->ip6_src), 229 ip6_sprintf(&ip6->ip6_dst), if_name(ifp))); | 230 ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src), 231 ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp))); |
230 goto bad; 231 } 232 233 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) { 234 nd6log((LOG_ERR, 235 "nd6_ra_input: src %s is not link-local\n", | 232 goto bad; 233 } 234 235 if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) { 236 nd6log((LOG_ERR, 237 "nd6_ra_input: src %s is not link-local\n", |
236 ip6_sprintf(&saddr6))); | 238 ip6_sprintf(ip6bufs, &saddr6))); |
237 goto bad; 238 } 239 240#ifndef PULLDOWN_TEST 241 IP6_EXTHDR_CHECK(m, off, icmp6len,); 242 nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off); 243#else 244 IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len); --- 75 unchanged lines hidden (view full) --- 320 continue; 321 } 322 323 if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) 324 || IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) { 325 nd6log((LOG_INFO, 326 "nd6_ra_input: invalid prefix " 327 "%s, ignored\n", | 239 goto bad; 240 } 241 242#ifndef PULLDOWN_TEST 243 IP6_EXTHDR_CHECK(m, off, icmp6len,); 244 nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off); 245#else 246 IP6_EXTHDR_GET(nd_ra, struct nd_router_advert *, m, off, icmp6len); --- 75 unchanged lines hidden (view full) --- 322 continue; 323 } 324 325 if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix) 326 || IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) { 327 nd6log((LOG_INFO, 328 "nd6_ra_input: invalid prefix " 329 "%s, ignored\n", |
328 ip6_sprintf(&pi->nd_opt_pi_prefix))); | 330 ip6_sprintf(ip6bufs, 331 &pi->nd_opt_pi_prefix))); |
329 continue; 330 } 331 332 bzero(&pr, sizeof(pr)); 333 pr.ndpr_prefix.sin6_family = AF_INET6; 334 pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix); 335 pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix; 336 pr.ndpr_ifp = (struct ifnet *)m->m_pkthdr.rcvif; --- 17 unchanged lines hidden (view full) --- 354 u_long maxmtu; 355 356 mtu = (u_long)ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu); 357 358 /* lower bound */ 359 if (mtu < IPV6_MMTU) { 360 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu option " 361 "mtu=%lu sent from %s, ignoring\n", | 332 continue; 333 } 334 335 bzero(&pr, sizeof(pr)); 336 pr.ndpr_prefix.sin6_family = AF_INET6; 337 pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix); 338 pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix; 339 pr.ndpr_ifp = (struct ifnet *)m->m_pkthdr.rcvif; --- 17 unchanged lines hidden (view full) --- 357 u_long maxmtu; 358 359 mtu = (u_long)ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu); 360 361 /* lower bound */ 362 if (mtu < IPV6_MMTU) { 363 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu option " 364 "mtu=%lu sent from %s, ignoring\n", |
362 mtu, ip6_sprintf(&ip6->ip6_src))); | 365 mtu, ip6_sprintf(ip6bufs, &ip6->ip6_src))); |
363 goto skip; 364 } 365 366 /* upper bound */ 367 maxmtu = (ndi->maxmtu && ndi->maxmtu < ifp->if_mtu) 368 ? ndi->maxmtu : ifp->if_mtu; 369 if (mtu <= maxmtu) { 370 int change = (ndi->linkmtu != mtu); 371 372 ndi->linkmtu = mtu; 373 if (change) /* in6_maxmtu may change */ 374 in6_setmaxmtu(); 375 } else { 376 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu " 377 "mtu=%lu sent from %s; " 378 "exceeds maxmtu %lu, ignoring\n", | 366 goto skip; 367 } 368 369 /* upper bound */ 370 maxmtu = (ndi->maxmtu && ndi->maxmtu < ifp->if_mtu) 371 ? ndi->maxmtu : ifp->if_mtu; 372 if (mtu <= maxmtu) { 373 int change = (ndi->linkmtu != mtu); 374 375 ndi->linkmtu = mtu; 376 if (change) /* in6_maxmtu may change */ 377 in6_setmaxmtu(); 378 } else { 379 nd6log((LOG_INFO, "nd6_ra_input: bogus mtu " 380 "mtu=%lu sent from %s; " 381 "exceeds maxmtu %lu, ignoring\n", |
379 mtu, ip6_sprintf(&ip6->ip6_src), maxmtu)); | 382 mtu, ip6_sprintf(ip6bufs, &ip6->ip6_src), maxmtu)); |
380 } 381 } 382 383 skip: 384 385 /* 386 * Source link layer address 387 */ --- 4 unchanged lines hidden (view full) --- 392 if (ndopts.nd_opts_src_lladdr) { 393 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 394 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 395 } 396 397 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 398 nd6log((LOG_INFO, 399 "nd6_ra_input: lladdrlen mismatch for %s " | 383 } 384 } 385 386 skip: 387 388 /* 389 * Source link layer address 390 */ --- 4 unchanged lines hidden (view full) --- 395 if (ndopts.nd_opts_src_lladdr) { 396 lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1); 397 lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3; 398 } 399 400 if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) { 401 nd6log((LOG_INFO, 402 "nd6_ra_input: lladdrlen mismatch for %s " |
400 "(if %d, RA packet %d)\n", ip6_sprintf(&saddr6), | 403 "(if %d, RA packet %d)\n", ip6_sprintf(ip6bufs, &saddr6), |
401 ifp->if_addrlen, lladdrlen - 2)); 402 goto bad; 403 } 404 405 nd6_cache_lladdr(ifp, &saddr6, lladdr, 406 lladdrlen, ND_ROUTER_ADVERT, 0); 407 408 /* --- 465 unchanged lines hidden (view full) --- 874nd6_prelist_add(pr, dr, newp) 875 struct nd_prefixctl *pr; 876 struct nd_prefix **newp; 877 struct nd_defrouter *dr; 878{ 879 struct nd_prefix *new = NULL; 880 int error = 0; 881 int i, s; | 404 ifp->if_addrlen, lladdrlen - 2)); 405 goto bad; 406 } 407 408 nd6_cache_lladdr(ifp, &saddr6, lladdr, 409 lladdrlen, ND_ROUTER_ADVERT, 0); 410 411 /* --- 465 unchanged lines hidden (view full) --- 877nd6_prelist_add(pr, dr, newp) 878 struct nd_prefixctl *pr; 879 struct nd_prefix **newp; 880 struct nd_defrouter *dr; 881{ 882 struct nd_prefix *new = NULL; 883 int error = 0; 884 int i, s; |
885 char ip6buf[INET6_ADDRSTRLEN]; |
|
882 883 new = (struct nd_prefix *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT); 884 if (new == NULL) 885 return(ENOMEM); 886 bzero(new, sizeof(*new)); 887 new->ndpr_ifp = pr->ndpr_ifp; 888 new->ndpr_prefix = pr->ndpr_prefix; 889 new->ndpr_plen = pr->ndpr_plen; --- 23 unchanged lines hidden (view full) --- 913 914 /* ND_OPT_PI_FLAG_ONLINK processing */ 915 if (new->ndpr_raf_onlink) { 916 int e; 917 918 if ((e = nd6_prefix_onlink(new)) != 0) { 919 nd6log((LOG_ERR, "nd6_prelist_add: failed to make " 920 "the prefix %s/%d on-link on %s (errno=%d)\n", | 886 887 new = (struct nd_prefix *)malloc(sizeof(*new), M_IP6NDP, M_NOWAIT); 888 if (new == NULL) 889 return(ENOMEM); 890 bzero(new, sizeof(*new)); 891 new->ndpr_ifp = pr->ndpr_ifp; 892 new->ndpr_prefix = pr->ndpr_prefix; 893 new->ndpr_plen = pr->ndpr_plen; --- 23 unchanged lines hidden (view full) --- 917 918 /* ND_OPT_PI_FLAG_ONLINK processing */ 919 if (new->ndpr_raf_onlink) { 920 int e; 921 922 if ((e = nd6_prefix_onlink(new)) != 0) { 923 nd6log((LOG_ERR, "nd6_prelist_add: failed to make " 924 "the prefix %s/%d on-link on %s (errno=%d)\n", |
921 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), | 925 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), |
922 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 923 /* proceed anyway. XXX: is it correct? */ 924 } 925 } 926 927 if (dr) 928 pfxrtr_add(new, dr); 929 930 return 0; 931} 932 933void 934prelist_remove(pr) 935 struct nd_prefix *pr; 936{ 937 struct nd_pfxrouter *pfr, *next; 938 int e, s; | 926 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 927 /* proceed anyway. XXX: is it correct? */ 928 } 929 } 930 931 if (dr) 932 pfxrtr_add(new, dr); 933 934 return 0; 935} 936 937void 938prelist_remove(pr) 939 struct nd_prefix *pr; 940{ 941 struct nd_pfxrouter *pfr, *next; 942 int e, s; |
943 char ip6buf[INET6_ADDRSTRLEN]; |
|
939 940 /* make sure to invalidate the prefix until it is really freed. */ 941 pr->ndpr_vltime = 0; 942 pr->ndpr_pltime = 0; 943 944 /* 945 * Though these flags are now meaningless, we'd rather keep the value 946 * of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users 947 * when executing "ndp -p". 948 */ 949 950 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 && 951 (e = nd6_prefix_offlink(pr)) != 0) { 952 nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink " 953 "on %s, errno=%d\n", | 944 945 /* make sure to invalidate the prefix until it is really freed. */ 946 pr->ndpr_vltime = 0; 947 pr->ndpr_pltime = 0; 948 949 /* 950 * Though these flags are now meaningless, we'd rather keep the value 951 * of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users 952 * when executing "ndp -p". 953 */ 954 955 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0 && 956 (e = nd6_prefix_offlink(pr)) != 0) { 957 nd6log((LOG_ERR, "prelist_remove: failed to make %s/%d offlink " 958 "on %s, errno=%d\n", |
954 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), | 959 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), |
955 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 956 /* what should we do? */ 957 } 958 959 if (pr->ndpr_refcnt > 0) 960 return; /* notice here? */ 961 962 s = splnet(); --- 25 unchanged lines hidden (view full) --- 988 struct ifaddr *ifa; 989 struct ifnet *ifp = new->ndpr_ifp; 990 struct nd_prefix *pr; 991 int s = splnet(); 992 int error = 0; 993 int newprefix = 0; 994 int auth; 995 struct in6_addrlifetime lt6_tmp; | 960 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 961 /* what should we do? */ 962 } 963 964 if (pr->ndpr_refcnt > 0) 965 return; /* notice here? */ 966 967 s = splnet(); --- 25 unchanged lines hidden (view full) --- 993 struct ifaddr *ifa; 994 struct ifnet *ifp = new->ndpr_ifp; 995 struct nd_prefix *pr; 996 int s = splnet(); 997 int error = 0; 998 int newprefix = 0; 999 int auth; 1000 struct in6_addrlifetime lt6_tmp; |
1001 char ip6buf[INET6_ADDRSTRLEN]; |
|
996 997 auth = 0; 998 if (m) { 999 /* 1000 * Authenticity for NA consists authentication for 1001 * both IP header and IP datagrams, doesn't it ? 1002 */ 1003#if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM) --- 28 unchanged lines hidden (view full) --- 1032 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1033 int e; 1034 1035 if ((e = nd6_prefix_onlink(pr)) != 0) { 1036 nd6log((LOG_ERR, 1037 "prelist_update: failed to make " 1038 "the prefix %s/%d on-link on %s " 1039 "(errno=%d)\n", | 1002 1003 auth = 0; 1004 if (m) { 1005 /* 1006 * Authenticity for NA consists authentication for 1007 * both IP header and IP datagrams, doesn't it ? 1008 */ 1009#if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM) --- 28 unchanged lines hidden (view full) --- 1038 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1039 int e; 1040 1041 if ((e = nd6_prefix_onlink(pr)) != 0) { 1042 nd6log((LOG_ERR, 1043 "prelist_update: failed to make " 1044 "the prefix %s/%d on-link on %s " 1045 "(errno=%d)\n", |
1040 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), | 1046 ip6_sprintf(ip6buf, 1047 &pr->ndpr_prefix.sin6_addr), |
1041 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 1042 /* proceed anyway. XXX: is it correct? */ 1043 } 1044 } 1045 1046 if (dr && pfxrtr_lookup(pr, dr) == NULL) 1047 pfxrtr_add(pr, dr); 1048 } else { --- 6 unchanged lines hidden (view full) --- 1055 if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0) 1056 goto end; 1057 1058 error = nd6_prelist_add(new, dr, &newpr); 1059 if (error != 0 || newpr == NULL) { 1060 nd6log((LOG_NOTICE, "prelist_update: " 1061 "nd6_prelist_add failed for %s/%d on %s " 1062 "errno=%d, returnpr=%p\n", | 1048 pr->ndpr_plen, if_name(pr->ndpr_ifp), e)); 1049 /* proceed anyway. XXX: is it correct? */ 1050 } 1051 } 1052 1053 if (dr && pfxrtr_lookup(pr, dr) == NULL) 1054 pfxrtr_add(pr, dr); 1055 } else { --- 6 unchanged lines hidden (view full) --- 1062 if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0) 1063 goto end; 1064 1065 error = nd6_prelist_add(new, dr, &newpr); 1066 if (error != 0 || newpr == NULL) { 1067 nd6log((LOG_NOTICE, "prelist_update: " 1068 "nd6_prelist_add failed for %s/%d on %s " 1069 "errno=%d, returnpr=%p\n", |
1063 ip6_sprintf(&new->ndpr_prefix.sin6_addr), | 1070 ip6_sprintf(ip6buf, &new->ndpr_prefix.sin6_addr), |
1064 new->ndpr_plen, if_name(new->ndpr_ifp), 1065 error, newpr)); 1066 goto end; /* we should just give up in this case. */ 1067 } 1068 1069 /* 1070 * XXX: from the ND point of view, we can ignore a prefix 1071 * with the on-link bit being zero. However, we need a --- 361 unchanged lines hidden (view full) --- 1433 * prefix, and reinstall the interface route for a (just) attached 1434 * prefix. Note that all attempt of reinstallation does not 1435 * necessarily success, when a same prefix is shared among multiple 1436 * interfaces. Such cases will be handled in nd6_prefix_onlink, 1437 * so we don't have to care about them. 1438 */ 1439 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 1440 int e; | 1071 new->ndpr_plen, if_name(new->ndpr_ifp), 1072 error, newpr)); 1073 goto end; /* we should just give up in this case. */ 1074 } 1075 1076 /* 1077 * XXX: from the ND point of view, we can ignore a prefix 1078 * with the on-link bit being zero. However, we need a --- 361 unchanged lines hidden (view full) --- 1440 * prefix, and reinstall the interface route for a (just) attached 1441 * prefix. Note that all attempt of reinstallation does not 1442 * necessarily success, when a same prefix is shared among multiple 1443 * interfaces. Such cases will be handled in nd6_prefix_onlink, 1444 * so we don't have to care about them. 1445 */ 1446 for (pr = nd_prefix.lh_first; pr; pr = pr->ndpr_next) { 1447 int e; |
1448 char ip6buf[INET6_ADDRSTRLEN]; |
|
1441 1442 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1443 continue; 1444 1445 if (pr->ndpr_raf_onlink == 0) 1446 continue; 1447 1448 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && 1449 (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1450 if ((e = nd6_prefix_offlink(pr)) != 0) { 1451 nd6log((LOG_ERR, 1452 "pfxlist_onlink_check: failed to " 1453 "make %s/%d offlink, errno=%d\n", | 1449 1450 if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr)) 1451 continue; 1452 1453 if (pr->ndpr_raf_onlink == 0) 1454 continue; 1455 1456 if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 && 1457 (pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1458 if ((e = nd6_prefix_offlink(pr)) != 0) { 1459 nd6log((LOG_ERR, 1460 "pfxlist_onlink_check: failed to " 1461 "make %s/%d offlink, errno=%d\n", |
1454 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1455 pr->ndpr_plen, e)); | 1462 ip6_sprintf(ip6buf, 1463 &pr->ndpr_prefix.sin6_addr), 1464 pr->ndpr_plen, e)); |
1456 } 1457 } 1458 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 1459 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 && 1460 pr->ndpr_raf_onlink) { 1461 if ((e = nd6_prefix_onlink(pr)) != 0) { 1462 nd6log((LOG_ERR, 1463 "pfxlist_onlink_check: failed to " 1464 "make %s/%d onlink, errno=%d\n", | 1465 } 1466 } 1467 if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && 1468 (pr->ndpr_stateflags & NDPRF_ONLINK) == 0 && 1469 pr->ndpr_raf_onlink) { 1470 if ((e = nd6_prefix_onlink(pr)) != 0) { 1471 nd6log((LOG_ERR, 1472 "pfxlist_onlink_check: failed to " 1473 "make %s/%d onlink, errno=%d\n", |
1465 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), 1466 pr->ndpr_plen, e)); | 1474 ip6_sprintf(ip6buf, 1475 &pr->ndpr_prefix.sin6_addr), 1476 pr->ndpr_plen, e)); |
1467 } 1468 } 1469 } 1470 1471 /* 1472 * Changes on the prefix status might affect address status as well. 1473 * Make sure that all addresses derived from an attached prefix are 1474 * attached, and that all addresses derived from a detached prefix are --- 57 unchanged lines hidden (view full) --- 1532{ 1533 struct ifaddr *ifa; 1534 struct ifnet *ifp = pr->ndpr_ifp; 1535 struct sockaddr_in6 mask6; 1536 struct nd_prefix *opr; 1537 u_long rtflags; 1538 int error = 0; 1539 struct rtentry *rt = NULL; | 1477 } 1478 } 1479 } 1480 1481 /* 1482 * Changes on the prefix status might affect address status as well. 1483 * Make sure that all addresses derived from an attached prefix are 1484 * attached, and that all addresses derived from a detached prefix are --- 57 unchanged lines hidden (view full) --- 1542{ 1543 struct ifaddr *ifa; 1544 struct ifnet *ifp = pr->ndpr_ifp; 1545 struct sockaddr_in6 mask6; 1546 struct nd_prefix *opr; 1547 u_long rtflags; 1548 int error = 0; 1549 struct rtentry *rt = NULL; |
1550 char ip6buf[INET6_ADDRSTRLEN]; |
|
1540 1541 /* sanity check */ 1542 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1543 nd6log((LOG_ERR, 1544 "nd6_prefix_onlink: %s/%d is already on-link\n", | 1551 1552 /* sanity check */ 1553 if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) { 1554 nd6log((LOG_ERR, 1555 "nd6_prefix_onlink: %s/%d is already on-link\n", |
1545 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen)); | 1556 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), 1557 pr->ndpr_plen)); |
1546 return (EEXIST); 1547 } 1548 1549 /* 1550 * Add the interface route associated with the prefix. Before 1551 * installing the route, check if there's the same prefix on another 1552 * interface, and the prefix has already installed the interface route. 1553 * Although such a configuration is expected to be rare, we explicitly --- 31 unchanged lines hidden (view full) --- 1585 * This can still happen, when, for example, we receive an RA 1586 * containing a prefix with the L bit set and the A bit clear, 1587 * after removing all IPv6 addresses on the receiving 1588 * interface. This should, of course, be rare though. 1589 */ 1590 nd6log((LOG_NOTICE, 1591 "nd6_prefix_onlink: failed to find any ifaddr" 1592 " to add route for a prefix(%s/%d) on %s\n", | 1558 return (EEXIST); 1559 } 1560 1561 /* 1562 * Add the interface route associated with the prefix. Before 1563 * installing the route, check if there's the same prefix on another 1564 * interface, and the prefix has already installed the interface route. 1565 * Although such a configuration is expected to be rare, we explicitly --- 31 unchanged lines hidden (view full) --- 1597 * This can still happen, when, for example, we receive an RA 1598 * containing a prefix with the L bit set and the A bit clear, 1599 * after removing all IPv6 addresses on the receiving 1600 * interface. This should, of course, be rare though. 1601 */ 1602 nd6log((LOG_NOTICE, 1603 "nd6_prefix_onlink: failed to find any ifaddr" 1604 " to add route for a prefix(%s/%d) on %s\n", |
1593 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), | 1605 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), |
1594 pr->ndpr_plen, if_name(ifp))); 1595 return (0); 1596 } 1597 1598 /* 1599 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. 1600 * ifa->ifa_rtrequest = nd6_rtrequest; 1601 */ --- 12 unchanged lines hidden (view full) --- 1614 } 1615 error = rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix, 1616 ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt); 1617 if (error == 0) { 1618 if (rt != NULL) /* this should be non NULL, though */ 1619 nd6_rtmsg(RTM_ADD, rt); 1620 pr->ndpr_stateflags |= NDPRF_ONLINK; 1621 } else { | 1606 pr->ndpr_plen, if_name(ifp))); 1607 return (0); 1608 } 1609 1610 /* 1611 * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. 1612 * ifa->ifa_rtrequest = nd6_rtrequest; 1613 */ --- 12 unchanged lines hidden (view full) --- 1626 } 1627 error = rtrequest(RTM_ADD, (struct sockaddr *)&pr->ndpr_prefix, 1628 ifa->ifa_addr, (struct sockaddr *)&mask6, rtflags, &rt); 1629 if (error == 0) { 1630 if (rt != NULL) /* this should be non NULL, though */ 1631 nd6_rtmsg(RTM_ADD, rt); 1632 pr->ndpr_stateflags |= NDPRF_ONLINK; 1633 } else { |
1634 char ip6bufg[INET6_ADDRSTRLEN], ip6bufm[INET6_ADDRSTRLEN]; |
|
1622 nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a" 1623 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx " 1624 "errno = %d\n", | 1635 nd6log((LOG_ERR, "nd6_prefix_onlink: failed to add route for a" 1636 " prefix (%s/%d) on %s, gw=%s, mask=%s, flags=%lx " 1637 "errno = %d\n", |
1625 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), | 1638 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), |
1626 pr->ndpr_plen, if_name(ifp), | 1639 pr->ndpr_plen, if_name(ifp), |
1627 ip6_sprintf(&((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr), 1628 ip6_sprintf(&mask6.sin6_addr), rtflags, error)); | 1640 ip6_sprintf(ip6bufg, &((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_addr), 1641 ip6_sprintf(ip6bufm, &mask6.sin6_addr), rtflags, error)); |
1629 } 1630 1631 if (rt != NULL) { 1632 RT_LOCK(rt); 1633 RT_REMREF(rt); 1634 RT_UNLOCK(rt); 1635 } 1636 --- 4 unchanged lines hidden (view full) --- 1641nd6_prefix_offlink(pr) 1642 struct nd_prefix *pr; 1643{ 1644 int error = 0; 1645 struct ifnet *ifp = pr->ndpr_ifp; 1646 struct nd_prefix *opr; 1647 struct sockaddr_in6 sa6, mask6; 1648 struct rtentry *rt = NULL; | 1642 } 1643 1644 if (rt != NULL) { 1645 RT_LOCK(rt); 1646 RT_REMREF(rt); 1647 RT_UNLOCK(rt); 1648 } 1649 --- 4 unchanged lines hidden (view full) --- 1654nd6_prefix_offlink(pr) 1655 struct nd_prefix *pr; 1656{ 1657 int error = 0; 1658 struct ifnet *ifp = pr->ndpr_ifp; 1659 struct nd_prefix *opr; 1660 struct sockaddr_in6 sa6, mask6; 1661 struct rtentry *rt = NULL; |
1662 char ip6buf[INET6_ADDRSTRLEN]; |
|
1649 1650 /* sanity check */ 1651 if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1652 nd6log((LOG_ERR, 1653 "nd6_prefix_offlink: %s/%d is already off-link\n", | 1663 1664 /* sanity check */ 1665 if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0) { 1666 nd6log((LOG_ERR, 1667 "nd6_prefix_offlink: %s/%d is already off-link\n", |
1654 ip6_sprintf(&pr->ndpr_prefix.sin6_addr), pr->ndpr_plen)); | 1668 ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr), 1669 pr->ndpr_plen)); |
1655 return (EEXIST); 1656 } 1657 1658 bzero(&sa6, sizeof(sa6)); 1659 sa6.sin6_family = AF_INET6; 1660 sa6.sin6_len = sizeof(sa6); 1661 bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr, 1662 sizeof(struct in6_addr)); --- 36 unchanged lines hidden (view full) --- 1699 &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { 1700 int e; 1701 1702 if ((e = nd6_prefix_onlink(opr)) != 0) { 1703 nd6log((LOG_ERR, 1704 "nd6_prefix_offlink: failed to " 1705 "recover a prefix %s/%d from %s " 1706 "to %s (errno = %d)\n", | 1670 return (EEXIST); 1671 } 1672 1673 bzero(&sa6, sizeof(sa6)); 1674 sa6.sin6_family = AF_INET6; 1675 sa6.sin6_len = sizeof(sa6); 1676 bcopy(&pr->ndpr_prefix.sin6_addr, &sa6.sin6_addr, 1677 sizeof(struct in6_addr)); --- 36 unchanged lines hidden (view full) --- 1714 &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { 1715 int e; 1716 1717 if ((e = nd6_prefix_onlink(opr)) != 0) { 1718 nd6log((LOG_ERR, 1719 "nd6_prefix_offlink: failed to " 1720 "recover a prefix %s/%d from %s " 1721 "to %s (errno = %d)\n", |
1707 ip6_sprintf(&opr->ndpr_prefix.sin6_addr), | 1722 ip6_sprintf(ip6buf, 1723 &opr->ndpr_prefix.sin6_addr), |
1708 opr->ndpr_plen, if_name(ifp), 1709 if_name(opr->ndpr_ifp), e)); 1710 } 1711 } 1712 } 1713 } else { 1714 /* XXX: can we still set the NDPRF_ONLINK flag? */ 1715 nd6log((LOG_ERR, 1716 "nd6_prefix_offlink: failed to delete route: " 1717 "%s/%d on %s (errno = %d)\n", | 1724 opr->ndpr_plen, if_name(ifp), 1725 if_name(opr->ndpr_ifp), e)); 1726 } 1727 } 1728 } 1729 } else { 1730 /* XXX: can we still set the NDPRF_ONLINK flag? */ 1731 nd6log((LOG_ERR, 1732 "nd6_prefix_offlink: failed to delete route: " 1733 "%s/%d on %s (errno = %d)\n", |
1718 ip6_sprintf(&sa6.sin6_addr), pr->ndpr_plen, if_name(ifp), 1719 error)); | 1734 ip6_sprintf(ip6buf, &sa6.sin6_addr), pr->ndpr_plen, 1735 if_name(ifp), error)); |
1720 } 1721 1722 if (rt != NULL) { 1723 RTFREE(rt); 1724 } 1725 1726 return (error); 1727} --- 6 unchanged lines hidden (view full) --- 1734 struct ifnet *ifp = pr->ndpr_ifp; 1735 struct ifaddr *ifa; 1736 struct in6_aliasreq ifra; 1737 struct in6_ifaddr *ia, *ib; 1738 int error, plen0; 1739 struct in6_addr mask; 1740 int prefixlen = pr->ndpr_plen; 1741 int updateflags; | 1736 } 1737 1738 if (rt != NULL) { 1739 RTFREE(rt); 1740 } 1741 1742 return (error); 1743} --- 6 unchanged lines hidden (view full) --- 1750 struct ifnet *ifp = pr->ndpr_ifp; 1751 struct ifaddr *ifa; 1752 struct in6_aliasreq ifra; 1753 struct in6_ifaddr *ia, *ib; 1754 int error, plen0; 1755 struct in6_addr mask; 1756 int prefixlen = pr->ndpr_plen; 1757 int updateflags; |
1758 char ip6buf[INET6_ADDRSTRLEN]; |
|
1742 1743 in6_prefixlen2mask(&mask, prefixlen); 1744 1745 /* 1746 * find a link-local address (will be interface ID). 1747 * Is it really mandatory? Theoretically, a global or a site-local 1748 * address can be configured without a link-local address, if we 1749 * have a unique interface identifier... --- 71 unchanged lines hidden (view full) --- 1821 /* 1822 * Make sure that we do not have this address already. This should 1823 * usually not happen, but we can still see this case, e.g., if we 1824 * have manually configured the exact address to be configured. 1825 */ 1826 if (in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr) != NULL) { 1827 /* this should be rare enough to make an explicit log */ 1828 log(LOG_INFO, "in6_ifadd: %s is already configured\n", | 1759 1760 in6_prefixlen2mask(&mask, prefixlen); 1761 1762 /* 1763 * find a link-local address (will be interface ID). 1764 * Is it really mandatory? Theoretically, a global or a site-local 1765 * address can be configured without a link-local address, if we 1766 * have a unique interface identifier... --- 71 unchanged lines hidden (view full) --- 1838 /* 1839 * Make sure that we do not have this address already. This should 1840 * usually not happen, but we can still see this case, e.g., if we 1841 * have manually configured the exact address to be configured. 1842 */ 1843 if (in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr) != NULL) { 1844 /* this should be rare enough to make an explicit log */ 1845 log(LOG_INFO, "in6_ifadd: %s is already configured\n", |
1829 ip6_sprintf(&ifra.ifra_addr.sin6_addr)); | 1846 ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr)); |
1830 return (NULL); 1831 } 1832 1833 /* 1834 * Allocate ifaddr structure, link into chain, etc. 1835 * If we are going to create a new address upon receiving a multicasted 1836 * RA, we need to impose a random delay before starting DAD. 1837 * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2] 1838 */ 1839 updateflags = 0; 1840 if (mcast) 1841 updateflags |= IN6_IFAUPDATE_DADDELAY; 1842 if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) { 1843 nd6log((LOG_ERR, 1844 "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n", | 1847 return (NULL); 1848 } 1849 1850 /* 1851 * Allocate ifaddr structure, link into chain, etc. 1852 * If we are going to create a new address upon receiving a multicasted 1853 * RA, we need to impose a random delay before starting DAD. 1854 * [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2] 1855 */ 1856 updateflags = 0; 1857 if (mcast) 1858 updateflags |= IN6_IFAUPDATE_DADDELAY; 1859 if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) { 1860 nd6log((LOG_ERR, 1861 "in6_ifadd: failed to make ifaddr %s on %s (errno=%d)\n", |
1845 ip6_sprintf(&ifra.ifra_addr.sin6_addr), if_name(ifp), 1846 error)); | 1862 ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr), 1863 if_name(ifp), error)); |
1847 return (NULL); /* ifaddr must not have been allocated. */ 1848 } 1849 1850 ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr); 1851 1852 return (ia); /* this is always non-NULL */ 1853} 1854 --- 253 unchanged lines hidden --- | 1864 return (NULL); /* ifaddr must not have been allocated. */ 1865 } 1866 1867 ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr); 1868 1869 return (ia); /* this is always non-NULL */ 1870} 1871 --- 253 unchanged lines hidden --- |