ng_ether.c (96265) | ng_ether.c (97896) |
---|---|
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 96265 2002-05-09 20:19:00Z archie $ | 40 * $FreeBSD: head/sys/netgraph/ng_ether.c 97896 2002-06-05 23:32:56Z archie $ |
41 */ 42 43/* 44 * ng_ether(4) netgraph node type 45 */ 46 47#include <sys/param.h> 48#include <sys/systm.h> --- 304 unchanged lines hidden (view full) --- 353/* 354 * Optimization for gluing the Ethernet header back onto 355 * the front of an incoming packet. 356 */ 357static int 358ng_ether_glueback_header(struct mbuf **mp, struct ether_header *eh) 359{ 360 struct mbuf *m = *mp; | 41 */ 42 43/* 44 * ng_ether(4) netgraph node type 45 */ 46 47#include <sys/param.h> 48#include <sys/systm.h> --- 304 unchanged lines hidden (view full) --- 353/* 354 * Optimization for gluing the Ethernet header back onto 355 * the front of an incoming packet. 356 */ 357static int 358ng_ether_glueback_header(struct mbuf **mp, struct ether_header *eh) 359{ 360 struct mbuf *m = *mp; |
361 uintfptr_t room; | |
362 int error = 0; 363 364 /* | 361 int error = 0; 362 363 /* |
365 * Possibly the header is already on the front. 366 * If this is the case so just move the markers back 367 * to re-include it. We lucked out. 368 * This allows us to avoid a yucky m_pullup 369 * in later nodes if it works. | 364 * Optimize for the case where the header is already in place 365 * at the front of the mbuf. This is actually quite likely 366 * because many Ethernet drivers generate packets this way. |
370 */ 371 if (eh == mtod(m, struct ether_header *) - 1) { 372 m->m_len += sizeof(*eh); 373 m->m_data -= sizeof(*eh); 374 m->m_pkthdr.len += sizeof(*eh); 375 goto done; 376 } 377 | 367 */ 368 if (eh == mtod(m, struct ether_header *) - 1) { 369 m->m_len += sizeof(*eh); 370 m->m_data -= sizeof(*eh); 371 m->m_pkthdr.len += sizeof(*eh); 372 goto done; 373 } 374 |
378 /* 379 * Alternatively there may be room even though 380 * it is stored somewhere else. If so, copy it in. 381 * This only safe because we KNOW that this packet has 382 * just been generated by an ethernet card, so there are 383 * no aliases to the buffer (not so for outgoing packets). 384 * Nearly all ethernet cards will end up producing mbufs 385 * that fall into these cases. So we are not optimizing 386 * contorted cases. 387 */ 388 if ((m->m_flags & M_EXT) != 0) { 389 room = mtod(m, caddr_t) - m->m_ext.ext_buf; 390 if (room > m->m_ext.ext_size) /* garbage, fail immediately */ 391 room = 0; 392 } else 393 room = mtod(m, caddr_t) - m->m_pktdat; 394 395 /* 396 * If we have room, just copy it and adjust 397 */ 398 if (room >= sizeof(*eh)) { 399 m->m_len += sizeof(*eh); 400 m->m_data -= sizeof(*eh); 401 m->m_pkthdr.len += sizeof(*eh); 402 goto copy; 403 } 404 405 /* 406 * Doing anything more is likely to get more 407 * expensive than it's worth.. 408 * it's probable that everything else is in one 409 * big lump. The next node will do an m_pullup() 410 * for exactly the amount of data it needs and 411 * hopefully everything after that will not 412 * need one. So let's just use M_PREPEND. 413 */ 414 M_PREPEND(m, sizeof (*eh), M_DONTWAIT); | 375 /* Prepend the header back onto the front of the mbuf */ 376 M_PREPEND(m, sizeof(*eh), M_DONTWAIT); |
415 if (m == NULL) { 416 error = ENOBUFS; 417 goto done; 418 } 419 | 377 if (m == NULL) { 378 error = ENOBUFS; 379 goto done; 380 } 381 |
420copy: 421 /* Copy header and return (possibly new) mbuf */ 422 bcopy((caddr_t)eh, mtod(m, struct ether_header *), sizeof(*eh)); | 382 /* Copy header into front of mbuf */ 383 bcopy(eh, mtod(m, void *), sizeof(*eh)); 384 |
423done: | 385done: |
386 /* Done */ |
|
424 *mp = m; 425 return error; 426} 427 428/****************************************************************** 429 NETGRAPH NODE METHODS 430******************************************************************/ 431 --- 192 unchanged lines hidden (view full) --- 624 * Handle an mbuf received on the "lower" hook. 625 */ 626static int 627ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta) 628{ 629 const priv_p priv = NG_NODE_PRIVATE(node); 630 struct ifnet *const ifp = priv->ifp; 631 | 387 *mp = m; 388 return error; 389} 390 391/****************************************************************** 392 NETGRAPH NODE METHODS 393******************************************************************/ 394 --- 192 unchanged lines hidden (view full) --- 587 * Handle an mbuf received on the "lower" hook. 588 */ 589static int 590ng_ether_rcv_lower(node_p node, struct mbuf *m, meta_p meta) 591{ 592 const priv_p priv = NG_NODE_PRIVATE(node); 593 struct ifnet *const ifp = priv->ifp; 594 |
595 /* Discard meta info */ 596 NG_FREE_META(meta); 597 |
|
632 /* Check whether interface is ready for packets */ 633 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { 634 NG_FREE_M(m); | 598 /* Check whether interface is ready for packets */ 599 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING)) { 600 NG_FREE_M(m); |
635 NG_FREE_META(meta); | |
636 return (ENETDOWN); 637 } 638 639 /* Make sure header is fully pulled up */ 640 if (m->m_pkthdr.len < sizeof(struct ether_header)) { 641 NG_FREE_M(m); | 601 return (ENETDOWN); 602 } 603 604 /* Make sure header is fully pulled up */ 605 if (m->m_pkthdr.len < sizeof(struct ether_header)) { 606 NG_FREE_M(m); |
642 NG_FREE_META(meta); | |
643 return (EINVAL); 644 } 645 if (m->m_len < sizeof(struct ether_header) | 607 return (EINVAL); 608 } 609 if (m->m_len < sizeof(struct ether_header) |
646 && (m = m_pullup(m, sizeof(struct ether_header))) == NULL) { 647 NG_FREE_META(meta); | 610 && (m = m_pullup(m, sizeof(struct ether_header))) == NULL) |
648 return (ENOBUFS); | 611 return (ENOBUFS); |
649 } | |
650 651 /* Drop in the MAC address if desired */ 652 if (priv->autoSrcAddr) { | 612 613 /* Drop in the MAC address if desired */ 614 if (priv->autoSrcAddr) { |
615 616 /* Make the mbuf writable if it's not already */ 617 if (!M_WRITABLE(m) 618 && (m = m_pullup(m, sizeof(struct ether_header))) == NULL) 619 return (ENOBUFS); 620 621 /* Overwrite source MAC address */ |
|
653 bcopy((IFP2AC(ifp))->ac_enaddr, 654 mtod(m, struct ether_header *)->ether_shost, 655 ETHER_ADDR_LEN); 656 } 657 658 /* Send it on its way */ | 622 bcopy((IFP2AC(ifp))->ac_enaddr, 623 mtod(m, struct ether_header *)->ether_shost, 624 ETHER_ADDR_LEN); 625 } 626 627 /* Send it on its way */ |
659 NG_FREE_META(meta); | |
660 return ether_output_frame(ifp, m); 661} 662 663/* 664 * Handle an mbuf received on the "upper" hook. 665 */ 666static int 667ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta) 668{ 669 const priv_p priv = NG_NODE_PRIVATE(node); 670 struct ether_header *eh; 671 | 628 return ether_output_frame(ifp, m); 629} 630 631/* 632 * Handle an mbuf received on the "upper" hook. 633 */ 634static int 635ng_ether_rcv_upper(node_p node, struct mbuf *m, meta_p meta) 636{ 637 const priv_p priv = NG_NODE_PRIVATE(node); 638 struct ether_header *eh; 639 |
640 /* Discard meta info */ 641 NG_FREE_META(meta); 642 |
|
672 /* Check length and pull off header */ 673 if (m->m_pkthdr.len < sizeof(*eh)) { 674 NG_FREE_M(m); | 643 /* Check length and pull off header */ 644 if (m->m_pkthdr.len < sizeof(*eh)) { 645 NG_FREE_M(m); |
675 NG_FREE_META(meta); | |
676 return (EINVAL); 677 } | 646 return (EINVAL); 647 } |
678 if (m->m_len < sizeof(*eh) && (m = m_pullup(m, sizeof(*eh))) == NULL) { 679 NG_FREE_META(meta); | 648 if (m->m_len < sizeof(*eh) && (m = m_pullup(m, sizeof(*eh))) == NULL) |
680 return (ENOBUFS); | 649 return (ENOBUFS); |
681 } | |
682 eh = mtod(m, struct ether_header *); 683 m->m_data += sizeof(*eh); 684 m->m_len -= sizeof(*eh); 685 m->m_pkthdr.len -= sizeof(*eh); 686 m->m_pkthdr.rcvif = priv->ifp; 687 688 /* Route packet back in */ | 650 eh = mtod(m, struct ether_header *); 651 m->m_data += sizeof(*eh); 652 m->m_len -= sizeof(*eh); 653 m->m_pkthdr.len -= sizeof(*eh); 654 m->m_pkthdr.rcvif = priv->ifp; 655 656 /* Route packet back in */ |
689 NG_FREE_META(meta); | |
690 ether_demux(priv->ifp, eh, m); 691 return (0); 692} 693 694/* 695 * Shutdown node. This resets the node but does not remove it 696 * unless the REALLY_DIE flag is set. 697 */ --- 153 unchanged lines hidden --- | 657 ether_demux(priv->ifp, eh, m); 658 return (0); 659} 660 661/* 662 * Shutdown node. This resets the node but does not remove it 663 * unless the REALLY_DIE flag is set. 664 */ --- 153 unchanged lines hidden --- |