From: chris Date: Wed, 26 Apr 2000 19:03:46 +0000 (+0000) Subject: if_vlan support X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=b9dc81a079c43483deebab62545756090918e7e8;p=openbsd if_vlan support --- diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index 5226ee26b81..0c5e3020574 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,4 +1,4 @@ -.\" $OpenBSD: ifconfig.8,v 1.42 2000/04/12 21:47:58 aaron Exp $ +.\" $OpenBSD: ifconfig.8,v 1.43 2000/04/26 19:03:46 chris Exp $ .\" $NetBSD: ifconfig.8,v 1.11 1996/01/04 21:27:29 pk Exp $ .\" $FreeBSD: ifconfig.8,v 1.16 1998/02/01 07:03:29 steve Exp $ .\" @@ -54,6 +54,12 @@ .Cm giftunnel .Ar src_address dest_address .Nm ifconfig +.Ar vlan-interface +.Cm vlan +.Ar vlan-tag +.Cm vlandev +.Ar parent-interface +.Nm ifconfig .Ar interface .Op Ar address_family .Nm ifconfig @@ -310,6 +316,48 @@ This is useful for devices which have multiple physical layer interfaces Setting the instance on such devices may not be strictly required by the network interface driver as the driver may take care of this automatically; see the driver's manual page for more information. +.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 +If the driver is a vlan pseudo device, disassociate the physical interface +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 , @@ -498,6 +546,10 @@ Configure the xl0 interface to use 10baseT. .Pp .It Cm ifconfig xl0 media 100baseTX mediaopt full-duplex Configure the xl0 interface to use 100baseTX, full duplex. +.Pp +.It Cm ifconfig vlan0 192.168.254.1 vlan 4 vlandev fxp0 +Configure the vlan0 interface for IP address 192.168.254.1, vlan tag 4, +and vlan parent device fxp0. .El .Sh DIAGNOSTICS Messages indicating the specified interface does not exist, the diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 976123ddbfb..342aa35586e 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ifconfig.c,v 1.34 2000/04/14 02:40:01 itojun Exp $ */ +/* $OpenBSD: ifconfig.c,v 1.35 2000/04/26 19:03:46 chris Exp $ */ /* $NetBSD: ifconfig.c,v 1.40 1997/10/01 02:19:43 enami Exp $ */ /* @@ -81,7 +81,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; #else -static char rcsid[] = "$OpenBSD: ifconfig.c,v 1.34 2000/04/14 02:40:01 itojun Exp $"; +static char rcsid[] = "$OpenBSD: ifconfig.c,v 1.35 2000/04/26 19:03:46 chris Exp $"; #endif #endif /* not lint */ @@ -118,6 +118,10 @@ static char rcsid[] = "$OpenBSD: ifconfig.c,v 1.34 2000/04/14 02:40:01 itojun Ex #include #include +#ifndef INET_ONLY +#include +#endif + #include #include #include @@ -187,6 +191,10 @@ void setmedia __P((char *, int)); void setmediaopt __P((char *, int)); void unsetmediaopt __P((char *, int)); void setmediainst __P((char *, int)); +void setvlantag __P((char *, int)); +void setvlandev __P((char *, int)); +void unsetvlandev __P((char *, int)); +void vlan_status (); void fixnsel __P((struct sockaddr_iso *)); int main __P((int, char *[])); @@ -259,6 +267,9 @@ const struct cmd { { "802.3", ETHERTYPE_8023, 0, setipxframetype }, { "snap", ETHERTYPE_SNAP, 0, setipxframetype }, { "EtherII", ETHERTYPE_II, 0, setipxframetype }, + { "vlan", NEXTARG, 0, setvlantag }, + { "vlandev", NEXTARG, 0, setvlandev }, + { "-vlandev", 1, 0, unsetvlandev }, #endif /* INET_ONLY */ { "giftunnel", NEXTARG2, 0, gifsettunnel } , { "dstsa", NEXTARG, 0, dstsa } , @@ -965,23 +976,32 @@ setifdstaddr(addr, param) (*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) char *vname; int value; { - 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) err(1, "SIOCGIFFLAGS"); - 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) err(1, "SIOCSIFFLAGS"); } @@ -1453,6 +1473,9 @@ status(link) printf(" mtu %d", mtu); putchar('\n'); +#ifndef INET_ONLY + vlan_status(); +#endif ieee80211_status(); (void) memset(&ifmr, 0, sizeof(ifmr)); @@ -2299,6 +2322,100 @@ usage() exit(1); } +#ifndef INET_ONLY + +static int __tag = 0; +static int __have_tag = 0; + +void vlan_status() +{ + struct vlanreq vreq; + + bzero((char *)&vreq, sizeof(struct vlanreq)); + ifr.ifr_data = (caddr_t)&vreq; + + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) + return; + + if (vreq.vlr_tag || (vreq.vlr_parent[0] != '\0')) + printf("\tvlan: %d parent interface: %s\n", + vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ? + "" : vreq.vlr_parent); + + return; +} + +void setvlantag(val, d) + char *val; + int d; +{ + 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) + char *val; + int d; +{ + 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) + char *val; + int d; +{ + 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; +} + +#endif /* INET_ONLY */ + #ifdef INET6 char * sec2str(total)