Blame src/vma/proto/header.h

Packit 6d2c1b
/*
Packit 6d2c1b
 * Copyright (c) 2001-2020 Mellanox Technologies, Ltd. All rights reserved.
Packit 6d2c1b
 *
Packit 6d2c1b
 * This software is available to you under a choice of one of two
Packit 6d2c1b
 * licenses.  You may choose to be licensed under the terms of the GNU
Packit 6d2c1b
 * General Public License (GPL) Version 2, available from the file
Packit 6d2c1b
 * COPYING in the main directory of this source tree, or the
Packit 6d2c1b
 * BSD license below:
Packit 6d2c1b
 *
Packit 6d2c1b
 *     Redistribution and use in source and binary forms, with or
Packit 6d2c1b
 *     without modification, are permitted provided that the following
Packit 6d2c1b
 *     conditions are met:
Packit 6d2c1b
 *
Packit 6d2c1b
 *      - Redistributions of source code must retain the above
Packit 6d2c1b
 *        copyright notice, this list of conditions and the following
Packit 6d2c1b
 *        disclaimer.
Packit 6d2c1b
 *
Packit 6d2c1b
 *      - Redistributions in binary form must reproduce the above
Packit 6d2c1b
 *        copyright notice, this list of conditions and the following
Packit 6d2c1b
 *        disclaimer in the documentation and/or other materials
Packit 6d2c1b
 *        provided with the distribution.
Packit 6d2c1b
 *
Packit 6d2c1b
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
Packit 6d2c1b
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
Packit 6d2c1b
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
Packit 6d2c1b
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
Packit 6d2c1b
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
Packit 6d2c1b
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
Packit 6d2c1b
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
Packit 6d2c1b
 * SOFTWARE.
Packit 6d2c1b
 */
