From nobody@FreeBSD.org  Mon Jun 10 23:19:07 2013
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1])
	by hub.freebsd.org (Postfix) with ESMTP id 2B32958D
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 10 Jun 2013 23:19:07 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from oldred.freebsd.org (oldred.freebsd.org [8.8.178.121])
	by mx1.freebsd.org (Postfix) with ESMTP id 1C59919B8
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 10 Jun 2013 23:19:07 +0000 (UTC)
Received: from oldred.freebsd.org ([127.0.1.6])
	by oldred.freebsd.org (8.14.5/8.14.7) with ESMTP id r5ANJ6Tr095597
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 10 Jun 2013 23:19:06 GMT
	(envelope-from nobody@oldred.freebsd.org)
Received: (from nobody@localhost)
	by oldred.freebsd.org (8.14.5/8.14.5/Submit) id r5ANJ6sm095594;
	Mon, 10 Jun 2013 23:19:06 GMT
	(envelope-from nobody)
Message-Id: <201306102319.r5ANJ6sm095594@oldred.freebsd.org>
Date: Mon, 10 Jun 2013 23:19:06 GMT
From: Henning Matyschok <henning.matyschok@stud.fh-flensburg.de>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Source code contribution of implementation about virtual ethernet interface 
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         179473
>Category:       kern
>Synopsis:       [new driver] if_vether.c: Source code contribution of implementation about virtual ethernet interface
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-net
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Mon Jun 10 23:20:00 UTC 2013
>Closed-Date:    
>Last-Modified:  Sun May 04 05:36:04 UTC 2014
>Originator:     Henning Matyschok
>Release:        RELENG_9_1
>Organization:
>Environment:
FreeBSD marduk.testenv.local 9.0-RELEASE-p4 FreeBSD 9.0-RELEASE-p4 #0: Sun Mar  3 19:11:46 CET 2013     supervisor@marduk.testenv.local:/usr/obj/usr/src/sys/MARDUK  i386

>Description:
ng_eiface(4) is not capable to interact with ng_pppoe(4) throught ng_ether(4).
>How-To-Repeat:
Try to use an instance of ng_eiface(4) as link layer interface for userland ppp.
>Fix:
I've written a virtual Ethernet interface (if_veth.c) wich uses bridge(4) to access link layer. This is capable to interact with ng_pppoe(4) by ng_ether(4). Now it is possible to use virtual Ethernet interfaces as link layer interface for userland ppp. 

Either, see
#
# http://wiki.bsdforen.de/wiki:user:marduk#if_vethc
#
or see attachment. 

Patch attached with submission follows:

/*-
 * Copyright (c) 2013 Henning Matyschok
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * Copyright (c) 1982, 1989, 1993
 *	The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 */
#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/libkern.h>
#include <sys/socket.h> 
#include <sys/sockio.h>
 
#include <net/if.h>
#include <net/if_clone.h>
#include <net/if_media.h>
#include <net/if_types.h>
#include <net/if_var.h>
#include <net/ethernet.h>
#include <net/if_bridgevar.h>
#include <net/if_vlan_var.h>
#include <net/if_dl.h>
#include <net/if_arp.h>
#include <net/bpf.h>
 
#include <netinet/in.h>
#include <netinet/in_var.h>
#include <netinet/ip_carp.h>
 
#ifdef MAC
#include <security/mac/mac_framework.h>
#endif /* MAC */
 
static const uint8_t ether_bcast_lla[ETHER_ADDR_LEN] =
	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
/* if_lagg(4) entry point. */
extern struct mbuf	*(*lagg_input_p)(struct ifnet *, struct mbuf *); 
 
/* ng_ether(4) entry point. */
extern	void	(*ng_ether_input_p)(struct ifnet *ifp, struct mbuf **mp);
 
/*
 * Declaration of reduced struct bridge_softc is needed to identify 
 * bridge(4) describing ifnet structure on the fly, when veth_start
 * may called. See net/if_bridge.c and net/if_var.h for further 
 * details.
 */
struct bridge_softc {
	struct ifnet	*sc_ifp; 	
};
 
#define VETHNAME	"veth"
 
struct veth_softc {
	struct ifnet	*sc_ifp;	/* It will be a network interface. */
	LIST_ENTRY(veth_softc) veth_list;
	struct mtx	sc_mtx;	
#define	VETH_LOCK_INIT(sc)	mtx_init(&(sc)->sc_mtx, "veth softc",	\
				     NULL, MTX_DEF)
#define	VETH_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
#define	VETH_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
#define	VETH_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
#define	VETH_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)	
	/* Fake information about used transmission media. */
	struct ifmedia	sc_ifm;	
	int	sc_status;
};
 
static LIST_HEAD(, veth_softc) veth_list;
 
static struct mtx veth_mtx;
static MALLOC_DEFINE(M_VETH, VETHNAME, "Virtual ethernet interface");
 
/* Ifc cloner specific subr.  */
static int	veth_clone_create(struct if_clone *, int, caddr_t);
static void	veth_clone_destroy(struct ifnet *);
 
IFC_SIMPLE_DECLARE(veth, 0);
 
/* Interface specific methods. */
static void	veth_init(void *);
static void	veth_input(struct ifnet *ifp, struct mbuf *m);
static int	veth_ioctl(struct ifnet *, u_long, caddr_t);
static void	veth_start(struct ifnet *);
static void	veth_stop(struct ifnet *, int);
 
/*
 * Module event handler.
 */
static int
veth_mod_event(module_t mod, int event, void *data)
{
	int error = 0;
 
	switch (event) {
	case MOD_LOAD:
 
		mtx_init(&veth_mtx, "if_veth", NULL, MTX_DEF);
		if_clone_attach(&veth_cloner);
		break;
	case MOD_UNLOAD:	
 
		if_clone_detach(&veth_cloner);
		mtx_destroy(&veth_mtx);
		break;
	default:
		error = EOPNOTSUPP;
	}
 
	return(error);
} 
 
static moduledata_t veth_mod = {
	"if_veth",
	veth_mod_event,
	0
};
DECLARE_MODULE(if_veth, veth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 
/*
 * By SIOCSIFMEDIA and SIOCGIFMEDIA ioctl requests invoked callbacks. 
 */
static int
veth_media_change(struct ifnet *ifp)
{
	return(0);
}
 
static void
veth_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
{
	ifmr->ifm_status = IFM_AVALID|IFM_ACTIVE;
	ifmr->ifm_active = IFM_ETHER|IFM_1000_T|IFM_FDX;
}
 
/*
 * Instantiates veth interface.
 */
static int
veth_clone_create(struct if_clone *ifc, int unit, caddr_t data)
{
	struct veth_softc *sc;
	struct ifnet *ifp;
	uint32_t randval;
	uint8_t	lla[ETHER_ADDR_LEN];
 
	sc = malloc(sizeof(struct veth_softc), M_VETH, M_WAITOK|M_ZERO);
	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
	if (ifp == NULL) {
		free(sc, M_VETH);
		return(ENOSPC);
	}
 
	VETH_LOCK_INIT(sc);
	ifp->if_softc = sc;
 
	if_initname(ifp, ifc->ifc_name, unit);
 
	/* Generates lla with randomized value. */
	lla[0] = 0x0;
	randval = arc4random();
	memcpy(&lla[1], &randval, sizeof(uint32_t));
	lla[5] = (uint8_t)unit; /* Interface major number */
 
	ether_ifattach(ifp, lla);
 
	ifp->if_init = veth_init;
	ifp->if_input = veth_input;
	ifp->if_ioctl = veth_ioctl;
	ifp->if_start = veth_start;
 
	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
	ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
	ifp->if_flags = (IFF_SIMPLEX|IFF_BROADCAST|IFF_MULTICAST);
	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 
	/* 
	 * Initializes by in context of SIOCSIFMEDIA and SIOCGIFMEDIA 
	 * ioctl requests used callbacks and adds faked media information 
	 * about non-existing physical transmission media of non-existing 
	 * hardware. 
	 */
	ifmedia_init(&sc->sc_ifm, 0, veth_media_change, veth_media_status);
	ifmedia_add(&sc->sc_ifm, IFM_ETHER|IFM_1000_T|IFM_FDX, 0, NULL);
	ifmedia_set(&sc->sc_ifm, IFM_ETHER|IFM_1000_T|IFM_FDX);
 
	sc->sc_status = IFM_AVALID;
	ifp->if_baudrate = 0;
 
	mtx_lock(&veth_mtx);
	LIST_INSERT_HEAD(&veth_list, sc, veth_list);
	mtx_unlock(&veth_mtx);
	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
	return(0);
}
 
/*
 * Destroys veth interface.
 */
static void
veth_clone_destroy(struct ifnet *ifp)
{
	struct veth_softc *sc;	
	sc = ifp->if_softc;	
 
	mtx_lock(&veth_mtx);
	veth_stop(ifp, 1);
	ifp->if_flags &= ~IFF_UP;			
	LIST_REMOVE(sc, veth_list);
	ether_ifdetach(ifp);
	VETH_LOCK_DESTROY(sc);
 
	mtx_unlock(&veth_mtx);
	free(sc, M_VETH);
}
 
/*
 * Initializes veth interface.
 */
static void
veth_init(void *xsc)
{
	struct veth_softc *sc;
	struct ifnet *ifp;
 
	sc = (struct veth_softc *)xsc;
	ifp = sc->sc_ifp;
 
	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
		return;
	}
 
	VETH_LOCK(sc);
	ifp->if_drv_flags |= IFF_DRV_RUNNING;
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
	VETH_UNLOCK(sc);
}
 
/*
 * Stops veth interface.
 */
static void
veth_stop(struct ifnet *ifp, int disable)
{
	struct veth_softc *sc;
 
	sc = ifp->if_softc;
	VETH_LOCK_ASSERT(sc);
 
	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
		return;
	}
	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
}	
 
/*
 * Handles ioctl requests. Media types can't changed, 
 * this is a virtual ethernet interface.
 */
static int
veth_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
{
	struct veth_softc *sc = ifp->if_softc;	
	struct ifreq *ifr = (struct ifreq *)data;
	int error = 0;
 
	VETH_LOCK(sc);
	switch (cmd) {
	case SIOCSIFMTU:
		if (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO) {
			error = EINVAL;
		} else {
			ifp->if_mtu = ifr->ifr_mtu;
		}	
		break;
	case SIOCSIFMEDIA:
	case SIOCGIFMEDIA:
		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifm, cmd);
		break;
	case SIOCSIFFLAGS:
	case SIOCADDMULTI:
	case SIOCDELMULTI:
		break;
	case SIOCSIFPHYS:
		error = EOPNOTSUPP;
		break;
	default:
		error = ether_ioctl(ifp, cmd, data);
		break;
	}
	VETH_UNLOCK(sc);
	return(error);
}
 
/*
 * Dispatches transmissions of queued frames to bridge(4) by
 * forwarding them throught veth_start() when frame transmission 
 * starts by ether_frame_output(). 
 *
 * Normally, an ethernet frame may dequeued and processed by 
 * network driver specific xxx_output() method (i. e. rl_start(), 
 * defined in pci/if_rl.c) via if_transmit() method, wich 
 * initializes enqueueing of frames temporarly. 
 *
 * But in this case, there exists no underlying hardware, this 
 * implies that if_transmit() of bridge(4) invocates bridge_start 
 * to forward by this network interface transmitted frames to 
 * real networking devices or other vitual networking devices 
 * wich are capable to be a member (i. e. gif(4)) of an instance 
 * of bridge(4). 
 * 
 * Finally, frames may dispatched to itself through call of  
 * veth_input() when frame comes from bridge(4). Otherwise, 
 * frames may discarded silently, when this interface is not 
 * member of bridge(4) or when frames are reinjected by bridge(4) 
 * throught bridge_start(). 
 */
static void
veth_start(struct ifnet *ifp)
{
	struct mbuf	*m;
	struct bridge_softc *sc;
	struct ifnet *bifp;
 
	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
	for (;;) {
		IFQ_DEQUEUE(&ifp->if_snd, m);
		if (m == NULL) {
			break;
		}
 
		if (ifp->if_bridge) {
			sc = ifp->if_bridge;
			bifp = sc->sc_ifp;
 
			if (m->m_pkthdr.rcvif == NULL) {
				m->m_pkthdr.rcvif = ifp;
                                ETHER_BPF_MTAP(ifp, m);
				ifp->if_obytes += m->m_pkthdr.len;
				ifp->if_opackets++;
				(bifp->if_transmit)(bifp, m);
			} else if (m->m_pkthdr.rcvif == ifp) {
				m_freem(m);
			} else {
				(ifp->if_input)(ifp, m);	
			} 
		} else {
			m_freem(m);
		}
	}
 
	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
}
 
/*
 * Handles input of frames. This method is derived 
 * from ether_input_internal where its implementation 
 * remains in net/if_ethersubr.c. Possibly, the
 * Regents of University of California owns the
 * copyright about this function, because I'm adopted
 * most of all code from it.
 */
static void
veth_input(struct ifnet *ifp, struct mbuf *m)
{
	struct ether_header *eh;
	uint16_t type;
 
	if ((ifp->if_flags & IFF_UP) == 0) {
		goto bad;
	}
 	
 	/*
 	 * Do some consistency checks about frame header 
 	 * related stuff (If exists, size, offset, etc.). 
 	 */ 
	if ((m->m_flags & M_PKTHDR) == 0) {
		goto drop;
	}
 
	if (m->m_len < ETHER_HDR_LEN) {
		m = m_pullup(m, ETHER_HDR_LEN);
		if (m == NULL) {
			goto drop;
		}
	}
 
	eh = mtod(m, struct ether_header *);
	type = ntohs(eh->ether_type);
	if (m->m_pkthdr.rcvif == NULL) {
		goto drop;
	}
 
	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
		if (bcmp(ether_bcast_lla, eh->ether_dhost, 
			ETHER_ADDR_LEN) == 0) {
			m->m_flags |= M_BCAST;
		} else {
			m->m_flags |= M_MCAST;
		}
		ifp->if_imcasts++;
	}
 
#ifdef MAC
	/* 
	 * MAC policy driven mbuf tagging. 
	 */ 
	mac_ifnet_create_mbuf(ifp, m);
#endif /* MAC */
 
	/* 
	 * Processing by bpf(4) is possible and do some statistics. 
	 */
	ETHER_BPF_MTAP(ifp, m);
	ifp->if_ibytes += m->m_pkthdr.len;
	ifp->if_ipackets++;
	if (ifp->if_flags & IFF_MONITOR) {
		goto drop;
	}
 
	/* 
	 * lagg(4) handling. 
	 */
	if (lagg_input_p) {
		if (ifp->if_type == IFT_IEEE8023ADLAG) {
			m = (*lagg_input_p)(ifp, m);
			if (m != NULL) {
				ifp = m->m_pkthdr.rcvif;
			} else { 
				return;
			}
		}
	}
 
	/* 
	 * Processing of 802.1Q tag, if vlan frames may occour. \
	 */
	if ((m->m_flags & M_VLANTAG) == 0 
		&& type == ETHERTYPE_VLAN) {
		struct ether_vlan_header *evl;
 
		if (m->m_len < sizeof(*evl) 
		&& (m = m_pullup(m, sizeof(*evl))) == NULL) {
			goto drop;
		}
 
		evl = mtod(m, struct ether_vlan_header *);
		m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag);
		m->m_flags |= M_VLANTAG;
 
		bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
		    ETHER_HDR_LEN - ETHER_TYPE_LEN);
		m_adj(m, ETHER_VLAN_ENCAP_LEN);
	}
 
	M_SETFIB(m, ifp->if_fib);
 
	/* 
	 * If ng_ether(4) node exist, then lets netgraph(4) 
	 * doing frame processing.
	 */
	if (ng_ether_input_p) {
		if (IFP2AC(ifp)->ac_netgraph) {
			(*ng_ether_input_p)(ifp, &m);
			if (m == NULL) {
				return;
			}
		}
	}
 
	/* 
	 * Finishes off M_PROMISC flag for processing 
	 * SDU through carp(4).
	 */ 
	if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) {
		m->m_flags &= ~M_PROMISC;
	} else {
		if (!ETHER_IS_MULTICAST(eh->ether_dhost) 
		&& bcmp(IF_LLADDR(ifp), eh->ether_dhost, 
			ETHER_ADDR_LEN) != 0) {
			m->m_flags |= M_PROMISC;
    	}
	}
 
	/* 
	 * Upper lzyer processing of received frame starts here.
	 */
	ether_demux(ifp, m);
	return;
drop:
	ifp->if_ierrors++;
bad:
	m_freem(m);
}


