Skip to content

Commit

Permalink
ice: Add support for PPPoE hardware offload
Browse files Browse the repository at this point in the history
Add support for creating PPPoE filters in switchdev mode. Add support
for parsing PPPoE and PPP-specific tc options: pppoe_sid and ppp_proto.

Example filter:
tc filter add dev $PF1 ingress protocol ppp_ses prio 1 flower pppoe_sid \
    1234 ppp_proto ip skip_sw action mirred egress redirect dev $VF1_PR

Changes in iproute2 are required to use the new fields.

ICE COMMS DDP package is required to create a filter as it contains PPPoE
profiles. Added a warning message when loaded DDP package does not contain
required profiles.

Signed-off-by: Marcin Szycik <marcin.szycik@linux.intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
  • Loading branch information
Marcin Szycik authored and anguy11 committed Jul 26, 2022
1 parent 6a21b08 commit cd8efee
Show file tree
Hide file tree
Showing 6 changed files with 259 additions and 2 deletions.
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/ice/ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
#include <net/udp_tunnel.h>
#include <net/vxlan.h>
#include <net/gtp.h>
#include <linux/ppp_defs.h>
#include "ice_devids.h"
#include "ice_type.h"
#include "ice_txrx.h"
Expand Down
5 changes: 4 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_flex_pipe.c
Original file line number Diff line number Diff line change
Expand Up @@ -1964,8 +1964,11 @@ ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
}
}
} while (fv);
if (list_empty(fv_list))
if (list_empty(fv_list)) {
dev_warn(ice_hw_to_dev(hw), "Required profiles not found in currently loaded DDP package");
return -EIO;
}

return 0;

err:
Expand Down
11 changes: 11 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_protocol_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ enum ice_protocol_type {
ICE_NVGRE,
ICE_GTP,
ICE_GTP_NO_PAY,
ICE_PPPOE,
ICE_VLAN_EX,
ICE_VLAN_IN,
ICE_VXLAN_GPE,
Expand Down Expand Up @@ -109,6 +110,7 @@ enum ice_prot_id {
#define ICE_TCP_IL_HW 49
#define ICE_UDP_ILOS_HW 53
#define ICE_GRE_OF_HW 64
#define ICE_PPPOE_HW 103

#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 @@ -207,6 +209,14 @@ struct ice_udp_gtp_hdr {
u8 rsvrd;
};

struct ice_pppoe_hdr {
u8 rsrvd_ver_type;
u8 rsrvd_code;
__be16 session_id;
__be16 length;
__be16 ppp_prot_id; /* control and data only */
};

struct ice_nvgre_hdr {
__be16 flags;
__be16 protocol;
Expand All @@ -224,6 +234,7 @@ union ice_prot_hdr {
struct ice_udp_tnl_hdr tnl_hdr;
struct ice_nvgre_hdr nvgre_hdr;
struct ice_udp_gtp_hdr gtp_hdr;
struct ice_pppoe_hdr pppoe_hdr;
};

/* This is mapping table entry that maps every word within a given protocol
Expand Down
165 changes: 165 additions & 0 deletions drivers/net/ethernet/intel/ice/ice_switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum {
ICE_PKT_INNER_UDP = BIT(7),
ICE_PKT_GTP_NOPAY = BIT(8),
ICE_PKT_KMALLOC = BIT(9),
ICE_PKT_PPPOE = BIT(10),
};

struct ice_dummy_pkt_offsets {
Expand Down Expand Up @@ -1109,6 +1110,154 @@ ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
0x00, 0x00,
};

ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_tcp) = {
{ ICE_MAC_OFOS, 0 },
{ ICE_ETYPE_OL, 12 },
{ ICE_PPPOE, 14 },
{ ICE_IPV4_OFOS, 22 },
{ ICE_TCP_IL, 42 },
{ ICE_PROTOCOL_LAST, 0 },
};

ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_tcp) = {
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x88, 0x64, /* ICE_ETYPE_OL 12 */

0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
0x00, 0x16,

0x00, 0x21, /* PPP Link Layer 20 */

0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_OFOS 22 */
0x00, 0x01, 0x00, 0x00,
0x00, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 42 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x00, 0x00, /* 2 bytes for 4 bytes alignment */
};

ICE_DECLARE_PKT_OFFSETS(pppoe_ipv4_udp) = {
{ ICE_MAC_OFOS, 0 },
{ ICE_ETYPE_OL, 12 },
{ ICE_PPPOE, 14 },
{ ICE_IPV4_OFOS, 22 },
{ ICE_UDP_ILOS, 42 },
{ ICE_PROTOCOL_LAST, 0 },
};

ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv4_udp) = {
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x88, 0x64, /* ICE_ETYPE_OL 12 */

0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
0x00, 0x16,

0x00, 0x21, /* PPP Link Layer 20 */

0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_OFOS 22 */
0x00, 0x01, 0x00, 0x00,
0x00, 0x11, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 42 */
0x00, 0x08, 0x00, 0x00,

0x00, 0x00, /* 2 bytes for 4 bytes alignment */
};

ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_tcp) = {
{ ICE_MAC_OFOS, 0 },
{ ICE_ETYPE_OL, 12 },
{ ICE_PPPOE, 14 },
{ ICE_IPV6_OFOS, 22 },
{ ICE_TCP_IL, 62 },
{ ICE_PROTOCOL_LAST, 0 },
};

ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_tcp) = {
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x88, 0x64, /* ICE_ETYPE_OL 12 */

0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
0x00, 0x2a,

0x00, 0x57, /* PPP Link Layer 20 */

0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
0x00, 0x14, 0x06, 0x00, /* Next header is TCP */
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_TCP_IL 62 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x50, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x00, 0x00, /* 2 bytes for 4 bytes alignment */
};

