Add netlink interface to manipulate the mdb_notify_on_flag_change knob. Signed-off-by: Joseph Huang <joseph.hu...@garmin.com> --- include/uapi/linux/if_link.h | 14 ++++++++++++++ net/bridge/br_netlink.c | 21 +++++++++++++++++++++ 2 files changed, 35 insertions(+)
diff --git a/include/uapi/linux/if_link.h b/include/uapi/linux/if_link.h index bfe880fbbb24..8fa830599972 100644 --- a/include/uapi/linux/if_link.h +++ b/include/uapi/linux/if_link.h @@ -741,6 +741,19 @@ enum in6_addr_gen_mode { * @IFLA_BR_FDB_MAX_LEARNED * Set the number of max dynamically learned FDB entries for the current * bridge. + * + * @IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE + * Set how the bridge shall notify user space about MDB flag change via + * RTM_NEWMDB netlink message. + * The valid values are: + * + * * 0 - the bridge will not notify user space about MDB flag change + * * 1 - the bridge will notify user space about flag change if either + * MDB_PG_FLAGS_OFFLOAD or MDB_PG_FLAGS_OFFLOAD_FAILED has changed + * * 2 - the bridge will notify user space about flag change only if + * MDB_PG_FLAGS_OFFLOAD_FAILED has changed + * + * The default value is 0. */ enum { IFLA_BR_UNSPEC, @@ -793,6 +806,7 @@ enum { IFLA_BR_MCAST_QUERIER_STATE, IFLA_BR_FDB_N_LEARNED, IFLA_BR_FDB_MAX_LEARNED, + IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE, __IFLA_BR_MAX, }; diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 3e0f47203f2a..e87d39b148d8 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c @@ -1270,6 +1270,7 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = { NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)), [IFLA_BR_FDB_N_LEARNED] = { .type = NLA_REJECT }, [IFLA_BR_FDB_MAX_LEARNED] = { .type = NLA_U32 }, + [IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE] = { .type = NLA_U8 }, }; static int br_changelink(struct net_device *brdev, struct nlattr *tb[], @@ -1514,6 +1515,18 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[], return err; } #endif + +#ifdef CONFIG_NET_SWITCHDEV + if (data[IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE]) { + __u8 val; + + val = nla_get_u8(data[IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE]); + err = br_multicast_set_mdb_notify_on_flag_change(&br->multicast_ctx, + val); + if (err) + return err; + } +#endif #endif #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) if (data[IFLA_BR_NF_CALL_IPTABLES]) { @@ -1625,6 +1638,9 @@ static size_t br_get_size(const struct net_device *brdev) nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_IGMP_VERSION */ nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_MLD_VERSION */ br_multicast_querier_state_size() + /* IFLA_BR_MCAST_QUERIER_STATE */ +#ifdef CONFIG_NET_SWITCHDEV + nla_total_size(sizeof(u8)) + /* IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE */ +#endif #endif #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) nla_total_size(sizeof(u8)) + /* IFLA_BR_NF_CALL_IPTABLES */ @@ -1722,6 +1738,11 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev) if (nla_put_u8(skb, IFLA_BR_MCAST_MLD_VERSION, br->multicast_ctx.multicast_mld_version)) return -EMSGSIZE; +#endif +#ifdef CONFIG_NET_SWITCHDEV + if (nla_put_u8(skb, IFLA_BR_MDB_NOTIFY_ON_FLAG_CHANGE, + br->multicast_ctx.multicast_mdb_notify_on_flag_change)) + return -EMSGSIZE; #endif clockval = jiffies_to_clock_t(br->multicast_ctx.multicast_last_member_interval); if (nla_put_u64_64bit(skb, IFLA_BR_MCAST_LAST_MEMBER_INTVL, clockval, -- 2.49.0