vlan1.diff

dragonfly, 12/30/2005 01:16 PM

Download (5.7 KB)

View differences:

sys/net/vlan/if_vlan.c 30 Dec 2005 00:24:00 -0000
303 303
			altq_etherclassify(&p->if_snd, m, &pktattr);
304 304

  
305 305
		/*
306
		 * If the LINK0 flag is set, it means the underlying interface
307
		 * can do VLAN tag insertion itself and doesn't require us to
308
	 	 * create a special header for it. In this case, we just pass
309
		 * the packet along. However, we need some way to tell the
310
		 * interface where the packet came from so that it knows how
311
		 * to find the VLAN tag to use, so we set the rcvif in the
312
		 * mbuf header to our ifnet.
306
		 * If underlying interface can do VLAN tag insertion itself,
307
		 * just pass the packet along. However, we need some way to
308
		 * tell the interface where the packet came from so that it
309
		 * knows how to find the VLAN tag to use, so we set the rcvif 
310
		 * in the mbuf header to our ifnet.
313 311
		 *
314 312
		 * Note: we also set the M_PROTO1 flag in the mbuf to let
315 313
		 * the parent driver know that the rcvif pointer is really
......
320 318
		 * following potentially bogus rcvif pointers off into
321 319
		 * never-never land.
322 320
		 */
