Commit 300c1918 authored by Michael Chan's avatar Michael Chan Committed by David S. Miller

bnxt_en: Add ntuple matching flags to the bnxt_ntuple_filter structure.

aRFS filters match all 5 tuples.  User defined ntuple filters may
specify some of the tuples as wildcards.  To support that, we add the
ntuple_flags to the bnxt_ntuple_filter struct to specify which tuple
fields are to be matched.  The matching tuple fields will then be
passed to the firmware in bnxt_hwrm_cfa_ntuple_filter_alloc() to create
the proper filter.
Reviewed-by: default avatarVasundhara Volam <vasundhara-v.volam@broadcom.com>
Reviewed-by: default avatarAndy Gospodarek <andrew.gospodarek@broadcom.com>
Reviewed-by: default avatarPavan Chebbi <pavan.chebbi@broadcom.com>
Signed-off-by: default avatarMichael Chan <michael.chan@broadcom.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4faeadfd
...@@ -5642,6 +5642,14 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, ...@@ -5642,6 +5642,14 @@ int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
#define BNXT_NTP_TUNNEL_FLTR_FLAG \ #define BNXT_NTP_TUNNEL_FLTR_FLAG \
CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE CFA_NTUPLE_FILTER_ALLOC_REQ_ENABLES_TUNNEL_TYPE
void bnxt_fill_ipv6_mask(__be32 mask[4])
{
int i;
for (i = 0; i < 4; i++)
mask[i] = cpu_to_be32(~0);
}
static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
struct bnxt_ntuple_filter *fltr) struct bnxt_ntuple_filter *fltr)
{ {
...@@ -5676,24 +5684,28 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, ...@@ -5676,24 +5684,28 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
req->ip_protocol = keys->basic.ip_proto; req->ip_protocol = keys->basic.ip_proto;
if (keys->basic.n_proto == htons(ETH_P_IPV6)) { if (keys->basic.n_proto == htons(ETH_P_IPV6)) {
int i;
req->ethertype = htons(ETH_P_IPV6); req->ethertype = htons(ETH_P_IPV6);
req->ip_addr_type = req->ip_addr_type =
CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6; CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6;
*(struct in6_addr *)&req->src_ipaddr[0] = if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
keys->addrs.v6addrs.src; *(struct in6_addr *)&req->src_ipaddr[0] =
*(struct in6_addr *)&req->dst_ipaddr[0] = keys->addrs.v6addrs.src;
keys->addrs.v6addrs.dst; bnxt_fill_ipv6_mask(req->src_ipaddr_mask);
for (i = 0; i < 4; i++) { }
req->src_ipaddr_mask[i] = cpu_to_be32(0xffffffff); if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
req->dst_ipaddr_mask[i] = cpu_to_be32(0xffffffff); *(struct in6_addr *)&req->dst_ipaddr[0] =
keys->addrs.v6addrs.dst;
bnxt_fill_ipv6_mask(req->dst_ipaddr_mask);
} }
} else { } else {
req->src_ipaddr[0] = keys->addrs.v4addrs.src; if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff); req->src_ipaddr[0] = keys->addrs.v4addrs.src;
req->dst_ipaddr[0] = keys->addrs.v4addrs.dst; req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff); }
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
req->dst_ipaddr[0] = keys->addrs.v4addrs.dst;
req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
}
} }
if (keys->control.flags & FLOW_DIS_ENCAPSULATION) { if (keys->control.flags & FLOW_DIS_ENCAPSULATION) {
req->enables |= cpu_to_le32(BNXT_NTP_TUNNEL_FLTR_FLAG); req->enables |= cpu_to_le32(BNXT_NTP_TUNNEL_FLTR_FLAG);
...@@ -5701,10 +5713,14 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp, ...@@ -5701,10 +5713,14 @@ static int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL; CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL;
} }
req->src_port = keys->ports.src; if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
req->src_port_mask = cpu_to_be16(0xffff); req->src_port = keys->ports.src;
req->dst_port = keys->ports.dst; req->src_port_mask = cpu_to_be16(0xffff);
req->dst_port_mask = cpu_to_be16(0xffff); }
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
req->dst_port = keys->ports.dst;
req->dst_port_mask = cpu_to_be16(0xffff);
}
resp = hwrm_req_hold(bp, req); resp = hwrm_req_hold(bp, req);
rc = hwrm_req_send(bp, req); rc = hwrm_req_send(bp, req);
...@@ -13886,24 +13902,38 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1, ...@@ -13886,24 +13902,38 @@ static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
struct flow_keys *keys1 = &f1->fkeys; struct flow_keys *keys1 = &f1->fkeys;
struct flow_keys *keys2 = &f2->fkeys; struct flow_keys *keys2 = &f2->fkeys;
if (f1->ntuple_flags != f2->ntuple_flags)
return false;
if (keys1->basic.n_proto != keys2->basic.n_proto || if (keys1->basic.n_proto != keys2->basic.n_proto ||
keys1->basic.ip_proto != keys2->basic.ip_proto) keys1->basic.ip_proto != keys2->basic.ip_proto)
return false; return false;
if (keys1->basic.n_proto == htons(ETH_P_IP)) { if (keys1->basic.n_proto == htons(ETH_P_IP)) {
if (keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src || if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) &&
keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst) keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src) ||
((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) &&
keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst))
return false; return false;
} else { } else {
if (memcmp(&keys1->addrs.v6addrs.src, &keys2->addrs.v6addrs.src, if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) &&
sizeof(keys1->addrs.v6addrs.src)) || memcmp(&keys1->addrs.v6addrs.src,
memcmp(&keys1->addrs.v6addrs.dst, &keys2->addrs.v6addrs.dst, &keys2->addrs.v6addrs.src,
sizeof(keys1->addrs.v6addrs.dst))) sizeof(keys1->addrs.v6addrs.src))) ||
((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) &&
memcmp(&keys1->addrs.v6addrs.dst,
&keys2->addrs.v6addrs.dst,
sizeof(keys1->addrs.v6addrs.dst))))
return false; return false;
} }
if (keys1->ports.ports == keys2->ports.ports && if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) &&
keys1->control.flags == keys2->control.flags && keys1->ports.src != keys2->ports.src) ||
((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) &&
keys1->ports.dst != keys2->ports.dst))
return false;
if (keys1->control.flags == keys2->control.flags &&
f1->l2_fltr == f2->l2_fltr) f1->l2_fltr == f2->l2_fltr)
return true; return true;
...@@ -13985,6 +14015,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb, ...@@ -13985,6 +14015,7 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
} }
new_fltr->l2_fltr = l2_fltr; new_fltr->l2_fltr = l2_fltr;
new_fltr->ntuple_flags = BNXT_NTUPLE_MATCH_ALL;
idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb); idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
rcu_read_lock(); rcu_read_lock();
......
...@@ -1358,6 +1358,15 @@ struct bnxt_ntuple_filter { ...@@ -1358,6 +1358,15 @@ struct bnxt_ntuple_filter {
struct bnxt_filter_base base; struct bnxt_filter_base base;
struct flow_keys fkeys; struct flow_keys fkeys;
struct bnxt_l2_filter *l2_fltr; struct bnxt_l2_filter *l2_fltr;
u32 ntuple_flags;
#define BNXT_NTUPLE_MATCH_SRC_IP 1
#define BNXT_NTUPLE_MATCH_DST_IP 2
#define BNXT_NTUPLE_MATCH_SRC_PORT 4
#define BNXT_NTUPLE_MATCH_DST_PORT 8
#define BNXT_NTUPLE_MATCH_ALL (BNXT_NTUPLE_MATCH_SRC_IP | \
BNXT_NTUPLE_MATCH_DST_IP | \
BNXT_NTUPLE_MATCH_SRC_PORT | \
BNXT_NTUPLE_MATCH_DST_PORT)
u32 flow_id; u32 flow_id;
}; };
...@@ -2638,6 +2647,7 @@ int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr); ...@@ -2638,6 +2647,7 @@ int bnxt_hwrm_l2_filter_free(struct bnxt *bp, struct bnxt_l2_filter *fltr);
int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr); int bnxt_hwrm_l2_filter_alloc(struct bnxt *bp, struct bnxt_l2_filter *fltr);
int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp, int bnxt_hwrm_cfa_ntuple_filter_free(struct bnxt *bp,
struct bnxt_ntuple_filter *fltr); struct bnxt_ntuple_filter *fltr);
void bnxt_fill_ipv6_mask(__be32 mask[4]);
int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings); int bnxt_get_nr_rss_ctxs(struct bnxt *bp, int rx_rings);
int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id); int bnxt_hwrm_vnic_cfg(struct bnxt *bp, u16 vnic_id);
int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings); int __bnxt_hwrm_get_tx_rings(struct bnxt *bp, u16 fid, int *tx_rings);
......
...@@ -1100,20 +1100,23 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd) ...@@ -1100,20 +1100,23 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
else else
goto fltr_err; goto fltr_err;
fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src; if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0); fs->h_u.tcp_ip4_spec.ip4src = fkeys->addrs.v4addrs.src;
fs->m_u.tcp_ip4_spec.ip4src = cpu_to_be32(~0);
fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst; }
fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0); if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
fs->h_u.tcp_ip4_spec.ip4dst = fkeys->addrs.v4addrs.dst;
fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src; fs->m_u.tcp_ip4_spec.ip4dst = cpu_to_be32(~0);
fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0); }
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst; fs->h_u.tcp_ip4_spec.psrc = fkeys->ports.src;
fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0); fs->m_u.tcp_ip4_spec.psrc = cpu_to_be16(~0);
}
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
fs->h_u.tcp_ip4_spec.pdst = fkeys->ports.dst;
fs->m_u.tcp_ip4_spec.pdst = cpu_to_be16(~0);
}
} else { } else {
int i;
if (fkeys->basic.ip_proto == IPPROTO_TCP) if (fkeys->basic.ip_proto == IPPROTO_TCP)
fs->flow_type = TCP_V6_FLOW; fs->flow_type = TCP_V6_FLOW;
else if (fkeys->basic.ip_proto == IPPROTO_UDP) else if (fkeys->basic.ip_proto == IPPROTO_UDP)
...@@ -1121,19 +1124,24 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd) ...@@ -1121,19 +1124,24 @@ static int bnxt_grxclsrule(struct bnxt *bp, struct ethtool_rxnfc *cmd)
else else
goto fltr_err; goto fltr_err;
*(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] = if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
fkeys->addrs.v6addrs.src; *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6src[0] =
*(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] = fkeys->addrs.v6addrs.src;
fkeys->addrs.v6addrs.dst; bnxt_fill_ipv6_mask(fs->m_u.tcp_ip6_spec.ip6src);
for (i = 0; i < 4; i++) { }
fs->m_u.tcp_ip6_spec.ip6src[i] = cpu_to_be32(~0); if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
fs->m_u.tcp_ip6_spec.ip6dst[i] = cpu_to_be32(~0); *(struct in6_addr *)&fs->h_u.tcp_ip6_spec.ip6dst[0] =
fkeys->addrs.v6addrs.dst;
bnxt_fill_ipv6_mask(fs->m_u.tcp_ip6_spec.ip6dst);
}
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src;
fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(~0);
}
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst;
fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0);
} }
fs->h_u.tcp_ip6_spec.psrc = fkeys->ports.src;
fs->m_u.tcp_ip6_spec.psrc = cpu_to_be16(~0);
fs->h_u.tcp_ip6_spec.pdst = fkeys->ports.dst;
fs->m_u.tcp_ip6_spec.pdst = cpu_to_be16(~0);
} }
fs->ring_cookie = fltr->base.rxq; fs->ring_cookie = fltr->base.rxq;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment