Blame src/vma/proto/ip_frag.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
#ifndef _IP_FRAG_H
Packit 6d2c1b
#define _IP_FRAG_H
Packit 6d2c1b
Packit 6d2c1b
/**
Packit 6d2c1b
 * IP reassembly is based on algorithm described in RFC815
Packit 6d2c1b
 */
Packit 6d2c1b
Packit 6d2c1b
#include <map>
Packit 6d2c1b
#include <netinet/ip.h>
Packit 6d2c1b
#include <netinet/udp.h>
Packit 6d2c1b
#include <sys/time.h>
Packit 6d2c1b
Packit 6d2c1b
#include "vlogger/vlogger.h"
Packit 6d2c1b
#include "utils/lock_wrapper.h"
Packit 6d2c1b
#include <vma/util/vtypes.h>
Packit 6d2c1b
#include <vma/util/sys_vars.h>
Packit 6d2c1b
#include <vma/event/timer_handler.h>
Packit 6d2c1b
#include <vma/dev/buffer_pool.h>
Packit 6d2c1b
Packit 6d2c1b
class mem_buf_desc_t;
Packit 6d2c1b
class event_handler_manager;
Packit 6d2c1b
class mem_buf_desc_owner;
Packit 6d2c1b
Packit 6d2c1b
#define IP_FRAG_FREED		((size_t)-1)
Packit 6d2c1b
Packit 6d2c1b
#define IP_FRAG_MAX_DESC	1024 	/* maximum number of preallocated descriptors */
Packit 6d2c1b
#define IP_FRAG_MAX_HOLES	16000 	/* maximum number of preallocated holes       */
Packit 6d2c1b
#define IP_FRAG_TTL		2 	/* default unassembled fragment time to live in ticks */
Packit 6d2c1b
#define IP_FRAG_INF 		0xFFFF
Packit 6d2c1b
#define IP_FRAG_NINF  		0x0
Packit 6d2c1b
#define IP_FRAG_SPACE 		60000
Packit 6d2c1b
#define IP_FRAG_CLEANUP_INT	10
Packit 6d2c1b
Packit 6d2c1b
struct ip_frag_key_t {
Packit 6d2c1b
	uint16_t  ip_id;
Packit 6d2c1b
	in_addr_t src_ip;
Packit 6d2c1b
	in_addr_t dst_ip;
Packit 6d2c1b
	uint8_t	  ipproto;
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
Packit 6d2c1b
inline bool
Packit 6d2c1b
operator<( ip_frag_key_t const& a, ip_frag_key_t const& b)
Packit 6d2c1b
{
Packit 6d2c1b
	if (a.ip_id < b.ip_id)
Packit 6d2c1b
		return true;
Packit 6d2c1b
Packit 6d2c1b
	if (a.ip_id > b.ip_id)
Packit 6d2c1b
		return false;
Packit 6d2c1b
Packit 6d2c1b
	if (a.src_ip < b.src_ip)
Packit 6d2c1b
		return true;
Packit 6d2c1b
Packit 6d2c1b
	if (a.src_ip > b.src_ip)
Packit 6d2c1b
		return false;
Packit 6d2c1b
Packit 6d2c1b
	if (a.dst_ip < b.dst_ip)
Packit 6d2c1b
		return true;
Packit 6d2c1b
Packit 6d2c1b
	if (a.dst_ip > b.dst_ip)
Packit 6d2c1b
		return false;
Packit 6d2c1b
Packit 6d2c1b
	if (a.ipproto < b.ipproto)
Packit 6d2c1b
		return true;
Packit 6d2c1b
Packit 6d2c1b
	if (a.ipproto > b.ipproto)
Packit 6d2c1b
		return false;
Packit 6d2c1b
Packit 6d2c1b
	return false;
Packit 6d2c1b
}
Packit 6d2c1b
Packit 6d2c1b
struct ip_frag_hole_desc {
Packit 6d2c1b
	uint16_t			first;
Packit 6d2c1b
	uint16_t			last;
Packit 6d2c1b
	mem_buf_desc_t			*data_first;
Packit 6d2c1b
	mem_buf_desc_t			*data_last;
Packit 6d2c1b
	struct ip_frag_hole_desc	*next;
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
typedef struct ip_frag_desc {
Packit 6d2c1b
	uint16_t			ttl;
Packit 6d2c1b
	uint16_t			pkt_size;
Packit 6d2c1b
	struct ip_frag_hole_desc 	*hole_list;
Packit 6d2c1b
	mem_buf_desc_t 			*frag_list;
Packit 6d2c1b
	int64_t				frag_counter;
Packit 6d2c1b
	struct ip_frag_desc		*next;
Packit 6d2c1b
} ip_frag_desc_t;
Packit 6d2c1b
Packit 6d2c1b
typedef std::map<ip_frag_key_t, ip_frag_desc_t *, std::less<ip_frag_key_t> > ip_frags_list_t;
Packit 6d2c1b
typedef std::map<ring_slave*, mem_buf_desc_t*> owner_desc_map_t;
Packit 6d2c1b
Packit 6d2c1b
class ip_frag_manager : private lock_spin, public timer_handler
Packit 6d2c1b
{
Packit 6d2c1b
public:
Packit 6d2c1b
	ip_frag_manager();
Packit 6d2c1b
	~ip_frag_manager();
Packit 6d2c1b
	/**
Packit 6d2c1b
	 * add fragment to the list.
Packit 6d2c1b
	 * Return:
Packit 6d2c1b
	 * 0 if finished OK
Packit 6d2c1b
	 * 		- if the packet is complete - put the pointer to the first fragment of the packet in ret.
Packit 6d2c1b
	 * 		  Rest of the packet fragments are linked in order.
Packit 6d2c1b
	 * 		- if we need more fragments - put NULL in ret.
Packit 6d2c1b
	 * -1 if finished with error and this packet needs to be droped
Packit 6d2c1b
	 */
Packit 6d2c1b
	int add_frag(iphdr *hdr, mem_buf_desc_t *frag, mem_buf_desc_t **ret);
Packit 6d2c1b
Packit 6d2c1b
	uint64_t	m_frag_counter;
Packit 6d2c1b
Packit 6d2c1b
private:
Packit 6d2c1b
	ip_frags_list_t			m_frags;
Packit 6d2c1b
Packit 6d2c1b
	// Map of buffers to return, by owner
Packit 6d2c1b
	owner_desc_map_t		m_return_descs;
Packit 6d2c1b
Packit 6d2c1b
Packit 6d2c1b
	/**
Packit 6d2c1b
	 * first fragment for given address is detected - setup
Packit 6d2c1b
	 */
Packit 6d2c1b
	ip_frag_desc_t*		new_frag_desc(ip_frag_key_t &key);
Packit 6d2c1b
	void			print_statistics();
Packit 6d2c1b
	void			return_buffers_to_owners(const owner_desc_map_t &buff_map);
Packit 6d2c1b
	void			free_frag(mem_buf_desc_t *frag);
Packit 6d2c1b
	ip_frag_hole_desc* 	alloc_hole_desc();
Packit 6d2c1b
	void			free_hole_desc(struct ip_frag_hole_desc *p);
Packit 6d2c1b
	ip_frag_desc_t*		alloc_frag_desc();
Packit 6d2c1b
	void			free_frag_desc(ip_frag_desc_t *p);
Packit 6d2c1b
	void			destroy_frag_desc(ip_frag_desc_t *desc);
Packit 6d2c1b
Packit 6d2c1b
	virtual void    	handle_timer_expired(void* user_data);
Packit 6d2c1b
Packit 6d2c1b
	void			free_frag_resources(void);
Packit 6d2c1b
};
Packit 6d2c1b
Packit 6d2c1b
extern ip_frag_manager * g_p_ip_frag_manager;
Packit 6d2c1b
Packit 6d2c1b
#endif