Skip to content

Commit

Permalink
netdev-dpdk: Refactor tunnel checksum offloading.
Browse files Browse the repository at this point in the history
All informations required for checksum offloading can be deduced by
already tracked dp_packet l3_ofs, l4_ofs, inner_l3_ofs and inner_l4_ofs
fields.
Remove DPDK specific l[2-4]_len from generic OVS code.

netdev-dpdk code then fills mbuf specifics step by step:
- outer_l2_len and outer_l3_len are needed for tunneling (and below
  features),
- l2_len and l3_len are needed for IP and L4 checksum (and below features),
- l4_len and tso_segsz are needed when doing TSO,

Signed-off-by: David Marchand <[email protected]>
  • Loading branch information
david-marchand committed Apr 19, 2024
1 parent f5a606a commit 281f804
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 95 deletions.
37 changes: 0 additions & 37 deletions lib/dp-packet.h
Original file line number Diff line number Diff line change
Expand Up @@ -604,25 +604,6 @@ dp_packet_get_nd_payload(const struct dp_packet *b)
}

#ifdef DPDK_NETDEV
static inline void
dp_packet_set_l2_len(struct dp_packet *b, size_t l2_len)
{
b->mbuf.l2_len = l2_len;
}

static inline void
dp_packet_set_l3_len(struct dp_packet *b, size_t l3_len)
{
b->mbuf.l3_len = l3_len;
}

static inline void
dp_packet_set_l4_len(struct dp_packet *b, size_t l4_len)
{
b->mbuf.l4_len = l4_len;
}


static inline uint64_t *
dp_packet_ol_flags_ptr(const struct dp_packet *b)
{
Expand All @@ -642,24 +623,6 @@ dp_packet_flow_mark_ptr(const struct dp_packet *b)
}

#else
static inline void
dp_packet_set_l2_len(struct dp_packet *b OVS_UNUSED, size_t l2_len OVS_UNUSED)
{
/* There is no implementation. */
}

static inline void
dp_packet_set_l3_len(struct dp_packet *b OVS_UNUSED, size_t l3_len OVS_UNUSED)
{
/* There is no implementation. */
}

static inline void
dp_packet_set_l4_len(struct dp_packet *b OVS_UNUSED, size_t l4_len OVS_UNUSED)
{
/* There is no implementation. */
}