ICE_DECLARE_PKT_OFFSETS(pppoe_ipv6_udp) = {
{ ICE_MAC_OFOS, 0 },
{ ICE_ETYPE_OL, 12 },
{ ICE_PPPOE, 14 },
{ ICE_IPV6_OFOS, 22 },
{ ICE_UDP_ILOS, 62 },
{ ICE_PROTOCOL_LAST, 0 },
};

ICE_DECLARE_PKT_TEMPLATE(pppoe_ipv6_udp) = {
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_OFOS 0 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,

0x88, 0x64, /* ICE_ETYPE_OL 12 */

0x11, 0x00, 0x00, 0x00, /* ICE_PPPOE 14 */
0x00, 0x2a,

0x00, 0x57, /* PPP Link Layer 20 */

0x60, 0x00, 0x00, 0x00, /* ICE_IPV6_OFOS 22 */
0x00, 0x08, 0x11, 0x00, /* Next header UDP*/
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_UDP_ILOS 62 */
0x00, 0x08, 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 All @@ -1135,6 +1284,11 @@ static const struct ice_dummy_pkt_profile ice_dummy_pkt_profiles[] = {
ICE_PKT_PROFILE(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
ICE_PKT_PROFILE(ipv4_gtpu_ipv4, ICE_PKT_TUN_GTPC),
ICE_PKT_PROFILE(pppoe_ipv6_udp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6 |
ICE_PKT_INNER_UDP),
ICE_PKT_PROFILE(pppoe_ipv6_tcp, ICE_PKT_PPPOE | ICE_PKT_OUTER_IPV6),
ICE_PKT_PROFILE(pppoe_ipv4_udp, ICE_PKT_PPPOE | ICE_PKT_INNER_UDP),
ICE_PKT_PROFILE(pppoe_ipv4_tcp, ICE_PKT_PPPOE),
ICE_PKT_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 |
ICE_PKT_INNER_TCP),
ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
Expand Down Expand Up @@ -4480,6 +4634,7 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
{ ICE_NVGRE, { 0, 2, 4, 6 } },
{ 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_VLAN_EX, { 2, 0 } },
{ ICE_VLAN_IN, { 2, 0 } },
};
Expand All @@ -4502,6 +4657,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
{ ICE_NVGRE, ICE_GRE_OF_HW },
{ ICE_GTP, ICE_UDP_OF_HW },
{ ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
{ ICE_PPPOE, ICE_PPPOE_HW },
{ ICE_VLAN_EX, ICE_VLAN_OF_HW },
{ ICE_VLAN_IN, ICE_VLAN_OL_HW },
};
Expand Down Expand Up @@ -5580,6 +5736,12 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
match |= ICE_PKT_INNER_IPV6;
else if (lkups[i].type == ICE_GTP_NO_PAY)
match |= ICE_PKT_GTP_NOPAY;
else if (lkups[i].type == ICE_PPPOE) {
match |= ICE_PKT_PPPOE;
if (lkups[i].h_u.pppoe_hdr.ppp_prot_id ==
htons(PPP_IPV6))
match |= ICE_PKT_OUTER_IPV6;
}
}

