diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8 index b148b0b1287b..f341aa36004c 100644 --- a/sbin/ifconfig/ifconfig.8 +++ b/sbin/ifconfig/ifconfig.8 @@ -1,4 +1,4 @@ -.\" $NetBSD: ifconfig.8,v 1.42 2000/08/13 17:17:26 wiz Exp $ +.\" $NetBSD: ifconfig.8,v 1.43 2000/09/27 23:00:24 thorpej Exp $ .\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. @@ -379,6 +379,46 @@ This may be used to enable an interface after an ``ifconfig down.'' It happens automatically when setting the first address on an interface. If the interface was reset when previously marked down, the hardware will be re-initialized. +.It Cm vlan Ar tag +If the interface is a +.Xr vlan 4 +pseudo-interface, set the VLAN tag to +.Ar tag . +This is a 16-bit number which is used to create an 802.1Q VLAN header for +packets sent from the +.Xr vlan 4 +interface. Note that +.Cm vlan +and +.Cm vlanif +must be set at the same time. +.It Cm vlanif Ar iface +If the interface is a +.Xr vlan 4 +pseudo-interface, associate the physical interface +.Ar iface +with it. Packets transmitted through the +.Xr vlan 4 +interface will be diverted to the specified physical interface +.Ar iface +with 802.1Q VLAN encapsulation. Packets with 802.1Q encapsulation received +by the physical interface with the correct VLAN tag will be diverted to the +associated +.Xr vlan 4 +pseudo-interface. The VLAN interface is assigned a copy of the physical +interface's flags and +.Tn Ethernet +address. +If the +.Xr vlan 4 +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. +Note that +.Cm vlanif +and +.Cm vlan +must be set at the same time. .It Cm vltime Ar n (inet6 only) Set valid lifetime for the address. diff --git a/sbin/ifconfig/ifconfig.c b/sbin/ifconfig/ifconfig.c index 6e69047c5771..afb9e1813fc7 100644 --- a/sbin/ifconfig/ifconfig.c +++ b/sbin/ifconfig/ifconfig.c @@ -1,4 +1,4 @@ -/* $NetBSD: ifconfig.c,v 1.88 2000/07/21 04:53:03 onoe Exp $ */ +/* $NetBSD: ifconfig.c,v 1.89 2000/09/27 23:00:24 thorpej Exp $ */ /*- * Copyright (c) 1997, 1998, 2000 The NetBSD Foundation, Inc. @@ -80,7 +80,7 @@ __COPYRIGHT("@(#) Copyright (c) 1983, 1993\n\ #if 0 static char sccsid[] = "@(#)ifconfig.c 8.2 (Berkeley) 2/16/94"; #else -__RCSID("$NetBSD: ifconfig.c,v 1.88 2000/07/21 04:53:03 onoe Exp $"); +__RCSID("$NetBSD: ifconfig.c,v 1.89 2000/09/27 23:00:24 thorpej Exp $"); #endif #endif /* not lint */ @@ -93,6 +93,7 @@ __RCSID("$NetBSD: ifconfig.c,v 1.88 2000/07/21 04:53:03 onoe Exp $"); #include #include #include +#include #include #include #ifdef INET6 @@ -148,6 +149,7 @@ int Lflag; #endif int reset_if_flags; int explicit_prefix = 0; +u_int vlan_tag = (u_int)-1; void notealias __P((const char *, int)); void notrailers __P((const char *, int)); @@ -182,6 +184,9 @@ void setmediainst __P((const char *, int)); void clone_create __P((const char *, int)); void clone_destroy __P((const char *, int)); void fixnsel __P((struct sockaddr_iso *)); +void setvlan __P((const char *, int)); +void setvlanif __P((const char *, int)); +void unsetvlanif __P((const char *, int)); int main __P((int, char *[])); /* @@ -255,6 +260,10 @@ const struct cmd { { "tunnel", NEXTARG2, 0, NULL, settunnel } , { "deletetunnel", 0, 0, deletetunnel }, + { "vlan", NEXTARG, 0, setvlan } , + { "vlanif", NEXTARG, 0, setvlanif } , + { "-vlanif", 0, 0, unsetvlanif } , + { "deletetunnel", 0, 0, deletetunnel }, #if 0 /* XXX `create' special-cased below */ { "create", 0, 0, clone_create } , @@ -322,6 +331,7 @@ void iso_getaddr __P((const char *, int)); void ieee80211_status __P((void)); void tunnel_status __P((void)); +void vlan_status __P((void)); /* Known address families */ struct afswtch { @@ -990,6 +1000,83 @@ deletetunnel(vname, param) err(1, "SIOCDIFPHYADDR"); } +void setvlan(val, d) + const char *val; + int d; +{ + struct vlanreq vlr; + + if (strncmp(ifr.ifr_name, "vlan", 4) != 0 || + !isdigit(ifr.ifr_name[4])) + errx(EXIT_FAILURE, + "``vlan'' valid only with vlan(4) interfaces"); + + vlan_tag = atoi(val); + + memset(&vlr, 0, sizeof(vlr)); + ifr.ifr_data = (caddr_t)&vlr; + + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) + err(EXIT_FAILURE, "SIOCGETVLAN"); + + vlr.vlr_tag = vlan_tag; + + if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) + err(EXIT_FAILURE, "SIOCSETVLAN"); +} + +void setvlanif(val, d) + const char *val; + int d; +{ + struct vlanreq vlr; + + if (strncmp(ifr.ifr_name, "vlan", 4) != 0 || + !isdigit(ifr.ifr_name[4])) + errx(EXIT_FAILURE, + "``vlanif'' valid only with vlan(4) interfaces"); + + if (vlan_tag == (u_int)-1) + errx(EXIT_FAILURE, + "must specify both ``vlan'' and ``vlanif''"); + + memset(&vlr, 0, sizeof(vlr)); + ifr.ifr_data = (caddr_t)&vlr; + + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) + err(EXIT_FAILURE, "SIOCGETVLAN"); + + strlcpy(vlr.vlr_parent, val, sizeof(vlr.vlr_parent)); + vlr.vlr_tag = vlan_tag; + + if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) + err(EXIT_FAILURE, "SIOCSETVLAN"); +} + +void unsetvlanif(val, d) + const char *val; + int d; +{ + struct vlanreq vlr; + + if (strncmp(ifr.ifr_name, "vlan", 4) != 0 || + !isdigit(ifr.ifr_name[4])) + errx(EXIT_FAILURE, + "``vlanif'' valid only with vlan(4) interfaces"); + + memset(&vlr, 0, sizeof(vlr)); + ifr.ifr_data = (caddr_t)&vlr; + + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) + err(EXIT_FAILURE, "SIOCGETVLAN"); + + vlr.vlr_parent[0] = '\0'; + vlr.vlr_tag = 0; + + if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) + err(EXIT_FAILURE, "SIOCSETVLAN"); +} + void setifnetmask(addr, d) const char *addr; @@ -1714,6 +1801,7 @@ status(ap, alen) putchar('\n'); ieee80211_status(); + vlan_status(); tunnel_status(); if (ap && alen > 0) { @@ -1883,6 +1971,27 @@ tunnel_status() psrcaddr, pdstaddr); } +void +vlan_status() +{ + struct vlanreq vlr; + + if (strncmp(ifr.ifr_name, "vlan", 4) != 0 || + !isdigit(ifr.ifr_name[4])) + return; + + memset(&vlr, 0, sizeof(vlr)); + ifr.ifr_data = (caddr_t)&vlr; + + if (ioctl(s, SIOCGETVLAN, (caddr_t)&ifr) == -1) + return; + + if (vlr.vlr_tag || vlr.vlr_parent[0] != '\0') + printf("\tvlan: %d parent: %s\n", + vlr.vlr_tag, vlr.vlr_parent[0] == '\0' ? + "" : vlr.vlr_parent); +} + void in_alias(creq) struct ifreq *creq; @@ -2727,6 +2836,7 @@ usage() "\t[ mediaopt mopts ]\n" "\t[ -mediaopt mopts ]\n" "\t[ instance minst ]\n" + "\t[ vlan n vlanif i ]\n" "\t[ link0 | -link0 ] [ link1 | -link1 ] [ link2 | -link2 ]\n" " %s -a [ -A ] [ -m ] [ -d ] [ -u ] [ af ]\n" " %s -l [ -d ] [ -u ]\n"