Date: Tue, 7 Jun 2016 09:15:31 +0800 From: Marcelo Araujo <araujobsdport@gmail.com> To: Slawa Olhovchenkov <slw@zxy.spb.ru> Cc: "src-committers@freebsd.org" <src-committers@freebsd.org>, "svn-src-all@freebsd.org" <svn-src-all@freebsd.org>, "svn-src-head@freebsd.org" <svn-src-head@freebsd.org> Subject: Re: svn commit: r301496 - in head: sbin/ifconfig share/man/man4 sys/net sys/sys Message-ID: <CAOfEmZh5cwd5tyrmukSSCYOd%2Bfqo1KgpT4PaLwDVanP54m2ACQ@mail.gmail.com> In-Reply-To: <20160606165431.GF75625@zxy.spb.ru> References: <201606060951.u569pwOI063390@repo.freebsd.org> <20160606165431.GF75625@zxy.spb.ru>
next in thread | previous in thread | raw e-mail | index | archive | help
Hi, Because 802.1p is Layer 2 and on its specification it sets video to 4, what DSCP does is convert those 3-bits to use on Layer 3 and try to do the CoS as close as possible with 802.1p. Best, 2016-06-07 0:54 GMT+08:00 Slawa Olhovchenkov <slw@zxy.spb.ru>: > On Mon, Jun 06, 2016 at 09:51:58AM +0000, Marcelo Araujo wrote: > > > Author: araujo > > Date: Mon Jun 6 09:51:58 2016 > > New Revision: 301496 > > URL: https://svnweb.freebsd.org/changeset/base/301496 > > > > Log: > > Add support to priority code point (PCP) that is an 3-bit field > > which refers to IEEE 802.1p class of service and maps to the frame > > priority level. > > > > Values in order of priority are: 1 (Background (lowest)), > > 0 (Best effort (default)), 2 (Excellent effort), > > 3 (Critical applications), 4 (Video, < 100ms latency), > > 5 (Video, < 10ms latency), 6 (Internetwork control) and > > 7 (Network control (highest)). > > What purpose to use 4 for video? > > http://www.cisco.com/c/en/us/td/docs/switches/datacenter/nexus1000/sw/4_0/qos/configuration/guide/nexus1000v_qos/qos_6dscp_val.pdf > point video is 3. > > > Example of usage: > > root# ifconfig em0.1 create > > root# ifconfig em0.1 vlanpcp 3 > > > > Note: > > The review D801 includes the pf(4) part, but as discussed with kristof, > > we won't commit the pf(4) bits for now. > > The credits of the original code is from rwatson. > > > > Differential Revision: https://reviews.freebsd.org/D801 > > Reviewed by: gnn, adrian, loos > > Discussed with: rwatson, glebius, kristof > > Tested by: many including Matthew Grooms <mgrooms__shrew.net> > > Obtained from: pfSense > > Relnotes: Yes > > > > Modified: > > head/sbin/ifconfig/ifconfig.8 > > head/sbin/ifconfig/ifvlan.c > > head/share/man/man4/vlan.4 > > head/sys/net/if.h > > head/sys/net/if_vlan.c > > head/sys/net/if_vlan_var.h > > head/sys/sys/priv.h > > > > Modified: head/sbin/ifconfig/ifconfig.8 > > > ============================================================================== > > --- head/sbin/ifconfig/ifconfig.8 Mon Jun 6 09:30:31 2016 > (r301495) > > +++ head/sbin/ifconfig/ifconfig.8 Mon Jun 6 09:51:58 2016 > (r301496) > > @@ -2614,6 +2614,29 @@ Note that > > and > > .Cm vlandev > > must both be set at the same time. > > +.It Cm vlanpcp Ar priority_code_point > > +Priority code point > > +.Pq Dv PCP > > +is an 3-bit field which refers to the IEEE 802.1p > > +class of service and maps to the frame priority level. > > +.Pp > > +Values in order of priority are: > > +.Cm 1 > > +.Pq Dv Background (lowest) , > > +.Cm 0 > > +.Pq Dv Best effort (default) , > > +.Cm 2 > > +.Pq Dv Excellent effort , > > +.Cm 3 > > +.Pq Dv Critical applications , > > +.Cm 4 > > +.Pq Dv Video, < 100ms latency , > > +.Cm 5 > > +.Pq Dv Video, < 10ms latency , > > +.Cm 6 > > +.Pq Dv Internetwork control , > > +.Cm 7 > > +.Pq Dv Network control (highest) . > > .It Cm vlandev Ar iface > > Associate the physical interface > > .Ar iface > > > > Modified: head/sbin/ifconfig/ifvlan.c > > > ============================================================================== > > --- head/sbin/ifconfig/ifvlan.c Mon Jun 6 09:30:31 2016 > (r301495) > > +++ head/sbin/ifconfig/ifvlan.c Mon Jun 6 09:51:58 2016 > (r301496) > > @@ -1,6 +1,10 @@ > > /* > > - * Copyright (c) 1999 > > - * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. > > + * Copyright (c) 1999 Bill Paul <wpaul@ctr.columbia.edu> > > + * Copyright (c) 2012 ADARA Networks, Inc. > > + * All rights reserved. > > + * > > + * Portions of this software were developed by Robert N. M. Watson under > > + * contract to ADARA Networks, Inc. > > * > > * Redistribution and use in source and binary forms, with or without > > * modification, are permitted provided that the following conditions > > @@ -78,10 +82,14 @@ vlan_status(int s) > > { > > struct vlanreq vreq; > > > > - if (getvlan(s, &ifr, &vreq) != -1) > > - printf("\tvlan: %d parent interface: %s\n", > > - vreq.vlr_tag, vreq.vlr_parent[0] == '\0' ? > > - "<none>" : vreq.vlr_parent); > > + 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(" parent interface: %s", vreq.vlr_parent[0] == '\0' ? > > + "<none>" : vreq.vlr_parent); > > + printf("\n"); > > } > > > > static void > > @@ -149,6 +157,22 @@ DECL_CMD_FUNC(setvlandev, val, d) > > } > > > > static > > +DECL_CMD_FUNC(setvlanpcp, val, d) > > +{ > > + u_long ul; > > + char *endp; > > + > > + ul = strtoul(val, &endp, 0); > > + if (*endp != '\0') > > + 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"); > > +} > > + > > +static > > DECL_CMD_FUNC(unsetvlandev, val, d) > > { > > struct vlanreq vreq; > > @@ -169,6 +193,7 @@ DECL_CMD_FUNC(unsetvlandev, val, d) > > static struct cmd vlan_cmds[] = { > > DEF_CLONE_CMD_ARG("vlan", setvlantag), > > DEF_CLONE_CMD_ARG("vlandev", setvlandev), > > + DEF_CMD_ARG("vlanpcp", setvlanpcp), > > /* NB: non-clone cmds */ > > DEF_CMD_ARG("vlan", setvlantag), > > DEF_CMD_ARG("vlandev", setvlandev), > > > > Modified: head/share/man/man4/vlan.4 > > > ============================================================================== > > --- head/share/man/man4/vlan.4 Mon Jun 6 09:30:31 2016 > (r301495) > > +++ head/share/man/man4/vlan.4 Mon Jun 6 09:51:58 2016 > (r301496) > > @@ -203,5 +203,3 @@ can be corrected manually if used in con > > .Sh SEE ALSO > > .Xr ifconfig 8 , > > .Xr sysctl 8 > > -.Sh BUGS > > -No 802.1Q features except VLAN tagging are implemented. > > > > Modified: head/sys/net/if.h > > > ============================================================================== > > --- head/sys/net/if.h Mon Jun 6 09:30:31 2016 (r301495) > > +++ head/sys/net/if.h Mon Jun 6 09:51:58 2016 (r301496) > > @@ -393,6 +393,7 @@ struct ifreq { > > 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,6 +411,7 @@ struct ifreq { > > #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) \ > > > > Modified: head/sys/net/if_vlan.c > > > ============================================================================== > > --- head/sys/net/if_vlan.c Mon Jun 6 09:30:31 2016 (r301495) > > +++ head/sys/net/if_vlan.c Mon Jun 6 09:51:58 2016 (r301496) > > @@ -1,5 +1,9 @@ > > /*- > > * Copyright 1998 Massachusetts Institute of Technology > > + * Copyright 2012 ADARA Networks, Inc. > > + * > > + * Portions of this software were developed by Robert N. M. Watson under > > + * contract to ADARA Networks, Inc. > > * > > * Permission to use, copy, modify, and distribute this software and > > * its documentation for any purpose and without fee is hereby > > @@ -29,8 +33,7 @@ > > > > /* > > * if_vlan.c - pseudo-device driver for IEEE 802.1Q virtual LANs. > > - * Might be extended some day to also handle IEEE 802.1p priority > > - * tagging. This is sort of sneaky in the implementation, since > > + * This is sort of sneaky in the implementation, since > > * we need to pretend to be enough of an Ethernet implementation > > * to make arp work. The way we do this is by telling everyone > > * that we are an Ethernet, and then catch the packets that > > @@ -52,6 +55,7 @@ __FBSDID("$FreeBSD$"); > > #include <sys/mbuf.h> > > #include <sys/module.h> > > #include <sys/rmlock.h> > > +#include <sys/priv.h> > > #include <sys/queue.h> > > #include <sys/socket.h> > > #include <sys/sockio.h> > > @@ -114,6 +118,8 @@ struct ifvlan { > > int ifvm_mintu; /* min transmission unit */ > > uint16_t ifvm_proto; /* encapsulation ethertype */ > > uint16_t ifvm_tag; /* tag to apply on packets leaving > if */ > > + uint16_t ifvm_vid; /* VLAN ID */ > > + uint8_t ifvm_pcp; /* Priority Code Point (PCP). */ > > } ifv_mib; > > SLIST_HEAD(, vlan_mc_entry) vlan_mc_listhead; > > #ifndef VLAN_ARRAY > > @@ -121,7 +127,9 @@ struct ifvlan { > > #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 > > #define ifv_mintu ifv_mib.ifvm_mintu > > @@ -147,6 +155,15 @@ static VNET_DEFINE(int, soft_pad); > > SYSCTL_INT(_net_link_vlan, OID_AUTO, soft_pad, CTLFLAG_RW | > CTLFLAG_VNET, > > &VNET_NAME(soft_pad), 0, "pad short frames before tagging"); > > > > +/* > > + * For now, make preserving PCP via an mbuf tag optional, as it > increases > > + * per-packet memory allocations and frees. In the future, it would be > > + * preferable to reuse ether_vtag for this, or similar. > > + */ > > +static int vlan_mtag_pcp = 0; > > +SYSCTL_INT(_net_link_vlan, OID_AUTO, mtag_pcp, CTLFLAG_RW, > &vlan_mtag_pcp, 0, > > + "Retain VLAN PCP information as packets are passed up the stack"); > > + > > static const char vlanname[] = "vlan"; > > static MALLOC_DEFINE(M_VLAN, vlanname, "802.1Q Virtual LAN Interface"); > > > > @@ -697,6 +714,16 @@ vlan_devat(struct ifnet *ifp, uint16_t v > > } > > > > /* > > + * Recalculate the cached VLAN tag exposed via the MIB. > > + */ > > +static void > > +vlan_tag_recalculate(struct ifvlan *ifv) > > +{ > > + > > + ifv->ifv_tag = EVL_MAKETAG(ifv->ifv_vid, ifv->ifv_pcp, 0); > > +} > > + > > +/* > > * VLAN support can be loaded as a module. The only place in the > > * system that's intimately aware of this is ether_input. We hook > > * into this code through vlan_input_p which is defined there and > > @@ -1009,6 +1036,8 @@ vlan_transmit(struct ifnet *ifp, struct > > { > > struct ifvlan *ifv; > > struct ifnet *p; > > + struct m_tag *mtag; > > + uint16_t tag; > > int error, len, mcast; > > > > ifv = ifp->if_softc; > > @@ -1064,11 +1093,16 @@ vlan_transmit(struct ifnet *ifp, struct > > * knows how to find the VLAN tag to use, so we attach a > > * packet tag that holds it. > > */ > > + if (vlan_mtag_pcp && (mtag = m_tag_locate(m, MTAG_8021Q, > > + MTAG_8021Q_PCP_OUT, NULL)) != NULL) > > + tag = EVL_MAKETAG(ifv->ifv_vid, *(uint8_t *)(mtag + 1), 0); > > + else > > + tag = ifv->ifv_tag; > > if (p->if_capenable & IFCAP_VLAN_HWTAGGING) { > > - m->m_pkthdr.ether_vtag = ifv->ifv_vid; > > + m->m_pkthdr.ether_vtag = tag; > > m->m_flags |= M_VLANTAG; > > } else { > > - m = ether_vlanencap(m, ifv->ifv_vid); > > + m = ether_vlanencap(m, tag); > > if (m == NULL) { > > if_printf(ifp, "unable to prepend VLAN header\n"); > > if_inc_counter(ifp, IFCOUNTER_OERRORS, 1); > > @@ -1103,7 +1137,8 @@ vlan_input(struct ifnet *ifp, struct mbu > > struct ifvlantrunk *trunk = ifp->if_vlantrunk; > > struct ifvlan *ifv; > > TRUNK_LOCK_READER; > > - uint16_t vid; > > + struct m_tag *mtag; > > + uint16_t vid, tag; > > > > KASSERT(trunk != NULL, ("%s: no trunk", __func__)); > > > > @@ -1112,7 +1147,7 @@ vlan_input(struct ifnet *ifp, struct mbu > > * Packet is tagged, but m contains a normal > > * Ethernet frame; the tag is stored out-of-band. > > */ > > - vid = EVL_VLANOFTAG(m->m_pkthdr.ether_vtag); > > + tag = m->m_pkthdr.ether_vtag; > > m->m_flags &= ~M_VLANTAG; > > } else { > > struct ether_vlan_header *evl; > > @@ -1128,7 +1163,7 @@ vlan_input(struct ifnet *ifp, struct mbu > > return; > > } > > evl = mtod(m, struct ether_vlan_header *); > > - vid = EVL_VLANOFTAG(ntohs(evl->evl_tag)); > > + tag = ntohs(evl->evl_tag); > > > > /* > > * Remove the 802.1q header by copying the Ethernet > > @@ -1152,6 +1187,8 @@ vlan_input(struct ifnet *ifp, struct mbu > > } > > } > > > > + vid = EVL_VLANOFTAG(tag); > > + > > TRUNK_RLOCK(trunk); > > ifv = vlan_gethash(trunk, vid); > > if (ifv == NULL || !UP_AND_RUNNING(ifv->ifv_ifp)) { > > @@ -1162,6 +1199,28 @@ vlan_input(struct ifnet *ifp, struct mbu > > } > > TRUNK_RUNLOCK(trunk); > > > > + if (vlan_mtag_pcp) { > > + /* > > + * While uncommon, it is possible that we will find a > 802.1q > > + * packet encapsulated inside another packet that also had > an > > + * 802.1q header. For example, ethernet tunneled over > IPSEC > > + * arriving over ethernet. In that case, we replace the > > + * existing 802.1q PCP m_tag value. > > + */ > > + mtag = m_tag_locate(m, MTAG_8021Q, MTAG_8021Q_PCP_IN, > NULL); > > + if (mtag == NULL) { > > + mtag = m_tag_alloc(MTAG_8021Q, MTAG_8021Q_PCP_IN, > > + sizeof(uint8_t), M_NOWAIT); > > + if (mtag == NULL) { > > + m_freem(m); > > + if_inc_counter(ifp, IFCOUNTER_IERRORS, 1); > > + return; > > + } > > + m_tag_prepend(m, mtag); > > + } > > + *(uint8_t *)(mtag + 1) = EVL_PRIOFTAG(tag); > > + } > > + > > m->m_pkthdr.rcvif = ifv->ifv_ifp; > > if_inc_counter(ifv->ifv_ifp, IFCOUNTER_IPACKETS, 1); > > > > @@ -1201,7 +1260,7 @@ vlan_config(struct ifvlan *ifv, struct i > > vlan_inithash(trunk); > > VLAN_LOCK(); > > if (p->if_vlantrunk != NULL) { > > - /* A race that that is very unlikely to be hit. */ > > + /* A race that is very unlikely to be hit. */ > > vlan_freehash(trunk); > > free(trunk, M_VLAN); > > goto exists; > > @@ -1218,6 +1277,8 @@ exists: > > } > > > > ifv->ifv_vid = vid; /* must set this before vlan_inshash() */ > > + ifv->ifv_pcp = 0; /* Default: best effort delivery. */ > > + vlan_tag_recalculate(ifv); > > error = vlan_inshash(trunk, ifv); > > if (error) > > goto done; > > @@ -1705,6 +1766,34 @@ vlan_ioctl(struct ifnet *ifp, u_long cmd > > } > > 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; > > > > Modified: head/sys/net/if_vlan_var.h > > > ============================================================================== > > --- head/sys/net/if_vlan_var.h Mon Jun 6 09:30:31 2016 > (r301495) > > +++ head/sys/net/if_vlan_var.h Mon Jun 6 09:51:58 2016 > (r301496) > > @@ -73,6 +73,23 @@ struct vlanreq { > > #define SIOCSETVLAN SIOCSIFGENERIC > > #define SIOCGETVLAN SIOCGIFGENERIC > > > > +#define SIOCGVLANPCP _IOWR('i', 152, struct ifreq) /* Get > VLAN PCP */ > > +#define SIOCSVLANPCP _IOW('i', 153, struct ifreq) /* Set > VLAN PCP */ > > + > > +/* > > + * Names for 802.1q priorities ("802.1p"). Notice that in this scheme, > > + * (0 < 1), allowing default 0-tagged traffic to take priority over > background > > + * tagged traffic. > > + */ > > +#define IEEE8021Q_PCP_BK 1 /* Background (lowest) */ > > +#define IEEE8021Q_PCP_BE 0 /* Best effort (default) */ > > +#define IEEE8021Q_PCP_EE 2 /* Excellent effort */ > > +#define IEEE8021Q_PCP_CA 3 /* Critical applications */ > > +#define IEEE8021Q_PCP_VI 4 /* Video, < 100ms latency > */ > > +#define IEEE8021Q_PCP_VO 5 /* Video, < 10ms latency */ > > +#define IEEE8021Q_PCP_IC 6 /* Internetwork control */ > > +#define IEEE8021Q_PCP_NC 7 /* Network control > (highest) */ > > + > > #ifdef _KERNEL > > /* > > * Drivers that are capable of adding and removing the VLAN header > > @@ -110,6 +127,16 @@ struct vlanreq { > > * if_capabilities. > > */ > > > > +/* > > + * The 802.1q code may also tag mbufs with the PCP (priority) field for > use in > > + * other layers of the stack, in which case an m_tag will be used. > This is > > + * semantically quite different from use of the ether_vtag field, which > is > > + * defined only between the device driver and VLAN layer. > > + */ > > +#define MTAG_8021Q 1326104895 > > +#define MTAG_8021Q_PCP_IN 0 /* Input priority. > */ > > +#define MTAG_8021Q_PCP_OUT 1 /* Output > priority. */ > > + > > #define VLAN_CAPABILITIES(_ifp) do { \ > > if ((_ifp)->if_vlantrunk != NULL) \ > > (*vlan_trunk_cap_p)(_ifp); \ > > > > Modified: head/sys/sys/priv.h > > > ============================================================================== > > --- head/sys/sys/priv.h Mon Jun 6 09:30:31 2016 (r301495) > > +++ head/sys/sys/priv.h Mon Jun 6 09:51:58 2016 (r301496) > > @@ -342,6 +342,7 @@ > > #define PRIV_NET_SETIFDESCR 418 /* Set interface > description. */ > > #define PRIV_NET_SETIFFIB 419 /* Set interface fib. */ > > #define PRIV_NET_VXLAN 420 /* Administer vxlan. */ > > +#define PRIV_NET_SETVLANPCP 421 /* Set VLAN priority. */ > > > > /* > > * 802.11-related privileges. > > _______________________________________________ > > svn-src-all@freebsd.org mailing list > > https://lists.freebsd.org/mailman/listinfo/svn-src-all > > To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org" > -- -- Marcelo Araujo (__)araujo@FreeBSD.org \\\'',)http://www.FreeBSD.org <http://www.freebsd.org/> \/ \ ^ Power To Server. .\. /_)
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CAOfEmZh5cwd5tyrmukSSCYOd%2Bfqo1KgpT4PaLwDVanP54m2ACQ>