Skip to content

Commit 996dcff

Browse files
committed
Merge branch 'tc-flower-SPI'
Ratheesh Kannoth says: ==================== Packet classify by matching against SPI 1. net: flow_dissector: Add IPSEC dissector. Flow dissector patch reads IPSEC headers (ESP or AH) header from packet and retrieves the SPI header. 2. tc: flower: support for SPI. TC control path changes to pass SPI field from userspace to kernel. 3. tc: flower: Enable offload support IPSEC SPI field. Next patch enables the HW support for classify offload for ESP/AH. This patch enables the HW offload control. 4. octeontx2-pf: TC flower offload support for SPI field. HW offload support for classification in octeontx2 driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents d7301c4 + 73b4c04 commit 996dcff

File tree

11 files changed

+159
-1
lines changed

11 files changed

+159
-1
lines changed

drivers/net/ethernet/marvell/octeontx2/af/mbox.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,10 @@ struct flow_msg {
14511451
__be32 ip4dst;
14521452
__be32 ip6dst[4];
14531453
};
1454+
union {
1455+
__be32 spi;
1456+
};
1457+
14541458
u8 tos;
14551459
u8 ip_ver;
14561460
u8 ip_proto;

drivers/net/ethernet/marvell/octeontx2/af/npc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ enum key_fields {
204204
NPC_DPORT_UDP,
205205
NPC_SPORT_SCTP,
206206
NPC_DPORT_SCTP,
207+
NPC_IPSEC_SPI,
207208
NPC_HEADER_FIELDS_MAX,
208209
NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
209210
NPC_PF_FUNC, /* Valid when Tx */

drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2827,6 +2827,10 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
28272827
seq_printf(s, "%d ", ntohs(rule->packet.dport));
28282828
seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.dport));
28292829
break;
2830+
case NPC_IPSEC_SPI:
2831+
seq_printf(s, "0x%x ", ntohl(rule->packet.spi));
2832+
seq_printf(s, "mask 0x%x\n", ntohl(rule->mask.spi));
2833+
break;
28302834
default:
28312835
seq_puts(s, "\n");
28322836
break;

drivers/net/ethernet/marvell/octeontx2/af/rvu_npc_fs.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ static const char * const npc_flow_names[] = {
4141
[NPC_SPORT_SCTP] = "sctp source port",
4242
[NPC_DPORT_SCTP] = "sctp destination port",
4343
[NPC_LXMB] = "Mcast/Bcast header ",
44+
[NPC_IPSEC_SPI] = "SPI ",
4445
[NPC_UNKNOWN] = "unknown",
4546
};
4647

@@ -513,6 +514,10 @@ do { \
513514
NPC_SCAN_HDR(NPC_VLAN_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 2, 2);
514515
NPC_SCAN_HDR(NPC_VLAN_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 2, 2);
515516
NPC_SCAN_HDR(NPC_DMAC, NPC_LID_LA, la_ltype, la_start, 6);
517+
518+
NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LD, NPC_LT_LD_AH, 4, 4);
519+
NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LE, NPC_LT_LE_ESP, 0, 4);
520+
516521
/* SMAC follows the DMAC(which is 6 bytes) */
517522
NPC_SCAN_HDR(NPC_SMAC, NPC_LID_LA, la_ltype, la_start + 6, 6);
518523
/* PF_FUNC is 2 bytes at 0th byte of NPC_LT_LA_IH_NIX_ETHER */
@@ -564,6 +569,9 @@ static void npc_set_features(struct rvu *rvu, int blkaddr, u8 intf)
564569
if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
565570
*features &= ~BIT_ULL(NPC_OUTER_VID);
566571

572+
if (*features & (BIT_ULL(NPC_IPPROTO_AH) | BIT_ULL(NPC_IPPROTO_ESP)))
573+
*features |= BIT_ULL(NPC_IPSEC_SPI);
574+
567575
/* for vlan ethertypes corresponding layer type should be in the key */
568576
if (npc_check_field(rvu, blkaddr, NPC_LB, intf))
569577
*features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG) |
@@ -930,6 +938,9 @@ do { \
930938
NPC_WRITE_FLOW(NPC_DPORT_SCTP, dport, ntohs(pkt->dport), 0,
931939
ntohs(mask->dport), 0);
932940

941+
NPC_WRITE_FLOW(NPC_IPSEC_SPI, spi, ntohl(pkt->spi), 0,
942+
ntohl(mask->spi), 0);
943+
933944
NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
934945
ntohs(mask->vlan_tci), 0);
935946

