MCPcopy Create free account
hub / github.com/F-Stack/f-stack / ether_8021q_frame

Function ether_8021q_frame

freebsd/net/if_ethersubr.c:1366–1432  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1364 "Retain VLAN PCP information as packets are passed up the stack");
1365
1366bool
1367ether_8021q_frame(struct mbuf **mp, struct ifnet *ife, struct ifnet *p,
1368 struct ether_8021q_tag *qtag)
1369{
1370 struct m_tag *mtag;
1371 int n;
1372 uint16_t tag;
1373 static const char pad[8]; /* just zeros */
1374
1375 /*
1376 * Pad the frame to the minimum size allowed if told to.
1377 * This option is in accord with IEEE Std 802.1Q, 2003 Ed.,
1378 * paragraph C.4.4.3.b. It can help to work around buggy
1379 * bridges that violate paragraph C.4.4.3.a from the same
1380 * document, i.e., fail to pad short frames after untagging.
1381 * E.g., a tagged frame 66 bytes long (incl. FCS) is OK, but
1382 * untagging it will produce a 62-byte frame, which is a runt
1383 * and requires padding. There are VLAN-enabled network
1384 * devices that just discard such runts instead or mishandle
1385 * them somehow.
1386 */
1387 if (V_soft_pad && p->if_type == IFT_ETHER) {
1388 for (n = ETHERMIN + ETHER_HDR_LEN - (*mp)->m_pkthdr.len;
1389 n > 0; n -= sizeof(pad)) {
1390 if (!m_append(*mp, min(n, sizeof(pad)), pad))
1391 break;
1392 }
1393 if (n > 0) {
1394 m_freem(*mp);
1395 *mp = NULL;
1396 if_printf(ife, "cannot pad short frame");
1397 return (false);
1398 }
1399 }
1400
1401 /*
1402 * If PCP is set in mbuf, use it
1403 */
1404 if ((*mp)->m_flags & M_VLANTAG) {
1405 qtag->pcp = EVL_PRIOFTAG((*mp)->m_pkthdr.ether_vtag);
1406 }
1407
1408 /*
1409 * If underlying interface can do VLAN tag insertion itself,
1410 * just pass the packet along. However, we need some way to
1411 * tell the interface where the packet came from so that it
1412 * knows how to find the VLAN tag to use, so we attach a
1413 * packet tag that holds it.
1414 */
1415 if (vlan_mtag_pcp && (mtag = m_tag_locate(*mp, MTAG_8021Q,
1416 MTAG_8021Q_PCP_OUT, NULL)) != NULL)
1417 tag = EVL_MAKETAG(qtag->vid, *(uint8_t *)(mtag + 1), 0);
1418 else
1419 tag = EVL_MAKETAG(qtag->vid, qtag->pcp, 0);
1420 if ((p->if_capenable & IFCAP_VLAN_HWTAGGING) &&
1421 (qtag->proto == ETHERTYPE_VLAN)) {
1422 (*mp)->m_pkthdr.ether_vtag = tag;
1423 (*mp)->m_flags |= M_VLANTAG;

Callers 2

ether_set_pcpFunction · 0.85
vlan_transmitFunction · 0.85

Calls 6

m_appendFunction · 0.85
minFunction · 0.85
if_printfFunction · 0.85
m_tag_locateFunction · 0.85
ether_vlanencap_protoFunction · 0.85
m_freemFunction · 0.50

Tested by

no test coverage detected