Deleted Added
full compact
if_llatbl.c (196481) if_llatbl.c (196535)
1/*
2 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
3 * Copyright (c) 2004-2008 Qing Li. All rights reserved.
4 * Copyright (c) 2008 Kip Macy. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27#include <sys/cdefs.h>
1/*
2 * Copyright (c) 2004 Luigi Rizzo, Alessandro Cerri. All rights reserved.
3 * Copyright (c) 2004-2008 Qing Li. All rights reserved.
4 * Copyright (c) 2008 Kip Macy. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

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

20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27#include <sys/cdefs.h>
28__FBSDID("$FreeBSD: head/sys/net/if_llatbl.c 196481 2009-08-23 20:40:19Z rwatson $");
28__FBSDID("$FreeBSD: head/sys/net/if_llatbl.c 196535 2009-08-25 09:52:38Z rwatson $");
29
30#include "opt_inet.h"
31#include "opt_inet6.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/mbuf.h>

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

57
58MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
59
60static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
61
62extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
63 u_char *);
64
29
30#include "opt_inet.h"
31#include "opt_inet6.h"
32
33#include <sys/param.h>
34#include <sys/systm.h>
35#include <sys/malloc.h>
36#include <sys/mbuf.h>

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

57
58MALLOC_DEFINE(M_LLTABLE, "lltable", "link level address tables");
59
60static SLIST_HEAD(, lltable) lltables = SLIST_HEAD_INITIALIZER(lltables);
61
62extern void arprequest(struct ifnet *, struct in_addr *, struct in_addr *,
63 u_char *);
64
65struct rwlock lltable_rwlock;
66RW_SYSINIT(lltable_rwlock, &lltable_rwlock, "lltable_rwlock");
67
65/*
66 * Dump arp state for a specific address family.
67 */
68int
69lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
70{
71 struct lltable *llt;
72 int error = 0;
73
68/*
69 * Dump arp state for a specific address family.
70 */
71int
72lltable_sysctl_dumparp(int af, struct sysctl_req *wr)
73{
74 struct lltable *llt;
75 int error = 0;
76
74 IFNET_RLOCK();
77 LLTABLE_RLOCK();
75 SLIST_FOREACH(llt, &lltables, llt_link) {
76 if (llt->llt_af == af) {
77 error = llt->llt_dump(llt, wr);
78 if (error != 0)
79 goto done;
80 }
81 }
82done:
78 SLIST_FOREACH(llt, &lltables, llt_link) {
79 if (llt->llt_af == af) {
80 error = llt->llt_dump(llt, wr);
81 if (error != 0)
82 goto done;
83 }
84 }
85done:
83 IFNET_RUNLOCK();
86 LLTABLE_RUNLOCK();
84 return (error);
85}
86
87/*
88 * Deletes an address from the address table.
89 * This function is called by the timer functions
90 * such as arptimer() and nd6_llinfo_timer(), and
91 * the caller does the locking.

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

139 if (la == NULL)
140 return (ENOENT);
141
142 return (0);
143}
144
145/*
146 * Free all entries from given table and free itself.
87 return (error);
88}
89
90/*
91 * Deletes an address from the address table.
92 * This function is called by the timer functions
93 * such as arptimer() and nd6_llinfo_timer(), and
94 * the caller does the locking.

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

142 if (la == NULL)
143 return (ENOENT);
144
145 return (0);
146}
147
148/*
149 * Free all entries from given table and free itself.
147 * Since lltables collects from all of the intefaces,
148 * the caller of this function must acquire IFNET_WLOCK().
149 */
150void
151lltable_free(struct lltable *llt)
152{
153 struct llentry *lle, *next;
154 int i;
155
156 KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
157
150 */
151void
152lltable_free(struct lltable *llt)
153{
154 struct llentry *lle, *next;
155 int i;
156
157 KASSERT(llt != NULL, ("%s: llt is NULL", __func__));
158
158 IFNET_WLOCK();
159 LLTABLE_WLOCK();
159 SLIST_REMOVE(&lltables, llt, lltable, llt_link);
160 SLIST_REMOVE(&lltables, llt, lltable, llt_link);
160 IFNET_WUNLOCK();
161 LLTABLE_WUNLOCK();
161
162 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
163 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
164
165 callout_drain(&lle->la_timer);
166 LLE_WLOCK(lle);
167 llentry_free(lle);
168 }

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

173
174void
175lltable_drain(int af)
176{
177 struct lltable *llt;
178 struct llentry *lle;
179 register int i;
180
162
163 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
164 LIST_FOREACH_SAFE(lle, &llt->lle_head[i], lle_next, next) {
165
166 callout_drain(&lle->la_timer);
167 LLE_WLOCK(lle);
168 llentry_free(lle);
169 }

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

174
175void
176lltable_drain(int af)
177{
178 struct lltable *llt;
179 struct llentry *lle;
180 register int i;
181
181 IFNET_RLOCK();
182 LLTABLE_RLOCK();
182 SLIST_FOREACH(llt, &lltables, llt_link) {
183 if (llt->llt_af != af)
184 continue;
185
186 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
187 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
188 if (lle->la_hold) {
189 m_freem(lle->la_hold);
190 lle->la_hold = NULL;
191 }
192 }
193 }
194 }
183 SLIST_FOREACH(llt, &lltables, llt_link) {
184 if (llt->llt_af != af)
185 continue;
186
187 for (i=0; i < LLTBL_HASHTBL_SIZE; i++) {
188 LIST_FOREACH(lle, &llt->lle_head[i], lle_next) {
189 if (lle->la_hold) {
190 m_freem(lle->la_hold);
191 lle->la_hold = NULL;
192 }
193 }
194 }
195 }
195 IFNET_RUNLOCK();
196 LLTABLE_RUNLOCK();
196}
197
198void
199lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask)
200{
201 struct lltable *llt;
202
197}
198
199void
200lltable_prefix_free(int af, struct sockaddr *prefix, struct sockaddr *mask)
201{
202 struct lltable *llt;
203
203 IFNET_RLOCK_NOSLEEP();
204 LLTABLE_RLOCK();
204 SLIST_FOREACH(llt, &lltables, llt_link) {
205 if (llt->llt_af != af)
206 continue;
207
208 llt->llt_prefix_free(llt, prefix, mask);
209 }
205 SLIST_FOREACH(llt, &lltables, llt_link) {
206 if (llt->llt_af != af)
207 continue;
208
209 llt->llt_prefix_free(llt, prefix, mask);
210 }
210 IFNET_RUNLOCK_NOSLEEP();
211 LLTABLE_RUNLOCK();
211}
212
213
214
215/*
216 * Create a new lltable.
217 */
218struct lltable *

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

