Deleted Added
full compact
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 ---