Project

General

Profile

Feature #4133 » pf_pcp_source.diff

Source patch - Clement Barnier, 12/20/2014 08:34 AM

View differences:

/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) &params;
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) &params;
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),
(2-2/4)