vether: Implement a virtual ethernet interface

The vether interface simulates a normal Ethernet interface by encapsulating
standard network frames with an Ethernet header, specifically for use as
a member in a bridge(4).

To use vether the administrator needs to configure an address onto the
interface so that packets can be routed to it. An Ethernet header will
be prepended and, if the vether interface is a member of a bridge(4),
the frame will show up there.

Taken from OpenBSD.
This commit is contained in:
roy 2020-09-27 13:31:04 +00:00
parent 60d7c828b9
commit 4b44dc0b5e
5 changed files with 222 additions and 4 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: mi,v 1.1703 2020/09/21 14:03:15 kim Exp $
# $NetBSD: mi,v 1.1704 2020/09/27 13:31:04 roy Exp $
#
# Note: don't delete entries from here - mark them as "obsolete" instead.
#
@ -2020,6 +2020,7 @@
./usr/share/man/cat4/vioscsi.0 man-sys-catman .cat
./usr/share/man/cat4/virt.0 man-sys-catman .cat
./usr/share/man/cat4/virtio.0 man-sys-catman .cat
./usr/share/man/cat4/vether.0 man-sys-catman .cat
./usr/share/man/cat4/vlan.0 man-sys-catman .cat
./usr/share/man/cat4/vmmon.0 man-sys-catman .cat
./usr/share/man/cat4/vmnet.0 man-sys-catman .cat
@ -5158,6 +5159,7 @@
./usr/share/man/html4/vioscsi.html man-sys-htmlman html
./usr/share/man/html4/virt.html man-sys-htmlman html
./usr/share/man/html4/virtio.html man-sys-htmlman html
./usr/share/man/html4/vether.html man-sys-htmlman html
./usr/share/man/html4/vlan.html man-sys-htmlman html
./usr/share/man/html4/vmmon.html man-sys-htmlman html
./usr/share/man/html4/vmnet.html man-sys-htmlman html
@ -8228,6 +8230,7 @@
./usr/share/man/man4/vioscsi.4 man-sys-man .man
./usr/share/man/man4/virt.4 man-sys-man .man
./usr/share/man/man4/virtio.4 man-sys-man .man
./usr/share/man/man4/vether.4 man-sys-man .man
./usr/share/man/man4/vlan.4 man-sys-man .man
./usr/share/man/man4/vmmon.4 man-sys-man .man
./usr/share/man/man4/vmnet.4 man-sys-man .man

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.708 2020/09/08 10:05:47 yamaguchi Exp $
# $NetBSD: Makefile,v 1.709 2020/09/27 13:31:04 roy Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
@ -69,7 +69,7 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 \
unix.4 userconf.4 \
vald.4 valz.4 veriexec.4 vga.4 vge.4 viaide.4 video.4 \
vio9p.4 vioif.4 viomb.4 viornd.4 vioscsi.4 virt.4 virtio.4 \
vlan.4 vmmon.4 vmnet.4 vnd.4 voodoofb.4 vr.4 vte.4 \
vether.4 vlan.4 vmmon.4 vmnet.4 vnd.4 voodoofb.4 vr.4 vte.4 \
wapbl.4 wb.4 wbsio.4 wd.4 wdc.4 wg.4 wi.4 wm.4 wpi.4 \
wsbell.4 wscons.4 wsdisplay.4 wsfont.4 wskbd.4 wsmouse.4 wsmux.4 \
xbox.4 xge.4 \

57
share/man/man4/vether.4 Normal file
View File

@ -0,0 +1,57 @@
.\" $OpenBSD: vether.4,v 1.5 2017/10/17 22:47:58 schwarze Exp $
.\"
.\" Copyright (c) 2009 Theo de Raadt <deraadt@openbsd.org>
.\"
.\" 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.
.\"
.Dd October 17, 2017
.Dt VETHER 4
.Os
.Sh NAME
.Nm vether
.Nd virtual Ethernet interface
.Sh SYNOPSIS
.Cd "pseudo-device vether"
.Sh DESCRIPTION
The
.Nm
interface simulates a normal Ethernet interface by encapsulating
standard network frames with an Ethernet header, specifically
for use as a member in a
.Xr bridge 4 .
.Pp
To use
.Nm
the administrator needs to configure an address onto the interface
so that packets can be routed to it.
An Ethernet header will be prepended and, if the
.Nm
interface is a member of a
.Xr bridge 4 ,
the frame will show up there.
.Sh SEE ALSO
.Xr bridge 4 ,
.Xr ifconfig 8
.Sh HISTORY
The
.Nm
interface first appeared in
.Ox 4.7 and
.Nx 10.
.Sh AUTHORS
.An Theo de Raadt Aq Mt deraadt@openbsd.org
.Sh BUGS
Like
.Xr tap 4 ,
the Ethernet address chosen will be partially random, and may
occasionally collide with another address.

