Grrr... botched remote commit. Let's try this again: vlan updates,

take two.
This commit is contained in:
Bill Paul 1999-03-15 01:22:01 +00:00
parent f731f10490
commit 97ed1257f9
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=44764
7 changed files with 257 additions and 13 deletions

View File

@ -1,5 +1,5 @@
# From: @(#)Makefile 8.1 (Berkeley) 6/5/93
# $Id: Makefile,v 1.9 1997/02/22 14:32:32 peter Exp $
# $Id: Makefile,v 1.10 1997/05/04 06:27:45 peter Exp $
PROG= ifconfig
SRCS= ifconfig.c
@ -8,10 +8,14 @@ SRCS= ifconfig.c
SRCS+= ifmedia.c
CFLAGS+=-DUSE_IF_MEDIA
#comment out to exclude SIOC[GS]ETVLAN support
SRCS+= ifvlan.c
CFLAGS+=-DUSE_VLANS
MAN8= ifconfig.8
DPADD= ${LIBIPX}
LDADD= -lipx
COPTS= -DNS -Wall -Wmissing-prototypes -Wcast-qual -Wwrite-strings \
-Wnested-externs
-Wnested-externs -I..
.include <bsd.prog.mk>

View File

@ -30,7 +30,7 @@
.\" SUCH DAMAGE.
.\"
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
.\" $Id: ifconfig.8,v 1.17 1998/06/08 02:00:45 danny Exp $
.\" $Id: ifconfig.8,v 1.18 1998/07/06 06:53:42 charnier Exp $
.\"
.Dd February 13, 1996
.Dt IFCONFIG 8
@ -200,6 +200,49 @@ list of available options.
.It Fl mediaopt Ar opts
If the driver supports the media selection system, disable the
specified media options on the interface.
.It Cm vlan Ar vlan_tag
If the interface is a vlan pseudo interface, set the vlan tag value
to
.Ar vlan_tag .
This value is a 16-bit number which is used to create an 802.1Q
vlan header for packets sent from the vlan interface. Note that
.Cm vlan
and
.Cm vlandev
must both be set at the same time.
.It Cm vlandev Ar iface
If the interface is a vlan pseudo device, associate physical interface
.Ar iface
with it. Packets transmitted through the vlan interface will be
diverted to the specified physical interface
.Ar iface
with 802.1Q vlan encapsulation. Packets with 802.1Q encapsulation received
by the parent interface with the correct vlan tag will be diverted to
the associated vlan pseudo-interface. The vlan interface is assigned a
copy of the parent interface's flags and the parent's ethernet address.
The
.Cm vlandev
and
.Cm vlan
must both be set at the same time. If the vlan interface already has
a physical interface associated with it, this command will fail. To
change the association to another physical interface, the existing
association must be cleared first.
.Pp
Note: if the
.Ar link0
flag is set on the vlan interface, the vlan pseudo
interface's behavior changes: the
.Ar link0
tells the vlan interface that the
parent interface supports insertion and extraction of vlan tags on its
own (usually in firmware) and that it should pass packets to and from
the parent unaltered.
.It Fl vlandev Ar iface
If the driver is a vlan pseudo device, disassociate the physical interface
.Ar iface
from it. This breaks the link between the vlan interface and its parent,
clears its vlan tag, flags and its link address and shuts the interface down.
.It Cm metric Ar n
Set the routing metric of the interface to
.Ar n ,

View File

