14#include "nl-default.h"
16#include <linux/if_bridge.h>
18#include <netlink/route/link/bridge_info.h>
23#define BRIDGE_ATTR_VLAN_FILTERING (1 << 0)
24#define BRIDGE_ATTR_VLAN_PROTOCOL (1 << 1)
25#define BRIDGE_ATTR_VLAN_STATS_ENABLED (1 << 2)
26#define BRIDGE_ATTR_AGEING_TIME (1 << 3)
27#define BRIDGE_ATTR_VLAN_DEFAULT_PVID (1 << 4)
28#define BRIDGE_ATTR_NF_CALL_IPTABLES (1 << 5)
29#define BRIDGE_ATTR_NF_CALL_IP6TABLES (1 << 6)
30#define BRIDGE_ATTR_NF_CALL_ARPTABLES (1 << 7)
31#define BRIDGE_ATTR_STP_STATE (1 << 8)
32#define BRIDGE_ATTR_MCAST_ROUTER (1 << 9)
33#define BRIDGE_ATTR_MCAST_SNOOPING (1 << 10)
34#define BRIDGE_ATTR_BOOLOPT (1 << 11)
38 uint32_t b_ageing_time;
39 uint16_t b_vlan_protocol;
40 uint16_t b_vlan_default_pvid;
41 uint8_t b_vlan_filtering;
42 uint8_t b_vlan_stats_enabled;
43 uint8_t b_nf_call_iptables;
44 uint8_t b_nf_call_ip6tables;
45 uint8_t b_nf_call_arptables;
47 uint8_t b_mcast_router;
48 uint8_t b_mcast_snooping;
49 struct br_boolopt_multi b_boolopts;
65 .minlen =
sizeof(
struct br_boolopt_multi),
66 .maxlen =
sizeof(
struct br_boolopt_multi) },
74static int bridge_info_alloc(
struct rtnl_link *link)
79 memset(link->l_info, 0,
sizeof(*bi));
81 bi = calloc(1,
sizeof(*bi));
91static int bridge_info_parse(
struct rtnl_link *link,
struct nlattr *data,
92 struct nlattr *xstats)
94 struct nlattr *tb[IFLA_BR_MAX + 1];
98 NL_DBG(3,
"Parsing Bridge link info\n");
104 if ((err = bridge_info_alloc(link)) < 0)
109 if (tb[IFLA_BR_AGEING_TIME]) {
110 bi->b_ageing_time =
nla_get_u32(tb[IFLA_BR_AGEING_TIME]);
111 bi->ce_mask |= BRIDGE_ATTR_AGEING_TIME;
114 if (tb[IFLA_BR_VLAN_DEFAULT_PVID]) {
115 bi->b_vlan_default_pvid =
117 bi->ce_mask |= BRIDGE_ATTR_VLAN_DEFAULT_PVID;
120 if (tb[IFLA_BR_VLAN_FILTERING]) {
121 bi->b_vlan_filtering =
nla_get_u8(tb[IFLA_BR_VLAN_FILTERING]);
122 bi->ce_mask |= BRIDGE_ATTR_VLAN_FILTERING;
125 if (tb[IFLA_BR_VLAN_PROTOCOL]) {
126 bi->b_vlan_protocol =
128 bi->ce_mask |= BRIDGE_ATTR_VLAN_PROTOCOL;
131 if (tb[IFLA_BR_VLAN_STATS_ENABLED]) {
132 bi->b_vlan_stats_enabled =
134 bi->ce_mask |= BRIDGE_ATTR_VLAN_STATS_ENABLED;
137 if (tb[IFLA_BR_NF_CALL_IPTABLES]) {
138 bi->b_nf_call_iptables =
140 bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IPTABLES;
143 if (tb[IFLA_BR_NF_CALL_IP6TABLES]) {
144 bi->b_nf_call_ip6tables =
146 bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IP6TABLES;
149 if (tb[IFLA_BR_NF_CALL_ARPTABLES]) {
150 bi->b_nf_call_arptables =
152 bi->ce_mask |= BRIDGE_ATTR_NF_CALL_ARPTABLES;
155 if (tb[IFLA_BR_STP_STATE]) {
156 bi->b_stp_state =
nla_get_u32(tb[IFLA_BR_STP_STATE]);
157 bi->ce_mask |= BRIDGE_ATTR_STP_STATE;
160 if (tb[IFLA_BR_MCAST_ROUTER]) {
161 bi->b_mcast_router =
nla_get_u8(tb[IFLA_BR_MCAST_ROUTER]);
162 bi->ce_mask |= BRIDGE_ATTR_MCAST_ROUTER;
165 if (tb[IFLA_BR_MCAST_SNOOPING]) {
166 bi->b_mcast_snooping =
nla_get_u8(tb[IFLA_BR_MCAST_SNOOPING]);
167 bi->ce_mask |= BRIDGE_ATTR_MCAST_SNOOPING;
170 if (tb[IFLA_BR_MULTI_BOOLOPT]) {
171 nla_memcpy(&bi->b_boolopts, tb[IFLA_BR_MULTI_BOOLOPT],
172 sizeof(bi->b_boolopts));
173 bi->ce_mask |= BRIDGE_ATTR_BOOLOPT;
179static int bridge_info_put_attrs(
struct nl_msg *msg,
struct rtnl_link *link)
188 if (bi->ce_mask & BRIDGE_ATTR_AGEING_TIME)
189 NLA_PUT_U32(msg, IFLA_BR_AGEING_TIME, bi->b_ageing_time);
191 if (bi->ce_mask & BRIDGE_ATTR_VLAN_FILTERING)
192 NLA_PUT_U8(msg, IFLA_BR_VLAN_FILTERING, bi->b_vlan_filtering);
194 if (bi->ce_mask & BRIDGE_ATTR_VLAN_DEFAULT_PVID)
196 bi->b_vlan_default_pvid);
198 if (bi->ce_mask & BRIDGE_ATTR_VLAN_PROTOCOL)
200 htons(bi->b_vlan_protocol));
202 if (bi->ce_mask & BRIDGE_ATTR_VLAN_STATS_ENABLED)
204 bi->b_vlan_stats_enabled);
206 if (bi->ce_mask & BRIDGE_ATTR_NF_CALL_IPTABLES)
208 bi->b_nf_call_iptables);
210 if (bi->ce_mask & BRIDGE_ATTR_NF_CALL_IP6TABLES)
212 bi->b_nf_call_ip6tables);
214 if (bi->ce_mask & BRIDGE_ATTR_NF_CALL_ARPTABLES)
216 bi->b_nf_call_arptables);
218 if (bi->ce_mask & BRIDGE_ATTR_STP_STATE)
219 NLA_PUT_U32(msg, IFLA_BR_STP_STATE, bi->b_stp_state);
221 if (bi->ce_mask & BRIDGE_ATTR_MCAST_ROUTER)
222 NLA_PUT_U8(msg, IFLA_BR_MCAST_ROUTER, bi->b_mcast_router);
224 if (bi->ce_mask & BRIDGE_ATTR_MCAST_SNOOPING)
225 NLA_PUT_U8(msg, IFLA_BR_MCAST_SNOOPING, bi->b_mcast_snooping);
227 if (bi->ce_mask & BRIDGE_ATTR_BOOLOPT)
228 NLA_PUT(msg, IFLA_BR_MULTI_BOOLOPT,
sizeof(bi->b_boolopts),
239static void bridge_info_free(
struct rtnl_link *link)
241 _nl_clear_free(&link->l_info);
246 .io_alloc = bridge_info_alloc,
247 .io_parse = bridge_info_parse,
248 .io_put_attrs = bridge_info_put_attrs,
249 .io_free = bridge_info_free,
252#define IS_BRIDGE_INFO_ASSERT(link) \
254 if ((link)->l_info_ops != &bridge_info_ops) { \
255 APPBUG("Link is not a bridge link. Set type \"bridge\" first."); \
269 uint32_t ageing_time)
273 IS_BRIDGE_INFO_ASSERT(link);
275 bi->b_ageing_time = ageing_time;
277 bi->ce_mask |= BRIDGE_ATTR_AGEING_TIME;
291 uint32_t *ageing_time)
295 IS_BRIDGE_INFO_ASSERT(link);
297 if (!(bi->ce_mask & BRIDGE_ATTR_AGEING_TIME))
303 *ageing_time = bi->b_ageing_time;
318 uint8_t vlan_filtering)
322 IS_BRIDGE_INFO_ASSERT(link);
324 bi->b_vlan_filtering = vlan_filtering;
326 bi->ce_mask |= BRIDGE_ATTR_VLAN_FILTERING;
341 uint8_t *vlan_filtering)
345 IS_BRIDGE_INFO_ASSERT(link);
347 if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_FILTERING))
353 *vlan_filtering = bi->b_vlan_filtering;
368 uint16_t vlan_protocol)
372 IS_BRIDGE_INFO_ASSERT(link);
374 bi->b_vlan_protocol = vlan_protocol;
376 bi->ce_mask |= BRIDGE_ATTR_VLAN_PROTOCOL;
391 uint16_t *vlan_protocol)
395 IS_BRIDGE_INFO_ASSERT(link);
397 if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_PROTOCOL))
403 *vlan_protocol = bi->b_vlan_protocol;
418 uint16_t default_pvid)
422 IS_BRIDGE_INFO_ASSERT(link);
424 bi->b_vlan_default_pvid = default_pvid;
426 bi->ce_mask |= BRIDGE_ATTR_VLAN_DEFAULT_PVID;
441 uint16_t *default_pvid)
445 IS_BRIDGE_INFO_ASSERT(link);
447 if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_DEFAULT_PVID))
453 *default_pvid = bi->b_vlan_default_pvid;
468 uint8_t vlan_stats_enabled)
472 IS_BRIDGE_INFO_ASSERT(link);
474 bi->b_vlan_stats_enabled = vlan_stats_enabled;
476 bi->ce_mask |= BRIDGE_ATTR_VLAN_STATS_ENABLED;
491 uint8_t *vlan_stats_enabled)
495 IS_BRIDGE_INFO_ASSERT(link);
497 if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_STATS_ENABLED))
500 if (!vlan_stats_enabled)
503 *vlan_stats_enabled = bi->b_vlan_stats_enabled;
518 uint8_t call_enabled)
522 IS_BRIDGE_INFO_ASSERT(link);
524 bi->b_nf_call_iptables = call_enabled;
526 bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IPTABLES;
541 uint8_t *call_enabled)
545 IS_BRIDGE_INFO_ASSERT(link);
547 if (!(bi->ce_mask & BRIDGE_ATTR_NF_CALL_IPTABLES))
553 *call_enabled = bi->b_nf_call_iptables;
568 uint8_t call_enabled)
572 IS_BRIDGE_INFO_ASSERT(link);
574 bi->b_nf_call_ip6tables = call_enabled;
576 bi->ce_mask |= BRIDGE_ATTR_NF_CALL_IP6TABLES;
591 uint8_t *call_enabled)
595 IS_BRIDGE_INFO_ASSERT(link);
597 if (!(bi->ce_mask & BRIDGE_ATTR_NF_CALL_IP6TABLES))
603 *call_enabled = bi->b_nf_call_ip6tables;
618 uint8_t call_enabled)
622 IS_BRIDGE_INFO_ASSERT(link);
624 bi->b_nf_call_arptables = call_enabled;
626 bi->ce_mask |= BRIDGE_ATTR_NF_CALL_ARPTABLES;
641 uint8_t *call_enabled)
645 IS_BRIDGE_INFO_ASSERT(link);
647 if (!(bi->ce_mask & BRIDGE_ATTR_NF_CALL_ARPTABLES))
653 *call_enabled = bi->b_nf_call_arptables;
671 IS_BRIDGE_INFO_ASSERT(link);
673 bi->b_stp_state = stp_state;
675 bi->ce_mask |= BRIDGE_ATTR_STP_STATE;
693 IS_BRIDGE_INFO_ASSERT(link);
695 if (!(bi->ce_mask & BRIDGE_ATTR_STP_STATE))
701 *stp_state = bi->b_stp_state;
718 IS_BRIDGE_INFO_ASSERT(link);
720 bi->b_mcast_router = type;
722 bi->ce_mask |= BRIDGE_ATTR_MCAST_ROUTER;
740 IS_BRIDGE_INFO_ASSERT(link);
742 if (!(bi->ce_mask & BRIDGE_ATTR_MCAST_ROUTER))
748 *type = bi->b_mcast_router;
765 IS_BRIDGE_INFO_ASSERT(link);
767 bi->b_mcast_snooping = value;
769 bi->ce_mask |= BRIDGE_ATTR_MCAST_SNOOPING;
787 IS_BRIDGE_INFO_ASSERT(link);
789 if (!(bi->ce_mask & BRIDGE_ATTR_MCAST_SNOOPING))
795 *value = bi->b_mcast_snooping;
815 IS_BRIDGE_INFO_ASSERT(link);
817 if (opt < 0 || opt >= 32 || !(value == 0 || value == 1))
823 bi->b_boolopts.optval |= mask;
825 bi->b_boolopts.optval &= ~mask;
827 bi->b_boolopts.optmask |= mask;
828 bi->ce_mask |= BRIDGE_ATTR_BOOLOPT;
849 IS_BRIDGE_INFO_ASSERT(link);
851 if (opt < 0 || opt >= 32)
856 if (!(bi->ce_mask & BRIDGE_ATTR_BOOLOPT) ||
857 !(bi->b_boolopts.optmask & mask))
860 return !!(bi->b_boolopts.optval & mask);
863static void _nl_init bridge_info_init(
void)
868static void _nl_exit bridge_info_exit(
void)
uint32_t nla_get_u32(const struct nlattr *nla)
Return payload of 32 bit integer attribute.
uint16_t nla_get_u16(const struct nlattr *nla)
Return payload of 16 bit integer attribute.
#define NLA_PUT_U16(msg, attrtype, value)
Add 16 bit integer attribute to netlink message.
#define NLA_PUT_U8(msg, attrtype, value)
Add 8 bit integer attribute to netlink message.
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
#define NLA_PUT_U32(msg, attrtype, value)
Add 32 bit integer attribute to netlink message.
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
struct nlattr * nla_nest_start(struct nl_msg *msg, int attrtype)
Start a new level of nested attributes.
int nla_parse_nested(struct nlattr *tb[], int maxtype, struct nlattr *nla, const struct nla_policy *policy)
Create attribute index based on nested attribute.
void nla_nest_cancel(struct nl_msg *msg, const struct nlattr *attr)
Cancel the addition of a nested attribute.
int nla_nest_end(struct nl_msg *msg, struct nlattr *start)
Finalize nesting of attributes.
int rtnl_link_bridge_get_nf_call_arptables(struct rtnl_link *link, uint8_t *call_enabled)
Get call enabled flag for passing ARP traffic to arptables.
void rtnl_link_bridge_set_stp_state(struct rtnl_link *link, uint32_t stp_state)
Set STP state.
int rtnl_link_bridge_get_vlan_default_pvid(struct rtnl_link *link, uint16_t *default_pvid)
Get VLAN default pvid.
int rtnl_link_bridge_get_vlan_protocol(struct rtnl_link *link, uint16_t *vlan_protocol)
Get VLAN protocol.
void rtnl_link_bridge_set_vlan_stats_enabled(struct rtnl_link *link, uint8_t vlan_stats_enabled)
Set VLAN stats enabled flag.
void rtnl_link_bridge_set_vlan_filtering(struct rtnl_link *link, uint8_t vlan_filtering)
Set VLAN filtering flag.
void rtnl_link_bridge_set_mcast_snooping(struct rtnl_link *link, uint8_t value)
Set multicast snooping.
int rtnl_link_bridge_get_stp_state(struct rtnl_link *link, uint32_t *stp_state)
Get STP state.
int rtnl_link_bridge_get_ageing_time(struct rtnl_link *link, uint32_t *ageing_time)
Get ageing time for dynamic forwarding entries.
int rtnl_link_bridge_get_vlan_filtering(struct rtnl_link *link, uint8_t *vlan_filtering)
Get VLAN filtering flag.
void rtnl_link_bridge_set_mcast_router(struct rtnl_link *link, uint8_t type)
Set multicast router type.
void rtnl_link_bridge_set_nf_call_iptables(struct rtnl_link *link, uint8_t call_enabled)
Set call enabled flag for passing IPv4 traffic to iptables.
int rtnl_link_bridge_get_mcast_snooping(struct rtnl_link *link, uint8_t *value)
Get multicast snooping value.
void rtnl_link_bridge_set_ageing_time(struct rtnl_link *link, uint32_t ageing_time)
Set ageing time for dynamic forwarding entries.
int rtnl_link_bridge_get_boolopt(struct rtnl_link *link, int opt)
Get the value of a boolopt.
void rtnl_link_bridge_set_nf_call_arptables(struct rtnl_link *link, uint8_t call_enabled)
Set call enabled flag for passing ARP traffic to arptables.
int rtnl_link_bridge_get_vlan_stats_enabled(struct rtnl_link *link, uint8_t *vlan_stats_enabled)
Get VLAN stats enabled flag.
int rtnl_link_bridge_set_boolopt(struct rtnl_link *link, int opt, int value)
Set a the value of a boolopt.
void rtnl_link_bridge_set_vlan_protocol(struct rtnl_link *link, uint16_t vlan_protocol)
Set VLAN protocol.
int rtnl_link_bridge_get_mcast_router(struct rtnl_link *link, uint8_t *type)
Get multicast router type.
int rtnl_link_bridge_get_nf_call_iptables(struct rtnl_link *link, uint8_t *call_enabled)
Get call enabled flag for passing IPv4 traffic to iptables.
void rtnl_link_bridge_set_nf_call_ip6tables(struct rtnl_link *link, uint8_t call_enabled)
Set call enabled flag for passing IPv6 traffic to ip6tables.
int rtnl_link_bridge_get_nf_call_ip6tables(struct rtnl_link *link, uint8_t *call_enabled)
Get call enabled flag for passing IPv6 traffic to iptables.
void rtnl_link_bridge_set_vlan_default_pvid(struct rtnl_link *link, uint16_t default_pvid)
Set VLAN default pvid.
int rtnl_link_register_info(struct rtnl_link_info_ops *ops)
Register operations for a link info type.
int rtnl_link_unregister_info(struct rtnl_link_info_ops *ops)
Unregister operations for a link info type.
Attribute validation policy.
uint16_t type
Type of attribute or NLA_UNSPEC.
Available operations to modules implementing a link info type.
char * io_name
Name of link info type, must match name on kernel side.