Packit 6d2c1b
Packit 6d2c1b
Packit 6d2c1b
Packit 6d2c1b
#ifndef HEADER_H
Packit 6d2c1b
#define HEADER_H
Packit 6d2c1b
Packit 6d2c1b
#include <string.h>
Packit 6d2c1b
#include <linux/if_ether.h>
Packit 6d2c1b
#include <linux/if_vlan.h>
Packit 6d2c1b
#include <netinet/ip.h>
Packit 6d2c1b
#include <netinet/udp.h>
Packit 6d2c1b
#include <netinet/tcp.h>
Packit 6d2c1b
#include <netinet/igmp.h>
Packit 6d2c1b
Packit 6d2c1b
#include "vma/util/vtypes.h"
Packit 6d2c1b
#include "vma/util/to_str.h"
Packit 6d2c1b
#include "L2_address.h"
Packit 6d2c1b
#include "vma/util/sys_vars.h"
Packit 6d2c1b
Packit 6d2c1b
// We align the frame so IP header will be 4 bytes align
Packit 6d2c1b
// And we align the L2 headers so IP header on both transport
Packit 6d2c1b
// types will be at the same offset from buffer start
Packit 6d2c1b
#define NET_IB_IP_ALIGN_SZ		16
Packit 6d2c1b
#define NET_ETH_IP_ALIGN_SZ		 6
Packit 6d2c1b
#define NET_ETH_VLAN_IP_ALIGN_SZ	 2
Packit 6d2c1b
#define NET_ETH_VLAN_PCP_OFFSET	13
Packit 6d2c1b
Packit 6d2c1b
struct __attribute__ ((packed)) ib_hdr_template_t  {		// Offeset  Size
Packit 6d2c1b
	char		m_alignment[NET_IB_IP_ALIGN_SZ];	//    0      16  = 16
Packit 6d2c1b
	ipoibhdr	m_ipoib_hdr;				//   16       4  = 20
Packit 6d2c1b
//	iphdr		m_ip_hdr;				//   20      20  = 40
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
struct __attribute__ ((packed)) eth_hdr_template_t  {		// Offeset  Size
Packit 6d2c1b
	char		m_alignment[NET_ETH_IP_ALIGN_SZ];	//    0       6  =  6
Packit 6d2c1b
	ethhdr		m_eth_hdr;				//    6      14  = 20
Packit 6d2c1b
//	iphdr		m_ip_hdr;				//   20      20  = 40
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
struct __attribute__ ((packed)) vlan_eth_hdr_template_t  {	// Offeset  Size
Packit 6d2c1b
	char		m_alignment[NET_ETH_VLAN_IP_ALIGN_SZ];	//    0       2  =  2
Packit 6d2c1b
	ethhdr		m_eth_hdr;				//    2      14  = 16
Packit 6d2c1b
	vlanhdr		m_vlan_hdr;				//   16       4  = 20
Packit 6d2c1b
//	iphdr		m_ip_hdr;				//   20      20  = 40
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
union l2_hdr_template_t  {
Packit 6d2c1b
	ib_hdr_template_t	ib_hdr;
Packit 6d2c1b
	eth_hdr_template_t	eth_hdr;
Packit 6d2c1b
	vlan_eth_hdr_template_t	vlan_eth_hdr;
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
struct __attribute__ ((packed, aligned)) tx_hdr_template_t  {		// Offeset  Size
Packit 6d2c1b
	l2_hdr_template_t	m_l2_hdr;			//    0      20
Packit 6d2c1b
	iphdr			m_ip_hdr;			//   20      20
Packit 6d2c1b
	union {
Packit 6d2c1b
	udphdr			m_udp_hdr;			//   40       8
Packit 6d2c1b
	tcphdr			m_tcp_hdr;			//   40	     20
Packit 6d2c1b
	};
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
union tx_packet_template_t {
Packit 6d2c1b
	tx_hdr_template_t	hdr;
Packit 6d2c1b
	uint32_t		words[15]; //change in tx_hdr_template_t size may require to modify this array size
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
Packit 6d2c1b
class header: public tostr
Packit 6d2c1b
{
Packit 6d2c1b
public:
Packit 6d2c1b
	header();
Packit 6d2c1b
	header(const header &h);
Packit 6d2c1b
	virtual ~header() {};
Packit 6d2c1b
Packit 6d2c1b
Packit 6d2c1b
	void init();
Packit 6d2c1b
	void configure_udp_header(uint16_t dest_port, uint16_t src_port);
Packit 6d2c1b
	void configure_tcp_ports(uint16_t dest_port, uint16_t src_port);
Packit 6d2c1b
	void configure_ip_header(uint8_t protocol, in_addr_t src_addr, in_addr_t dest_addr, uint8_t ttl = 64, uint8_t tos = 0, uint16_t packet_id = 0);
Packit 6d2c1b
	void configure_ipoib_headers(uint32_t ipoib_header = IPOIB_HEADER);
Packit 6d2c1b
	void set_mac_to_eth_header(const L2_address &src, const L2_address &dst, ethhdr &eth_header);
Packit 6d2c1b
	void set_ip_ttl(uint8_t ttl);
Packit 6d2c1b
	void set_ip_tos(uint8_t tos);
Packit 6d2c1b
	void configure_eth_headers(const L2_address &src, const L2_address &dst, uint16_t encapsulated_proto = ETH_P_IP);
Packit 6d2c1b
	void configure_vlan_eth_headers(const L2_address &src, const L2_address &dst, uint16_t tci, uint16_t encapsulated_proto = ETH_P_IP);
Packit 6d2c1b
	bool set_vlan_pcp(uint8_t pcp);
Packit 6d2c1b
	void update_actual_hdr_addr();
Packit 6d2c1b
Packit 6d2c1b
	inline void copy_l2_ip_hdr(tx_packet_template_t *p_hdr)
Packit 6d2c1b
	{
Packit 6d2c1b
		// copy words every time, to optimize for speed
Packit 6d2c1b
		p_hdr->words[0] = m_header.words[0]; // dummy(16) + l2(16) (mac / dummy)
Packit 6d2c1b
		p_hdr->words[1] = m_header.words[1]; // l2 (32)            (mac / dummy)
Packit 6d2c1b
		p_hdr->words[2] = m_header.words[2]; // l2 (32)            (mac / dummy)
Packit 6d2c1b
		p_hdr->words[3] = m_header.words[3]; // l2 (32)            (mac / dummy)
Packit 6d2c1b
		p_hdr->words[4] = m_header.words[4]; // l2 (32)            (mac / vlan / ipoib)
Packit 6d2c1b
		p_hdr->words[5] = m_header.words[5]; // IP-> ver(4) + hdrlen(4) + tos(8) + totlen(16)
Packit 6d2c1b
		p_hdr->words[6] = m_header.words[6]; // IP-> id(16) + frag(16)
Packit 6d2c1b
		p_hdr->words[7] = m_header.words[7]; // IP-> ttl(8) + protocol(8) + checksum(16)
Packit 6d2c1b
		p_hdr->words[8] = m_header.words[8]; // IP-> saddr(32)
Packit 6d2c1b
		p_hdr->words[9] = m_header.words[9]; // IP-> daddr(32)
Packit 6d2c1b
	}
Packit 6d2c1b
Packit 6d2c1b
	inline void copy_l2_ip_udp_hdr(tx_packet_template_t *p_hdr)
Packit 6d2c1b
	{
Packit 6d2c1b
		copy_l2_ip_hdr(p_hdr);
Packit 6d2c1b
		p_hdr->words[10] = m_header.words[10]; // UDP-> sport(16) + dst_port(16)
Packit 6d2c1b
		p_hdr->words[11] = m_header.words[11]; // UDP-> len(16) + check(16)
Packit 6d2c1b
	}
Packit 6d2c1b
Packit 6d2c1b
	inline void copy_l2_hdr(tx_packet_template_t *p_hdr)
Packit 6d2c1b
	{
Packit 6d2c1b
		uint32_t *to_words   = p_hdr->words;
Packit 6d2c1b
		uint32_t *from_words = m_header.words;
Packit 6d2c1b
		to_words[0] = from_words[0]; // dummy(16) + l2(16) (mac / dummy)
Packit 6d2c1b
		to_words[1] = from_words[1]; // l2 (32)            (mac / dummy)
Packit 6d2c1b
		to_words[2] = from_words[2]; // l2 (32)            (mac / dummy)
Packit 6d2c1b
		to_words[3] = from_words[3]; // l2 (32)            (mac / dummy)
Packit 6d2c1b
		to_words[4] = from_words[4]; // l2 (32)            (mac / vlan / ipoib)
Packit 6d2c1b
	}
Packit 6d2c1b
Packit 6d2c1b
	uintptr_t m_actual_hdr_addr;
Packit 6d2c1b
	tx_packet_template_t m_header;
Packit 6d2c1b
	uint16_t m_ip_header_len;
Packit 6d2c1b
	uint16_t m_transport_header_len;
Packit 6d2c1b
	uint16_t m_total_hdr_len;
Packit 6d2c1b
	uint16_t m_aligned_l2_l3_len;
Packit 6d2c1b
	uint16_t m_transport_header_tx_offset;
Packit 6d2c1b
	bool m_is_vlan_enabled;
Packit 6d2c1b
	transport_type_t m_transport_type;
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
#endif /* HEADER_H */