diff mbox series

[ovs-dev,PATCH/RFC,2/7] netdev-offload-tc: support offload of meter action

Message ID 20211110162858.20101-3-simon.horman@corigine.com
State RFC
Headers show
Series Allow offload of OpenFlow Meters via TC | expand

Commit Message

Simon Horman Nov. 10, 2021, 4:28 p.m. UTC
From: Tianyu Yuan <tianyu.yuan@corigine.com>

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 <tianyu.yuan@corigine.com>
Signed-off-by: Simon Horman <simon.horman@corigine.com>
---
 lib/netdev-offload-tc.c |  4 ++++
 lib/tc.c                | 30 ++++++++++++++++++++++++++++++
 lib/tc.h                |  8 ++++++++
 3 files changed, 42 insertions(+)
diff mbox series

Patch

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;