summaryrefslogtreecommitdiff
path: root/lib/tc.c
diff options
context:
space:
mode:
authorJianbo Liu <jianbol@nvidia.com>2021-01-26 09:17:46 +0200
committerSimon Horman <simon.horman@netronome.com>2021-02-24 11:07:20 +0100
commit47e73f7f00589d70541ab87ecc7b45f070d2e6be (patch)
treefe993d91c529cd8882cd178c97b1696a14bfddbc /lib/tc.c
parent436ce00da03e0a09df875fc775ebc47b50b5bd01 (diff)
downloadopenvswitch-47e73f7f00589d70541ab87ecc7b45f070d2e6be.tar.gz
netdev-offload-tc: Flush rules on all chains before attach ingress block
Previously, only chain 0 is deleted before attach the ingress block. If there are rules on the chain other than 0, these rules are not flushed. In this case, the recreation of qdisc also fails. To fix this issue, flush rules from all chains. Signed-off-by: Jianbo Liu <jianbol@nvidia.com> Reviewed-by: Roi Dayan <roid@nvidia.com> Signed-off-by: Simon Horman <simon.horman@netronome.com>
Diffstat (limited to 'lib/tc.c')
-rw-r--r--lib/tc.c39
1 files changed, 39 insertions, 0 deletions
diff --git a/lib/tc.c b/lib/tc.c
index ef3706425..a27cca2cc 100644
--- a/lib/tc.c
+++ b/lib/tc.c
@@ -61,6 +61,10 @@
#define TCA_DUMP_FLAGS 15
#endif
+#ifndef RTM_GETCHAIN
+#define RTM_GETCHAIN 102
+#endif
+
VLOG_DEFINE_THIS_MODULE(tc);
static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(60, 5);
@@ -297,6 +301,10 @@ static const struct nl_policy tca_policy[] = {
[TCA_STATS2] = { .type = NL_A_NESTED, .optional = true, },
};
+static const struct nl_policy tca_chain_policy[] = {
+ [TCA_CHAIN] = { .type = NL_A_U32, .optional = false, },
+};
+
static const struct nl_policy tca_flower_policy[] = {
[TCA_FLOWER_CLASSID] = { .type = NL_A_U32, .optional = true, },
[TCA_FLOWER_INDEV] = { .type = NL_A_STRING, .max_len = IFNAMSIZ,
@@ -1906,6 +1914,25 @@ parse_netlink_to_tc_flower(struct ofpbuf *reply, struct tcf_id *id,
}
int
+parse_netlink_to_tc_chain(struct ofpbuf *reply, uint32_t *chain)
+{
+ struct nlattr *ta[ARRAY_SIZE(tca_chain_policy)];
+ struct tcmsg *tc;
+
+ tc = ofpbuf_at_assert(reply, NLMSG_HDRLEN, sizeof *tc);
+
+ if (!nl_policy_parse(reply, NLMSG_HDRLEN + sizeof *tc,
+ tca_chain_policy, ta, ARRAY_SIZE(ta))) {
+ VLOG_ERR_RL(&error_rl, "failed to parse tca chain policy");
+ return EINVAL;
+ }
+
+ *chain = nl_attr_get_u32(ta[TCA_CHAIN]);
+
+ return 0;
+}
+
+int
tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse)
{
struct ofpbuf request;
@@ -1925,6 +1952,18 @@ tc_dump_flower_start(struct tcf_id *id, struct nl_dump *dump, bool terse)
}
int
+tc_dump_tc_chain_start(struct tcf_id *id, struct nl_dump *dump)
+{
+ struct ofpbuf request;
+
+ request_from_tcf_id(id, 0, RTM_GETCHAIN, NLM_F_DUMP, &request);
+ nl_dump_start(dump, NETLINK_ROUTE, &request);
+ ofpbuf_uninit(&request);
+
+ return 0;
+}
+
+int
tc_del_filter(struct tcf_id *id)
{
struct ofpbuf request;