@@ -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));
@@ -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;
}
}
}
@@ -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;