@ -42,7 +42,7 @@ static const char copyright[] =
static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94";
#endif
static const char rcsid[] =
"$Id: ifconfig.c,v 1.37 1998/07/06 19:54:39 bde Exp $";
"$Id: ifconfig.c,v 1.38 1998/08/07 06:36:53 phk Exp $";
#endif /* not lint */
#include <sys/param.h>
@ -165,6 +165,11 @@ struct cmd {
{ "media", NEXTARG, setmedia },
{ "mediaopt", NEXTARG, setmediaopt },
{ "-mediaopt", NEXTARG, unsetmediaopt },
#endif
#ifdef USE_VLANS
{ "vlan", NEXTARG, setvlantag },
{ "vlandev", NEXTARG, setvlandev },
{ "-vlandev", NEXTARG, unsetvlandev },
#endif
{ "normal", -IFF_LINK0, setifflags },
{ "compress", IFF_LINK0, setifflags },
@ -217,6 +222,9 @@ struct afswtch {
#ifdef USE_IF_MEDIA
{ "media", AF_INET, media_status, NULL }, /* XXX not real!! */
#endif
#ifdef USE_VLANS
{ "vlan", AF_INET, media_status, NULL }, /* XXX not real!! */
#endif
#endif
{ 0, 0, 0, 0 }
};
@ -632,6 +640,11 @@ setifdstaddr(addr, param, s, afp)
(*afp->af_getaddr)(addr, DSTADDR);
}
/*
* Note: doing an SIOCIGIFFLAGS scribbles on the union portion
* of the ifreq structure, which may confuse other parts of ifconfig.
* Make a private copy so we can avoid that.
*/
void
setifflags(vname, value, s, afp)
const char *vname;
@ -639,20 +652,24 @@ setifflags(vname, value, s, afp)
int s;
const struct afswtch *afp;
{
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&ifr) < 0) {
struct ifreq my_ifr;
bcopy((char *)&ifr, (char *)&my_ifr, sizeof(struct ifreq));
if (ioctl(s, SIOCGIFFLAGS, (caddr_t)&my_ifr) < 0) {
Perror("ioctl (SIOCGIFFLAGS)");
exit(1);
}
strncpy(ifr.ifr_name, name, sizeof (ifr.ifr_name));
flags = ifr.ifr_flags;
strncpy(my_ifr.ifr_name, name, sizeof (my_ifr.ifr_name));
flags = my_ifr.ifr_flags;
if (value < 0) {
value = -value;
flags &= ~value;
} else
flags |= value;
ifr.ifr_flags = flags;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&ifr) < 0)
my_ifr.ifr_flags = flags;
if (ioctl(s, SIOCSIFFLAGS, (caddr_t)&my_ifr) < 0)
Perror(vname);
}
@ -752,6 +769,9 @@ status(afp, addrcount, sdl, ifm, ifam)
if (afp->af_af == info.rti_info[RTAX_IFA]->sa_family &&
#ifdef USE_IF_MEDIA
afp->af_status != media_status &&
#endif
#ifdef USE_VLANS
afp->af_status != vlan_status &&
#endif
afp->af_status != ether_status) {
p = afp;
@ -761,6 +781,9 @@ status(afp, addrcount, sdl, ifm, ifam)
if (p->af_af == info.rti_info[RTAX_IFA]->sa_family &&
#ifdef USE_IF_MEDIA
p->af_status != media_status &&
#endif
#ifdef USE_VLANS
p->af_status != vlan_status &&
#endif
p->af_status != ether_status)
(*p->af_status)(s, &info);
@ -773,9 +796,13 @@ status(afp, addrcount, sdl, ifm, ifam)
#ifdef USE_IF_MEDIA
if (allfamilies || afp->af_status == media_status)
media_status(s, NULL);
#endif
#ifdef USE_VLANS
if (allfamilies || afp->af_status == vlan_status)
vlan_status(s, NULL);
#endif
if (!allfamilies && !p && afp->af_status != media_status &&
afp->af_status != ether_status)
afp->af_status != ether_status && afp->af_status != vlan_status)
warnx("%s has no %s interface address!", name, afp->af_name);
close(s);

View File

@ -31,7 +31,7 @@
*
* so there!
*
* $Id: ifconfig.h,v 1.2 1997/05/10 14:47:35 peter Exp $
* $Id: ifconfig.h,v 1.3 1997/05/10 17:14:53 peter Exp $
*/
extern struct ifreq ifr;
@ -44,3 +44,8 @@ extern void setmedia(const char *, int, int, const struct afswtch *rafp);
extern void setmediaopt(const char *, int, int, const struct afswtch *rafp);
extern void unsetmediaopt(const char *, int, int, const struct afswtch *rafp);
extern void media_status(int s, struct rt_addrinfo *);
extern void setvlantag(const char *, int, int, const struct afswtch *rafp);
extern void setvlandev(const char *, int, int, const struct afswtch *rafp);
extern void unsetvlandev(const char *, int, int, const struct afswtch *rafp);
extern void vlan_status(int s, struct rt_addrinfo *);

156
sbin/ifconfig/ifvlan.c Normal file
View File