225 if (llt == NULL)
226 return (NULL);
227
228 llt->llt_af = af;
229 llt->llt_ifp = ifp;
230 for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
231 LIST_INIT(&llt->lle_head[i]);
232
212}
213
214
215
216/*
217 * Create a new lltable.
218 */
219struct lltable *

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

226 if (llt == NULL)
227 return (NULL);
228
229 llt->llt_af = af;
230 llt->llt_ifp = ifp;
231 for (i = 0; i < LLTBL_HASHTBL_SIZE; i++)
232 LIST_INIT(&llt->lle_head[i]);
233
233 IFNET_WLOCK();
234 LLTABLE_WLOCK();
234 SLIST_INSERT_HEAD(&lltables, llt, llt_link);
235 SLIST_INSERT_HEAD(&lltables, llt, llt_link);
235 IFNET_WUNLOCK();
236 LLTABLE_WUNLOCK();
236
237 return (llt);
238}
239
240/*
241 * Called in route_output when adding/deleting a route to an interface.
242 */
243int

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

295 case RTM_CHANGE:
296 break;
297
298 default:
299 return EINVAL; /* XXX not implemented yet */
300 }
301
302 /* XXX linked list may be too expensive */
237
238 return (llt);
239}
240
241/*
242 * Called in route_output when adding/deleting a route to an interface.
243 */
244int

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

296 case RTM_CHANGE:
297 break;
298
299 default:
300 return EINVAL; /* XXX not implemented yet */
301 }
302
303 /* XXX linked list may be too expensive */
303 IFNET_RLOCK_NOSLEEP();
304 LLTABLE_RLOCK();
304 SLIST_FOREACH(llt, &lltables, llt_link) {
305 if (llt->llt_af == dst->sa_family &&
306 llt->llt_ifp == ifp)
307 break;
308 }
305 SLIST_FOREACH(llt, &lltables, llt_link) {
306 if (llt->llt_af == dst->sa_family &&
307 llt->llt_ifp == ifp)
308 break;
309 }
309 IFNET_RUNLOCK_NOSLEEP();
310 LLTABLE_RUNLOCK();
310 KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
311
312 if (flags && LLE_CREATE)
313 flags |= LLE_EXCLUSIVE;
314
315 IF_AFDATA_LOCK(ifp);
316 lle = lla_lookup(llt, flags, dst);
317 IF_AFDATA_UNLOCK(ifp);

--- 51 unchanged lines hidden ---
311 KASSERT(llt != NULL, ("Yep, ugly hacks are bad\n"));
312
313 if (flags && LLE_CREATE)
314 flags |= LLE_EXCLUSIVE;
315
316 IF_AFDATA_LOCK(ifp);
317 lle = lla_lookup(llt, flags, dst);
318 IF_AFDATA_UNLOCK(ifp);

--- 51 unchanged lines hidden ---