forked from Minki/linux
Merge branch '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue
Tony Nguyen says: ==================== ice: PPPoE offload support Marcin Szycik says: Add support for dissecting PPPoE and PPP-specific fields in flow dissector: PPPoE session id and PPP protocol type. Add support for those fields in tc-flower and support offloading PPPoE. Finally, add support for hardware offload of PPPoE packets in switchdev mode in ice driver. 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 (will be submitted soon). ICE COMMS DDP package is required to create a filter in ice. * '100GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/tnguy/next-queue: ice: Add support for PPPoE hardware offload flow_offload: Introduce flow_match_pppoe net/sched: flower: Add PPPoE filter flow_dissector: Add PPPoE dissectors ==================== Link: https://lore.kernel.org/r/20220726203133.2171332-1-anthony.l.nguyen@intel.com Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
commit
7d85e9cb40
@ -52,6 +52,7 @@
|
|||||||
#include <net/udp_tunnel.h>
|
#include <net/udp_tunnel.h>
|
||||||
#include <net/vxlan.h>
|
#include <net/vxlan.h>
|
||||||
#include <net/gtp.h>
|
#include <net/gtp.h>
|
||||||
|
#include <linux/ppp_defs.h>
|
||||||
#include "ice_devids.h"
|
#include "ice_devids.h"
|
||||||
#include "ice_type.h"
|
#include "ice_type.h"
|
||||||
#include "ice_txrx.h"
|
#include "ice_txrx.h"
|
||||||
|
@ -1964,8 +1964,11 @@ ice_get_sw_fv_list(struct ice_hw *hw, struct ice_prot_lkup_ext *lkups,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (fv);
|
} 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 -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
@ -43,6 +43,7 @@ enum ice_protocol_type {
|
|||||||
ICE_NVGRE,
|
ICE_NVGRE,
|
||||||
ICE_GTP,
|
ICE_GTP,
|
||||||
ICE_GTP_NO_PAY,
|
ICE_GTP_NO_PAY,
|
||||||
|
ICE_PPPOE,
|
||||||
ICE_VLAN_EX,
|
ICE_VLAN_EX,
|
||||||
ICE_VLAN_IN,
|
ICE_VLAN_IN,
|
||||||
ICE_VXLAN_GPE,
|
ICE_VXLAN_GPE,
|
||||||
@ -109,6 +110,7 @@ enum ice_prot_id {
|
|||||||
#define ICE_TCP_IL_HW 49
|
#define ICE_TCP_IL_HW 49
|
||||||
#define ICE_UDP_ILOS_HW 53
|
#define ICE_UDP_ILOS_HW 53
|
||||||
#define ICE_GRE_OF_HW 64
|
#define ICE_GRE_OF_HW 64
|
||||||
|
#define ICE_PPPOE_HW 103
|
||||||
|
|
||||||
#define ICE_UDP_OF_HW 52 /* UDP Tunnels */
|
#define ICE_UDP_OF_HW 52 /* UDP Tunnels */
|
||||||
#define ICE_META_DATA_ID_HW 255 /* this is used for tunnel and VLAN type */
|
#define ICE_META_DATA_ID_HW 255 /* this is used for tunnel and VLAN type */
|
||||||
@ -207,6 +209,14 @@ struct ice_udp_gtp_hdr {
|
|||||||
u8 rsvrd;
|
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 {
|
struct ice_nvgre_hdr {
|
||||||
__be16 flags;
|
__be16 flags;
|
||||||
__be16 protocol;
|
__be16 protocol;
|
||||||
@ -224,6 +234,7 @@ union ice_prot_hdr {
|
|||||||
struct ice_udp_tnl_hdr tnl_hdr;
|
struct ice_udp_tnl_hdr tnl_hdr;
|
||||||
struct ice_nvgre_hdr nvgre_hdr;
|
struct ice_nvgre_hdr nvgre_hdr;
|
||||||
struct ice_udp_gtp_hdr gtp_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
|
/* This is mapping table entry that maps every word within a given protocol
|
||||||
|
@ -41,6 +41,7 @@ enum {
|
|||||||
ICE_PKT_INNER_UDP = BIT(7),
|
ICE_PKT_INNER_UDP = BIT(7),
|
||||||
ICE_PKT_GTP_NOPAY = BIT(8),
|
ICE_PKT_GTP_NOPAY = BIT(8),
|
||||||
ICE_PKT_KMALLOC = BIT(9),
|
ICE_PKT_KMALLOC = BIT(9),
|
||||||
|
ICE_PKT_PPPOE = BIT(10),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ice_dummy_pkt_offsets {
|
struct ice_dummy_pkt_offsets {
|
||||||
@ -1109,6 +1110,154 @@ ICE_DECLARE_PKT_TEMPLATE(ipv6_gtp) = {
|
|||||||
0x00, 0x00,
|
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[] = {
|
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_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPU | ICE_PKT_OUTER_IPV6 |
|
||||||
ICE_PKT_GTP_NOPAY),
|
ICE_PKT_GTP_NOPAY),
|
||||||
@ -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(ipv4_gtpu_ipv4_tcp, ICE_PKT_TUN_GTPU),
|
||||||
ICE_PKT_PROFILE(ipv6_gtp, ICE_PKT_TUN_GTPC | ICE_PKT_OUTER_IPV6),
|
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(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_PROFILE(gre_ipv6_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_IPV6 |
|
||||||
ICE_PKT_INNER_TCP),
|
ICE_PKT_INNER_TCP),
|
||||||
ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
|
ICE_PKT_PROFILE(gre_tcp, ICE_PKT_TUN_NVGRE | ICE_PKT_INNER_TCP),
|
||||||
@ -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_NVGRE, { 0, 2, 4, 6 } },
|
||||||
{ ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
|
{ ICE_GTP, { 8, 10, 12, 14, 16, 18, 20, 22 } },
|
||||||
{ ICE_GTP_NO_PAY, { 8, 10, 12, 14 } },
|
{ ICE_GTP_NO_PAY, { 8, 10, 12, 14 } },
|
||||||
|
{ ICE_PPPOE, { 0, 2, 4, 6 } },
|
||||||
{ ICE_VLAN_EX, { 2, 0 } },
|
{ ICE_VLAN_EX, { 2, 0 } },
|
||||||
{ ICE_VLAN_IN, { 2, 0 } },
|
{ ICE_VLAN_IN, { 2, 0 } },
|
||||||
};
|
};
|
||||||
@ -4502,6 +4657,7 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
|
|||||||
{ ICE_NVGRE, ICE_GRE_OF_HW },
|
{ ICE_NVGRE, ICE_GRE_OF_HW },
|
||||||
{ ICE_GTP, ICE_UDP_OF_HW },
|
{ ICE_GTP, ICE_UDP_OF_HW },
|
||||||
{ ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
|
{ ICE_GTP_NO_PAY, ICE_UDP_ILOS_HW },
|
||||||
|
{ ICE_PPPOE, ICE_PPPOE_HW },
|
||||||
{ ICE_VLAN_EX, ICE_VLAN_OF_HW },
|
{ ICE_VLAN_EX, ICE_VLAN_OF_HW },
|
||||||
{ ICE_VLAN_IN, ICE_VLAN_OL_HW },
|
{ ICE_VLAN_IN, ICE_VLAN_OL_HW },
|
||||||
};
|
};
|
||||||
@ -5580,6 +5736,12 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
|
|||||||
match |= ICE_PKT_INNER_IPV6;
|
match |= ICE_PKT_INNER_IPV6;
|
||||||
else if (lkups[i].type == ICE_GTP_NO_PAY)
|
else if (lkups[i].type == ICE_GTP_NO_PAY)
|
||||||
match |= ICE_PKT_GTP_NOPAY;
|
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)
|
while (ret->match && (match & ret->match) != ret->match)
|
||||||
@ -5677,6 +5839,9 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
|
|||||||
case ICE_GTP:
|
case ICE_GTP:
|
||||||
len = sizeof(struct ice_udp_gtp_hdr);
|
len = sizeof(struct ice_udp_gtp_hdr);
|
||||||
break;
|
break;
|
||||||
|
case ICE_PPPOE:
|
||||||
|
len = sizeof(struct ice_pppoe_hdr);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -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)
|
if (flags & ICE_TC_FLWR_FIELD_CVLAN)
|
||||||
lkups_cnt++;
|
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? */
|
/* are IPv[4|6] fields specified? */
|
||||||
if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 | ICE_TC_FLWR_FIELD_SRC_IPV4 |
|
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))
|
ICE_TC_FLWR_FIELD_DEST_IPV6 | ICE_TC_FLWR_FIELD_SRC_IPV6))
|
||||||
@ -350,6 +355,28 @@ ice_tc_fill_rules(struct ice_hw *hw, u32 flags,
|
|||||||
i++;
|
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 */
|
/* copy L3 (IPv[4|6]: src, dest) address */
|
||||||
if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 |
|
if (flags & (ICE_TC_FLWR_FIELD_DEST_IPV4 |
|
||||||
ICE_TC_FLWR_FIELD_SRC_IPV4)) {
|
ICE_TC_FLWR_FIELD_SRC_IPV4)) {
|
||||||
@ -693,6 +720,31 @@ exit:
|
|||||||
return ret;
|
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
|
* ice_tc_set_ipv4 - Parse IPv4 addresses from TC flower filter
|
||||||
* @match: Pointer to flow match structure
|
* @match: Pointer to flow match structure
|
||||||
@ -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_PORTS) |
|
||||||
BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) |
|
BIT(FLOW_DISSECTOR_KEY_ENC_OPTS) |
|
||||||
BIT(FLOW_DISSECTOR_KEY_ENC_IP) |
|
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");
|
NL_SET_ERR_MSG_MOD(fltr->extack, "Unsupported key used");
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
@ -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;
|
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)) {
|
if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_CONTROL)) {
|
||||||
struct flow_match_control match;
|
struct flow_match_control match;
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#define ICE_TC_FLWR_FIELD_ETH_TYPE_ID BIT(17)
|
#define ICE_TC_FLWR_FIELD_ETH_TYPE_ID BIT(17)
|
||||||
#define ICE_TC_FLWR_FIELD_ENC_OPTS BIT(18)
|
#define ICE_TC_FLWR_FIELD_ENC_OPTS BIT(18)
|
||||||
#define ICE_TC_FLWR_FIELD_CVLAN BIT(19)
|
#define ICE_TC_FLWR_FIELD_CVLAN BIT(19)
|
||||||
|
#define ICE_TC_FLWR_FIELD_PPPOE_SESSID BIT(20)
|
||||||
|
#define ICE_TC_FLWR_FIELD_PPP_PROTO BIT(21)
|
||||||
|
|
||||||
#define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF
|
#define ICE_TC_FLOWER_MASK_32 0xFFFFFFFF
|
||||||
|
|
||||||
@ -44,6 +46,11 @@ struct ice_tc_vlan_hdr {
|
|||||||
__be16 vlan_tpid;
|
__be16 vlan_tpid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct ice_tc_pppoe_hdr {
|
||||||
|
__be16 session_id;
|
||||||
|
__be16 ppp_proto;
|
||||||
|
};
|
||||||
|
|
||||||
struct ice_tc_l2_hdr {
|
struct ice_tc_l2_hdr {
|
||||||
u8 dst_mac[ETH_ALEN];
|
u8 dst_mac[ETH_ALEN];
|
||||||
u8 src_mac[ETH_ALEN];
|
u8 src_mac[ETH_ALEN];
|
||||||
@ -84,6 +91,7 @@ struct ice_tc_flower_lyr_2_4_hdrs {
|
|||||||
struct ice_tc_l2_hdr l2_mask;
|
struct ice_tc_l2_hdr l2_mask;
|
||||||
struct ice_tc_vlan_hdr vlan_hdr;
|
struct ice_tc_vlan_hdr vlan_hdr;
|
||||||
struct ice_tc_vlan_hdr cvlan_hdr;
|
struct ice_tc_vlan_hdr cvlan_hdr;
|
||||||
|
struct ice_tc_pppoe_hdr pppoe_hdr;
|
||||||
/* L3 (IPv4[6]) layer fields with their mask */
|
/* L3 (IPv4[6]) layer fields with their mask */
|
||||||
struct ice_tc_l3_hdr l3_key;
|
struct ice_tc_l3_hdr l3_key;
|
||||||
struct ice_tc_l3_hdr l3_mask;
|
struct ice_tc_l3_hdr l3_mask;
|
||||||
|
@ -11,4 +11,18 @@
|
|||||||
#include <uapi/linux/ppp_defs.h>
|
#include <uapi/linux/ppp_defs.h>
|
||||||
|
|
||||||
#define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c)
|
#define PPP_FCS(fcs, c) crc_ccitt_byte(fcs, c)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ppp_proto_is_valid - checks if PPP protocol is valid
|
||||||
|
* @proto: PPP protocol
|
||||||
|
*
|
||||||
|
* Assumes proto is not compressed.
|
||||||
|
* Protocol is valid if the value is odd and the least significant bit of the
|
||||||
|
* most significant octet is 0 (see RFC 1661, section 2).
|
||||||
|
*/
|
||||||
|
static inline bool ppp_proto_is_valid(u16 proto)
|
||||||
|
{
|
||||||
|
return !!((proto & 0x0101) == 0x0001);
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* _PPP_DEFS_H_ */
|
#endif /* _PPP_DEFS_H_ */
|
||||||
|
@ -277,6 +277,18 @@ struct flow_dissector_key_num_of_vlans {
|
|||||||
u8 num_of_vlans;
|
u8 num_of_vlans;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* struct flow_dissector_key_pppoe:
|
||||||
|
* @session_id: pppoe session id
|
||||||
|
* @ppp_proto: ppp protocol
|
||||||
|
* @type: pppoe eth type
|
||||||
|
*/
|
||||||
|
struct flow_dissector_key_pppoe {
|
||||||
|
__be16 session_id;
|
||||||
|
__be16 ppp_proto;
|
||||||
|
__be16 type;
|
||||||
|
};
|
||||||
|
|
||||||
enum flow_dissector_key_id {
|
enum flow_dissector_key_id {
|
||||||
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
|
FLOW_DISSECTOR_KEY_CONTROL, /* struct flow_dissector_key_control */
|
||||||
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
|
FLOW_DISSECTOR_KEY_BASIC, /* struct flow_dissector_key_basic */
|
||||||
@ -307,6 +319,7 @@ enum flow_dissector_key_id {
|
|||||||
FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
|
FLOW_DISSECTOR_KEY_CT, /* struct flow_dissector_key_ct */
|
||||||
FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
|
FLOW_DISSECTOR_KEY_HASH, /* struct flow_dissector_key_hash */
|
||||||
FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
|
FLOW_DISSECTOR_KEY_NUM_OF_VLANS, /* struct flow_dissector_key_num_of_vlans */
|
||||||
|
FLOW_DISSECTOR_KEY_PPPOE, /* struct flow_dissector_key_pppoe */
|
||||||
|
|
||||||
FLOW_DISSECTOR_KEY_MAX,
|
FLOW_DISSECTOR_KEY_MAX,
|
||||||
};
|
};
|
||||||
|
@ -76,6 +76,10 @@ struct flow_match_ct {
|
|||||||
struct flow_dissector_key_ct *key, *mask;
|
struct flow_dissector_key_ct *key, *mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct flow_match_pppoe {
|
||||||
|
struct flow_dissector_key_pppoe *key, *mask;
|
||||||
|
};
|
||||||
|
|
||||||
struct flow_rule;
|
struct flow_rule;
|
||||||
|
|
||||||
void flow_rule_match_meta(const struct flow_rule *rule,
|
void flow_rule_match_meta(const struct flow_rule *rule,
|
||||||
@ -122,6 +126,8 @@ void flow_rule_match_enc_opts(const struct flow_rule *rule,
|
|||||||
struct flow_match_enc_opts *out);
|
struct flow_match_enc_opts *out);
|
||||||
void flow_rule_match_ct(const struct flow_rule *rule,
|
void flow_rule_match_ct(const struct flow_rule *rule,
|
||||||
struct flow_match_ct *out);
|
struct flow_match_ct *out);
|
||||||
|
void flow_rule_match_pppoe(const struct flow_rule *rule,
|
||||||
|
struct flow_match_pppoe *out);
|
||||||
|
|
||||||
enum flow_action_id {
|
enum flow_action_id {
|
||||||
FLOW_ACTION_ACCEPT = 0,
|
FLOW_ACTION_ACCEPT = 0,
|
||||||
|
@ -589,6 +589,9 @@ enum {
|
|||||||
|
|
||||||
TCA_FLOWER_KEY_NUM_OF_VLANS, /* u8 */
|
TCA_FLOWER_KEY_NUM_OF_VLANS, /* u8 */
|
||||||
|
|
||||||
|
TCA_FLOWER_KEY_PPPOE_SID, /* be16 */
|
||||||
|
TCA_FLOWER_KEY_PPP_PROTO, /* be16 */
|
||||||
|
|
||||||
__TCA_FLOWER_MAX,
|
__TCA_FLOWER_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -895,6 +895,11 @@ bool bpf_flow_dissect(struct bpf_prog *prog, struct bpf_flow_dissector *ctx,
|
|||||||
return result == BPF_OK;
|
return result == BPF_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool is_pppoe_ses_hdr_valid(struct pppoe_hdr hdr)
|
||||||
|
{
|
||||||
|
return hdr.ver == 1 && hdr.type == 1 && hdr.code == 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* __skb_flow_dissect - extract the flow_keys struct and return it
|
* __skb_flow_dissect - extract the flow_keys struct and return it
|
||||||
* @net: associated network namespace, derived from @skb if NULL
|
* @net: associated network namespace, derived from @skb if NULL
|
||||||
@ -1214,26 +1219,60 @@ proto_again:
|
|||||||
struct pppoe_hdr hdr;
|
struct pppoe_hdr hdr;
|
||||||
__be16 proto;
|
__be16 proto;
|
||||||
} *hdr, _hdr;
|
} *hdr, _hdr;
|
||||||
|
u16 ppp_proto;
|
||||||
|
|
||||||
hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
|
hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
|
||||||
if (!hdr) {
|
if (!hdr) {
|
||||||
fdret = FLOW_DISSECT_RET_OUT_BAD;
|
fdret = FLOW_DISSECT_RET_OUT_BAD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
nhoff += PPPOE_SES_HLEN;
|
if (!is_pppoe_ses_hdr_valid(hdr->hdr)) {
|
||||||
switch (hdr->proto) {
|
|
||||||
case htons(PPP_IP):
|
|
||||||
proto = htons(ETH_P_IP);
|
|
||||||
fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
|
|
||||||
break;
|
|
||||||
case htons(PPP_IPV6):
|
|
||||||
proto = htons(ETH_P_IPV6);
|
|
||||||
fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
fdret = FLOW_DISSECT_RET_OUT_BAD;
|
fdret = FLOW_DISSECT_RET_OUT_BAD;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* least significant bit of the most significant octet
|
||||||
|
* indicates if protocol field was compressed
|
||||||
|
*/
|
||||||
|
ppp_proto = ntohs(hdr->proto);
|
||||||
|
if (ppp_proto & 0x0100) {
|
||||||
|
ppp_proto = ppp_proto >> 8;
|
||||||
|
nhoff += PPPOE_SES_HLEN - 1;
|
||||||
|
} else {
|
||||||
|
nhoff += PPPOE_SES_HLEN;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ppp_proto == PPP_IP) {
|
||||||
|
proto = htons(ETH_P_IP);
|
||||||
|
fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
|
||||||
|
} else if (ppp_proto == PPP_IPV6) {
|
||||||
|
proto = htons(ETH_P_IPV6);
|
||||||
|
fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
|
||||||
|
} else if (ppp_proto == PPP_MPLS_UC) {
|
||||||
|
proto = htons(ETH_P_MPLS_UC);
|
||||||
|
fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
|
||||||
|
} else if (ppp_proto == PPP_MPLS_MC) {
|
||||||
|
proto = htons(ETH_P_MPLS_MC);
|
||||||
|
fdret = FLOW_DISSECT_RET_PROTO_AGAIN;
|
||||||
|
} else if (ppp_proto_is_valid(ppp_proto)) {
|
||||||
|
fdret = FLOW_DISSECT_RET_OUT_GOOD;
|
||||||
|
} else {
|
||||||
|
fdret = FLOW_DISSECT_RET_OUT_BAD;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dissector_uses_key(flow_dissector,
|
||||||
|
FLOW_DISSECTOR_KEY_PPPOE)) {
|
||||||
|
struct flow_dissector_key_pppoe *key_pppoe;
|
||||||
|
|
||||||
|
key_pppoe = skb_flow_dissector_target(flow_dissector,
|
||||||
|
FLOW_DISSECTOR_KEY_PPPOE,
|
||||||
|
target_container);
|
||||||
|
key_pppoe->session_id = hdr->hdr.sid;
|
||||||
|
key_pppoe->ppp_proto = htons(ppp_proto);
|
||||||
|
key_pppoe->type = htons(ETH_P_PPP_SES);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case htons(ETH_P_TIPC): {
|
case htons(ETH_P_TIPC): {
|
||||||
|
@ -230,6 +230,13 @@ void flow_rule_match_ct(const struct flow_rule *rule,
|
|||||||
}
|
}
|
||||||
EXPORT_SYMBOL(flow_rule_match_ct);
|
EXPORT_SYMBOL(flow_rule_match_ct);
|
||||||
|
|
||||||
|
void flow_rule_match_pppoe(const struct flow_rule *rule,
|
||||||
|
struct flow_match_pppoe *out)
|
||||||
|
{
|
||||||
|
FLOW_DISSECTOR_MATCH(rule, FLOW_DISSECTOR_KEY_PPPOE, out);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(flow_rule_match_pppoe);
|
||||||
|
|
||||||
struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb,
|
struct flow_block_cb *flow_block_cb_alloc(flow_setup_cb_t *cb,
|
||||||
void *cb_ident, void *cb_priv,
|
void *cb_ident, void *cb_priv,
|
||||||
void (*release)(void *cb_priv))
|
void (*release)(void *cb_priv))
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#include <linux/in6.h>
|
#include <linux/in6.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/mpls.h>
|
#include <linux/mpls.h>
|
||||||
|
#include <linux/ppp_defs.h>
|
||||||
|
|
||||||
#include <net/sch_generic.h>
|
#include <net/sch_generic.h>
|
||||||
#include <net/pkt_cls.h>
|
#include <net/pkt_cls.h>
|
||||||
@ -67,6 +68,7 @@ struct fl_flow_key {
|
|||||||
struct flow_dissector_key_ct ct;
|
struct flow_dissector_key_ct ct;
|
||||||
struct flow_dissector_key_hash hash;
|
struct flow_dissector_key_hash hash;
|
||||||
struct flow_dissector_key_num_of_vlans num_of_vlans;
|
struct flow_dissector_key_num_of_vlans num_of_vlans;
|
||||||
|
struct flow_dissector_key_pppoe pppoe;
|
||||||
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
|
} __aligned(BITS_PER_LONG / 8); /* Ensure that we can do comparisons as longs. */
|
||||||
|
|
||||||
struct fl_flow_mask_range {
|
struct fl_flow_mask_range {
|
||||||
@ -708,6 +710,8 @@ static const struct nla_policy fl_policy[TCA_FLOWER_MAX + 1] = {
|
|||||||
[TCA_FLOWER_KEY_HASH] = { .type = NLA_U32 },
|
[TCA_FLOWER_KEY_HASH] = { .type = NLA_U32 },
|
||||||
[TCA_FLOWER_KEY_HASH_MASK] = { .type = NLA_U32 },
|
[TCA_FLOWER_KEY_HASH_MASK] = { .type = NLA_U32 },
|
||||||
[TCA_FLOWER_KEY_NUM_OF_VLANS] = { .type = NLA_U8 },
|
[TCA_FLOWER_KEY_NUM_OF_VLANS] = { .type = NLA_U8 },
|
||||||
|
[TCA_FLOWER_KEY_PPPOE_SID] = { .type = NLA_U16 },
|
||||||
|
[TCA_FLOWER_KEY_PPP_PROTO] = { .type = NLA_U16 },
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1035,6 +1039,50 @@ static void fl_set_key_vlan(struct nlattr **tb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fl_set_key_pppoe(struct nlattr **tb,
|
||||||
|
struct flow_dissector_key_pppoe *key_val,
|
||||||
|
struct flow_dissector_key_pppoe *key_mask,
|
||||||
|
struct fl_flow_key *key,
|
||||||
|
struct fl_flow_key *mask)
|
||||||
|
{
|
||||||
|
/* key_val::type must be set to ETH_P_PPP_SES
|
||||||
|
* because ETH_P_PPP_SES was stored in basic.n_proto
|
||||||
|
* which might get overwritten by ppp_proto
|
||||||
|
* or might be set to 0, the role of key_val::type
|
||||||
|
* is simmilar to vlan_key::tpid
|
||||||
|
*/
|
||||||
|
key_val->type = htons(ETH_P_PPP_SES);
|
||||||
|
key_mask->type = cpu_to_be16(~0);
|
||||||
|
|
||||||
|
if (tb[TCA_FLOWER_KEY_PPPOE_SID]) {
|
||||||
|
key_val->session_id =
|
||||||
|
nla_get_be16(tb[TCA_FLOWER_KEY_PPPOE_SID]);
|
||||||
|
key_mask->session_id = cpu_to_be16(~0);
|
||||||
|
}
|
||||||
|
if (tb[TCA_FLOWER_KEY_PPP_PROTO]) {
|
||||||
|
key_val->ppp_proto =
|
||||||
|
nla_get_be16(tb[TCA_FLOWER_KEY_PPP_PROTO]);
|
||||||
|
key_mask->ppp_proto = cpu_to_be16(~0);
|
||||||
|
|
||||||
|
if (key_val->ppp_proto == htons(PPP_IP)) {
|
||||||
|
key->basic.n_proto = htons(ETH_P_IP);
|
||||||
|
mask->basic.n_proto = cpu_to_be16(~0);
|
||||||
|
} else if (key_val->ppp_proto == htons(PPP_IPV6)) {
|
||||||
|
key->basic.n_proto = htons(ETH_P_IPV6);
|
||||||
|
mask->basic.n_proto = cpu_to_be16(~0);
|
||||||
|
} else if (key_val->ppp_proto == htons(PPP_MPLS_UC)) {
|
||||||
|
key->basic.n_proto = htons(ETH_P_MPLS_UC);
|
||||||
|
mask->basic.n_proto = cpu_to_be16(~0);
|
||||||
|
} else if (key_val->ppp_proto == htons(PPP_MPLS_MC)) {
|
||||||
|
key->basic.n_proto = htons(ETH_P_MPLS_MC);
|
||||||
|
mask->basic.n_proto = cpu_to_be16(~0);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
key->basic.n_proto = 0;
|
||||||
|
mask->basic.n_proto = cpu_to_be16(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void fl_set_key_flag(u32 flower_key, u32 flower_mask,
|
static void fl_set_key_flag(u32 flower_key, u32 flower_mask,
|
||||||
u32 *dissector_key, u32 *dissector_mask,
|
u32 *dissector_key, u32 *dissector_mask,
|
||||||
u32 flower_flag_bit, u32 dissector_flag_bit)
|
u32 flower_flag_bit, u32 dissector_flag_bit)
|
||||||
@ -1645,6 +1693,9 @@ static int fl_set_key(struct net *net, struct nlattr **tb,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (key->basic.n_proto == htons(ETH_P_PPP_SES))
|
||||||
|
fl_set_key_pppoe(tb, &key->pppoe, &mask->pppoe, key, mask);
|
||||||
|
|
||||||
if (key->basic.n_proto == htons(ETH_P_IP) ||
|
if (key->basic.n_proto == htons(ETH_P_IP) ||
|
||||||
key->basic.n_proto == htons(ETH_P_IPV6)) {
|
key->basic.n_proto == htons(ETH_P_IPV6)) {
|
||||||
fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
|
fl_set_key_val(tb, &key->basic.ip_proto, TCA_FLOWER_KEY_IP_PROTO,
|
||||||
@ -1917,6 +1968,8 @@ static void fl_init_dissector(struct flow_dissector *dissector,
|
|||||||
FLOW_DISSECTOR_KEY_HASH, hash);
|
FLOW_DISSECTOR_KEY_HASH, hash);
|
||||||
FL_KEY_SET_IF_MASKED(mask, keys, cnt,
|
FL_KEY_SET_IF_MASKED(mask, keys, cnt,
|
||||||
FLOW_DISSECTOR_KEY_NUM_OF_VLANS, num_of_vlans);
|
FLOW_DISSECTOR_KEY_NUM_OF_VLANS, num_of_vlans);
|
||||||
|
FL_KEY_SET_IF_MASKED(mask, keys, cnt,
|
||||||
|
FLOW_DISSECTOR_KEY_PPPOE, pppoe);
|
||||||
|
|
||||||
skb_flow_dissector_init(dissector, keys, cnt);
|
skb_flow_dissector_init(dissector, keys, cnt);
|
||||||
}
|
}
|
||||||
@ -3045,6 +3098,17 @@ static int fl_dump_key(struct sk_buff *skb, struct net *net,
|
|||||||
fl_dump_key_ip(skb, false, &key->ip, &mask->ip)))
|
fl_dump_key_ip(skb, false, &key->ip, &mask->ip)))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
if (mask->pppoe.session_id) {
|
||||||
|
if (nla_put_be16(skb, TCA_FLOWER_KEY_PPPOE_SID,
|
||||||
|
key->pppoe.session_id))
|
||||||
|
goto nla_put_failure;
|
||||||
|
}
|
||||||
|
if (mask->basic.n_proto && mask->pppoe.ppp_proto) {
|
||||||
|
if (nla_put_be16(skb, TCA_FLOWER_KEY_PPP_PROTO,
|
||||||
|
key->pppoe.ppp_proto))
|
||||||
|
goto nla_put_failure;
|
||||||
|
}
|
||||||
|
|
||||||
if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
|
if (key->control.addr_type == FLOW_DISSECTOR_KEY_IPV4_ADDRS &&
|
||||||
(fl_dump_key_val(skb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,
|
(fl_dump_key_val(skb, &key->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC,
|
||||||
&mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK,
|
&mask->ipv4.src, TCA_FLOWER_KEY_IPV4_SRC_MASK,
|
||||||
|
Loading…
Reference in New Issue
Block a user