diff -ur /pfsense/dev/orig/src/sys/net/if.h /pfsense/src/sys/net/if.h --- /pfsense/dev/orig/src/sys/net/if.h 2014-08-23 20:53:02.000000000 +0200 +++ /pfsense/src/sys/net/if.h 2014-08-23 20:54:01.000000000 +0200 @@ -392,7 +392,6 @@ caddr_t ifru_data; int ifru_cap[2]; u_int ifru_fib; - u_char ifru_vlan_pcp; } ifr_ifru; #define ifr_addr ifr_ifru.ifru_addr /* address */ #define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */ @@ -410,7 +409,6 @@ #define ifr_curcap ifr_ifru.ifru_cap[1] /* current capabilities */ #define ifr_index ifr_ifru.ifru_index /* interface index */ #define ifr_fib ifr_ifru.ifru_fib /* interface fib */ -#define ifr_vlan_pcp ifr_ifru.ifru_vlan_pcp /* VLAN priority */ }; #define _SIZEOF_ADDR_IFREQ(ifr) \ diff -ur /pfsense/dev/orig/src/sys/net/if_lagg.c /pfsense/src/sys/net/if_lagg.c --- /pfsense/dev/orig/src/sys/net/if_lagg.c 2014-08-23 20:53:02.000000000 +0200 +++ /pfsense/src/sys/net/if_lagg.c 2014-08-23 20:54:01.000000000 +0200 @@ -234,7 +234,7 @@ * config EVENT */ static void -lagg_register_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag) +lagg_register_vlan(void *arg, struct ifnet *ifp, u_int16_t vid) { struct lagg_softc *sc = ifp->if_softc; struct lagg_port *lp; @@ -246,7 +246,7 @@ LAGG_RLOCK(sc, &tracker); if (!SLIST_EMPTY(&sc->sc_ports)) { SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) - EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vtag); + EVENTHANDLER_INVOKE(vlan_config, lp->lp_ifp, vid, 0); } LAGG_RUNLOCK(sc, &tracker); } @@ -256,7 +256,7 @@ * unconfig EVENT */ static void -lagg_unregister_vlan(void *arg, struct ifnet *ifp, u_int16_t vtag) +lagg_unregister_vlan(void *arg, struct ifnet *ifp) { struct lagg_softc *sc = ifp->if_softc; struct lagg_port *lp; @@ -268,7 +268,7 @@ LAGG_RLOCK(sc, &tracker); if (!SLIST_EMPTY(&sc->sc_ports)) { SLIST_FOREACH(lp, &sc->sc_ports, lp_entries) - EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp, vtag); + EVENTHANDLER_INVOKE(vlan_unconfig, lp->lp_ifp); } LAGG_RUNLOCK(sc, &tracker); } diff -ur /pfsense/dev/orig/src/sys/net/if_vlan.c /pfsense/src/sys/net/if_vlan.c --- /pfsense/dev/orig/src/sys/net/if_vlan.c 2014-08-23 20:53:02.000000000 +0200 +++ /pfsense/src/sys/net/if_vlan.c 2014-09-12 19:06:25.000000000 +0200 @@ -117,6 +117,7 @@ int ifvm_mintu; /* min transmission unit */ uint16_t ifvm_proto; /* encapsulation ethertype */ uint16_t ifvm_tag; /* tag to apply on packets leaving if */ + int16_t ifvm_vid; /* VLAN ID */ uint8_t ifvm_pcp; /* Priority Code Point (PCP). */ } ifv_mib; SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; @@ -125,7 +126,8 @@ #endif }; #define ifv_proto ifv_mib.ifvm_proto -#define ifv_vid ifv_mib.ifvm_tag +#define ifv_tag ifv_mib.ifvm_tag +#define ifv_vid ifv_mib.ifvm_vid #define ifv_pcp ifv_mib.ifvm_pcp #define ifv_encaplen ifv_mib.ifvm_encaplen #define ifv_mtufudge ifv_mib.ifvm_mtufudge @@ -214,7 +216,7 @@ static int vlan_setmulti(struct ifnet *ifp); static void vlan_unconfig(struct ifnet *ifp); static void vlan_unconfig_locked(struct ifnet *ifp, int departing); -static int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t tag); +static int vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid, uint16_t pcp); static void vlan_link_state(struct ifnet *ifp); static void vlan_capabilities(struct ifvlan *ifv); static void vlan_trunk_capabilities(struct ifnet *ifp); @@ -714,7 +716,7 @@ vlan_tag_recalculate(struct ifvlan *ifv) { - ifv->ifv_mib.ifvm_tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0); + ifv->ifv_tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0); } /* @@ -884,7 +886,7 @@ int wildcard; int unit; int error; - int vid; + int vid, pcp; int ethertag; struct ifvlan *ifv; struct ifnet *ifp; @@ -913,21 +915,19 @@ p = ifunit(vlr.vlr_parent); if (p == NULL) return ENXIO; - /* - * Don't let the caller set up a VLAN VID with - * anything except VLID bits. - */ - if (vlr.vlr_tag & ~EVL_VLID_MASK) - return (EINVAL); + error = ifc_name2unit(name, &unit); if (error != 0) return (error); ethertag = 1; - vid = vlr.vlr_tag; + vid = vlr.vlr_vid; + pcp = vlr.vlr_pcp; wildcard = (unit < 0); } else if ((p = vlan_clone_match_ethervid(ifc, name, &vid)) != NULL) { ethertag = 1; + vid = vlr.vlr_vid; + pcp = 0; /* Default: Best Effort */ unit = -1; wildcard = 0; @@ -939,6 +939,8 @@ return (EINVAL); } else { ethertag = 0; + vid = -1; + pcp = -1; error = ifc_name2unit(name, &unit); if (error != 0) @@ -1000,7 +1002,7 @@ sdl->sdl_type = IFT_L2VLAN; if (ethertag) { - error = vlan_config(ifv, p, vid); + error = vlan_config(ifv, p, vid, pcp); if (error != 0) { /* * Since we've partially failed, we need to back @@ -1133,7 +1135,7 @@ MTAG_8021Q_PCP_OUT, NULL)) != NULL) tag = EVL_MAKETAG(ifv->ifv_vid, *(uint8_t *)(mtag + 1), 0); else - tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0); + tag = ifv->ifv_tag; if (p->if_capenable & IFCAP_VLAN_HWTAGGING) { m->m_pkthdr.ether_vtag = tag; m->m_flags |= M_VLANTAG; @@ -1258,7 +1260,7 @@ } static int -vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid) +vlan_config(struct ifvlan *ifv, struct ifnet *p, uint16_t vid, uint16_t pcp) { struct ifvlantrunk *trunk; struct ifnet *ifp; @@ -1298,7 +1300,7 @@ } ifv->ifv_vid = vid; /* must set this before vlan_inshash() */ - ifv->ifv_pcp = 0; /* Default: best effort delivery. */ + ifv->ifv_pcp = pcp; vlan_tag_recalculate(ifv); error = vlan_inshash(trunk, ifv); if (error) @@ -1377,7 +1379,7 @@ done: TRUNK_UNLOCK(trunk); if (error == 0) - EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid); + EVENTHANDLER_INVOKE(vlan_config, p, ifv->ifv_vid, ifv->ifv_pcp); VLAN_UNLOCK(); return (error); @@ -1473,7 +1475,7 @@ * to cleanup anyway. */ if (parent != NULL) - EVENTHANDLER_INVOKE(vlan_unconfig, parent, ifv->ifv_vid); + EVENTHANDLER_INVOKE(vlan_unconfig, parent); } /* Handle a reference counted flag that should be set on the parent as well */ @@ -1736,15 +1738,12 @@ error = ENOENT; break; } - /* - * Don't let the caller set up a VLAN VID with - * anything except VLID bits. - */ - if (vlr.vlr_tag & ~EVL_VLID_MASK) { - error = EINVAL; - break; - } - error = vlan_config(ifv, p, vlr.vlr_tag); + + error = priv_check(curthread, PRIV_NET_SETVLANPCP); + if (error) + error = vlan_config(ifv, p, vlr.vlr_vid, 0); /* Set default PCP if privilege missing */ + else + error = vlan_config(ifv, p, vlr.vlr_vid, vlr.vlr_pcp); if (error) break; @@ -1764,7 +1763,8 @@ if (TRUNK(ifv) != NULL) { strlcpy(vlr.vlr_parent, PARENT(ifv)->if_xname, sizeof(vlr.vlr_parent)); - vlr.vlr_tag = ifv->ifv_vid; + vlr.vlr_vid = ifv->ifv_vid; + vlr.vlr_pcp = ifv->ifv_pcp; } VLAN_UNLOCK(); error = copyout(&vlr, ifr->ifr_data, sizeof(vlr)); @@ -1793,34 +1793,6 @@ } break; - case SIOCGVLANPCP: -#ifdef VIMAGE - if (ifp->if_vnet != ifp->if_home_vnet) { - error = EPERM; - break; - } -#endif - ifr->ifr_vlan_pcp = ifv->ifv_pcp; - break; - - case SIOCSVLANPCP: -#ifdef VIMAGE - if (ifp->if_vnet != ifp->if_home_vnet) { - error = EPERM; - break; - } -#endif - error = priv_check(curthread, PRIV_NET_SETVLANPCP); - if (error) - break; - if (ifr->ifr_vlan_pcp > 7) { - error = EINVAL; - break; - } - ifv->ifv_pcp = ifr->ifr_vlan_pcp; - vlan_tag_recalculate(ifv); - break; - default: error = EINVAL; break; diff -ur /pfsense/dev/orig/src/sys/net/if_vlan_var.h /pfsense/src/sys/net/if_vlan_var.h --- /pfsense/dev/orig/src/sys/net/if_vlan_var.h 2014-08-23 20:53:02.000000000 +0200 +++ /pfsense/src/sys/net/if_vlan_var.h 2014-08-23 20:54:01.000000000 +0200 @@ -84,7 +84,8 @@ */ struct vlanreq { char vlr_parent[IFNAMSIZ]; - u_short vlr_tag; + u_short vlr_vid; + u_short vlr_pcp; }; #define SIOCSETVLAN SIOCSIFGENERIC #define SIOCGETVLAN SIOCGIFGENERIC diff -ur /pfsense/dev/orig/src/sys/sys/eventhandler.h /pfsense/src/sys/sys/eventhandler.h --- /pfsense/dev/orig/src/sys/sys/eventhandler.h 2014-08-23 20:53:02.000000000 +0200 +++ /pfsense/src/sys/sys/eventhandler.h 2014-08-23 20:54:01.000000000 +0200 @@ -205,8 +205,8 @@ /* VLAN state change events */ struct ifnet; -typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t); -typedef void (*vlan_unconfig_fn)(void *, struct ifnet *, uint16_t); +typedef void (*vlan_config_fn)(void *, struct ifnet *, uint16_t, uint16_t); +typedef void (*vlan_unconfig_fn)(void *, struct ifnet *); EVENTHANDLER_DECLARE(vlan_config, vlan_config_fn); EVENTHANDLER_DECLARE(vlan_unconfig, vlan_unconfig_fn); diff -ur /pfsense/dev/orig/src/sbin/ifconfig/ifvlan.c /pfsense/src/sbin/ifconfig/ifvlan.c --- /pfsense/dev/orig/src/sbin/ifconfig/ifvlan.c 2014-08-23 20:53:02.000000000 +0200 +++ /pfsense/src/sbin/ifconfig/ifvlan.c 2014-08-23 20:54:01.000000000 +0200 @@ -63,10 +63,11 @@ "$FreeBSD$"; #endif -#define NOTAG ((u_short) -1) +#define NOPARAM ((u_short) -1) static struct vlanreq params = { - .vlr_tag = NOTAG, + .vlr_vid = NOPARAM, + .vlr_pcp = NOPARAM, }; static int @@ -85,9 +86,8 @@ if (getvlan(s, &ifr, &vreq) == -1) return; - printf("\tvlan: %d", vreq.vlr_tag); - if (ioctl(s, SIOCGVLANPCP, (caddr_t)&ifr) != -1) - printf(" vlanpcp: %u", ifr.ifr_vlan_pcp); + printf("\tvlan: %u", vreq.vlr_vid); + printf(" pcp: %u", vreq.vlr_pcp); printf(" parent interface: %s", vreq.vlr_parent[0] == '\0' ? "" : vreq.vlr_parent); printf("\n"); @@ -96,14 +96,18 @@ static void vlan_create(int s, struct ifreq *ifr) { - if (params.vlr_tag != NOTAG || params.vlr_parent[0] != '\0') { + if (params.vlr_vid != NOPARAM || params.vlr_parent[0] != '\0') { /* * One or both parameters were specified, make sure both. */ - if (params.vlr_tag == NOTAG) - errx(1, "must specify a tag for vlan create"); + if (params.vlr_vid == NOPARAM) + errx(1, "must specify a vid for vlan create"); if (params.vlr_parent[0] == '\0') errx(1, "must specify a parent device for vlan create"); + + if (params.vlr_pcp == NOPARAM) + params.vlr_pcp = 0; /* Best Effort by default */ + ifr->ifr_data = (caddr_t) ¶ms; } if (ioctl(s, SIOCIFCREATE2, ifr) < 0) @@ -113,14 +117,16 @@ static void vlan_cb(int s, void *arg) { - if ((params.vlr_tag != NOTAG) ^ (params.vlr_parent[0] != '\0')) + if ((params.vlr_vid != NOPARAM) ^ (params.vlr_parent[0] != '\0')) errx(1, "both vlan and vlandev must be specified"); } static void vlan_set(int s, struct ifreq *ifr) { - if (params.vlr_tag != NOTAG && params.vlr_parent[0] != '\0') { + if (params.vlr_vid != NOPARAM && params.vlr_parent[0] != '\0') { + if (params.vlr_pcp == NOPARAM) + params.vlr_pcp = 0; /* Set to Best Effort by default */ ifr->ifr_data = (caddr_t) ¶ms; if (ioctl(s, SIOCSETVLAN, (caddr_t)ifr) == -1) err(1, "SIOCSETVLAN"); @@ -128,7 +134,7 @@ } static -DECL_CMD_FUNC(setvlantag, val, d) +DECL_CMD_FUNC(setvlanvid, val, d) { struct vlanreq vreq; u_long ul; @@ -137,9 +143,9 @@ ul = strtoul(val, &endp, 0); if (*endp != '\0') errx(1, "invalid value for vlan"); - params.vlr_tag = ul; - /* check if the value can be represented in vlr_tag */ - if (params.vlr_tag != ul) + params.vlr_vid = ul; + /* check if the value can be represented in vlr_vid */ + if (params.vlr_vid != ul) errx(1, "value for vlan out of range"); if (getvlan(s, &ifr, &vreq) != -1) @@ -160,6 +166,7 @@ static DECL_CMD_FUNC(setvlanpcp, val, d) { + struct vlanreq vreq; u_long ul; char *endp; @@ -168,9 +175,10 @@ errx(1, "invalid value for vlanpcp"); if (ul > 7) errx(1, "value for vlanpcp out of range"); - ifr.ifr_vlan_pcp = ul; - if (ioctl(s, SIOCSVLANPCP, (caddr_t)&ifr) == -1) - err(1, "SIOCSVLANPCP"); + + params.vlr_pcp = ul; + if (getvlan(s, &ifr, &vreq) != -1) + vlan_set(s, &ifr); } static @@ -185,18 +193,17 @@ 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"); } static struct cmd vlan_cmds[] = { - DEF_CLONE_CMD_ARG("vlan", setvlantag), + DEF_CLONE_CMD_ARG("vlan", setvlanvid), DEF_CLONE_CMD_ARG("vlandev", setvlandev), DEF_CMD_ARG("vlanpcp", setvlanpcp), /* NB: non-clone cmds */ - DEF_CMD_ARG("vlan", setvlantag), + DEF_CMD_ARG("vlan", setvlanvid), DEF_CMD_ARG("vlandev", setvlandev), /* XXX For compatibility. Should become DEF_CMD() some day. */ DEF_CMD_OPTARG("-vlandev", unsetvlandev),