Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -2298,6 +2298,7 @@ struct ifnet *(*vlan_trunkdev_p)(struct ifnet *); struct ifnet *(*vlan_devat_p)(struct ifnet *, uint16_t); int (*vlan_tag_p)(struct ifnet *, uint16_t *); +int (*vlan_pcp_p)(struct ifnet *, uint16_t *); int (*vlan_setcookie_p)(struct ifnet *, void *); void *(*vlan_cookie_p)(struct ifnet *); Index: sys/net/if_vlan.c =================================================================== --- sys/net/if_vlan.c +++ sys/net/if_vlan.c @@ -758,6 +758,18 @@ return (0); } +static int +vlan_pcp(struct ifnet *ifp, uint16_t *pcpp) +{ + struct ifvlan *ifv; + + if (ifp->if_type != IFT_L2VLAN) + return (EINVAL); + ifv = ifp->if_softc; + *pcpp = ifv->ifv_pcp; + return (0); +} + /* * Return a driver specific cookie for this interface. Synchronization * with setcookie must be provided by the driver. @@ -861,6 +873,7 @@ vlan_cookie_p = vlan_cookie; vlan_setcookie_p = vlan_setcookie; vlan_tag_p = vlan_tag; + vlan_pcp_p = vlan_pcp; vlan_devat_p = vlan_devat; #ifndef VIMAGE vlan_cloner = if_clone_advanced(vlanname, 0, vlan_clone_match, Index: sys/net/if_vlan_var.h =================================================================== --- sys/net/if_vlan_var.h +++ sys/net/if_vlan_var.h @@ -132,6 +132,8 @@ ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_trunkdev_p)((_ifp)) : NULL) #define VLAN_TAG(_ifp, _vid) \ ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_tag_p)((_ifp), (_vid)) : EINVAL) +#define VLAN_PCP(_ifp, _pcp) \ + ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_pcp_p)((_ifp), (_pcp)) : EINVAL) #define VLAN_COOKIE(_ifp) \ ((_ifp)->if_type == IFT_L2VLAN ? (*vlan_cookie_p)((_ifp)) : NULL) #define VLAN_SETCOOKIE(_ifp, _cookie) \ @@ -144,6 +146,7 @@ extern struct ifnet *(*vlan_trunkdev_p)(struct ifnet *); extern struct ifnet *(*vlan_devat_p)(struct ifnet *, uint16_t); extern int (*vlan_tag_p)(struct ifnet *, uint16_t *); +extern int (*vlan_pcp_p)(struct ifnet *, uint16_t *); extern int (*vlan_setcookie_p)(struct ifnet *, void *); extern void *(*vlan_cookie_p)(struct ifnet *); Index: sys/netinet/toecore.c =================================================================== --- sys/netinet/toecore.c +++ sys/netinet/toecore.c @@ -400,7 +400,7 @@ struct ifnet *ifp; struct sockaddr *sa; uint8_t *lladdr; - uint16_t vtag; + uint16_t vid, pcp; int family; struct sockaddr_in6 sin6; @@ -425,7 +425,8 @@ sa = (struct sockaddr *)&sin6; lltable_fill_sa_entry(lle, sa); - vtag = 0xfff; + vid = 0xfff; + pcp = 0; if (evt != LLENTRY_RESOLVED) { /* @@ -440,12 +441,11 @@ ("%s: %p resolved but not valid?", __func__, lle)); lladdr = (uint8_t *)lle->ll_addr; -#ifdef VLAN_TAG - VLAN_TAG(ifp, &vtag); -#endif + VLAN_TAG(ifp, &vid); + VLAN_PCP(ifp, &pcp); } - tod->tod_l2_update(tod, ifp, sa, lladdr, vtag); + tod->tod_l2_update(tod, ifp, sa, lladdr, EVL_MAKETAG(vid, pcp, 0)); } /* @@ -458,6 +458,7 @@ uint8_t *lladdr, uint16_t *vtag) { int rc; + uint16_t vid, pcp; switch (sa->sa_family) { #ifdef INET @@ -475,10 +476,16 @@ } if (rc == 0) { -#ifdef VLAN_TAG - if (VLAN_TAG(ifp, vtag) != 0) -#endif - *vtag = 0xfff; + vid = 0xfff; + pcp = 0; + if (ifp->if_type == IFT_L2VLAN) { + VLAN_TAG(ifp, &vid); + VLAN_PCP(ifp, &pcp); + } else if (ifp->if_pcp != IFNET_PCP_NONE) { + vid = 0; + pcp = ifp->if_pcp; + } + *vtag = EVL_MAKETAG(vid, pcp, 0); } return (rc);