>Release-Note:
>Audit-Trail:

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Thu, 20 Jun 2013 00:34:17 -0000

 ------------yPGQsOt2uvF1CxHxvIlgW8
 Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 I'm excusing for my bad english.
 ------------yPGQsOt2uvF1CxHxvIlgW8
 Content-Disposition: attachment; filename=if_veth.c.txt
 Content-Type: text/plain; name=if_veth.c.txt
 Content-Transfer-Encoding: 7bit
 
 /*-
  * Copyright (c) 2013 Henning Matyschok
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  * Copyright (c) 1982, 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/libkern.h>
 #include <sys/socket.h> 
 #include <sys/sockio.h>
  
 #include <net/if.h>
 #include <net/if_clone.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/if_var.h>
 #include <net/ethernet.h>
 #include <net/if_bridgevar.h>
 #include <net/if_vlan_var.h>
 #include <net/if_dl.h>
 #include <net/if_arp.h>
 #include <net/bpf.h>
  
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_carp.h>
  
 #ifdef MAC
 #include <security/mac/mac_framework.h>
 #endif /* MAC */
  
 static const uint8_t ether_bcast_lla[ETHER_ADDR_LEN] =
 	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  
 /* if_lagg(4) entry point. */
 extern struct mbuf	*(*lagg_input_p)(struct ifnet *, struct mbuf *); 
  
 /* ng_ether(4) entry point. */
 extern	void	(*ng_ether_input_p)(struct ifnet *, struct mbuf **);
  
 /*
  * Declaration of reduced struct bridge_softc is needed to identify 
  * bridge(4) describing ifnet structure on the fly, when veth_start()
  * may called. See net/if_bridge.c and net/if_var.h for further 
  * details.
  */
 struct bridge_softc {
 	struct ifnet	*sc_ifp; 	
 };
  
 #define VETHNAME	"veth"
  
 struct veth_softc {
 	struct ifnet	*sc_ifp;
 	LIST_ENTRY(veth_softc) veth_list;
 	struct mtx	sc_mtx;	
 #define	VETH_LOCK_INIT(sc)	mtx_init(&(sc)->sc_mtx, "veth softc",	\
 				     NULL, MTX_DEF)
 #define	VETH_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
 #define	VETH_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
 #define	VETH_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
 #define	VETH_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)	
 	/* Fake information about used transmission media. */
 	struct ifmedia	sc_ifm;	
 	int	sc_status;
 };
  
 static LIST_HEAD(, veth_softc) veth_list;
  
 static struct mtx veth_mtx;
 static MALLOC_DEFINE(M_VETH, VETHNAME, "Virtual ethernet interface");
  
 /* Ifc cloner specific subr.  */
 static int	veth_clone_create(struct if_clone *, int, caddr_t);
 static void	veth_clone_destroy(struct ifnet *);
  
 IFC_SIMPLE_DECLARE(veth, 0);
  
 /* Interface specific methods. */
 static void	veth_init(void *);
 static void	veth_input_internal(struct ifnet *, struct mbuf *);
 static void	veth_input(struct ifnet *, struct mbuf *);
 static int	veth_media_change(struct ifnet *);
 static void	veth_media_status(struct ifnet *ifp, struct ifmediareq *);
 static int	veth_ioctl(struct ifnet *, u_long, caddr_t);
 static void	veth_start(struct ifnet *);
 static void	veth_stop(struct ifnet *, int);
  
 /* See net/netisr.h for further deteils. */
 #define NETISR_VETH	13
 static void	veth_nh_input(struct mbuf *);
  
 /* Netisr handler definition. */
 static struct netisr_handler veth_nh = {
 	.nh_name = VETHNAME,
 	.nh_handler = veth_nh_input,
 	.nh_proto = NETISR_VETH,
 	.nh_policy = NETISR_POLICY_SOURCE,
 	.nh_dispatch = NETISR_DISPATCH_DIRECT,
 };
  
 /*
  * Module event handler.
  */
 static int
 veth_mod_event(module_t mod, int event, void *data)
 {
 	int error = 0;
  
 	switch (event) {
 	case MOD_LOAD:
  
 		mtx_init(&veth_mtx, "if_veth", NULL, MTX_DEF);
 		netisr_register(&veth_nh);
 		if_clone_attach(&veth_cloner);
 		break;
 	case MOD_UNLOAD:	
  
 		if_clone_detach(&veth_cloner);
 		netisr_unregister(&veth_nh);
 		mtx_destroy(&veth_mtx);
 		break;
 	default:
 		error = EOPNOTSUPP;
 	}
  
 	return(error);
 } 
  
 static moduledata_t veth_mod = {
 	"if_veth",
 	veth_mod_event,
 	0
 };
 DECLARE_MODULE(if_veth, veth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  
 /*
  * Instantiates veth interface.
  */
 static int
 veth_clone_create(struct if_clone *ifc, int unit, caddr_t data)
 {
 	struct veth_softc *sc;
 	struct ifnet *ifp;
 	uint32_t randval;
 	uint8_t	lla[ETHER_ADDR_LEN];
  
 	sc = malloc(sizeof(struct veth_softc), M_VETH, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		free(sc, M_VETH);
 		return(ENOSPC);
 	}
  
 	VETH_LOCK_INIT(sc);
 	ifp->if_softc = sc;
  
 	if_initname(ifp, ifc->ifc_name, unit);
  
 	/* Generates lla with randomized value. */
 	lla[0] = 0x0;
 	randval = arc4random();
 	memcpy(&lla[1], &randval, sizeof(uint32_t));
 	lla[5] = (uint8_t)unit; /* Interface major number */
  
 	ether_ifattach(ifp, lla);
  
 	ifp->if_init = veth_init;
 	ifp->if_input = veth_input;
 	ifp->if_ioctl = veth_ioctl;
 	ifp->if_start = veth_start;
  
 	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_flags = (IFF_SIMPLEX|IFF_BROADCAST|IFF_MULTICAST);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
  
 	ifmedia_init(&sc->sc_ifm, 0, veth_media_change, veth_media_status);
 	ifmedia_add(&sc->sc_ifm, IFM_ETHER|IFM_1000_T|IFM_FDX, 0, NULL);
 	ifmedia_set(&sc->sc_ifm, IFM_ETHER|IFM_1000_T|IFM_FDX);
  
 	sc->sc_status = IFM_AVALID;
 	ifp->if_baudrate = 0;
  
 	mtx_lock(&veth_mtx);
 	LIST_INSERT_HEAD(&veth_list, sc, veth_list);
 	mtx_unlock(&veth_mtx);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
  
 	return(0);
 }
  
 /*
  * Destroys veth interface.
  */
 static void
 veth_clone_destroy(struct ifnet *ifp)
 {
 	struct veth_softc *sc;	
 	sc = ifp->if_softc;	
  
 	mtx_lock(&veth_mtx);
 	veth_stop(ifp, 1);
 	ifp->if_flags &= ~IFF_UP;			
 	LIST_REMOVE(sc, veth_list);
 	ether_ifdetach(ifp);
 	VETH_LOCK_DESTROY(sc);
  
 	mtx_unlock(&veth_mtx);
 	free(sc, M_VETH);
 }
  
 static int
 veth_media_change(struct ifnet *ifp)
 {
 	return(0);
 }
  
 static void
 veth_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
 	ifmr->ifm_status = IFM_AVALID|IFM_ACTIVE;
 	ifmr->ifm_active = IFM_ETHER|IFM_1000_T|IFM_FDX;
 }
  
 /*
  * Handles ioctl requests. Media types can't changed, 
  * this is a virtual ethernet interface.
  */
 static int
 veth_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct veth_softc *sc = ifp->if_softc;	
 	struct ifreq *ifr = (struct ifreq *)data;
 	int error = 0;
  
 	VETH_LOCK(sc);
 	switch (cmd) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO) {
 			error = EINVAL;
 		} else {
 			ifp->if_mtu = ifr->ifr_mtu;
 		}	
 		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:
 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifm, cmd);
 		break;
 	case SIOCSIFFLAGS:
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		break;
 	case SIOCSIFPHYS:
 		error = EOPNOTSUPP;
 		break;
 	default:
 		error = ether_ioctl(ifp, cmd, data);
 		break;
 	}
 	VETH_UNLOCK(sc);
 	return(error);
 }
  
 /*
  * Initializes veth interface.
  */
 static void
 veth_init(void *xsc)
 {
 	struct veth_softc *sc;
 	struct ifnet *ifp;
  
 	sc = (struct veth_softc *)xsc;
 	ifp = sc->sc_ifp;
  
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		return;
 	}
  
 	VETH_LOCK(sc);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	VETH_UNLOCK(sc);
 }
  
 /*
  * Stops veth interface.
  */
 static void
 veth_stop(struct ifnet *ifp, int disable)
 {
 	struct veth_softc *sc;
  
 	sc = ifp->if_softc;
 	VETH_LOCK_ASSERT(sc);
  
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		return;
 	}
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 }	
  
 /*
  * Dispatches transmissions of queued frames to bridge(4) or to
  * itself when bridge(4) forwarded frames to this interface. 
  */
 static void
 veth_start(struct ifnet *ifp)
 {
 	struct mbuf	*m;
 	struct bridge_softc *sc;
 	struct ifnet *bifp;
  
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 	for (;;) {
 		IFQ_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL) {
 			break;
 		}
  
 		if (ifp->if_bridge) {
 			sc = ifp->if_bridge;
 			bifp = sc->sc_ifp;
  
 			if (m->m_pkthdr.rcvif == NULL) {
 				m->m_pkthdr.rcvif = ifp;
                 ETHER_BPF_MTAP(ifp, m);
 				ifp->if_obytes += m->m_pkthdr.len;
 				ifp->if_opackets++;
 				(bifp->if_transmit)(bifp, m);
 			} else if (m->m_pkthdr.rcvif == ifp) {
 				m_freem(m);
 			} else {
 				(ifp->if_input)(ifp, m);	
 			} 
 		} else {
 			m_freem(m);
 		}
 	}
  
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
  
 /*
  * Handles input of frames. This method is derived 
  * from ether_input_internal() where its implementation 
  * remains in net/if_ethersubr.c. 
  */
 static void
 veth_input_internal(struct ifnet *ifp, struct mbuf *m)
 {
 	struct ether_header *eh;
 	uint16_t type;
  
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		goto bad;
 	}
  
 	if ((m->m_flags & M_PKTHDR) == 0) {
 		goto drop;
 	}
  
 	if (m->m_len < ETHER_HDR_LEN) {
 		m = m_pullup(m, ETHER_HDR_LEN);
 		if (m == NULL) {
 			goto drop;
 		}
 	}
  
 	eh = mtod(m, struct ether_header *);
 	type = ntohs(eh->ether_type);
 	if (m->m_pkthdr.rcvif == NULL) {
 		goto drop;
 	}
  
 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
 		if (bcmp(ether_bcast_lla, eh->ether_dhost, 
 			ETHER_ADDR_LEN) == 0) {
 			m->m_flags |= M_BCAST;
 		} else {
 			m->m_flags |= M_MCAST;
 		}
 		ifp->if_imcasts++;
 	}
  
 #ifdef MAC
 	mac_ifnet_create_mbuf(ifp, m);
 #endif /* MAC */
  
 	ETHER_BPF_MTAP(ifp, m);
 	ifp->if_ibytes += m->m_pkthdr.len;
 	ifp->if_ipackets++;
 	if (ifp->if_flags & IFF_MONITOR) {
 		goto drop;
 	}
  
 	if (lagg_input_p) {
 		if (ifp->if_type == IFT_IEEE8023ADLAG) {
 			m = (*lagg_input_p)(ifp, m);
 			if (m != NULL) {
 				ifp = m->m_pkthdr.rcvif;
 			} else { 
 				return;
 			}
 		}
 	}
  
 	if ((m->m_flags & M_VLANTAG) == 0 
 		&& type == ETHERTYPE_VLAN) {
 		struct ether_vlan_header *evl;
  
 		if (m->m_len < sizeof(*evl) 
 		&& (m = m_pullup(m, sizeof(*evl))) == NULL) {
 			goto drop;
 		}
  
 		evl = mtod(m, struct ether_vlan_header *);
 		m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag);
 		m->m_flags |= M_VLANTAG;
  
 		bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
 		    ETHER_HDR_LEN - ETHER_TYPE_LEN);
 		m_adj(m, ETHER_VLAN_ENCAP_LEN);
 	}
  
 	M_SETFIB(m, ifp->if_fib);
  
 	if (ng_ether_input_p) {
 		if (IFP2AC(ifp)->ac_netgraph) {
 			(*ng_ether_input_p)(ifp, &m);
 			if (m == NULL) {
 				return;
 			}
 		}
 	}
  
 	if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) {
 		m->m_flags &= ~M_PROMISC;
 	} else {
 		if (!ETHER_IS_MULTICAST(eh->ether_dhost) 
 		&& bcmp(IF_LLADDR(ifp), eh->ether_dhost, 
 			ETHER_ADDR_LEN) != 0) {
 			m->m_flags |= M_PROMISC;
     	}
 	}
  
 	ether_demux(ifp, m);
 	return;
 drop:
 	ifp->if_ierrors++;
 bad:
 	m_freem(m);
 }
  
 static void
 veth_nh_input(struct mbuf *m)
 {
 	veth_input_internal(m->m_pkthdr.rcvif, m);
 }
  
 static void
 veth_input(struct ifnet *ifp, struct mbuf *m)
 {
 	netisr_dispatch(NETISR_VETH, m);
 }
 
 ------------yPGQsOt2uvF1CxHxvIlgW8--
 

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Thu, 20 Jun 2013 00:28:33 -0000

 /*-
   * Copyright (c) 2013 Henning Matyschok
   * All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
 PURPOSE
   * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  
 CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  
 STRICT
   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY  
 WAY
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
   * Copyright (c) 1982, 1989, 1993
   *	The Regents of the University of California.  All rights reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   * 4. Neither the name of the University nor the names of its contributors
   *    may be used to endorse or promote products derived from this software
   *    without specific prior written permission.
   *
   * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR  
 PURPOSE
   * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR  
 CONSEQUENTIAL
   * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,  
 STRICT
   * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY  
 WAY
   * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   * SUCH DAMAGE.
   *
   */
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/libkern.h>
 #include <sys/socket.h>
 #include <sys/sockio.h>
 
 #include <net/if.h>
 #include <net/if_clone.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/if_var.h>
 #include <net/ethernet.h>
 #include <net/if_bridgevar.h>
 #include <net/if_vlan_var.h>
 #include <net/if_dl.h>
 #include <net/if_arp.h>
 #include <net/bpf.h>
 
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_carp.h>
 
 #ifdef MAC
 #include <security/mac/mac_framework.h>
 #endif /* MAC */
 
 static const uint8_t ether_bcast_lla[ETHER_ADDR_LEN] =
 	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
 
 /* if_lagg(4) entry point. */
 extern struct mbuf	*(*lagg_input_p)(struct ifnet *, struct mbuf *);
 
 /* ng_ether(4) entry point. */
 extern	void	(*ng_ether_input_p)(struct ifnet *, struct mbuf **);
 
 /*
   * Declaration of reduced struct bridge_softc is needed to identify
   * bridge(4) describing ifnet structure on the fly, when veth_start()
   * may called. See net/if_bridge.c and net/if_var.h for further
   * details.
   */
 struct bridge_softc {
 	struct ifnet	*sc_ifp; 	
 };
 
 #define VETHNAME	"veth"
 
 struct veth_softc {
 	struct ifnet	*sc_ifp;
 	LIST_ENTRY(veth_softc) veth_list;
 	struct mtx	sc_mtx;	
 #define	VETH_LOCK_INIT(sc)	mtx_init(&(sc)->sc_mtx, "veth softc",	\
 				     NULL, MTX_DEF)
 #define	VETH_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
 #define	VETH_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
 #define	VETH_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
 #define	VETH_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)	
 	/* Fake information about used transmission media. */
 	struct ifmedia	sc_ifm;	
 	int	sc_status;
 };
 
 static LIST_HEAD(, veth_softc) veth_list;
 
 static struct mtx veth_mtx;
 static MALLOC_DEFINE(M_VETH, VETHNAME, "Virtual ethernet interface");
 
 /* Ifc cloner specific subr.  */
 static int	veth_clone_create(struct if_clone *, int, caddr_t);
 static void	veth_clone_destroy(struct ifnet *);
 
 IFC_SIMPLE_DECLARE(veth, 0);
 
 /* Interface specific methods. */
 static void	veth_init(void *);
 static void	veth_input_internal(struct ifnet *, struct mbuf *);
 static void	veth_input(struct ifnet *, struct mbuf *);
 static int	veth_media_change(struct ifnet *);
 static void	veth_media_status(struct ifnet *ifp, struct ifmediareq *);
 static int	veth_ioctl(struct ifnet *, u_long, caddr_t);
 static void	veth_start(struct ifnet *);
 static void	veth_stop(struct ifnet *, int);
 
 /* See net/netisr.h for further deteils. */
 #define NETISR_VETH	13
 static void	veth_nh_input(struct mbuf *);
 
 /* Netisr handler definition. */
 static struct netisr_handler veth_nh = {
 	.nh_name = VETHNAME,
 	.nh_handler = veth_nh_input,
 	.nh_proto = NETISR_VETH,
 	.nh_policy = NETISR_POLICY_SOURCE,
 	.nh_dispatch = NETISR_DISPATCH_DIRECT,
 };
 
 /*
   * Module event handler.
   */
 static int
 veth_mod_event(module_t mod, int event, void *data)
 {
 	int error = 0;
 
 	switch (event) {
 	case MOD_LOAD:
 
 		mtx_init(&veth_mtx, "if_veth", NULL, MTX_DEF);
 		netisr_register(&veth_nh);
 		if_clone_attach(&veth_cloner);
 		break;
 	case MOD_UNLOAD:	
 
 		if_clone_detach(&veth_cloner);
 		netisr_unregister(&veth_nh);
 		mtx_destroy(&veth_mtx);
 		break;
 	default:
 		error = EOPNOTSUPP;
 	}
 
 	return(error);
 }
 
 static moduledata_t veth_mod = {
 	"if_veth",
 	veth_mod_event,
 	0
 };
 DECLARE_MODULE(if_veth, veth_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
 
 /*
   * Instantiates veth interface.
   */
 static int
 veth_clone_create(struct if_clone *ifc, int unit, caddr_t data)
 {
 	struct veth_softc *sc;
 	struct ifnet *ifp;
 	uint32_t randval;
 	uint8_t	lla[ETHER_ADDR_LEN];
 
 	sc = malloc(sizeof(struct veth_softc), M_VETH, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		free(sc, M_VETH);
 		return(ENOSPC);
 	}
 
 	VETH_LOCK_INIT(sc);
 	ifp->if_softc = sc;
 
 	if_initname(ifp, ifc->ifc_name, unit);
 
 	/* Generates lla with randomized value. */
 	lla[0] = 0x0;
 	randval = arc4random();
 	memcpy(&lla[1], &randval, sizeof(uint32_t));
 	lla[5] = (uint8_t)unit; /* Interface major number */
 
 	ether_ifattach(ifp, lla);
 
 	ifp->if_init = veth_init;
 	ifp->if_input = veth_input;
 	ifp->if_ioctl = veth_ioctl;
 	ifp->if_start = veth_start;
 
 	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_flags = (IFF_SIMPLEX|IFF_BROADCAST|IFF_MULTICAST);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
 
 	ifmedia_init(&sc->sc_ifm, 0, veth_media_change, veth_media_status);
 	ifmedia_add(&sc->sc_ifm, IFM_ETHER|IFM_1000_T|IFM_FDX, 0, NULL);
 	ifmedia_set(&sc->sc_ifm, IFM_ETHER|IFM_1000_T|IFM_FDX);
 
 	sc->sc_status = IFM_AVALID;
 	ifp->if_baudrate = 0;
 
 	mtx_lock(&veth_mtx);
 	LIST_INSERT_HEAD(&veth_list, sc, veth_list);
 	mtx_unlock(&veth_mtx);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 
 	return(0);
 }
 
 /*
   * Destroys veth interface.
   */
 static void
 veth_clone_destroy(struct ifnet *ifp)
 {
 	struct veth_softc *sc;	
 	sc = ifp->if_softc;	
 
 	mtx_lock(&veth_mtx);
 	veth_stop(ifp, 1);
 	ifp->if_flags &= ~IFF_UP;			
 	LIST_REMOVE(sc, veth_list);
 	ether_ifdetach(ifp);
 	VETH_LOCK_DESTROY(sc);
 
 	mtx_unlock(&veth_mtx);
 	free(sc, M_VETH);
 }
 
 static int
 veth_media_change(struct ifnet *ifp)
 {
 	return(0);
 }
 
 static void
 veth_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
 	ifmr->ifm_status = IFM_AVALID|IFM_ACTIVE;
 	ifmr->ifm_active = IFM_ETHER|IFM_1000_T|IFM_FDX;
 }
 
 /*
   * Handles ioctl requests. Media types can't changed,
   * this is a virtual ethernet interface.
   */
 static int
 veth_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct veth_softc *sc = ifp->if_softc;	
 	struct ifreq *ifr = (struct ifreq *)data;
 	int error = 0;
 
 	VETH_LOCK(sc);
 	switch (cmd) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO) {
 			error = EINVAL;
 		} else {
 			ifp->if_mtu = ifr->ifr_mtu;
 		}	
 		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:
 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifm, cmd);
 		break;
 	case SIOCSIFFLAGS:
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		break;
 	case SIOCSIFPHYS:
 		error = EOPNOTSUPP;
 		break;
 	default:
 		error = ether_ioctl(ifp, cmd, data);
 		break;
 	}
 	VETH_UNLOCK(sc);
 	return(error);
 }
 
 /*
   * Initializes veth interface.
   */
 static void
 veth_init(void *xsc)
 {
 	struct veth_softc *sc;
 	struct ifnet *ifp;
 
 	sc = (struct veth_softc *)xsc;
 	ifp = sc->sc_ifp;
 
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		return;
 	}
 
 	VETH_LOCK(sc);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	VETH_UNLOCK(sc);
 }
 
 /*
   * Stops veth interface.
   */
 static void
 veth_stop(struct ifnet *ifp, int disable)
 {
 	struct veth_softc *sc;
 
 	sc = ifp->if_softc;
 	VETH_LOCK_ASSERT(sc);
 
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		return;
 	}
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 }	
 
 /*
   * Dispatches transmissions of queued frames to bridge(4) or to
   * itself when bridge(4) forwarded frames to this interface.
   */
 static void
 veth_start(struct ifnet *ifp)
 {
 	struct mbuf	*m;
 	struct bridge_softc *sc;
 	struct ifnet *bifp;
 
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 	for (;;) {
 		IFQ_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL) {
 			break;
 		}
 
 		if (ifp->if_bridge) {
 			sc = ifp->if_bridge;
 			bifp = sc->sc_ifp;
 
 			if (m->m_pkthdr.rcvif == NULL) {
 				m->m_pkthdr.rcvif = ifp;
                  ETHER_BPF_MTAP(ifp, m);
 				ifp->if_obytes += m->m_pkthdr.len;
 				ifp->if_opackets++;
 				(bifp->if_transmit)(bifp, m);
 			} else if (m->m_pkthdr.rcvif == ifp) {
 				m_freem(m);
 			} else {
 				(ifp->if_input)(ifp, m);	
 			}
 		} else {
 			m_freem(m);
 		}
 	}
 
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
 
 /*
   * Handles input of frames. This method is derived
   * from ether_input_internal() where its implementation
   * remains in net/if_ethersubr.c.
   */
 static void
 veth_input_internal(struct ifnet *ifp, struct mbuf *m)
 {
 	struct ether_header *eh;
 	uint16_t type;
 
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		goto bad;
 	}
 
 	if ((m->m_flags & M_PKTHDR) == 0) {
 		goto drop;
 	}
 
 	if (m->m_len < ETHER_HDR_LEN) {
 		m = m_pullup(m, ETHER_HDR_LEN);
 		if (m == NULL) {
 			goto drop;
 		}
 	}
 
 	eh = mtod(m, struct ether_header *);
 	type = ntohs(eh->ether_type);
 	if (m->m_pkthdr.rcvif == NULL) {
 		goto drop;
 	}
 
 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
 		if (bcmp(ether_bcast_lla, eh->ether_dhost,
 			ETHER_ADDR_LEN) == 0) {
 			m->m_flags |= M_BCAST;
 		} else {
 			m->m_flags |= M_MCAST;
 		}
 		ifp->if_imcasts++;
 	}
 
 #ifdef MAC
 	mac_ifnet_create_mbuf(ifp, m);
 #endif /* MAC */
 
 	ETHER_BPF_MTAP(ifp, m);
 	ifp->if_ibytes += m->m_pkthdr.len;
 	ifp->if_ipackets++;
 	if (ifp->if_flags & IFF_MONITOR) {
 		goto drop;
 	}
 
 	if (lagg_input_p) {
 		if (ifp->if_type == IFT_IEEE8023ADLAG) {
 			m = (*lagg_input_p)(ifp, m);
 			if (m != NULL) {
 				ifp = m->m_pkthdr.rcvif;
 			} else {
 				return;
 			}
 		}
 	}
 
 	if ((m->m_flags & M_VLANTAG) == 0
 		&& type == ETHERTYPE_VLAN) {
 		struct ether_vlan_header *evl;
 
 		if (m->m_len < sizeof(*evl)
 		&& (m = m_pullup(m, sizeof(*evl))) == NULL) {
 			goto drop;
 		}
 
 		evl = mtod(m, struct ether_vlan_header *);
 		m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag);
 		m->m_flags |= M_VLANTAG;
 
 		bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
 		    ETHER_HDR_LEN - ETHER_TYPE_LEN);
 		m_adj(m, ETHER_VLAN_ENCAP_LEN);
 	}
 
 	M_SETFIB(m, ifp->if_fib);
 
 	if (ng_ether_input_p) {
 		if (IFP2AC(ifp)->ac_netgraph) {
 			(*ng_ether_input_p)(ifp, &m);
 			if (m == NULL) {
 				return;
 			}
 		}
 	}
 
 	if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) {
 		m->m_flags &= ~M_PROMISC;
 	} else {
 		if (!ETHER_IS_MULTICAST(eh->ether_dhost)
 		&& bcmp(IF_LLADDR(ifp), eh->ether_dhost,
 			ETHER_ADDR_LEN) != 0) {
 			m->m_flags |= M_PROMISC;
      	        }
 	}
 
 	ether_demux(ifp, m);
 	return;
 drop:
 	ifp->if_ierrors++;
 bad:
 	m_freem(m);
 }
 
 static void
 veth_nh_input(struct mbuf *m)
 {
 	veth_input_internal(m->m_pkthdr.rcvif, m);
 }
 
 static void
 veth_input(struct ifnet *ifp, struct mbuf *m)
 {
 	netisr_dispatch(NETISR_VETH, m);
 }

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Thu, 20 Jun 2013 05:21:20 -0000

 ------------PSPBI3LkwZ7miaxwqpbSiu
 Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 I apologize for my inexperiences of using the pr system and wrong spelling.
 
 After code review, an hour ago, I've realized that there exists a similar  
 implementation of a virtual Ethernet interface by OpenBSD project since  
 2009. In avoidance of misunderstoodings, I've change namespace of source  
 code entirely and added copyright information on top of file.
 ------------PSPBI3LkwZ7miaxwqpbSiu
 Content-Disposition: attachment; filename=if_vether.c.txt
 Content-Type: text/plain; name="if_vether.c.txt"
 Content-Transfer-Encoding: 7bit
 
 /*-
  * Copyright (c) 2013 Henning Matyschok
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 /*
  * Copyright (c) 2009 Theo de Raadt
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/libkern.h>
 #include <sys/socket.h> 
 #include <sys/sockio.h>
  
 #include <net/if.h>
 #include <net/if_clone.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/if_var.h>
 #include <net/ethernet.h>
 #include <net/if_bridgevar.h>
 #include <net/if_vlan_var.h>
 #include <net/if_dl.h>
 #include <net/if_arp.h>
 #include <net/bpf.h>
  
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_carp.h>
  
 static const uint8_t ether_bcast_lla[ETHER_ADDR_LEN] =
 	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  
 /*
  * Declaration of reduced struct bridge_softc is needed to identify 
  * bridge(4) describing ifnet structure on the fly, when frame
  * originates from ng_ether(4).
  * 
  * See net/if_bridge.c and net/if_var.h for further 
  * details.
  */
 struct bridge_softc {
 	struct ifnet	*sc_ifp; 	
 };
  
 #define VETHERNAME	"vether"
  
 struct vether_softc {
 	struct ifnet	*sc_ifp;	/* It will be a network interface. */
 	LIST_ENTRY(vether_softc) vether_list;
 	struct mtx	sc_mtx;	
 #define	VETHER_LOCK_INIT(sc)	mtx_init(&(sc)->sc_mtx, "vether softc",	\
 				     NULL, MTX_DEF)
 #define	VETHER_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
 #define	VETHER_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
 #define	VETHER_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
 #define	VETHER_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)	
 	/* Fake information about used transmission media. */
 	struct ifmedia	sc_ifm;	
 	int	sc_status;
 };
  
 static LIST_HEAD(, vether_softc) vether_list;
  
 static struct mtx vether_mtx;
 static MALLOC_DEFINE(M_VETHER, VETHERNAME, "Virtual ethernet interface");
  
 /* Ifc cloner specific subr.  */
 static int	vether_clone_create(struct if_clone *, int, caddr_t);
 static void	vether_clone_destroy(struct ifnet *);
  
 IFC_SIMPLE_DECLARE(vether, 0);
  
 /* Interface specific methods. */
 static void	vether_init(void *);
 static void	vether_start(struct ifnet *);
 static void	vether_stop(struct ifnet *, int);
 
 static int	vether_media_change(struct ifnet *);
 static void	vether_media_status(struct ifnet *, struct ifmediareq *);
 static int	vether_ioctl(struct ifnet *, u_long, caddr_t);
 
 /*
  * Module event handler.
  */
 static int
 vether_mod_event(module_t mod, int event, void *data)
 {
 	int error = 0;
  
 	switch (event) {
 	case MOD_LOAD:
  
 		mtx_init(&vether_mtx, "if_vether", NULL, MTX_DEF);
 		if_clone_attach(&vether_cloner);
 		break;
 	case MOD_UNLOAD:	
  
 		if_clone_detach(&vether_cloner);
 		mtx_destroy(&vether_mtx);
 		break;
 	default:
 		error = EOPNOTSUPP;
 	}
  
 	return(error);
 } 
  
 static moduledata_t vether_mod = {
 	"if_vether",
 	vether_mod_event,
 	0
 };
 DECLARE_MODULE(if_vether, vether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  
 /*
  * Instantiates vether interface.
  */
 static int
 vether_clone_create(struct if_clone *ifc, int unit, caddr_t data)
 {
 	struct vether_softc *sc;
 	struct ifnet *ifp;
 	uint32_t randval;
 	uint8_t	lla[ETHER_ADDR_LEN];
  
 	sc = malloc(sizeof(struct vether_softc), M_VETHER, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		free(sc, M_VETHER);
 		return(ENOSPC);
 	}
  
 	VETHER_LOCK_INIT(sc);
 	ifp->if_softc = sc;
  
 	if_initname(ifp, ifc->ifc_name, unit);
  
 	/* Generates lla with randomized value. */
 	lla[0] = 0x0;
 	randval = arc4random();
 	memcpy(&lla[1], &randval, sizeof(uint32_t));
 	lla[5] = (uint8_t)unit; /* Interface major number */
  
 	ether_ifattach(ifp, lla);
  
 	ifp->if_init = vether_init;
 	ifp->if_ioctl = vether_ioctl;
 	ifp->if_start = vether_start;
  
 	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_flags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
  
 	ifmedia_init(&sc->sc_ifm, 0, vether_media_change, vether_media_status);
 	ifmedia_add(&sc->sc_ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
 	ifmedia_set(&sc->sc_ifm, IFM_ETHER | IFM_AUTO);
  
 	sc->sc_status = IFM_AVALID;
 	ifp->if_baudrate = 0;
  
 	mtx_lock(&vether_mtx);
 	LIST_INSERT_HEAD(&vether_list, sc, vether_list);
 	mtx_unlock(&vether_mtx);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
  
 	return(0);
 }
 
 /*
  * Destroys vether interface.
  */
 static void
 vether_clone_destroy(struct ifnet *ifp)
 {
 	struct vether_softc *sc;	
 	sc = ifp->if_softc;	
  
 	mtx_lock(&vether_mtx);
 	vether_stop(ifp, 1);
 	ifp->if_flags &= ~IFF_UP;			
 	LIST_REMOVE(sc, vether_list);
 	ether_ifdetach(ifp);
 	VETHER_LOCK_DESTROY(sc);
  
 	mtx_unlock(&vether_mtx);
 	free(sc, M_VETHER);
 }
 
 /*
  * Initializes vether interface.
  */
 static void
 vether_init(void *xsc)
 {
 	struct vether_softc *sc;
 	struct ifnet *ifp;
  
 	sc = (struct vether_softc *)xsc;
 	ifp = sc->sc_ifp;
  
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		return;
 	}
  
 	VETHER_LOCK(sc);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	VETHER_UNLOCK(sc);
 }
 
 /*
  * Stops vether interface.
  */
 static void
 vether_stop(struct ifnet *ifp, int disable)
 {
 	struct vether_softc *sc;
  
 	sc = ifp->if_softc;
 	VETHER_LOCK_ASSERT(sc);
  
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		return;
 	}
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 }	
  
 /*
  * Dispatches transmissions of queued frames to bridge(4) or to
  * itself when bridge(4) forwarded frames to this interface. 
  */
 static void
 vether_start(struct ifnet *ifp)
 {
 	struct mbuf	*m;
 	struct bridge_softc *sc;
 
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 	for (;;) {
 		IFQ_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL) {
 			break;
 		}
  
 		if (ifp->if_bridge) {
 			sc = ifp->if_bridge;
  
 			if (m->m_pkthdr.rcvif == NULL) {
 				m->m_pkthdr.rcvif = ifp;
                 ETHER_BPF_MTAP(ifp, m);
 				ifp->if_obytes += m->m_pkthdr.len;
 				ifp->if_opackets++;
 				(sc->sc_ifp->if_transmit)(sc->sc_ifp, m);
 			} else if (m->m_pkthdr.rcvif == ifp) {
 				m_freem(m);
 			} else {
 				(ifp->if_input)(ifp, m);	
 			} 
 		} else {
 			m_freem(m);
 		}
 	}
  
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
  
 static int
 vether_media_change(struct ifnet *ifp)
 {
 	return(0);
 }
  
 static void
 vether_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
 	ifmr->ifm_active = IFM_ETHER | IFM_AUTO;
 }
  
 /*
  * Handles ioctl requests. Media types can't changed, 
  * this is a virtual ethernet interface.
  */
 static int
 vether_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct vether_softc *sc = ifp->if_softc;	
 	struct ifreq *ifr = (struct ifreq *)data;
 	int error = 0;
  
 	VETHER_LOCK(sc);
 	switch (cmd) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO) {
 			error = EINVAL;
 		} else {
 			ifp->if_mtu = ifr->ifr_mtu;
 		}	
 		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:
 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifm, cmd);
 		break;
 	case SIOCSIFFLAGS:
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		break;
 	case SIOCSIFPHYS:
 		error = EOPNOTSUPP;
 		break;
 	default:
 		error = ether_ioctl(ifp, cmd, data);
 		break;
 	}
 	VETHER_UNLOCK(sc);
 	return(error);
 } 
 
 ------------PSPBI3LkwZ7miaxwqpbSiu--
 

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Thu, 20 Jun 2013 06:22:30 -0000

 ------------oKMi9dqgNjekGU4luIpr2E
 Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 I apologize for this repost. I've changed the source code.
 ------------oKMi9dqgNjekGU4luIpr2E
 Content-Disposition: attachment; filename=if_vether.c.txt
 Content-Type: text/plain; name=if_vether.c.txt
 Content-Transfer-Encoding: 7bit
 
 /*-
  * Copyright (c) 2013 Henning Matyschok
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 /*
  * Copyright (c) 2009 Theo de Raadt
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/socket.h> 
 #include <sys/sockio.h>
  
 #include <net/if.h>
 #include <net/if_clone.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/if_var.h>
 #include <net/ethernet.h>
 #include <net/bpf.h>
  
 /*
  * Declaration of reduced struct bridge_softc is needed to identify 
  * bridge(4) describing ifnet structure on the fly, when frame
  * originates from ng_ether(4).
  * 
  * See net/if_bridge.c and net/if_var.h for further 
  * details.
  */
 struct bridge_softc {
 	struct ifnet	*sc_ifp; 	
 };
  
 #define VETHERNAME	"vether"
  
 struct vether_softc {
 	struct ifnet	*sc_ifp;	/* It will be a network interface. */
 	LIST_ENTRY(vether_softc) vether_list;
 	struct mtx	sc_mtx;	
 #define	VETHER_LOCK_INIT(sc)	mtx_init(&(sc)->sc_mtx, "vether softc",	\
 				     NULL, MTX_DEF)
 #define	VETHER_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
 #define	VETHER_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
 #define	VETHER_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
 #define	VETHER_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)	
 	/* Fake information about used transmission media. */
 	struct ifmedia	sc_ifm;	
 	int	sc_status;
 };
  
 static LIST_HEAD(, vether_softc) vether_list;
  
 static struct mtx vether_mtx;
 static MALLOC_DEFINE(M_VETHER, VETHERNAME, "Virtual ethernet interface");
  
 /* Ifc cloner specific subr.  */
 static int	vether_clone_create(struct if_clone *, int, caddr_t);
 static void	vether_clone_destroy(struct ifnet *);
  
 IFC_SIMPLE_DECLARE(vether, 0);
  
 /* Interface specific methods. */
 static void	vether_init(void *);
 static void	vether_start(struct ifnet *);
 static void	vether_stop(struct ifnet *, int);
 
 static int	vether_media_change(struct ifnet *);
 static void	vether_media_status(struct ifnet *, struct ifmediareq *);
 static int	vether_ioctl(struct ifnet *, u_long, caddr_t);
 
 /*
  * Module event handler.
  */
 static int
 vether_mod_event(module_t mod, int event, void *data)
 {
 	int error = 0;
  
 	switch (event) {
 	case MOD_LOAD:
  
 		mtx_init(&vether_mtx, "if_vether", NULL, MTX_DEF);
 		if_clone_attach(&vether_cloner);
 		break;
 	case MOD_UNLOAD:	
  
 		if_clone_detach(&vether_cloner);
 		mtx_destroy(&vether_mtx);
 		break;
 	default:
 		error = EOPNOTSUPP;
 	}
  
 	return(error);
 } 
  
 static moduledata_t vether_mod = {
 	"if_vether",
 	vether_mod_event,
 	0
 };
 DECLARE_MODULE(if_vether, vether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  
 /*
  * Instantiates vether interface.
  */
 static int
 vether_clone_create(struct if_clone *ifc, int unit, caddr_t data)
 {
 	struct vether_softc *sc;
 	struct ifnet *ifp;
 	uint32_t randval;
 	uint8_t	lla[ETHER_ADDR_LEN];
  
 	sc = malloc(sizeof(struct vether_softc), M_VETHER, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		free(sc, M_VETHER);
 		return(ENOSPC);
 	}
  
 	VETHER_LOCK_INIT(sc);
 	ifp->if_softc = sc;
  
 	if_initname(ifp, ifc->ifc_name, unit);
  
 	/* Generates lla with randomized value. */
 	lla[0] = 0x0;
 	randval = arc4random();
 	memcpy(&lla[1], &randval, sizeof(uint32_t));
 	lla[5] = (uint8_t)unit; /* Interface major number */
  
 	ether_ifattach(ifp, lla);
  
 	ifp->if_init = vether_init;
 	ifp->if_ioctl = vether_ioctl;
 	ifp->if_start = vether_start;
  
 	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_flags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
  
 	ifmedia_init(&sc->sc_ifm, 0, vether_media_change, vether_media_status);
 	ifmedia_add(&sc->sc_ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
 	ifmedia_set(&sc->sc_ifm, IFM_ETHER | IFM_AUTO);
  
 	sc->sc_status = IFM_AVALID;
 	ifp->if_baudrate = 0;
  
 	mtx_lock(&vether_mtx);
 	LIST_INSERT_HEAD(&vether_list, sc, vether_list);
 	mtx_unlock(&vether_mtx);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
  
 	return(0);
 }
 
 /*
  * Destroys vether interface.
  */
 static void
 vether_clone_destroy(struct ifnet *ifp)
 {
 	struct vether_softc *sc;	
 	sc = ifp->if_softc;	
  
 	mtx_lock(&vether_mtx);
 	vether_stop(ifp, 1);
 	ifp->if_flags &= ~IFF_UP;			
 	LIST_REMOVE(sc, vether_list);
 	ether_ifdetach(ifp);
 	VETHER_LOCK_DESTROY(sc);
  
 	mtx_unlock(&vether_mtx);
 	free(sc, M_VETHER);
 }
 
 /*
  * Initializes vether interface.
  */
 static void
 vether_init(void *xsc)
 {
 	struct vether_softc *sc;
 	struct ifnet *ifp;
  
 	sc = (struct vether_softc *)xsc;
 	ifp = sc->sc_ifp;
  
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		return;
 	}
  
 	VETHER_LOCK(sc);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	VETHER_UNLOCK(sc);
 }
 
 /*
  * Stops vether interface.
  */
 static void
 vether_stop(struct ifnet *ifp, int disable)
 {
 	struct vether_softc *sc;
  
 	sc = ifp->if_softc;
 	VETHER_LOCK_ASSERT(sc);
  
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		return;
 	}
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 }	
  
 /*
  * Dispatches transmissions of queued frames to bridge(4) or to
  * itself when bridge(4) forwarded frames to this interface. 
  */
 static void
 vether_start(struct ifnet *ifp)
 {
 	struct mbuf	*m;
 	struct bridge_softc *sc;
 
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 	for (;;) {
 		IFQ_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL) {
 			break;
 		}
  
 		if (ifp->if_bridge) {
 			sc = ifp->if_bridge;
  
 			if (m->m_pkthdr.rcvif == NULL) {
 				m->m_pkthdr.rcvif = ifp;
                 ETHER_BPF_MTAP(ifp, m);
 				ifp->if_obytes += m->m_pkthdr.len;
 				ifp->if_opackets++;
 				(sc->sc_ifp->if_transmit)(sc->sc_ifp, m);
 			} else if (m->m_pkthdr.rcvif == ifp) {
 				m_freem(m);
 			} else {
 				(ifp->if_input)(ifp, m);	
 			} 
 		} else {
 			m_freem(m);
 		}
 	}
  
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
  
 static int
 vether_media_change(struct ifnet *ifp)
 {
 	return(0);
 }
  
 static void
 vether_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
 	ifmr->ifm_active = IFM_ETHER | IFM_AUTO;
 }
  
 /*
  * Handles ioctl requests. Media types can't changed, 
  * this is a virtual ethernet interface.
  */
 static int
 vether_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct vether_softc *sc = ifp->if_softc;	
 	struct ifreq *ifr = (struct ifreq *)data;
 	int error = 0;
  
 	VETHER_LOCK(sc);
 	switch (cmd) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO) {
 			error = EINVAL;
 		} else {
 			ifp->if_mtu = ifr->ifr_mtu;
 		}	
 		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:
 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifm, cmd);
 		break;
 	case SIOCSIFFLAGS:
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		break;
 	case SIOCSIFPHYS:
 		error = EOPNOTSUPP;
 		break;
 	default:
 		error = ether_ioctl(ifp, cmd, data);
 		break;
 	}
 	VETHER_UNLOCK(sc);
 	return(error);
 } 
 
 ------------oKMi9dqgNjekGU4luIpr2E--
 

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Thu, 20 Jun 2013 16:21:19 -0000

 ------------vvLriZts3VI7yX6XiRHp05
 Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 I apologize for my chaotic mutiple postings. I've rethought current  
 implementation.
 ------------vvLriZts3VI7yX6XiRHp05
 Content-Disposition: attachment; filename=if_vether.c.txt
 Content-Type: text/plain; name=if_vether.c.txt
 Content-Transfer-Encoding: 7bit
 
 /*-
  * Copyright (c) 2013 Henning Matyschok
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  *
  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 /*
  * Copyright (c) 2009 Theo de Raadt
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
  * copyright notice and this permission notice appear in all copies.
  *
  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
 /*- 
  * Copyright (c) 1982, 1989, 1993
  *	The Regents of the University of California.  All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 1. Redistributions of source code must retain the above copyright
  *    notice, this list of conditions and the following disclaimer.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
  */
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/libkern.h>
 #include <sys/socket.h> 
 #include <sys/sockio.h>
  
 #include <net/if.h>
 #include <net/if_clone.h>
 #include <net/if_media.h>
 #include <net/if_types.h>
 #include <net/netisr.h>
 #include <net/if_var.h>
 #include <net/ethernet.h>
 #include <net/if_bridgevar.h>
 #include <net/if_vlan_var.h>
 #include <net/if_dl.h>
 #include <net/if_arp.h>
 #include <net/bpf.h>
  
 #include <netinet/in.h>
 #include <netinet/in_var.h>
 #include <netinet/ip_carp.h>
  
 #ifdef MAC
 #include <security/mac/mac_framework.h>
 #endif /* MAC */
  
 static const uint8_t ether_bcast_lla[ETHER_ADDR_LEN] =
 	{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  
 /* if_lagg(4) entry point. */
 extern struct mbuf	*(*lagg_input_p)(struct ifnet *, struct mbuf *); 
  
 /* ng_ether(4) entry point. */
 extern	void	(*ng_ether_input_p)(struct ifnet *, struct mbuf **);
 
 /*
  * Declaration of reduced struct bridge_softc is needed to identify 
  * bridge(4) describing ifnet structure on the fly, when frame
  * originates from ng_ether(4).
  * 
  * See net/if_bridge.c and net/if_var.h for further 
  * details.
  */
 struct bridge_softc {
 	struct ifnet	*sc_ifp; 	
 };
  
 #define VETHERNAME	"vether"
  
 struct vether_softc {
 	struct ifnet	*sc_ifp;	/* It will be a network interface. */
 	LIST_ENTRY(vether_softc) vether_list;
 	struct mtx	sc_mtx;	
 #define	VETHER_LOCK_INIT(sc)	mtx_init(&(sc)->sc_mtx, "vether softc",	\
 				     NULL, MTX_DEF)
 #define	VETHER_LOCK_DESTROY(sc)	mtx_destroy(&(sc)->sc_mtx)
 #define	VETHER_LOCK(sc)		mtx_lock(&(sc)->sc_mtx)
 #define	VETHER_UNLOCK(sc)		mtx_unlock(&(sc)->sc_mtx)
 #define	VETHER_LOCK_ASSERT(sc)	mtx_assert(&(sc)->sc_mtx, MA_OWNED)	
 	/* Fake information about used transmission media. */
 	struct ifmedia	sc_ifm;	
 	int	sc_status;
 };
  
 static LIST_HEAD(, vether_softc) vether_list;
  
 static struct mtx vether_mtx;
 static MALLOC_DEFINE(M_VETHER, VETHERNAME, "Virtual Ethernet interface");
  
 /* Ifc cloner specific subr.  */
 static int	vether_clone_create(struct if_clone *, int, caddr_t);
 static void	vether_clone_destroy(struct ifnet *);
  
 IFC_SIMPLE_DECLARE(vether, 0);
  
 /* Interface specific methods. */
 static void	vether_init(void *);
 static void	vether_start(struct ifnet *);
 static void	vether_stop(struct ifnet *, int);
 static void	vether_input_internal(struct ifnet *, struct mbuf *);
 static void	vether_input(struct ifnet *, struct mbuf *);
 
 static int	vether_media_change(struct ifnet *);
 static void	vether_media_status(struct ifnet *, struct ifmediareq *);
 static int	vether_ioctl(struct ifnet *, u_long, caddr_t);
 
 /* See net/netisr.h for further deteils. */
 #define NETISR_VETHER	13
 static void	vether_nh_input(struct mbuf *);
  
 /* Netisr handler definition. */
 static struct netisr_handler vether_nh = {
 	.nh_name = VETHERNAME,
 	.nh_handler = vether_nh_input,
 	.nh_proto = NETISR_VETHER,
 	.nh_policy = NETISR_POLICY_SOURCE,
 	.nh_dispatch = NETISR_DISPATCH_DIRECT,
 };
 
 /*
  * Module event handler.
  */
 static int
 vether_mod_event(module_t mod, int event, void *data)
 {
 	int error = 0;
  
 	switch (event) {
 	case MOD_LOAD:
  
 		mtx_init(&vether_mtx, "if_vether", NULL, MTX_DEF);
 		netisr_register(&vether_nh);
 		if_clone_attach(&vether_cloner);
 		break;
 	case MOD_UNLOAD:	
  
 		if_clone_detach(&vether_cloner);
 		netisr_unregister(&vether_nh);
 		mtx_destroy(&vether_mtx);
 		break;
 	default:
 		error = EOPNOTSUPP;
 	}
  
 	return(error);
 } 
  
 static moduledata_t vether_mod = {
 	"if_vether",
 	vether_mod_event,
 	0
 };
 DECLARE_MODULE(if_vether, vether_mod, SI_SUB_PSEUDO, SI_ORDER_ANY);
  
 /*
  * Instantiates vether interface.
  */
 static int
 vether_clone_create(struct if_clone *ifc, int unit, caddr_t data)
 {
 	struct vether_softc *sc;
 	struct ifnet *ifp;
 	uint32_t randval;
 	uint8_t	lla[ETHER_ADDR_LEN];
  
 	sc = malloc(sizeof(struct vether_softc), M_VETHER, M_WAITOK|M_ZERO);
 	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		free(sc, M_VETHER);
 		return(ENOSPC);
 	}
  
 	VETHER_LOCK_INIT(sc);
 	ifp->if_softc = sc;
  
 	if_initname(ifp, ifc->ifc_name, unit);
  
 	/* Generates lla with randomized value. */
 	lla[0] = 0x0;
 	randval = arc4random();
 	memcpy(&lla[1], &randval, sizeof(uint32_t));
 	lla[5] = (uint8_t)unit; /* Interface major number */
  
 	ether_ifattach(ifp, lla);
  
 	ifp->if_init = vether_init;
 	ifp->if_input = vether_input;
 	ifp->if_ioctl = vether_ioctl;
 	ifp->if_start = vether_start;
  
 	ifp->if_capabilities = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_capenable = IFCAP_VLAN_MTU | IFCAP_JUMBO_MTU;
 	ifp->if_flags = (IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST);
 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
  
 	ifmedia_init(&sc->sc_ifm, 0, vether_media_change, vether_media_status);
 	ifmedia_add(&sc->sc_ifm, IFM_ETHER | IFM_AUTO, 0, NULL);
 	ifmedia_set(&sc->sc_ifm, IFM_ETHER | IFM_AUTO);
  
 	sc->sc_status = IFM_AVALID;
 	ifp->if_baudrate = 0;
  
 	mtx_lock(&vether_mtx);
 	LIST_INSERT_HEAD(&vether_list, sc, vether_list);
 	mtx_unlock(&vether_mtx);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
  
 	return(0);
 }
 
 /*
  * Destroys vether interface.
  */
 static void
 vether_clone_destroy(struct ifnet *ifp)
 {
 	struct vether_softc *sc;	
 	sc = ifp->if_softc;	
  
 	mtx_lock(&vether_mtx);
 	vether_stop(ifp, 1);
 	ifp->if_flags &= ~IFF_UP;			
 	LIST_REMOVE(sc, vether_list);
 	ether_ifdetach(ifp);
 	VETHER_LOCK_DESTROY(sc);
  
 	mtx_unlock(&vether_mtx);
 	free(sc, M_VETHER);
 }
 
 /*
  * Initializes vether interface.
  */
 static void
 vether_init(void *xsc)
 {
 	struct vether_softc *sc;
 	struct ifnet *ifp;
  
 	sc = (struct vether_softc *)xsc;
 	ifp = sc->sc_ifp;
  
 	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
 		return;
 	}
  
 	VETHER_LOCK(sc);
 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 	VETHER_UNLOCK(sc);
 }
 
 /*
  * Stops vether interface.
  */
 static void
 vether_stop(struct ifnet *ifp, int disable)
 {
 	struct vether_softc *sc;
  
 	sc = ifp->if_softc;
 	VETHER_LOCK_ASSERT(sc);
  
 	if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
 		return;
 	}
 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
 }	
  
 /*
  * Dispatches transmissions of queued frames to bridge(4) or to
  * itself when bridge(4) forwarded frames to this interface. 
  */
 static void
 vether_start(struct ifnet *ifp)
 {
 	struct mbuf	*m;
 	struct bridge_softc *sc;
 
 	ifp->if_drv_flags |= IFF_DRV_OACTIVE;
 	for (;;) {
 		IFQ_DEQUEUE(&ifp->if_snd, m);
 		if (m == NULL) {
 			break;
 		}
  
 		if (ifp->if_bridge) {
 			sc = ifp->if_bridge;
  
 			if (m->m_pkthdr.rcvif == NULL) {
 				m->m_pkthdr.rcvif = ifp;
                 ETHER_BPF_MTAP(ifp, m);
 				ifp->if_obytes += m->m_pkthdr.len;
 				ifp->if_opackets++;
 				(sc->sc_ifp->if_transmit)(sc->sc_ifp, m);
 			} else if (m->m_pkthdr.rcvif == ifp) {
 				m_freem(m);
 			} else {
 				(ifp->if_input)(ifp, m);	
 			} 
 		} else {
 			m_freem(m);
 		}
 	}
  
 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
 }
 
 /*
  * Handles input of frames. This method is derived 
  * from ether_input_internal() where its implementation 
  * remains in net/if_ethersubr.c. 
  */
 static void
 vether_input_internal(struct ifnet *ifp, struct mbuf *m)
 {
 	struct ether_header *eh;
 	uint16_t type;
  
 	if ((ifp->if_flags & IFF_UP) == 0) {
 		goto bad;
 	}
  
 	if ((m->m_flags & M_PKTHDR) == 0) {
 		goto drop;
 	}
  
 	if (m->m_len < ETHER_HDR_LEN) {
 		m = m_pullup(m, ETHER_HDR_LEN);
 		if (m == NULL) {
 			goto drop;
 		}
 	}
  
 	eh = mtod(m, struct ether_header *);
 	type = ntohs(eh->ether_type);
 	if (m->m_pkthdr.rcvif == NULL) {
 		goto drop;
 	}
  
 	if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
 		if (bcmp(ether_bcast_lla, eh->ether_dhost, 
 			ETHER_ADDR_LEN) == 0) {
 			m->m_flags |= M_BCAST;
 		} else {
 			m->m_flags |= M_MCAST;
 		}
 		ifp->if_imcasts++;
 	}
  
 #ifdef MAC
 	mac_ifnet_create_mbuf(ifp, m);
 #endif /* MAC */
  
 	ETHER_BPF_MTAP(ifp, m);
 	ifp->if_ibytes += m->m_pkthdr.len;
 	ifp->if_ipackets++;
 	if (ifp->if_flags & IFF_MONITOR) {
 		goto drop;
 	}
  
 	if (lagg_input_p) {
 		if (ifp->if_type == IFT_IEEE8023ADLAG) {
 			m = (*lagg_input_p)(ifp, m);
 			if (m != NULL) {
 				ifp = m->m_pkthdr.rcvif;
 			} else { 
 				return;
 			}
 		}
 	}
  
 	if ((m->m_flags & M_VLANTAG) == 0 
 		&& type == ETHERTYPE_VLAN) {
 		struct ether_vlan_header *evl;
  
 		if (m->m_len < sizeof(*evl) 
 		&& (m = m_pullup(m, sizeof(*evl))) == NULL) {
 			goto drop;
 		}
  
 		evl = mtod(m, struct ether_vlan_header *);
 		m->m_pkthdr.ether_vtag = ntohs(evl->evl_tag);
 		m->m_flags |= M_VLANTAG;
  
 		bcopy((char *)evl, (char *)evl + ETHER_VLAN_ENCAP_LEN,
 		    ETHER_HDR_LEN - ETHER_TYPE_LEN);
 		m_adj(m, ETHER_VLAN_ENCAP_LEN);
 	}
  
 	M_SETFIB(m, ifp->if_fib);
  
 	if (ng_ether_input_p) {
 		if (IFP2AC(ifp)->ac_netgraph) {
 			(*ng_ether_input_p)(ifp, &m);
 			if (m == NULL) {
 				return;
 			}
 		}
 	}
  
 	if (ifp->if_carp && (*carp_forus_p)(ifp, eh->ether_dhost)) {
 		m->m_flags &= ~M_PROMISC;
 	} else {
 		if (!ETHER_IS_MULTICAST(eh->ether_dhost) 
 		&& bcmp(IF_LLADDR(ifp), eh->ether_dhost, 
 			ETHER_ADDR_LEN) != 0) {
 			m->m_flags |= M_PROMISC;
     	        }
 	}
  
 	ether_demux(ifp, m);
 	return;
 drop:
 	ifp->if_ierrors++;
 bad:
 	m_freem(m);
 }
  
 static void
 vether_nh_input(struct mbuf *m)
 {
 	vether_input_internal(m->m_pkthdr.rcvif, m);
 } 
  
 static void
 vether_input(struct ifnet *ifp, struct mbuf *m)
 {
 	netisr_dispatch(NETISR_VETHER, m);
 }
 
 /*
  * Handles ioctl requests. Media types can't changed, 
  * this is a virtual ethernet interface.
  */
 static int
 vether_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
 {
 	struct vether_softc *sc = ifp->if_softc;	
 	struct ifreq *ifr = (struct ifreq *)data;
 	int error = 0;
  
 	VETHER_LOCK(sc);
 	switch (cmd) {
 	case SIOCSIFMTU:
 		if (ifr->ifr_mtu > ETHER_MAX_LEN_JUMBO) {
 			error = EINVAL;
 		} else {
 			ifp->if_mtu = ifr->ifr_mtu;
 		}	
 		break;
 	case SIOCSIFMEDIA:
 	case SIOCGIFMEDIA:
 		error = ifmedia_ioctl(ifp, ifr, &sc->sc_ifm, cmd);
 		break;
 	case SIOCSIFFLAGS:
 	case SIOCADDMULTI:
 	case SIOCDELMULTI:
 		break;
 	case SIOCSIFPHYS:
 		error = EOPNOTSUPP;
 		break;
 	default:
 		error = ether_ioctl(ifp, cmd, data);
 		break;
 	}
 	VETHER_UNLOCK(sc);
 	return(error);
 } 
 
 static int
 vether_media_change(struct ifnet *ifp)
 {
 	return(0);
 }
  
 static void
 vether_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
 {
 	ifmr->ifm_active = IFM_ETHER | IFM_AUTO;
 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE;
 }
 
 ------------vvLriZts3VI7yX6XiRHp05--
 

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Mon, 19 Aug 2013 05:32:16 -0000

 ------------5OCVZbrxpul0dnsDsZO7pQ
 Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 
 
 -- 
 Using Opera's mail client: http://www.opera.com/mail/
 ------------5OCVZbrxpul0dnsDsZO7pQ
 Content-Disposition: attachment; filename=if_vether.c
 Content-Type: application/octet-stream; name=if_vether.c
 Content-Transfer-Encoding: Base64
 
 LyotCiAqIENvcHlyaWdodCAoYykgMjAxMyBIZW5uaW5nIE1hdHlzY2hvawogKiBB
 bGwgcmlnaHRzIHJlc2VydmVkLgogKgogKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNl
 IGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKICog
 bW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZv
 bGxvd2luZyBjb25kaXRpb25zCiAqIGFyZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0
 aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUgYWJvdmUgY29weXJp
 Z2h0CiAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRo
 ZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4KICogMi4gUmVkaXN0cmlidXRpb25zIGlu
 IGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQK
 ICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZv
 bGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZQogKiAgICBkb2N1bWVudGF0aW9uIGFu
 ZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0
 aW9uLgogKgogKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRI
 T1IgQU5EIENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECiAqIEFOWSBFWFBSRVNT
 IE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlU
 RUQgVE8sIFRIRQogKiBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklM
 SVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUg
 RElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09O
 VFJJQlVUT1JTIEJFIExJQUJMRQogKiBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1Qs
 IElOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElB
 TAogKiBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJP
 Q1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUwogKiBPUiBTRVJWSUNFUzsgTE9T
 UyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQ
 VElPTikKICogSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWSBUSEVPUlkgT0YgTElB
 QklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QKICogTElBQklMSVRZ
 LCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFS
 SVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRX
 QVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCiAqIFNV
 Q0ggREFNQUdFLgogKgogKi8KLyoKICogQ29weXJpZ2h0IChjKSAyMDA5IFRoZW8g
 ZGUgUmFhZHQKICoKICogUGVybWlzc2lvbiB0byB1c2UsIGNvcHksIG1vZGlmeSwg
 YW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0d2FyZSBmb3IgYW55CiAqIHB1cnBvc2Ug
 d2l0aCBvciB3aXRob3V0IGZlZSBpcyBoZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQg
 dGhhdCB0aGUgYWJvdmUKICogY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJt
 aXNzaW9uIG5vdGljZSBhcHBlYXIgaW4gYWxsIGNvcGllcy4KICoKICogVEhFIFNP
 RlRXQVJFIElTIFBST1ZJREVEICJBUyBJUyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xB
 SU1TIEFMTCBXQVJSQU5USUVTCiAqIFdJVEggUkVHQVJEIFRPIFRISVMgU09GVFdB
 UkUgSU5DTFVESU5HIEFMTCBJTVBMSUVEIFdBUlJBTlRJRVMgT0YKICogTUVSQ0hB
 TlRBQklMSVRZIEFORCBGSVRORVNTLiBJTiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVU
 SE9SIEJFIExJQUJMRSBGT1IKICogQU5ZIFNQRUNJQUwsIERJUkVDVCwgSU5ESVJF
 Q1QsIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyBPUiBBTlkgREFNQUdFUwogKiBX
 SEFUU09FVkVSIFJFU1VMVElORyBGUk9NIExPU1MgT0YgVVNFLCBEQVRBIE9SIFBS
 T0ZJVFMsIFdIRVRIRVIgSU4gQU4KICogQUNUSU9OIE9GIENPTlRSQUNULCBORUdM
 SUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YK
 ICogT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBVU0UgT1IgUEVSRk9STUFOQ0Ug
 T0YgVEhJUyBTT0ZUV0FSRS4KICovCiNpbmNsdWRlIDxzeXMvcGFyYW0uaD4KI2lu
 Y2x1ZGUgPHN5cy9rZXJuZWwuaD4KI2luY2x1ZGUgPHN5cy9tb2R1bGUuaD4KI2lu
 Y2x1ZGUgPHN5cy9saWJrZXJuLmg+CiNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+IAoj
 aW5jbHVkZSA8c3lzL3NvY2tpby5oPgogCiNpbmNsdWRlIDxuZXQvaWYuaD4KI2lu
 Y2x1ZGUgPG5ldC9pZl9jbG9uZS5oPgojaW5jbHVkZSA8bmV0L2lmX21lZGlhLmg+
 CiNpbmNsdWRlIDxuZXQvaWZfdHlwZXMuaD4KCiNpbmNsdWRlIDxuZXQvZXRoZXJu
 ZXQuaD4KI2luY2x1ZGUgPG5ldC9pZl9icmlkZ2V2YXIuaD4KCiNkZWZpbmUgVkVU
 SEVSTkFNRQkidmV0aGVyIgogCnN0cnVjdCB2ZXRoZXJfc29mdGMgewoJc3RydWN0
 IGlmbmV0CSpzY19pZnA7CS8qIE5ldHdvcmsgaW50ZXJmYWNlLiAqLwoJTElTVF9F
 TlRSWSh2ZXRoZXJfc29mdGMpIHZldGhlcl9saXN0OwoJc3RydWN0IG10eAlzY19t
 dHg7CQojZGVmaW5lCVZFVEhFUl9MT0NLX0lOSVQoc2MpCW10eF9pbml0KCYoc2Mp
 LT5zY19tdHgsICJ2ZXRoZXIgc29mdGMiLAlcCgkJCQkgICAgIE5VTEwsIE1UWF9E
 RUYpCiNkZWZpbmUJVkVUSEVSX0xPQ0tfREVTVFJPWShzYykJbXR4X2Rlc3Ryb3ko
 JihzYyktPnNjX210eCkKI2RlZmluZQlWRVRIRVJfTE9DSyhzYykJCW10eF9sb2Nr
 KCYoc2MpLT5zY19tdHgpCiNkZWZpbmUJVkVUSEVSX1VOTE9DSyhzYykJCW10eF91
 bmxvY2soJihzYyktPnNjX210eCkKI2RlZmluZQlWRVRIRVJfTE9DS19BU1NFUlQo
 c2MpCW10eF9hc3NlcnQoJihzYyktPnNjX210eCwgTUFfT1dORUQpCQoJLyogRmFr
 ZSBpbmZvcm1hdGlvbiBhYm91dCB0cmFuc21pc3Npb24gbWVkaWEuICovCglzdHJ1
 Y3QgaWZtZWRpYQlzY19pZm07CQoJaW50CXNjX3N0YXR1czsKfTsKCnN0YXRpYyBM
 SVNUX0hFQUQoLCB2ZXRoZXJfc29mdGMpIHZldGhlcl9saXN0OwogCnN0YXRpYyBz
 dHJ1Y3QgbXR4IHZldGhlcl9tdHg7CnN0YXRpYyBNQUxMT0NfREVGSU5FKE1fVkVU
 SEVSLCBWRVRIRVJOQU1FLCAiVmlydHVhbCBFdGhlcm5ldCBpbnRlcmZhY2UiKTsK
 IApzdGF0aWMgaW50CXZldGhlcl9jbG9uZV9jcmVhdGUoc3RydWN0IGlmX2Nsb25l
 ICosIGludCwgY2FkZHJfdCk7CnN0YXRpYyB2b2lkCXZldGhlcl9jbG9uZV9kZXN0
 cm95KHN0cnVjdCBpZm5ldCAqKTsKIApJRkNfU0lNUExFX0RFQ0xBUkUodmV0aGVy
 LCAwKTsKCnN0YXRpYyB2b2lkCXZldGhlcl9pbml0KHZvaWQgKik7CnN0YXRpYyB2
 b2lkCXZldGhlcl9zdG9wKHN0cnVjdCBpZm5ldCAqLCBpbnQpOwpzdGF0aWMgdm9p
 ZAl2ZXRoZXJfc3RhcnRfbG9ja2VkKHN0cnVjdCBpZm5ldCAqKTsKc3RhdGljIHZv
 aWQJdmV0aGVyX3N0YXJ0KHN0cnVjdCBpZm5ldCAqKTsKCnN0YXRpYyBpbnQJdmV0
 aGVyX21lZGlhX2NoYW5nZShzdHJ1Y3QgaWZuZXQgKik7CnN0YXRpYyB2b2lkCXZl
 dGhlcl9tZWRpYV9zdGF0dXMoc3RydWN0IGlmbmV0ICosIHN0cnVjdCBpZm1lZGlh
 cmVxICopOwpzdGF0aWMgaW50CXZldGhlcl9pb2N0bChzdHJ1Y3QgaWZuZXQgKiwg
 dV9sb25nLCBjYWRkcl90KTsKCi8qCiAqIEluc3RhbnRpYXRlcyB2ZXRoZXIgaW50
 ZXJmYWNlLgogKi8Kc3RhdGljIGludAp2ZXRoZXJfY2xvbmVfY3JlYXRlKHN0cnVj
 dCBpZl9jbG9uZSAqaWZjLCBpbnQgdW5pdCwgY2FkZHJfdCBkYXRhKQp7CglzdHJ1
 Y3QgdmV0aGVyX3NvZnRjICpzYzsKCXN0cnVjdCBpZm5ldCAqaWZwOwoJdWludDMy
 X3QgcmFuZHZhbDsKCXVpbnQ4X3QJbGxhW0VUSEVSX0FERFJfTEVOXTsKIAoJc2Mg
 PSBtYWxsb2Moc2l6ZW9mKHN0cnVjdCB2ZXRoZXJfc29mdGMpLCBNX1ZFVEhFUiwg
 TV9XQUlUT0t8TV9aRVJPKTsKCWlmcCA9IHNjLT5zY19pZnAgPSBpZl9hbGxvYyhJ
 RlRfRVRIRVIpOwoJaWYgKGlmcCA9PSBOVUxMKSB7CgkJZnJlZShzYywgTV9WRVRI
 RVIpOwoJCXJldHVybihFTk9TUEMpOwoJfQogCglWRVRIRVJfTE9DS19JTklUKHNj
 KTsKCWlmcC0+aWZfc29mdGMgPSBzYzsKIAoJaWZfaW5pdG5hbWUoaWZwLCBpZmMt
 PmlmY19uYW1lLCB1bml0KTsKIAoJLyogR2VuZXJhdGVzIGxsYSB3aXRoIHJhbmRv
 bWl6ZWQgdmFsdWUuICovCglsbGFbMF0gPSAweDA7CglyYW5kdmFsID0gYXJjNHJh
 bmRvbSgpOwoJbWVtY3B5KCZsbGFbMV0sICZyYW5kdmFsLCBzaXplb2YodWludDMy
 X3QpKTsKCWxsYVs1XSA9ICh1aW50OF90KXVuaXQ7IC8qIEludGVyZmFjZSBtYWpv
 ciBudW1iZXIgKi8KIAoJZXRoZXJfaWZhdHRhY2goaWZwLCBsbGEpOwogCglpZnAt
 PmlmX2luaXQgPSB2ZXRoZXJfaW5pdDsKCWlmcC0+aWZfaW9jdGwgPSB2ZXRoZXJf
 aW9jdGw7CglpZnAtPmlmX3N0YXJ0ID0gdmV0aGVyX3N0YXJ0OwogCglpZnAtPmlm
 X2NhcGFiaWxpdGllcyA9IElGQ0FQX1ZMQU5fTVRVIHwgSUZDQVBfSlVNQk9fTVRV
 OwoJaWZwLT5pZl9jYXBlbmFibGUgPSBJRkNBUF9WTEFOX01UVSB8IElGQ0FQX0pV
 TUJPX01UVTsKCWlmcC0+aWZfZmxhZ3MgPSAoSUZGX1NJTVBMRVggfCBJRkZfQlJP
 QURDQVNUIHwgSUZGX01VTFRJQ0FTVCk7CglpZnAtPmlmX3NuZC5pZnFfbWF4bGVu
 ID0gaWZxbWF4bGVuOwogCglpZm1lZGlhX2luaXQoJnNjLT5zY19pZm0sIDAsIHZl
 dGhlcl9tZWRpYV9jaGFuZ2UsIHZldGhlcl9tZWRpYV9zdGF0dXMpOwoJaWZtZWRp
 YV9hZGQoJnNjLT5zY19pZm0sIElGTV9FVEhFUiB8IElGTV9BVVRPLCAwLCBOVUxM
 KTsKCWlmbWVkaWFfc2V0KCZzYy0+c2NfaWZtLCBJRk1fRVRIRVIgfCBJRk1fQVVU
 Tyk7CiAKCXNjLT5zY19zdGF0dXMgPSBJRk1fQVZBTElEOwoJaWZwLT5pZl9iYXVk
 cmF0ZSA9IDA7CiAKCW10eF9sb2NrKCZ2ZXRoZXJfbXR4KTsKCUxJU1RfSU5TRVJU
 X0hFQUQoJnZldGhlcl9saXN0LCBzYywgdmV0aGVyX2xpc3QpOwoJbXR4X3VubG9j
 aygmdmV0aGVyX210eCk7CglpZnAtPmlmX2Rydl9mbGFncyB8PSBJRkZfRFJWX1JV
 Tk5JTkc7CiAKCXJldHVybigwKTsKfQogCi8qCiAqIERlc3Ryb3lzIHZldGhlciBp
 bnRlcmZhY2UuCiAqLwpzdGF0aWMgdm9pZAp2ZXRoZXJfY2xvbmVfZGVzdHJveShz
 dHJ1Y3QgaWZuZXQgKmlmcCkKewoJc3RydWN0IHZldGhlcl9zb2Z0YyAqc2M7CQoJ
 c2MgPSBpZnAtPmlmX3NvZnRjOwkKIAoJbXR4X2xvY2soJnZldGhlcl9tdHgpOwoJ
 dmV0aGVyX3N0b3AoaWZwLCAxKTsKCWlmcC0+aWZfZmxhZ3MgJj0gfklGRl9VUDsJ
 CQkKCUxJU1RfUkVNT1ZFKHNjLCB2ZXRoZXJfbGlzdCk7CglldGhlcl9pZmRldGFj
 aChpZnApOwoJVkVUSEVSX0xPQ0tfREVTVFJPWShzYyk7CiAKCW10eF91bmxvY2so
 JnZldGhlcl9tdHgpOwoJZnJlZShzYywgTV9WRVRIRVIpOwp9CiAKLyoKICogSW5p
 dGlhbGl6ZXMgdmV0aGVyIGludGVyZmFjZS4KICovCnN0YXRpYyB2b2lkCnZldGhl
 cl9pbml0KHZvaWQgKnhzYykKewoJc3RydWN0IHZldGhlcl9zb2Z0YyAqc2M7Cglz
 dHJ1Y3QgaWZuZXQgKmlmcDsKIAogCXNjID0gKHN0cnVjdCB2ZXRoZXJfc29mdGMg
 Kil4c2M7CglWRVRIRVJfTE9DSyhzYyk7CglpZnAgPSBzYy0+c2NfaWZwOwoJaWZw
 LT5pZl9kcnZfZmxhZ3MgfD0gSUZGX0RSVl9SVU5OSU5HOwoJaWZwLT5pZl9kcnZf
 ZmxhZ3MgJj0gfklGRl9EUlZfT0FDVElWRTsKCVZFVEhFUl9VTkxPQ0soc2MpOwp9
 CiAKLyoKICogU3RvcHMgdmV0aGVyIGludGVyZmFjZS4KICovCnN0YXRpYyB2b2lk
 CnZldGhlcl9zdG9wKHN0cnVjdCBpZm5ldCAqaWZwLCBpbnQgZGlzYWJsZSkKewoJ
 c3RydWN0IHZldGhlcl9zb2Z0YyAqc2M7CgkKCXNjID0gaWZwLT5pZl9zb2Z0YzsK
 CVZFVEhFUl9MT0NLX0FTU0VSVChzYyk7CglpZnAtPmlmX2Rydl9mbGFncyAmPSB+
 SUZGX0RSVl9SVU5OSU5HOwp9CQogCi8qCiAqIFN0YXJ0cyB0cmFuc21pc3Npb24u
 CiAqLwpzdGF0aWMgdm9pZAp2ZXRoZXJfc3RhcnQoc3RydWN0IGlmbmV0ICppZnAp
 CnsKCXN0cnVjdCB2ZXRoZXJfc29mdGMJKnNjOwoKCXNjID0gaWZwLT5pZl9zb2Z0
 YzsKCVZFVEhFUl9MT0NLKHNjKTsKCXZldGhlcl9zdGFydF9sb2NrZWQoaWZwKTsK
 CVZFVEhFUl9VTkxPQ0soc2MpOwp9CgpzdGF0aWMgdm9pZAp2ZXRoZXJfc3RhcnRf
 bG9ja2VkKHN0cnVjdCBpZm5ldCAqaWZwKQp7CglzdHJ1Y3QgdmV0aGVyX3NvZnRj
 CSpzYzsKCXN0cnVjdCBtYnVmICptOwoKCXNjID0gaWZwLT5pZl9zb2Z0YzsKCVZF
 VEhFUl9MT0NLX0FTU0VSVChzYyk7CgoJaWZwLT5pZl9kcnZfZmxhZ3MgfD0gSUZG
 X0RSVl9PQUNUSVZFOwoJCglmb3IgKDs7KSB7CgkJSUZRX0RFUVVFVUUoJmlmcC0+
 aWZfc25kLCBtKTsKCQlpZiAobSA9PSBOVUxMKSAKCQkJYnJlYWs7CgkJCiAJCWlm
 IChpZnAtPmlmX2JyaWRnZSA9PSBOVUxMKSB7CgkJCW1fZnJlZW0obSk7CgkJCWNv
 bnRpbnVlOwoJCX0KCQoJCWlmIChtLT5tX2ZsYWdzICYgTV9QUk9UTzEpIHsKCQkJ
 bV9mcmVlbShtKTsKCQkJY29udGludWU7CQkgCQkKCQl9CgkJCgkJaWYgKG0tPm1f
 cGt0aGRyLnJjdmlmID09IE5VTEwpIHsKCQkJbS0+bV9mbGFncyB8PSBNX1BST1RP
 MTsKCQkJbS0+bV9mbGFncyAmPSB+TV9QUk9NSVNDOwoJCQltLT5tX3BrdGhkci5y
 Y3ZpZiA9IGlmcC0+aWZfYnJpZGdlOwoJCgkJCSh2b2lkKShicmlkZ2Vfb3V0cHV0
 X3ApKGlmcCwgbSwgTlVMTCwgTlVMTCk7CQkKIAkJfSBlbHNlIAogCQkJbV9mcmVl
 bShtKTsKCX0KCQkJCQkKCWlmcC0+aWZfZHJ2X2ZsYWdzICY9IH5JRkZfRFJWX09B
 Q1RJVkU7Cn0KCi8qCiAqIE1lZGlhIHR5cGVzIGNhbid0IGNoYW5nZWQuCiAqLwpz
 dGF0aWMgaW50CnZldGhlcl9pb2N0bChzdHJ1Y3QgaWZuZXQgKmlmcCwgdV9sb25n
 IGNtZCwgY2FkZHJfdCBkYXRhKQp7CglzdHJ1Y3QgdmV0aGVyX3NvZnRjICpzYyA9
 IGlmcC0+aWZfc29mdGM7CQoJc3RydWN0IGlmcmVxICppZnIgPSAoc3RydWN0IGlm
 cmVxICopZGF0YTsKCWludCBlcnJvciA9IDA7CiAKCVZFVEhFUl9MT0NLKHNjKTsK
 CXN3aXRjaCAoY21kKSB7CgljYXNlIFNJT0NTSUZNVFU6CgkJaWYgKGlmci0+aWZy
 X210dSA+IEVUSEVSX01BWF9MRU5fSlVNQk8pIAoJCQllcnJvciA9IEVJTlZBTDsK
 CQllbHNlIAoJCQlpZnAtPmlmX210dSA9IGlmci0+aWZyX210dTsJCgkJYnJlYWs7
 CgljYXNlIFNJT0NTSUZNRURJQToKCWNhc2UgU0lPQ0dJRk1FRElBOgoJCWVycm9y
 ID0gaWZtZWRpYV9pb2N0bChpZnAsIGlmciwgJnNjLT5zY19pZm0sIGNtZCk7CgkJ
 YnJlYWs7CgljYXNlIFNJT0NTSUZGTEFHUzoKCWNhc2UgU0lPQ0FERE1VTFRJOgoJ
 Y2FzZSBTSU9DREVMTVVMVEk6CgkJYnJlYWs7CgljYXNlIFNJT0NTSUZQSFlTOgoJ
 CWVycm9yID0gRU9QTk9UU1VQUDsKCQlicmVhazsKCWRlZmF1bHQ6CgkJZXJyb3Ig
 PSBldGhlcl9pb2N0bChpZnAsIGNtZCwgZGF0YSk7CgkJYnJlYWs7Cgl9CglWRVRI
 RVJfVU5MT0NLKHNjKTsKCXJldHVybihlcnJvcik7Cn0gCgpzdGF0aWMgaW50CnZl
 dGhlcl9tZWRpYV9jaGFuZ2Uoc3RydWN0IGlmbmV0ICppZnApCnsKCXJldHVybigw
 KTsKfQogCnN0YXRpYyB2b2lkCnZldGhlcl9tZWRpYV9zdGF0dXMoc3RydWN0IGlm
 bmV0ICppZnAsIHN0cnVjdCBpZm1lZGlhcmVxICppZm1yKQp7CglpZm1yLT5pZm1f
 YWN0aXZlID0gSUZNX0VUSEVSIHwgSUZNX0FVVE87CglpZm1yLT5pZm1fc3RhdHVz
 ID0gSUZNX0FWQUxJRCB8IElGTV9BQ1RJVkU7Cn0KCnN0YXRpYyBpbnQKdmV0aGVy
 X21vZF9ldmVudChtb2R1bGVfdCBtb2QsIGludCBldmVudCwgdm9pZCAqZGF0YSkK
 ewoJaW50IGVycm9yID0gMDsKIAoJc3dpdGNoIChldmVudCkgewoJY2FzZSBNT0Rf
 TE9BRDoKCQltdHhfaW5pdCgmdmV0aGVyX210eCwgImlmX3ZldGhlciIsIE5VTEws
 IE1UWF9ERUYpOwoJCWlmX2Nsb25lX2F0dGFjaCgmdmV0aGVyX2Nsb25lcik7CQoJ
 CWJyZWFrOwoJY2FzZSBNT0RfVU5MT0FEOgkKCQlpZl9jbG9uZV9kZXRhY2goJnZl
 dGhlcl9jbG9uZXIpOwoJCW10eF9kZXN0cm95KCZ2ZXRoZXJfbXR4KTsKCQlicmVh
 azsKCWRlZmF1bHQ6CgkJZXJyb3IgPSBFT1BOT1RTVVBQOwoJfQogCglyZXR1cm4o
 ZXJyb3IpOwp9IAogCnN0YXRpYyBtb2R1bGVkYXRhX3QgdmV0aGVyX21vZCA9IHsK
 CSJpZl92ZXRoZXIiLAoJdmV0aGVyX21vZF9ldmVudCwKCTAKfTsKREVDTEFSRV9N
 T0RVTEUoaWZfdmV0aGVyLCB2ZXRoZXJfbW9kLCBTSV9TVUJfUFNFVURPLCBTSV9P
 UkRFUl9BTlkpOwo=
 
 ------------5OCVZbrxpul0dnsDsZO7pQ--
 

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Tue, 24 Sep 2013 02:16:14 -0000

 ------------EQZm5yNQd8MHugbtzE49mf
 Content-Type: text/plain; charset=us-ascii; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 
 ------------EQZm5yNQd8MHugbtzE49mf
 Content-Disposition: attachment; filename=if_vether.c
 Content-Type: application/octet-stream; name=if_vether.c
 Content-Transfer-Encoding: Base64
 
 LyotCiAqIENvcHlyaWdodCAoYykgMjAxMyBIZW5uaW5nIE1hdHlzY2hvawogKgog
 KiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZv
 cm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0
 dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFy
 ZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0
 IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBs
 aXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4K
 ICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9k
 dWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qg
 b2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRo
 ZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJv
 dmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiBUSElTIFNPRlRXQVJF
 IElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgQU5EIENPTlRSSUJVVE9SUyBgYEFT
 IElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywg
 SU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdB
 UlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBB
 UlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5U
 IFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBG
 T1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVY
 RU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcs
 IEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBH
 T09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJ
 VFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQg
 QU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRS
 QUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVH
 TElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQg
 T0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0Yg
 VEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKgogKi8KLyoKICog
 Q29weXJpZ2h0IChjKSAyMDA5IFRoZW8gZGUgUmFhZHQKICoKICogUGVybWlzc2lv
 biB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0
 d2FyZSBmb3IgYW55CiAqIHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBo
 ZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUKICogY29weXJp
 Z2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4g
 YWxsIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJ
 UyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTCiAqIFdJ
 VEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVE
 IFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJ
 TiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IKICogQU5Z
 IFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFN
 QUdFUyBPUiBBTlkgREFNQUdFUwogKiBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9N
 IExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4KICog
 QUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VT
 IEFDVElPTiwgQVJJU0lORyBPVVQgT0YKICogT1IgSU4gQ09OTkVDVElPTiBXSVRI
 IFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCiNp
 bmNsdWRlIDxzeXMvcGFyYW0uaD4KI2luY2x1ZGUgPHN5cy9rZXJuZWwuaD4KI2lu
 Y2x1ZGUgPHN5cy9tb2R1bGUuaD4KI2luY2x1ZGUgPHN5cy9saWJrZXJuLmg+CiNp
 bmNsdWRlIDxzeXMvc29ja2V0Lmg+IAojaW5jbHVkZSA8c3lzL3NvY2tpby5oPgog
 CiNpbmNsdWRlIDxuZXQvaWYuaD4KI2luY2x1ZGUgPG5ldC9pZl9jbG9uZS5oPgoj
 aW5jbHVkZSA8bmV0L2lmX21lZGlhLmg+CiNpbmNsdWRlIDxuZXQvaWZfdHlwZXMu
 aD4KI2luY2x1ZGUgPG5ldC9icGYuaD4KI2luY2x1ZGUgPG5ldC9ldGhlcm5ldC5o
 PgojaW5jbHVkZSA8bmV0L2lmX2JyaWRnZXZhci5oPgoKI2RlZmluZSBWRVRIRVJO
 QU1FCSJ2ZXRoZXIiCiNkZWZpbmUJTVRBR19WRVRIRVIJMTM3NzE0Njc2NAojZGVm
 aW5lCU1UQUdfVkVUSEVSX0NBTExFRAkwIAogCnN0cnVjdCB2ZXRoZXJfc29mdGMg
 ewoJc3RydWN0IGlmbmV0CSpzY19pZnA7CS8qIE5ldHdvcmsgaW50ZXJmYWNlLiAq
 LwoJTElTVF9FTlRSWSh2ZXRoZXJfc29mdGMpIHZldGhlcl9saXN0OwoJc3RydWN0
 IG10eAlzY19tdHg7CQojZGVmaW5lCVZFVEhFUl9MT0NLX0lOSVQoc2MpCW10eF9p
 bml0KCYoc2MpLT5zY19tdHgsICJ2ZXRoZXIgc29mdGMiLAlcCgkJCQkgICAgIE5V
 TEwsIE1UWF9ERUYpCiNkZWZpbmUJVkVUSEVSX0xPQ0tfREVTVFJPWShzYykJbXR4
 X2Rlc3Ryb3koJihzYyktPnNjX210eCkKI2RlZmluZQlWRVRIRVJfTE9DSyhzYykJ
 CW10eF9sb2NrKCYoc2MpLT5zY19tdHgpCiNkZWZpbmUJVkVUSEVSX1VOTE9DSyhz
 YykJCW10eF91bmxvY2soJihzYyktPnNjX210eCkKI2RlZmluZQlWRVRIRVJfTE9D
 S19BU1NFUlQoc2MpCW10eF9hc3NlcnQoJihzYyktPnNjX210eCwgTUFfT1dORUQp
 CQoJLyogRmFrZSBpbmZvcm1hdGlvbiBhYm91dCB0cmFuc21pc3Npb24gbWVkaWEu
 ICovCglzdHJ1Y3QgaWZtZWRpYQlzY19pZm07CQoJaW50CXNjX3N0YXR1czsKfTsK
 CnN0YXRpYyBMSVNUX0hFQUQoLCB2ZXRoZXJfc29mdGMpIHZldGhlcl9saXN0Owog
 CnN0YXRpYyBzdHJ1Y3QgbXR4IHZldGhlcl9tdHg7CnN0YXRpYyBNQUxMT0NfREVG
 SU5FKE1fVkVUSEVSLCBWRVRIRVJOQU1FLCAiVmlydHVhbCBFdGhlcm5ldCBpbnRl
 cmZhY2UiKTsKIApzdGF0aWMgaW50CXZldGhlcl9jbG9uZV9jcmVhdGUoc3RydWN0
 IGlmX2Nsb25lICosIGludCwgY2FkZHJfdCk7CnN0YXRpYyB2b2lkCXZldGhlcl9j
 bG9uZV9kZXN0cm95KHN0cnVjdCBpZm5ldCAqKTsKIApJRkNfU0lNUExFX0RFQ0xB
 UkUodmV0aGVyLCAwKTsKCnN0YXRpYyB2b2lkCXZldGhlcl9pbml0KHZvaWQgKik7
 CnN0YXRpYyB2b2lkCXZldGhlcl9zdG9wKHN0cnVjdCBpZm5ldCAqLCBpbnQpOwpz
 dGF0aWMgdm9pZAl2ZXRoZXJfc3RhcnRfbG9ja2VkKHN0cnVjdCBpZm5ldCAqKTsK
 c3RhdGljIHZvaWQJdmV0aGVyX3N0YXJ0KHN0cnVjdCBpZm5ldCAqKTsKCnN0YXRp
 YyBpbnQJdmV0aGVyX21lZGlhX2NoYW5nZShzdHJ1Y3QgaWZuZXQgKik7CnN0YXRp
 YyB2b2lkCXZldGhlcl9tZWRpYV9zdGF0dXMoc3RydWN0IGlmbmV0ICosIHN0cnVj
 dCBpZm1lZGlhcmVxICopOwpzdGF0aWMgaW50CXZldGhlcl9pb2N0bChzdHJ1Y3Qg
 aWZuZXQgKiwgdV9sb25nLCBjYWRkcl90KTsKCi8qCiAqIEluc3RhbnRpYXRlcyB2
 ZXRoZXIgaW50ZXJmYWNlLgogKi8Kc3RhdGljIGludAp2ZXRoZXJfY2xvbmVfY3Jl
 YXRlKHN0cnVjdCBpZl9jbG9uZSAqaWZjLCBpbnQgdW5pdCwgY2FkZHJfdCBkYXRh
 KQp7CglzdHJ1Y3QgdmV0aGVyX3NvZnRjICpzYzsKCXN0cnVjdCBpZm5ldCAqaWZw
 OwoJdWludDMyX3QgcmFuZHZhbDsKCXVpbnQ4X3QJbGxhW0VUSEVSX0FERFJfTEVO
 XTsKIAoJc2MgPSBtYWxsb2Moc2l6ZW9mKHN0cnVjdCB2ZXRoZXJfc29mdGMpLCBN
 X1ZFVEhFUiwgTV9XQUlUT0t8TV9aRVJPKTsKCWlmcCA9IHNjLT5zY19pZnAgPSBp
 Zl9hbGxvYyhJRlRfRVRIRVIpOwoJaWYgKGlmcCA9PSBOVUxMKSB7CgkJZnJlZShz
 YywgTV9WRVRIRVIpOwoJCXJldHVybiAoRU5PU1BDKTsKCX0KIAoJVkVUSEVSX0xP
 Q0tfSU5JVChzYyk7CglpZnAtPmlmX3NvZnRjID0gc2M7CiAKCWlmX2luaXRuYW1l
 KGlmcCwgaWZjLT5pZmNfbmFtZSwgdW5pdCk7CiAKCS8qIEdlbmVyYXRlcyBsbGEg
 d2l0aCByYW5kb21pemVkIHZhbHVlLiAqLwoJbGxhWzBdID0gMHgwOwoJcmFuZHZh
 bCA9IGFyYzRyYW5kb20oKTsKCW1lbWNweSgmbGxhWzFdLCAmcmFuZHZhbCwgc2l6
 ZW9mKHVpbnQzMl90KSk7CglsbGFbNV0gPSAodWludDhfdCl1bml0OyAvKiBJbnRl
 cmZhY2UgbWFqb3IgbnVtYmVyICovCiAKCWV0aGVyX2lmYXR0YWNoKGlmcCwgbGxh
 KTsKIAoJaWZwLT5pZl9pbml0ID0gdmV0aGVyX2luaXQ7CglpZnAtPmlmX2lvY3Rs
 ID0gdmV0aGVyX2lvY3RsOwoJaWZwLT5pZl9zdGFydCA9IHZldGhlcl9zdGFydDsK
 IAoJaWZwLT5pZl9jYXBhYmlsaXRpZXMgPSBJRkNBUF9WTEFOX01UVSB8IElGQ0FQ
 X0pVTUJPX01UVTsKCWlmcC0+aWZfY2FwZW5hYmxlID0gSUZDQVBfVkxBTl9NVFUg
 fCBJRkNBUF9KVU1CT19NVFU7CglpZnAtPmlmX2ZsYWdzID0gKElGRl9TSU1QTEVY
 IHwgSUZGX0JST0FEQ0FTVCB8IElGRl9NVUxUSUNBU1QpOwoJaWZwLT5pZl9zbmQu
 aWZxX21heGxlbiA9IGlmcW1heGxlbjsKIAoJaWZtZWRpYV9pbml0KCZzYy0+c2Nf
 aWZtLCAwLCB2ZXRoZXJfbWVkaWFfY2hhbmdlLCB2ZXRoZXJfbWVkaWFfc3RhdHVz
 KTsKCWlmbWVkaWFfYWRkKCZzYy0+c2NfaWZtLCBJRk1fRVRIRVIgfCBJRk1fQVVU
 TywgMCwgTlVMTCk7CglpZm1lZGlhX3NldCgmc2MtPnNjX2lmbSwgSUZNX0VUSEVS
 IHwgSUZNX0FVVE8pOwogCglzYy0+c2Nfc3RhdHVzID0gSUZNX0FWQUxJRDsKCWlm
 cC0+aWZfYmF1ZHJhdGUgPSAwOwogCgltdHhfbG9jaygmdmV0aGVyX210eCk7CglM
 SVNUX0lOU0VSVF9IRUFEKCZ2ZXRoZXJfbGlzdCwgc2MsIHZldGhlcl9saXN0KTsK
 CW10eF91bmxvY2soJnZldGhlcl9tdHgpOwoJaWZwLT5pZl9kcnZfZmxhZ3MgfD0g
 SUZGX0RSVl9SVU5OSU5HOwogCglyZXR1cm4gKDApOwp9CiAKLyoKICogRGVzdHJv
 eXMgdmV0aGVyIGludGVyZmFjZS4KICovCnN0YXRpYyB2b2lkCnZldGhlcl9jbG9u
 ZV9kZXN0cm95KHN0cnVjdCBpZm5ldCAqaWZwKQp7CglzdHJ1Y3QgdmV0aGVyX3Nv
 ZnRjICpzYzsJCglzYyA9IGlmcC0+aWZfc29mdGM7CQogCgltdHhfbG9jaygmdmV0
 aGVyX210eCk7Cgl2ZXRoZXJfc3RvcChpZnAsIDEpOwoJaWZwLT5pZl9mbGFncyAm
 PSB+SUZGX1VQOwkJCQoJTElTVF9SRU1PVkUoc2MsIHZldGhlcl9saXN0KTsKCWV0
 aGVyX2lmZGV0YWNoKGlmcCk7CglWRVRIRVJfTE9DS19ERVNUUk9ZKHNjKTsKIAoJ
 bXR4X3VubG9jaygmdmV0aGVyX210eCk7CglmcmVlKHNjLCBNX1ZFVEhFUik7Cn0K
 IAovKgogKiBJbml0aWFsaXplcyB2ZXRoZXIgaW50ZXJmYWNlLgogKi8Kc3RhdGlj
 IHZvaWQKdmV0aGVyX2luaXQodm9pZCAqeHNjKQp7CglzdHJ1Y3QgdmV0aGVyX3Nv
 ZnRjICpzYzsKCXN0cnVjdCBpZm5ldCAqaWZwOwogCiAJc2MgPSAoc3RydWN0IHZl
 dGhlcl9zb2Z0YyAqKXhzYzsKCVZFVEhFUl9MT0NLKHNjKTsKCWlmcCA9IHNjLT5z
 Y19pZnA7CglpZnAtPmlmX2Rydl9mbGFncyB8PSBJRkZfRFJWX1JVTk5JTkc7Cglp
 ZnAtPmlmX2Rydl9mbGFncyAmPSB+SUZGX0RSVl9PQUNUSVZFOwoJVkVUSEVSX1VO
 TE9DSyhzYyk7Cn0KIAovKgogKiBTdG9wcyB2ZXRoZXIgaW50ZXJmYWNlLgogKi8K
 c3RhdGljIHZvaWQKdmV0aGVyX3N0b3Aoc3RydWN0IGlmbmV0ICppZnAsIGludCBk
 aXNhYmxlKQp7CglzdHJ1Y3QgdmV0aGVyX3NvZnRjICpzYzsKCQoJc2MgPSBpZnAt
 PmlmX3NvZnRjOwoJVkVUSEVSX0xPQ0tfQVNTRVJUKHNjKTsKCWlmcC0+aWZfZHJ2
 X2ZsYWdzICY9IH5JRkZfRFJWX1JVTk5JTkc7Cn0JCiAKLyoKICogU3RhcnRzIHRy
 YW5zbWlzc2lvbi4KICovCnN0YXRpYyB2b2lkCnZldGhlcl9zdGFydChzdHJ1Y3Qg
 aWZuZXQgKmlmcCkKewoJc3RydWN0IHZldGhlcl9zb2Z0Ywkqc2M7CgoJc2MgPSBp
 ZnAtPmlmX3NvZnRjOwoJVkVUSEVSX0xPQ0soc2MpOwoJdmV0aGVyX3N0YXJ0X2xv
 Y2tlZChpZnApOwoJVkVUSEVSX1VOTE9DSyhzYyk7Cn0KCnN0YXRpYyB2b2lkCnZl
 dGhlcl9zdGFydF9sb2NrZWQoc3RydWN0IGlmbmV0ICppZnApCnsKCXN0cnVjdCB2
 ZXRoZXJfc29mdGMJKnNjOwoJc3RydWN0IG1idWYgKm07CglzdHJ1Y3QgbV90YWcg
 KnQ7CgoJc2MgPSBpZnAtPmlmX3NvZnRjOwoJVkVUSEVSX0xPQ0tfQVNTRVJUKHNj
 KTsKCglpZnAtPmlmX2Rydl9mbGFncyB8PSBJRkZfRFJWX09BQ1RJVkU7CgkKCWZv
 ciAoOzspIHsKCQlJRlFfREVRVUVVRSgmaWZwLT5pZl9zbmQsIG0pOwoJCWlmICht
 ID09IE5VTEwpIAoJCQlicmVhazsKCQkKIAkJaWYgKGlmcC0+aWZfYnJpZGdlID09
 IE5VTEwpIHsKCQkJbV9mcmVlbShtKTsKCQkJY29udGludWU7CgkJfQoJCgkJdCA9
 IG1fdGFnX2xvY2F0ZShtLCBNVEFHX1ZFVEhFUiwgTVRBR19WRVRIRVJfQ0FMTEVE
 LCBOVUxMKTsKCQlpZiAodCAhPSBOVUxMKSB7CgkJCW1fZnJlZW0obSk7CgkJCWNv
 bnRpbnVlOwkJIAkJCgkJfQoJCQkJCgkJaWYgKG0tPm1fcGt0aGRyLnJjdmlmID09
 IE5VTEwpIHsKCQkJdCA9IG1fdGFnX2FsbG9jKE1UQUdfVkVUSEVSLCBNVEFHX1ZF
 VEhFUl9DQUxMRUQsCgkJCQlzaXplb2Yoc3RydWN0IG1fdGFnKSwgTV9OT1dBSVQp
 OwoJCQlpZiAodCA9PSBOVUxMKSB7IAoJCQkJbV9mcmVlbShtKTsKCQkJCWNvbnRp
 bnVlOwoJCQl9CgkJCQoJCQltX3RhZ19wcmVwZW5kKG0sIHQpOwoJCQlFVEhFUl9C
 UEZfTVRBUChpZnAsIG0pOwkJCgoJCQkodm9pZCkoYnJpZGdlX291dHB1dF9wKShp
 ZnAsIG0sIE5VTEwsIE5VTEwpOwkJCiAJCX0gZWxzZSAKIAkJCW1fZnJlZW0obSk7
 Cgl9CgkJCQkJCglpZnAtPmlmX2Rydl9mbGFncyAmPSB+SUZGX0RSVl9PQUNUSVZF
 Owp9CgovKgogKiBNZWRpYSB0eXBlcyBjYW4ndCBjaGFuZ2VkLgogKi8Kc3RhdGlj
 IGludAp2ZXRoZXJfaW9jdGwoc3RydWN0IGlmbmV0ICppZnAsIHVfbG9uZyBjbWQs
 IGNhZGRyX3QgZGF0YSkKewoJc3RydWN0IHZldGhlcl9zb2Z0YyAqc2MgPSBpZnAt
 PmlmX3NvZnRjOwkKCXN0cnVjdCBpZnJlcSAqaWZyID0gKHN0cnVjdCBpZnJlcSAq
 KWRhdGE7CglpbnQgZXJyb3IgPSAwOwogCglWRVRIRVJfTE9DSyhzYyk7Cglzd2l0
 Y2ggKGNtZCkgewoJY2FzZSBTSU9DU0lGTVRVOgoJCWlmIChpZnItPmlmcl9tdHUg
 PiBFVEhFUl9NQVhfTEVOX0pVTUJPKSAKCQkJZXJyb3IgPSBFSU5WQUw7CgkJZWxz
 ZSAKCQkJaWZwLT5pZl9tdHUgPSBpZnItPmlmcl9tdHU7CQoJCWJyZWFrOwoJY2Fz
 ZSBTSU9DU0lGTUVESUE6CgljYXNlIFNJT0NHSUZNRURJQToKCQllcnJvciA9IGlm
 bWVkaWFfaW9jdGwoaWZwLCBpZnIsICZzYy0+c2NfaWZtLCBjbWQpOwoJCWJyZWFr
 OwoJY2FzZSBTSU9DU0lGRkxBR1M6CgljYXNlIFNJT0NBRERNVUxUSToKCWNhc2Ug
 U0lPQ0RFTE1VTFRJOgoJCWJyZWFrOwoJY2FzZSBTSU9DU0lGUEhZUzoKCQllcnJv
 ciA9IEVPUE5PVFNVUFA7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWVycm9yID0gZXRo
 ZXJfaW9jdGwoaWZwLCBjbWQsIGRhdGEpOwoJCWJyZWFrOwoJfQoJVkVUSEVSX1VO
 TE9DSyhzYyk7CglyZXR1cm4gKGVycm9yKTsKfSAKCnN0YXRpYyBpbnQKdmV0aGVy
 X21lZGlhX2NoYW5nZShzdHJ1Y3QgaWZuZXQgKmlmcCkKewoJcmV0dXJuICgwKTsK
 fQogCnN0YXRpYyB2b2lkCnZldGhlcl9tZWRpYV9zdGF0dXMoc3RydWN0IGlmbmV0
 ICppZnAsIHN0cnVjdCBpZm1lZGlhcmVxICppZm1yKQp7CglpZm1yLT5pZm1fYWN0
 aXZlID0gSUZNX0VUSEVSIHwgSUZNX0FVVE87CglpZm1yLT5pZm1fc3RhdHVzID0g
 SUZNX0FWQUxJRCB8IElGTV9BQ1RJVkU7Cn0KCnN0YXRpYyBpbnQKdmV0aGVyX21v
 ZF9ldmVudChtb2R1bGVfdCBtb2QsIGludCBldmVudCwgdm9pZCAqZGF0YSkKewoJ
 aW50IGVycm9yID0gMDsKIAoJc3dpdGNoIChldmVudCkgewoJY2FzZSBNT0RfTE9B
 RDoKCQltdHhfaW5pdCgmdmV0aGVyX210eCwgImlmX3ZldGhlciIsIE5VTEwsIE1U
 WF9ERUYpOwoJCWlmX2Nsb25lX2F0dGFjaCgmdmV0aGVyX2Nsb25lcik7CQoJCWJy
 ZWFrOwoJY2FzZSBNT0RfVU5MT0FEOgkKCQlpZl9jbG9uZV9kZXRhY2goJnZldGhl
 cl9jbG9uZXIpOwoJCW10eF9kZXN0cm95KCZ2ZXRoZXJfbXR4KTsKCQlicmVhazsK
 CWRlZmF1bHQ6CgkJZXJyb3IgPSBFT1BOT1RTVVBQOwoJfQogCglyZXR1cm4gKGVy
 cm9yKTsKfSAKIApzdGF0aWMgbW9kdWxlZGF0YV90IHZldGhlcl9tb2QgPSB7Cgki
 aWZfdmV0aGVyIiwKCXZldGhlcl9tb2RfZXZlbnQsCgkwCn07CkRFQ0xBUkVfTU9E
 VUxFKGlmX3ZldGhlciwgdmV0aGVyX21vZCwgU0lfU1VCX1BTRVVETywgU0lfT1JE
 RVJfQU5ZKTsK
 
 ------------EQZm5yNQd8MHugbtzE49mf--
 

