From: Tianyu Yuan <[email protected]>

Support offload of OF meter action using TC police actions.
The TC police action instances are created when meters are configured
and referred to here, in TC flower classifiers (flows) that use meter actions,
by index.

Signed-off-by: Tianyu Yuan <[email protected]>
Signed-off-by: Simon Horman <[email protected]>
---
 lib/netdev-offload-tc.c |  4 ++++
 lib/tc.c                | 30 ++++++++++++++++++++++++++++++
 lib/tc.h                |  8 ++++++++
 3 files changed, 42 insertions(+)

diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
index 9845e8d3f..0387b9b2e 100644
--- a/lib/netdev-offload-tc.c
+++ b/lib/netdev-offload-tc.c
@@ -1917,6 +1917,10 @@ netdev_tc_flow_put(struct netdev *netdev, struct match 
*match,
             action->type = TC_ACT_GOTO;
             action->chain = 0;  /* 0 is reserved and not used by recirc. */
             flower.action_count++;
+        } else if (nl_attr_type(nla) == OVS_ACTION_ATTR_METER) {
+            action->type = TC_ACT_METER;
+            action->meter.meter_id = nl_attr_get_u32(nla);
+            flower.action_count++;
         } else {
             VLOG_DBG_RL(&rl, "unsupported put action type: %d",
                         nl_attr_type(nla));
diff --git a/lib/tc.c b/lib/tc.c
index 3d54cd28e..9fb7eba07 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -2403,6 +2403,30 @@ nl_msg_put_act_flags(struct ofpbuf *request) {
     nl_msg_put_unspec(request, TCA_ACT_FLAGS, &act_flags, sizeof act_flags);
 }
 
+void
+nl_msg_fill_police(struct ofpbuf *request, struct tc_police police,
+                   size_t *offset)
+{
+    nl_msg_put_string(request, TCA_ACT_KIND, "police");
+    *offset = nl_msg_start_nested(request, TCA_ACT_OPTIONS);
+    nl_msg_put_unspec(request, TCA_POLICE_TBF, &police, sizeof police);
+}
+
+static void
+nl_msg_put_act_meter(struct ofpbuf *request, uint32_t meter_id)
+{
+    struct tc_police tc_police;
+    int mtu = 65535;
+    size_t offset;
+
+    tc_police.action = TC_POLICE_SHOT;
+    tc_police.mtu = mtu;
+    tc_police.index = METER_ID_TO_POLICY_INDEX(meter_id);
+    nl_msg_fill_police(request, tc_police, &offset);
+    nl_msg_end_nested(request, offset);
+}
+
+
 /* Given flower, a key_to_pedit map entry, calculates the rest,
  * where:
  *
@@ -2719,6 +2743,12 @@ nl_msg_put_flower_acts(struct ofpbuf *request, struct 
tc_flower *flower)
                 nl_msg_end_nested(request, act_offset);
             }
             break;
+            case TC_ACT_METER: {
+                act_offset = nl_msg_start_nested(request,act_index++);
+                nl_msg_put_act_meter(request, action->meter.meter_id);
+                nl_msg_end_nested(request, act_offset);
+            }
+            break;
             }
         }
     }
diff --git a/lib/tc.h b/lib/tc.h
index 2408a0e92..6ba7f946c 100644
--- a/lib/tc.h
+++ b/lib/tc.h
@@ -90,6 +90,9 @@ struct tcmsg *tc_make_request(int ifindex, int type,
 int tc_transact(struct ofpbuf *request, struct ofpbuf **replyp);
 int tc_add_del_qdisc(int ifindex, bool add, uint32_t block_id,
                      enum tc_qdisc_hook hook);
+void
+nl_msg_fill_police(struct ofpbuf *request, struct tc_police police,
+                   size_t *offset);
 
 struct tc_cookie {
     const void *data;
@@ -181,6 +184,7 @@ enum tc_action_type {
     TC_ACT_MPLS_SET,
     TC_ACT_GOTO,
     TC_ACT_CT,
+    TC_ACT_METER,
 };
 
 enum nat_type {
@@ -263,6 +267,10 @@ struct tc_action {
             bool force;
             bool commit;
         } ct;
+
+        struct {
+            uint32_t meter_id;
+        } meter;
      };
 
      enum tc_action_type type;
-- 
2.20.1

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to