drivers/net/ethernet/marvell/octeontx2/nic/otx2_tc.c

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
461461
BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
462462
BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
463463
BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
464+
BIT(FLOW_DISSECTOR_KEY_IPSEC) |
464465
BIT_ULL(FLOW_DISSECTOR_KEY_IP)))) {
465466
netdev_info(nic->netdev, "unsupported flow used key 0x%llx",
466467
dissector->used_keys);
@@ -482,6 +483,8 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
482483
match.key->ip_proto != IPPROTO_UDP &&
483484
match.key->ip_proto != IPPROTO_SCTP &&
484485
match.key->ip_proto != IPPROTO_ICMP &&
486+
match.key->ip_proto != IPPROTO_ESP &&
487+
match.key->ip_proto != IPPROTO_AH &&
485488
match.key->ip_proto != IPPROTO_ICMPV6)) {
486489
netdev_info(nic->netdev,
487490
"ip_proto=0x%x not supported\n",
@@ -501,6 +504,10 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
501504
req->features |= BIT_ULL(NPC_IPPROTO_ICMP);
502505
else if (ip_proto == IPPROTO_ICMPV6)
503506
req->features |= BIT_ULL(NPC_IPPROTO_ICMP6);
507+
else if (ip_proto == IPPROTO_ESP)
508+
req->features |= BIT_ULL(NPC_IPPROTO_ESP);
509+
else if (ip_proto == IPPROTO_AH)
510+
req->features |= BIT_ULL(NPC_IPPROTO_AH);
504511
}
505512

506513
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
@@ -545,6 +552,26 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
545552
}
546553
}
547554

555+
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPSEC)) {
556+
struct flow_match_ipsec match;
557+
558+
flow_rule_match_ipsec(rule, &match);
559+
if (!match.mask->spi) {
560+
NL_SET_ERR_MSG_MOD(extack, "spi index not specified");
561+
return -EOPNOTSUPP;
562+
}
563+
if (ip_proto != IPPROTO_ESP &&
564+
ip_proto != IPPROTO_AH) {
565+
NL_SET_ERR_MSG_MOD(extack,
566+
"SPI index is valid only for ESP/AH proto");
567+
return -EOPNOTSUPP;
568+
}
569+
570+
flow_spec->spi = match.key->spi;
571+
flow_mask->spi = match.mask->spi;
572+
req->features |= BIT_ULL(NPC_IPSEC_SPI);
573+
}
574+
548575
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
549576
struct flow_match_ip match;
550577

include/net/flow_dissector.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,14 @@ struct flow_dissector_key_l2tpv3 {
301301
__be32 session_id;
302302
};
303303

304+
/**
305+
* struct flow_dissector_key_ipsec:
306+
* @spi: identifier for a ipsec connection
307+
*/
308+
struct flow_dissector_key_ipsec {
309+
__be32 spi;
310+
};
311+
304312
/**
305313
* struct flow_dissector_key_cfm
306314
* @mdl_ver: maintenance domain level (mdl) and cfm protocol version
@@ -354,6 +362,7 @@ enum flow_dissector_key_id {
354362
FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
355363
FLOW_DISSECTOR_KEY_L2TPV3, /* struct flow_dissector_key_l2tpv3 */
356364
FLOW_DISSECTOR_KEY_CFM, /* struct flow_dissector_key_cfm */
365+
FLOW_DISSECTOR_KEY_IPSEC, /* struct flow_dissector_key_ipsec */
357366

358367
FLOW_DISSECTOR_KEY_MAX,
359368
};

include/net/flow_offload.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ struct flow_match_tcp {
6464
struct flow_dissector_key_tcp *key, *mask;
6565
};
6666