From: "Henning Matyschok" <henning.matyschok@stud.fh-flensburg.de>
To: bug-followup@freebsd.org, henning.matyschok@stud.fh-flensburg.de
Cc:  
Subject: Re: kern/179473: Source code contribution of implementation about
 virtual ethernet interface
Date: Wed, 16 Oct 2013 04:16:57 -0000

 ------------AUg3WsvCZxErQAqbTzKG0C
 Content-Type: text/plain; charset=us-ascii; format=flowed; delsp=yes
 Content-Transfer-Encoding: 7bit
 
 bpf(4)
 ------------AUg3WsvCZxErQAqbTzKG0C
 Content-Disposition: attachment; filename=if_vether.c
 Content-Type: application/octet-stream; name=if_vether.c
 Content-Transfer-Encoding: Base64
 
 LyotCiAqIENvcHlyaWdodCAoYykgMjAxMyBIZW5uaW5nIE1hdHlzY2hvawogKgog
 KiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZv
 cm1zLCB3aXRoIG9yIHdpdGhvdXQKICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0
 dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCiAqIGFy
 ZSBtZXQ6CiAqIDEuIFJlZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0
 IHJldGFpbiB0aGUgYWJvdmUgY29weXJpZ2h0CiAqICAgIG5vdGljZSwgdGhpcyBs
 aXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci4K
 ICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9k
 dWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKICogICAgbm90aWNlLCB0aGlzIGxpc3Qg
 b2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRo
 ZQogKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJv
 dmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgogKgogKiBUSElTIFNPRlRXQVJF
 IElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgQU5EIENPTlRSSUJVVE9SUyBgYEFT
 IElTJycgQU5ECiAqIEFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywg
 SU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRQogKiBJTVBMSUVEIFdB
 UlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBB
 UlRJQ1VMQVIgUFVSUE9TRQogKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5U
 IFNIQUxMIFRIRSBBVVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQogKiBG
 T1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsIFNQRUNJQUwsIEVY
 RU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTAogKiBEQU1BR0VTIChJTkNMVURJTkcs
 IEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBH
 T09EUwogKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9SIFBST0ZJ
 VFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKICogSE9XRVZFUiBDQVVTRUQg
 QU5EIE9OIEFOWSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRS
 QUNULCBTVFJJQ1QKICogTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVH
 TElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWQogKiBPVVQg
 T0YgVEhFIFVTRSBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0Yg
 VEhFIFBPU1NJQklMSVRZIE9GCiAqIFNVQ0ggREFNQUdFLgogKgogKi8KLyoKICog
 Q29weXJpZ2h0IChjKSAyMDA5IFRoZW8gZGUgUmFhZHQKICoKICogUGVybWlzc2lv
 biB0byB1c2UsIGNvcHksIG1vZGlmeSwgYW5kIGRpc3RyaWJ1dGUgdGhpcyBzb2Z0
 d2FyZSBmb3IgYW55CiAqIHB1cnBvc2Ugd2l0aCBvciB3aXRob3V0IGZlZSBpcyBo
 ZXJlYnkgZ3JhbnRlZCwgcHJvdmlkZWQgdGhhdCB0aGUgYWJvdmUKICogY29weXJp
 Z2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBhcHBlYXIgaW4g
 YWxsIGNvcGllcy4KICoKICogVEhFIFNPRlRXQVJFIElTIFBST1ZJREVEICJBUyBJ
 UyIgQU5EIFRIRSBBVVRIT1IgRElTQ0xBSU1TIEFMTCBXQVJSQU5USUVTCiAqIFdJ
 VEggUkVHQVJEIFRPIFRISVMgU09GVFdBUkUgSU5DTFVESU5HIEFMTCBJTVBMSUVE
 IFdBUlJBTlRJRVMgT0YKICogTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTLiBJ
 TiBOTyBFVkVOVCBTSEFMTCBUSEUgQVVUSE9SIEJFIExJQUJMRSBGT1IKICogQU5Z
 IFNQRUNJQUwsIERJUkVDVCwgSU5ESVJFQ1QsIE9SIENPTlNFUVVFTlRJQUwgREFN
 QUdFUyBPUiBBTlkgREFNQUdFUwogKiBXSEFUU09FVkVSIFJFU1VMVElORyBGUk9N
 IExPU1MgT0YgVVNFLCBEQVRBIE9SIFBST0ZJVFMsIFdIRVRIRVIgSU4gQU4KICog
 QUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VT
 IEFDVElPTiwgQVJJU0lORyBPVVQgT0YKICogT1IgSU4gQ09OTkVDVElPTiBXSVRI
 IFRIRSBVU0UgT1IgUEVSRk9STUFOQ0UgT0YgVEhJUyBTT0ZUV0FSRS4KICovCiNp
 bmNsdWRlIDxzeXMvcGFyYW0uaD4KI2luY2x1ZGUgPHN5cy9rZXJuZWwuaD4KI2lu
 Y2x1ZGUgPHN5cy9tb2R1bGUuaD4KI2luY2x1ZGUgPHN5cy9saWJrZXJuLmg+CiNp
 bmNsdWRlIDxzeXMvc29ja2V0Lmg+IAojaW5jbHVkZSA8c3lzL3NvY2tpby5oPgog
 CiNpbmNsdWRlIDxuZXQvaWYuaD4KI2luY2x1ZGUgPG5ldC9pZl9jbG9uZS5oPgoj
 aW5jbHVkZSA8bmV0L2lmX21lZGlhLmg+CiNpbmNsdWRlIDxuZXQvaWZfdHlwZXMu
 aD4KI2luY2x1ZGUgPG5ldC9icGYuaD4KI2luY2x1ZGUgPG5ldC9ldGhlcm5ldC5o
 PgojaW5jbHVkZSA8bmV0L2lmX2JyaWRnZXZhci5oPgoKI2RlZmluZSBWRVRIRVJO
 QU1FCSJ2ZXRoZXIiCiNkZWZpbmUJTVRBR19WRVRIRVIJMTM3NzE0Njc2NAojZGVm
 aW5lCU1UQUdfVkVUSEVSX0NBTExFRAkwIAogCnN0cnVjdCB2ZXRoZXJfc29mdGMg
 ewoJc3RydWN0IGlmbmV0CSpzY19pZnA7CS8qIE5ldHdvcmsgaW50ZXJmYWNlLiAq
 LwoJTElTVF9FTlRSWSh2ZXRoZXJfc29mdGMpIHZldGhlcl9saXN0OwoJc3RydWN0
 IG10eAlzY19tdHg7CQojZGVmaW5lCVZFVEhFUl9MT0NLX0lOSVQoc2MpCW10eF9p
 bml0KCYoc2MpLT5zY19tdHgsICJ2ZXRoZXIgc29mdGMiLAlcCgkJCQkgICAgIE5V
 TEwsIE1UWF9ERUYpCiNkZWZpbmUJVkVUSEVSX0xPQ0tfREVTVFJPWShzYykJbXR4
 X2Rlc3Ryb3koJihzYyktPnNjX210eCkKI2RlZmluZQlWRVRIRVJfTE9DSyhzYykJ
 CW10eF9sb2NrKCYoc2MpLT5zY19tdHgpCiNkZWZpbmUJVkVUSEVSX1VOTE9DSyhz
 YykJCW10eF91bmxvY2soJihzYyktPnNjX210eCkKI2RlZmluZQlWRVRIRVJfTE9D
 S19BU1NFUlQoc2MpCW10eF9hc3NlcnQoJihzYyktPnNjX210eCwgTUFfT1dORUQp
 CQoJLyogRmFrZSBpbmZvcm1hdGlvbiBhYm91dCB0cmFuc21pc3Npb24gbWVkaWEu
 ICovCglzdHJ1Y3QgaWZtZWRpYQlzY19pZm07CQoJaW50CXNjX3N0YXR1czsKfTsK
 CnN0YXRpYyBMSVNUX0hFQUQoLCB2ZXRoZXJfc29mdGMpIHZldGhlcl9saXN0Owog
 CnN0YXRpYyBzdHJ1Y3QgbXR4IHZldGhlcl9tdHg7CnN0YXRpYyBNQUxMT0NfREVG
 SU5FKE1fVkVUSEVSLCBWRVRIRVJOQU1FLCAiVmlydHVhbCBFdGhlcm5ldCBpbnRl
 cmZhY2UiKTsKIApzdGF0aWMgaW50CXZldGhlcl9jbG9uZV9jcmVhdGUoc3RydWN0
 IGlmX2Nsb25lICosIGludCwgY2FkZHJfdCk7CnN0YXRpYyB2b2lkCXZldGhlcl9j
 bG9uZV9kZXN0cm95KHN0cnVjdCBpZm5ldCAqKTsKIApJRkNfU0lNUExFX0RFQ0xB
 UkUodmV0aGVyLCAwKTsKCnN0YXRpYyB2b2lkCXZldGhlcl9pbml0KHZvaWQgKik7
 CnN0YXRpYyB2b2lkCXZldGhlcl9zdG9wKHN0cnVjdCBpZm5ldCAqLCBpbnQpOwpz
 dGF0aWMgdm9pZAl2ZXRoZXJfc3RhcnRfbG9ja2VkKHN0cnVjdCBpZm5ldCAqKTsK
 c3RhdGljIHZvaWQJdmV0aGVyX3N0YXJ0KHN0cnVjdCBpZm5ldCAqKTsKCnN0YXRp
 YyBpbnQJdmV0aGVyX21lZGlhX2NoYW5nZShzdHJ1Y3QgaWZuZXQgKik7CnN0YXRp
 YyB2b2lkCXZldGhlcl9tZWRpYV9zdGF0dXMoc3RydWN0IGlmbmV0ICosIHN0cnVj
 dCBpZm1lZGlhcmVxICopOwpzdGF0aWMgaW50CXZldGhlcl9pb2N0bChzdHJ1Y3Qg
 aWZuZXQgKiwgdV9sb25nLCBjYWRkcl90KTsKCi8qCiAqIEluc3RhbnRpYXRlcyB2
 ZXRoZXIgaW50ZXJmYWNlLgogKi8Kc3RhdGljIGludAp2ZXRoZXJfY2xvbmVfY3Jl
 YXRlKHN0cnVjdCBpZl9jbG9uZSAqaWZjLCBpbnQgdW5pdCwgY2FkZHJfdCBkYXRh
 KQp7CglzdHJ1Y3QgdmV0aGVyX3NvZnRjICpzYzsKCXN0cnVjdCBpZm5ldCAqaWZw
 OwoJdWludDMyX3QgcmFuZHZhbDsKCXVpbnQ4X3QJbGxhW0VUSEVSX0FERFJfTEVO
 XTsKIAoJc2MgPSBtYWxsb2Moc2l6ZW9mKHN0cnVjdCB2ZXRoZXJfc29mdGMpLCBN
 X1ZFVEhFUiwgTV9XQUlUT0t8TV9aRVJPKTsKCWlmcCA9IHNjLT5zY19pZnAgPSBp
 Zl9hbGxvYyhJRlRfRVRIRVIpOwoJaWYgKGlmcCA9PSBOVUxMKSB7CgkJZnJlZShz
 YywgTV9WRVRIRVIpOwoJCXJldHVybiAoRU5PU1BDKTsKCX0KIAoJVkVUSEVSX0xP
 Q0tfSU5JVChzYyk7CglpZnAtPmlmX3NvZnRjID0gc2M7CiAKCWlmX2luaXRuYW1l
 KGlmcCwgaWZjLT5pZmNfbmFtZSwgdW5pdCk7CiAKCS8qIEdlbmVyYXRlcyBsbGEg
 d2l0aCByYW5kb21pemVkIHZhbHVlLiAqLwoJbGxhWzBdID0gMHgwOwoJcmFuZHZh
 bCA9IGFyYzRyYW5kb20oKTsKCW1lbWNweSgmbGxhWzFdLCAmcmFuZHZhbCwgc2l6
 ZW9mKHVpbnQzMl90KSk7CglsbGFbNV0gPSAodWludDhfdCl1bml0OyAvKiBJbnRl
 cmZhY2UgbWFqb3IgbnVtYmVyICovCiAKCWV0aGVyX2lmYXR0YWNoKGlmcCwgbGxh
 KTsKIAoJaWZwLT5pZl9pbml0ID0gdmV0aGVyX2luaXQ7CglpZnAtPmlmX2lvY3Rs
 ID0gdmV0aGVyX2lvY3RsOwoJaWZwLT5pZl9zdGFydCA9IHZldGhlcl9zdGFydDsK
 IAoJaWZwLT5pZl9jYXBhYmlsaXRpZXMgPSBJRkNBUF9WTEFOX01UVSB8IElGQ0FQ
 X0pVTUJPX01UVTsKCWlmcC0+aWZfY2FwZW5hYmxlID0gSUZDQVBfVkxBTl9NVFUg
 fCBJRkNBUF9KVU1CT19NVFU7CglpZnAtPmlmX2ZsYWdzID0gKElGRl9TSU1QTEVY
 IHwgSUZGX0JST0FEQ0FTVCB8IElGRl9NVUxUSUNBU1QpOwoJaWZwLT5pZl9zbmQu
 aWZxX21heGxlbiA9IGlmcW1heGxlbjsKIAoJaWZtZWRpYV9pbml0KCZzYy0+c2Nf
 aWZtLCAwLCB2ZXRoZXJfbWVkaWFfY2hhbmdlLCB2ZXRoZXJfbWVkaWFfc3RhdHVz
 KTsKCWlmbWVkaWFfYWRkKCZzYy0+c2NfaWZtLCBJRk1fRVRIRVIgfCBJRk1fQVVU
 TywgMCwgTlVMTCk7CglpZm1lZGlhX3NldCgmc2MtPnNjX2lmbSwgSUZNX0VUSEVS
 IHwgSUZNX0FVVE8pOwogCglzYy0+c2Nfc3RhdHVzID0gSUZNX0FWQUxJRDsKCWlm
 cC0+aWZfYmF1ZHJhdGUgPSAwOwogCgltdHhfbG9jaygmdmV0aGVyX210eCk7CglM
 SVNUX0lOU0VSVF9IRUFEKCZ2ZXRoZXJfbGlzdCwgc2MsIHZldGhlcl9saXN0KTsK
 CW10eF91bmxvY2soJnZldGhlcl9tdHgpOwoJaWZwLT5pZl9kcnZfZmxhZ3MgfD0g
 SUZGX0RSVl9SVU5OSU5HOwogCglyZXR1cm4gKDApOwp9CiAKLyoKICogRGVzdHJv
 eXMgdmV0aGVyIGludGVyZmFjZS4KICovCnN0YXRpYyB2b2lkCnZldGhlcl9jbG9u
 ZV9kZXN0cm95KHN0cnVjdCBpZm5ldCAqaWZwKQp7CglzdHJ1Y3QgdmV0aGVyX3Nv
 ZnRjICpzYzsJCglzYyA9IGlmcC0+aWZfc29mdGM7CQogCgltdHhfbG9jaygmdmV0
 aGVyX210eCk7Cgl2ZXRoZXJfc3RvcChpZnAsIDEpOwoJaWZwLT5pZl9mbGFncyAm
 PSB+SUZGX1VQOwkJCQoJTElTVF9SRU1PVkUoc2MsIHZldGhlcl9saXN0KTsKCWV0
 aGVyX2lmZGV0YWNoKGlmcCk7CglWRVRIRVJfTE9DS19ERVNUUk9ZKHNjKTsKIAoJ
 bXR4X3VubG9jaygmdmV0aGVyX210eCk7CglmcmVlKHNjLCBNX1ZFVEhFUik7Cn0K
 IAovKgogKiBJbml0aWFsaXplcyB2ZXRoZXIgaW50ZXJmYWNlLgogKi8Kc3RhdGlj
 IHZvaWQKdmV0aGVyX2luaXQodm9pZCAqeHNjKQp7CglzdHJ1Y3QgdmV0aGVyX3Nv
 ZnRjICpzYzsKCXN0cnVjdCBpZm5ldCAqaWZwOwogCiAJc2MgPSAoc3RydWN0IHZl
 dGhlcl9zb2Z0YyAqKXhzYzsKCVZFVEhFUl9MT0NLKHNjKTsKCWlmcCA9IHNjLT5z
 Y19pZnA7CglpZnAtPmlmX2Rydl9mbGFncyB8PSBJRkZfRFJWX1JVTk5JTkc7Cglp
 ZnAtPmlmX2Rydl9mbGFncyAmPSB+SUZGX0RSVl9PQUNUSVZFOwoJVkVUSEVSX1VO
 TE9DSyhzYyk7Cn0KIAovKgogKiBTdG9wcyB2ZXRoZXIgaW50ZXJmYWNlLgogKi8K
 c3RhdGljIHZvaWQKdmV0aGVyX3N0b3Aoc3RydWN0IGlmbmV0ICppZnAsIGludCBk
 aXNhYmxlKQp7CglzdHJ1Y3QgdmV0aGVyX3NvZnRjICpzYzsKCQoJc2MgPSBpZnAt
 PmlmX3NvZnRjOwoJVkVUSEVSX0xPQ0tfQVNTRVJUKHNjKTsKCWlmcC0+aWZfZHJ2
 X2ZsYWdzICY9IH5JRkZfRFJWX1JVTk5JTkc7Cn0JCiAKLyoKICogU3RhcnRzIHRy
 YW5zbWlzc2lvbi4KICovCnN0YXRpYyB2b2lkCnZldGhlcl9zdGFydChzdHJ1Y3Qg
 aWZuZXQgKmlmcCkKewoJc3RydWN0IHZldGhlcl9zb2Z0Ywkqc2M7CgoJc2MgPSBp
 ZnAtPmlmX3NvZnRjOwoJVkVUSEVSX0xPQ0soc2MpOwoJdmV0aGVyX3N0YXJ0X2xv
 Y2tlZChpZnApOwoJVkVUSEVSX1VOTE9DSyhzYyk7Cn0KCnN0YXRpYyB2b2lkCnZl
 dGhlcl9zdGFydF9sb2NrZWQoc3RydWN0IGlmbmV0ICppZnApCnsKCXN0cnVjdCB2
 ZXRoZXJfc29mdGMJKnNjOwoJc3RydWN0IG1idWYgKm07CglzdHJ1Y3QgbV90YWcg
 KnQ7CgoJc2MgPSBpZnAtPmlmX3NvZnRjOwoJVkVUSEVSX0xPQ0tfQVNTRVJUKHNj
 KTsKCglpZnAtPmlmX2Rydl9mbGFncyB8PSBJRkZfRFJWX09BQ1RJVkU7CgkKCWZv
 ciAoOzspIHsKCQlJRlFfREVRVUVVRSgmaWZwLT5pZl9zbmQsIG0pOwoJCWlmICht
 ID09IE5VTEwpIAoJCQlicmVhazsKCQkKCQlFVEhFUl9CUEZfTVRBUChpZnAsIG0p
 OwkKCQkKIAkJaWYgKGlmcC0+aWZfYnJpZGdlID09IE5VTEwpIHsKCQkJbV9mcmVl
 bShtKTsKCQkJY29udGludWU7CgkJfQoJCgkJdCA9IG1fdGFnX2xvY2F0ZShtLCBN
 VEFHX1ZFVEhFUiwgTVRBR19WRVRIRVJfQ0FMTEVELCBOVUxMKTsKCQlpZiAodCAh
 PSBOVUxMKSB7CgkJCW1fZnJlZW0obSk7CgkJCWNvbnRpbnVlOwkJIAkJCgkJfQoJ
 CQkJCgkJaWYgKG0tPm1fcGt0aGRyLnJjdmlmID09IE5VTEwpIHsKCQkJdCA9IG1f
 dGFnX2FsbG9jKE1UQUdfVkVUSEVSLCBNVEFHX1ZFVEhFUl9DQUxMRUQsCgkJCQlz
 aXplb2Yoc3RydWN0IG1fdGFnKSwgTV9OT1dBSVQpOwoJCQlpZiAodCA9PSBOVUxM
 KSB7IAoJCQkJbV9mcmVlbShtKTsKCQkJCWNvbnRpbnVlOwoJCQl9CgkJCQoJCQlt
 X3RhZ19wcmVwZW5kKG0sIHQpOwoJCQkodm9pZCkoYnJpZGdlX291dHB1dF9wKShp
 ZnAsIG0sIE5VTEwsIE5VTEwpOwkJCiAJCX0gZWxzZSAKIAkJCW1fZnJlZW0obSk7
 Cgl9CgkJCQkJCglpZnAtPmlmX2Rydl9mbGFncyAmPSB+SUZGX0RSVl9PQUNUSVZF
 Owp9CgovKgogKiBNZWRpYSB0eXBlcyBjYW4ndCBjaGFuZ2VkLgogKi8Kc3RhdGlj
 IGludAp2ZXRoZXJfaW9jdGwoc3RydWN0IGlmbmV0ICppZnAsIHVfbG9uZyBjbWQs
 IGNhZGRyX3QgZGF0YSkKewoJc3RydWN0IHZldGhlcl9zb2Z0YyAqc2MgPSBpZnAt
 PmlmX3NvZnRjOwkKCXN0cnVjdCBpZnJlcSAqaWZyID0gKHN0cnVjdCBpZnJlcSAq
 KWRhdGE7CglpbnQgZXJyb3IgPSAwOwogCglWRVRIRVJfTE9DSyhzYyk7Cglzd2l0
 Y2ggKGNtZCkgewoJY2FzZSBTSU9DU0lGTVRVOgoJCWlmIChpZnItPmlmcl9tdHUg
 PiBFVEhFUl9NQVhfTEVOX0pVTUJPKSAKCQkJZXJyb3IgPSBFSU5WQUw7CgkJZWxz
 ZSAKCQkJaWZwLT5pZl9tdHUgPSBpZnItPmlmcl9tdHU7CQoJCWJyZWFrOwoJY2Fz
 ZSBTSU9DU0lGTUVESUE6CgljYXNlIFNJT0NHSUZNRURJQToKCQllcnJvciA9IGlm
 bWVkaWFfaW9jdGwoaWZwLCBpZnIsICZzYy0+c2NfaWZtLCBjbWQpOwoJCWJyZWFr
 OwoJY2FzZSBTSU9DU0lGRkxBR1M6CgljYXNlIFNJT0NBRERNVUxUSToKCWNhc2Ug
 U0lPQ0RFTE1VTFRJOgoJCWJyZWFrOwoJY2FzZSBTSU9DU0lGUEhZUzoKCQllcnJv
 ciA9IEVPUE5PVFNVUFA7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWVycm9yID0gZXRo
 ZXJfaW9jdGwoaWZwLCBjbWQsIGRhdGEpOwoJCWJyZWFrOwoJfQoJVkVUSEVSX1VO
 TE9DSyhzYyk7CglyZXR1cm4gKGVycm9yKTsKfSAKCnN0YXRpYyBpbnQKdmV0aGVy
 X21lZGlhX2NoYW5nZShzdHJ1Y3QgaWZuZXQgKmlmcCkKewoJcmV0dXJuICgwKTsK
 fQogCnN0YXRpYyB2b2lkCnZldGhlcl9tZWRpYV9zdGF0dXMoc3RydWN0IGlmbmV0
 ICppZnAsIHN0cnVjdCBpZm1lZGlhcmVxICppZm1yKQp7CglpZm1yLT5pZm1fYWN0
 aXZlID0gSUZNX0VUSEVSIHwgSUZNX0FVVE87CglpZm1yLT5pZm1fc3RhdHVzID0g
 SUZNX0FWQUxJRCB8IElGTV9BQ1RJVkU7Cn0KCnN0YXRpYyBpbnQKdmV0aGVyX21v
 ZF9ldmVudChtb2R1bGVfdCBtb2QsIGludCBldmVudCwgdm9pZCAqZGF0YSkKewoJ
 aW50IGVycm9yID0gMDsKIAoJc3dpdGNoIChldmVudCkgewoJY2FzZSBNT0RfTE9B
 RDoKCQltdHhfaW5pdCgmdmV0aGVyX210eCwgImlmX3ZldGhlciIsIE5VTEwsIE1U
 WF9ERUYpOwoJCWlmX2Nsb25lX2F0dGFjaCgmdmV0aGVyX2Nsb25lcik7CQoJCWJy
 ZWFrOwoJY2FzZSBNT0RfVU5MT0FEOgkKCQlpZl9jbG9uZV9kZXRhY2goJnZldGhl
 cl9jbG9uZXIpOwoJCW10eF9kZXN0cm95KCZ2ZXRoZXJfbXR4KTsKCQlicmVhazsK
 CWRlZmF1bHQ6CgkJZXJyb3IgPSBFT1BOT1RTVVBQOwoJfQogCglyZXR1cm4gKGVy
 cm9yKTsKfSAKIApzdGF0aWMgbW9kdWxlZGF0YV90IHZldGhlcl9tb2QgPSB7Cgki
 aWZfdmV0aGVyIiwKCXZldGhlcl9tb2RfZXZlbnQsCgkwCn07CkRFQ0xBUkVfTU9E
 VUxFKGlmX3ZldGhlciwgdmV0aGVyX21vZCwgU0lfU1VCX1BTRVVETywgU0lfT1JE
 RVJfQU5ZKTsK
 
 ------------AUg3WsvCZxErQAqbTzKG0C--
 
Responsible-Changed-From-To: freebsd-bugs->freebsd-net 
Responsible-Changed-By: linimon 
Responsible-Changed-When: Sun May 4 05:34:19 UTC 2014 
Responsible-Changed-Why:  
Over to maintainer(s). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=179473 
>Unformatted:
