summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/netlink-private/route/link/api.h6
-rw-r--r--lib/route/link.c6
-rw-r--r--lib/route/link/bridge.c16
3 files changed, 21 insertions, 7 deletions
diff --git a/include/netlink-private/route/link/api.h b/include/netlink-private/route/link/api.h
index 47fed6ff..6d30bf7c 100644
--- a/include/netlink-private/route/link/api.h
+++ b/include/netlink-private/route/link/api.h
@@ -149,11 +149,11 @@ struct rtnl_link_af_ops
/* RTM_NEWLINK override
*
- * Called if a change link request is set to the kernel. If this is set
- * to anything other than zero, RTM_NEWLINK will be overriden with
+ * Called if a change link request is set to the kernel. If this returns
+ * anything other than zero, RTM_NEWLINK will be overriden with
* RTM_SETLINK when rtnl_link_build_change_request() is called.
*/
- const int ao_override_rtm;
+ int (*ao_override_rtm)(struct rtnl_link *);
/** Called if a link message is sent to the kernel. Must append the
* link protocol specific attributes to the message. (IFLA_PROTINFO) */
diff --git a/lib/route/link.c b/lib/route/link.c
index 4384ea1a..de3c393d 100644
--- a/lib/route/link.c
+++ b/lib/route/link.c
@@ -116,12 +116,12 @@ static int af_free(struct rtnl_link *link, struct rtnl_link_af_ops *ops,
return 0;
}
-static int af_request_type(int af_type)
+static int af_request_type(int af_type, struct rtnl_link *changes)
{
struct rtnl_link_af_ops *ops;
ops = rtnl_link_af_ops_lookup(af_type);
- if (ops && ops->ao_override_rtm)
+ if (ops && ops->ao_override_rtm(changes))
return RTM_SETLINK;
return RTM_NEWLINK;
@@ -1732,7 +1732,7 @@ int rtnl_link_build_change_request(struct rtnl_link *orig,
!strcmp(orig->l_name, changes->l_name))
changes->ce_mask &= ~LINK_ATTR_IFNAME;
- rt = af_request_type(orig->l_family);
+ rt = af_request_type(orig->l_family, changes);
if ((err = build_link_msg(rt, &ifi, changes, flags, result)) < 0)
goto errout;
diff --git a/lib/route/link/bridge.c b/lib/route/link/bridge.c
index b9d05bc4..2d95faf8 100644
--- a/lib/route/link/bridge.c
+++ b/lib/route/link/bridge.c
@@ -307,6 +307,20 @@ nla_put_failure:
return -NLE_MSGSIZE;
}
+static int bridge_override_rtm(struct rtnl_link *link) {
+ struct bridge_data *bd;
+
+ if (!rtnl_link_is_bridge(link))
+ return 0;
+
+ bd = bridge_data(link);
+
+ if (bd->ce_mask & BRIDGE_ATTR_FLAGS)
+ return 1;
+
+ return 0;
+}
+
static int bridge_get_af(struct nl_msg *msg, uint32_t *ext_filter_mask)
{
*ext_filter_mask |= RTEXT_FILTER_BRVLAN;
@@ -961,7 +975,7 @@ static struct rtnl_link_af_ops bridge_ops = {
.ao_fill_af = &bridge_fill_af,
.ao_fill_pi = &bridge_fill_pi,
.ao_fill_pi_flags = NLA_F_NESTED,
- .ao_override_rtm = 1,
+ .ao_override_rtm = &bridge_override_rtm,
.ao_fill_af_no_nest = 1,
};