* Insert VLAN tag into mbuf. * * Software version of VLAN unstripping * * @param m * The packet mbuf. * @return * - 0: On success * -EPERM: mbuf is shared overwriting would be unsafe * -ENOSPC: not enough headroom in mbuf */
| 374 | * -ENOSPC: not enough headroom in mbuf |
| 375 | */ |
| 376 | static inline int rte_vlan_insert(struct rte_mbuf **m) |
| 377 | { |
| 378 | struct rte_ether_hdr *oh, *nh; |
| 379 | struct rte_vlan_hdr *vh; |
| 380 | |
| 381 | /* Can't insert header if mbuf is shared */ |
| 382 | if (!RTE_MBUF_DIRECT(*m) || rte_mbuf_refcnt_read(*m) > 1) |
| 383 | return -EINVAL; |
| 384 | |
| 385 | /* Can't insert header if the first segment is too short */ |
| 386 | if (rte_pktmbuf_data_len(*m) < 2 * RTE_ETHER_ADDR_LEN) |
| 387 | return -EINVAL; |
| 388 | |
| 389 | oh = rte_pktmbuf_mtod(*m, struct rte_ether_hdr *); |
| 390 | nh = (struct rte_ether_hdr *)(void *) |
| 391 | rte_pktmbuf_prepend(*m, sizeof(struct rte_vlan_hdr)); |
| 392 | if (nh == NULL) |
| 393 | return -ENOSPC; |
| 394 | |
| 395 | memmove(nh, oh, 2 * RTE_ETHER_ADDR_LEN); |
| 396 | nh->ether_type = rte_cpu_to_be_16(RTE_ETHER_TYPE_VLAN); |
| 397 | |
| 398 | vh = (struct rte_vlan_hdr *) (nh + 1); |
| 399 | vh->vlan_tci = rte_cpu_to_be_16((*m)->vlan_tci); |
| 400 | |
| 401 | (*m)->ol_flags &= ~(RTE_MBUF_F_RX_VLAN_STRIPPED | RTE_MBUF_F_TX_VLAN); |
| 402 | |
| 403 | if ((*m)->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK) |
| 404 | (*m)->outer_l2_len += sizeof(struct rte_vlan_hdr); |
| 405 | else |
| 406 | (*m)->l2_len += sizeof(struct rte_vlan_hdr); |
| 407 | |
| 408 | return 0; |
| 409 | } |
| 410 | |
| 411 | #ifdef __cplusplus |
| 412 | } |
no test coverage detected