Commit 8b032a55 authored by Michal Swiatkowski's avatar Michal Swiatkowski Committed by Tony Nguyen

ice: low level support for tunnels

Add definition of UDP tunnel dummy packets. Fill destination port value
in filter based on UDP tunnel port. Append tunnel flags to switch filter
definition in case of matching the tunnel.

Both VXLAN and Geneve are UDP tunnels, so only one new header is needed.
Signed-off-by: default avatarMichal Swiatkowski <michal.swiatkowski@linux.intel.com>
Tested-by: default avatarSandeep Penigalapati <sandeep.penigalapati@intel.com>
Signed-off-by: default avatarTony Nguyen <anthony.l.nguyen@intel.com>
parent 9e300987
...@@ -1565,6 +1565,26 @@ static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw) ...@@ -1565,6 +1565,26 @@ static struct ice_buf_build *ice_pkg_buf_alloc(struct ice_hw *hw)
return bld; return bld;
} }
/**
* ice_get_sw_prof_type - determine switch profile type
* @hw: pointer to the HW structure
* @fv: pointer to the switch field vector
*/
static enum ice_prof_type
ice_get_sw_prof_type(struct ice_hw *hw, struct ice_fv *fv)
{
u16 i;
for (i = 0; i < hw->blk[ICE_BLK_SW].es.fvw; i++) {
/* UDP tunnel will have UDP_OF protocol ID and VNI offset */
if (fv->ew[i].prot_id == (u8)ICE_PROT_UDP_OF &&
fv->ew[i].off == ICE_VNI_OFFSET)
return ICE_PROF_TUN_UDP;
}
return ICE_PROF_NON_TUN;
}
/** /**
* ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type * ice_get_sw_fv_bitmap - Get switch field vector bitmap based on profile type
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -1588,6 +1608,7 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs, ...@@ -1588,6 +1608,7 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,
bitmap_zero(bm, ICE_MAX_NUM_PROFILES); bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
ice_seg = hw->seg; ice_seg = hw->seg;
do { do {
enum ice_prof_type prof_type;
u32 offset; u32 offset;
fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW, fv = ice_pkg_enum_entry(ice_seg, &state, ICE_SID_FLD_VEC_SW,
...@@ -1595,7 +1616,10 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs, ...@@ -1595,7 +1616,10 @@ ice_get_sw_fv_bitmap(struct ice_hw *hw, enum ice_prof_type req_profs,
ice_seg = NULL; ice_seg = NULL;
if (fv) { if (fv) {
if (req_profs & ICE_PROF_NON_TUN) /* Determine field vector type */
prof_type = ice_get_sw_prof_type(hw, fv);
if (req_profs & prof_type)
set_bit((u16)offset, bm); set_bit((u16)offset, bm);
} }
} while (fv); } while (fv);
......
...@@ -614,6 +614,8 @@ struct ice_chs_chg { ...@@ -614,6 +614,8 @@ struct ice_chs_chg {
enum ice_prof_type { enum ice_prof_type {
ICE_PROF_NON_TUN = 0x1, ICE_PROF_NON_TUN = 0x1,
ICE_PROF_TUN_UDP = 0x2,
ICE_PROF_TUN_ALL = 0x6,
ICE_PROF_ALL = 0xFF, ICE_PROF_ALL = 0xFF,
}; };
#endif /* _ICE_FLEX_TYPE_H_ */ #endif /* _ICE_FLEX_TYPE_H_ */
...@@ -48,6 +48,7 @@ enum ice_sw_tunnel_type { ...@@ -48,6 +48,7 @@ enum ice_sw_tunnel_type {
ICE_NON_TUN = 0, ICE_NON_TUN = 0,
ICE_SW_TUN_VXLAN, ICE_SW_TUN_VXLAN,
ICE_SW_TUN_GENEVE, ICE_SW_TUN_GENEVE,
ICE_ALL_TUNNELS /* All tunnel types */
}; };
/* Decoders for ice_prot_id: /* Decoders for ice_prot_id:
...@@ -83,6 +84,8 @@ enum ice_prot_id { ...@@ -83,6 +84,8 @@ enum ice_prot_id {
ICE_PROT_INVALID = 255 /* when offset == ICE_FV_OFFSET_INVAL */ ICE_PROT_INVALID = 255 /* when offset == ICE_FV_OFFSET_INVAL */
}; };
#define ICE_VNI_OFFSET 12 /* offset of VNI from ICE_PROT_UDP_OF */
#define ICE_MAC_OFOS_HW 1 #define ICE_MAC_OFOS_HW 1
#define ICE_MAC_IL_HW 4 #define ICE_MAC_IL_HW 4
#define ICE_ETYPE_OL_HW 9 #define ICE_ETYPE_OL_HW 9
...@@ -96,6 +99,12 @@ enum ice_prot_id { ...@@ -96,6 +99,12 @@ enum ice_prot_id {
#define ICE_UDP_ILOS_HW 53 #define ICE_UDP_ILOS_HW 53
#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 type */
#define ICE_MDID_SIZE 2
#define ICE_TUN_FLAG_MDID 21
#define ICE_TUN_FLAG_MDID_OFF (ICE_MDID_SIZE * ICE_TUN_FLAG_MDID)
#define ICE_TUN_FLAG_MASK 0xFF
#define ICE_TUN_FLAG_FV_IND 2 #define ICE_TUN_FLAG_FV_IND 2
......
...@@ -35,6 +35,105 @@ struct ice_dummy_pkt_offsets { ...@@ -35,6 +35,105 @@ struct ice_dummy_pkt_offsets {
u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */ u16 offset; /* ICE_PROTOCOL_LAST indicates end of list */
}; };
static const struct ice_dummy_pkt_offsets dummy_udp_tun_tcp_packet_offsets[] = {
{ ICE_MAC_OFOS, 0 },
{ ICE_ETYPE_OL, 12 },
{ ICE_IPV4_OFOS, 14 },
{ ICE_UDP_OF, 34 },
{ ICE_VXLAN, 42 },
{ ICE_GENEVE, 42 },
{ ICE_VXLAN_GPE, 42 },
{ ICE_MAC_IL, 50 },
{ ICE_IPV4_IL, 64 },
{ ICE_TCP_IL, 84 },
{ ICE_PROTOCOL_LAST, 0 },
};
static const u8 dummy_udp_tun_tcp_packet[] = {
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, 0x5a, /* ICE_IPV4_OFOS 14 */
0x00, 0x01, 0x00, 0x00,
0x40, 0x11, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
0x00, 0x46, 0x00, 0x00,
0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x08, 0x00,
0x45, 0x00, 0x00, 0x28, /* ICE_IPV4_IL 64 */
0x00, 0x01, 0x00, 0x00,
0x40, 0x06, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, /* ICE_TCP_IL 84 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x50, 0x02, 0x20, 0x00,
0x00, 0x00, 0x00, 0x00
};
static const struct ice_dummy_pkt_offsets dummy_udp_tun_udp_packet_offsets[] = {
{ ICE_MAC_OFOS, 0 },
{ ICE_ETYPE_OL, 12 },
{ ICE_IPV4_OFOS, 14 },
{ ICE_UDP_OF, 34 },
{ ICE_VXLAN, 42 },
{ ICE_GENEVE, 42 },
{ ICE_VXLAN_GPE, 42 },
{ ICE_MAC_IL, 50 },
{ ICE_IPV4_IL, 64 },
{ ICE_UDP_ILOS, 84 },
{ ICE_PROTOCOL_LAST, 0 },
};
static const u8 dummy_udp_tun_udp_packet[] = {
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, 0x4e, /* ICE_IPV4_OFOS 14 */
0x00, 0x01, 0x00, 0x00,
0x00, 0x11, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x12, 0xb5, /* ICE_UDP_OF 34 */
0x00, 0x3a, 0x00, 0x00,
0x00, 0x00, 0x65, 0x58, /* ICE_VXLAN 42 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, /* ICE_MAC_IL 50 */
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x08, 0x00,
0x45, 0x00, 0x00, 0x1c, /* ICE_IPV4_IL 64 */
0x00, 0x01, 0x00, 0x00,
0x00, 0x11, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, /* ICE_UDP_ILOS 84 */
0x00, 0x08, 0x00, 0x00,
};
/* offset info for MAC + IPv4 + UDP dummy packet */ /* offset info for MAC + IPv4 + UDP dummy packet */
static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = { static const struct ice_dummy_pkt_offsets dummy_udp_packet_offsets[] = {
{ ICE_MAC_OFOS, 0 }, { ICE_MAC_OFOS, 0 },
...@@ -3582,6 +3681,8 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = { ...@@ -3582,6 +3681,8 @@ static const struct ice_prot_ext_tbl_entry ice_prot_ext[ICE_PROTOCOL_LAST] = {
{ ICE_TCP_IL, { 0, 2 } }, { ICE_TCP_IL, { 0, 2 } },
{ ICE_UDP_OF, { 0, 2 } }, { ICE_UDP_OF, { 0, 2 } },
{ ICE_UDP_ILOS, { 0, 2 } }, { ICE_UDP_ILOS, { 0, 2 } },
{ ICE_VXLAN, { 8, 10, 12, 14 } },
{ ICE_GENEVE, { 8, 10, 12, 14 } },
}; };
static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
...@@ -3596,6 +3697,8 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = { ...@@ -3596,6 +3697,8 @@ static struct ice_protocol_entry ice_prot_id_tbl[ICE_PROTOCOL_LAST] = {
{ ICE_TCP_IL, ICE_TCP_IL_HW }, { ICE_TCP_IL, ICE_TCP_IL_HW },
{ ICE_UDP_OF, ICE_UDP_OF_HW }, { ICE_UDP_OF, ICE_UDP_OF_HW },
{ ICE_UDP_ILOS, ICE_UDP_ILOS_HW }, { ICE_UDP_ILOS, ICE_UDP_ILOS_HW },
{ ICE_VXLAN, ICE_UDP_OF_HW },
{ ICE_GENEVE, ICE_UDP_OF_HW },
}; };
/** /**
...@@ -3915,12 +4018,11 @@ ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles, ...@@ -3915,12 +4018,11 @@ ice_find_free_recp_res_idx(struct ice_hw *hw, const unsigned long *profiles,
* ice_add_sw_recipe - function to call AQ calls to create switch recipe * ice_add_sw_recipe - function to call AQ calls to create switch recipe
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
* @rm: recipe management list entry * @rm: recipe management list entry
* @match_tun_mask: tunnel mask that needs to be programmed
* @profiles: bitmap of profiles that will be associated. * @profiles: bitmap of profiles that will be associated.
*/ */
static enum ice_status static enum ice_status
ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
u16 match_tun_mask, unsigned long *profiles) unsigned long *profiles)
{ {
DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS); DECLARE_BITMAP(result_idx_bm, ICE_MAX_FV_WORDS);
struct ice_aqc_recipe_data_elem *tmp; struct ice_aqc_recipe_data_elem *tmp;
...@@ -4128,15 +4230,6 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, ...@@ -4128,15 +4230,6 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
} }
buf[recps].content.act_ctrl_fwd_priority = rm->priority; buf[recps].content.act_ctrl_fwd_priority = rm->priority;
/* To differentiate among different UDP tunnels, a meta data ID
* flag is used.
*/
if (match_tun_mask) {
buf[recps].content.lkup_indx[i] = ICE_TUN_FLAG_FV_IND;
buf[recps].content.mask[i] =
cpu_to_le16(match_tun_mask);
}
recps++; recps++;
rm->root_rid = (u8)rid; rm->root_rid = (u8)rid;
} }
...@@ -4199,6 +4292,7 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm, ...@@ -4199,6 +4292,7 @@ ice_add_sw_recipe(struct ice_hw *hw, struct ice_sw_recipe *rm,
recp->chain_idx = entry->chain_idx; recp->chain_idx = entry->chain_idx;
recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority; recp->priority = buf[buf_idx].content.act_ctrl_fwd_priority;
recp->n_grp_count = rm->n_grp_count; recp->n_grp_count = rm->n_grp_count;
recp->tun_type = rm->tun_type;
recp->recp_created = true; recp->recp_created = true;
} }
rm->root_buf = buf; rm->root_buf = buf;
...@@ -4279,6 +4373,54 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, ...@@ -4279,6 +4373,54 @@ ice_get_fv(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
return status; return status;
} }
/**
* ice_tun_type_match_word - determine if tun type needs a match mask
* @tun_type: tunnel type
* @mask: mask to be used for the tunnel
*/
static bool ice_tun_type_match_word(enum ice_sw_tunnel_type tun_type, u16 *mask)
{
switch (tun_type) {
case ICE_SW_TUN_GENEVE:
case ICE_SW_TUN_VXLAN:
*mask = ICE_TUN_FLAG_MASK;
return true;
default:
*mask = 0;
return false;
}
}
/**
* ice_add_special_words - Add words that are not protocols, such as metadata
* @rinfo: other information regarding the rule e.g. priority and action info
* @lkup_exts: lookup word structure
*/
static enum ice_status
ice_add_special_words(struct ice_adv_rule_info *rinfo,
struct ice_prot_lkup_ext *lkup_exts)
{
u16 mask;
/* If this is a tunneled packet, then add recipe index to match the
* tunnel bit in the packet metadata flags.
*/
if (ice_tun_type_match_word(rinfo->tun_type, &mask)) {
if (lkup_exts->n_val_words < ICE_MAX_CHAIN_WORDS) {
u8 word = lkup_exts->n_val_words++;
lkup_exts->fv_words[word].prot_id = ICE_META_DATA_ID_HW;
lkup_exts->fv_words[word].off = ICE_TUN_FLAG_MDID_OFF;
lkup_exts->field_mask[word] = mask;
} else {
return ICE_ERR_MAX_LIMIT;
}
}
return 0;
}
/* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule /* ice_get_compat_fv_bitmap - Get compatible field vector bitmap for rule
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
* @rinfo: other information regarding the rule e.g. priority and action info * @rinfo: other information regarding the rule e.g. priority and action info
...@@ -4288,9 +4430,27 @@ static void ...@@ -4288,9 +4430,27 @@ static void
ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo, ice_get_compat_fv_bitmap(struct ice_hw *hw, struct ice_adv_rule_info *rinfo,
unsigned long *bm) unsigned long *bm)
{ {
enum ice_prof_type prof_type;
bitmap_zero(bm, ICE_MAX_NUM_PROFILES); bitmap_zero(bm, ICE_MAX_NUM_PROFILES);
ice_get_sw_fv_bitmap(hw, ICE_PROF_NON_TUN, bm); switch (rinfo->tun_type) {
case ICE_NON_TUN:
prof_type = ICE_PROF_NON_TUN;
break;
case ICE_ALL_TUNNELS:
prof_type = ICE_PROF_TUN_ALL;
break;
case ICE_SW_TUN_GENEVE:
case ICE_SW_TUN_VXLAN:
prof_type = ICE_PROF_TUN_UDP;
break;
default:
prof_type = ICE_PROF_ALL;
break;
}
ice_get_sw_fv_bitmap(hw, prof_type, bm);
} }
/** /**
...@@ -4315,7 +4475,6 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4315,7 +4475,6 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
struct ice_sw_fv_list_entry *tmp; struct ice_sw_fv_list_entry *tmp;
enum ice_status status = 0; enum ice_status status = 0;
struct ice_sw_recipe *rm; struct ice_sw_recipe *rm;
u16 match_tun_mask = 0;
u8 i; u8 i;
if (!lkups_cnt) if (!lkups_cnt)
...@@ -4365,6 +4524,13 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4365,6 +4524,13 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
if (status) if (status)
goto err_unroll; goto err_unroll;
/* Create any special protocol/offset pairs, such as looking at tunnel
* bits by extracting metadata
*/
status = ice_add_special_words(rinfo, lkup_exts);
if (status)
goto err_free_lkup_exts;
/* Group match words into recipes using preferred recipe grouping /* Group match words into recipes using preferred recipe grouping
* criteria. * criteria.
*/ */
...@@ -4396,7 +4562,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4396,7 +4562,7 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
goto err_unroll; goto err_unroll;
/* Recipe we need does not exist, add a recipe */ /* Recipe we need does not exist, add a recipe */
status = ice_add_sw_recipe(hw, rm, match_tun_mask, profiles); status = ice_add_sw_recipe(hw, rm, profiles);
if (status) if (status)
goto err_unroll; goto err_unroll;
...@@ -4466,12 +4632,14 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4466,12 +4632,14 @@ ice_add_adv_recipe(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
* @lkups: lookup elements or match criteria for the advanced recipe, one * @lkups: lookup elements or match criteria for the advanced recipe, one
* structure per protocol header * structure per protocol header
* @lkups_cnt: number of protocols * @lkups_cnt: number of protocols
* @tun_type: tunnel type
* @pkt: dummy packet to fill according to filter match criteria * @pkt: dummy packet to fill according to filter match criteria
* @pkt_len: packet length of dummy packet * @pkt_len: packet length of dummy packet
* @offsets: pointer to receive the pointer to the offsets for the packet * @offsets: pointer to receive the pointer to the offsets for the packet
*/ */
static void static void
ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
enum ice_sw_tunnel_type tun_type,
const u8 **pkt, u16 *pkt_len, const u8 **pkt, u16 *pkt_len,
const struct ice_dummy_pkt_offsets **offsets) const struct ice_dummy_pkt_offsets **offsets)
{ {
...@@ -4495,6 +4663,21 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, ...@@ -4495,6 +4663,21 @@ ice_find_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
ipv6 = true; ipv6 = true;
} }
if (tun_type == ICE_SW_TUN_VXLAN ||
tun_type == ICE_SW_TUN_GENEVE) {
if (tcp) {
*pkt = dummy_udp_tun_tcp_packet;
*pkt_len = sizeof(dummy_udp_tun_tcp_packet);
*offsets = dummy_udp_tun_tcp_packet_offsets;
return;
}
*pkt = dummy_udp_tun_udp_packet;
*pkt_len = sizeof(dummy_udp_tun_udp_packet);
*offsets = dummy_udp_tun_udp_packet_offsets;
return;
}
if (udp && !ipv6) { if (udp && !ipv6) {
if (vlan) { if (vlan) {
*pkt = dummy_vlan_udp_packet; *pkt = dummy_vlan_udp_packet;
...@@ -4615,6 +4798,10 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, ...@@ -4615,6 +4798,10 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
case ICE_SCTP_IL: case ICE_SCTP_IL:
len = sizeof(struct ice_sctp_hdr); len = sizeof(struct ice_sctp_hdr);
break; break;
case ICE_VXLAN:
case ICE_GENEVE:
len = sizeof(struct ice_udp_tnl_hdr);
break;
default: default:
return ICE_ERR_PARAM; return ICE_ERR_PARAM;
} }
...@@ -4644,6 +4831,48 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt, ...@@ -4644,6 +4831,48 @@ ice_fill_adv_dummy_packet(struct ice_adv_lkup_elem *lkups, u16 lkups_cnt,
return 0; return 0;
} }
/**
* ice_fill_adv_packet_tun - fill dummy packet with udp tunnel port
* @hw: pointer to the hardware structure
* @tun_type: tunnel type
* @pkt: dummy packet to fill in
* @offsets: offset info for the dummy packet
*/
static enum ice_status
ice_fill_adv_packet_tun(struct ice_hw *hw, enum ice_sw_tunnel_type tun_type,
u8 *pkt, const struct ice_dummy_pkt_offsets *offsets)
{
u16 open_port, i;
switch (tun_type) {
case ICE_SW_TUN_VXLAN:
case ICE_SW_TUN_GENEVE:
if (!ice_get_open_tunnel_port(hw, &open_port))
return ICE_ERR_CFG;
break;
default:
/* Nothing needs to be done for this tunnel type */
return 0;
}
/* Find the outer UDP protocol header and insert the port number */
for (i = 0; offsets[i].type != ICE_PROTOCOL_LAST; i++) {
if (offsets[i].type == ICE_UDP_OF) {
struct ice_l4_hdr *hdr;
u16 offset;
offset = offsets[i].offset;
hdr = (struct ice_l4_hdr *)&pkt[offset];
hdr->dst_port = cpu_to_be16(open_port);
return 0;
}
}
return ICE_ERR_CFG;
}
/** /**
* ice_find_adv_rule_entry - Search a rule entry * ice_find_adv_rule_entry - Search a rule entry
* @hw: pointer to the hardware structure * @hw: pointer to the hardware structure
...@@ -4678,6 +4907,7 @@ ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4678,6 +4907,7 @@ ice_find_adv_rule_entry(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
break; break;
} }
if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag && if (rinfo->sw_act.flag == list_itr->rule_info.sw_act.flag &&
rinfo->tun_type == list_itr->rule_info.tun_type &&
lkups_matched) lkups_matched)
return list_itr; return list_itr;
} }
...@@ -4852,7 +5082,7 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4852,7 +5082,7 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
return ICE_ERR_PARAM; return ICE_ERR_PARAM;
/* make sure that we can locate a dummy packet */ /* make sure that we can locate a dummy packet */
ice_find_dummy_packet(lkups, lkups_cnt, &pkt, &pkt_len, ice_find_dummy_packet(lkups, lkups_cnt, rinfo->tun_type, &pkt, &pkt_len,
&pkt_offsets); &pkt_offsets);
if (!pkt) { if (!pkt) {
status = ICE_ERR_PARAM; status = ICE_ERR_PARAM;
...@@ -4963,6 +5193,14 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -4963,6 +5193,14 @@ ice_add_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
if (status) if (status)
goto err_ice_add_adv_rule; goto err_ice_add_adv_rule;
if (rinfo->tun_type != ICE_NON_TUN) {
status = ice_fill_adv_packet_tun(hw, rinfo->tun_type,
s_rule->pdata.lkup_tx_rx.hdr,
pkt_offsets);
if (status)
goto err_ice_add_adv_rule;
}
status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule, status = ice_aq_sw_rules(hw, (struct ice_aqc_sw_rules *)s_rule,
rule_buf_sz, 1, ice_aqc_opc_add_sw_rules, rule_buf_sz, 1, ice_aqc_opc_add_sw_rules,
NULL); NULL);
...@@ -5198,6 +5436,13 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups, ...@@ -5198,6 +5436,13 @@ ice_rem_adv_rule(struct ice_hw *hw, struct ice_adv_lkup_elem *lkups,
return ICE_ERR_CFG; return ICE_ERR_CFG;
} }
/* Create any special protocol/offset pairs, such as looking at tunnel
* bits by extracting metadata
*/
status = ice_add_special_words(rinfo, &lkup_exts);
if (status)
return status;
rid = ice_find_recp(hw, &lkup_exts); rid = ice_find_recp(hw, &lkup_exts);
/* If did not find a recipe that match the existing criteria */ /* If did not find a recipe that match the existing criteria */
if (rid == ICE_MAX_NUM_RECIPES) if (rid == ICE_MAX_NUM_RECIPES)
......
...@@ -212,6 +212,8 @@ struct ice_sw_recipe { ...@@ -212,6 +212,8 @@ struct ice_sw_recipe {
/* Bit map specifying the IDs associated with this group of recipe */ /* Bit map specifying the IDs associated with this group of recipe */
DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES); DECLARE_BITMAP(r_bitmap, ICE_MAX_NUM_RECIPES);
enum ice_sw_tunnel_type tun_type;
/* List of type ice_fltr_mgmt_list_entry or adv_rule */ /* List of type ice_fltr_mgmt_list_entry or adv_rule */
u8 adv_rule; u8 adv_rule;
struct list_head filt_rules; struct list_head filt_rules;
......
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