Feature #4133 » pf_pcp_source.diff
| /pfsense/src/sys/net/if.h 2014-08-23 20:54:01.000000000 +0200 | ||
|---|---|---|
| 392 | 392 |
caddr_t ifru_data; |
| 393 | 393 |
int ifru_cap[2]; |
| 394 | 394 |
u_int ifru_fib; |
| 395 |
u_char ifru_vlan_pcp; |
|
| 396 | 395 |
} ifr_ifru; |
| 397 | 396 |
#define ifr_addr ifr_ifru.ifru_addr /* address */ |
| 398 | 397 |
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ |
| ... | ... | |
| 410 | 409 |
#define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */ |
| 411 | 410 |
#define ifr_index ifr_ifru.ifru_index /* interface index */ |
| 412 | 411 |
#define ifr_fib ifr_ifru.ifru_fib /* interface fib */ |
| 413 |
#define ifr_vlan_pcp ifr_ifru.ifru_vlan_pcp /* VLAN priority */ |
|
| 414 | 412 |
}; |
| 415 | 413 | |
| 416 | 414 |
#define _SIZEOF_ADDR_IFREQ(ifr) \ |
| /pfsense/src/sys/net/if_lagg.c 2014-08-23 20:54:01.000000000 +0200 | ||
|---|---|---|
| 234 | 234 |
* config EVENT |
| 235 | 235 |
*/ |
| 236 | 236 |
static void |
| 237 |
lagg_register_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag)
|
|
| 237 |
lagg_register_vlan(void *arg, struct ifnet *ifp, u_int16_t vid)
|
|
| 238 | 238 |
{
|
| 239 | 239 |
struct lagg_softc *sc = ifp->if_softc; |
| 240 | 240 |
struct lagg_port *lp; |
| ... | ... | |
| 246 | 246 |
LAGG_RLOCK(sc, &tracker); |
| 247 | 247 |
if (!SLIST_EMPTY(&sc->sc_ports)) {
|
| 248 | 248 |
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) |
| 249 |
EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vtag);
|
|
| 249 |
EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vid, 0);
|
|
| 250 | 250 |
} |
| 251 | 251 |
LAGG_RUNLOCK(sc, &tracker); |
| 252 | 252 |
} |
| ... | ... | |
| 256 | 256 |
* unconfig EVENT |
| 257 | 257 |
*/ |
| 258 | 258 |
static void |
| 259 |
lagg_unregister_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag)
|
|
| 259 |
lagg_unregister_vlan(void *arg, struct ifnet *ifp) |
|
| 260 | 260 |
{
|
| 261 | 261 |
struct lagg_softc *sc = ifp->if_softc; |
| 262 | 262 |
struct lagg_port *lp; |
| ... | ... | |
| 268 | 268 |
LAGG_RLOCK(sc, &tracker); |
| 269 | 269 |
if (!SLIST_EMPTY(&sc->sc_ports)) {
|
| 270 | 270 |
SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) |
| 271 |
EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp, vtag);
|
|
| 271 |
EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp); |
|
| 272 | 272 |
} |
| 273 | 273 |
LAGG_RUNLOCK(sc, &tracker); |
| 274 | 274 |
} |
| /pfsense/src/sys/net/if_vlan.c 2014-09-12 19:06:25.000000000 +0200 | ||
|---|---|---|
| 117 | 117 |
int ifvm_mintu; /* min transmission unit */ |
| 118 | 118 |
uint16_t ifvm_proto; /* encapsulation ethertype */ |
| 119 | 119 |
uint16_t ifvm_tag; /* tag to apply on packets leaving if */ |
| 120 |
int16_t ifvm_vid; /* VLAN ID */ |
|
| 120 | 121 |
uint8_t ifvm_pcp; /* Priority Code Point (PCP). */ |
| 121 | 122 |
} ifv_mib; |
| 122 | 123 |
SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; |
| ... | ... | |
| 125 | 126 |
#endif |
| 126 | 127 |
}; |
| 127 | 128 |
#define ifv_proto ifv_mib.ifvm_proto |
| 128 |
#define ifv_vid ifv_mib.ifvm_tag |
|
| 129 |
#define ifv_tag ifv_mib.ifvm_tag |
|
| 130 |
#define ifv_vid ifv_mib.ifvm_vid |
|
| 129 | 131 |
#define ifv_pcp ifv_mib.ifvm_pcp |
| 130 | 132 |
#define ifv_encaplen ifv_mib.ifvm_encaplen |
| 131 | 133 |
#define ifv_mtufudge ifv_mib.ifvm_mtufudge |
| ... | ... | |
| 214 | 216 |
static int vlan_setmulti(struct ifnet *ifp); |
| 215 | 217 |
static void vlan_unconfig(struct ifnet *ifp); |
| 216 | 218 |
static void vlan_unconfig_locked(struct ifnet *ifp, int departing); |
| 217 |
static int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag);
|
|
| 219 |
static int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid, uint16_t pcp);
|
|
| 218 | 220 |
static void vlan_link_state(struct ifnet *ifp); |
| 219 | 221 |
static void vlan_capabilities(struct ifvlan *ifv); |
| 220 | 222 |
static void vlan_trunk_capabilities(struct ifnet *ifp); |
| ... | ... | |
| 714 | 716 |
vlan_tag_recalculate(struct ifvlan *ifv) |
| 715 | 717 |
{
|
| 716 | 718 | |
| 717 |
ifv->ifv_mib.ifvm_tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0);
|
|
| 719 |
ifv->ifv_tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0); |
|
| 718 | 720 |
} |
| 719 | 721 | |
| 720 | 722 |
/* |
| ... | ... | |
| 884 | 886 |
int wildcard; |
| 885 | 887 |
int unit; |
| 886 | 888 |
int error; |
| 887 |
int vid; |
|
| 889 |
int vid, pcp;
|
|
| 888 | 890 |
int ethertag; |
| 889 | 891 |
struct ifvlan *ifv; |
| 890 | 892 |
struct ifnet *ifp; |
| ... | ... | |
| 913 | 915 |
p = ifunit(vlr.vlr_parent); |
| 914 | 916 |
if (p == NULL) |
| 915 | 917 |
return ENXIO; |
| 916 |
/* |
|
| 917 |
* Don't let the caller set up a VLAN VID with |
|
| 918 |
* anything except VLID bits. |
|
| 919 |
*/ |
|
| 920 |
if (vlr.vlr_tag & ~EVL_VLID_MASK) |
|
| 921 |
return (EINVAL); |
|
| 918 | ||
| 922 | 919 |
error = ifc_name2unit(name, &unit); |
| 923 | 920 |
if (error != 0) |
| 924 | 921 |
return (error); |
| 925 | 922 | |
| 926 | 923 |
ethertag = 1; |
| 927 |
vid = vlr.vlr_tag; |
|
| 924 |
vid = vlr.vlr_vid; |
|
| 925 |
pcp = vlr.vlr_pcp; |
|
| 928 | 926 |
wildcard = (unit < 0); |
| 929 | 927 |
} else if ((p = vlan_clone_match_ethervid(ifc, name, &vid)) != NULL) {
|
| 930 | 928 |
ethertag = 1; |
| 929 |
vid = vlr.vlr_vid; |
|
| 930 |
pcp = 0; /* Default: Best Effort */ |
|
| 931 | 931 |
unit = -1; |
| 932 | 932 |
wildcard = 0; |
| 933 | 933 | |
| ... | ... | |
| 939 | 939 |
return (EINVAL); |
| 940 | 940 |
} else {
|
| 941 | 941 |
ethertag = 0; |
| 942 |
vid = -1; |
|
| 943 |
pcp = -1; |
|
| 942 | 944 | |
| 943 | 945 |
error = ifc_name2unit(name, &unit); |
| 944 | 946 |
if (error != 0) |
| ... | ... | |
| 1000 | 1002 |
sdl->sdl_type = IFT_L2VLAN; |
| 1001 | 1003 | |
| 1002 | 1004 |
if (ethertag) {
|
| 1003 |
error = vlan_config(ifv, p, vid); |
|
| 1005 |
error = vlan_config(ifv, p, vid, pcp);
|
|
| 1004 | 1006 |
if (error != 0) {
|
| 1005 | 1007 |
/* |
| 1006 | 1008 |
* Since we've partially failed, we need to back |
| ... | ... | |
| 1133 | 1135 |
MTAG_8021Q_PCP_OUT, NULL)) != NULL) |
| 1134 | 1136 |
tag = EVL_MAKETAG(ifv->ifv_vid, *(uint8_t *)(mtag + 1), 0); |
| 1135 | 1137 |
else |
| 1136 |
tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0);
|
|
| 1138 |
tag = ifv->ifv_tag;
|
|
| 1137 | 1139 |
if (p->if_capenable & IFCAP_VLAN_HWTAGGING) {
|
| 1138 | 1140 |
m->m_pkthdr.ether_vtag = tag; |
| 1139 | 1141 |
m->m_flags |= M_VLANTAG; |
| ... | ... | |
| 1258 | 1260 |
} |
| 1259 | 1261 | |
| 1260 | 1262 |
static int |
| 1261 |
vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) |
|
| 1263 |
vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid, uint16_t pcp)
|
|
| 1262 | 1264 |
{
|
| 1263 | 1265 |
struct ifvlantrunk *trunk; |
| 1264 | 1266 |
struct ifnet *ifp; |
| ... | ... | |
| 1298 | 1300 |
} |
| 1299 | 1301 | |
| 1300 | 1302 |
ifv->ifv_vid = vid; /* must set this before vlan_inshash() */ |
| 1301 |
ifv->ifv_pcp = 0; /* Default: best effort delivery. */
|
|
| 1303 |
ifv->ifv_pcp = pcp;
|
|
| 1302 | 1304 |
vlan_tag_recalculate(ifv); |
| 1303 | 1305 |
error = vlan_inshash(trunk, ifv); |
| 1304 | 1306 |
if (error) |
| ... | ... | |
| 1377 | 1379 |
done: |
| 1378 | 1380 |
TRUNK_UNLOCK(trunk); |
| 1379 | 1381 |
if (error == 0) |
| 1380 |
EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid); |
|
| 1382 |
EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid, ifv->ifv_pcp);
|
|
| 1381 | 1383 |
VLAN_UNLOCK(); |
| 1382 | 1384 | |
| 1383 | 1385 |
return (error); |
| ... | ... | |
| 1473 | 1475 |
* to cleanup anyway. |
| 1474 | 1476 |
*/ |
| 1475 | 1477 |
if (parent != NULL) |
| 1476 |
EVENTHANDLER_INVOKE(vlan_unconfig, parent, ifv->ifv_vid);
|
|
| 1478 |
EVENTHANDLER_INVOKE(vlan_unconfig, parent); |
|
| 1477 | 1479 |
} |
| 1478 | 1480 | |
| 1479 | 1481 |
/* Handle a reference counted flag that should be set on the parent as well */ |
| ... | ... | |
| 1736 | 1738 |
error = ENOENT; |
| 1737 | 1739 |
break; |
| 1738 | 1740 |
} |
| 1739 |
/* |
|
| 1740 |
* Don't let the caller set up a VLAN VID with |
|
| 1741 |
* anything except VLID bits. |
|
| 1742 |
*/ |
|
| 1743 |
if (vlr.vlr_tag & ~EVL_VLID_MASK) {
|
|
| 1744 |
error = EINVAL; |
|
| 1745 |
break; |
|
| 1746 |
} |
|
| 1747 |
error = vlan_config(ifv, p, vlr.vlr_tag); |
|
| 1741 | ||
| 1742 |
error = priv_check(curthread, PRIV_NET_SETVLANPCP); |
|
| 1743 |
if (error) |
|
| 1744 |
error = vlan_config(ifv, p, vlr.vlr_vid, 0); /* Set default PCP if privilege missing */ |
|
| 1745 |
else |
|
| 1746 |
error = vlan_config(ifv, p, vlr.vlr_vid, vlr.vlr_pcp); |
|
| 1748 | 1747 |
if (error) |
| 1749 | 1748 |
break; |
| 1750 | 1749 | |
| ... | ... | |
| 1764 | 1763 |
if (TRUNK(ifv) != NULL) {
|
| 1765 | 1764 |
strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname, |
| 1766 | 1765 |
sizeof(vlr.vlr_parent)); |
| 1767 |
vlr.vlr_tag = ifv->ifv_vid; |
|
| 1766 |
vlr.vlr_vid = ifv->ifv_vid; |
|
| 1767 |
vlr.vlr_pcp = ifv->ifv_pcp; |
|
| 1768 | 1768 |
} |
| 1769 | 1769 |
VLAN_UNLOCK(); |
| 1770 | 1770 |
error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); |
| ... | ... | |
| 1793 | 1793 |
} |
| 1794 | 1794 |
break; |
| 1795 | 1795 | |
| 1796 |
case SIOCGVLANPCP: |
|
| 1797 |
#ifdef VIMAGE |
|
| 1798 |
if (ifp->if_vnet != ifp->if_home_vnet) {
|
|
| 1799 |
error = EPERM; |
|
| 1800 |
break; |
|
| 1801 |
} |
|
| 1802 |
#endif |
|
| 1803 |
ifr->ifr_vlan_pcp = ifv->ifv_pcp; |
|
| 1804 |
break; |
|
| 1805 | ||
| 1806 |
case SIOCSVLANPCP: |
|
| 1807 |
#ifdef VIMAGE |
|
| 1808 |
if (ifp->if_vnet != ifp->if_home_vnet) {
|
|
| 1809 |
error = EPERM; |
|
| 1810 |
break; |
|
| 1811 |
} |
|
| 1812 |
#endif |
|
| 1813 |
error = priv_check(curthread, PRIV_NET_SETVLANPCP); |
|
| 1814 |
if (error) |
|
| 1815 |
break; |
|
| 1816 |
if (ifr->ifr_vlan_pcp > 7) {
|
|
| 1817 |
error = EINVAL; |
|
| 1818 |
break; |
|
| 1819 |
} |
|
| 1820 |
ifv->ifv_pcp = ifr->ifr_vlan_pcp; |
|
| 1821 |
vlan_tag_recalculate(ifv); |
|
| 1822 |
break; |
|
| 1823 | ||
| 1824 | 1796 |
default: |
| 1825 | 1797 |
error = EINVAL; |
| 1826 | 1798 |
break; |
| /pfsense/src/sys/net/if_vlan_var.h 2014-08-23 20:54:01.000000000 +0200 | ||
|---|---|---|
| 84 | 84 |
*/ |
| 85 | 85 |
struct vlanreq {
|
| 86 | 86 |
char vlr_parent[IFNAMSIZ]; |
| 87 |
u_short vlr_tag; |
|
| 87 |
u_short vlr_vid; |
|
| 88 |
u_short vlr_pcp; |
|
| 88 | 89 |
}; |
| 89 | 90 |
#define SIOCSETVLAN SIOCSIFGENERIC |
| 90 | 91 |
#define SIOCGETVLAN SIOCGIFGENERIC |
| /pfsense/src/sys/sys/eventhandler.h 2014-08-23 20:54:01.000000000 +0200 | ||
|---|---|---|
| 205 | 205 | |
| 206 | 206 |
/* VLAN state change events */ |
| 207 | 207 |
struct ifnet; |
| 208 |
typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t); |
|
| 209 |
typedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t);
|
|
| 208 |
typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t, uint16_t);
|
|
| 209 |
typedef void (*vlan_unconfig_fn)(void *, struct ifnet *); |
|
| 210 | 210 |
EVENTHANDLER_DECLARE(vlan_config, vlan_config_fn); |
| 211 | 211 |
EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); |
| 212 | 212 | |
| /pfsense/src/sbin/ifconfig/ifvlan.c 2014-08-23 20:54:01.000000000 +0200 | ||
|---|---|---|
| 63 | 63 |
"$FreeBSD$"; |
| 64 | 64 |
#endif |
| 65 | 65 | |
| 66 |
#define NOTAG ((u_short) -1)
|
|
| 66 |
#define NOPARAM ((u_short) -1)
|
|
| 67 | 67 | |
| 68 | 68 |
static struct vlanreq params = {
|
| 69 |
.vlr_tag = NOTAG, |
|
| 69 |
.vlr_vid = NOPARAM, |
|
| 70 |
.vlr_pcp = NOPARAM, |
|
| 70 | 71 |
}; |
| 71 | 72 | |
| 72 | 73 |
static int |
| ... | ... | |
| 85 | 86 | |
| 86 | 87 |
if (getvlan(s, &ifr, &vreq) == -1) |
| 87 | 88 |
return; |
| 88 |
printf("\tvlan: %d", vreq.vlr_tag);
|
|
| 89 |
if (ioctl(s, SIOCGVLANPCP, (caddr_t)&ifr) != -1) |
|
| 90 |
printf(" vlanpcp: %u", ifr.ifr_vlan_pcp);
|
|
| 89 |
printf("\tvlan: %u", vreq.vlr_vid);
|
|
| 90 |
printf(" pcp: %u", vreq.vlr_pcp);
|
|
| 91 | 91 |
printf(" parent interface: %s", vreq.vlr_parent[0] == '\0' ?
|
| 92 | 92 |
"<none>" : vreq.vlr_parent); |
| 93 | 93 |
printf("\n");
|
| ... | ... | |
| 96 | 96 |
static void |
| 97 | 97 |
vlan_create(int s, struct ifreq *ifr) |
| 98 | 98 |
{
|
| 99 |
if (params.vlr_tag != NOTAG || params.vlr_parent[0] != '\0') {
|
|
| 99 |
if (params.vlr_vid != NOPARAM || params.vlr_parent[0] != '\0') {
|
|
| 100 | 100 |
/* |
| 101 | 101 |
* One or both parameters were specified, make sure both. |
| 102 | 102 |
*/ |
| 103 |
if (params.vlr_tag == NOTAG)
|
|
| 104 |
errx(1, "must specify a tag for vlan create");
|
|
| 103 |
if (params.vlr_vid == NOPARAM)
|
|
| 104 |
errx(1, "must specify a vid for vlan create");
|
|
| 105 | 105 |
if (params.vlr_parent[0] == '\0') |
| 106 | 106 |
errx(1, "must specify a parent device for vlan create"); |
| 107 |
|
|
| 108 |
if (params.vlr_pcp == NOPARAM) |
|
| 109 |
params.vlr_pcp = 0; /* Best Effort by default */ |
|
| 110 |
|
|
| 107 | 111 |
ifr->ifr_data = (caddr_t) ¶ms; |
| 108 | 112 |
} |
| 109 | 113 |
if (ioctl(s, SIOCIFCREATE2, ifr) < 0) |
| ... | ... | |
| 113 | 117 |
static void |
| 114 | 118 |
vlan_cb(int s, void *arg) |
| 115 | 119 |
{
|
| 116 |
if ((params.vlr_tag != NOTAG) ^ (params.vlr_parent[0] != '\0'))
|
|
| 120 |
if ((params.vlr_vid != NOPARAM) ^ (params.vlr_parent[0] != '\0'))
|
|
| 117 | 121 |
errx(1, "both vlan and vlandev must be specified"); |
| 118 | 122 |
} |
| 119 | 123 | |
| 120 | 124 |
static void |
| 121 | 125 |
vlan_set(int s, struct ifreq *ifr) |
| 122 | 126 |
{
|
| 123 |
if (params.vlr_tag != NOTAG && params.vlr_parent[0] != '\0') {
|
|
| 127 |
if (params.vlr_vid != NOPARAM && params.vlr_parent[0] != '\0') {
|
|
| 128 |
if (params.vlr_pcp == NOPARAM) |
|
| 129 |
params.vlr_pcp = 0; /* Set to Best Effort by default */ |
|
| 124 | 130 |
ifr->ifr_data = (caddr_t) ¶ms; |
| 125 | 131 |
if (ioctl(s, SIOCSETVLAN, (caddr_t)ifr) == -1) |
| 126 | 132 |
err(1, "SIOCSETVLAN"); |
| ... | ... | |
| 128 | 134 |
} |
| 129 | 135 | |
| 130 | 136 |
static |
| 131 |
DECL_CMD_FUNC(setvlantag, val, d)
|
|
| 137 |
DECL_CMD_FUNC(setvlanvid, val, d)
|
|
| 132 | 138 |
{
|
| 133 | 139 |
struct vlanreq vreq; |
| 134 | 140 |
u_long ul; |
| ... | ... | |
| 137 | 143 |
ul = strtoul(val, &endp, 0); |
| 138 | 144 |
if (*endp != '\0') |
| 139 | 145 |
errx(1, "invalid value for vlan"); |
| 140 |
params.vlr_tag = ul;
|
|
| 141 |
/* check if the value can be represented in vlr_tag */
|
|
| 142 |
if (params.vlr_tag != ul)
|
|
| 146 |
params.vlr_vid = ul;
|
|
| 147 |
/* check if the value can be represented in vlr_vid */
|
|
| 148 |
if (params.vlr_vid != ul)
|
|
| 143 | 149 |
errx(1, "value for vlan out of range"); |
| 144 | 150 | |
| 145 | 151 |
if (getvlan(s, &ifr, &vreq) != -1) |
| ... | ... | |
| 160 | 166 |
static |
| 161 | 167 |
DECL_CMD_FUNC(setvlanpcp, val, d) |
| 162 | 168 |
{
|
| 169 |
struct vlanreq vreq; |
|
| 163 | 170 |
u_long ul; |
| 164 | 171 |
char *endp; |
| 165 | 172 | |
| ... | ... | |
| 168 | 175 |
errx(1, "invalid value for vlanpcp"); |
| 169 | 176 |
if (ul > 7) |
| 170 | 177 |
errx(1, "value for vlanpcp out of range"); |
| 171 |
ifr.ifr_vlan_pcp = ul; |
|
| 172 |
if (ioctl(s, SIOCSVLANPCP, (caddr_t)&ifr) == -1) |
|
| 173 |
err(1, "SIOCSVLANPCP"); |
|
| 178 |
|
|
| 179 |
params.vlr_pcp = ul; |
|
| 180 |
if (getvlan(s, &ifr, &vreq) != -1) |
|
| 181 |
vlan_set(s, &ifr); |
|
| 174 | 182 |
} |
| 175 | 183 | |
| 176 | 184 |
static |
| ... | ... | |
| 185 | 193 |
err(1, "SIOCGETVLAN"); |
| 186 | 194 | |
| 187 | 195 |
bzero((char *)&vreq.vlr_parent, sizeof(vreq.vlr_parent)); |
| 188 |
vreq.vlr_tag = 0; |
|
| 189 | 196 | |
| 190 | 197 |
if (ioctl(s, SIOCSETVLAN, (caddr_t)&ifr) == -1) |
| 191 | 198 |
err(1, "SIOCSETVLAN"); |
| 192 | 199 |
} |
| 193 | 200 | |
| 194 | 201 |
static struct cmd vlan_cmds[] = {
|
| 195 |
DEF_CLONE_CMD_ARG("vlan", setvlantag),
|
|
| 202 |
DEF_CLONE_CMD_ARG("vlan", setvlanvid),
|
|
| 196 | 203 |
DEF_CLONE_CMD_ARG("vlandev", setvlandev),
|
| 197 | 204 |
DEF_CMD_ARG("vlanpcp", setvlanpcp),
|
| 198 | 205 |
/* NB: non-clone cmds */ |
| 199 |
DEF_CMD_ARG("vlan", setvlantag),
|
|
| 206 |
DEF_CMD_ARG("vlan", setvlanvid),
|
|
| 200 | 207 |
DEF_CMD_ARG("vlandev", setvlandev),
|
| 201 | 208 |
/* XXX For compatibility. Should become DEF_CMD() some day. */ |
| 202 | 209 |
DEF_CMD_OPTARG("-vlandev", unsetvlandev),
|