[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20220409105857.803667-2-razor@blackwall.org>
Date: Sat, 9 Apr 2022 13:58:52 +0300
From: Nikolay Aleksandrov <razor@...ckwall.org>
To: netdev@...r.kernel.org
Cc: roopa@...dia.com, kuba@...nel.org, davem@...emloft.net,
bridge@...ts.linux-foundation.org,
Nikolay Aleksandrov <razor@...ckwall.org>
Subject: [PATCH net-next 1/6] net: bridge: add a generic flush operation
Add a new bridge attribute (IFLA_BRIDGE_FLUSH) which will have embedded
attributes describing the object types that will be flushed. It will
allow fine-grained object flushing. Only a single flush attribute is
allowed per call since it can be a very load heavy operation. Also it is
allowed only with setlink command (similar to changelink flush). A nice
side-effect of using an af spec attribute is that it avoids making the
bridge link attribute options list longer.
An example structure for fdbs:
[ IFLA_BRIDGE_FLUSH ]
`[ BRIDGE_FDB_FLUSH ]
`[ FDB_FLUSH_NDM_STATE ]
`[ FDB_FLUSH_NDM_FLAGS ]
Signed-off-by: Nikolay Aleksandrov <razor@...ckwall.org>
---
include/uapi/linux/if_bridge.h | 8 +++++++
net/bridge/br_netlink.c | 42 +++++++++++++++++++++++++++++++++-
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/if_bridge.h b/include/uapi/linux/if_bridge.h
index a86a7e7b811f..221a4256808f 100644
--- a/include/uapi/linux/if_bridge.h
+++ b/include/uapi/linux/if_bridge.h
@@ -123,6 +123,7 @@ enum {
IFLA_BRIDGE_MRP,
IFLA_BRIDGE_CFM,
IFLA_BRIDGE_MST,
+ IFLA_BRIDGE_FLUSH,
__IFLA_BRIDGE_MAX,
};
#define IFLA_BRIDGE_MAX (__IFLA_BRIDGE_MAX - 1)
@@ -802,4 +803,11 @@ enum {
__BRIDGE_QUERIER_MAX
};
#define BRIDGE_QUERIER_MAX (__BRIDGE_QUERIER_MAX - 1)
+
+/* embedded in IFLA_BRIDGE_FLUSH */
+enum {
+ BRIDGE_FLUSH_UNSPEC,
+ __BRIDGE_FLUSH_MAX
+};
+#define BRIDGE_FLUSH_MAX (__BRIDGE_FLUSH_MAX - 1)
#endif /* _UAPI_LINUX_IF_BRIDGE_H */
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c
index 200ad05b296f..fe2211d4c0c7 100644
--- a/net/bridge/br_netlink.c
+++ b/net/bridge/br_netlink.c
@@ -779,6 +779,34 @@ int br_process_vlan_info(struct net_bridge *br,
return err;
}
+static const struct nla_policy br_flush_policy[BRIDGE_FLUSH_MAX + 1] = {
+ [BRIDGE_FLUSH_UNSPEC] = { .type = NLA_REJECT },
+};
+
+static int br_flush(struct net_bridge *br, int cmd,
+ struct nlattr *flush_attr,
+ struct netlink_ext_ack *extack)
+{
+ struct nlattr *flush_tb[BRIDGE_FLUSH_MAX + 1];
+ int err;
+
+ switch (cmd) {
+ case RTM_SETLINK:
+ break;
+ default:
+ NL_SET_ERR_MSG_MOD(extack,
+ "Bridge flush attribute is allowed only with RTM_SETLINK");
+ return -EINVAL;
+ }
+
+ err = nla_parse_nested(flush_tb, BRIDGE_FLUSH_MAX, flush_attr,
+ br_flush_policy, extack);
+ if (err)
+ return err;
+
+ return 0;
+}
+
static int br_afspec(struct net_bridge *br,
struct net_bridge_port *p,
struct nlattr *af_spec,
@@ -787,9 +815,10 @@ static int br_afspec(struct net_bridge *br,
{
struct bridge_vlan_info *vinfo_curr = NULL;
struct bridge_vlan_info *vinfo_last = NULL;
- struct nlattr *attr;
struct vtunnel_info tinfo_last = {};
struct vtunnel_info tinfo_curr = {};
+ bool flushed = false;
+ struct nlattr *attr;
int err = 0, rem;
nla_for_each_nested(attr, af_spec, rem) {
@@ -845,6 +874,17 @@ static int br_afspec(struct net_bridge *br,
if (err)
return err;
break;
+ case IFLA_BRIDGE_FLUSH:
+ if (flushed) {
+ NL_SET_ERR_MSG_MOD(extack,
+ "Multiple bridge flush attributes are not allowed");
+ return -EINVAL;
+ }
+ err = br_flush(br, cmd, attr, extack);
+ if (err)
+ return err;
+ flushed = true;
+ break;
}
}
--
2.35.1
Powered by blists - more mailing lists