[ovs-dev] [PATCH OvS 4/4] ovs-tc: offload MPLS set actions to TC datapath

John Hurley john.hurley at netronome.com
Tue Jul 30 11:05:17 UTC 2019


Recent modifications to TC allows the modifying of fields within the
outermost MPLS header of a packet. OvS datapath rules impliment an MPLS
set action by supplying a new MPLS header that should overwrite the
current one.

Convert the OvS datapath MPLS set action to a TC modify action and allow
such rules to be offloaded to a TC datapath.

Signed-off-by: John Hurley <john.hurley at netronome.com>
Reviewed-by: Simon Horman <simon.horman at netronome.com>
---
 lib/netdev-offload-tc.c | 37 +++++++++++++++++++++++++++++++++++++
 lib/tc.c                | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
 lib/tc.h                |  1 +
 3 files changed, 86 insertions(+)

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 03610d8..6814390 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -665,6 +665,23 @@ parse_tc_flower_to_match(struct tc_flower *flower,
                 push->mpls_lse = mpls_lse;
             }
             break;
+            case TC_ACT_MPLS_SET: {
+                size_t set_offset = nl_msg_start_nested(buf,
+                                                        OVS_ACTION_ATTR_SET);
+                struct ovs_key_mpls *set_mpls;
+                ovs_be32 mpls_lse = 0;
+
+                flow_set_mpls_lse_label(&mpls_lse, action->mpls.label);
+                flow_set_mpls_lse_tc(&mpls_lse, action->mpls.tc);
+                flow_set_mpls_lse_ttl(&mpls_lse, action->mpls.ttl);
+                flow_set_mpls_lse_bos(&mpls_lse, action->mpls.bos);
+
+                set_mpls = nl_msg_put_unspec_zero(buf, OVS_KEY_ATTR_MPLS,
+                                                  sizeof *set_mpls);
+                set_mpls->mpls_lse = mpls_lse;
+                nl_msg_end_nested(buf, set_offset);
+            }
+            break;
             case TC_ACT_PEDIT: {
                 parse_flower_rewrite_to_netlink_action(buf, flower);
             }
@@ -790,6 +807,22 @@ netdev_tc_flow_dump_next(struct netdev_flow_dump *dump,
 }
 
 static int
+parse_mpls_set_action(struct tc_flower *flower, struct tc_action *action,
+                      const struct nlattr *set)
+{
+        const struct ovs_key_mpls *mpls_set = nl_attr_get(set);
+
+        action->mpls.label = mpls_lse_to_label(mpls_set->mpls_lse);
+        action->mpls.tc = mpls_lse_to_tc(mpls_set->mpls_lse);
+        action->mpls.ttl = mpls_lse_to_ttl(mpls_set->mpls_lse);
+        action->mpls.bos = mpls_lse_to_bos(mpls_set->mpls_lse);
+        action->type = TC_ACT_MPLS_SET;
+        flower->action_count++;
+
+        return 0;
+}
+
+static int
 parse_put_flow_set_masked_action(struct tc_flower *flower,
                                  struct tc_action *action,
                                  const struct nlattr *set,
@@ -870,6 +903,10 @@ parse_put_flow_set_action(struct tc_flower *flower, struct tc_action *action,
     const struct nlattr *tun_attr;
     size_t tun_left, tunnel_len;
 
+    if (nl_attr_type(set) == OVS_KEY_ATTR_MPLS) {
+        return parse_mpls_set_action(flower, action, set);
+    }
+
     if (nl_attr_type(set) != OVS_KEY_ATTR_TUNNEL) {
             return parse_put_flow_set_masked_action(flower, action, set,
                                                     set_len, false);
diff --git a/lib/tc.c b/lib/tc.c
index 71aa55c..316a0ee 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -1303,6 +1303,25 @@ nl_parse_act_mpls(struct nlattr *options, struct tc_flower *flower)
         }
         action->type = TC_ACT_MPLS_PUSH;
         break;
+    case TCA_MPLS_ACT_MODIFY:
+        mpls_label = mpls_attrs[TCA_MPLS_LABEL];
+        if (mpls_label) {
+            action->mpls.label = nl_attr_get_u32(mpls_label);
+        }
+        mpls_tc = mpls_attrs[TCA_MPLS_TC];
+        if (mpls_tc) {
+            action->mpls.tc = nl_attr_get_u8(mpls_tc);
+        }
+        mpls_ttl = mpls_attrs[TCA_MPLS_TTL];
+        if (mpls_ttl) {
+            action->mpls.ttl = nl_attr_get_u8(mpls_ttl);
+        }
+        mpls_bos = mpls_attrs[TCA_MPLS_BOS];
+        if (mpls_bos) {
+            action->mpls.bos = nl_attr_get_u8(mpls_bos);
+        }
+        action->type = TC_ACT_MPLS_SET;
+        break;
     default:
         VLOG_ERR_RL(&error_rl, "unknown mpls action: %d, %d",
                     m->action, m->m_action);
@@ -1765,6 +1784,27 @@ nl_msg_put_act_push_mpls(struct ofpbuf *request, ovs_be16 proto,
 }
 
 static void
+nl_msg_put_act_set_mpls(struct ofpbuf *request, uint32_t label, uint8_t tc,
+                        uint8_t ttl, uint8_t bos)
+{
+    size_t offset;
+
+    nl_msg_put_string(request, TCA_ACT_KIND, "mpls");
+    offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS | NLA_F_NESTED);
+    {
+        struct tc_mpls parm = { .action = TC_ACT_PIPE,
+                                .m_action = TCA_MPLS_ACT_MODIFY };
+
+        nl_msg_put_unspec(request, TCA_MPLS_PARMS, &parm, sizeof parm);
+        nl_msg_put_u32(request, TCA_MPLS_LABEL, label);
+        nl_msg_put_u8(request, TCA_MPLS_TC, tc);
+        nl_msg_put_u8(request, TCA_MPLS_TTL, ttl);
+        nl_msg_put_u8(request, TCA_MPLS_BOS, bos);
+    }
+    nl_msg_end_nested(request, offset);
+}
+
+static void
 nl_msg_put_act_tunnel_key_release(struct ofpbuf *request)
 {
     size_t offset;
@@ -2155,6 +2195,14 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct tc_flower *flower)
                 nl_msg_end_nested(request, act_offset);
             }
             break;
+            case TC_ACT_MPLS_SET: {
+                act_offset = nl_msg_start_nested(request, act_index++);
+                nl_msg_put_act_set_mpls(request, action->mpls.label,
+                                        action->mpls.tc, action->mpls.ttl,
+                                        action->mpls.bos);
+                nl_msg_end_nested(request, act_offset);
+            }
+            break;
             case TC_ACT_OUTPUT: {
                 ingress = action->out.ingress;
                 ifindex = action->out.ifindex_out;
diff --git a/lib/tc.h b/lib/tc.h
index a498a84..f421357 100644
--- a/lib/tc.h
+++ b/lib/tc.h
@@ -155,6 +155,7 @@ enum tc_action_type {
     TC_ACT_VLAN_PUSH,
     TC_ACT_MPLS_POP,
     TC_ACT_MPLS_PUSH,
+    TC_ACT_MPLS_SET,
 };
 
 struct tc_action {
-- 
2.7.4



More information about the dev mailing list