while (ret->match && (match & ret->match) != ret->match)
Expand Down Expand Up @@ -5677,6 +5839,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
case ICE_GTP:
len = sizeof(struct ice_udp_gtp_hdr);
break;
case ICE_PPPOE:
len = sizeof(struct ice_pppoe_hdr);
break;
default:
return -EINVAL;
}
Expand Down
71 changes: 70 additions & 1 deletion drivers/net/ethernet/intel/ice/ice_tc_lib.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ ice_tc_count_lkups(u32 flags, struct ice_tc_flower_lyr_2_4_hdrs *headers,
if (flags & ICE_TC_FLWR_FIELD_CVLAN)
lkups_cnt++;

/* are PPPoE options specified? */
if (flags & (ICE_TC_FLWR_FIELD_PPPOE_SESSID |
ICE_TC_FLWR_FIELD_PPP_PROTO))
lkups_cnt++;

/* are IPv[4|6] fields specified? */
if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 | ICE_TC_FLWR_FIELD_SRC_IPV4 |
ICE_TC_FLWR_FIELD_DEST_IPV6 | ICE_TC_FLWR_FIELD_SRC_IPV6))
Expand Down Expand Up @@ -350,6 +355,28 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
i++;
}

if (flags & (ICE_TC_FLWR_FIELD_PPPOE_SESSID |
ICE_TC_FLWR_FIELD_PPP_PROTO)) {
struct ice_pppoe_hdr *vals, *masks;

vals = &list[i].h_u.pppoe_hdr;
masks = &list[i].m_u.pppoe_hdr;

list[i].type = ICE_PPPOE;

if (flags & ICE_TC_FLWR_FIELD_PPPOE_SESSID) {
vals->session_id = headers->pppoe_hdr.session_id;
masks->session_id = cpu_to_be16(0xFFFF);
}

if (flags & ICE_TC_FLWR_FIELD_PPP_PROTO) {
vals->ppp_prot_id = headers->pppoe_hdr.ppp_proto;
masks->ppp_prot_id = cpu_to_be16(0xFFFF);
}

i++;
}

/* copy L3 (IPv[4|6]: src, dest) address */
if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 |
ICE_TC_FLWR_FIELD_SRC_IPV4)) {
Expand Down Expand Up @@ -693,6 +720,31 @@ ice_add_tc_flower_adv_fltr(struct ice_vsi *vsi,
return ret;
}

/**
* ice_tc_set_pppoe - Parse PPPoE fields from TC flower filter
* @match: Pointer to flow match structure
* @fltr: Pointer to filter structure
* @headers: Pointer to outer header fields
* @returns PPP protocol used in filter (ppp_ses or ppp_disc)
*/
static u16
ice_tc_set_pppoe(struct flow_match_pppoe *match,
struct ice_tc_flower_fltr *fltr,
struct ice_tc_flower_lyr_2_4_hdrs *headers)
{
if (match->mask->session_id) {
fltr->flags |= ICE_TC_FLWR_FIELD_PPPOE_SESSID;
headers->pppoe_hdr.session_id = match->key->session_id;
}

if (match->mask->ppp_proto) {
fltr->flags |= ICE_TC_FLWR_FIELD_PPP_PROTO;
headers->pppoe_hdr.ppp_proto = match->key->ppp_proto;
}

return be16_to_cpu(match->key->type);
}

/**
* ice_tc_set_ipv4 - Parse IPv4 addresses from TC flower filter
* @match: Pointer to flow match structure
Expand Down Expand Up @@ -988,7 +1040,8 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
BIT(FLOW_DISSECTOR_KEY_ENC_PORTS) |
BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) |
BIT(FLOW_DISSECTOR_KEY_ENC_IP) |
BIT(FLOW_DISSECTOR_KEY_PORTS))) {
BIT(FLOW_DISSECTOR_KEY_PORTS) |
BIT(FLOW_DISSECTOR_KEY_PPPOE))) {
NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported key used");
return -EOPNOTSUPP;
}
Expand Down Expand Up @@ -1124,6 +1177,22 @@ ice_parse_cls_flower(struct net_device *filter_dev, struct ice_vsi *vsi,
headers->cvlan_hdr.vlan_prio = match.key->vlan_priority;
}

if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_PPPOE)) {
struct flow_match_pppoe match;

flow_rule_match_pppoe(rule, &match);
n_proto_key = ice_tc_set_pppoe(&match, fltr, headers);

/* If ethertype equals ETH_P_PPP_SES, n_proto might be
* overwritten by encapsulated protocol (ppp_proto field) or set
* to 0. To correct this, flow_match_pppoe provides the type
* field, which contains the actual ethertype (ETH_P_PPP_SES).
*/
headers->l2_key.n_proto = cpu_to_be16(n_proto_key);
headers->l2_mask.n_proto = cpu_to_be16(0xFFFF);
fltr->flags |= ICE_TC_FLWR_FIELD_ETH_TYPE_ID;
}

if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
struct flow_match_control match;

Expand Down

0 comments on commit cd8efee

Please sign in to comment.