mirror of
https://github.com/openvswitch/ovs
synced 2025-08-22 01:51:26 +00:00
tc: Add vxlan encap action with gbp option offload.
Add TC offload support for vxlan encap with gbp option. Reviewed-by: Gavi Teitz <gavi@nvidia.com> Reviewed-by: Roi Dayan <roid@nvidia.com> Reviewed-by: Simon Horman <simon.horman@corigine.com> Signed-off-by: Gavin Li <gavinl@nvidia.com> Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
This commit is contained in:
parent
256c1e5819
commit
a2a3f1983f
2
NEWS
2
NEWS
@ -44,6 +44,8 @@ Post-v3.1.0
|
||||
* IP and L4 checksum offload support is now enabled by default for
|
||||
interfaces that support it. See the 'status' column in the 'interface'
|
||||
table to check the status.
|
||||
- Linux TC offload:
|
||||
* Add support for offloading VXLAN tunnels with the GBP extensions.
|
||||
|
||||
|
||||
v3.1.0 - 16 Feb 2023
|
||||
|
@ -191,6 +191,13 @@ AC_DEFUN([OVS_CHECK_LINUX_TC], [
|
||||
[AC_DEFINE([HAVE_TCA_TUNNEL_KEY_ENC_TTL], [1],
|
||||
[Define to 1 if TCA_TUNNEL_KEY_ENC_TTL is available.])])
|
||||
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([#include <linux/tc_act/tc_tunnel_key.h>], [
|
||||
int x = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN;
|
||||
])],
|
||||
[AC_DEFINE([HAVE_TCA_TUNNEL_KEY_ENC_OPTS_VXLAN], [1],
|
||||
[Define to 1 if TCA_TUNNEL_KEY_ENC_OPTS_VXLAN is available.])])
|
||||
|
||||
AC_COMPILE_IFELSE([
|
||||
AC_LANG_PROGRAM([#include <linux/tc_act/tc_pedit.h>], [
|
||||
int x = TCA_PEDIT_KEY_EX_HDR_TYPE_UDP;
|
||||
|
@ -1,7 +1,7 @@
|
||||
#ifndef __LINUX_TC_ACT_TC_TUNNEL_KEY_WRAPPER_H
|
||||
#define __LINUX_TC_ACT_TC_TUNNEL_KEY_WRAPPER_H 1
|
||||
|
||||
#if defined(__KERNEL__) || defined(HAVE_TCA_TUNNEL_KEY_ENC_TTL)
|
||||
#if defined(__KERNEL__) || defined(HAVE_TCA_TUNNEL_KEY_ENC_OPTS_VXLAN)
|
||||
#include_next <linux/tc_act/tc_tunnel_key.h>
|
||||
#else
|
||||
|
||||
@ -53,6 +53,10 @@ enum {
|
||||
* TCA_TUNNEL_KEY_ENC_OPTS_GENEVE
|
||||
* attributes
|
||||
*/
|
||||
TCA_TUNNEL_KEY_ENC_OPTS_VXLAN, /* Nested
|
||||
* TCA_TUNNEL_KEY_ENC_OPTS_VXLAN
|
||||
* attributes
|
||||
*/
|
||||
__TCA_TUNNEL_KEY_ENC_OPTS_MAX,
|
||||
};
|
||||
|
||||
@ -70,6 +74,15 @@ enum {
|
||||
#define TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX \
|
||||
(__TCA_TUNNEL_KEY_ENC_OPT_GENEVE_MAX - 1)
|
||||
|
||||
#endif /* __KERNEL__ || HAVE_TCA_TUNNEL_KEY_ENC_TTL */
|
||||
enum {
|
||||
TCA_TUNNEL_KEY_ENC_OPT_VXLAN_UNSPEC,
|
||||
TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, /* u32 */
|
||||
__TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX,
|
||||
};
|
||||
|
||||
#define TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX \
|
||||
(__TCA_TUNNEL_KEY_ENC_OPT_VXLAN_MAX - 1)
|
||||
|
||||
#endif /* __KERNEL__ || HAVE_TCA_TUNNEL_KEY_ENC_OPTS_VXLAN */
|
||||
|
||||
#endif /* __LINUX_TC_ACT_TC_TUNNEL_KEY_WRAPPER_H */
|
||||
|
@ -668,6 +668,23 @@ static void parse_tc_flower_geneve_opts(struct tc_action *action,
|
||||
nl_msg_end_nested(buf, geneve_off);
|
||||
}
|
||||
|
||||
static void
|
||||
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;
|
||||
}
|
||||
|
||||
gbp_off = nl_msg_start_nested(buf, OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS);
|
||||
gbp_raw = odp_encode_gbp_raw(action->encap.gbp.flags,
|
||||
action->encap.gbp.id);
|
||||
nl_msg_put_u32(buf, OVS_VXLAN_EXT_GBP, gbp_raw);
|
||||
nl_msg_end_nested(buf, gbp_off);
|
||||
}
|
||||
|
||||
static void
|
||||
flower_tun_opt_to_match(struct match *match, struct tc_flower *flower)
|
||||
{
|
||||
@ -863,7 +880,7 @@ 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);
|
||||
parse_tc_flower_geneve_opts(action, buf);
|
||||
nl_msg_end_nested(buf, tunnel_offset);
|
||||
nl_msg_end_nested(buf, set_offset);
|
||||
@ -1552,6 +1569,7 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
|
||||
|
||||
action->type = TC_ACT_ENCAP;
|
||||
action->encap.id_present = false;
|
||||
action->encap.gbp.id_present = false;
|
||||
action->encap.no_csum = 1;
|
||||
flower->action_count++;
|
||||
NL_ATTR_FOR_EACH_UNSAFE(tun_attr, tun_left, tunnel, tunnel_len) {
|
||||
@ -1613,6 +1631,16 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
|
||||
action->encap.data.present.len = nl_attr_get_size(tun_attr);
|
||||
}
|
||||
break;
|
||||
case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
|
||||
if (odp_vxlan_tun_opts_from_attr(tun_attr,
|
||||
&action->encap.gbp.id,
|
||||
&action->encap.gbp.flags,
|
||||
&action->encap.gbp.id_present)) {
|
||||
VLOG_ERR_RL(&rl, "error parsing VXLAN options");
|
||||
return EINVAL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
VLOG_DBG_RL(&rl, "unsupported tunnel key attribute %d",
|
||||
nl_attr_type(tun_attr));
|
||||
|
@ -3149,22 +3149,12 @@ odp_tun_key_from_attr__(const struct nlattr *attr, bool is_mask,
|
||||
tun->flags |= FLOW_TNL_F_OAM;
|
||||
break;
|
||||
case OVS_TUNNEL_KEY_ATTR_VXLAN_OPTS: {
|
||||
static const struct nl_policy vxlan_opts_policy[] = {
|
||||
[OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 },
|
||||
};
|
||||
struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)];
|
||||
|
||||
if (!nl_parse_nested(a, vxlan_opts_policy, ext, ARRAY_SIZE(ext))) {
|
||||
if (odp_vxlan_tun_opts_from_attr(a, &tun->gbp_id,
|
||||
&tun->gbp_flags,
|
||||
NULL)) {
|
||||
odp_parse_error(&rl, errorp, "error parsing VXLAN options");
|
||||
return ODP_FIT_ERROR;
|
||||
}
|
||||
|
||||
if (ext[OVS_VXLAN_EXT_GBP]) {
|
||||
uint32_t gbp = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GBP]);
|
||||
|
||||
odp_decode_gbp_raw(gbp, &tun->gbp_id, &tun->gbp_flags);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case OVS_TUNNEL_KEY_ATTR_GENEVE_OPTS:
|
||||
@ -8844,3 +8834,29 @@ commit_odp_actions(const struct flow *flow, struct flow *base,
|
||||
|
||||
return slow1 ? slow1 : slow2;
|
||||
}
|
||||
|
||||
int
|
||||
odp_vxlan_tun_opts_from_attr(const struct nlattr *tun_attr, ovs_be16 *id,
|
||||
uint8_t *flags, bool *id_present)
|
||||
{
|
||||
static const struct nl_policy vxlan_opts_policy[] = {
|
||||
[OVS_VXLAN_EXT_GBP] = { .type = NL_A_U32 },
|
||||
};
|
||||
struct nlattr *ext[ARRAY_SIZE(vxlan_opts_policy)];
|
||||
|
||||
if (!nl_parse_nested(tun_attr, vxlan_opts_policy, ext, ARRAY_SIZE(ext))) {
|
||||
return EINVAL;
|
||||
}
|
||||
|
||||
if (ext[OVS_VXLAN_EXT_GBP]) {
|
||||
uint32_t gbp_raw = nl_attr_get_u32(ext[OVS_VXLAN_EXT_GBP]);
|
||||
|
||||
odp_decode_gbp_raw(gbp_raw, id, flags);
|
||||
}
|
||||
|
||||
if (id_present) {
|
||||
*id_present = !!ext[OVS_VXLAN_EXT_GBP];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -292,6 +292,9 @@ enum slow_path_reason commit_odp_actions(const struct flow *,
|
||||
bool pending_decap,
|
||||
struct ofpbuf *encap_data);
|
||||
|
||||
int odp_vxlan_tun_opts_from_attr(const struct nlattr *tun_attr, ovs_be16 *id,
|
||||
uint8_t *flags, bool *id_present);
|
||||
|
||||
/* ofproto-dpif interface.
|
||||
*
|
||||
* The following types and functions are logically part of ofproto-dpif.
|
||||
|
58
lib/tc.c
58
lib/tc.c
@ -1290,6 +1290,35 @@ nl_parse_act_geneve_opts(const struct nlattr *in_nlattr,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nl_parse_act_vxlan_opts(struct nlattr *in_nlattr, struct tc_action *action)
|
||||
{
|
||||
const struct ofpbuf *msg;
|
||||
struct nlattr *nla;
|
||||
struct ofpbuf buf;
|
||||
size_t left;
|
||||
|
||||
nl_attr_get_nested(in_nlattr, &buf);
|
||||
msg = &buf;
|
||||
|
||||
NL_ATTR_FOR_EACH (nla, left, ofpbuf_at(msg, 0, 0), msg->size) {
|
||||
uint16_t type = nl_attr_type(nla);
|
||||
int32_t gbp_raw;
|
||||
|
||||
switch (type) {
|
||||
case TCA_FLOWER_KEY_ENC_OPT_VXLAN_GBP:
|
||||
gbp_raw = nl_attr_get_u32(nla);
|
||||
odp_decode_gbp_raw(gbp_raw, &action->encap.gbp.id,
|
||||
&action->encap.gbp.flags);
|
||||
action->encap.gbp.id_present = true;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nl_parse_act_tunnel_opts(struct nlattr *options, struct tc_action *action)
|
||||
{
|
||||
@ -1314,7 +1343,12 @@ nl_parse_act_tunnel_opts(struct nlattr *options, struct tc_action *action)
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
|
||||
break;
|
||||
case TCA_TUNNEL_KEY_ENC_OPTS_VXLAN:
|
||||
err = nl_parse_act_vxlan_opts(nla, action);
|
||||
if (err) {
|
||||
return err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -2640,6 +2674,27 @@ nl_msg_put_act_tunnel_geneve_option(struct ofpbuf *request,
|
||||
nl_msg_end_nested(request, outer);
|
||||
}
|
||||
|
||||
static void
|
||||
nl_msg_put_act_tunnel_vxlan_opts(struct ofpbuf *request,
|
||||
struct tc_action_encap *encap)
|
||||
{
|
||||
size_t outer, inner;
|
||||
uint32_t gbp_raw;
|
||||
|
||||
if (!encap->gbp.id_present) {
|
||||
return;
|
||||
}
|
||||
|
||||
gbp_raw = odp_encode_gbp_raw(encap->gbp.flags,
|
||||
encap->gbp.id);
|
||||
outer = nl_msg_start_nested_with_flag(request, TCA_TUNNEL_KEY_ENC_OPTS);
|
||||
inner = nl_msg_start_nested_with_flag(request,
|
||||
TCA_TUNNEL_KEY_ENC_OPTS_VXLAN);
|
||||
nl_msg_put_u32(request, TCA_TUNNEL_KEY_ENC_OPT_VXLAN_GBP, gbp_raw);
|
||||
nl_msg_end_nested(request, inner);
|
||||
nl_msg_end_nested(request, outer);
|
||||
}
|
||||
|
||||
static void
|
||||
nl_msg_put_act_tunnel_key_set(struct ofpbuf *request,
|
||||
struct tc_action_encap *encap,
|
||||
@ -2680,6 +2735,7 @@ nl_msg_put_act_tunnel_key_set(struct ofpbuf *request,
|
||||
nl_msg_put_be16(request, TCA_TUNNEL_KEY_ENC_DST_PORT,
|
||||
encap->tp_dst);
|
||||
}
|
||||
nl_msg_put_act_tunnel_vxlan_opts(request, encap);
|
||||
nl_msg_put_act_tunnel_geneve_option(request, &encap->data);
|
||||
nl_msg_put_u8(request, TCA_TUNNEL_KEY_NO_CSUM, encap->no_csum);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user