ng_ether.c (128376) | ng_ether.c (129281) |
---|---|
1 2/* 3 * ng_ether.c 4 * 5 * Copyright (c) 1996-2000 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and --- 23 unchanged lines hidden (view full) --- 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Authors: Archie Cobbs <archie@freebsd.org> 38 * Julian Elischer <julian@freebsd.org> 39 * | 1 2/* 3 * ng_ether.c 4 * 5 * Copyright (c) 1996-2000 Whistle Communications, Inc. 6 * All rights reserved. 7 * 8 * Subject to the following obligations and disclaimer of warranty, use and --- 23 unchanged lines hidden (view full) --- 32 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 33 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY 35 * OF SUCH DAMAGE. 36 * 37 * Authors: Archie Cobbs <archie@freebsd.org> 38 * Julian Elischer <julian@freebsd.org> 39 * |
40 * $FreeBSD: head/sys/netgraph/ng_ether.c 128376 2004-04-18 01:15:32Z luigi $ | 40 * $FreeBSD: head/sys/netgraph/ng_ether.c 129281 2004-05-16 19:31:35Z archie $ |
41 */ 42 43/* 44 * ng_ether(4) netgraph node type 45 */ 46 47#include <sys/param.h> 48#include <sys/systm.h> --- 16 unchanged lines hidden (view full) --- 65#include <netgraph/ng_ether.h> 66 67#define IFP2NG(ifp) ((struct ng_node *)((struct arpcom *)(ifp))->ac_netgraph) 68 69/* Per-node private data */ 70struct private { 71 struct ifnet *ifp; /* associated interface */ 72 hook_p upper; /* upper hook connection */ | 41 */ 42 43/* 44 * ng_ether(4) netgraph node type 45 */ 46 47#include <sys/param.h> 48#include <sys/systm.h> --- 16 unchanged lines hidden (view full) --- 65#include <netgraph/ng_ether.h> 66 67#define IFP2NG(ifp) ((struct ng_node *)((struct arpcom *)(ifp))->ac_netgraph) 68 69/* Per-node private data */ 70struct private { 71 struct ifnet *ifp; /* associated interface */ 72 hook_p upper; /* upper hook connection */ |
73 hook_p lower; /* lower OR orphan hook connection */ 74 u_char lowerOrphan; /* whether lower is lower or orphan */ | 73 hook_p lower; /* lower hook connection */ 74 hook_p orphan; /* orphan hook connection */ |
75 u_char autoSrcAddr; /* always overwrite source address */ 76 u_char promisc; /* promiscuous mode enabled */ 77 u_long hwassist; /* hardware checksum capabilities */ 78 u_int flags; /* flags e.g. really die */ 79}; 80typedef struct private *priv_p; 81 82/* Hook pointers used by if_ethersubr.c to callback to netgraph */ --- 6 unchanged lines hidden (view full) --- 89/* Functional hooks called from if_ethersubr.c */ 90static void ng_ether_input(struct ifnet *ifp, struct mbuf **mp); 91static void ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m); 92static int ng_ether_output(struct ifnet *ifp, struct mbuf **mp); 93static void ng_ether_attach(struct ifnet *ifp); 94static void ng_ether_detach(struct ifnet *ifp); 95 96/* Other functions */ | 75 u_char autoSrcAddr; /* always overwrite source address */ 76 u_char promisc; /* promiscuous mode enabled */ 77 u_long hwassist; /* hardware checksum capabilities */ 78 u_int flags; /* flags e.g. really die */ 79}; 80typedef struct private *priv_p; 81 82/* Hook pointers used by if_ethersubr.c to callback to netgraph */ --- 6 unchanged lines hidden (view full) --- 89/* Functional hooks called from if_ethersubr.c */ 90static void ng_ether_input(struct ifnet *ifp, struct mbuf **mp); 91static void ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m); 92static int ng_ether_output(struct ifnet *ifp, struct mbuf **mp); 93static void ng_ether_attach(struct ifnet *ifp); 94static void ng_ether_detach(struct ifnet *ifp); 95 96/* Other functions */ |
97static void ng_ether_input2(node_p node, struct mbuf **mp); | |
98static int ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta); 99static int ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta); 100 101/* Netgraph node methods */ 102static ng_constructor_t ng_ether_constructor; 103static ng_rcvmsg_t ng_ether_rcvmsg; 104static ng_shutdown_t ng_ether_shutdown; 105static ng_newhook_t ng_ether_newhook; --- 90 unchanged lines hidden (view full) --- 196 * 197 * NOTE: this function will get called at splimp() 198 */ 199static void 200ng_ether_input(struct ifnet *ifp, struct mbuf **mp) 201{ 202 const node_p node = IFP2NG(ifp); 203 const priv_p priv = NG_NODE_PRIVATE(node); | 97static int ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta); 98static int ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta); 99 100/* Netgraph node methods */ 101static ng_constructor_t ng_ether_constructor; 102static ng_rcvmsg_t ng_ether_rcvmsg; 103static ng_shutdown_t ng_ether_shutdown; 104static ng_newhook_t ng_ether_newhook; --- 90 unchanged lines hidden (view full) --- 195 * 196 * NOTE: this function will get called at splimp() 197 */ 198static void 199ng_ether_input(struct ifnet *ifp, struct mbuf **mp) 200{ 201 const node_p node = IFP2NG(ifp); 202 const priv_p priv = NG_NODE_PRIVATE(node); |
203 int error; |
|
204 205 /* If "lower" hook not connected, let packet continue */ | 204 205 /* If "lower" hook not connected, let packet continue */ |
206 if (priv->lower == NULL || priv->lowerOrphan) | 206 if (priv->lower == NULL) |
207 return; | 207 return; |
208 ng_ether_input2(node, mp); | 208 NG_SEND_DATA_ONLY(error, priv->lower, *mp); /* sets *mp = NULL */ |
209} 210 211/* 212 * Handle a packet that has come in on an interface, and which 213 * does not match any of our known protocols (an ``orphan''). 214 * 215 * NOTE: this function will get called at splimp() 216 */ 217static void 218ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m) 219{ 220 const node_p node = IFP2NG(ifp); 221 const priv_p priv = NG_NODE_PRIVATE(node); | 209} 210 211/* 212 * Handle a packet that has come in on an interface, and which 213 * does not match any of our known protocols (an ``orphan''). 214 * 215 * NOTE: this function will get called at splimp() 216 */ 217static void 218ng_ether_input_orphan(struct ifnet *ifp, struct mbuf *m) 219{ 220 const node_p node = IFP2NG(ifp); 221 const priv_p priv = NG_NODE_PRIVATE(node); |
222 int error; |
|
222 | 223 |
223 /* If "orphan" hook not connected, let packet continue */ 224 if (priv->lower == NULL || !priv->lowerOrphan) { | 224 /* If "orphan" hook not connected, discard packet */ 225 if (priv->orphan == NULL) { |
225 m_freem(m); 226 return; 227 } | 226 m_freem(m); 227 return; 228 } |
228 ng_ether_input2(node, &m); 229 if (m != NULL) 230 m_freem(m); | 229 NG_SEND_DATA_ONLY(error, priv->orphan, m); |
231} 232 233/* | 230} 231 232/* |
234 * Handle a packet that has come in on an ethernet interface. 235 * The Ethernet header has already been detached from the mbuf, 236 * so we have to put it back. 237 * 238 * NOTE: this function will get called at splimp() 239 */ 240static void 241ng_ether_input2(node_p node, struct mbuf **mp) 242{ 243 const priv_p priv = NG_NODE_PRIVATE(node); 244 int error; 245 246 /* Send out lower/orphan hook */ 247 NG_SEND_DATA_ONLY(error, priv->lower, *mp); 248 *mp = NULL; 249} 250 251/* | |
252 * Handle a packet that is going out on an interface. 253 * The Ethernet header is already attached to the mbuf. 254 */ 255static int 256ng_ether_output(struct ifnet *ifp, struct mbuf **mp) 257{ 258 const node_p node = IFP2NG(ifp); 259 const priv_p priv = NG_NODE_PRIVATE(node); --- 87 unchanged lines hidden (view full) --- 347 348/* 349 * Check for attaching a new hook. 350 */ 351static int 352ng_ether_newhook(node_p node, hook_p hook, const char *name) 353{ 354 const priv_p priv = NG_NODE_PRIVATE(node); | 233 * Handle a packet that is going out on an interface. 234 * The Ethernet header is already attached to the mbuf. 235 */ 236static int 237ng_ether_output(struct ifnet *ifp, struct mbuf **mp) 238{ 239 const node_p node = IFP2NG(ifp); 240 const priv_p priv = NG_NODE_PRIVATE(node); --- 87 unchanged lines hidden (view full) --- 328 329/* 330 * Check for attaching a new hook. 331 */ 332static int 333ng_ether_newhook(node_p node, hook_p hook, const char *name) 334{ 335 const priv_p priv = NG_NODE_PRIVATE(node); |
355 u_char orphan = priv->lowerOrphan; | |
356 hook_p *hookptr; 357 358 /* Divert hook is an alias for lower */ 359 if (strcmp(name, NG_ETHER_HOOK_DIVERT) == 0) 360 name = NG_ETHER_HOOK_LOWER; 361 362 /* Which hook? */ 363 if (strcmp(name, NG_ETHER_HOOK_UPPER) == 0) 364 hookptr = &priv->upper; | 336 hook_p *hookptr; 337 338 /* Divert hook is an alias for lower */ 339 if (strcmp(name, NG_ETHER_HOOK_DIVERT) == 0) 340 name = NG_ETHER_HOOK_LOWER; 341 342 /* Which hook? */ 343 if (strcmp(name, NG_ETHER_HOOK_UPPER) == 0) 344 hookptr = &priv->upper; |
365 else if (strcmp(name, NG_ETHER_HOOK_LOWER) == 0) { | 345 else if (strcmp(name, NG_ETHER_HOOK_LOWER) == 0) |
366 hookptr = &priv->lower; | 346 hookptr = &priv->lower; |
367 orphan = 0; 368 } else if (strcmp(name, NG_ETHER_HOOK_ORPHAN) == 0) { 369 hookptr = &priv->lower; 370 orphan = 1; 371 } else | 347 else if (strcmp(name, NG_ETHER_HOOK_ORPHAN) == 0) 348 hookptr = &priv->orphan; 349 else |
372 return (EINVAL); 373 374 /* Check if already connected (shouldn't be, but doesn't hurt) */ 375 if (*hookptr != NULL) 376 return (EISCONN); 377 378 /* Disable hardware checksums while 'upper' hook is connected */ 379 if (hookptr == &priv->upper) 380 priv->ifp->if_hwassist = 0; 381 382 /* OK */ 383 *hookptr = hook; | 350 return (EINVAL); 351 352 /* Check if already connected (shouldn't be, but doesn't hurt) */ 353 if (*hookptr != NULL) 354 return (EISCONN); 355 356 /* Disable hardware checksums while 'upper' hook is connected */ 357 if (hookptr == &priv->upper) 358 priv->ifp->if_hwassist = 0; 359 360 /* OK */ 361 *hookptr = hook; |
384 priv->lowerOrphan = orphan; | |
385 return (0); 386} 387 388/* 389 * Hooks are attached, adjust to force queueing. 390 * We don't really care which hook it is. 391 * they should all be queuing for outgoing data. 392 */ --- 116 unchanged lines hidden (view full) --- 509 const node_p node = NG_HOOK_NODE(hook); 510 const priv_p priv = NG_NODE_PRIVATE(node); 511 struct mbuf *m; 512 meta_p meta; 513 514 NGI_GET_M(item, m); 515 NGI_GET_META(item, meta); 516 NG_FREE_ITEM(item); | 362 return (0); 363} 364 365/* 366 * Hooks are attached, adjust to force queueing. 367 * We don't really care which hook it is. 368 * they should all be queuing for outgoing data. 369 */ --- 116 unchanged lines hidden (view full) --- 486 const node_p node = NG_HOOK_NODE(hook); 487 const priv_p priv = NG_NODE_PRIVATE(node); 488 struct mbuf *m; 489 meta_p meta; 490 491 NGI_GET_M(item, m); 492 NGI_GET_META(item, meta); 493 NG_FREE_ITEM(item); |
517 if (hook == priv->lower) | 494 if (hook == priv->lower || hook == priv->orphan) |
518 return ng_ether_rcv_lower(node, m, meta); 519 if (hook == priv->upper) 520 return ng_ether_rcv_upper(node, m, meta); 521 panic("%s: weird hook", __func__); | 495 return ng_ether_rcv_lower(node, m, meta); 496 if (hook == priv->upper) 497 return ng_ether_rcv_upper(node, m, meta); 498 panic("%s: weird hook", __func__); |
522#ifdef RESTARTABLE_PANICS /* so we don;t get an error msg in LINT */ | 499#ifdef RESTARTABLE_PANICS /* so we don't get an error msg in LINT */ |
523 return NULL; 524#endif 525} 526 527/* | 500 return NULL; 501#endif 502} 503 504/* |
528 * Handle an mbuf received on the "lower" hook. | 505 * Handle an mbuf received on the "lower" or "orphan" hook. |
529 */ 530static int 531ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta) 532{ 533 const priv_p priv = NG_NODE_PRIVATE(node); 534 struct ifnet *const ifp = priv->ifp; 535 536 /* Discard meta info */ --- 87 unchanged lines hidden (view full) --- 624ng_ether_disconnect(hook_p hook) 625{ 626 const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 627 628 if (hook == priv->upper) { 629 priv->upper = NULL; 630 if (priv->ifp != NULL) /* restore h/w csum */ 631 priv->ifp->if_hwassist = priv->hwassist; | 506 */ 507static int 508ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta) 509{ 510 const priv_p priv = NG_NODE_PRIVATE(node); 511 struct ifnet *const ifp = priv->ifp; 512 513 /* Discard meta info */ --- 87 unchanged lines hidden (view full) --- 601ng_ether_disconnect(hook_p hook) 602{ 603 const priv_p priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); 604 605 if (hook == priv->upper) { 606 priv->upper = NULL; 607 if (priv->ifp != NULL) /* restore h/w csum */ 608 priv->ifp->if_hwassist = priv->hwassist; |
632 } else if (hook == priv->lower) { | 609 } else if (hook == priv->lower) |
633 priv->lower = NULL; | 610 priv->lower = NULL; |
634 priv->lowerOrphan = 0; 635 } else | 611 else if (hook == priv->orphan) 612 priv->orphan = NULL; 613 else |
636 panic("%s: weird hook", __func__); 637 if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 638 && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) 639 ng_rmnode_self(NG_HOOK_NODE(hook)); /* reset node */ 640 return (0); 641} 642 643/****************************************************************** --- 64 unchanged lines hidden --- | 614 panic("%s: weird hook", __func__); 615 if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) 616 && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) 617 ng_rmnode_self(NG_HOOK_NODE(hook)); /* reset node */ 618 return (0); 619} 620 621/****************************************************************** --- 64 unchanged lines hidden --- |