static inline uint32_t *
dp_packet_ol_flags_ptr(const struct dp_packet *b)
{
Expand Down
35 changes: 22 additions & 13 deletions lib/netdev-dpdk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2584,6 +2584,9 @@ static bool
netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
{
struct dp_packet *pkt = CONTAINER_OF(mbuf, struct dp_packet, mbuf);
void *l2;
void *l3;
void *l4;

const uint64_t all_inner_requests = (RTE_MBUF_F_TX_IP_CKSUM |
RTE_MBUF_F_TX_L4_MASK |
Expand Down Expand Up @@ -2613,11 +2616,6 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
return true;
}

ovs_assert(dp_packet_l4(pkt));

/* If packet is vxlan or geneve tunnel packet, calculate outer
* l2 len and outer l3 len. Inner l2/l3/l4 len are calculated
* before. */
const uint64_t tunnel_type = mbuf->ol_flags & RTE_MBUF_F_TX_TUNNEL_MASK;
if (OVS_UNLIKELY(tunnel_type &&
tunnel_type != RTE_MBUF_F_TX_TUNNEL_GENEVE &&
Expand All @@ -2635,15 +2633,21 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
(char *) dp_packet_eth(pkt);
mbuf->outer_l3_len = (char *) dp_packet_l4(pkt) -
(char *) dp_packet_l3(pkt);

/* Inner L2 length must account for the tunnel header length. */
l2 = dp_packet_l4(pkt);
l3 = dp_packet_inner_l3(pkt);
l4 = dp_packet_inner_l4(pkt);
} else {
/* If no outer offloading is requested, clear outer marks. */
mbuf->ol_flags &= ~all_outer_marks;
mbuf->outer_l2_len = 0;
mbuf->outer_l3_len = 0;

/* Skip outer headers. */
mbuf->l2_len += (char *) dp_packet_l4(pkt) -
(char *) dp_packet_eth(pkt);
l2 = dp_packet_eth(pkt);
l3 = dp_packet_inner_l3(pkt);
l4 = dp_packet_inner_l4(pkt);
}
} else {
if (tunnel_type) {
Expand All @@ -2663,22 +2667,27 @@ netdev_dpdk_prep_hwol_packet(struct netdev_dpdk *dev, struct rte_mbuf *mbuf)
}
mbuf->outer_l2_len = 0;
mbuf->outer_l3_len = 0;
mbuf->l2_len = (char *) dp_packet_l3(pkt) -
(char *) dp_packet_eth(pkt);
mbuf->l3_len = (char *) dp_packet_l4(pkt) -
(char *) dp_packet_l3(pkt);

l2 = dp_packet_eth(pkt);
l3 = dp_packet_l3(pkt);
l4 = dp_packet_l4(pkt);
}

ovs_assert(l4);

mbuf->l2_len = (char *) l3 - (char *) l2;
mbuf->l3_len = (char *) l4 - (char *) l3;

if (mbuf->ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
struct tcp_header *th = dp_packet_l4(pkt);
struct tcp_header *th = l4;
uint16_t link_tso_segsz;
int hdr_len;

mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4;
if (tunnel_type) {
link_tso_segsz = dev->mtu - mbuf->l2_len - mbuf->l3_len -
mbuf->l4_len - mbuf->outer_l3_len;
} else {
mbuf->l4_len = TCP_OFFSET(th->tcp_ctl) * 4;
link_tso_segsz = dev->mtu - mbuf->l3_len - mbuf->l4_len;
}

Expand Down
50 changes: 5 additions & 45 deletions lib/netdev-native-tnl.c
Original file line number Diff line number Diff line change
Expand Up @@ -240,35 +240,15 @@ udp_extract_tnl_md(struct dp_packet *packet, struct flow_tnl *tnl,
return udp + 1;
}

/* Calculate inner l2 l3 l4 len as tunnel outer header is not
* encapsulated now. */
static void
dp_packet_tnl_ol_process(struct dp_packet *packet,
const struct ovs_action_push_tnl *data)
{
struct udp_header *udp = NULL;
uint8_t opt_len = 0;
struct eth_header *eth = NULL;
struct ip_header *ip = NULL;
struct genevehdr *gnh = NULL;

/* l2 l3 l4 len refer to inner len, tunnel outer
* header is not encapsulated here. */
if (dp_packet_hwol_l4_mask(packet)) {
ip = dp_packet_l3(packet);

if (ip->ip_proto == IPPROTO_TCP) {
struct tcp_header *th = dp_packet_l4(packet);
dp_packet_set_l4_len(packet, TCP_OFFSET(th->tcp_ctl) * 4);
} else if (ip->ip_proto == IPPROTO_UDP) {
dp_packet_set_l4_len(packet, UDP_HEADER_LEN);
} else if (ip->ip_proto == IPPROTO_SCTP) {
dp_packet_set_l4_len(packet, SCTP_HEADER_LEN);
}

dp_packet_set_l3_len(packet, (char *) dp_packet_l4(packet) -
(char *) dp_packet_l3(packet));

if (data->tnl_type == OVS_VPORT_TYPE_GENEVE ||
data->tnl_type == OVS_VPORT_TYPE_VXLAN) {

Expand All @@ -279,32 +259,12 @@ dp_packet_tnl_ol_process(struct dp_packet *packet,
dp_packet_hwol_set_tx_ipv6(packet);
}
}
}

/* Attention please, tunnel inner l2 len is consist of udp header
* len and tunnel header len and inner l2 len. */
if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) {
eth = (struct eth_header *)(data->header);
ip = (struct ip_header *)(eth + 1);
udp = (struct udp_header *)(ip + 1);
gnh = (struct genevehdr *)(udp + 1);
opt_len = gnh->opt_len * 4;
dp_packet_hwol_set_tunnel_geneve(packet);
dp_packet_set_l2_len(packet, (char *) dp_packet_l3(packet) -
(char *) dp_packet_eth(packet) +
GENEVE_BASE_HLEN + opt_len);
} else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) {
dp_packet_hwol_set_tunnel_vxlan(packet);
dp_packet_set_l2_len(packet, (char *) dp_packet_l3(packet) -
(char *) dp_packet_eth(packet) +
VXLAN_HLEN);
}
} else {
/* Mark non-l4 packets as tunneled. */
if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) {
dp_packet_hwol_set_tunnel_geneve(packet);
} else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) {
dp_packet_hwol_set_tunnel_vxlan(packet);
}
if (data->tnl_type == OVS_VPORT_TYPE_GENEVE) {
dp_packet_hwol_set_tunnel_geneve(packet);
} else if (data->tnl_type == OVS_VPORT_TYPE_VXLAN) {
dp_packet_hwol_set_tunnel_vxlan(packet);
}
}

Expand Down

0 comments on commit 281f804

Please sign in to comment.