Sat Jun 9 14:44:33 2018 UTC ()
Pull up following revision(s) (requested by nonaka in ticket #862):

	sys/net/if_llatbl.c: revision 1.27

It is necessary to set wall time instead of monotonic time to rmx_expire.


(martin)
diff -r1.18.6.3 -r1.18.6.4 src/sys/net/if_llatbl.c

cvs diff -r1.18.6.3 -r1.18.6.4 src/sys/net/if_llatbl.c (switch to unified diff)

--- src/sys/net/if_llatbl.c 2018/03/13 13:27:10 1.18.6.3
+++ src/sys/net/if_llatbl.c 2018/06/09 14:44:33 1.18.6.4
@@ -1,912 +1,912 @@ @@ -1,912 +1,912 @@
1/* $NetBSD: if_llatbl.c,v 1.18.6.3 2018/03/13 13:27:10 martin Exp $ */ 1/* $NetBSD: if_llatbl.c,v 1.18.6.4 2018/06/09 14:44:33 martin Exp $ */
2/* 2/*
3 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved. 3 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
4 * Copyright (c) 2004-2008 Qing Li. All rights reserved. 4 * Copyright (c) 2004-2008 Qing Li. All rights reserved.
5 * Copyright (c) 2008 Kip Macy. All rights reserved. 5 * Copyright (c) 2008 Kip Macy. All rights reserved.
6 * Copyright (c) 2015 The NetBSD Foundation, Inc. 6 * Copyright (c) 2015 The NetBSD Foundation, Inc.
7 * All rights reserved. 7 * All rights reserved.
8 * 8 *
9 * Redistribution and use in source and binary forms, with or without 9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions 10 * modification, are permitted provided that the following conditions
11 * are met: 11 * are met:
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright 14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the 15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution. 16 * documentation and/or other materials provided with the distribution.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE 21 * ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE. 28 * SUCH DAMAGE.
29 */ 29 */
30#include <sys/cdefs.h> 30#include <sys/cdefs.h>
31 31
32#ifdef _KERNEL_OPT 32#ifdef _KERNEL_OPT
33#include "opt_ddb.h" 33#include "opt_ddb.h"
34#include "opt_inet.h" 34#include "opt_inet.h"
35#include "opt_inet6.h" 35#include "opt_inet6.h"
36#include "opt_net_mpsafe.h" 36#include "opt_net_mpsafe.h"
37#endif 37#endif
38 38
39#include "arp.h" 39#include "arp.h"
40 40
41#include <sys/param.h> 41#include <sys/param.h>
42#include <sys/systm.h> 42#include <sys/systm.h>
43#include <sys/malloc.h> 43#include <sys/malloc.h>
44#include <sys/mbuf.h> 44#include <sys/mbuf.h>
45#include <sys/syslog.h> 45#include <sys/syslog.h>
46#include <sys/sysctl.h> 46#include <sys/sysctl.h>
47#include <sys/socket.h> 47#include <sys/socket.h>
48#include <sys/socketvar.h> 48#include <sys/socketvar.h>
49#include <sys/kernel.h> 49#include <sys/kernel.h>
50#include <sys/lock.h> 50#include <sys/lock.h>
51#include <sys/mutex.h> 51#include <sys/mutex.h>
52#include <sys/rwlock.h> 52#include <sys/rwlock.h>
53 53
54#ifdef DDB 54#ifdef DDB
55#include <ddb/ddb.h> 55#include <ddb/ddb.h>
56#endif 56#endif
57 57
58#include <netinet/in.h> 58#include <netinet/in.h>
59#include <net/if_llatbl.h> 59#include <net/if_llatbl.h>
60#include <net/if.h> 60#include <net/if.h>
61#include <net/if_dl.h> 61#include <net/if_dl.h>
62#include <net/route.h> 62#include <net/route.h>
63#include <netinet/if_inarp.h> 63#include <netinet/if_inarp.h>
64#include <netinet/in_var.h> 64#include <netinet/in_var.h>
65#include <netinet6/in6_var.h> 65#include <netinet6/in6_var.h>
66#include <netinet6/nd6.h> 66#include <netinet6/nd6.h>
67 67
68static SLIST_HEAD(, lltable) lltables; 68static SLIST_HEAD(, lltable) lltables;
69krwlock_t lltable_rwlock; 69krwlock_t lltable_rwlock;
70static struct pool llentry_pool; 70static struct pool llentry_pool;
71 71
72static void lltable_unlink(struct lltable *llt); 72static void lltable_unlink(struct lltable *llt);
73static void llentries_unlink(struct lltable *llt, struct llentries *head); 73static void llentries_unlink(struct lltable *llt, struct llentries *head);
74 74
75static void htable_unlink_entry(struct llentry *lle); 75static void htable_unlink_entry(struct llentry *lle);
76static void htable_link_entry(struct lltable *llt, struct llentry *lle); 76static void htable_link_entry(struct lltable *llt, struct llentry *lle);
77static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, 77static int htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f,
78 void *farg); 78 void *farg);
79 79
80int 80int
81lltable_dump_entry(struct lltable *llt, struct llentry *lle, 81lltable_dump_entry(struct lltable *llt, struct llentry *lle,
82 struct rt_walkarg *w, struct sockaddr *sa) 82 struct rt_walkarg *w, struct sockaddr *sa)
83{ 83{
84#define RTF_LLINFO 0x400 84#define RTF_LLINFO 0x400
85#define RTF_CLONED 0x2000 85#define RTF_CLONED 0x2000
86 struct ifnet *ifp = llt->llt_ifp; 86 struct ifnet *ifp = llt->llt_ifp;
87 int error; 87 int error;
88 void *a; 88 void *a;
89 struct sockaddr_dl sdl; 89 struct sockaddr_dl sdl;
90 int size; 90 int size;
91 struct rt_addrinfo info; 91 struct rt_addrinfo info;
92 92
93 memset(&info, 0, sizeof(info)); 93 memset(&info, 0, sizeof(info));
94 info.rti_info[RTAX_DST] = sa; 94 info.rti_info[RTAX_DST] = sa;
95 95
96 a = (lle->la_flags & LLE_VALID) == LLE_VALID ? &lle->ll_addr : NULL; 96 a = (lle->la_flags & LLE_VALID) == LLE_VALID ? &lle->ll_addr : NULL;
97 if (sockaddr_dl_init(&sdl, sizeof(sdl), ifp->if_index, ifp->if_type, 97 if (sockaddr_dl_init(&sdl, sizeof(sdl), ifp->if_index, ifp->if_type,
98 NULL, 0, a, ifp->if_addrlen) == NULL) 98 NULL, 0, a, ifp->if_addrlen) == NULL)
99 return EINVAL; 99 return EINVAL;
100 100
101 info.rti_info[RTAX_GATEWAY] = sstocsa(&sdl); 101 info.rti_info[RTAX_GATEWAY] = sstocsa(&sdl);
102 if (sa->sa_family == AF_INET && lle->la_flags & LLE_PUB) { 102 if (sa->sa_family == AF_INET && lle->la_flags & LLE_PUB) {
103 struct sockaddr_inarp *sin; 103 struct sockaddr_inarp *sin;
104 sin = (struct sockaddr_inarp *)sa; 104 sin = (struct sockaddr_inarp *)sa;
105 sin->sin_other = SIN_PROXY; 105 sin->sin_other = SIN_PROXY;
106 } 106 }
107 if ((error = rt_msg3(RTM_GET, &info, 0, w, &size))) 107 if ((error = rt_msg3(RTM_GET, &info, 0, w, &size)))
108 return error; 108 return error;
109 if (w->w_where && w->w_tmem && w->w_needed <= 0) { 109 if (w->w_where && w->w_tmem && w->w_needed <= 0) {
110 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem; 110 struct rt_msghdr *rtm = (struct rt_msghdr *)w->w_tmem;
111 111
112 /* Need to copy by myself */ 112 /* Need to copy by myself */
113 rtm->rtm_index = ifp->if_index; 113 rtm->rtm_index = ifp->if_index;
114 rtm->rtm_rmx.rmx_mtu = 0; 114 rtm->rtm_rmx.rmx_mtu = 0;
115 rtm->rtm_rmx.rmx_expire = 115 rtm->rtm_rmx.rmx_expire = (lle->la_flags & LLE_STATIC) ? 0 :
116 (lle->la_flags & LLE_STATIC) ? 0 : lle->la_expire; 116 time_mono_to_wall(lle->la_expire);
117 rtm->rtm_flags = RTF_UP; 117 rtm->rtm_flags = RTF_UP;
118 rtm->rtm_flags |= RTF_HOST; /* For ndp */ 118 rtm->rtm_flags |= RTF_HOST; /* For ndp */
119 /* For backward compatibility */ 119 /* For backward compatibility */
120 rtm->rtm_flags |= RTF_LLINFO | RTF_CLONED; 120 rtm->rtm_flags |= RTF_LLINFO | RTF_CLONED;
121 rtm->rtm_flags |= (lle->la_flags & LLE_STATIC) ? RTF_STATIC : 0; 121 rtm->rtm_flags |= (lle->la_flags & LLE_STATIC) ? RTF_STATIC : 0;
122 if (lle->la_flags & LLE_PUB) 122 if (lle->la_flags & LLE_PUB)
123 rtm->rtm_flags |= RTF_ANNOUNCE; 123 rtm->rtm_flags |= RTF_ANNOUNCE;
124 rtm->rtm_addrs = info.rti_addrs; 124 rtm->rtm_addrs = info.rti_addrs;
125 if ((error = copyout(rtm, w->w_where, size)) != 0) 125 if ((error = copyout(rtm, w->w_where, size)) != 0)
126 w->w_where = NULL; 126 w->w_where = NULL;
127 else 127 else
128 w->w_where = (char *)w->w_where + size; 128 w->w_where = (char *)w->w_where + size;
129 } 129 }
130 130
131 return error; 131 return error;
132#undef RTF_LLINFO 132#undef RTF_LLINFO
133#undef RTF_CLONED 133#undef RTF_CLONED
134} 134}
135 135
136/* 136/*
137 * Dump lle state for a specific address family. 137 * Dump lle state for a specific address family.
138 */ 138 */
139static int 139static int
140lltable_dump_af(struct lltable *llt, struct rt_walkarg *w) 140lltable_dump_af(struct lltable *llt, struct rt_walkarg *w)
141{ 141{
142 int error; 142 int error;
143 143
144 LLTABLE_LOCK_ASSERT(); 144 LLTABLE_LOCK_ASSERT();
145 145
146 if (llt->llt_ifp->if_flags & IFF_LOOPBACK) 146 if (llt->llt_ifp->if_flags & IFF_LOOPBACK)
147 return (0); 147 return (0);
148 error = 0; 148 error = 0;
149 149
150 IF_AFDATA_RLOCK(llt->llt_ifp); 150 IF_AFDATA_RLOCK(llt->llt_ifp);
151 error = lltable_foreach_lle(llt, 151 error = lltable_foreach_lle(llt,
152 (llt_foreach_cb_t *)llt->llt_dump_entry, w); 152 (llt_foreach_cb_t *)llt->llt_dump_entry, w);
153 IF_AFDATA_RUNLOCK(llt->llt_ifp); 153 IF_AFDATA_RUNLOCK(llt->llt_ifp);
154 154
155 return (error); 155 return (error);
156} 156}
157 157
158/* 158/*
159 * Dump arp state for a specific address family. 159 * Dump arp state for a specific address family.
160 */ 160 */
161int 161int
162lltable_sysctl_dump(int af, struct rt_walkarg *w) 162lltable_sysctl_dump(int af, struct rt_walkarg *w)
163{ 163{
164 struct lltable *llt; 164 struct lltable *llt;
165 int error = 0; 165 int error = 0;
166 166
167 LLTABLE_RLOCK(); 167 LLTABLE_RLOCK();
168 SLIST_FOREACH(llt, &lltables, llt_link) { 168 SLIST_FOREACH(llt, &lltables, llt_link) {
169 if (llt->llt_af == af) { 169 if (llt->llt_af == af) {
170 error = lltable_dump_af(llt, w); 170 error = lltable_dump_af(llt, w);
171 if (error != 0) 171 if (error != 0)
172 goto done; 172 goto done;
173 } 173 }
174 } 174 }
175done: 175done:
176 LLTABLE_RUNLOCK(); 176 LLTABLE_RUNLOCK();
177 return (error); 177 return (error);
178} 178}
179 179
180/* 180/*
181 * Common function helpers for chained hash table. 181 * Common function helpers for chained hash table.
182 */ 182 */
183 183
184/* 184/*
185 * Runs specified callback for each entry in @llt. 185 * Runs specified callback for each entry in @llt.
186 * Caller does the locking. 186 * Caller does the locking.
187 * 187 *
188 */ 188 */
189static int 189static int
190htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg) 190htable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
191{ 191{
192 struct llentry *lle, *next; 192 struct llentry *lle, *next;
193 int i, error; 193 int i, error;
194 194
195 error = 0; 195 error = 0;
196 196
197 for (i = 0; i < llt->llt_hsize; i++) { 197 for (i = 0; i < llt->llt_hsize; i++) {
198 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) { 198 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
199 error = f(llt, lle, farg); 199 error = f(llt, lle, farg);
200 if (error != 0) 200 if (error != 0)
201 break; 201 break;
202 } 202 }
203 } 203 }
204 204
205 return (error); 205 return (error);
206} 206}
207 207
208static void 208static void
209htable_link_entry(struct lltable *llt, struct llentry *lle) 209htable_link_entry(struct lltable *llt, struct llentry *lle)
210{ 210{
211 struct llentries *lleh; 211 struct llentries *lleh;
212 uint32_t hashidx; 212 uint32_t hashidx;
213 213
214 if ((lle->la_flags & LLE_LINKED) != 0) 214 if ((lle->la_flags & LLE_LINKED) != 0)
215 return; 215 return;
216 216
217 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); 217 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
218 218
219 hashidx = llt->llt_hash(lle, llt->llt_hsize); 219 hashidx = llt->llt_hash(lle, llt->llt_hsize);
220 lleh = &llt->lle_head[hashidx]; 220 lleh = &llt->lle_head[hashidx];
221 221
222 lle->lle_tbl = llt; 222 lle->lle_tbl = llt;
223 lle->lle_head = lleh; 223 lle->lle_head = lleh;
224 lle->la_flags |= LLE_LINKED; 224 lle->la_flags |= LLE_LINKED;
225 LIST_INSERT_HEAD(lleh, lle, lle_next); 225 LIST_INSERT_HEAD(lleh, lle, lle_next);
226 226
227 llt->llt_lle_count++; 227 llt->llt_lle_count++;
228} 228}
229 229
230static void 230static void
231htable_unlink_entry(struct llentry *lle) 231htable_unlink_entry(struct llentry *lle)
232{ 232{
233 233
234 if ((lle->la_flags & LLE_LINKED) != 0) { 234 if ((lle->la_flags & LLE_LINKED) != 0) {
235 IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp); 235 IF_AFDATA_WLOCK_ASSERT(lle->lle_tbl->llt_ifp);
236 LIST_REMOVE(lle, lle_next); 236 LIST_REMOVE(lle, lle_next);
237 lle->la_flags &= ~(LLE_VALID | LLE_LINKED); 237 lle->la_flags &= ~(LLE_VALID | LLE_LINKED);
238#if 0 238#if 0
239 lle->lle_tbl = NULL; 239 lle->lle_tbl = NULL;
240 lle->lle_head = NULL; 240 lle->lle_head = NULL;
241#endif 241#endif
242 KASSERT(lle->lle_tbl->llt_lle_count != 0); 242 KASSERT(lle->lle_tbl->llt_lle_count != 0);
243 lle->lle_tbl->llt_lle_count--; 243 lle->lle_tbl->llt_lle_count--;
244 } 244 }
245} 245}
246 246
247struct prefix_match_data { 247struct prefix_match_data {
248 const struct sockaddr *prefix; 248 const struct sockaddr *prefix;
249 const struct sockaddr *mask; 249 const struct sockaddr *mask;
250 struct llentries dchain; 250 struct llentries dchain;
251 u_int flags; 251 u_int flags;
252}; 252};
253 253
254static int 254static int
255htable_prefix_free_cb(struct lltable *llt, struct llentry *lle, void *farg) 255htable_prefix_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
256{ 256{
257 struct prefix_match_data *pmd; 257 struct prefix_match_data *pmd;
258 258
259 pmd = (struct prefix_match_data *)farg; 259 pmd = (struct prefix_match_data *)farg;
260 260
261 if (llt->llt_match_prefix(pmd->prefix, pmd->mask, pmd->flags, lle)) { 261 if (llt->llt_match_prefix(pmd->prefix, pmd->mask, pmd->flags, lle)) {
262 LLE_WLOCK(lle); 262 LLE_WLOCK(lle);
263 LIST_INSERT_HEAD(&pmd->dchain, lle, lle_chain); 263 LIST_INSERT_HEAD(&pmd->dchain, lle, lle_chain);
264 } 264 }
265 265
266 return (0); 266 return (0);
267} 267}
268 268
269static void 269static void
270htable_prefix_free(struct lltable *llt, const struct sockaddr *prefix, 270htable_prefix_free(struct lltable *llt, const struct sockaddr *prefix,
271 const struct sockaddr *mask, u_int flags) 271 const struct sockaddr *mask, u_int flags)
272{ 272{
273 struct llentry *lle, *next; 273 struct llentry *lle, *next;
274 struct prefix_match_data pmd; 274 struct prefix_match_data pmd;
275 275
276 memset(&pmd, 0, sizeof(pmd)); 276 memset(&pmd, 0, sizeof(pmd));
277 pmd.prefix = prefix; 277 pmd.prefix = prefix;
278 pmd.mask = mask; 278 pmd.mask = mask;
279 pmd.flags = flags; 279 pmd.flags = flags;
280 LIST_INIT(&pmd.dchain); 280 LIST_INIT(&pmd.dchain);
281 281
282 IF_AFDATA_WLOCK(llt->llt_ifp); 282 IF_AFDATA_WLOCK(llt->llt_ifp);
283 /* Push matching lles to chain */ 283 /* Push matching lles to chain */
284 lltable_foreach_lle(llt, htable_prefix_free_cb, &pmd); 284 lltable_foreach_lle(llt, htable_prefix_free_cb, &pmd);
285 285
286 llentries_unlink(llt, &pmd.dchain); 286 llentries_unlink(llt, &pmd.dchain);
287 IF_AFDATA_WUNLOCK(llt->llt_ifp); 287 IF_AFDATA_WUNLOCK(llt->llt_ifp);
288 288
289 LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next) 289 LIST_FOREACH_SAFE(lle, &pmd.dchain, lle_chain, next)
290 llt->llt_free_entry(llt, lle); 290 llt->llt_free_entry(llt, lle);
291} 291}
292 292
293static void 293static void
294htable_free_tbl(struct lltable *llt) 294htable_free_tbl(struct lltable *llt)
295{ 295{
296 296
297 free(llt->lle_head, M_LLTABLE); 297 free(llt->lle_head, M_LLTABLE);
298 free(llt, M_LLTABLE); 298 free(llt, M_LLTABLE);
299} 299}
300 300
301static void 301static void
302llentries_unlink(struct lltable *llt, struct llentries *head) 302llentries_unlink(struct lltable *llt, struct llentries *head)
303{ 303{
304 struct llentry *lle, *next; 304 struct llentry *lle, *next;
305 305
306 LIST_FOREACH_SAFE(lle, head, lle_chain, next) 306 LIST_FOREACH_SAFE(lle, head, lle_chain, next)
307 llt->llt_unlink_entry(lle); 307 llt->llt_unlink_entry(lle);
308} 308}
309 309
310/* 310/*
311 * Helper function used to drop all mbufs in hold queue. 311 * Helper function used to drop all mbufs in hold queue.
312 * 312 *
313 * Returns the number of held packets, if any, that were dropped. 313 * Returns the number of held packets, if any, that were dropped.
314 */ 314 */
315size_t 315size_t
316lltable_drop_entry_queue(struct llentry *lle) 316lltable_drop_entry_queue(struct llentry *lle)
317{ 317{
318 size_t pkts_dropped; 318 size_t pkts_dropped;
319 struct mbuf *next; 319 struct mbuf *next;
320 320
321 LLE_WLOCK_ASSERT(lle); 321 LLE_WLOCK_ASSERT(lle);
322 322
323 pkts_dropped = 0; 323 pkts_dropped = 0;
324 while ((lle->la_numheld > 0) && (lle->la_hold != NULL)) { 324 while ((lle->la_numheld > 0) && (lle->la_hold != NULL)) {
325 next = lle->la_hold->m_nextpkt; 325 next = lle->la_hold->m_nextpkt;
326 m_freem(lle->la_hold); 326 m_freem(lle->la_hold);
327 lle->la_hold = next; 327 lle->la_hold = next;
328 lle->la_numheld--; 328 lle->la_numheld--;
329 pkts_dropped++; 329 pkts_dropped++;
330 } 330 }
331 331
332 KASSERTMSG(lle->la_numheld == 0, 332 KASSERTMSG(lle->la_numheld == 0,
333 "la_numheld %d > 0, pkts_droped %zd", 333 "la_numheld %d > 0, pkts_droped %zd",
334 lle->la_numheld, pkts_dropped); 334 lle->la_numheld, pkts_dropped);
335 335
336 return (pkts_dropped); 336 return (pkts_dropped);
337} 337}
338 338
339struct llentry * 339struct llentry *
340llentry_pool_get(int flags) 340llentry_pool_get(int flags)
341{ 341{
342 struct llentry *lle; 342 struct llentry *lle;
343 343
344 lle = pool_get(&llentry_pool, flags); 344 lle = pool_get(&llentry_pool, flags);
345 if (lle != NULL) 345 if (lle != NULL)
346 memset(lle, 0, sizeof(*lle)); 346 memset(lle, 0, sizeof(*lle));
347 return lle; 347 return lle;
348} 348}
349 349
350void 350void
351llentry_pool_put(struct llentry *lle) 351llentry_pool_put(struct llentry *lle)
352{ 352{
353 353
354 pool_put(&llentry_pool, lle); 354 pool_put(&llentry_pool, lle);
355} 355}
356 356
357/* 357/*
358 * Deletes an address from the address table. 358 * Deletes an address from the address table.
359 * This function is called by the timer functions 359 * This function is called by the timer functions
360 * such as arptimer() and nd6_llinfo_timer(), and 360 * such as arptimer() and nd6_llinfo_timer(), and
361 * the caller does the locking. 361 * the caller does the locking.
362 * 362 *
363 * Returns the number of held packets, if any, that were dropped. 363 * Returns the number of held packets, if any, that were dropped.
364 */ 364 */
365size_t 365size_t
366llentry_free(struct llentry *lle) 366llentry_free(struct llentry *lle)
367{ 367{
368 struct lltable *llt; 368 struct lltable *llt;
369 size_t pkts_dropped; 369 size_t pkts_dropped;
370 370
371 LLE_WLOCK_ASSERT(lle); 371 LLE_WLOCK_ASSERT(lle);
372 372
373 lle->la_flags |= LLE_DELETED; 373 lle->la_flags |= LLE_DELETED;
374 374
375 if ((lle->la_flags & LLE_LINKED) != 0) { 375 if ((lle->la_flags & LLE_LINKED) != 0) {
376 llt = lle->lle_tbl; 376 llt = lle->lle_tbl;
377 377
378 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp); 378 IF_AFDATA_WLOCK_ASSERT(llt->llt_ifp);
379 llt->llt_unlink_entry(lle); 379 llt->llt_unlink_entry(lle);
380 } 380 }
381 381
382 /* 382 /*
383 * Stop a pending callout if one exists. If we cancel one, we have to 383 * Stop a pending callout if one exists. If we cancel one, we have to
384 * remove a reference to avoid a leak. callout_pending is required to 384 * remove a reference to avoid a leak. callout_pending is required to
385 * to exclude the case that the callout has never been scheduled. 385 * to exclude the case that the callout has never been scheduled.
386 */ 386 */
387 /* XXX once softnet_lock goes away, we should use callout_halt */ 387 /* XXX once softnet_lock goes away, we should use callout_halt */
388 if (callout_pending(&lle->la_timer)) { 388 if (callout_pending(&lle->la_timer)) {
389 bool expired = callout_stop(&lle->la_timer); 389 bool expired = callout_stop(&lle->la_timer);
390 if (!expired) 390 if (!expired)
391 LLE_REMREF(lle); 391 LLE_REMREF(lle);
392 } 392 }
393 393
394 pkts_dropped = lltable_drop_entry_queue(lle); 394 pkts_dropped = lltable_drop_entry_queue(lle);
395 395
396 LLE_FREE_LOCKED(lle); 396 LLE_FREE_LOCKED(lle);
397 397
398 return (pkts_dropped); 398 return (pkts_dropped);
399} 399}
400 400
401/* 401/*
402 * (al)locate an llentry for address dst (equivalent to rtalloc for new-arp). 402 * (al)locate an llentry for address dst (equivalent to rtalloc for new-arp).
403 * 403 *
404 * If found the llentry * is returned referenced and unlocked. 404 * If found the llentry * is returned referenced and unlocked.
405 */ 405 */
406struct llentry * 406struct llentry *
407llentry_alloc(struct ifnet *ifp, struct lltable *lt, 407llentry_alloc(struct ifnet *ifp, struct lltable *lt,
408 struct sockaddr_storage *dst) 408 struct sockaddr_storage *dst)
409{ 409{
410 struct llentry *la; 410 struct llentry *la;
411 411
412 IF_AFDATA_RLOCK(ifp); 412 IF_AFDATA_RLOCK(ifp);
413 la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst); 413 la = lla_lookup(lt, LLE_EXCLUSIVE, (struct sockaddr *)dst);
414 IF_AFDATA_RUNLOCK(ifp); 414 IF_AFDATA_RUNLOCK(ifp);
415 if ((la == NULL) && 415 if ((la == NULL) &&
416#ifdef __FreeBSD__ 416#ifdef __FreeBSD__
417 (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) { 417 (ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) == 0) {
418#else /* XXX */ 418#else /* XXX */
419 (ifp->if_flags & IFF_NOARP) == 0) { 419 (ifp->if_flags & IFF_NOARP) == 0) {
420#endif 420#endif
421 IF_AFDATA_WLOCK(ifp); 421 IF_AFDATA_WLOCK(ifp);
422 la = lla_create(lt, 0, (struct sockaddr *)dst, NULL /* XXX */); 422 la = lla_create(lt, 0, (struct sockaddr *)dst, NULL /* XXX */);
423 IF_AFDATA_WUNLOCK(ifp); 423 IF_AFDATA_WUNLOCK(ifp);
424 } 424 }
425 425
426 if (la != NULL) { 426 if (la != NULL) {
427 LLE_ADDREF(la); 427 LLE_ADDREF(la);
428 LLE_WUNLOCK(la); 428 LLE_WUNLOCK(la);
429 } 429 }
430 430
431 return (la); 431 return (la);
432} 432}
433 433
434/* 434/*
435 * Free all entries from given table and free itself. 435 * Free all entries from given table and free itself.
436 */ 436 */
437 437
438static int 438static int
439lltable_free_cb(struct lltable *llt, struct llentry *lle, void *farg) 439lltable_free_cb(struct lltable *llt, struct llentry *lle, void *farg)
440{ 440{
441 struct llentries *dchain; 441 struct llentries *dchain;
442 442
443 dchain = (struct llentries *)farg; 443 dchain = (struct llentries *)farg;
444 444
445 LLE_WLOCK(lle); 445 LLE_WLOCK(lle);
446 LIST_INSERT_HEAD(dchain, lle, lle_chain); 446 LIST_INSERT_HEAD(dchain, lle, lle_chain);
447 447
448 return (0); 448 return (0);
449} 449}
450 450
451/* 451/*
452 * Free all entries from given table. 452 * Free all entries from given table.
453 */ 453 */
454void 454void
455lltable_purge_entries(struct lltable *llt) 455lltable_purge_entries(struct lltable *llt)
456{ 456{
457 struct llentry *lle, *next; 457 struct llentry *lle, *next;
458 struct llentries dchain; 458 struct llentries dchain;
459 459
460 KASSERTMSG(llt != NULL, "llt is NULL"); 460 KASSERTMSG(llt != NULL, "llt is NULL");
461 461
462 LIST_INIT(&dchain); 462 LIST_INIT(&dchain);
463 IF_AFDATA_WLOCK(llt->llt_ifp); 463 IF_AFDATA_WLOCK(llt->llt_ifp);
464 /* Push all lles to @dchain */ 464 /* Push all lles to @dchain */
465 lltable_foreach_lle(llt, lltable_free_cb, &dchain); 465 lltable_foreach_lle(llt, lltable_free_cb, &dchain);
466 llentries_unlink(llt, &dchain); 466 llentries_unlink(llt, &dchain);
467 IF_AFDATA_WUNLOCK(llt->llt_ifp); 467 IF_AFDATA_WUNLOCK(llt->llt_ifp);
468 468
469 LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next) 469 LIST_FOREACH_SAFE(lle, &dchain, lle_chain, next)
470 (void)llentry_free(lle); 470 (void)llentry_free(lle);
471} 471}
472 472
473/* 473/*
474 * Free all entries from given table and free itself. 474 * Free all entries from given table and free itself.
475 */ 475 */
476void 476void
477lltable_free(struct lltable *llt) 477lltable_free(struct lltable *llt)
478{ 478{
479 479
480 KASSERTMSG(llt != NULL, "llt is NULL"); 480 KASSERTMSG(llt != NULL, "llt is NULL");
481 481
482 lltable_unlink(llt); 482 lltable_unlink(llt);
483 lltable_purge_entries(llt); 483 lltable_purge_entries(llt);
484 llt->llt_free_tbl(llt); 484 llt->llt_free_tbl(llt);
485} 485}
486 486
487void 487void
488lltable_drain(int af) 488lltable_drain(int af)
489{ 489{
490 struct lltable *llt; 490 struct lltable *llt;
491 struct llentry *lle; 491 struct llentry *lle;
492 register int i; 492 register int i;
493 493
494 LLTABLE_RLOCK(); 494 LLTABLE_RLOCK();
495 SLIST_FOREACH(llt, &lltables, llt_link) { 495 SLIST_FOREACH(llt, &lltables, llt_link) {
496 if (llt->llt_af != af) 496 if (llt->llt_af != af)
497 continue; 497 continue;
498 498
499 for (i=0; i < llt->llt_hsize; i++) { 499 for (i=0; i < llt->llt_hsize; i++) {
500 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) { 500 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
501 LLE_WLOCK(lle); 501 LLE_WLOCK(lle);
502 lltable_drop_entry_queue(lle); 502 lltable_drop_entry_queue(lle);
503 LLE_WUNLOCK(lle); 503 LLE_WUNLOCK(lle);
504 } 504 }
505 } 505 }
506 } 506 }
507 LLTABLE_RUNLOCK(); 507 LLTABLE_RUNLOCK();
508} 508}
509 509
510void 510void
511lltable_prefix_free(const int af, const struct sockaddr *prefix, 511lltable_prefix_free(const int af, const struct sockaddr *prefix,
512 const struct sockaddr *mask, const u_int flags) 512 const struct sockaddr *mask, const u_int flags)
513{ 513{
514 struct lltable *llt; 514 struct lltable *llt;
515 515
516 LLTABLE_RLOCK(); 516 LLTABLE_RLOCK();
517 SLIST_FOREACH(llt, &lltables, llt_link) { 517 SLIST_FOREACH(llt, &lltables, llt_link) {
518 if (llt->llt_af != af) 518 if (llt->llt_af != af)
519 continue; 519 continue;
520 520
521 llt->llt_prefix_free(llt, prefix, mask, flags); 521 llt->llt_prefix_free(llt, prefix, mask, flags);
522 } 522 }
523 LLTABLE_RUNLOCK(); 523 LLTABLE_RUNLOCK();
524} 524}
525 525
526struct lltable * 526struct lltable *
527lltable_allocate_htbl(uint32_t hsize) 527lltable_allocate_htbl(uint32_t hsize)
528{ 528{
529 struct lltable *llt; 529 struct lltable *llt;
530 int i; 530 int i;
531 531
532 llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO); 532 llt = malloc(sizeof(struct lltable), M_LLTABLE, M_WAITOK | M_ZERO);
533 llt->llt_hsize = hsize; 533 llt->llt_hsize = hsize;
534 llt->lle_head = malloc(sizeof(struct llentries) * hsize, 534 llt->lle_head = malloc(sizeof(struct llentries) * hsize,
535 M_LLTABLE, M_WAITOK | M_ZERO); 535 M_LLTABLE, M_WAITOK | M_ZERO);
536 536
537 for (i = 0; i < llt->llt_hsize; i++) 537 for (i = 0; i < llt->llt_hsize; i++)
538 LIST_INIT(&llt->lle_head[i]); 538 LIST_INIT(&llt->lle_head[i]);
539 539
540 /* Set some default callbacks */ 540 /* Set some default callbacks */
541 llt->llt_link_entry = htable_link_entry; 541 llt->llt_link_entry = htable_link_entry;
542 llt->llt_unlink_entry = htable_unlink_entry; 542 llt->llt_unlink_entry = htable_unlink_entry;
543 llt->llt_prefix_free = htable_prefix_free; 543 llt->llt_prefix_free = htable_prefix_free;
544 llt->llt_foreach_entry = htable_foreach_lle; 544 llt->llt_foreach_entry = htable_foreach_lle;
545 545
546 llt->llt_free_tbl = htable_free_tbl; 546 llt->llt_free_tbl = htable_free_tbl;
547 547
548 return (llt); 548 return (llt);
549} 549}
550 550
551/* 551/*
552 * Links lltable to global llt list. 552 * Links lltable to global llt list.
553 */ 553 */
554void 554void
555lltable_link(struct lltable *llt) 555lltable_link(struct lltable *llt)
556{ 556{
557 557
558 LLTABLE_WLOCK(); 558 LLTABLE_WLOCK();
559 SLIST_INSERT_HEAD(&lltables, llt, llt_link); 559 SLIST_INSERT_HEAD(&lltables, llt, llt_link);
560 LLTABLE_WUNLOCK(); 560 LLTABLE_WUNLOCK();
561} 561}
562 562
563static void 563static void
564lltable_unlink(struct lltable *llt) 564lltable_unlink(struct lltable *llt)
565{ 565{
566 566
567 LLTABLE_WLOCK(); 567 LLTABLE_WLOCK();
568 SLIST_REMOVE(&lltables, llt, lltable, llt_link); 568 SLIST_REMOVE(&lltables, llt, lltable, llt_link);
569 LLTABLE_WUNLOCK(); 569 LLTABLE_WUNLOCK();
570 570
571} 571}
572 572
573/* 573/*
574 * External methods used by lltable consumers 574 * External methods used by lltable consumers
575 */ 575 */
576 576
577int 577int
578lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg) 578lltable_foreach_lle(struct lltable *llt, llt_foreach_cb_t *f, void *farg)
579{ 579{
580 580
581 return (llt->llt_foreach_entry(llt, f, farg)); 581 return (llt->llt_foreach_entry(llt, f, farg));
582} 582}
583 583
584void 584void
585lltable_link_entry(struct lltable *llt, struct llentry *lle) 585lltable_link_entry(struct lltable *llt, struct llentry *lle)
586{ 586{
587 587
588 llt->llt_link_entry(llt, lle); 588 llt->llt_link_entry(llt, lle);
589} 589}
590 590
591void 591void
592lltable_unlink_entry(struct lltable *llt, struct llentry *lle) 592lltable_unlink_entry(struct lltable *llt, struct llentry *lle)
593{ 593{
594 594
595 llt->llt_unlink_entry(lle); 595 llt->llt_unlink_entry(lle);
596} 596}
597 597
598void 598void
599lltable_free_entry(struct lltable *llt, struct llentry *lle) 599lltable_free_entry(struct lltable *llt, struct llentry *lle)
600{ 600{
601 601
602 llt->llt_free_entry(llt, lle); 602 llt->llt_free_entry(llt, lle);
603} 603}
604 604
605void 605void
606lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa) 606lltable_fill_sa_entry(const struct llentry *lle, struct sockaddr *sa)
607{ 607{
608 struct lltable *llt; 608 struct lltable *llt;
609 609
610 llt = lle->lle_tbl; 610 llt = lle->lle_tbl;
611 llt->llt_fill_sa_entry(lle, sa); 611 llt->llt_fill_sa_entry(lle, sa);
612} 612}
613 613
614struct ifnet * 614struct ifnet *
615lltable_get_ifp(const struct lltable *llt) 615lltable_get_ifp(const struct lltable *llt)
616{ 616{
617 617
618 return (llt->llt_ifp); 618 return (llt->llt_ifp);
619} 619}
620 620
621int 621int
622lltable_get_af(const struct lltable *llt) 622lltable_get_af(const struct lltable *llt)
623{ 623{
624 624
625 return (llt->llt_af); 625 return (llt->llt_af);
626} 626}
627 627
628/* 628/*
629 * Called in route_output when rtm_flags contains RTF_LLDATA. 629 * Called in route_output when rtm_flags contains RTF_LLDATA.
630 */ 630 */
631int 631int
632lla_rt_output(const u_char rtm_type, const int rtm_flags, const time_t rtm_expire, 632lla_rt_output(const u_char rtm_type, const int rtm_flags, const time_t rtm_expire,
633 struct rt_addrinfo *info, int sdl_index) 633 struct rt_addrinfo *info, int sdl_index)
634{ 634{
635 const struct sockaddr_dl *dl = satocsdl(info->rti_info[RTAX_GATEWAY]); 635 const struct sockaddr_dl *dl = satocsdl(info->rti_info[RTAX_GATEWAY]);
636 const struct sockaddr *dst = info->rti_info[RTAX_DST]; 636 const struct sockaddr *dst = info->rti_info[RTAX_DST];
637 struct ifnet *ifp; 637 struct ifnet *ifp;
638 struct lltable *llt; 638 struct lltable *llt;
639 struct llentry *lle; 639 struct llentry *lle;
640 u_int laflags; 640 u_int laflags;
641 int error; 641 int error;
642 struct psref psref; 642 struct psref psref;
643 int bound; 643 int bound;
644 644
645 KASSERTMSG(dl != NULL && dl->sdl_family == AF_LINK, "invalid dl"); 645 KASSERTMSG(dl != NULL && dl->sdl_family == AF_LINK, "invalid dl");
646 646
647 bound = curlwp_bind(); 647 bound = curlwp_bind();
648 if (sdl_index != 0) 648 if (sdl_index != 0)
649 ifp = if_get_byindex(sdl_index, &psref); 649 ifp = if_get_byindex(sdl_index, &psref);
650 else 650 else
651 ifp = if_get_byindex(dl->sdl_index, &psref); 651 ifp = if_get_byindex(dl->sdl_index, &psref);
652 if (ifp == NULL) { 652 if (ifp == NULL) {
653 curlwp_bindx(bound); 653 curlwp_bindx(bound);
654 log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n", 654 log(LOG_INFO, "%s: invalid ifp (sdl_index %d)\n",
655 __func__, sdl_index != 0 ? sdl_index : dl->sdl_index); 655 __func__, sdl_index != 0 ? sdl_index : dl->sdl_index);
656 return EINVAL; 656 return EINVAL;
657 } 657 }
658 658
659 /* XXX linked list may be too expensive */ 659 /* XXX linked list may be too expensive */
660 LLTABLE_RLOCK(); 660 LLTABLE_RLOCK();
661 SLIST_FOREACH(llt, &lltables, llt_link) { 661 SLIST_FOREACH(llt, &lltables, llt_link) {
662 if (llt->llt_af == dst->sa_family && 662 if (llt->llt_af == dst->sa_family &&
663 llt->llt_ifp == ifp) 663 llt->llt_ifp == ifp)
664 break; 664 break;
665 } 665 }
666 LLTABLE_RUNLOCK(); 666 LLTABLE_RUNLOCK();
667 KASSERTMSG(llt != NULL, "Yep, ugly hacks are bad"); 667 KASSERTMSG(llt != NULL, "Yep, ugly hacks are bad");
668 668
669 error = 0; 669 error = 0;
670 670
671 switch (rtm_type) { 671 switch (rtm_type) {
672 case RTM_ADD: { 672 case RTM_ADD: {
673 struct rtentry *rt; 673 struct rtentry *rt;
674 674
675 /* Never call rtalloc1 with IF_AFDATA_WLOCK */ 675 /* Never call rtalloc1 with IF_AFDATA_WLOCK */
676 rt = rtalloc1(dst, 0); 676 rt = rtalloc1(dst, 0);
677 677
678 /* Add static LLE */ 678 /* Add static LLE */
679 IF_AFDATA_WLOCK(ifp); 679 IF_AFDATA_WLOCK(ifp);
680 lle = lla_lookup(llt, 0, dst); 680 lle = lla_lookup(llt, 0, dst);
681 681
682 /* Cannot overwrite an existing static entry */ 682 /* Cannot overwrite an existing static entry */
683 if (lle != NULL && 683 if (lle != NULL &&
684 (lle->la_flags & LLE_STATIC || lle->la_expire == 0)) { 684 (lle->la_flags & LLE_STATIC || lle->la_expire == 0)) {
685 LLE_RUNLOCK(lle); 685 LLE_RUNLOCK(lle);
686 IF_AFDATA_WUNLOCK(ifp); 686 IF_AFDATA_WUNLOCK(ifp);
687 if (rt != NULL) 687 if (rt != NULL)
688 rt_unref(rt); 688 rt_unref(rt);
689 error = EEXIST; 689 error = EEXIST;
690 goto out; 690 goto out;
691 } 691 }
692 if (lle != NULL) 692 if (lle != NULL)
693 LLE_RUNLOCK(lle); 693 LLE_RUNLOCK(lle);
694 694
695 lle = lla_create(llt, 0, dst, rt); 695 lle = lla_create(llt, 0, dst, rt);
696 if (lle == NULL) { 696 if (lle == NULL) {
697 IF_AFDATA_WUNLOCK(ifp); 697 IF_AFDATA_WUNLOCK(ifp);
698 if (rt != NULL) 698 if (rt != NULL)
699 rt_unref(rt); 699 rt_unref(rt);
700 error = ENOMEM; 700 error = ENOMEM;
701 goto out; 701 goto out;
702 } 702 }
703 703
704 KASSERT(ifp->if_addrlen <= sizeof(lle->ll_addr)); 704 KASSERT(ifp->if_addrlen <= sizeof(lle->ll_addr));
705 memcpy(&lle->ll_addr, CLLADDR(dl), ifp->if_addrlen); 705 memcpy(&lle->ll_addr, CLLADDR(dl), ifp->if_addrlen);
706 if ((rtm_flags & RTF_ANNOUNCE)) 706 if ((rtm_flags & RTF_ANNOUNCE))
707 lle->la_flags |= LLE_PUB; 707 lle->la_flags |= LLE_PUB;
708 lle->la_flags |= LLE_VALID; 708 lle->la_flags |= LLE_VALID;
709#ifdef INET6 709#ifdef INET6
710 /* 710 /*
711 * ND6 711 * ND6
712 */ 712 */
713 if (dst->sa_family == AF_INET6) 713 if (dst->sa_family == AF_INET6)
714 lle->ln_state = ND6_LLINFO_REACHABLE; 714 lle->ln_state = ND6_LLINFO_REACHABLE;
715#endif 715#endif
716 /* 716 /*
717 * NB: arp and ndp always set (RTF_STATIC | RTF_HOST) 717 * NB: arp and ndp always set (RTF_STATIC | RTF_HOST)
718 */ 718 */
719 719
720 if (rtm_expire == 0) { 720 if (rtm_expire == 0) {
721 lle->la_flags |= LLE_STATIC; 721 lle->la_flags |= LLE_STATIC;
722 lle->la_expire = 0; 722 lle->la_expire = 0;
723 } else 723 } else
724 lle->la_expire = rtm_expire; 724 lle->la_expire = rtm_expire;
725 laflags = lle->la_flags; 725 laflags = lle->la_flags;
726 LLE_WUNLOCK(lle); 726 LLE_WUNLOCK(lle);
727 IF_AFDATA_WUNLOCK(ifp); 727 IF_AFDATA_WUNLOCK(ifp);
728 if (rt != NULL) 728 if (rt != NULL)
729 rt_unref(rt); 729 rt_unref(rt);
730#if defined(INET) && NARP > 0 730#if defined(INET) && NARP > 0
731 /* gratuitous ARP */ 731 /* gratuitous ARP */
732 if ((laflags & LLE_PUB) && dst->sa_family == AF_INET) { 732 if ((laflags & LLE_PUB) && dst->sa_family == AF_INET) {
733 const struct sockaddr_in *sin; 733 const struct sockaddr_in *sin;
734 struct in_ifaddr *ia; 734 struct in_ifaddr *ia;
735 struct psref _psref; 735 struct psref _psref;
736 736
737 sin = satocsin(dst); 737 sin = satocsin(dst);
738 ia = in_get_ia_on_iface_psref(sin->sin_addr, 738 ia = in_get_ia_on_iface_psref(sin->sin_addr,
739 ifp, &_psref); 739 ifp, &_psref);
740 if (ia != NULL) { 740 if (ia != NULL) {
741 arpannounce(ifp, &ia->ia_ifa, CLLADDR(dl)); 741 arpannounce(ifp, &ia->ia_ifa, CLLADDR(dl));
742 ia4_release(ia, &_psref); 742 ia4_release(ia, &_psref);
743 } 743 }
744 } 744 }
745#else 745#else
746 (void)laflags; 746 (void)laflags;
747#endif 747#endif
748 break; 748 break;
749 } 749 }
750 750
751 case RTM_DELETE: 751 case RTM_DELETE:
752 IF_AFDATA_WLOCK(ifp); 752 IF_AFDATA_WLOCK(ifp);
753 error = lla_delete(llt, 0, dst); 753 error = lla_delete(llt, 0, dst);
754 IF_AFDATA_WUNLOCK(ifp); 754 IF_AFDATA_WUNLOCK(ifp);
755 error = (error == 0 ? 0 : ENOENT); 755 error = (error == 0 ? 0 : ENOENT);
756 break; 756 break;
757 757
758 default: 758 default:
759 error = EINVAL; 759 error = EINVAL;
760 } 760 }
761 761
762out: 762out:
763 if_put(ifp, &psref); 763 if_put(ifp, &psref);
764 curlwp_bindx(bound); 764 curlwp_bindx(bound);
765 return (error); 765 return (error);
766} 766}
767 767
768void 768void
769lltableinit(void) 769lltableinit(void)
770{ 770{
771 771
772 SLIST_INIT(&lltables); 772 SLIST_INIT(&lltables);
773 rw_init(&lltable_rwlock); 773 rw_init(&lltable_rwlock);
774 774
775 pool_init(&llentry_pool, sizeof(struct llentry), 0, 0, 0, "llentrypl", 775 pool_init(&llentry_pool, sizeof(struct llentry), 0, 0, 0, "llentrypl",
776 NULL, IPL_SOFTNET); 776 NULL, IPL_SOFTNET);
777} 777}
778 778
779#ifdef __FreeBSD__ 779#ifdef __FreeBSD__
780#ifdef DDB 780#ifdef DDB
781struct llentry_sa { 781struct llentry_sa {
782 struct llentry base; 782 struct llentry base;
783 struct sockaddr l3_addr; 783 struct sockaddr l3_addr;
784}; 784};
785 785
786static void 786static void
787llatbl_lle_show(struct llentry_sa *la) 787llatbl_lle_show(struct llentry_sa *la)
788{ 788{
789 struct llentry *lle; 789 struct llentry *lle;
790 uint8_t octet[6]; 790 uint8_t octet[6];
791 791
792 lle = &la->base; 792 lle = &la->base;
793 db_printf("lle=%p\n", lle); 793 db_printf("lle=%p\n", lle);
794 db_printf(" lle_next=%p\n", lle->lle_next.le_next); 794 db_printf(" lle_next=%p\n", lle->lle_next.le_next);
795 db_printf(" lle_lock=%p\n", &lle->lle_lock); 795 db_printf(" lle_lock=%p\n", &lle->lle_lock);
796 db_printf(" lle_tbl=%p\n", lle->lle_tbl); 796 db_printf(" lle_tbl=%p\n", lle->lle_tbl);
797 db_printf(" lle_head=%p\n", lle->lle_head); 797 db_printf(" lle_head=%p\n", lle->lle_head);
798 db_printf(" la_hold=%p\n", lle->la_hold); 798 db_printf(" la_hold=%p\n", lle->la_hold);
799 db_printf(" la_numheld=%d\n", lle->la_numheld); 799 db_printf(" la_numheld=%d\n", lle->la_numheld);
800 db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire); 800 db_printf(" la_expire=%ju\n", (uintmax_t)lle->la_expire);
801 db_printf(" la_flags=0x%04x\n", lle->la_flags); 801 db_printf(" la_flags=0x%04x\n", lle->la_flags);
802 db_printf(" la_asked=%u\n", lle->la_asked); 802 db_printf(" la_asked=%u\n", lle->la_asked);
803 db_printf(" la_preempt=%u\n", lle->la_preempt); 803 db_printf(" la_preempt=%u\n", lle->la_preempt);
804 db_printf(" ln_byhint=%u\n", lle->ln_byhint); 804 db_printf(" ln_byhint=%u\n", lle->ln_byhint);
805 db_printf(" ln_state=%d\n", lle->ln_state); 805 db_printf(" ln_state=%d\n", lle->ln_state);
806 db_printf(" ln_router=%u\n", lle->ln_router); 806 db_printf(" ln_router=%u\n", lle->ln_router);
807 db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick); 807 db_printf(" ln_ntick=%ju\n", (uintmax_t)lle->ln_ntick);
808 db_printf(" lle_refcnt=%d\n", lle->lle_refcnt); 808 db_printf(" lle_refcnt=%d\n", lle->lle_refcnt);
809 memcopy(octet, &lle->ll_addr.mac16, sizeof(octet)); 809 memcopy(octet, &lle->ll_addr.mac16, sizeof(octet));
810 db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n", 810 db_printf(" ll_addr=%02x:%02x:%02x:%02x:%02x:%02x\n",
811 octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]); 811 octet[0], octet[1], octet[2], octet[3], octet[4], octet[5]);
812 db_printf(" lle_timer=%p\n", &lle->lle_timer); 812 db_printf(" lle_timer=%p\n", &lle->lle_timer);
813 813
814 switch (la->l3_addr.sa_family) { 814 switch (la->l3_addr.sa_family) {
815#ifdef INET 815#ifdef INET
816 case AF_INET: 816 case AF_INET:
817 { 817 {
818 struct sockaddr_in *sin; 818 struct sockaddr_in *sin;
819 char l3s[INET_ADDRSTRLEN]; 819 char l3s[INET_ADDRSTRLEN];
820 820
821 sin = (struct sockaddr_in *)&la->l3_addr; 821 sin = (struct sockaddr_in *)&la->l3_addr;
822 inet_ntoa_r(sin->sin_addr, l3s); 822 inet_ntoa_r(sin->sin_addr, l3s);
823 db_printf(" l3_addr=%s\n", l3s); 823 db_printf(" l3_addr=%s\n", l3s);
824 break; 824 break;
825 } 825 }
826#endif 826#endif
827#ifdef INET6 827#ifdef INET6
828 case AF_INET6: 828 case AF_INET6:
829 { 829 {
830 struct sockaddr_in6 *sin6; 830 struct sockaddr_in6 *sin6;
831 char l3s[INET6_ADDRSTRLEN]; 831 char l3s[INET6_ADDRSTRLEN];
832 832
833 sin6 = (struct sockaddr_in6 *)&la->l3_addr; 833 sin6 = (struct sockaddr_in6 *)&la->l3_addr;
834 IN6_PRINT(l3s, &sin6->sin6_addr); 834 IN6_PRINT(l3s, &sin6->sin6_addr);
835 db_printf(" l3_addr=%s\n", l3s); 835 db_printf(" l3_addr=%s\n", l3s);
836 break; 836 break;
837 } 837 }
838#endif 838#endif
839 default: 839 default:
840 db_printf(" l3_addr=N/A (af=%d)\n", la->l3_addr.sa_family); 840 db_printf(" l3_addr=N/A (af=%d)\n", la->l3_addr.sa_family);
841 break; 841 break;
842 } 842 }
843} 843}
844 844
845DB_SHOW_COMMAND(llentry, db_show_llentry) 845DB_SHOW_COMMAND(llentry, db_show_llentry)
846{ 846{
847 847
848 if (!have_addr) { 848 if (!have_addr) {
849 db_printf("usage: show llentry <struct llentry *>\n"); 849 db_printf("usage: show llentry <struct llentry *>\n");
850 return; 850 return;
851 } 851 }
852 852
853 llatbl_lle_show((struct llentry_sa *)addr); 853 llatbl_lle_show((struct llentry_sa *)addr);
854} 854}
855 855
856static void 856static void
857llatbl_llt_show(struct lltable *llt) 857llatbl_llt_show(struct lltable *llt)
858{ 858{
859 int i; 859 int i;
860 struct llentry *lle; 860 struct llentry *lle;
861 861
862 db_printf("llt=%p llt_af=%d llt_ifp=%p\n", 862 db_printf("llt=%p llt_af=%d llt_ifp=%p\n",
863 llt, llt->llt_af, llt->llt_ifp); 863 llt, llt->llt_af, llt->llt_ifp);
864 864
865 for (i = 0; i < llt->llt_hsize; i++) { 865 for (i = 0; i < llt->llt_hsize; i++) {
866 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) { 866 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
867 867
868 llatbl_lle_show((struct llentry_sa *)lle); 868 llatbl_lle_show((struct llentry_sa *)lle);
869 if (db_pager_quit) 869 if (db_pager_quit)
870 return; 870 return;
871 } 871 }
872 } 872 }
873} 873}
874 874
875DB_SHOW_COMMAND(lltable, db_show_lltable) 875DB_SHOW_COMMAND(lltable, db_show_lltable)
876{ 876{
877 877
878 if (!have_addr) { 878 if (!have_addr) {
879 db_printf("usage: show lltable <struct lltable *>\n"); 879 db_printf("usage: show lltable <struct lltable *>\n");
880 return; 880 return;
881 } 881 }
882 882
883 llatbl_llt_show((struct lltable *)addr); 883 llatbl_llt_show((struct lltable *)addr);
884} 884}
885 885
886DB_SHOW_ALL_COMMAND(lltables, db_show_all_lltables) 886DB_SHOW_ALL_COMMAND(lltables, db_show_all_lltables)
887{ 887{
888 VNET_ITERATOR_DECL(vnet_iter); 888 VNET_ITERATOR_DECL(vnet_iter);
889 struct lltable *llt; 889 struct lltable *llt;
890 890
891 VNET_FOREACH(vnet_iter) { 891 VNET_FOREACH(vnet_iter) {
892 CURVNET_SET_QUIET(vnet_iter); 892 CURVNET_SET_QUIET(vnet_iter);
893#ifdef VIMAGE 893#ifdef VIMAGE
894 db_printf("vnet=%p\n", curvnet); 894 db_printf("vnet=%p\n", curvnet);
895#endif 895#endif
896 SLIST_FOREACH(llt, &lltables, llt_link) { 896 SLIST_FOREACH(llt, &lltables, llt_link) {
897 db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n", 897 db_printf("llt=%p llt_af=%d llt_ifp=%p(%s)\n",
898 llt, llt->llt_af, llt->llt_ifp, 898 llt, llt->llt_af, llt->llt_ifp,
899 (llt->llt_ifp != NULL) ? 899 (llt->llt_ifp != NULL) ?
900 llt->llt_ifp->if_xname : "?"); 900 llt->llt_ifp->if_xname : "?");
901 if (have_addr && addr != 0) /* verbose */ 901 if (have_addr && addr != 0) /* verbose */
902 llatbl_llt_show(llt); 902 llatbl_llt_show(llt);
903 if (db_pager_quit) { 903 if (db_pager_quit) {
904 CURVNET_RESTORE(); 904 CURVNET_RESTORE();
905 return; 905 return;
906 } 906 }
907 } 907 }
908 CURVNET_RESTORE(); 908 CURVNET_RESTORE();
909 } 909 }
910} 910}
911#endif /* DDB */ 911#endif /* DDB */
912#endif /* __FreeBSD__ */ 912#endif /* __FreeBSD__ */