Deleted Added
full compact
in6.c (287617) in6.c (287789)
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

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

56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)in.c 8.2 (Berkeley) 11/15/93
61 */
62
63#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

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

56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE.
59 *
60 * @(#)in.c 8.2 (Berkeley) 11/15/93
61 */
62
63#include <sys/cdefs.h>
64__FBSDID("$FreeBSD: head/sys/netinet6/in6.c 287617 2015-09-10 08:37:03Z hrs $");
64__FBSDID("$FreeBSD: head/sys/netinet6/in6.c 287789 2015-09-14 16:48:19Z melifaro $");
65
66#include "opt_compat.h"
67#include "opt_inet.h"
68#include "opt_inet6.h"
69
70#include <sys/param.h>
71#include <sys/eventhandler.h>
72#include <sys/errno.h>

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

1302 (struct sockaddr *)&ia->ia_addr);
1303 if (error == 0)
1304 ia->ia_flags &= ~IFA_RTSELF;
1305 }
1306
1307 /* stop DAD processing */
1308 nd6_dad_stop(ifa);
1309
65
66#include "opt_compat.h"
67#include "opt_inet.h"
68#include "opt_inet6.h"
69
70#include <sys/param.h>
71#include <sys/eventhandler.h>
72#include <sys/errno.h>

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

