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 --- |