forked from Minki/linux
ice: Add L2TPv3 hardware offload support
Add support for offloading packets based on L2TPv3 session id in switchdev mode. Example filter: tc filter add dev $PF1 ingress prio 1 protocol ip flower ip_proto l2tp \ l2tpv3_sid 1234 skip_sw action mirred egress redirect dev $VF1_PR Changes in iproute2 are required to be able to specify l2tpv3_sid. ICE COMMS DDP package is required to create a filter as it contains L2TPv3 profiles. Reviewed-by: Michal Swiatkowski <michal.swiatkowski@linux.intel.com> Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com> Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
parent
2c1befaced
commit
cd63454902
@ -44,6 +44,7 @@ enum ice_protocol_type {
|
||||
ICE_GTP,
|
||||
ICE_GTP_NO_PAY,
|
||||
ICE_PPPOE,
|
||||
ICE_L2TPV3,
|
||||
ICE_VLAN_EX,
|
||||
ICE_VLAN_IN,
|
||||
ICE_VXLAN_GPE,
|
||||
@ -111,6 +112,7 @@ enum ice_prot_id {
|
||||
#define ICE_UDP_ILOS_HW 53
|
||||
#define ICE_GRE_OF_HW 64
|
||||
#define ICE_PPPOE_HW 103
|
||||
#define ICE_L2TPV3_HW 104
|
||||
|
||||
#define ICE_UDP_OF_HW 52 /* UDP Tunnels */
|
||||
#define ICE_META_DATA_ID_HW 255 /* this is used for tunnel and VLAN type */
|
||||
@ -217,6 +219,11 @@ struct ice_pppoe_hdr {
|
||||
__be16 ppp_prot_id; /* control and data only */
|
||||
};
|
||||
|
||||
struct ice_l2tpv3_sess_hdr {
|
||||
__be32 session_id;
|
||||
__be64 cookie;
|
||||
};
|
||||
|
||||
struct ice_nvgre_hdr {
|
||||
__be16 flags;
|
||||
__be16 protocol;
|
||||
@ -235,6 +242,7 @@ union ice_prot_hdr {
|
||||
struct ice_nvgre_hdr nvgre_hdr;
|
||||
struct ice_udp_gtp_hdr gtp_hdr;
|
||||
struct ice_pppoe_hdr pppoe_hdr;
|
||||
struct ice_l2tpv3_sess_hdr l2tpv3_sess_hdr;
|
||||
};
|
||||
|
||||
/* This is mapping table entry that maps every word within a given protocol
|
||||
|
@ -42,6 +42,7 @@ enum {
|
||||
ICE_PKT_GTP_NOPAY = BIT(8),
|
||||
ICE_PKT_KMALLOC = BIT(9),
|
||||
ICE_PKT_PPPOE = BIT(10),
|
||||
ICE_PKT_L2TPV3 = BIT(11),
|
||||
};
|
||||
|
||||
struct ice_dummy_pkt_offsets {
|
||||
@ -1258,6 +1259,65 @@ ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = {
|
||||
0x00, 0x00, /* 2 bytes for 4 bytes alignment */
|
||||
};
|
||||
|
||||
ICE_DECLARE_PKT_OFFSETS(ipv4_l2tpv3) = {
|
||||
{ ICE_MAC_OFOS, 0 },
|
||||
{ ICE_ETYPE_OL, 12 },
|
||||
{ ICE_IPV4_OFOS, 14 },
|
||||
{ ICE_L2TPV3, 34 },
|
||||
{ ICE_PROTOCOL_LAST, 0 },
|
||||
};
|
||||
|
||||
ICE_DECLARE_PKT_TEMPLATE(ipv4_l2tpv3) = {
|
||||
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x08, 0x00, /* ICE_ETYPE_OL 12 */
|
||||
|
||||
0x45, 0x00, 0x00, 0x20, /* ICE_IPV4_IL 14 */
|
||||
0x00, 0x00, 0x40, 0x00,
|
||||
0x40, 0x73, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 34 */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, /* 2 bytes for 4 bytes alignment */
|
||||
};
|
||||
|
||||
ICE_DECLARE_PKT_OFFSETS(ipv6_l2tpv3) = {
|
||||
{ ICE_MAC_OFOS, 0 },
|
||||
{ ICE_ETYPE_OL, 12 },
|
||||
{ ICE_IPV6_OFOS, 14 },
|
||||
{ ICE_L2TPV3, 54 },
|
||||
{ ICE_PROTOCOL_LAST, 0 },
|
||||
};
|
||||
|
||||
ICE_DECLARE_PKT_TEMPLATE(ipv6_l2tpv3) = {
|
||||
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x86, 0xDD, /* ICE_ETYPE_OL 12 */
|
||||
|
||||
0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_IL 14 */
|
||||
0x00, 0x0c, 0x73, 0x40,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
|
||||
0x00, 0x00, 0x00, 0x00, /* ICE_L2TPV3 54 */
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, /* 2 bytes for 4 bytes alignment */
|
||||
};
|
||||
|
||||
static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
|
||||
ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 |
|
||||
ICE_PKT_GTP_NOPAY),
|
||||
@ -1297,6 +1357,8 @@ static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
|
||||
ICE_PKT_PROFILE(udp_tun_ipv6_tcp, ICE_PKT_TUN_UDP |
|
||||
ICE_PKT_INNER_IPV6 |
|
||||
ICE_PKT_INNER_TCP),
|
||||
ICE_PKT_PROFILE(ipv6_l2tpv3, ICE_PKT_L2TPV3 | ICE_PKT_OUTER_IPV6),
|
||||
ICE_PKT_PROFILE(ipv4_l2tpv3, ICE_PKT_L2TPV3),
|
||||
ICE_PKT_PROFILE(udp_tun_tcp, ICE_PKT_TUN_UDP | ICE_PKT_INNER_TCP),
|
||||
ICE_PKT_PROFILE(udp_tun_ipv6_udp, ICE_PKT_TUN_UDP |
|
||||
ICE_PKT_INNER_IPV6),
|
||||
@ -4490,6 +4552,7 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
|
||||
{ ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
|
||||
{ ICE_GTP_NO_PAY, { 8, 10, 12, 14 } },
|
||||
{ ICE_PPPOE, { 0, 2, 4, 6 } },
|
||||
{ ICE_L2TPV3, { 0, 2, 4, 6, 8, 10 } },
|
||||
{ ICE_VLAN_EX, { 2, 0 } },
|
||||
{ ICE_VLAN_IN, { 2, 0 } },
|
||||
};
|
||||
@ -4513,6 +4576,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
|
||||
{ ICE_GTP, ICE_UDP_OF_HW },
|
||||
{ ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
|
||||
{ ICE_PPPOE, ICE_PPPOE_HW },
|
||||
{ ICE_L2TPV3, ICE_L2TPV3_HW },
|
||||
{ ICE_VLAN_EX, ICE_VLAN_OF_HW },
|
||||
{ ICE_VLAN_IN, ICE_VLAN_OL_HW },
|
||||
};
|
||||
@ -5596,7 +5660,8 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
|
||||
if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
|
||||
htons(PPP_IPV6))
|
||||
match |= ICE_PKT_OUTER_IPV6;
|
||||
}
|
||||
} else if (lkups[i].type == ICE_L2TPV3)
|
||||
match |= ICE_PKT_L2TPV3;
|
||||
}
|
||||
|
||||
while (ret->match && (match & ret->match) != ret->match)
|
||||
@ -5697,6 +5762,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
|
||||
case ICE_PPPOE:
|
||||
len = sizeof(struct ice_pppoe_hdr);
|
||||
break;
|
||||
case ICE_L2TPV3:
|
||||
len = sizeof(struct ice_l2tpv3_sess_hdr);
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
@ -71,6 +71,10 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
|
||||
if (flags & (ICE_TC_FLWR_FIELD_IP_TOS | ICE_TC_FLWR_FIELD_IP_TTL))
|
||||
lkups_cnt++;
|
||||
|
||||
/* are L2TPv3 options specified? */
|
||||
if (flags & ICE_TC_FLWR_FIELD_L2TPV3_SESSID)
|
||||
lkups_cnt++;
|
||||
|
||||
/* is L4 (TCP/UDP/any other L4 protocol fields) specified? */
|
||||
if (flags & (ICE_TC_FLWR_FIELD_DEST_L4_PORT |
|
||||
ICE_TC_FLWR_FIELD_SRC_L4_PORT))
|
||||
@ -515,6 +519,17 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
|
||||
i++;
|
||||
}
|
||||
|
||||
if (flags & ICE_TC_FLWR_FIELD_L2TPV3_SESSID) {
|
||||
list[i].type = ICE_L2TPV3;
|
||||
|
||||
list[i].h_u.l2tpv3_sess_hdr.session_id =
|
||||
headers->l2tpv3_hdr.session_id;
|
||||
list[i].m_u.l2tpv3_sess_hdr.session_id =
|
||||
cpu_to_be32(0xFFFFFFFF);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
/* copy L4 (src, dest) port */
|
||||
if (flags & (ICE_TC_FLWR_FIELD_DEST_L4_PORT |
|
||||
ICE_TC_FLWR_FIELD_SRC_L4_PORT)) {
|
||||
@ -1168,7 +1183,8 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
|
||||
BIT(FLOW_DISSECTOR_KEY_IP) |
|
||||
BIT(FLOW_DISSECTOR_KEY_ENC_IP) |
|
||||
BIT(FLOW_DISSECTOR_KEY_PORTS) |
|
||||
BIT(FLOW_DISSECTOR_KEY_PPPOE))) {
|
||||
BIT(FLOW_DISSECTOR_KEY_PPPOE) |
|
||||
BIT(FLOW_DISSECTOR_KEY_L2TPV3))) {
|
||||
NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported key used");
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
@ -1351,6 +1367,15 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
|
||||
ice_tc_set_tos_ttl(&match, fltr, headers, false);
|
||||
}
|
||||
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_L2TPV3)) {
|
||||
struct flow_match_l2tpv3 match;
|
||||
|
||||
flow_rule_match_l2tpv3(rule, &match);
|
||||
|
||||
fltr->flags |= ICE_TC_FLWR_FIELD_L2TPV3_SESSID;
|
||||
headers->l2tpv3_hdr.session_id = match.key->session_id;
|
||||
}
|
||||
|
||||
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PORTS)) {
|
||||
struct flow_match_ports match;
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#define ICE_TC_FLWR_FIELD_IP_TTL BIT(23)
|
||||
#define ICE_TC_FLWR_FIELD_ENC_IP_TOS BIT(24)
|
||||
#define ICE_TC_FLWR_FIELD_ENC_IP_TTL BIT(25)
|
||||
#define ICE_TC_FLWR_FIELD_L2TPV3_SESSID BIT(26)
|
||||
|
||||
#define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF
|
||||
|
||||
@ -86,6 +87,10 @@ struct ice_tc_l3_hdr {
|
||||
u8 ttl;
|
||||
};
|
||||
|
||||
struct ice_tc_l2tpv3_hdr {
|
||||
__be32 session_id;
|
||||
};
|
||||
|
||||
struct ice_tc_l4_hdr {
|
||||
__be16 dst_port;
|
||||
__be16 src_port;
|
||||
@ -98,6 +103,7 @@ struct ice_tc_flower_lyr_2_4_hdrs {
|
||||
struct ice_tc_vlan_hdr vlan_hdr;
|
||||
struct ice_tc_vlan_hdr cvlan_hdr;
|
||||
struct ice_tc_pppoe_hdr pppoe_hdr;
|
||||
struct ice_tc_l2tpv3_hdr l2tpv3_hdr;
|
||||
/* L3 (IPv4[6]) layer fields with their mask */
|
||||
struct ice_tc_l3_hdr l3_key;
|
||||
struct ice_tc_l3_hdr l3_mask;
|
||||
|
Loading…
Reference in New Issue
Block a user