From a3952d0f55dff24f9c0310b3f5965d4769890445 Mon Sep 17 00:00:00 2001 From: Ronan Dalton Date: Wed, 11 Sep 2024 16:30:22 +1200 Subject: [PATCH 1/3] lib/route: add missing bridge info getter functions There are bridge info setter functions for nf_call_iptables, nf_call_ip6tables and nf_call_arptables, but no corresponding getter functions, so add them. A corresponding entry for rtnl_link_bridge_set_vlan_default_pvid was also missing in libnl-route-3.sym, so add that as well. --- include/netlink/route/link/bridge_info.h | 9 +++ lib/route/link/bridge_info.c | 95 ++++++++++++++++++++++++ libnl-route-3.sym | 6 +- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/include/netlink/route/link/bridge_info.h b/include/netlink/route/link/bridge_info.h index bb7bf0b6..ff93c779 100644 --- a/include/netlink/route/link/bridge_info.h +++ b/include/netlink/route/link/bridge_info.h @@ -37,12 +37,21 @@ extern void rtnl_link_bridge_set_vlan_stats_enabled(struct rtnl_link *link, uint8_t vlan_stats_enabled); extern int rtnl_link_bridge_get_vlan_stats_enabled(struct rtnl_link *link, uint8_t *vlan_stats_enabled); + extern void rtnl_link_bridge_set_nf_call_iptables(struct rtnl_link *link, uint8_t call_enabled); +extern int rtnl_link_bridge_get_nf_call_iptables(struct rtnl_link *link, + uint8_t *call_enabled); + extern void rtnl_link_bridge_set_nf_call_ip6tables(struct rtnl_link *link, uint8_t call_enabled); +extern int rtnl_link_bridge_get_nf_call_ip6tables(struct rtnl_link *link, + uint8_t *call_enabled); + extern void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link, uint8_t call_enabled); +extern int rtnl_link_bridge_get_nf_call_arptables(struct rtnl_link *link, + uint8_t *call_enabled); #ifdef __cplusplus } diff --git a/lib/route/link/bridge_info.c b/lib/route/link/bridge_info.c index 5d69b5ca..7250b437 100644 --- a/lib/route/link/bridge_info.c +++ b/lib/route/link/bridge_info.c @@ -211,6 +211,8 @@ static struct rtnl_link_info_ops bridge_info_ops = { * @arg link Link object of type bridge * @arg ageing_time Interval to set. * + * @see rtnl_link_bridge_get_ageing_time() + * * @return void */ void rtnl_link_bridge_set_ageing_time(struct rtnl_link *link, @@ -458,6 +460,8 @@ int rtnl_link_bridge_get_vlan_stats_enabled(struct rtnl_link *link, * @arg link Link object of type bridge * @arg call_enabled call enabled boolean flag to set. * + * @see rtnl_link_bridge_get_nf_call_iptables() + * * @return void */ void rtnl_link_bridge_set_nf_call_iptables(struct rtnl_link *link, @@ -472,11 +476,42 @@ void rtnl_link_bridge_set_nf_call_iptables(struct rtnl_link *link, bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IPTABLES; } +/** + * Get call enabled flag for passing IPv4 traffic to iptables + * @arg link Link object of type bridge + * @arg call_enabled Output argument. + * + * @see rtnl_link_bridge_set_nf_call_iptables() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_nf_call_iptables(struct rtnl_link *link, + uint8_t *call_enabled) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + if (!(bi->ce_mask & BRIDGE_ATTR_NF_CALL_IPTABLES)) + return -NLE_NOATTR; + + if (!call_enabled) + return -NLE_INVAL; + + *call_enabled = bi->b_nf_call_iptables; + + return 0; +} + /** * Set call enabled flag for passing IPv6 traffic to ip6tables * @arg link Link object of type bridge * @arg call_enabled call enabled boolean flag to set. * + * @see rtnl_link_bridge_get_nf_call_ip6tables() + * * @return void */ void rtnl_link_bridge_set_nf_call_ip6tables(struct rtnl_link *link, @@ -491,11 +526,42 @@ void rtnl_link_bridge_set_nf_call_ip6tables(struct rtnl_link *link, bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IP6TABLES; } +/** + * Get call enabled flag for passing IPv6 traffic to iptables + * @arg link Link object of type bridge + * @arg call_enabled Output argument. + * + * @see rtnl_link_bridge_set_nf_call_ip6tables() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_nf_call_ip6tables(struct rtnl_link *link, + uint8_t *call_enabled) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + if (!(bi->ce_mask & BRIDGE_ATTR_NF_CALL_IP6TABLES)) + return -NLE_NOATTR; + + if (!call_enabled) + return -NLE_INVAL; + + *call_enabled = bi->b_nf_call_ip6tables; + + return 0; +} + /** * Set call enabled flag for passing ARP traffic to arptables * @arg link Link object of type bridge * @arg call_enabled call enabled boolean flag to set. * + * @see rtnl_link_bridge_get_nf_call_arptables() + * * @return void */ void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link, @@ -510,6 +576,35 @@ void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link, bi->ce_mask |= BRIDGE_ATTR_NF_CALL_ARPTABLES; } +/** + * Get call enabled flag for passing ARP traffic to arptables + * @arg link Link object of type bridge + * @arg call_enabled Output argument. + * + * @see rtnl_link_bridge_set_nf_call_arptables() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_nf_call_arptables(struct rtnl_link *link, + uint8_t *call_enabled) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + if (!(bi->ce_mask & BRIDGE_ATTR_NF_CALL_ARPTABLES)) + return -NLE_NOATTR; + + if (!call_enabled) + return -NLE_INVAL; + + *call_enabled = bi->b_nf_call_arptables; + + return 0; +} + static void _nl_init bridge_info_init(void) { rtnl_link_register_info(&bridge_info_ops); diff --git a/libnl-route-3.sym b/libnl-route-3.sym index 60eefe47..90e3c148 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -1323,8 +1323,8 @@ global: rtnl_link_bridge_set_ageing_time; rtnl_link_bridge_set_master; rtnl_link_bridge_set_nf_call_arptables; - rtnl_link_bridge_set_nf_call_iptables; rtnl_link_bridge_set_nf_call_ip6tables; + rtnl_link_bridge_set_nf_call_iptables; rtnl_link_bridge_set_port_vlan_map_range; rtnl_link_bridge_set_port_vlan_pvid; rtnl_link_bridge_unset_port_vlan_map_range; @@ -1340,5 +1340,9 @@ global: rtnl_link_bond_get_miimon; rtnl_link_bond_get_min_links; rtnl_link_bond_get_mode; + rtnl_link_bridge_get_nf_call_arptables; + rtnl_link_bridge_get_nf_call_ip6tables; + rtnl_link_bridge_get_nf_call_iptables; + rtnl_link_bridge_set_vlan_default_pvid; rtnl_link_get_perm_addr; } libnl_3_10; From 96f05e5b3bbab1a9fd3ad708d116ec46ad5d78c0 Mon Sep 17 00:00:00 2001 From: Ronan Dalton Date: Fri, 13 Sep 2024 10:46:54 +1200 Subject: [PATCH 2/3] lib/route: extend bridge info support Add support for the following attributes for bridge links: IFLA_BR_STP_STATE IFLA_BR_MCAST_ROUTER IFLA_BR_MCAST_SNOOPING --- include/netlink/route/link/bridge_info.h | 15 ++ lib/route/link/bridge_info.c | 174 +++++++++++++++++++++++ libnl-route-3.sym | 6 + 3 files changed, 195 insertions(+) diff --git a/include/netlink/route/link/bridge_info.h b/include/netlink/route/link/bridge_info.h index ff93c779..b7485ac8 100644 --- a/include/netlink/route/link/bridge_info.h +++ b/include/netlink/route/link/bridge_info.h @@ -53,6 +53,21 @@ extern void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link, extern int rtnl_link_bridge_get_nf_call_arptables(struct rtnl_link *link, uint8_t *call_enabled); +extern void rtnl_link_bridge_set_stp_state(struct rtnl_link *link, + uint32_t stp_state); +extern int rtnl_link_bridge_get_stp_state(struct rtnl_link *link, + uint32_t *stp_state); + +extern void rtnl_link_bridge_set_mcast_router(struct rtnl_link *link, + uint8_t type); +extern int rtnl_link_bridge_get_mcast_router(struct rtnl_link *link, + uint8_t *type); + +extern void rtnl_link_bridge_set_mcast_snooping(struct rtnl_link *link, + uint8_t value); +extern int rtnl_link_bridge_get_mcast_snooping(struct rtnl_link *link, + uint8_t *value); + #ifdef __cplusplus } #endif diff --git a/lib/route/link/bridge_info.c b/lib/route/link/bridge_info.c index 7250b437..0e4fdea6 100644 --- a/lib/route/link/bridge_info.c +++ b/lib/route/link/bridge_info.c @@ -26,6 +26,9 @@ #define BRIDGE_ATTR_NF_CALL_IPTABLES (1 << 5) #define BRIDGE_ATTR_NF_CALL_IP6TABLES (1 << 6) #define BRIDGE_ATTR_NF_CALL_ARPTABLES (1 << 7) +#define BRIDGE_ATTR_STP_STATE (1 << 8) +#define BRIDGE_ATTR_MCAST_ROUTER (1 << 9) +#define BRIDGE_ATTR_MCAST_SNOOPING (1 << 10) struct bridge_info { uint32_t ce_mask; /* to support attr macros */ @@ -37,6 +40,9 @@ struct bridge_info { uint8_t b_nf_call_iptables; uint8_t b_nf_call_ip6tables; uint8_t b_nf_call_arptables; + uint32_t b_stp_state; + uint8_t b_mcast_router; + uint8_t b_mcast_snooping; }; static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = { @@ -48,6 +54,9 @@ static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = { [IFLA_BR_NF_CALL_IPTABLES] = { .type = NLA_U8 }, [IFLA_BR_NF_CALL_IP6TABLES] = { .type = NLA_U8 }, [IFLA_BR_NF_CALL_ARPTABLES] = { .type = NLA_U8 }, + [IFLA_BR_STP_STATE] = { .type = NLA_U32 }, + [IFLA_BR_MCAST_ROUTER] = { .type = NLA_U8 }, + [IFLA_BR_MCAST_SNOOPING] = { .type = NLA_U8 }, }; static inline struct bridge_info *bridge_info(struct rtnl_link *link) @@ -136,6 +145,21 @@ static int bridge_info_parse(struct rtnl_link *link, struct nlattr *data, bi->ce_mask |= BRIDGE_ATTR_NF_CALL_ARPTABLES; } + if (tb[IFLA_BR_STP_STATE]) { + bi->b_stp_state = nla_get_u32(tb[IFLA_BR_STP_STATE]); + bi->ce_mask |= BRIDGE_ATTR_STP_STATE; + } + + if (tb[IFLA_BR_MCAST_ROUTER]) { + bi->b_mcast_router = nla_get_u8(tb[IFLA_BR_MCAST_ROUTER]); + bi->ce_mask |= BRIDGE_ATTR_MCAST_ROUTER; + } + + if (tb[IFLA_BR_MCAST_SNOOPING]) { + bi->b_mcast_snooping = nla_get_u8(tb[IFLA_BR_MCAST_SNOOPING]); + bi->ce_mask |= BRIDGE_ATTR_MCAST_SNOOPING; + } + return 0; } @@ -178,6 +202,15 @@ static int bridge_info_put_attrs(struct nl_msg *msg, struct rtnl_link *link) NLA_PUT_U8(msg, IFLA_BR_NF_CALL_ARPTABLES, bi->b_nf_call_arptables); + if (bi->ce_mask & BRIDGE_ATTR_STP_STATE) + NLA_PUT_U32(msg, IFLA_BR_STP_STATE, bi->b_stp_state); + + if (bi->ce_mask & BRIDGE_ATTR_MCAST_ROUTER) + NLA_PUT_U8(msg, IFLA_BR_MCAST_ROUTER, bi->b_mcast_router); + + if (bi->ce_mask & BRIDGE_ATTR_MCAST_SNOOPING) + NLA_PUT_U8(msg, IFLA_BR_MCAST_SNOOPING, bi->b_mcast_snooping); + nla_nest_end(msg, data); return 0; @@ -605,6 +638,147 @@ int rtnl_link_bridge_get_nf_call_arptables(struct rtnl_link *link, return 0; } +/** + * Set STP state + * @arg link Link object of type bridge + * @arg stp_state STP state to set. Typically 0 or 1. + * + * @see rtnl_link_bridge_get_stp_state() + * + * @return void + */ +void rtnl_link_bridge_set_stp_state(struct rtnl_link *link, uint32_t stp_state) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + bi->b_stp_state = stp_state; + + bi->ce_mask |= BRIDGE_ATTR_STP_STATE; +} + +/** + * Get STP state + * @arg link Link object of type bridge + * @arg stp_state Output argument. + * + * @see rtnl_link_bridge_set_stp_state() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_stp_state(struct rtnl_link *link, uint32_t *stp_state) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + if (!(bi->ce_mask & BRIDGE_ATTR_STP_STATE)) + return -NLE_NOATTR; + + if (!stp_state) + return -NLE_INVAL; + + *stp_state = bi->b_stp_state; + return 0; +} + +/** + * Set multicast router type + * @arg link Link object of type bridge + * @arg type Multicast router type (MDB_RTR_TYPE_*) + * + * @see rtnl_link_bridge_get_mcast_router() + * + * @return void + */ +void rtnl_link_bridge_set_mcast_router(struct rtnl_link *link, uint8_t type) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + bi->b_mcast_router = type; + + bi->ce_mask |= BRIDGE_ATTR_MCAST_ROUTER; +} + +/** + * Get multicast router type + * @arg link Link object of type bridge + * @arg type Output argument. + * + * @see rtnl_link_bridge_set_mcast_router() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_mcast_router(struct rtnl_link *link, uint8_t *type) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + if (!(bi->ce_mask & BRIDGE_ATTR_MCAST_ROUTER)) + return -NLE_NOATTR; + + if (!type) + return -NLE_INVAL; + + *type = bi->b_mcast_router; + return 0; +} + +/** + * Set multicast snooping + * @arg link Link object of type bridge + * @arg value Value to set. Typically 0 or 1. + * + * @see rtnl_link_bridge_get_mcast_snooping() + * + * @return void + */ +void rtnl_link_bridge_set_mcast_snooping(struct rtnl_link *link, uint8_t value) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + bi->b_mcast_snooping = value; + + bi->ce_mask |= BRIDGE_ATTR_MCAST_SNOOPING; +} + +/** + * Get multicast snooping value + * @arg link Link object of type bridge + * @arg value Output argument. + * + * @see rtnl_link_bridge_set_mcast_snooping() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_mcast_snooping(struct rtnl_link *link, uint8_t *value) +{ + struct bridge_info *bi = bridge_info(link); + + IS_BRIDGE_INFO_ASSERT(link); + + if (!(bi->ce_mask & BRIDGE_ATTR_MCAST_SNOOPING)) + return -NLE_NOATTR; + + if (!value) + return -NLE_INVAL; + + *value = bi->b_mcast_snooping; + return 0; +} + static void _nl_init bridge_info_init(void) { rtnl_link_register_info(&bridge_info_ops); diff --git a/libnl-route-3.sym b/libnl-route-3.sym index 90e3c148..5d959cda 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -1340,9 +1340,15 @@ global: rtnl_link_bond_get_miimon; rtnl_link_bond_get_min_links; rtnl_link_bond_get_mode; + rtnl_link_bridge_get_mcast_router; + rtnl_link_bridge_get_mcast_snooping; rtnl_link_bridge_get_nf_call_arptables; rtnl_link_bridge_get_nf_call_ip6tables; rtnl_link_bridge_get_nf_call_iptables; + rtnl_link_bridge_get_stp_state; + rtnl_link_bridge_set_mcast_router; + rtnl_link_bridge_set_mcast_snooping; + rtnl_link_bridge_set_stp_state; rtnl_link_bridge_set_vlan_default_pvid; rtnl_link_get_perm_addr; } libnl_3_10; From 20b2d79035a9a443e8ddb7d84f91a651cf59ad51 Mon Sep 17 00:00:00 2001 From: Ronan Dalton Date: Fri, 13 Sep 2024 10:47:02 +1200 Subject: [PATCH 3/3] lib/route: add support for bridge info boolopts Add support for the IFLA_BR_MULTI_BOOLOPT bridge link attribute by adding functions for all current boolean options. --- include/netlink/route/link/bridge_info.h | 14 ++ lib/route/link/bridge_info.c | 159 +++++++++++++++++++++++ libnl-route-3.sym | 6 + 3 files changed, 179 insertions(+) diff --git a/include/netlink/route/link/bridge_info.h b/include/netlink/route/link/bridge_info.h index b7485ac8..63b5e7b3 100644 --- a/include/netlink/route/link/bridge_info.h +++ b/include/netlink/route/link/bridge_info.h @@ -6,6 +6,7 @@ #ifndef NETLINK_LINK_BRIDGE_INFO_H_ #define NETLINK_LINK_BRIDGE_INFO_H_ +#include #include #include @@ -68,6 +69,19 @@ extern void rtnl_link_bridge_set_mcast_snooping(struct rtnl_link *link, extern int rtnl_link_bridge_get_mcast_snooping(struct rtnl_link *link, uint8_t *value); +extern void rtnl_link_bridge_set_no_linklocal_learn(struct rtnl_link *link, + bool value); +extern int rtnl_link_bridge_get_no_linklocal_learn(struct rtnl_link *link, + bool *value); + +extern void rtnl_link_bridge_set_mcast_vlan_snooping(struct rtnl_link *link, + bool value); +extern int rtnl_link_bridge_get_mcast_vlan_snooping(struct rtnl_link *link, + bool *value); + +extern void rtnl_link_bridge_set_mst_enable(struct rtnl_link *link, bool value); +extern int rtnl_link_bridge_get_mst_enable(struct rtnl_link *link, bool *value); + #ifdef __cplusplus } #endif diff --git a/lib/route/link/bridge_info.c b/lib/route/link/bridge_info.c index 0e4fdea6..d1654058 100644 --- a/lib/route/link/bridge_info.c +++ b/lib/route/link/bridge_info.c @@ -13,6 +13,8 @@ #include "nl-default.h" +#include + #include #include "nl-route.h" @@ -29,6 +31,7 @@ #define BRIDGE_ATTR_STP_STATE (1 << 8) #define BRIDGE_ATTR_MCAST_ROUTER (1 << 9) #define BRIDGE_ATTR_MCAST_SNOOPING (1 << 10) +#define BRIDGE_ATTR_BOOLOPT (1 << 11) struct bridge_info { uint32_t ce_mask; /* to support attr macros */ @@ -43,6 +46,7 @@ struct bridge_info { uint32_t b_stp_state; uint8_t b_mcast_router; uint8_t b_mcast_snooping; + struct br_boolopt_multi b_boolopts; }; static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = { @@ -57,6 +61,9 @@ static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = { [IFLA_BR_STP_STATE] = { .type = NLA_U32 }, [IFLA_BR_MCAST_ROUTER] = { .type = NLA_U8 }, [IFLA_BR_MCAST_SNOOPING] = { .type = NLA_U8 }, + [IFLA_BR_MULTI_BOOLOPT] = { .type = NLA_BINARY, + .minlen = sizeof(struct br_boolopt_multi), + .maxlen = sizeof(struct br_boolopt_multi) }, }; static inline struct bridge_info *bridge_info(struct rtnl_link *link) @@ -160,6 +167,12 @@ static int bridge_info_parse(struct rtnl_link *link, struct nlattr *data, bi->ce_mask |= BRIDGE_ATTR_MCAST_SNOOPING; } + if (tb[IFLA_BR_MULTI_BOOLOPT]) { + nla_memcpy(&bi->b_boolopts, tb[IFLA_BR_MULTI_BOOLOPT], + sizeof(bi->b_boolopts)); + bi->ce_mask |= BRIDGE_ATTR_BOOLOPT; + } + return 0; } @@ -211,6 +224,10 @@ static int bridge_info_put_attrs(struct nl_msg *msg, struct rtnl_link *link) if (bi->ce_mask & BRIDGE_ATTR_MCAST_SNOOPING) NLA_PUT_U8(msg, IFLA_BR_MCAST_SNOOPING, bi->b_mcast_snooping); + if (bi->ce_mask & BRIDGE_ATTR_BOOLOPT) + NLA_PUT(msg, IFLA_BR_MULTI_BOOLOPT, sizeof(bi->b_boolopts), + &bi->b_boolopts); + nla_nest_end(msg, data); return 0; @@ -239,6 +256,55 @@ static struct rtnl_link_info_ops bridge_info_ops = { } \ } while (0) +static int bridge_info_set_boolopt(struct rtnl_link *link, + enum br_boolopt_id opt, bool value) +{ + struct bridge_info *bi = bridge_info(link); + uint32_t mask; + + IS_BRIDGE_INFO_ASSERT(link); + + if (opt < 0 || opt >= BR_BOOLOPT_MAX) + return -NLE_INVAL; + + mask = 1ul << opt; + + if (value) + bi->b_boolopts.optval |= mask; + else + bi->b_boolopts.optval &= ~mask; + + bi->b_boolopts.optmask |= mask; + bi->ce_mask |= BRIDGE_ATTR_BOOLOPT; + + return 0; +} + +static int bridge_info_get_boolopt(struct rtnl_link *link, + enum br_boolopt_id opt, bool *value) +{ + struct bridge_info *bi = bridge_info(link); + uint32_t mask; + + IS_BRIDGE_INFO_ASSERT(link); + + if (opt < 0 || opt >= BR_BOOLOPT_MAX) + return -NLE_INVAL; + + mask = 1ul << opt; + + if (!(bi->ce_mask & BRIDGE_ATTR_BOOLOPT) || + !(bi->b_boolopts.optmask & mask)) + return -NLE_NOATTR; + + if (!value) + return -NLE_INVAL; + + *value = bi->b_boolopts.optval & mask; + + return 0; +} + /** * Set ageing time for dynamic forwarding entries * @arg link Link object of type bridge @@ -779,6 +845,99 @@ int rtnl_link_bridge_get_mcast_snooping(struct rtnl_link *link, uint8_t *value) return 0; } +/** + * Set the no link-local learn flag + * @arg link Link object of type bridge + * @arg value Value to set the flag to + * + * @see rtnl_link_bridge_get_no_linklocal_learn() + * + * @return void + */ +void rtnl_link_bridge_set_no_linklocal_learn(struct rtnl_link *link, bool value) +{ + bridge_info_set_boolopt(link, BR_BOOLOPT_NO_LL_LEARN, value); +} + +/** + * Get the no link-local learn flag + * @arg link Link object of type bridge + * @arg value Output argument. + * + * @see rtnl_link_bridge_set_no_linklocal_learn() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_no_linklocal_learn(struct rtnl_link *link, bool *value) +{ + return bridge_info_get_boolopt(link, BR_BOOLOPT_NO_LL_LEARN, value); +} + +/** + * Set the multicast vlan snooping flag + * @arg link Link object of type bridge + * @arg value Value to set the flag to + * + * @see rtnl_link_bridge_get_mcast_vlan_snooping() + * + * @return void + */ +void rtnl_link_bridge_set_mcast_vlan_snooping(struct rtnl_link *link, + bool value) +{ + bridge_info_set_boolopt(link, BR_BOOLOPT_MCAST_VLAN_SNOOPING, value); +} + +/** + * Get the multicast vlan snooping flag + * @arg link Link object of type bridge + * @arg value Output argument. + * + * @see rtnl_link_bridge_set_mcast_vlan_snooping() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_mcast_vlan_snooping(struct rtnl_link *link, + bool *value) +{ + return bridge_info_get_boolopt(link, BR_BOOLOPT_MCAST_VLAN_SNOOPING, + value); +} + +/** + * Set the MST enable flag + * @arg link Link object of type bridge + * @arg value Value to set the flag to + * + * @see rtnl_link_bridge_get_mst_enable() + * + * @return void + */ +void rtnl_link_bridge_set_mst_enable(struct rtnl_link *link, bool value) +{ + bridge_info_set_boolopt(link, BR_BOOLOPT_MST_ENABLE, value); +} + +/** + * Get the MST enable flag + * @arg link Link object of type bridge + * @arg value Output argument + * + * @see rtnl_link_bridge_set_mst_enable() + * + * @return Zero on success, otherwise a negative error code. + * @retval -NLE_NOATTR + * @retval -NLE_INVAL + */ +int rtnl_link_bridge_get_mst_enable(struct rtnl_link *link, bool *value) +{ + return bridge_info_get_boolopt(link, BR_BOOLOPT_MST_ENABLE, value); +} + static void _nl_init bridge_info_init(void) { rtnl_link_register_info(&bridge_info_ops); diff --git a/libnl-route-3.sym b/libnl-route-3.sym index 5d959cda..84e1e79b 100644 --- a/libnl-route-3.sym +++ b/libnl-route-3.sym @@ -1342,12 +1342,18 @@ global: rtnl_link_bond_get_mode; rtnl_link_bridge_get_mcast_router; rtnl_link_bridge_get_mcast_snooping; + rtnl_link_bridge_get_mcast_vlan_snooping; + rtnl_link_bridge_get_mst_enable; rtnl_link_bridge_get_nf_call_arptables; rtnl_link_bridge_get_nf_call_ip6tables; rtnl_link_bridge_get_nf_call_iptables; + rtnl_link_bridge_get_no_linklocal_learn; rtnl_link_bridge_get_stp_state; rtnl_link_bridge_set_mcast_router; rtnl_link_bridge_set_mcast_snooping; + rtnl_link_bridge_set_mcast_vlan_snooping; + rtnl_link_bridge_set_mst_enable; + rtnl_link_bridge_set_no_linklocal_learn; rtnl_link_bridge_set_stp_state; rtnl_link_bridge_set_vlan_default_pvid; rtnl_link_get_perm_addr;