Skip to content

Commit c8d129c

Browse files
Edwin Peerkuba-moo
authored andcommitted
bnxt_en: implement fully specified 5-tuple masks
Support subfield masking for IP addresses and ports. Previously, only entire fields could be included or excluded in NTUPLE filters. Reviewed-by: Pavan Chebbi <pavan.chebbi@broadcom.com> Signed-off-by: Edwin Peer <edwin.peer@broadcom.com> Signed-off-by: Michael Chan <michael.chan@broadcom.com> Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Link: https://lore.kernel.org/r/20240205223202.25341-5-michael.chan@broadcom.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
1 parent 7c8036f commit c8d129c

File tree

3 files changed

+134
-168
lines changed

3 files changed

+134
-168
lines changed

drivers/net/ethernet/broadcom/bnxt/bnxt.c

Lines changed: 83 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,49 @@ static const u16 bnxt_async_events_arr[] = {
246246

247247
static struct workqueue_struct *bnxt_pf_wq;
248248

249+
#define BNXT_IPV6_MASK_ALL {{{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, \
250+
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }}}
251+
#define BNXT_IPV6_MASK_NONE {{{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }}}
252+
253+
const struct bnxt_flow_masks BNXT_FLOW_MASK_NONE = {
254+
.ports = {
255+
.src = 0,
256+
.dst = 0,
257+
},
258+
.addrs = {
259+
.v6addrs = {
260+
.src = BNXT_IPV6_MASK_NONE,
261+
.dst = BNXT_IPV6_MASK_NONE,
262+
},
263+
},
264+
};
265+
266+
const struct bnxt_flow_masks BNXT_FLOW_IPV6_MASK_ALL = {
267+
.ports = {
268+
.src = cpu_to_be16(0xffff),
269+
.dst = cpu_to_be16(0xffff),
270+
},
271+
.addrs = {
272+
.v6addrs = {
273+
.src = BNXT_IPV6_MASK_ALL,
274+
.dst = BNXT_IPV6_MASK_ALL,
275+
},
276+
},
277+
};
278+
279+
const struct bnxt_flow_masks BNXT_FLOW_IPV4_MASK_ALL = {
280+
.ports = {
281+
.src = cpu_to_be16(0xffff),
282+
.dst = cpu_to_be16(0xffff),
283+
},
284+
.addrs = {
285+
.v4addrs = {
286+
.src = cpu_to_be32(0xffffffff),
287+
.dst = cpu_to_be32(0xffffffff),
288+
},
289+
},
290+
};
291+
249292
static bool bnxt_vf_pciid(enum board_idx idx)
250293
{
251294
return (idx == NETXTREME_C_VF || idx == NETXTREME_E_VF ||
@@ -5690,6 +5733,7 @@ int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
56905733
{
56915734
struct hwrm_cfa_ntuple_filter_alloc_output *resp;
56925735
struct hwrm_cfa_ntuple_filter_alloc_input *req;
5736+
struct bnxt_flow_masks *masks = &fltr->fmasks;
56935737
struct flow_keys *keys = &fltr->fkeys;
56945738
struct bnxt_l2_filter *l2_fltr;
56955739
struct bnxt_vnic_info *vnic;
@@ -5722,40 +5766,26 @@ int bnxt_hwrm_cfa_ntuple_filter_alloc(struct bnxt *bp,
57225766
req->ethertype = htons(ETH_P_IPV6);
57235767
req->ip_addr_type =
57245768
CFA_NTUPLE_FILTER_ALLOC_REQ_IP_ADDR_TYPE_IPV6;
5725-
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
5726-
*(struct in6_addr *)&req->src_ipaddr[0] =
5727-
keys->addrs.v6addrs.src;
5728-
bnxt_fill_ipv6_mask(req->src_ipaddr_mask);
5729-
}
5730-
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
5731-
*(struct in6_addr *)&req->dst_ipaddr[0] =
5732-
keys->addrs.v6addrs.dst;
5733-
bnxt_fill_ipv6_mask(req->dst_ipaddr_mask);
5734-
}
5769+
*(struct in6_addr *)&req->src_ipaddr[0] = keys->addrs.v6addrs.src;
5770+
*(struct in6_addr *)&req->src_ipaddr_mask[0] = masks->addrs.v6addrs.src;
5771+
*(struct in6_addr *)&req->dst_ipaddr[0] = keys->addrs.v6addrs.dst;
5772+
*(struct in6_addr *)&req->dst_ipaddr_mask[0] = masks->addrs.v6addrs.dst;
57355773
} else {
5736-
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) {
5737-
req->src_ipaddr[0] = keys->addrs.v4addrs.src;
5738-
req->src_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
5739-
}
5740-
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) {
5741-
req->dst_ipaddr[0] = keys->addrs.v4addrs.dst;
5742-
req->dst_ipaddr_mask[0] = cpu_to_be32(0xffffffff);
5743-
}
5774+
req->src_ipaddr[0] = keys->addrs.v4addrs.src;
5775+
req->src_ipaddr_mask[0] = masks->addrs.v4addrs.src;
5776+
req->dst_ipaddr[0] = keys->addrs.v4addrs.dst;
5777+
req->dst_ipaddr_mask[0] = masks->addrs.v4addrs.dst;
57445778
}
57455779
if (keys->control.flags & FLOW_DIS_ENCAPSULATION) {
57465780
req->enables |= cpu_to_le32(BNXT_NTP_TUNNEL_FLTR_FLAG);
57475781
req->tunnel_type =
57485782
CFA_NTUPLE_FILTER_ALLOC_REQ_TUNNEL_TYPE_ANYTUNNEL;
57495783
}
57505784

