|
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 RFS_H
|
|
Packit |
6d2c1b |
#define RFS_H
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#include <vector>
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#include "vma/ib/base/verbs_extra.h"
|
|
Packit |
6d2c1b |
#include "vma/util/vtypes.h"
|
|
Packit |
6d2c1b |
#include "vma/dev/ring_simple.h"
|
|
Packit |
6d2c1b |
#include "vma/proto/mem_buf_desc.h"
|
|
Packit |
6d2c1b |
#include "vma/proto/flow_tuple.h"
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#define rfs_logpanic __log_info_panic
|
|
Packit |
6d2c1b |
#define rfs_logerr __log_info_err
|
|
Packit |
6d2c1b |
#define rfs_logwarn __log_info_warn
|
|
Packit |
6d2c1b |
#define rfs_loginfo __log_info_info
|
|
Packit |
6d2c1b |
#define rfs_logdbg __log_info_dbg
|
|
Packit |
6d2c1b |
#define rfs_logfunc __log_info_func
|
|
Packit |
6d2c1b |
#define rfs_logfuncall __log_info_funcall
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#define RFS_SINKS_LIST_DEFAULT_LEN 32
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
class qp_mgr;
|
|
Packit |
6d2c1b |
class pkt_rcvr_sink;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
/* ETHERNET
|
|
Packit |
6d2c1b |
*/
|
|
Packit |
6d2c1b |
typedef struct attach_flow_data_eth_ipv4_tcp_udp_t {
|
|
Packit |
6d2c1b |
struct ibv_flow * ibv_flow;
|
|
Packit |
6d2c1b |
qp_mgr* p_qp_mgr;
|
|
Packit |
6d2c1b |
struct ibv_flow_attr_eth_ipv4_tcp_udp {
|
|
Packit |
6d2c1b |
vma_ibv_flow_attr attr;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_eth eth;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_ipv4 ipv4;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_tcp_udp tcp_udp;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_action_tag flow_tag; // must be the last as struct can be used without it
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ibv_flow_attr_eth_ipv4_tcp_udp(uint8_t port) {
|
|
Packit |
6d2c1b |
memset(this, 0, sizeof(*this));
|
|
Packit |
6d2c1b |
attr.size = sizeof(struct ibv_flow_attr_eth_ipv4_tcp_udp) - sizeof(flow_tag);
|
|
Packit |
6d2c1b |
attr.num_of_specs = 3;
|
|
Packit |
6d2c1b |
attr.type = VMA_IBV_FLOW_ATTR_NORMAL;
|
|
Packit |
6d2c1b |
attr.priority = 1; // almost highest priority, 0 is used for 5-tuple later
|
|
Packit |
6d2c1b |
attr.port = port;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
inline void add_flow_tag_spec(void) {
|
|
Packit |
6d2c1b |
attr.num_of_specs++;
|
|
Packit |
6d2c1b |
attr.size += sizeof(flow_tag);
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
} ibv_flow_attr;
|
|
Packit |
6d2c1b |
attach_flow_data_eth_ipv4_tcp_udp_t(qp_mgr* qp_mgr) :
|
|
Packit |
6d2c1b |
ibv_flow(NULL),
|
|
Packit |
6d2c1b |
p_qp_mgr(qp_mgr),
|
|
Packit |
6d2c1b |
ibv_flow_attr(qp_mgr->get_port_num()) {}
|
|
Packit |
6d2c1b |
} attach_flow_data_eth_ipv4_tcp_udp_t;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
/* IPOIB (MC)
|
|
Packit |
6d2c1b |
*/
|
|
Packit |
6d2c1b |
typedef struct attach_flow_data_ib_v2_t {
|
|
Packit |
6d2c1b |
struct ibv_flow * ibv_flow;
|
|
Packit |
6d2c1b |
qp_mgr* p_qp_mgr;
|
|
Packit |
6d2c1b |
struct ibv_flow_attr_ib_v2 {
|
|
Packit |
6d2c1b |
vma_ibv_flow_attr attr;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_ipv4 ipv4;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_tcp_udp tcp_udp;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ibv_flow_attr_ib_v2(uint8_t port) {
|
|
Packit |
6d2c1b |
memset(this, 0, sizeof(*this));
|
|
Packit |
6d2c1b |
attr.size = sizeof(struct ibv_flow_attr_ib_v2);
|
|
Packit |
6d2c1b |
attr.num_of_specs = 2;
|
|
Packit |
6d2c1b |
attr.type = VMA_IBV_FLOW_ATTR_NORMAL;
|
|
Packit |
6d2c1b |
attr.priority = 1; // almost highest priority, 0 is used for 5-tuple later
|
|
Packit |
6d2c1b |
attr.port = port;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
} ibv_flow_attr;
|
|
Packit |
6d2c1b |
attach_flow_data_ib_v2_t(qp_mgr* qp_mgr) :
|
|
Packit |
6d2c1b |
ibv_flow(NULL),
|
|
Packit |
6d2c1b |
p_qp_mgr(qp_mgr),
|
|
Packit |
6d2c1b |
ibv_flow_attr(qp_mgr->get_port_num()) {}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
} attach_flow_data_ib_v2_t;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#ifdef DEFINED_IBV_FLOW_SPEC_IB
|
|
Packit |
6d2c1b |
typedef struct attach_flow_data_ib_v1_t {
|
|
Packit |
6d2c1b |
struct ibv_flow * ibv_flow;
|
|
Packit |
6d2c1b |
qp_mgr* p_qp_mgr;
|
|
Packit |
6d2c1b |
struct ibv_flow_attr_ib_v1 {
|
|
Packit |
6d2c1b |
vma_ibv_flow_attr attr;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_ib ib;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ibv_flow_attr_ib_v1(uint8_t port) {
|
|
Packit |
6d2c1b |
memset(this, 0, sizeof(*this));
|
|
Packit |
6d2c1b |
attr.size = sizeof(struct ibv_flow_attr_ib_v1);
|
|
Packit |
6d2c1b |
attr.num_of_specs = 1;
|
|
Packit |
6d2c1b |
attr.type = VMA_IBV_FLOW_ATTR_NORMAL;
|
|
Packit |
6d2c1b |
attr.priority = 1; // almost highest priority, 0 is used for 5-tuple later
|
|
Packit |
6d2c1b |
attr.port = port;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
} ibv_flow_attr;
|
|
Packit |
6d2c1b |
attach_flow_data_ib_v1_t(qp_mgr* qp_mgr) :
|
|
Packit |
6d2c1b |
ibv_flow(NULL),
|
|
Packit |
6d2c1b |
p_qp_mgr(qp_mgr),
|
|
Packit |
6d2c1b |
ibv_flow_attr(qp_mgr->get_port_num()) {}
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
} attach_flow_data_ib_v1_t;
|
|
Packit |
6d2c1b |
#endif
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
/* IPOIB (UC)
|
|
Packit |
6d2c1b |
*/
|
|
Packit |
6d2c1b |
typedef struct attach_flow_data_ib_ipv4_tcp_udp_v2_t {
|
|
Packit |
6d2c1b |
struct ibv_flow * ibv_flow;
|
|
Packit |
6d2c1b |
qp_mgr* p_qp_mgr;
|
|
Packit |
6d2c1b |
struct ibv_flow_attr_ib_ipv4_tcp_udp_v2 {
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
vma_ibv_flow_attr attr;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_ipv4 ipv4;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_tcp_udp tcp_udp;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ibv_flow_attr_ib_ipv4_tcp_udp_v2(uint8_t port) {
|
|
Packit |
6d2c1b |
memset(this, 0, sizeof(*this));
|
|
Packit |
6d2c1b |
attr.size = sizeof(struct ibv_flow_attr_ib_ipv4_tcp_udp_v2);
|
|
Packit |
6d2c1b |
attr.num_of_specs = 2;
|
|
Packit |
6d2c1b |
attr.type = VMA_IBV_FLOW_ATTR_NORMAL;
|
|
Packit |
6d2c1b |
attr.priority = 1; // almost highest priority, 0 is used for 5-tuple later
|
|
Packit |
6d2c1b |
attr.port = port;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
} ibv_flow_attr;
|
|
Packit |
6d2c1b |
attach_flow_data_ib_ipv4_tcp_udp_v2_t(qp_mgr* qp_mgr) :
|
|
Packit |
6d2c1b |
ibv_flow(NULL),
|
|
Packit |
6d2c1b |
p_qp_mgr(qp_mgr),
|
|
Packit |
6d2c1b |
ibv_flow_attr(qp_mgr->get_port_num()) {}
|
|
Packit |
6d2c1b |
} attach_flow_data_ib_ipv4_tcp_udp_v2_t;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#ifdef DEFINED_IBV_FLOW_SPEC_IB
|
|
Packit |
6d2c1b |
typedef struct attach_flow_data_ib_ipv4_tcp_udp_v1_t {
|
|
Packit |
6d2c1b |
struct ibv_flow * ibv_flow;
|
|
Packit |
6d2c1b |
qp_mgr* p_qp_mgr;
|
|
Packit |
6d2c1b |
struct ibv_flow_attr_ib_ipv4_tcp_udp_v1 {
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
vma_ibv_flow_attr attr;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_ib ib;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_ipv4 ipv4;
|
|
Packit |
6d2c1b |
vma_ibv_flow_spec_tcp_udp tcp_udp;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
ibv_flow_attr_ib_ipv4_tcp_udp_v1(uint8_t port) {
|
|
Packit |
6d2c1b |
memset(this, 0, sizeof(*this));
|
|
Packit |
6d2c1b |
attr.size = sizeof(struct ibv_flow_attr_ib_ipv4_tcp_udp_v1);
|
|
Packit |
6d2c1b |
attr.num_of_specs = 3;
|
|
Packit |
6d2c1b |
attr.type = VMA_IBV_FLOW_ATTR_NORMAL;
|
|
Packit |
6d2c1b |
attr.priority = 1; // almost highest priority, 0 is used for 5-tuple later
|
|
Packit |
6d2c1b |
attr.port = port;
|
|
Packit |
6d2c1b |
}
|
|
Packit |
6d2c1b |
} ibv_flow_attr;
|
|
Packit |
6d2c1b |
attach_flow_data_ib_ipv4_tcp_udp_v1_t(qp_mgr* qp_mgr) :
|
|
Packit |
6d2c1b |
ibv_flow(NULL),
|
|
Packit |
6d2c1b |
p_qp_mgr(qp_mgr),
|
|
Packit |
6d2c1b |
ibv_flow_attr(qp_mgr->get_port_num()) {}
|
|
Packit |
6d2c1b |
} attach_flow_data_ib_ipv4_tcp_udp_v1_t;
|
|
Packit |
6d2c1b |
#endif /* DEFINED_IBV_FLOW_SPEC_IB */
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
typedef struct attach_flow_data_t {
|
|
Packit |
6d2c1b |
vma_ibv_flow * ibv_flow;
|
|
Packit |
6d2c1b |
qp_mgr* p_qp_mgr;
|
|
Packit |
6d2c1b |
vma_ibv_flow_attr ibv_flow_attr;
|
|
Packit |
6d2c1b |
} attach_flow_data_t;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
typedef std::vector<attach_flow_data_t*> attach_flow_data_vector_t;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
class rfs_rule_filter
|
|
Packit |
6d2c1b |
{
|
|
Packit |
6d2c1b |
public:
|
|
Packit |
6d2c1b |
rfs_rule_filter(rule_filter_map_t& map, uint64_t key, flow_tuple& flow_tuple) : m_map(map), m_key(key), m_flow_tuple(flow_tuple) {}
|
|
Packit |
6d2c1b |
rule_filter_map_t& m_map;
|
|
Packit |
6d2c1b |
uint64_t m_key;
|
|
Packit |
6d2c1b |
flow_tuple m_flow_tuple;
|
|
Packit |
6d2c1b |
};
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
/**
|
|
Packit |
6d2c1b |
* @class rfs
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
* Object to manages the sink list
|
|
Packit |
6d2c1b |
* This object is used for maintaining the sink list and dispatching packets
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
*/
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
class rfs
|
|
Packit |
6d2c1b |
{
|
|
Packit |
6d2c1b |
public:
|
|
Packit |
6d2c1b |
rfs(flow_tuple *flow_spec_5t, ring_slave *p_ring,
|
|
Packit |
6d2c1b |
rfs_rule_filter* rule_filter = NULL, uint32_t flow_tag_id = 0);
|
|
Packit |
6d2c1b |
virtual ~rfs();
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
/**
|
|
Packit |
6d2c1b |
* Register/Unregister a sink with this rfs object
|
|
Packit |
6d2c1b |
* Get notifications about incoming packets using the pkt_rcvr_sink callback api
|
|
Packit |
6d2c1b |
* The rfs will call ibv_attach on the QP once when at least one receiver sink is registered
|
|
Packit |
6d2c1b |
* An ibv_detach is called when the last receiver sink is deleted from the registered list
|
|
Packit |
6d2c1b |
*
|
|
Packit |
6d2c1b |
*/
|
|
Packit |
6d2c1b |
bool attach_flow(pkt_rcvr_sink *sink); // Add a sink. If this is the first sink --> map the sink and attach flow to QP
|
|
Packit |
6d2c1b |
bool detach_flow(pkt_rcvr_sink *sink); // Delete a sink. If this is the last sink --> delete it and detach flow from QP
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
uint32_t get_num_of_sinks() const { return m_n_sinks_list_entries; }
|
|
Packit |
6d2c1b |
virtual bool rx_dispatch_packet(mem_buf_desc_t* p_rx_wc_buf_desc, void* pv_fd_ready_array) = 0;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
protected:
|
|
Packit |
6d2c1b |
flow_tuple m_flow_tuple;
|
|
Packit |
6d2c1b |
ring_slave* m_p_ring;
|
|
Packit |
6d2c1b |
rfs_rule_filter* m_p_rule_filter;
|
|
Packit |
6d2c1b |
attach_flow_data_vector_t m_attach_flow_data_vector;
|
|
Packit |
6d2c1b |
pkt_rcvr_sink** m_sinks_list;
|
|
Packit |
6d2c1b |
uint32_t m_n_sinks_list_entries; // Number of actual sinks in the array (we shrink the array if a sink is removed)
|
|
Packit |
6d2c1b |
uint32_t m_n_sinks_list_max_length;
|
|
Packit |
6d2c1b |
uint32_t m_flow_tag_id; // Associated with this rule, set by attach_flow()
|
|
Packit |
6d2c1b |
bool m_b_tmp_is_attached; // Only temporary, while ibcm calls attach_flow with no sinks...
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
bool create_ibv_flow(); // Attach flow to all qps
|
|
Packit |
6d2c1b |
bool destroy_ibv_flow(); // Detach flow from all qps
|
|
Packit |
6d2c1b |
bool add_sink(pkt_rcvr_sink* p_sink);
|
|
Packit |
6d2c1b |
bool del_sink(pkt_rcvr_sink* p_sink);
|
|
Packit |
6d2c1b |
virtual bool prepare_flow_spec() = 0;
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
private:
|
|
Packit |
6d2c1b |
rfs(); // I don't want anyone to use the default constructor
|
|
Packit |
6d2c1b |
inline void prepare_filter_attach(int& filter_counter, rule_filter_map_t::iterator& filter_iter);
|
|
Packit |
6d2c1b |
inline void filter_keep_attached(rule_filter_map_t::iterator& filter_iter);
|
|
Packit |
6d2c1b |
inline void prepare_filter_detach(int& filter_counter, bool decrease_counter);
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
};
|
|
Packit |
6d2c1b |
|
|
Packit |
6d2c1b |
#endif /* RFS_H */
|