Commit 996dcfff authored by David S. Miller's avatar David S. Miller
Browse files

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: default avatarDavid S. Miller <davem@davemloft.net>
parents d7301c4a 73b4c04e
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -1451,6 +1451,10 @@ struct flow_msg {
		__be32 ip4dst;
		__be32 ip6dst[4];
	};
	union {
		__be32 spi;
	};

	u8 tos;
	u8 ip_ver;
	u8 ip_proto;
+1 −0
Original line number Diff line number Diff line
@@ -204,6 +204,7 @@ enum key_fields {
	NPC_DPORT_UDP,
	NPC_SPORT_SCTP,
	NPC_DPORT_SCTP,
	NPC_IPSEC_SPI,
	NPC_HEADER_FIELDS_MAX,
	NPC_CHAN = NPC_HEADER_FIELDS_MAX, /* Valid when Rx */
	NPC_PF_FUNC, /* Valid when Tx */
+4 −0
Original line number Diff line number Diff line
@@ -2827,6 +2827,10 @@ static void rvu_dbg_npc_mcam_show_flows(struct seq_file *s,
			seq_printf(s, "%d ", ntohs(rule->packet.dport));
			seq_printf(s, "mask 0x%x\n", ntohs(rule->mask.dport));
			break;
		case NPC_IPSEC_SPI:
			seq_printf(s, "0x%x ", ntohl(rule->packet.spi));
			seq_printf(s, "mask 0x%x\n", ntohl(rule->mask.spi));
			break;
		default:
			seq_puts(s, "\n");
			break;
+11 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ static const char * const npc_flow_names[] = {
	[NPC_SPORT_SCTP] = "sctp source port",
	[NPC_DPORT_SCTP] = "sctp destination port",
	[NPC_LXMB]	= "Mcast/Bcast header ",
	[NPC_IPSEC_SPI] = "SPI ",
	[NPC_UNKNOWN]	= "unknown",
};

@@ -513,6 +514,10 @@ do { \
	NPC_SCAN_HDR(NPC_VLAN_TAG1, NPC_LID_LB, NPC_LT_LB_CTAG, 2, 2);
	NPC_SCAN_HDR(NPC_VLAN_TAG2, NPC_LID_LB, NPC_LT_LB_STAG_QINQ, 2, 2);
	NPC_SCAN_HDR(NPC_DMAC, NPC_LID_LA, la_ltype, la_start, 6);

	NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LD, NPC_LT_LD_AH, 4, 4);
	NPC_SCAN_HDR(NPC_IPSEC_SPI, NPC_LID_LE, NPC_LT_LE_ESP, 0, 4);

	/* SMAC follows the DMAC(which is 6 bytes) */
	NPC_SCAN_HDR(NPC_SMAC, NPC_LID_LA, la_ltype, la_start + 6, 6);
	/* 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)
		if (!npc_check_field(rvu, blkaddr, NPC_LB, intf))
			*features &= ~BIT_ULL(NPC_OUTER_VID);

	if (*features & (BIT_ULL(NPC_IPPROTO_AH) | BIT_ULL(NPC_IPPROTO_ESP)))
		*features |= BIT_ULL(NPC_IPSEC_SPI);

	/* for vlan ethertypes corresponding layer type should be in the key */
	if (npc_check_field(rvu, blkaddr, NPC_LB, intf))
		*features |= BIT_ULL(NPC_VLAN_ETYPE_CTAG) |
@@ -930,6 +938,9 @@ do { \
	NPC_WRITE_FLOW(NPC_DPORT_SCTP, dport, ntohs(pkt->dport), 0,
		       ntohs(mask->dport), 0);

	NPC_WRITE_FLOW(NPC_IPSEC_SPI, spi, ntohl(pkt->spi), 0,
		       ntohl(mask->spi), 0);

	NPC_WRITE_FLOW(NPC_OUTER_VID, vlan_tci, ntohs(pkt->vlan_tci), 0,
		       ntohs(mask->vlan_tci), 0);

+27 −0
Original line number Diff line number Diff line
@@ -461,6 +461,7 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
	      BIT_ULL(FLOW_DISSECTOR_KEY_IPV4_ADDRS) |
	      BIT_ULL(FLOW_DISSECTOR_KEY_IPV6_ADDRS) |
	      BIT_ULL(FLOW_DISSECTOR_KEY_PORTS) |
	      BIT(FLOW_DISSECTOR_KEY_IPSEC) |
	      BIT_ULL(FLOW_DISSECTOR_KEY_IP))))  {
		netdev_info(nic->netdev, "unsupported flow used key 0x%llx",
			    dissector->used_keys);
@@ -482,6 +483,8 @@ static int otx2_tc_prepare_flow(struct otx2_nic *nic, struct otx2_tc_flow *node,
		     match.key->ip_proto != IPPROTO_UDP &&
		     match.key->ip_proto != IPPROTO_SCTP &&
		     match.key->ip_proto != IPPROTO_ICMP &&
		     match.key->ip_proto != IPPROTO_ESP &&
		     match.key->ip_proto != IPPROTO_AH &&
		     match.key->ip_proto != IPPROTO_ICMPV6)) {
			netdev_info(nic->netdev,
				    "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,
			req->features |= BIT_ULL(NPC_IPPROTO_ICMP);
		else if (ip_proto == IPPROTO_ICMPV6)
			req->features |= BIT_ULL(NPC_IPPROTO_ICMP6);
		else if (ip_proto == IPPROTO_ESP)
			req->features |= BIT_ULL(NPC_IPPROTO_ESP);
		else if (ip_proto == IPPROTO_AH)
			req->features |= BIT_ULL(NPC_IPPROTO_AH);
	}

	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,
		}
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IPSEC)) {
		struct flow_match_ipsec match;

		flow_rule_match_ipsec(rule, &match);
		if (!match.mask->spi) {
			NL_SET_ERR_MSG_MOD(extack, "spi index not specified");
			return -EOPNOTSUPP;
		}
		if (ip_proto != IPPROTO_ESP &&
		    ip_proto != IPPROTO_AH) {
			NL_SET_ERR_MSG_MOD(extack,
					   "SPI index is valid only for ESP/AH proto");
			return -EOPNOTSUPP;
		}

		flow_spec->spi = match.key->spi;
		flow_mask->spi = match.mask->spi;
		req->features |= BIT_ULL(NPC_IPSEC_SPI);
	}

	if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) {
		struct flow_match_ip match;

Loading