5751-
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) {
5752-
req->src_port = keys->ports.src;
5753-
req->src_port_mask = cpu_to_be16(0xffff);
5754-
}
5755-
if (fltr->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) {
5756-
req->dst_port = keys->ports.dst;
5757-
req->dst_port_mask = cpu_to_be16(0xffff);
5758-
}
5785+
req->src_port = keys->ports.src;
5786+
req->src_port_mask = masks->ports.src;
5787+
req->dst_port = keys->ports.dst;
5788+
req->dst_port_mask = masks->ports.dst;
57595789

57605790
resp = hwrm_req_hold(bp, req);
57615791
rc = hwrm_req_send(bp, req);
@@ -13956,45 +13986,39 @@ int bnxt_insert_ntp_filter(struct bnxt *bp, struct bnxt_ntuple_filter *fltr,
1395613986
static bool bnxt_fltr_match(struct bnxt_ntuple_filter *f1,
1395713987
struct bnxt_ntuple_filter *f2)
1395813988
{
13989+
struct bnxt_flow_masks *masks1 = &f1->fmasks;
13990+
struct bnxt_flow_masks *masks2 = &f2->fmasks;
1395913991
struct flow_keys *keys1 = &f1->fkeys;
1396013992
struct flow_keys *keys2 = &f2->fkeys;
1396113993

13962-
if (f1->ntuple_flags != f2->ntuple_flags)
13963-
return false;
13964-
1396513994
if (keys1->basic.n_proto != keys2->basic.n_proto ||
1396613995
keys1->basic.ip_proto != keys2->basic.ip_proto)
1396713996
return false;
1396813997

1396913998
if (keys1->basic.n_proto == htons(ETH_P_IP)) {
13970-
if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) &&
13971-
keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src) ||
13972-
((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) &&
13973-
keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst))
13999+
if (keys1->addrs.v4addrs.src != keys2->addrs.v4addrs.src ||
14000+
masks1->addrs.v4addrs.src != masks2->addrs.v4addrs.src ||
14001+
keys1->addrs.v4addrs.dst != keys2->addrs.v4addrs.dst ||
14002+
masks1->addrs.v4addrs.dst != masks2->addrs.v4addrs.dst)
1397414003
return false;
1397514004
} else {
13976-
if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_IP) &&
13977-
memcmp(&keys1->addrs.v6addrs.src,
13978-
&keys2->addrs.v6addrs.src,
13979-
sizeof(keys1->addrs.v6addrs.src))) ||
13980-
((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_IP) &&
13981-
memcmp(&keys1->addrs.v6addrs.dst,
13982-
&keys2->addrs.v6addrs.dst,
13983-
sizeof(keys1->addrs.v6addrs.dst))))
14005+
if (!ipv6_addr_equal(&keys1->addrs.v6addrs.src,
14006+
&keys2->addrs.v6addrs.src) ||
14007+
!ipv6_addr_equal(&masks1->addrs.v6addrs.src,
14008+
&masks2->addrs.v6addrs.src) ||
14009+
!ipv6_addr_equal(&keys1->addrs.v6addrs.dst,
14010+
&keys2->addrs.v6addrs.dst) ||
14011+
!ipv6_addr_equal(&masks1->addrs.v6addrs.dst,
14012+
&masks2->addrs.v6addrs.dst))
1398414013
return false;
1398514014
}
1398614015

