@@ -193,10 +193,10 @@ AC_DEFUN([OVS_CHECK_LINUX_TC], [
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([#include <linux/tc_act/tc_tunnel_key.h>], [
- int x = TCA_TUNNEL_KEY_ENC_OPTS_VXLAN;
+ int x = TCA_TUNNEL_KEY_NO_FRAG;
])],
- [AC_DEFINE([HAVE_TCA_TUNNEL_KEY_ENC_OPTS_VXLAN], [1],
- [Define to 1 if TCA_TUNNEL_KEY_ENC_OPTS_VXLAN is available.])])
+ [AC_DEFINE([HAVE_TCA_TUNNEL_KEY_NO_FRAG], [1],
+ [Define to 1 if TCA_TUNNEL_KEY_NO_FRAG is available.])])
AC_COMPILE_IFELSE([
AC_LANG_PROGRAM([#include <linux/tc_act/tc_pedit.h>], [
@@ -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_OPTS_VXLAN)
+#if defined(__KERNEL__) || defined(HAVE_TCA_TUNNEL_KEY_NO_FRAG)
#include_next <linux/tc_act/tc_tunnel_key.h>
#else
@@ -42,6 +42,7 @@ enum {
*/
TCA_TUNNEL_KEY_ENC_TOS, /* u8 */
TCA_TUNNEL_KEY_ENC_TTL, /* u8 */
+ TCA_TUNNEL_KEY_NO_FRAG, /* flag */
__TCA_TUNNEL_KEY_MAX,
};
@@ -919,6 +919,9 @@ 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);
}
+ if (action->encap.dont_fragment) {
+ nl_msg_put_flag(buf, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT);
+ }
ret = parse_tc_flower_vxlan_tun_opts(action, buf);
if (ret) {
return ret;
@@ -1641,11 +1644,14 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
}
break;
case OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT: {
- /* XXX: This is wrong! We're ignoring the DF flag configuration
- * requested by the user. However, TC for now has no way to pass
- * that flag and it is set by default, meaning tunnel offloading
- * will not work if 'options:df_default=false' is not set.
- * Keeping incorrect behavior for now. */
+ if (enc_flags_support) {
+ action->encap.dont_fragment = true;
+ } else {
+ /* For kernels not supporting the DF flag, we ignoring the
+ * configuration requested by the user. This to keep the old,
+ * incorrect behaviour, and allow tunnels to be offloaded by
+ * TC with these kernels. */
+ }
}
break;
case OVS_TUNNEL_KEY_ATTR_CSUM: {
@@ -1229,6 +1229,7 @@ static const struct nl_policy tunnel_key_policy[] = {
[TCA_TUNNEL_KEY_ENC_TTL] = { .type = NL_A_U8, .optional = true, },
[TCA_TUNNEL_KEY_ENC_OPTS] = { .type = NL_A_NESTED, .optional = true, },
[TCA_TUNNEL_KEY_NO_CSUM] = { .type = NL_A_U8, .optional = true, },
+ [TCA_TUNNEL_KEY_NO_FRAG] = { .type = NL_A_FLAG, .optional = true, },
};
static int
@@ -1394,6 +1395,7 @@ nl_parse_act_tunnel_key(struct nlattr *options, struct tc_flower *flower)
struct nlattr *ttl = tun_attrs[TCA_TUNNEL_KEY_ENC_TTL];
struct nlattr *tun_opt = tun_attrs[TCA_TUNNEL_KEY_ENC_OPTS];
struct nlattr *no_csum = tun_attrs[TCA_TUNNEL_KEY_NO_CSUM];
+ struct nlattr *no_frag = tun_attrs[TCA_TUNNEL_KEY_NO_FRAG];
action = &flower->actions[flower->action_count++];
action->type = TC_ACT_ENCAP;
@@ -1411,6 +1413,7 @@ nl_parse_act_tunnel_key(struct nlattr *options, struct tc_flower *flower)
action->encap.tos = tos ? nl_attr_get_u8(tos) : 0;
action->encap.ttl = ttl ? nl_attr_get_u8(ttl) : 0;
action->encap.no_csum = no_csum ? nl_attr_get_u8(no_csum) : 0;
+ action->encap.dont_fragment = no_frag ? true : false;
err = nl_parse_act_tunnel_opts(tun_opt, action);
if (err) {
@@ -2747,6 +2750,9 @@ nl_msg_put_act_tunnel_key_set(struct ofpbuf *request,
nl_msg_put_be16(request, TCA_TUNNEL_KEY_ENC_DST_PORT,
encap->tp_dst);
}
+ if (encap->dont_fragment) {
+ nl_msg_put_flag(request, TCA_TUNNEL_KEY_NO_FRAG);
+ }
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);
@@ -229,6 +229,7 @@ struct tc_action_encap {
uint8_t tos;
uint8_t ttl;
uint8_t no_csum;
+ bool dont_fragment;
struct {
ovs_be32 ipv4_src;
ovs_be32 ipv4_dst;