67+
struct flow_match_ipsec {
68+
struct flow_dissector_key_ipsec *key, *mask;
69+
};
70+
6771
struct flow_match_mpls {
6872
struct flow_dissector_key_mpls *key, *mask;
6973
};
@@ -116,6 +120,8 @@ void flow_rule_match_ports_range(const struct flow_rule *rule,
116120
struct flow_match_ports_range *out);
117121
void flow_rule_match_tcp(const struct flow_rule *rule,
118122
struct flow_match_tcp *out);
123+
void flow_rule_match_ipsec(const struct flow_rule *rule,
124+
struct flow_match_ipsec *out);
119125
void flow_rule_match_icmp(const struct flow_rule *rule,
120126
struct flow_match_icmp *out);
121127
void flow_rule_match_mpls(const struct flow_rule *rule,

include/uapi/linux/pkt_cls.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@ enum {
598598

599599
TCA_FLOWER_KEY_CFM, /* nested */
600600

601+
TCA_FLOWER_KEY_SPI, /* be32 */
602+
TCA_FLOWER_KEY_SPI_MASK, /* be32 */
603+
601604
__TCA_FLOWER_MAX,
602605
};
603606

net/core/flow_dissector.c

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,50 @@ static void __skb_flow_dissect_icmp(const struct sk_buff *skb,
205205
skb_flow_get_icmp_tci(skb, key_icmp, data, thoff, hlen);
206206
}
207207

208+
static void __skb_flow_dissect_ah(const struct sk_buff *skb,
209+
struct flow_dissector *flow_dissector,
210+
void *target_container, const void *data,
211+
int nhoff, int hlen)
212+
{
213+
struct flow_dissector_key_ipsec *key_ah;
214+
struct ip_auth_hdr _hdr, *hdr;
215+
216+
if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IPSEC))
217+
return;
218+
219+
hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
220+
if (!hdr)
221+
return;
222+
223+
key_ah = skb_flow_dissector_target(flow_dissector,
224+
FLOW_DISSECTOR_KEY_IPSEC,
225+
target_container);
226+
227+
key_ah->spi = hdr->spi;
228+
}
229+
230+
static void __skb_flow_dissect_esp(const struct sk_buff *skb,
231+
struct flow_dissector *flow_dissector,
232+
void *target_container, const void *data,
233+
int nhoff, int hlen)
234+
{
235+
struct flow_dissector_key_ipsec *key_esp;
236+
struct ip_esp_hdr _hdr, *hdr;
237+
238+
if (!dissector_uses_key(flow_dissector, FLOW_DISSECTOR_KEY_IPSEC))
239+
return;
240+
241+
hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
242+
if (!hdr)
243+
return;
244+
245+
key_esp = skb_flow_dissector_target(flow_dissector,
246+
FLOW_DISSECTOR_KEY_IPSEC,
247+
target_container);
248+
249+
key_esp->spi = hdr->spi;
250+
}
251+
208252
static void __skb_flow_dissect_l2tpv3(const struct sk_buff *skb,
209253
struct flow_dissector *flow_dissector,
210254
void *target_container, const void *data,
@@ -1571,7 +1615,14 @@ bool __skb_flow_dissect(const struct net *net,
15711615
__skb_flow_dissect_l2tpv3(skb, flow_dissector, target_container,
15721616
data, nhoff, hlen);
15731617
break;
1574-
1618+
case IPPROTO_ESP:
1619+
__skb_flow_dissect_esp(skb, flow_dissector, target_container,
1620+
data, nhoff, hlen);
1621+
break;
1622+
case IPPROTO_AH:
1623+
__skb_flow_dissect_ah(skb, flow_dissector, target_container,
1624+
data, nhoff, hlen);
1625+
break;
15751626
default:
15761627
break;
15771628
}

net/core/flow_offload.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,13 @@ void flow_rule_match_tcp(const struct flow_rule *rule,
146146
}
147147
EXPORT_SYMBOL(flow_rule_match_tcp);
148148

149+
void flow_rule_match_ipsec(const struct flow_rule *rule,
150+
struct flow_match_ipsec *out)
151+
{
152+
FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_IPSEC, out);
153+
}
154+
EXPORT_SYMBOL(flow_rule_match_ipsec);
155+
149156
void flow_rule_match_icmp(const struct flow_rule *rule,
150157
struct flow_match_icmp *out)
151158
{

0 commit comments

Comments
 (0)