View File

@ -1,4 +1,4 @@
# $NetBSD: files.net,v 1.28 2020/09/13 11:48:45 roy Exp $
# $NetBSD: files.net,v 1.29 2020/09/27 13:31:04 roy Exp $
# XXX CLEANUP
define net
@ -31,6 +31,7 @@ file net/if_sl.c sl needs-flag
file net/if_spppsubr.c sppp
file net/if_tap.c tap
file net/if_tun.c tun
file net/if_vether.c vether
file net/if_vlan.c vlan needs-flag
file net/if_pppoe.c pppoe needs-flag
file net/if_wg.c wg needs-flag

157
sys/net/if_vether.c Normal file
View File

@ -0,0 +1,157 @@
/* $NetBSD: if_vether.c,v 1.1 2020/09/27 13:31:04 roy Exp $ */
/* $OpenBSD: if_vether.c,v 1.27 2016/04/13 11:41:15 mpi Exp $ */
/*
* Copyright (c) 2009 Theo de Raadt
* Copyright (c) 2020 Roy Marples
*
* 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/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: if_vether.c,v 1.1 2020/09/27 13:31:04 roy Exp $");
#include <sys/cprng.h>
#include <sys/kmem.h>
#include <sys/mbuf.h>
#include <net/if.h>
#include <net/if_ether.h>
#include <net/bpf.h>
void vetherattach(int);
static int vether_ioctl(struct ifnet *, u_long, void *);
static void vether_start(struct ifnet *);
static int vether_clone_create(struct if_clone *, int);
static int vether_clone_destroy(struct ifnet *);
static void vether_stop(struct ifnet *, int);
static int vether_init(struct ifnet *);
struct vether_softc {
struct ethercom sc_ec;
};
struct if_clone vether_cloner =
IF_CLONE_INITIALIZER("vether", vether_clone_create, vether_clone_destroy);
void
vetherattach(int nvether)
{
if_clone_attach(&vether_cloner);
}
static int
vether_clone_create(struct if_clone *ifc, int unit)
{
struct ifnet *ifp;
struct vether_softc *sc;
uint8_t enaddr[ETHER_ADDR_LEN] =
{ 0xf2, 0x0b, 0xa4, 0xff, 0xff, 0xff };
sc = kmem_zalloc(sizeof(*sc), KM_SLEEP);
ifp = &sc->sc_ec.ec_if;
if_initname(ifp, ifc->ifc_name, unit);
ifp->if_softc = sc;
ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
#ifdef NET_MPSAFE
ifp->if_extflags = IFEF_MPSAFE;
#endif
ifp->if_ioctl = vether_ioctl;
ifp->if_start = vether_start;
ifp->if_stop = vether_stop;
ifp->if_init = vether_init;
IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
IFQ_SET_READY(&ifp->if_snd);
sc->sc_ec.ec_capabilities = ETHERCAP_VLAN_MTU | ETHERCAP_JUMBO_MTU;
/*
* In order to obtain unique initial Ethernet address on a host,
* do some randomisation. It's not meant for anything but avoiding
* hard-coding an address.
*/
cprng_fast(&enaddr[3], 3);
/* Those steps are mandatory for an Ethernet driver. */
if_initialize(ifp);
ether_ifattach(ifp, enaddr);
if_register(ifp);
return 0;
}
static int
vether_clone_destroy(struct ifnet *ifp)
{
struct vether_softc *sc = ifp->if_softc;
ether_ifdetach(ifp);
if_detach(ifp);
kmem_free(sc, sizeof(*sc));
return 0;
}
static int
vether_init(struct ifnet *ifp)
{
ifp->if_flags |= IFF_RUNNING;
if_link_state_change(ifp, LINK_STATE_UP);
vether_start(ifp);
return 0;
}
/*
* The bridge has magically already done all the work for us,
* and we only need to discard the packets.
*/
static void
vether_start(struct ifnet *ifp)
{
struct mbuf *m;
for (;;) {
IFQ_DEQUEUE(&ifp->if_snd, m);
if (m == NULL)
break;
bpf_mtap(ifp, m, BPF_D_OUT);
m_freem(m);
if_statinc(ifp, if_opackets);
}
}
static void
vether_stop(struct ifnet *ifp, __unused int disable)
{
ifp->if_flags &= ~IFF_RUNNING;
if_link_state_change(ifp, LINK_STATE_DOWN);
}
static int
vether_ioctl(struct ifnet *ifp, unsigned long cmd, void *data)
{
int error = 0;
switch (cmd) {
case SIOCADDMULTI:
case SIOCDELMULTI:
break;
default:
error = ether_ioctl(ifp, cmd, data);
}
return error;
}