Commit ef9e4cc5 authored by Qi Zhang's avatar Qi Zhang Committed by Tony Nguyen

ice: Add GTPU FDIR filter for AVF

Add new FDIR filter type to forward GTPU packets by matching TEID or QFI.
The filter is only enabled when COMMS DDP package is downloaded.
Signed-off-by: default avatarYahui Cao <yahui.cao@intel.com>
Signed-off-by: default avatarQi Zhang <qi.z.zhang@intel.com>
Tested-by: default avatarChen Bo <BoX.C.Chen@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 21606584
......@@ -40,6 +40,66 @@ static const u8 ice_fdir_ipv4_pkt[] = {
0x00, 0x00
};
static const u8 ice_fdir_udp4_gtpu4_pkt[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
};
static const u8 ice_fdir_tcp4_gtpu4_pkt[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
0x00, 0x58, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x28, 0x00, 0x00, 0x40, 0x00, 0x40, 0x06,
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,
};
static const u8 ice_fdir_icmp4_gtpu4_pkt[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
0x00, 0x4c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x1c, 0x00, 0x00, 0x40, 0x00, 0x40, 0x01,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
};
static const u8 ice_fdir_ipv4_gtpu4_pkt[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x45, 0x00,
0x00, 0x44, 0x00, 0x00, 0x40, 0x00, 0x40, 0x11,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x08, 0x68, 0x08, 0x68, 0x00, 0x00,
0x00, 0x00, 0x34, 0xff, 0x00, 0x28, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0x02, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x00,
0x00, 0x14, 0x00, 0x00, 0x40, 0x00, 0x40, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00,
};
static const u8 ice_fdir_non_ip_l2_pkt[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
......@@ -244,6 +304,34 @@ static const struct ice_fdir_base_pkt ice_fdir_pkt[] = {
sizeof(ice_fdir_ipv4_pkt), ice_fdir_ipv4_pkt,
sizeof(ice_fdir_ip4_tun_pkt), ice_fdir_ip4_tun_pkt,
},
{
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP,
sizeof(ice_fdir_udp4_gtpu4_pkt),
ice_fdir_udp4_gtpu4_pkt,
sizeof(ice_fdir_udp4_gtpu4_pkt),
ice_fdir_udp4_gtpu4_pkt,
},
{
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP,
sizeof(ice_fdir_tcp4_gtpu4_pkt),
ice_fdir_tcp4_gtpu4_pkt,
sizeof(ice_fdir_tcp4_gtpu4_pkt),
ice_fdir_tcp4_gtpu4_pkt,
},
{
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP,
sizeof(ice_fdir_icmp4_gtpu4_pkt),
ice_fdir_icmp4_gtpu4_pkt,
sizeof(ice_fdir_icmp4_gtpu4_pkt),
ice_fdir_icmp4_gtpu4_pkt,
},
{
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER,
sizeof(ice_fdir_ipv4_gtpu4_pkt),
ice_fdir_ipv4_gtpu4_pkt,
sizeof(ice_fdir_ipv4_gtpu4_pkt),
ice_fdir_ipv4_gtpu4_pkt,
},
{
ICE_FLTR_PTYPE_NON_IP_L2,
sizeof(ice_fdir_non_ip_l2_pkt), ice_fdir_non_ip_l2_pkt,
......@@ -491,6 +579,22 @@ static void ice_pkt_insert_ipv6_addr(u8 *pkt, int offset, __be32 *addr)
sizeof(*addr));
}
/**
* ice_pkt_insert_u6_qfi - insert a u6 value QFI into a memory buffer for GTPU
* @pkt: packet buffer
* @offset: offset into buffer
* @data: 8 bit value to convert and insert into pkt at offset
*
* This function is designed for inserting QFI (6 bits) for GTPU.
*/
static void ice_pkt_insert_u6_qfi(u8 *pkt, int offset, u8 data)
{
u8 ret;
ret = (data & 0x3F) + (*(pkt + offset) & 0xC0);
memcpy(pkt + offset, &ret, sizeof(ret));
}
/**
* ice_pkt_insert_u8 - insert a u8 value into a memory buffer.
* @pkt: packet buffer
......@@ -685,6 +789,19 @@ ice_fdir_get_gen_prgm_pkt(struct ice_hw *hw, struct ice_fdir_fltr *input,
input->ip.v4.proto);
ice_pkt_insert_mac_addr(loc, input->ext_data.dst_mac);
break;
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
ice_pkt_insert_u32(loc, ICE_IPV4_DST_ADDR_OFFSET,
input->ip.v4.src_ip);
ice_pkt_insert_u32(loc, ICE_IPV4_SRC_ADDR_OFFSET,
input->ip.v4.dst_ip);
ice_pkt_insert_u32(loc, ICE_IPV4_GTPU_TEID_OFFSET,
input->gtpu_data.teid);
ice_pkt_insert_u6_qfi(loc, ICE_IPV4_GTPU_QFI_OFFSET,
input->gtpu_data.qfi);
break;
case ICE_FLTR_PTYPE_NON_IP_L2:
ice_pkt_insert_u16(loc, ICE_MAC_ETHTYPE_OFFSET,
input->ext_data.ether_type);
......
......@@ -31,6 +31,8 @@
#define ICE_IPV6_TC_OFFSET 14
#define ICE_IPV6_HLIM_OFFSET 21
#define ICE_IPV6_PROTO_OFFSET 20
#define ICE_IPV4_GTPU_TEID_OFFSET 46
#define ICE_IPV4_GTPU_QFI_OFFSET 56
#define ICE_FDIR_MAX_FLTRS 16384
......@@ -114,6 +116,24 @@ struct ice_fdir_v6 {
u8 hlim;
};
struct ice_fdir_udp_gtp {
u8 flags;
u8 msg_type;
__be16 rsrvd_len;
__be32 teid;
__be16 rsrvd_seq_nbr;
u8 rsrvd_n_pdu_nbr;
u8 rsrvd_next_ext_type;
u8 rsvrd_ext_len;
u8 pdu_type:4,
spare:4;
u8 ppp:1,
rqi:1,
qfi:6;
u32 rsvrd;
u8 next_ext;
};
struct ice_fdir_extra {
u8 dst_mac[ETH_ALEN]; /* dest MAC address */
u8 src_mac[ETH_ALEN]; /* src MAC address */
......@@ -132,6 +152,9 @@ struct ice_fdir_fltr {
struct ice_fdir_v6 v6;
} ip, mask;
struct ice_fdir_udp_gtp gtpu_data;
struct ice_fdir_udp_gtp gtpu_mask;
struct ice_fdir_extra ext_data;
struct ice_fdir_extra ext_mask;
......
......@@ -192,6 +192,10 @@ enum ice_fltr_ptype {
ICE_FLTR_PTYPE_NONF_IPV4_TCP,
ICE_FLTR_PTYPE_NONF_IPV4_SCTP,
ICE_FLTR_PTYPE_NONF_IPV4_OTHER,
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP,
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP,
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP,
ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER,
ICE_FLTR_PTYPE_NON_IP_L2,
ICE_FLTR_PTYPE_FRAG_IPV4,
ICE_FLTR_PTYPE_NONF_IPV6_UDP,
......
......@@ -22,8 +22,19 @@
((u64)(((((flow) + (tun_offs)) & ICE_FLOW_PROF_TYPE_M)) | \
(((u64)(vsi) << ICE_FLOW_PROF_VSI_S) & ICE_FLOW_PROF_VSI_M)))
#define GTPU_TEID_OFFSET 4
#define GTPU_EH_QFI_OFFSET 1
#define GTPU_EH_QFI_MASK 0x3F
enum ice_fdir_tunnel_type {
ICE_FDIR_TUNNEL_TYPE_NONE = 0,
ICE_FDIR_TUNNEL_TYPE_GTPU,
ICE_FDIR_TUNNEL_TYPE_GTPU_EH,
};
struct virtchnl_fdir_fltr_conf {
struct ice_fdir_fltr input;
enum ice_fdir_tunnel_type ttype;
};
static enum virtchnl_proto_hdr_type vc_pattern_ether[] = {
......@@ -85,6 +96,23 @@ static enum virtchnl_proto_hdr_type vc_pattern_ipv6_sctp[] = {
VIRTCHNL_PROTO_HDR_NONE,
};
static enum virtchnl_proto_hdr_type vc_pattern_ipv4_gtpu[] = {
VIRTCHNL_PROTO_HDR_ETH,
VIRTCHNL_PROTO_HDR_IPV4,
VIRTCHNL_PROTO_HDR_UDP,
VIRTCHNL_PROTO_HDR_GTPU_IP,
VIRTCHNL_PROTO_HDR_NONE,
};
static enum virtchnl_proto_hdr_type vc_pattern_ipv4_gtpu_eh[] = {
VIRTCHNL_PROTO_HDR_ETH,
VIRTCHNL_PROTO_HDR_IPV4,
VIRTCHNL_PROTO_HDR_UDP,
VIRTCHNL_PROTO_HDR_GTPU_IP,
VIRTCHNL_PROTO_HDR_GTPU_EH,
VIRTCHNL_PROTO_HDR_NONE,
};
struct virtchnl_fdir_pattern_match_item {
enum virtchnl_proto_hdr_type *list;
u64 input_set;
......@@ -112,6 +140,8 @@ static const struct virtchnl_fdir_pattern_match_item vc_fdir_pattern_comms[] = {
{vc_pattern_ipv6_udp, 0, NULL},
{vc_pattern_ipv6_sctp, 0, NULL},
{vc_pattern_ether, 0, NULL},
{vc_pattern_ipv4_gtpu, 0, NULL},
{vc_pattern_ipv4_gtpu_eh, 0, NULL},
};
struct virtchnl_fdir_inset_map {
......@@ -136,6 +166,8 @@ static const struct virtchnl_fdir_inset_map fdir_inset_map[] = {
{VIRTCHNL_PROTO_HDR_TCP_DST_PORT, ICE_FLOW_FIELD_IDX_TCP_DST_PORT},
{VIRTCHNL_PROTO_HDR_SCTP_SRC_PORT, ICE_FLOW_FIELD_IDX_SCTP_SRC_PORT},
{VIRTCHNL_PROTO_HDR_SCTP_DST_PORT, ICE_FLOW_FIELD_IDX_SCTP_DST_PORT},
{VIRTCHNL_PROTO_HDR_GTPU_IP_TEID, ICE_FLOW_FIELD_IDX_GTPU_IP_TEID},
{VIRTCHNL_PROTO_HDR_GTPU_EH_QFI, ICE_FLOW_FIELD_IDX_GTPU_EH_QFI},
};
/**
......@@ -385,6 +417,7 @@ ice_vc_fdir_set_flow_hdr(struct ice_vf *vf,
struct ice_flow_seg_info *seg)
{
enum ice_fltr_ptype flow = conf->input.flow_type;
enum ice_fdir_tunnel_type ttype = conf->ttype;
struct device *dev = ice_pf_to_dev(vf->pf);
switch (flow) {
......@@ -405,6 +438,25 @@ ice_vc_fdir_set_flow_hdr(struct ice_vf *vf,
ICE_FLOW_SEG_HDR_IPV4 |
ICE_FLOW_SEG_HDR_IPV_OTHER);
break;
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_UDP:
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_TCP:
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_ICMP:
case ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER:
if (ttype == ICE_FDIR_TUNNEL_TYPE_GTPU) {
ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_IP |
ICE_FLOW_SEG_HDR_IPV4 |
ICE_FLOW_SEG_HDR_IPV_OTHER);
} else if (ttype == ICE_FDIR_TUNNEL_TYPE_GTPU_EH) {
ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_GTPU_EH |
ICE_FLOW_SEG_HDR_GTPU_IP |
ICE_FLOW_SEG_HDR_IPV4 |
ICE_FLOW_SEG_HDR_IPV_OTHER);
} else {
dev_dbg(dev, "Invalid tunnel type 0x%x for VF %d\n",
flow, vf->vf_id);
return -EINVAL;
}
break;
case ICE_FLTR_PTYPE_NONF_IPV4_SCTP:
ICE_FLOW_SET_HDRS(seg, ICE_FLOW_SEG_HDR_SCTP |
ICE_FLOW_SEG_HDR_IPV4 |
......@@ -800,6 +852,7 @@ ice_vc_fdir_parse_pattern(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
struct tcphdr *tcph;
struct ethhdr *eth;
struct iphdr *iph;
u8 *rawh;
switch (hdr->type) {
case VIRTCHNL_PROTO_HDR_ETH:
......@@ -891,6 +944,21 @@ ice_vc_fdir_parse_pattern(struct ice_vf *vf, struct virtchnl_fdir_add *fltr,
}
}
break;
case VIRTCHNL_PROTO_HDR_GTPU_IP:
rawh = (u8 *)hdr->buffer;
input->flow_type = ICE_FLTR_PTYPE_NONF_IPV4_GTPU_IPV4_OTHER;
if (hdr->field_selector)
input->gtpu_data.teid = *(__be32 *)(&rawh[GTPU_TEID_OFFSET]);
conf->ttype = ICE_FDIR_TUNNEL_TYPE_GTPU;
break;
case VIRTCHNL_PROTO_HDR_GTPU_EH:
rawh = (u8 *)hdr->buffer;
if (hdr->field_selector)
input->gtpu_data.qfi = rawh[GTPU_EH_QFI_OFFSET] & GTPU_EH_QFI_MASK;
conf->ttype = ICE_FDIR_TUNNEL_TYPE_GTPU_EH;
break;
default:
dev_dbg(dev, "Invalid header type 0x:%x for VF %d\n",
hdr->type, vf->vf_id);
......@@ -1016,12 +1084,18 @@ ice_vc_fdir_comp_rules(struct virtchnl_fdir_fltr_conf *conf_a,
struct ice_fdir_fltr *a = &conf_a->input;
struct ice_fdir_fltr *b = &conf_b->input;
if (conf_a->ttype != conf_b->ttype)
return false;
if (a->flow_type != b->flow_type)
return false;
if (memcmp(&a->ip, &b->ip, sizeof(a->ip)))
return false;
if (memcmp(&a->mask, &b->mask, sizeof(a->mask)))
return false;
if (memcmp(&a->gtpu_data, &b->gtpu_data, sizeof(a->gtpu_data)))
return false;
if (memcmp(&a->gtpu_mask, &b->gtpu_mask, sizeof(a->gtpu_mask)))
return false;
if (memcmp(&a->ext_data, &b->ext_data, sizeof(a->ext_data)))
return false;
if (memcmp(&a->ext_mask, &b->ext_mask, sizeof(a->ext_mask)))
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment