Skip to content

Commit

Permalink
lib/route: extend bridge info support
Browse files Browse the repository at this point in the history
Add support for the following attributes for bridge links:

IFLA_BR_STP_STATE
IFLA_BR_MCAST_ROUTER
IFLA_BR_MCAST_SNOOPING
  • Loading branch information
ronand-atl committed Sep 16, 2024
1 parent a43a41c commit 3b284a1
Show file tree
Hide file tree
Showing 3 changed files with 195 additions and 0 deletions.
15 changes: 15 additions & 0 deletions include/netlink/route/link/bridge_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
174 changes: 174 additions & 0 deletions lib/route/link/bridge_info.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand All @@ -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] = {
Expand All @@ -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)
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions libnl-route-3.sym
Original file line number Diff line number Diff line change
Expand Up @@ -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;
rtnl_neigh_extflags2str;
Expand Down

0 comments on commit 3b284a1

Please sign in to comment.