From: Gavin Li <gav...@nvidia.com> Kernels that do not support vxlan gbp would treat the rule that has vxlan gbp encap action or vxlan gbp id match differently, either reject it or just skip the action/match and continue processing the knowing ones.
To solve the issue, probe and disallow inserting rules with vxlan gbp action/match if kernel does not support it. Signed-off-by: Gavin Li <gav...@nvidia.com> Reviewed-by: Roi Dayan <r...@nvidia.com> Reviewed-by: Simon Horman <simon.hor...@corigine.com> Acked-by: Eelco Chaudron <echau...@redhat.com> --- lib/netdev-offload-tc.c | 64 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c index c43eacd4d94f..b846a63c222f 100644 --- a/lib/netdev-offload-tc.c +++ b/lib/netdev-offload-tc.c @@ -52,6 +52,7 @@ static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid); static bool multi_mask_per_prio = false; static bool block_support = false; static uint16_t ct_state_support; +static bool vxlan_gbp_support = false; struct netlink_field { int offset; @@ -668,14 +669,17 @@ static void parse_tc_flower_geneve_opts(struct tc_action *action, nl_msg_end_nested(buf, geneve_off); } -static void +static int parse_tc_flower_vxlan_tun_opts(struct tc_action *action, struct ofpbuf *buf) { size_t gbp_off; uint32_t gbp_raw; if (!action->encap.gbp.id_present) { - return; + return 0; + } + if (!vxlan_gbp_support) { + return -EOPNOTSUPP; } gbp_off = nl_msg_start_nested(buf, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS); @@ -683,6 +687,7 @@ parse_tc_flower_vxlan_tun_opts(struct tc_action *action, struct ofpbuf *buf) action->encap.gbp.id); nl_msg_put_u32(buf, OVS_VXLAN_EXT_GBP, gbp_raw); nl_msg_end_nested(buf, gbp_off); + return 0; } static void @@ -845,6 +850,7 @@ parse_tc_flower_to_actions__(struct tc_flower *flower, struct ofpbuf *buf, size_t set_offset = nl_msg_start_nested(buf, OVS_ACTION_ATTR_SET); size_t tunnel_offset = nl_msg_start_nested(buf, OVS_KEY_ATTR_TUNNEL); + int ret; if (action->encap.id_present) { nl_msg_put_be64(buf, OVS_TUNNEL_KEY_ATTR_ID, action->encap.id); @@ -880,7 +886,10 @@ parse_tc_flower_to_actions__(struct tc_flower *flower, struct ofpbuf *buf, if (!action->encap.no_csum) { nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_CSUM); } - parse_tc_flower_vxlan_tun_opts(action, buf); + ret = parse_tc_flower_vxlan_tun_opts(action, buf); + if (ret) { + return ret; + } parse_tc_flower_geneve_opts(action, buf); nl_msg_end_nested(buf, tunnel_offset); nl_msg_end_nested(buf, set_offset); @@ -1632,6 +1641,9 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action, } break; case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: { + if (!vxlan_gbp_support) { + return EOPNOTSUPP; + } if (odp_vxlan_tun_opts_from_attr(tun_attr, &action->encap.gbp.id, &action->encap.gbp.flags, @@ -2787,6 +2799,51 @@ probe_tc_block_support(int ifindex) } } +static void +probe_vxlan_gbp_support(int ifindex) +{ + struct tc_flower flower; + struct tcf_id id; + int block_id = 0; + int prio = 1; + int error; + + error = tc_add_del_qdisc(ifindex, true, block_id, TC_INGRESS); + if (error) { + return; + } + + memset(&flower, 0, sizeof flower); + + flower.tc_policy = TC_POLICY_SKIP_HW; + flower.key.eth_type = htons(ETH_P_IP); + flower.mask.eth_type = OVS_BE16_MAX; + flower.tunnel = true; + flower.mask.tunnel.id = OVS_BE64_MAX; + flower.mask.tunnel.ipv4.ipv4_src = OVS_BE32_MAX; + flower.mask.tunnel.ipv4.ipv4_dst = OVS_BE32_MAX; + flower.mask.tunnel.tp_dst = OVS_BE16_MAX; + flower.mask.tunnel.gbp.id = OVS_BE16_MAX; + flower.key.tunnel.ipv4.ipv4_src = htonl(0x01010101); + flower.key.tunnel.ipv4.ipv4_dst = htonl(0x01010102); + flower.key.tunnel.tp_dst = htons(46354); + flower.key.tunnel.gbp.id = htons(512); + + id = tc_make_tcf_id(ifindex, block_id, prio, TC_INGRESS); + error = tc_replace_flower(&id, &flower); + if (error) { + goto out; + } + + tc_del_flower_filter(&id); + + vxlan_gbp_support = true; + VLOG_INFO("probe tc: vxlan gbp is supported."); + +out: + tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS); +} + static int tc_get_policer_action_ids(struct hmap *map) { @@ -2914,6 +2971,7 @@ netdev_tc_init_flow_api(struct netdev *netdev) probe_multi_mask_per_prio(ifindex); probe_ct_state_support(ifindex); + probe_vxlan_gbp_support(ifindex); ovs_mutex_lock(&meter_police_ids_mutex); meter_police_ids = id_pool_create(METER_POLICE_IDS_BASE, -- 2.38.0 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev