72#include <sys/eventhandler.h>
75#include <sys/malloc.h>
76#include <sys/socket.h>
77#include <sys/socketvar.h>
78#include <sys/sockio.h>
82#include <sys/protosw.h>
84#include <sys/kernel.h>
86#include <sys/rmlock.h>
87#include <sys/sysctl.h>
88#include <sys/syslog.h>
91#include <net/if_var.h>
92#include <net/if_types.h>
94#include <net/route/route_ctl.h>
95#include <net/route/nhop.h>
99#include <netinet/in.h>
100#include <netinet/in_var.h>
101#include <net/if_llatbl.h>
102#include <netinet/if_ether.h>
103#include <netinet/in_systm.h>
104#include <netinet/ip.h>
105#include <netinet/in_pcb.h>
106#include <netinet/ip_carp.h>
108#include <netinet/ip6.h>
123 offsetof(
struct ifreq, ifr_ifru),
124 "struct in6_ifreq and struct ifreq are not type punnable");
127#define V_icmp6_nodeinfo_oldmcprefix VNET(icmp6_nodeinfo_oldmcprefix)
135 IN6ADDR_NODELOCAL_ALLNODES_INIT;
137 IN6ADDR_LINKLOCAL_ALLNODES_INIT;
139 IN6ADDR_LINKLOCAL_ALLROUTERS_INIT;
141 IN6ADDR_LINKLOCAL_ALLV2ROUTERS_INIT;
150 {
sizeof(
sa6_any), AF_INET6, 0, 0, IN6ADDR_ANY_INIT, 0 };
165#define ifa2ia6(ifa) ((struct in6_ifaddr *)(ifa))
166#define ia62ifa(ia6) (&((ia6)->ia_ifa))
171 struct rt_addrinfo info;
173 struct sockaddr_dl gateway;
182 bzero(&info,
sizeof(
struct rt_addrinfo));
183 info.rti_flags = ifa->ifa_flags | RTF_HOST | RTF_STATIC | RTF_PINNED;
184 info.rti_info[RTAX_DST] = ifa->ifa_addr;
185 info.rti_info[RTAX_GATEWAY] = (
struct sockaddr *)&gateway;
186 link_init_sdl(ifa->ifa_ifp, (
struct sockaddr *)&gateway, ifa->ifa_ifp->if_type);
187 if (cmd != RTM_DELETE)
188 info.rti_ifp = V_loif;
190 fibnum =
ia62ifa(ia)->ifa_ifp->if_fib;
192 if (cmd == RTM_ADD) {
193 rt_addrmsg(cmd, &ia->
ia_ifa, fibnum);
194 rt_routemsg_info(cmd, &info, fibnum);
195 }
else if (cmd == RTM_DELETE) {
196 rt_routemsg_info(cmd, &info, fibnum);
197 rt_addrmsg(cmd, &ia->
ia_ifa, fibnum);
205 u_char *lim = lim0, *p;
208 if (lim0 == NULL || lim0 - (u_char *)mask >
sizeof(*mask))
209 lim = (u_char *)mask +
sizeof(*mask);
210 for (p = (u_char *)mask; p < lim; x++, p++) {
216 for (y = 0; y < 8; y++) {
217 if ((*p & (0x80 >> y)) == 0)
227 if (y != 0 && (*p & (0x00ff >> y)) != 0)
229 for (p = p + 1; p < lim; p++)
237#ifdef COMPAT_FREEBSD32
238struct in6_ndifreq32 {
239 char ifname[IFNAMSIZ];
242#define SIOCGDEFIFACE32_IN6 _IOWR('i', 86, struct in6_ndifreq32)
247 struct ifnet *ifp,
struct thread *td)
253 int carp_attached = 0;
278 error = priv_check(td, PRIV_NETINET_ADDRCTRL6);
296 error = priv_check(td, PRIV_NETINET_ND6);
307#ifdef COMPAT_FREEBSD32
308 case SIOCGDEFIFACE32_IN6:
311 struct in6_ndifreq32 *ndif32;
317 ndif32 = (
struct in6_ndifreq32 *)data;
318 ndif32->ifindex = ndif.
ifindex;
332 "prefix ioctls are now invalidated. "
333 "please use ifconfig.\n");
340 error = priv_check(td, PRIV_NETINET_SCOPE6);
383 sa6 = &ifr->ifr_addr;
436 error = EADDRNOTAVAIL;
447 error = EAFNOSUPPORT;
453 PRIV_NET_DELIFADDR : PRIV_NET_ADDIFADDR);
460 if (ifp->if_afdata[AF_INET6] == NULL) {
461 error = EPFNOSUPPORT;
475 error = EADDRNOTAVAIL;
489 if ((ifp->if_flags & IFF_POINTOPOINT) == 0) {
508 ifp->if_afdata[AF_INET6])->in6_ifstat,
510 sizeof(
struct in6_ifstat) /
sizeof(uint64_t));
515 ifp->if_afdata[AF_INET6])->icmp6_ifstat,
532 ~((time_t)1 << ((
sizeof(maxexpire) * 8) - 1));
550 ~((time_t)1 << ((
sizeof(maxexpire) * 8) - 1));
573 (*carp_detach_p)(&ia->
ia_ifa,
true);
585 if (cmd == ocmd && ifra->
ifra_vhid > 0) {
586 if (carp_attach_p != NULL)
587 error = (*carp_attach_p)(&ia->
ia_ifa,
590 error = EPROTONOSUPPORT;
608 bzero(&pr0,
sizeof(pr0));
628 pr0.ndpr_raf_onlink = 1;
642 (*carp_detach_p)(&ia->
ia_ifa,
false);
661 log(LOG_NOTICE,
"in6_control: failed "
662 "to create a temporary address, "
683 memset(&nd, 0,
sizeof(nd));
685 nd.
ndi.
flags &= ~ND6_IFF_IFDISABLED;
687 log(LOG_NOTICE,
"SIOCAIFADDR_IN6: "
688 "SIOCSIFINFO_FLAGS for -ifdisabled "
700 EVENTHANDLER_INVOKE(ifaddr_event_ext, ifp, &ia->
ia_ifa,
705 if (ifp->if_ioctl == NULL) {
709 error = (*ifp->if_ioctl)(ifp, cmd, data);
722 int *errorp,
int delay)
727 imm = malloc(
sizeof(*imm), M_IP6MADDR, M_NOWAIT);
733 delay = (delay * PR_FASTHZ) / hz;
738 free(imm, M_IP6MADDR);
757 KASSERT(in6m_sol != NULL, (
"%s: in6m_sol is NULL", __func__));
760 bzero(&mltaddr,
sizeof(
struct in6_addr));
762 mltaddr.s6_addr32[2] = htonl(1);
764 mltaddr.s6_addr8[12] = 0xff;
767 log(LOG_ERR,
"%s: in6_setscope failed\n", __func__);
782 nd6log((LOG_WARNING,
"%s: in6_joingroup failed for %s on %s "
783 "(errno=%d)\n", __func__,
ip6_sprintf(ip6buf, &mltaddr),
784 if_name(ifp), error));
787 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
799 nd6log((LOG_WARNING,
"%s: in6_joingroup failed for %s on %s "
800 "(errno=%d)\n", __func__,
ip6_sprintf(ip6buf, &mltaddr),
801 if_name(ifp), error));
804 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
822 "%s: in6_joingroup failed for %s on %s "
824 &mltaddr), if_name(ifp), error));
827 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
834 "%s: in6_joingroup failed for %s on %s "
836 &mltaddr), if_name(ifp), error));
839 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
852 nd6log((LOG_WARNING,
"%s: in6_joingroup failed for %s on %s "
854 &mltaddr), if_name(ifp), error));
857 LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain);
872 int error, hostIsNew = 0;
885 if (hostIsNew != 0) {
929 if (ifp == NULL || ifra == NULL)
936 if ((ifp->if_flags & IFF_POINTOPOINT) != 0 &&
939 return (EAFNOSUPPORT);
981 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 &&
1009 if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) {
1011 nd6log((LOG_INFO,
"in6_update_ifa: a destination can "
1012 "be specified for a p2p or a loopback IF only\n"));
1016 nd6log((LOG_INFO,
"in6_update_ifa: prefixlen should "
1017 "be 128 when dstaddr is specified\n"));
1031 "in6_update_ifa: valid lifetime is 0 for %s\n",
1048 nd6log((LOG_INFO,
"in6_validate_ifa: the prefix length "
1049 "of an existing %s address should not be changed\n",
1072 ia = (
struct in6_ifaddr *)ifa_alloc(
sizeof(*ia), M_NOWAIT);
1075 LIST_INIT(&ia->ia6_memberships);
1083 if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) {
1091 ia->
ia_ifa.ifa_dstaddr = NULL;
1105 CK_STAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->
ia_ifa, ifa_link);
1106 IF_ADDR_WUNLOCK(ifp);
1126 struct in6_ifaddr *ia,
int hostIsNew,
int flags)
1208 if ((ifp->if_flags & IFF_MULTICAST) != 0) {
1219 int delay, mindelay, maxdelay;
1234 if (in6m_sol != NULL &&
1239 if (maxdelay - mindelay == 0)
1243 (arc4random() % (maxdelay - mindelay)) +
1262 struct epoch_tracker et;
1263 struct ifaddr *ifa = &ia->
ia_ifa;
1267 struct sockaddr_dl_short sdl = {
1268 .sdl_family = AF_LINK,
1269 .sdl_len =
sizeof(
struct sockaddr_dl_short),
1270 .sdl_type = ifa->ifa_ifp->if_type,
1271 .sdl_index = ifa->ifa_ifp->if_index,
1280 struct rt_addrinfo info = {
1282 .rti_flags = RTF_PINNED | RTF_HOST,
1284 [RTAX_DST] = (
struct sockaddr *)&dst,
1285 [RTAX_GATEWAY] = (
struct sockaddr *)&sdl,
1290 NET_EPOCH_ENTER(et);
1291 error = rib_handle_ifaddr_info(ifa->ifa_ifp->if_fib, cmd, &info);
1314 struct ifnet *ifp = ifa->ifa_ifp;
1320 (*carp_detach_p)(ifa,
false);
1327 if (ia->ia_flags & IFA_RTSELF) {
1328 error = ifa_del_loopback_route((
struct ifaddr *)ia,
1329 (
struct sockaddr *)&ia->
ia_addr);
1331 ia->ia_flags &= ~IFA_RTSELF;
1338 while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
1339 LIST_REMOVE(imm, i6mm_chain);
1342 free(imm, M_IP6MADDR);
1345 if ((ia->ia_flags & IFA_ROUTE) &&
ifa_is_p2p(ia)) {
1348 log(LOG_INFO,
"%s: err=%d, destination address delete "
1349 "failed\n", __func__, error);
1350 ia->ia_flags &= ~IFA_ROUTE;
1394 CK_STAILQ_REMOVE(&ifp->if_addrhead, &ia->
ia_ifa, ifaddr, ifa_link);
1395 IF_ADDR_WUNLOCK(ifp);
1405 CK_LIST_REMOVE(ia, ia6_hash);
1415 "in6_unlink_ifa: autoconf'ed address "
1448 int error = 0, ifacount = 0;
1457 if (hostIsNew != 0) {
1458 struct epoch_tracker et;
1460 NET_EPOCH_ENTER(et);
1461 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1462 if (ifa->ifa_addr->sa_family != AF_INET6)
1469 if (ifacount <= 1 && ifp->if_ioctl) {
1470 error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia);
1483 if ((ia->ia_flags & IFA_ROUTE) != 0 &&
1485 nd6log((LOG_ERR,
"in6_update_ifa_internal: failed to "
1486 "remove a route to the old destination: %s\n",
1490 ia->ia_flags &= ~IFA_ROUTE;
1501 if (!(ia->ia_flags & IFA_ROUTE) &&
ifa_is_p2p(ia)) {
1505 ia->ia_flags |= IFA_ROUTE;
1512 error = ifa_add_loopback_route((
struct ifaddr *)ia,
1513 (
struct sockaddr *)&ia->
ia_addr);
1515 ia->ia_flags |= IFA_RTSELF;
1518 WITNESS_WARN(WARN_GIANTOK | WARN_SLEEPOK, NULL,
1519 "Invoking IPv6 network device address event may sleep");
1522 EVENTHANDLER_INVOKE(ifaddr_event_ext, ifp, &ia->
ia_ifa,
1540 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1541 if (ifa->ifa_addr->sa_family != AF_INET6)
1562 struct rm_priotracker in6_ifa_tracker;
1587 struct epoch_tracker et;
1590 NET_EPOCH_ENTER(et);
1591 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1592 if (ifa->ifa_addr->sa_family != AF_INET6)
1610 struct epoch_tracker et;
1616 NET_EPOCH_ENTER(et);
1617 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1618 if (ifa->ifa_addr->sa_family != AF_INET6)
1639 int i, cnt = 0, maxcnt = 0, idx = 0, index = 0;
1641 const u_int16_t *a = (
const u_int16_t *)addr;
1643 int dcolon = 0, zero = 0;
1647 for (i = 0; i < 8; i++) {
1648 if (*(a + i) == 0) {
1653 else if (maxcnt < cnt) {
1664 for (i = 0; i < 8; i++) {
1675 if (dcolon == 0 && *(a + 1) == 0 && i == index) {
1687 d = (
const u_char *)a;
1695 *cp =
digits[*d++ & 0xf];
1696 if (zero == 0 || (*cp !=
'0')) {
1701 if (zero == 0 || (*cp !=
'0')) {
1705 *cp++ =
digits[*d & 0xf];
1716 struct rm_priotracker in6_ifa_tracker;
1742 struct rm_priotracker in6_ifa_tracker;
1762 struct rm_priotracker in6_ifa_tracker;
1768 ia->
ia_ifa.ifa_ifp->if_fib == fib) {
1794 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1795 if (ifa->ifa_addr->sa_family != AF_INET6)
1808 struct rm_priotracker in6_ifa_tracker;
1834 u_char *s = (u_char *)src, *d = (u_char *)dst;
1835 u_char *lim = s + 16, r;
1838 if ((r = (*d++ ^ *s++)) != 0) {
1853 int bytelen, bitlen;
1856 if (0 > len || len > 128) {
1857 log(LOG_ERR,
"in6_are_prefix_equal: invalid prefix length(%d)\n",
1865 if (bcmp(&p1->s6_addr, &p2->s6_addr, bytelen))
1868 p1->s6_addr[bytelen] >> (8 - bitlen) !=
1869 p2->s6_addr[bytelen] >> (8 - bitlen))
1878 u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff};
1879 int bytelen, bitlen, i;
1882 if (0 > len || len > 128) {
1883 log(LOG_ERR,
"in6_prefixlen2mask: invalid prefix length(%d)\n",
1888 bzero(maskp,
sizeof(*maskp));
1891 for (i = 0; i < bytelen; i++)
1892 maskp->s6_addr[i] = 0xff;
1894 maskp->s6_addr[bytelen] = maskarray[bitlen - 1];
1911 dep[0] = dep[1] = NULL;
1919 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1920 if (ifa->ifa_addr->sa_family != AF_INET6)
1953 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1954 if (ifa->ifa_addr->sa_family != AF_INET6)
1986 struct epoch_tracker et;
1990 NET_EPOCH_ENTER(et);
1991 CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1992 if (ifa->ifa_addr->sa_family != AF_INET6)
2018 if ((ifp->if_flags & IFF_LOOPBACK) != 0)
2020 if ((ifp->if_flags & IFF_MULTICAST) == 0)
2035 struct epoch_tracker et;
2036 unsigned long maxmtu = 0;
2039 NET_EPOCH_ENTER(et);
2040 CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) {
2042 if (!ifp->if_afdata[AF_INET6])
2044 if ((ifp->if_flags & IFF_LOOPBACK) == 0 &&
2064 switch (ifp->if_type) {
2066 case IFT_PROPVIRTUAL:
2069 case IFT_INFINIBAND:
2093 printf(
"in6_if2idlen: unknown link type (%d)\n", ifp->if_type);
2102#define IN6_LLTBL_DEFAULT_HSIZE 32
2103#define IN6_LLTBL_HASH(k, h) \
2104 (((((((k >> 8) ^ k) >> 8) ^ k) >> 8) ^ k) & ((h) - 1))
2112 struct llentry *lle;
2114 lle = __containerof(ctx,
struct llentry, lle_epoch_ctx);
2115 LLE_LOCK_DESTROY(lle);
2116 LLE_REQ_DESTROY(lle);
2117 free(lle, M_LLTABLE);
2132static struct llentry *
2137 lle = malloc(
sizeof(
struct in6_llentry), M_LLTABLE, M_NOWAIT | M_ZERO);
2141 lle->
base.r_l3addr.addr6 = *addr6;
2142 lle->
base.lle_refcnt = 1;
2144 LLE_LOCK_INIT(&lle->
base);
2145 LLE_REQ_INIT(&lle->
base);
2146 callout_init(&lle->
base.lle_timer, 1);
2148 return (&lle->
base);
2153 const struct sockaddr *smask, u_int flags,
struct llentry *lle)
2155 const struct in6_addr *addr, *mask, *lle_addr;
2157 addr = &((
const struct sockaddr_in6 *)saddr)->sin6_addr;
2158 mask = &((
const struct sockaddr_in6 *)smask)->sin6_addr;
2159 lle_addr = &lle->r_l3addr.addr6;
2164 if (lle->la_flags & LLE_IFADDR) {
2171 (flags & LLE_STATIC) != 0)
2177 if ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC))
2188 LLE_WLOCK_ASSERT(lle);
2189 KASSERT(llt != NULL, (
"lltable is NULL"));
2192 if ((lle->la_flags & LLE_LINKED) != 0) {
2194 IF_AFDATA_WLOCK_ASSERT(ifp);
2195 lltable_unlink_entry(llt, lle);
2204 const struct sockaddr *l3addr)
2207 struct nhop_object *nh;
2214 KASSERT(l3addr->sa_family == AF_INET6,
2215 (
"sin_family %d", l3addr->sa_family));
2219 fibnum = V_rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib;
2220 nh =
fib6_lookup(fibnum, &dst, scopeid, NHR_NONE, 0);
2221 if (nh && ((nh->nh_flags & NHF_GATEWAY) || nh->nh_ifp != ifp)) {
2227 ifa = ifaof_ifpforaddr(l3addr, ifp);
2231 log(LOG_INFO,
"IPv6 address: \"%s\" is not on the network\n",
2238static inline uint32_t
2264static inline struct llentry *
2267 struct llentry *lle;
2268 struct llentries *lleh;
2272 lleh = &llt->lle_head[hashidx];
2273 CK_LIST_FOREACH(lle, lleh, lle_next) {
2274 if (lle->la_flags & LLE_DELETED)
2287 lle->la_flags |= LLE_DELETED;
2288 EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
2290 log(LOG_INFO,
"ifaddr cache = %p is deleted\n", lle);
2295static struct llentry *
2297 const struct sockaddr *l3addr)
2300 struct ifnet *ifp = llt->llt_ifp;
2301 struct llentry *lle;
2302 char linkhdr[LLE_MAX_LINKHDR];
2306 KASSERT(l3addr->sa_family == AF_INET6,
2307 (
"sin_family %d", l3addr->sa_family));
2314 if (!(flags & LLE_IFADDR) &&
2320 log(LOG_INFO,
"lla_lookup: new lle malloc failed\n");
2323 lle->la_flags = flags;
2324 if ((flags & LLE_IFADDR) == LLE_IFADDR) {
2325 linkhdrsize = LLE_MAX_LINKHDR;
2326 if (lltable_calc_llheader(ifp, AF_INET6, IF_LLADDR(ifp),
2327 linkhdr, &linkhdrsize, &lladdr_off) != 0) {
2331 lltable_set_entry_addr(ifp, lle, linkhdr, linkhdrsize,
2333 lle->la_flags |= LLE_STATIC;
2336 if ((lle->la_flags & LLE_STATIC) != 0)
2342static struct llentry *
2344 const struct sockaddr *l3addr)
2347 int family = flags >> 16;
2348 struct llentry *lle;
2350 IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
2351 KASSERT(l3addr->sa_family == AF_INET6,
2352 (
"sin_family %d", l3addr->sa_family));
2353 KASSERT((flags & (LLE_UNLOCKED | LLE_EXCLUSIVE)) !=
2354 (LLE_UNLOCKED | LLE_EXCLUSIVE),
2355 (
"wrong lle request flags: %#x", flags));
2359 if (__predict_false(family != AF_INET6))
2360 lle = llentry_lookup_family(lle, family);
2365 if (flags & LLE_UNLOCKED)
2368 if (flags & LLE_EXCLUSIVE)
2377 if (__predict_false((lle->la_flags & LLE_LINKED) == 0)) {
2378 if (flags & LLE_EXCLUSIVE)
2389 struct sysctl_req *wr)
2391 struct ifnet *ifp = llt->llt_ifp;
2394 struct rt_msghdr rtm;
2402 struct sockaddr_dl sdl;
2404 struct sockaddr_dl *sdl;
2407 bzero(&ndpc,
sizeof(ndpc));
2409 if ((lle->la_flags & LLE_DELETED) == LLE_DELETED)
2412 lltable_fill_sa_entry(lle, (
struct sockaddr *)&ndpc.sin6);
2413 if (prison_if(wr->td->td_ucred, (
struct sockaddr *)&ndpc.sin6) != 0)
2421 ndpc.rtm.rtm_msglen =
sizeof(ndpc);
2422 ndpc.rtm.rtm_version = RTM_VERSION;
2423 ndpc.rtm.rtm_type = RTM_GET;
2424 ndpc.rtm.rtm_flags = RTF_UP;
2425 ndpc.rtm.rtm_addrs = RTA_DST | RTA_GATEWAY;
2429 if (lle->la_flags & LLE_PUB)
2433 sdl->sdl_family = AF_LINK;
2434 sdl->sdl_len =
sizeof(*sdl);
2435 sdl->sdl_index = ifp->if_index;
2436 sdl->sdl_type = ifp->if_type;
2437 if ((lle->la_flags & LLE_VALID) == LLE_VALID) {
2438 sdl->sdl_alen = ifp->if_addrlen;
2439 bcopy(lle->ll_addr, LLADDR(sdl), ifp->if_addrlen);
2442 bzero(LLADDR(sdl), ifp->if_addrlen);
2444 if (lle->la_expire != 0)
2445 ndpc.rtm.rtm_rmx.rmx_expire = lle->la_expire +
2446 lle->lle_remtime / hz + time_second - time_uptime;
2447 ndpc.rtm.rtm_flags |= (RTF_HOST | RTF_LLDATA);
2448 if (lle->la_flags & LLE_STATIC)
2449 ndpc.rtm.rtm_flags |= RTF_STATIC;
2450 if (lle->la_flags & LLE_IFADDR)
2451 ndpc.rtm.rtm_flags |= RTF_PINNED;
2452 if (lle->ln_router != 0)
2453 ndpc.rtm.rtm_flags |= RTF_GATEWAY;
2454 ndpc.rtm.rtm_rmx.rmx_pksent = lle->la_asked;
2456 ndpc.rtm.rtm_rmx.rmx_state = lle->ln_state;
2457 ndpc.rtm.rtm_index = ifp->if_index;
2458 error = SYSCTL_OUT(wr, &ndpc,
sizeof(ndpc));
2463static struct lltable *
2466 struct lltable *llt;
2469 llt->llt_af = AF_INET6;
2480 llt->llt_mark_used = llentry_mark_used;
2489 struct lltable *llt = NULL;
2491 void *afdata_ptr = ifp->if_afdata[AF_INET6];
2492 if (afdata_ptr != NULL)
2493 llt = ((
struct in6_ifextra *)afdata_ptr)->lltable;
2503 switch (ifp->if_type) {
2509 ext = (
struct in6_ifextra *)malloc(
sizeof(*ext), M_IFADDR, M_WAITOK);
2510 bzero(ext,
sizeof(*ext));
2512 ext->
in6_ifstat = malloc(
sizeof(counter_u64_t) *
2513 sizeof(
struct in6_ifstat) /
sizeof(uint64_t), M_IFADDR, M_WAITOK);
2515 sizeof(
struct in6_ifstat) /
sizeof(uint64_t), M_WAITOK);
2518 sizeof(
struct icmp6_ifstat) /
sizeof(uint64_t), M_IFADDR,
2521 sizeof(
struct icmp6_ifstat) /
sizeof(uint64_t), M_WAITOK);
2535 if (ifp->if_afdata[AF_INET6] == NULL)
2551 sizeof(
struct in6_ifstat) /
sizeof(uint64_t));
2556 free(ext, M_IFADDR);
2567 bzero(sin,
sizeof(*sin));
2568 sin->sin_len =
sizeof(
struct sockaddr_in);
2569 sin->sin_family = AF_INET;
2592 struct sockaddr_in *sin_p;
2600 sin_p = (
struct sockaddr_in *)nam;
2608 struct sockaddr_in *sin_p;
2611 sin6_p = malloc(
sizeof *sin6_p, M_SONAME, M_WAITOK);
2612 sin_p = (
struct sockaddr_in *)*nam;
2614 free(*nam, M_SONAME);
2615 *nam = (
struct sockaddr *)sin6_p;
static struct llentry * in6_lltable_find_dst(struct lltable *llt, const struct in6_addr *dst)
static int in6_notify_ifa(struct ifnet *, struct in6_ifaddr *, struct in6_aliasreq *, int)
const struct in6_addr in6addr_linklocal_allrouters
const struct in6_addr in6mask96
static struct llentry * in6_lltable_new(const struct in6_addr *addr6, u_int flags)
struct in6_ifaddr * in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags)
void in6_purgeifaddr(struct in6_ifaddr *ia)
static int in6_update_ifa_join_mc(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia, int flags, struct in6_multi **in6m_sol)
const struct in6_addr in6mask128
int in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, struct in6_ifaddr *ia, int flags)
static int in6_lltable_dump_entry(struct lltable *llt, struct llentry *lle, struct sysctl_req *wr)
void in6_newaddrmsg(struct in6_ifaddr *ia, int cmd)
static void in6_lltable_free_entry(struct lltable *llt, struct llentry *lle)
static struct llentry * in6_lltable_lookup(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
const struct in6_addr in6mask32
const struct in6_addr in6addr_nodelocal_allnodes
static int in6_broadcast_ifa(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int)
void in6_sin_2_v4mapsin6(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
int in6_is_addr_deprecated(struct sockaddr_in6 *sa6)
const struct in6_addr in6addr_linklocal_allv2routers
void in6_purgeaddr(struct ifaddr *ifa)
int in6_matchlen(struct in6_addr *src, struct in6_addr *dst)
const struct in6_addr in6addr_loopback
void in6_prefixlen2mask(struct in6_addr *maskp, int len)
struct lltable * in6_lltable_get(struct ifnet *ifp)
int in6_ifhasaddr(struct ifnet *ifp, struct in6_addr *addr)
static int in6_update_ifa_internal(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int, int)
void in6_sin6_2_sin(struct sockaddr_in *sin, struct sockaddr_in6 *sin6)
static void in6_lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
int in6_domifmtu(struct ifnet *ifp)
static int in6_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr)
void in6_sin_2_v4mapsin6_in_sock(struct sockaddr **nam)
static void in6_lltable_destroy_lle(struct llentry *lle)
void in6_prepare_ifra(struct in6_aliasreq *ifra, const struct in6_addr *addr, const struct in6_addr *mask)
struct in6_ifaddr * in6ifa_llaonifp(struct ifnet *ifp)
const struct in6_addr in6mask0
#define IN6_LLTBL_HASH(k, h)
_Static_assert(offsetof(struct in6_ifreq, ifr_ifru)==offsetof(struct ifreq, ifr_ifru), "struct in6_ifreq and struct ifreq are not type punnable")
static struct in6_multi_mship * in6_joingroup_legacy(struct ifnet *ifp, const struct in6_addr *mcaddr, int *errorp, int delay)
static struct in6_ifaddr * in6_alloc_ifa(struct ifnet *, struct in6_aliasreq *, int flags)
static uint32_t in6_lltable_hash_dst(const struct in6_addr *dst, uint32_t hsize)
char * ip6_sprintf(char *ip6buf, const struct in6_addr *addr)
VNET_DECLARE(int, icmp6_nodeinfo_oldmcprefix)
const struct in6_addr in6mask64
struct in6_ifaddr * in6_ifawithifp(struct ifnet *ifp, struct in6_addr *dst)
static int in6_lltable_match_prefix(const struct sockaddr *saddr, const struct sockaddr *smask, u_int flags, struct llentry *lle)
void in6_domifdetach(struct ifnet *ifp, void *aux)
#define V_icmp6_nodeinfo_oldmcprefix
static uint32_t in6_lltable_hash(const struct llentry *lle, uint32_t hsize)
int in6_mask2len(struct in6_addr *mask, u_char *lim0)
int in6_localip(struct in6_addr *in6)
static struct lltable * in6_lltattach(struct ifnet *ifp)
bool in6_localip_fib(struct in6_addr *in6, uint16_t fib)
void * in6_domifattach(struct ifnet *ifp)
static void in6_lltable_destroy_lle_unlocked(epoch_context_t ctx)
struct in6_ifaddr * in6ifa_ifwithaddr(const struct in6_addr *addr, uint32_t zoneid, bool referenced)
static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *)
static struct llentry * in6_lltable_alloc(struct lltable *llt, u_int flags, const struct sockaddr *l3addr)
int in6_if2idlen(struct ifnet *ifp)
static int in6_handle_dstaddr_rtrequest(int cmd, struct in6_ifaddr *ia)
const struct in6_addr in6addr_linklocal_allnodes
int in6_localaddr(struct in6_addr *in6)
static void in6_lltable_delete_entry(struct lltable *llt, struct llentry *lle)
struct in6_ifaddr * in6ifa_ifpwithaddr(struct ifnet *ifp, const struct in6_addr *addr)
int in6if_do_dad(struct ifnet *ifp)
void in6_sin6_2_sin_in_sock(struct sockaddr *nam)
static bool ifa_is_p2p(struct in6_ifaddr *ia)
static int in6_validate_ifra(struct ifnet *, struct in6_aliasreq *, struct in6_ifaddr *, int)
int in6_are_prefix_equal(struct in6_addr *p1, struct in6_addr *p2, int len)
const struct sockaddr_in6 sa6_any
void in6_if_up(struct ifnet *ifp)
const struct in6_addr in6addr_any
int in6_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
#define IN6_LLTBL_DEFAULT_HSIZE
#define IPV6_ADDR_INT32_SMP
int in6_addrscope(const struct in6_addr *)
#define IN6_IS_ADDR_LINKLOCAL(a)
#define IN6_IS_ADDR_LOOPBACK(a)
#define IPV6_ADDR_INT32_MLL
#define IN6_ARE_ADDR_EQUAL(a, b)
#define IN6_IS_ADDR_MC_INTFACELOCAL(a)
#define IN6_IS_ADDR_MC_NODELOCAL(a)
#define IN6_IS_SCOPE_LINKLOCAL(a)
struct nhop_object * fib6_lookup(uint32_t fibnum, const struct in6_addr *dst6, uint32_t scopeid, uint32_t flags, uint32_t flowid)
int in6_nigroup(struct ifnet *ifp, const char *name, int namelen, struct in6_addr *in6)
int in6_nigroup_oldmcprefix(struct ifnet *ifp, const char *name, int namelen, struct in6_addr *in6)
void in6_ifattach(struct ifnet *ifp, struct ifnet *altifp)
int prison_check_ip6(const struct ucred *cred, const struct in6_addr *ia6)
int in6_leavegroup(struct in6_multi *inm, struct in6_mfilter *imf)
int in6_joingroup(struct ifnet *ifp, const struct in6_addr *mcaddr, struct in6_mfilter *imf, struct in6_multi **pinm, const int delay)
int in6_src_ioctl(u_long cmd, caddr_t data)
#define IN6_ARE_MASKED_ADDR_EQUAL(d, a, m)
#define IN6_IFF_TENTATIVE
#define SIOCGIFDSTADDR_IN6
#define SIOCAADDRCTL_POLICY
#define IN6_IFADDR_RLOCK(t)
#define IN6_IFADDR_WLOCK()
#define SIOCGIFPDSTADDR_IN6
#define SIOCDIFPREFIX_IN6
#define SIOCGIFNETMASK_IN6
#define IN6_IFF_DEPRECATED
#define SIOCGDEFIFACE_IN6
#define SIOCGIFPSRCADDR_IN6
#define SIOCSRTRFLUSH_IN6
#define SIOCSGIFPREFIX_IN6
#define SIOCDADDRCTL_POLICY
#define SIOCSPFXFLUSH_IN6
#define SIOCSIFDSTADDR_IN6
#define IN6_IFADDR_RUNLOCK(t)
#define IN6_IFAUPDATE_DADDELAY
#define SIOCSIFPREFIX_IN6
#define SIOCAIFPREFIX_IN6
#define SIOCGIFALIFETIME_IN6
#define SIOCGIFSTAT_ICMP6
#define SIOCSIFNETMASK_IN6
#define SIOCGETMIFCNT_IN6
#define SIOCGIFPREFIX_IN6
#define SIOCSIFPHYADDR_IN6
#define IN6_MASK_ADDR(a, m)
#define IN6_IFADDR_WUNLOCK()
#define SIOCSIFINFO_FLAGS
#define SIOCSDEFIFACE_IN6
#define SIOCCIFPREFIX_IN6
static struct sockaddr_in6 sin6
int(* mrt6_ioctl)(u_long, caddr_t)
#define V_ip6_use_tempaddr
#define V_ip6_use_deprecated
struct mld_ifsoftc * mld_domifattach(struct ifnet *ifp)
void mld_domifdetach(struct ifnet *ifp)
#define MLD_REPORTING_MEMBER
int nd6_add_ifa_lle(struct in6_ifaddr *ia)
void nd6_rem_ifa_lle(struct in6_ifaddr *ia, int all)
int nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
void nd6_ifdetach(struct ifnet *ifp, struct nd_ifinfo *nd)
struct nd_ifinfo * nd6_ifattach(struct ifnet *ifp)
void pfxlist_onlink_check(void)
void nd6_dad_start(struct ifaddr *, int)
int nd6_prelist_add(struct nd_prefixctl *, struct nd_defrouter *, struct nd_prefix **)
void nd6_dad_stop(struct ifaddr *)
#define V_nd6_useloopback
void nd6_prefix_unlink(struct nd_prefix *, struct nd_prhead *)
void nd6_prefix_rele(struct nd_prefix *)
#define ND6_IFF_IFDISABLED
#define ND6_LLINFO_REACHABLE
struct nd_prefix * nd6_prefix_lookup(struct nd_prefixctl *)
#define ND6_INFINITE_LIFETIME
void nd6_prefix_del(struct nd_prefix *)
int in6_tmpifadd(const struct in6_ifaddr *, int, int)
#define MAX_RTR_SOLICITATION_DELAY
int in6_setscope(struct in6_addr *in6, struct ifnet *ifp, u_int32_t *ret_id)
struct scope6_id * scope6_ifattach(struct ifnet *ifp)
void in6_splitscope(const struct in6_addr *src, struct in6_addr *dst, uint32_t *scopeid)
int in6_clearscope(struct in6_addr *in6)
int sa6_embedscope(struct sockaddr_in6 *sin6, int defaultok)
int sa6_recoverscope(struct sockaddr_in6 *sin6)
void scope6_ifdetach(struct scope6_id *sid)
int scope6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp)
struct in6_addrlifetime ifra_lifetime
struct sockaddr_in6 ifra_prefixmask
struct sockaddr_in6 ifra_addr
struct sockaddr_in6 ifra_dstaddr
struct sockaddr_in6 ia_dstaddr
struct sockaddr_in6 ia_addr
struct nd_prefix * ia6_ndpr
struct in6_addrlifetime ia6_lifetime
struct sockaddr_in6 ia_prefixmask
struct icmp6_ifstat ifru_icmp6stat
struct in6_ifstat ifru_stat
struct in6_addrlifetime ifru_lifetime
union in6_ifreq::@2 ifr_ifru
struct in6_multi * i6mm_maddr
struct sockaddr_in6 ndpr_prefix
struct in6_addr sin6_addr