323
		if (ifp->if_flags & IFF_LINK0) {
321
		if (p->if_capenable & IFCAP_VLAN_HWTAGGING) {
324 322
			m->m_pkthdr.rcvif = ifp;
325 323
			m->m_flags |= M_PROTO1;
326 324
		} else {
......
379 377
{
380 378
	struct bpf_if *bif;
381 379
	struct ifvlan *ifv;
382
	struct ether_header *eh = mtod(m, struct ether_header *);
383 380
	struct ifnet *rcvif;
384 381

  
385
	m_adj(m, ETHER_HDR_LEN);
386 382
	rcvif = m->m_pkthdr.rcvif;
387 383

  
388 384
	ASSERT_SERIALIZED(rcvif->if_serializer);
......
392 388
	 * bpf tap if active.
393 389
	 */
394 390
	if ((bif = rcvif->if_bpf) != NULL) {
391
		struct ether_header *eh;
395 392
		struct ether_vlan_header evh;
396 393

  
394
		eh = mtod(m, struct ether_header *);
395
		m_adj(m, ETHER_HDR_LEN);
397 396
		bcopy(eh, &evh, 2*ETHER_ADDR_LEN);
398 397
		evh.evl_encap_proto = htons(ETHERTYPE_VLAN);
399 398
		evh.evl_tag = htons(t);
400 399
		evh.evl_proto = eh->ether_type;
401

  
402 400
		bpf_ptap(bif, m, &evh, ETHER_HDR_LEN + EVL_ENCAPLEN);
401
		/* XXX assumes data was left intact */
402
		M_PREPEND(m, ETHER_HDR_LEN, MB_WAIT); 
403 403
	}
404 404

  
405 405
	for (ifv = LIST_FIRST(&ifv_list); ifv != NULL;
......
423 423
	ifv->ifv_if.if_ipackets++;
424 424
	lwkt_serialize_exit(rcvif->if_serializer);
425 425
	lwkt_serialize_enter(ifv->ifv_if.if_serializer);
426
	ether_input(&ifv->ifv_if, eh, m);
426
	ether_input(&ifv->ifv_if, NULL, m);
427 427
	lwkt_serialize_exit(ifv->ifv_if.if_serializer);
428 428
	lwkt_serialize_enter(rcvif->if_serializer);
429 429
	return 0;
......
434 434
{
435 435
	struct ifvlan *ifv;
436 436
	struct ifnet *rcvif;
437
	struct ether_header eh_copy;
437 438

  
438 439
	rcvif = m->m_pkthdr.rcvif;
439 440
	ASSERT_SERIALIZED(rcvif->if_serializer);
......
455 456
	/*
456 457
	 * Having found a valid vlan interface corresponding to
457 458
	 * the given source interface and vlan tag, remove the
458
	 * encapsulation, and run the real packet through
459
	 * ether_input() a second time (it had better be
459
	 * remaining encapsulation (ether_vlan_header minus the ether_header
460
	 * that had already been removed) and run the real packet
461
	 * through ether_input() a second time (it had better be
460 462
	 * reentrant!).
461 463
	 */
464
	eh_copy = *eh;
465
	eh_copy.ether_type = mtod(m, u_int16_t *)[1];	/* evl_proto */
462 466
	m->m_pkthdr.rcvif = &ifv->ifv_if;
463
	eh->ether_type = mtod(m, u_int16_t *)[1];
464
	m->m_data += EVL_ENCAPLEN;
465
	m->m_len -= EVL_ENCAPLEN;
466
	m->m_pkthdr.len -= EVL_ENCAPLEN;
467
	m_adj(m, EVL_ENCAPLEN);
468
	M_PREPEND(m, ETHER_HDR_LEN, MB_WAIT); 
469
	*(struct ether_header *)mtod(m, void *) = eh_copy;
467 470

  
468 471
	ifv->ifv_if.if_ipackets++;
469 472
	lwkt_serialize_exit(rcvif->if_serializer);
470 473
	lwkt_serialize_enter(ifv->ifv_if.if_serializer);
471
	ether_input(&ifv->ifv_if, eh, m);
474
	ether_input(&ifv->ifv_if, NULL, m);
472 475
	lwkt_serialize_exit(ifv->ifv_if.if_serializer);
473 476
	lwkt_serialize_enter(rcvif->if_serializer);
474 477
	return 0;
......
484 487
	if (ifv->ifv_p)
485 488
		return EBUSY;
486 489
	ifv->ifv_p = p;
487
	if (p->if_data.ifi_hdrlen == sizeof(struct ether_vlan_header))
490
	if (p->if_capenable & IFCAP_VLAN_MTU)
488 491
		ifv->ifv_if.if_mtu = p->if_mtu;
489 492
	else
490 493
		ifv->ifv_if.if_mtu = p->if_data.ifi_mtu - EVL_ENCAPLEN;
share/man/man4/vlan.4 30 Dec 2005 00:00:41 -0000
71 71
.Pp
72 72
The
73 73
.Nm
74
driver supports physical devices that do
75
the VLAN demultiplexing in firmware.
76
The
77
.Cm link0
78
flag should be set on a
79
.Nm
80
interface
81
.Pq Em not on its parent
82
using
83
.Xr ifconfig 8
84
in that case to indicate that hardware support for
85
the 802.1Q VLANs is present in its parent.
74
driver supports efficient operation over parent interfaces that can provide
75
help in processing VLANs.
76
Such interfaces are automatically recognized by their capabilities.
77
Depending on the level of sophistication found in a physical
78
interface, it may do full VLAN processing or just be able to
79
receive and transmit frames exceeding the maximum Ethernet frame size
80
by the length of a 802.1Q header.
81
The capabilities may be user-controlled by the respective parameters to
82
.Xr ifconfig 8 ,
83
.Cm vlanhwtag
84
and
85
.Cm vlanmtu .
86
However, a physical interface is not obliged to react to them:
87
It may have either capability enabled permanently without
88
a way to turn it off.
89
The whole issue is very specific to a particular device and its driver.
86 90
.\"
87 91
.Ss "Selecting the Right Network Interface Card to Run VLANs Through"
88 92
By now, the only NICs that have both hardware support and proper
......
93 97
.Xr em 4 ,
94 98
.Xr gx 4 ,
95 99
.Xr nge 4 ,
100
.Xr re 4 ,
96 101
.Xr ti 4 ,
97 102
and
98 103
.Xr txp 4 .