#include <stdint.h>
#include "main.h"
#include "vxlan.h"
static uint16_t
get_psd_sum(void *l3_hdr, uint16_t ethertype, uint64_t ol_flags)
{
else
}
static void
parse_ethernet(
struct ether_hdr *eth_hdr,
union tunnel_offload_info *info,
uint8_t *l4_proto)
{
uint16_t ethertype;
info->outer_l2_len =
sizeof(
struct ether_hdr);
info->outer_l2_len += sizeof(struct vlan_hdr);
}
switch (ethertype) {
ipv4_hdr = (struct ipv4_hdr *)
((char *)eth_hdr + info->outer_l2_len);
info->outer_l3_len = sizeof(struct ipv4_hdr);
break;
ipv6_hdr = (struct ipv6_hdr *)
((char *)eth_hdr + info->outer_l2_len);
info->outer_l3_len = sizeof(struct ipv6_hdr);
*l4_proto = ipv6_hdr->
proto;
break;
default:
info->outer_l3_len = 0;
*l4_proto = 0;
break;
}
}
static uint64_t
process_inner_cksums(
struct ether_hdr *eth_hdr,
union tunnel_offload_info *info)
{
void *l3_hdr = NULL;
uint8_t l4_proto;
uint16_t ethertype;
struct ipv4_hdr *ipv4_hdr;
struct ipv6_hdr *ipv6_hdr;
uint64_t ol_flags = 0;
struct vlan_hdr *vlan_hdr = (struct vlan_hdr *)(eth_hdr + 1);
info->l2_len += sizeof(struct vlan_hdr);
}
l3_hdr = (char *)eth_hdr + info->l2_len;
ipv4_hdr = (struct ipv4_hdr *)l3_hdr;
info->l3_len = sizeof(struct ipv4_hdr);
ipv6_hdr = (struct ipv6_hdr *)l3_hdr;
info->l3_len = sizeof(struct ipv6_hdr);
l4_proto = ipv6_hdr->
proto;
} else
return 0;
if (l4_proto == IPPROTO_UDP) {
udp_hdr = (struct udp_hdr *)((char *)l3_hdr + info->l3_len);
ethertype, ol_flags);
} else if (l4_proto == IPPROTO_TCP) {
tcp_hdr = (struct tcp_hdr *)((char *)l3_hdr + info->l3_len);
tcp_hdr->
cksum = get_psd_sum(l3_hdr, ethertype,
ol_flags);
if (tso_segsz != 0) {
info->tso_segsz = tso_segsz;
info->l4_len = sizeof(struct tcp_hdr);
}
} else if (l4_proto == IPPROTO_SCTP) {
sctp_hdr = (struct sctp_hdr *)((char *)l3_hdr + info->l3_len);
}
return ol_flags;
}
int
{
uint8_t l4_proto = 0;
uint16_t outer_header_len;
struct udp_hdr *udp_hdr;
union tunnel_offload_info info = { .data = 0 };
parse_ethernet(phdr, &info, &l4_proto);
if (l4_proto != IPPROTO_UDP)
return -1;
udp_hdr = (struct udp_hdr *)((char *)phdr +
info.outer_l2_len + info.outer_l3_len);
return -1;
outer_header_len = info.outer_l2_len + info.outer_l3_len
+
sizeof(
struct udp_hdr) + sizeof(struct
vxlan_hdr);
return 0;
}
void
encapsulation(
struct rte_mbuf *m, uint8_t queue_id)
{
uint vport_id;
uint64_t ol_flags = 0;
uint32_t old_len = m->
pkt_len, hash;
union tunnel_offload_info tx_offload = { .data = 0 };
sizeof(
struct ether_hdr) +
sizeof(
struct ipv4_hdr)
+ sizeof(struct udp_hdr) + sizeof(struct
vxlan_hdr));
struct ipv4_hdr *ip = (struct ipv4_hdr *) &pneth[1];
struct udp_hdr *udp = (struct udp_hdr *) &ip[1];
vport_id = queue_id - 1;
sizeof(struct ipv4_hdr));
if (tx_checksum) {
ol_flags |= process_inner_cksums(phdr, &tx_offload);
m->
l2_len = tx_offload.l2_len;
m->
l3_len = tx_offload.l3_len;
m->
l4_len = tx_offload.l4_len;
}
+ sizeof(struct udp_hdr)
+ PORT_MIN);
return;
}