-
Notifications
You must be signed in to change notification settings - Fork 735
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
introduce kni isolate rx queue support #695
base: devel
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -29,6 +29,28 @@ | |
#include <stdbool.h> | ||
#include "netif.h" | ||
|
||
/* | ||
* NOTE: | ||
* 1. local ip filter will make input set fixed on ixgbe/i40e. | ||
* 2. dip filter is not supported by ixgbe and i40e under the | ||
* premise of local ip filter. | ||
* 3. use dip + dport + dst_port_mask filters to cover port range | ||
* [0-65535] to replace dip filter on ixgbe/i40e. | ||
* 4. kni fdir filter support tcp and udp, icmp not supported. | ||
* 5. if (fdir_conf.mask.dst_port_mask & pkt.dport) equal to an | ||
* element in the port_base_array, pkt will match kni fdir | ||
* filter and redirected to kni rx queue. | ||
Comment on lines
+34
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there a solution to support both tcp/udp and IP protocols? Somebody may prefer OSPF (IP protocol 89) to BGP(TCP) for ECMP routes. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. flow支持ip粒度或者tcp/udp的,这里的注释是解释的ixgbe/i40e,intel卡有input set,一种filter/flow会固定input set,其他input set的filter/flow可能就不生效。 |
||
* 6. rss rte_flow to specfic rss queue region should with lower | ||
* priority than lip and kni fdir filter. | ||
*/ | ||
typedef struct kni_fdir { | ||
bool init_success; /* kni fdir init flag */ | ||
uint16_t filter_mask; /* kni filter's port mask */ | ||
uint16_t port_base_num; /* kni port_base num */ | ||
__be16 port_base_array[DPVS_MAX_LCORE]; /* kni port_base set */ | ||
uint32_t soft_id_array[DPVS_MAX_LCORE][MAX_FDIR_PROTO]; | ||
} dp_vs_kni_fdir; | ||
|
||
/* | ||
* @dev - real device kni attach to. | ||
* @kniname - optional, kni device name or auto generate. | ||
|
@@ -38,6 +60,11 @@ int kni_add_dev(struct netif_port *dev, const char *kniname); | |
int kni_del_dev(struct netif_port *dev); | ||
int kni_init(void); | ||
|
||
int kni_fdir_init(void); | ||
int kni_fdir_filter_add(struct netif_port *dev, | ||
const union inet_addr *kni_ip, | ||
int af); | ||
|
||
static inline bool kni_dev_exist(const struct netif_port *dev) | ||
{ | ||
return dev->kni.kni ? true : false; | ||
|
@@ -51,4 +78,21 @@ static inline void kni_handle_request(const struct netif_port *dev) | |
rte_kni_handle_request(dev->kni.kni); | ||
} | ||
|
||
static inline bool kni_fwd_valid(const struct netif_port *dev, | ||
kni_fwd_mode_t fwd_mode) | ||
{ | ||
if (fwd_mode == KNI_FWD_MODE_DEFAULT) { | ||
return true; | ||
} | ||
|
||
if ((fwd_mode == KNI_FWD_MODE_ISOLATE_RX) | ||
&& (dev->kni.fwd_mode == fwd_mode) | ||
&& (dev->kni.rx_queue_id != NETIF_QUEUE_ID_INVALID)) | ||
{ | ||
Comment on lines
+90
to
+91
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
return true; | ||
} | ||
|
||
return false; | ||
} | ||
|
||
#endif /* __DPVS_KNI_H__ */ |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
/* | ||
* DPVS is a software load balancer (Virtual Server) based on DPDK. | ||
* | ||
* Copyright (C) 2020 ByteDance (www.bytedance.com). | ||
* All Rights Reserved. | ||
* | ||
* This program is free software; you can redistribute it and/or | ||
* modify it under the terms of the GNU General Public License | ||
* as published by the Free Software Foundation; either version 2 | ||
* of the License, or (at your option) any later version. | ||
* | ||
* This program is distributed in the hope that it will be useful, | ||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
* GNU General Public License for more details. | ||
* | ||
* Copyright (C) 2020 ByteDance (www.bytedance.com). | ||
* All Rights Reserved. | ||
* | ||
* [email protected], 12/2020. | ||
*/ | ||
#ifndef __NETDEV_FLOW_H__ | ||
#define __NETDEV_FLOW_H__ | ||
|
||
#include <assert.h> | ||
#include <rte_flow.h> | ||
|
||
#include "conf/common.h" | ||
#include "netif.h" | ||
|
||
#ifndef NETDEV | ||
#define NETDEV | ||
#define RTE_LOGTYPE_NETDEV RTE_LOGTYPE_USER1 | ||
#endif | ||
|
||
#define DEFAULT_MAX_PATTERNS 6 | ||
#define DEFAULT_MAX_ACTIONS 6 | ||
|
||
#define NETDEV_FLOW_DEFAULT_MARK_ID 1 | ||
#define NETDEV_FLOW_DEFAULT_RSS_LEVEL 0 | ||
|
||
/* fuzzy match level with signature mode */ | ||
#define DEFAULT_FUZZY_SPEC 2 | ||
#define DEFAULT_FUZZY_LAST 0xfffffff0 | ||
#define DEFAULT_FUZZY_MASK 0xffffffff | ||
|
||
#define NETDEV_IXGBE_DRIVER_NAME "ixgbe" | ||
#define NETDEV_I40E_DRIVER_NAME "i40e" | ||
#define NETDEV_MLNX_DRIVER_NAME "net_mlx5" | ||
|
||
/* flags for netdev flow */ | ||
#define NETDEV_FLOW_F_SIP_FIELD (1 << 0) | ||
#define NETDEV_FLOW_F_DIP_FIELD (1 << 1) | ||
#define NETDEV_FLOW_F_SPORT_FIELD (1 << 2) | ||
#define NETDEV_FLOW_F_DPORT_FIELD (1 << 3) | ||
#define NETDEV_FLOW_F_L3_PROTO_FIELD (1 << 4) | ||
#define NETDEV_FLOW_F_L4_PROTO_FIELD (1 << 5) | ||
|
||
/* | ||
* assign static priority on various flow | ||
* the smaller the priority higher on mellanox nic. | ||
*/ | ||
enum netdev_flow_priority { | ||
NETDEV_FLOW_PRIORITY_NONE = 0, | ||
NETDEV_FLOW_PRIORITY_FILTER, | ||
NETDEV_FLOW_PRIORITY_VXLAN, | ||
NETDEV_FLOW_PRIORITY_RSS, | ||
}; | ||
|
||
/* move to next acts index, abort on failure */ | ||
#define get_next_acts_index(index) do { \ | ||
assert((index) < DEFAULT_MAX_ACTIONS - 1); \ | ||
(index)++; \ | ||
} while(0) | ||
|
||
/* move to next patts index, abort on failure */ | ||
#define get_next_patts_index(index) do { \ | ||
assert((index) < DEFAULT_MAX_PATTERNS - 1); \ | ||
(index)++; \ | ||
} while(0) | ||
|
||
/* netdev rss flow init */ | ||
#define NETDEV_RSS_FLOW_INIT(flow, port) do { \ | ||
flow->type = NETDEV_FLOW_TYPE_RSS; \ | ||
flow->port_id = port->id; \ | ||
flow->flow_handle = NULL; \ | ||
flow->hw_offloaded = false; \ | ||
flow->flow_id = netdev_flow_hash(flow); \ | ||
} while(0) | ||
|
||
enum netdev_flow_type { | ||
NETDEV_FLOW_TYPE_RSS, | ||
NETDEV_FLOW_TYPE_FILTER, | ||
NETDEV_FLOW_TYPE_MAX | ||
}; | ||
|
||
union netdev_flow_query { | ||
struct rte_flow_query_count count; | ||
struct rte_flow_action_queue queue; | ||
struct rte_flow_action_rss rss_conf; | ||
}; | ||
|
||
struct netdev_flow_stats { | ||
uint64_t n_pkts; | ||
uint64_t n_bytes; | ||
}; | ||
|
||
struct netdev_flow { | ||
enum netdev_flow_type type; | ||
portid_t port_id; | ||
|
||
/* flow meta data */ | ||
union { | ||
struct { | ||
queueid_t rss_queues[NETIF_MAX_QUEUES]; | ||
uint32_t rss_queue_num; | ||
} rss_info; | ||
struct { | ||
queueid_t queue_id; | ||
uint16_t sport; | ||
uint16_t dport; | ||
uint8_t l3_proto; | ||
uint8_t l4_proto; | ||
union inet_addr saddr; | ||
union inet_addr daddr; | ||
} filter_info; | ||
} data; | ||
|
||
uint32_t flags; | ||
/* unique flow id */ | ||
uint32_t flow_id; | ||
|
||
/* pointer to rte flow in hardware */ | ||
struct rte_flow *flow_handle; | ||
bool hw_offloaded; | ||
struct list_head list; | ||
struct netdev_flow_stats stats; | ||
}; | ||
|
||
/* l4_proto used by i40e only */ | ||
int netdev_flow_add_kni_filter(struct netif_port *port, | ||
ywc689 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
const union inet_addr *kni_ip, | ||
queueid_t kni_queue_id, | ||
uint8_t l3_proto, | ||
uint8_t l4_proto); | ||
/* called on dpvs initial */ | ||
int netdev_flow_add_rss_filter(struct netif_port *port); | ||
|
||
/* | ||
* NOTE: netdev flow api, operate flow on initial or terminal, | ||
* need to use lock on rte_flow_* in case of concurrent. | ||
*/ | ||
int netdev_flow_init(struct netif_port *port); | ||
int netdev_flow_add(struct netif_port *port, | ||
struct netdev_flow *netdev_flow); | ||
int netdev_flow_del(struct netif_port *port, | ||
struct netdev_flow *netdev_flow); | ||
int netdev_flow_query(struct netif_port *port, | ||
struct netdev_flow *netdev_flow, | ||
union netdev_flow_query *query); | ||
int netdev_flow_flush(struct netif_port *port); | ||
|
||
#endif /* __NETDEV_FLOW_H__ */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is
rx_queue_id
needed to config in kni worker type?