Skip to content

Commit

Permalink
ice: Add L2TPv3 hardware offload support
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Marcin Szycik authored and Paolo Abeni committed Sep 20, 2022
1 parent 2c1befa commit cd63454
Show file tree
Hide file tree
Showing 4 changed files with 109 additions and 2 deletions.
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_protocol_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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;
Expand All @@ -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
Expand Down
70 changes: 69 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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),
Expand Down Expand Up @@ -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 } },
};
Expand All @@ -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 },
};
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand Down
27 changes: 26 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_tc_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;

Expand Down
6 changes: 6 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_tc_lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down

0 comments on commit cd63454

Please sign in to comment.