1302 (struct sockaddr *)&ia->ia_addr);
1303 if (error == 0)
1304 ia->ia_flags &= ~IFA_RTSELF;
1305 }
1306
1307 /* stop DAD processing */
1308 nd6_dad_stop(ifa);
1309
1310 /* Remove local address entry from lltable. */
1311 nd6_rem_ifa_lle(ia);
1312
1313 /* Leave multicast groups. */
1314 while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
1315 LIST_REMOVE(imm, i6mm_chain);
1316 in6_leavegroup(imm);
1317 }
1318 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
1319 if ((ia->ia_flags & IFA_ROUTE) && plen == 128) {
1320 error = rtinit(&(ia->ia_ifa), RTM_DELETE, ia->ia_flags |

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

1328 in6_newaddrmsg(ia, RTM_DELETE);
1329 in6_unlink_ifa(ia, ifp);
1330}
1331
1332static void
1333in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
1334{
1335 char ip6buf[INET6_ADDRSTRLEN];
1310 /* Leave multicast groups. */
1311 while ((imm = LIST_FIRST(&ia->ia6_memberships)) != NULL) {
1312 LIST_REMOVE(imm, i6mm_chain);
1313 in6_leavegroup(imm);
1314 }
1315 plen = in6_mask2len(&ia->ia_prefixmask.sin6_addr, NULL); /* XXX */
1316 if ((ia->ia_flags & IFA_ROUTE) && plen == 128) {
1317 error = rtinit(&(ia->ia_ifa), RTM_DELETE, ia->ia_flags |

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

1325 in6_newaddrmsg(ia, RTM_DELETE);
1326 in6_unlink_ifa(ia, ifp);
1327}
1328
1329static void
1330in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp)
1331{
1332 char ip6buf[INET6_ADDRSTRLEN];
1333 int remove_lle;
1336
1337 IF_ADDR_WLOCK(ifp);
1338 TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
1339 IF_ADDR_WUNLOCK(ifp);
1340 ifa_free(&ia->ia_ifa); /* if_addrhead */
1341
1342 /*
1343 * Defer the release of what might be the last reference to the

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

1348 TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link);
1349 LIST_REMOVE(ia, ia6_hash);
1350 IN6_IFADDR_WUNLOCK();
1351
1352 /*
1353 * Release the reference to the base prefix. There should be a
1354 * positive reference.
1355 */
1334
1335 IF_ADDR_WLOCK(ifp);
1336 TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link);
1337 IF_ADDR_WUNLOCK(ifp);
1338 ifa_free(&ia->ia_ifa); /* if_addrhead */
1339
1340 /*
1341 * Defer the release of what might be the last reference to the

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

1346 TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link);
1347 LIST_REMOVE(ia, ia6_hash);
1348 IN6_IFADDR_WUNLOCK();
1349
1350 /*
1351 * Release the reference to the base prefix. There should be a
1352 * positive reference.
1353 */
1354 remove_lle = 0;
1356 if (ia->ia6_ndpr == NULL) {
1357 nd6log((LOG_NOTICE,
1358 "in6_unlink_ifa: autoconf'ed address "
1359 "%s has no prefix\n", ip6_sprintf(ip6buf, IA6_IN6(ia))));
1360 } else {
1361 ia->ia6_ndpr->ndpr_refcnt--;
1355 if (ia->ia6_ndpr == NULL) {
1356 nd6log((LOG_NOTICE,
1357 "in6_unlink_ifa: autoconf'ed address "
1358 "%s has no prefix\n", ip6_sprintf(ip6buf, IA6_IN6(ia))));
1359 } else {
1360 ia->ia6_ndpr->ndpr_refcnt--;
1361 /* Do not delete lles within prefix if refcont != 0 */
1362 if (ia->ia6_ndpr->ndpr_refcnt == 0)
1363 remove_lle = 1;
1362 ia->ia6_ndpr = NULL;
1363 }
1364
1364 ia->ia6_ndpr = NULL;
1365 }
1366
1367 nd6_rem_ifa_lle(ia, remove_lle);
1368
1365 /*
1366 * Also, if the address being removed is autoconf'ed, call
1367 * pfxlist_onlink_check() since the release might affect the status of
1368 * other (detached) addresses.
1369 */
1370 if ((ia->ia6_flags & IN6_IFF_AUTOCONF)) {
1371 pfxlist_onlink_check();
1372 }

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

2076 lle->base.lle_free = in6_lltable_destroy_lle;
2077 LLE_LOCK_INIT(&lle->base);
2078 callout_init(&lle->base.lle_timer, 1);
2079
2080 return (&lle->base);
2081}
2082
2083static int
1369 /*
1370 * Also, if the address being removed is autoconf'ed, call
1371 * pfxlist_onlink_check() since the release might affect the status of
1372 * other (detached) addresses.
1373 */
1374 if ((ia->ia6_flags & IN6_IFF_AUTOCONF)) {
1375 pfxlist_onlink_check();
1376 }

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

2080 lle->base.lle_free = in6_lltable_destroy_lle;
2081 LLE_LOCK_INIT(&lle->base);
2082 callout_init(&lle->base.lle_timer, 1);
2083
2084 return (&lle->base);
2085}
2086
2087static int
2084in6_lltable_match_prefix(const struct sockaddr *prefix,
2085 const struct sockaddr *mask, u_int flags, struct llentry *lle)
2088in6_lltable_match_prefix(const struct sockaddr *saddr,
2089 const struct sockaddr *smask, u_int flags, struct llentry *lle)
2086{
2090{
2087 const struct sockaddr_in6 *pfx = (const struct sockaddr_in6 *)prefix;
2088 const struct sockaddr_in6 *msk = (const struct sockaddr_in6 *)mask;
2091 const struct in6_addr *addr, *mask, *lle_addr;
2089
2092
2090 if (IN6_ARE_MASKED_ADDR_EQUAL(&lle->r_l3addr.addr6,
2091 &pfx->sin6_addr, &msk->sin6_addr) &&
2092 ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC)))
2093 addr = &((const struct sockaddr_in6 *)saddr)->sin6_addr;
2094 mask = &((const struct sockaddr_in6 *)smask)->sin6_addr;
2095 lle_addr = &lle->r_l3addr.addr6;
2096
2097 if (IN6_ARE_MASKED_ADDR_EQUAL(lle_addr, addr, mask) == 0)
2098 return (0);
2099
2100 if (lle->la_flags & LLE_IFADDR) {
2101
2102 /*
2103 * Delete LLE_IFADDR records IFF address & flag matches.
2104 * Note that addr is the interface address within prefix
2105 * being matched.
2106 */
2107 if (IN6_ARE_ADDR_EQUAL(addr, lle_addr) &&
2108 (flags & LLE_STATIC) != 0)
2109 return (1);
2110 return (0);
2111 }
2112
2113 /* flags & LLE_STATIC means deleting both dynamic and static entries */
2114 if ((flags & LLE_STATIC) || !(lle->la_flags & LLE_STATIC))
2093 return (1);
2094
2095 return (0);
2096}
2097
2098static void
2099in6_lltable_free_entry(struct lltable *llt, struct llentry *lle)
2100{

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

2195 continue;
2196 if (IN6_ARE_ADDR_EQUAL(&lle->r_l3addr.addr6, dst))
2197 break;
2198 }
2199
2200 return (lle);
2201}
2202
2115 return (1);
2116
2117 return (0);
2118}
2119
2120static void
2121in6_lltable_free_entry(struct lltable *llt, struct llentry *lle)
2122{

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

2217 continue;
2218 if (IN6_ARE_ADDR_EQUAL(&lle->r_l3addr.addr6, dst))
2219 break;
2220 }
2221
2222 return (lle);
2223}
2224
2203static int
2204in6_lltable_delete(struct lltable *llt, u_int flags,
2205 const struct sockaddr *l3addr)
2225static void
2226in6_lltable_delete_entry(struct lltable *llt, struct llentry *lle)
2206{
2227{
2207 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
2208 struct llentry *lle;
2209
2228
2210 IF_AFDATA_LOCK_ASSERT(llt->llt_ifp);
2211 KASSERT(l3addr->sa_family == AF_INET6,
2212 ("sin_family %d", l3addr->sa_family));
2213
2214 lle = in6_lltable_find_dst(llt, &sin6->sin6_addr);
2215
2216 if (lle == NULL)
2217 return (ENOENT);
2218
2219 if (!(lle->la_flags & LLE_IFADDR) || (flags & LLE_IFADDR)) {
2220 LLE_WLOCK(lle);
2221 lle->la_flags |= LLE_DELETED;
2222 EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
2229 lle->la_flags |= LLE_DELETED;
2230 EVENTHANDLER_INVOKE(lle_event, lle, LLENTRY_DELETED);
2223#ifdef DIAGNOSTIC
2231#ifdef DIAGNOSTIC
2224 log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
2232 log(LOG_INFO, "ifaddr cache = %p is deleted\n", lle);
2225#endif
2233#endif
2226 if ((lle->la_flags & (LLE_STATIC | LLE_IFADDR)) == LLE_STATIC)
2227 llentry_free(lle);
2228 else
2229 LLE_WUNLOCK(lle);
2230 }
2231
2232 return (0);
2234 llentry_free(lle);
2233}
2234
2235static struct llentry *
2236in6_lltable_alloc(struct lltable *llt, u_int flags,
2237 const struct sockaddr *l3addr)
2238{
2239 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
2240 struct ifnet *ifp = llt->llt_ifp;

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

2364 struct lltable *llt;
2365
2366 llt = lltable_allocate_htbl(IN6_LLTBL_DEFAULT_HSIZE);
2367 llt->llt_af = AF_INET6;
2368 llt->llt_ifp = ifp;
2369
2370 llt->llt_lookup = in6_lltable_lookup;
2371 llt->llt_alloc_entry = in6_lltable_alloc;
2235}
2236
2237static struct llentry *
2238in6_lltable_alloc(struct lltable *llt, u_int flags,
2239 const struct sockaddr *l3addr)
2240{
2241 const struct sockaddr_in6 *sin6 = (const struct sockaddr_in6 *)l3addr;
2242 struct ifnet *ifp = llt->llt_ifp;

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

2366 struct lltable *llt;
2367
2368 llt = lltable_allocate_htbl(IN6_LLTBL_DEFAULT_HSIZE);
2369 llt->llt_af = AF_INET6;
2370 llt->llt_ifp = ifp;
2371
2372 llt->llt_lookup = in6_lltable_lookup;
2373 llt->llt_alloc_entry = in6_lltable_alloc;
2372 llt->llt_delete = in6_lltable_delete;
2374 llt->llt_delete_entry = in6_lltable_delete_entry;
2373 llt->llt_dump_entry = in6_lltable_dump_entry;
2374 llt->llt_hash = in6_lltable_hash;
2375 llt->llt_fill_sa_entry = in6_lltable_fill_sa_entry;
2376 llt->llt_free_entry = in6_lltable_free_entry;
2377 llt->llt_match_prefix = in6_lltable_match_prefix;
2378 lltable_link(llt);
2379
2380 return (llt);

--- 120 unchanged lines hidden ---
2375 llt->llt_dump_entry = in6_lltable_dump_entry;
2376 llt->llt_hash = in6_lltable_hash;
2377 llt->llt_fill_sa_entry = in6_lltable_fill_sa_entry;
2378 llt->llt_free_entry = in6_lltable_free_entry;
2379 llt->llt_match_prefix = in6_lltable_match_prefix;
2380 lltable_link(llt);
2381
2382 return (llt);

--- 120 unchanged lines hidden ---