13987-
if (((f1->ntuple_flags & BNXT_NTUPLE_MATCH_SRC_PORT) &&
13988-
keys1->ports.src != keys2->ports.src) ||
13989-
((f1->ntuple_flags & BNXT_NTUPLE_MATCH_DST_PORT) &&
13990-
keys1->ports.dst != keys2->ports.dst))
13991-
return false;
13992-
13993-
if (keys1->control.flags == keys2->control.flags &&
13994-
f1->l2_fltr == f2->l2_fltr)
13995-
return true;
13996-
13997-
return false;
14016+
return keys1->ports.src == keys2->ports.src &&
14017+
masks1->ports.src == masks2->ports.src &&
14018+
keys1->ports.dst == keys2->ports.dst &&
14019+
masks1->ports.dst == masks2->ports.dst &&
14020+
keys1->control.flags == keys2->control.flags &&
14021+
f1->l2_fltr == f2->l2_fltr;
1399814022
}
1399914023

1400014024
struct bnxt_ntuple_filter *
@@ -14059,20 +14083,21 @@ static int bnxt_rx_flow_steer(struct net_device *dev, const struct sk_buff *skb,
1405914083
rc = -EPROTONOSUPPORT;
1406014084
goto err_free;
1406114085
}
14062-
if (fkeys->basic.n_proto == htons(ETH_P_IPV6) &&
14063-
bp->hwrm_spec_code < 0x10601) {
14064-
rc = -EPROTONOSUPPORT;
14065-
goto err_free;
14086+
new_fltr->fmasks = BNXT_FLOW_IPV4_MASK_ALL;
14087+
if (fkeys->basic.n_proto == htons(ETH_P_IPV6)) {
14088+
if (bp->hwrm_spec_code < 0x10601) {
14089+
rc = -EPROTONOSUPPORT;
14090+
goto err_free;
14091+
}
14092+
new_fltr->fmasks = BNXT_FLOW_IPV6_MASK_ALL;
1406614093
}
1406714094
flags = fkeys->control.flags;
1406814095
if (((flags & FLOW_DIS_ENCAPSULATION) &&
1406914096
bp->hwrm_spec_code < 0x10601) || (flags & FLOW_DIS_IS_FRAGMENT)) {
1407014097
rc = -EPROTONOSUPPORT;
1407114098
goto err_free;
1407214099
}
14073-
1407414100
new_fltr->l2_fltr = l2_fltr;
14075-
new_fltr->ntuple_flags = BNXT_NTUPLE_MATCH_ALL;
1407614101

1407714102
idx = bnxt_get_ntp_filter_idx(bp, fkeys, skb);
1407814103
rcu_read_lock();

drivers/net/ethernet/broadcom/bnxt/bnxt.h

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1355,19 +1355,20 @@ struct bnxt_filter_base {
13551355
struct rcu_head rcu;
13561356
};
13571357

1358+
struct bnxt_flow_masks {
1359+
struct flow_dissector_key_ports ports;
1360+
struct flow_dissector_key_addrs addrs;
1361+
};
1362+
1363+
extern const struct bnxt_flow_masks BNXT_FLOW_MASK_NONE;
1364+
extern const struct bnxt_flow_masks BNXT_FLOW_IPV6_MASK_ALL;
1365+
extern const struct bnxt_flow_masks BNXT_FLOW_IPV4_MASK_ALL;
1366+
13581367
struct bnxt_ntuple_filter {
13591368
struct bnxt_filter_base base;
13601369
struct flow_keys fkeys;
1370+
struct bnxt_flow_masks fmasks;
13611371
struct bnxt_l2_filter *l2_fltr;
1362-
u32 ntuple_flags;
1363-
#define BNXT_NTUPLE_MATCH_SRC_IP 1
1364-
#define BNXT_NTUPLE_MATCH_DST_IP 2
1365-
#define BNXT_NTUPLE_MATCH_SRC_PORT 4
1366-
#define BNXT_NTUPLE_MATCH_DST_PORT 8
1367-
#define BNXT_NTUPLE_MATCH_ALL (BNXT_NTUPLE_MATCH_SRC_IP | \
1368-
BNXT_NTUPLE_MATCH_DST_IP | \
1369-
BNXT_NTUPLE_MATCH_SRC_PORT | \
1370-
BNXT_NTUPLE_MATCH_DST_PORT)
13711372
u32 flow_id;
13721373
};
13731374

0 commit comments

Comments
 (0)