@ -0,0 +1,156 @@
/*
* Copyright (c) 1999
* Bill Paul <wpaul@ctr.columbia.edu>. 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.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by Bill Paul.
* 4. Neither the name of the author nor the names of any co-contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul OR THE VOICES IN HIS HEAD
* 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.
*
* $Id$
*/
#include <sys/param.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/sockio.h>
#include <sys/mbuf.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/ethernet.h>
#include <net/if.h>
#include <net/if_var.h>
#include <net/if_vlan_var.h>
#include <net/route.h>
#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <err.h>
#include <errno.h>
#include "ifconfig.h"
#ifndef lint
static const char rcsid[] =
"$Id$";
#endif
static int __tag = 0;
static int __have_tag = 0;
void vlan_status(s, info)
int s;
struct rt_addrinfo *info __unused;
{
struct vlanreq vreq;
bzero((char *)&vreq, sizeof(struct vlanreq));
ifr.ifr_data = (caddr_t)&vreq;
if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
return;
printf("\tvlan: %d parent interface: %s\n",
vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ?
"<none>" : vreq.vlr_parent);
return;
}
void setvlantag(val, d, s, afp)
const char *val;
int d, s;
const struct afswtch *afp;
{
u_int16_t tag;
struct vlanreq vreq;
__tag = tag = atoi(val);
__have_tag = 1;
bzero((char *)&vreq, sizeof(struct vlanreq));
ifr.ifr_data = (caddr_t)&vreq;
if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
err(1, "SIOCGETVLAN");
vreq.vlr_tag = tag;
if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
err(1, "SIOCSETVLAN");
return;
}
void setvlandev(val, d, s, afp)
const char *val;
int d, s;
const struct afswtch *afp;
{
struct vlanreq vreq;
if (!__have_tag)
errx(1, "must specify both vlan tag and device");
bzero((char *)&vreq, sizeof(struct vlanreq));
ifr.ifr_data = (caddr_t)&vreq;
if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
err(1, "SIOCGETVLAN");
strncpy(vreq.vlr_parent, val, sizeof(vreq.vlr_parent));
vreq.vlr_tag = __tag;
if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
err(1, "SIOCSETVLAN");
return;
}
void unsetvlandev(val, d, s, afp)
const char *val;
int d, s;
const struct afswtch *afp;
{
struct vlanreq vreq;
bzero((char *)&vreq, sizeof(struct vlanreq));
ifr.ifr_data = (caddr_t)&vreq;
if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1)
err(1, "SIOCGETVLAN");
bzero((char *)&vreq.vlr_parent, sizeof(vreq.vlr_parent));
vreq.vlr_tag = 0;
if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1)
err(1, "SIOCSETVLAN");
return;
}

View File

@ -26,7 +26,7 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: if_vlan.c,v 1.9 1999/03/15 00:33:02 wpaul Exp $
* $Id: if_vlan.c,v 1.5 1999/03/15 01:17:26 wpaul Exp $
*/
/*
@ -40,6 +40,7 @@
* if_start(), rewrite them for use by the real outgoing interface,
* and ask it to send them.
*
*
* XXX It's incorrect to assume that we must always kludge up
* headers on the physical device's behalf: some devices support
* VLAN tag insersion and extraction in firmware. For these cases,

View File

@ -26,13 +26,18 @@
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id: if_vlan_var.h,v 1.3 1999/03/15 00:33:02 wpaul Exp $
*/
#ifndef _NET_IF_VLAN_VAR_H_
#define _NET_IF_VLAN_VAR_H_ 1
#ifdef KERNEL
struct vlan_mc_entry {
struct ether_addr mc_addr;
SLIST_ENTRY(vlan_mc_entry) mc_entries;
};
struct ifvlan {
struct arpcom ifv_ac; /* make this an interface */
struct ifnet *ifv_p; /* parent inteface of this vlan */
@ -41,6 +46,7 @@ struct ifvlan {
u_int16_t ifvm_proto; /* encapsulation ethertype */
u_int16_t ifvm_tag; /* tag to apply on packets leaving if */
} ifv_mib;
SLIST_HEAD(__vlan_mchead, vlan_mc_entry) vlan_mc_listhead;
};
#define ifv_if ifv_ac.ac_if
#define ifv_tag ifv_mib.ifvm_tag
@ -79,6 +85,8 @@ struct vlanreq {
/* shared with if_ethersubr.c: */
extern u_int vlan_proto;
extern int vlan_input(struct ether_header *eh, struct mbuf *m);
extern void vlan_input_tag(struct ether_header *eh,
struct mbuf *m, u_int16_t t);
#endif
#endif /* _NET_IF_VLAN_VAR_H_ */