14#include <netlink-private/netlink.h> 
   15#include <netlink/route/link/bridge_info.h> 
   16#include <netlink-private/route/link/api.h> 
   18#define BRIDGE_ATTR_VLAN_FILTERING (1 << 0) 
   19#define BRIDGE_ATTR_VLAN_PROTOCOL (1 << 1) 
   20#define BRIDGE_ATTR_VLAN_STATS_ENABLED (1 << 2) 
   24        uint16_t b_vlan_protocol;
 
   25        uint8_t b_vlan_filtering;
 
   26        uint8_t b_vlan_stats_enabled;
 
   29static const struct nla_policy bi_attrs_policy[IFLA_BR_MAX + 1] = {
 
   31        [IFLA_BR_VLAN_PROTOCOL] = { .type = 
NLA_U16 },
 
   32        [IFLA_BR_VLAN_STATS_ENABLED] = { .type = 
NLA_U8 },
 
   40static int bridge_info_alloc(
struct rtnl_link *link)
 
   45                memset(link->l_info, 0, 
sizeof(*bi));
 
   47                bi = calloc(1, 
sizeof(*bi));
 
   57static int bridge_info_parse(
struct rtnl_link *link, 
struct nlattr *data,
 
   58                             struct nlattr *xstats)
 
   60        struct nlattr *tb[IFLA_BR_MAX + 1];
 
   64        NL_DBG(3, 
"Parsing Bridge link info\n");
 
   70        if ((err = bridge_info_alloc(link)) < 0)
 
   75        if (tb[IFLA_BR_VLAN_FILTERING]) {
 
   76                bi->b_vlan_filtering = 
nla_get_u8(tb[IFLA_BR_VLAN_FILTERING]);
 
   77                bi->ce_mask |= BRIDGE_ATTR_VLAN_FILTERING;
 
   80        if (tb[IFLA_BR_VLAN_PROTOCOL]) {
 
   83                bi->ce_mask |= BRIDGE_ATTR_VLAN_PROTOCOL;
 
   86        if (tb[IFLA_BR_VLAN_STATS_ENABLED]) {
 
   87                bi->b_vlan_stats_enabled =
 
   89                bi->ce_mask |= BRIDGE_ATTR_VLAN_STATS_ENABLED;
 
   95static int bridge_info_put_attrs(
struct nl_msg *msg, 
struct rtnl_link *link)
 
  104        if (bi->ce_mask & BRIDGE_ATTR_VLAN_FILTERING)
 
  105                NLA_PUT_U8(msg, IFLA_BR_VLAN_FILTERING, bi->b_vlan_filtering);
 
  107        if (bi->ce_mask & BRIDGE_ATTR_VLAN_PROTOCOL)
 
  109                            htons(bi->b_vlan_protocol));
 
  111        if (bi->ce_mask & BRIDGE_ATTR_VLAN_STATS_ENABLED)
 
  113                           bi->b_vlan_stats_enabled);
 
  123static void bridge_info_free(
struct rtnl_link *link)
 
  125        _nl_clear_free(&link->l_info);
 
  128static struct rtnl_link_info_ops bridge_info_ops = {
 
  130        .io_alloc = bridge_info_alloc,
 
  131        .io_parse = bridge_info_parse,
 
  132        .io_put_attrs = bridge_info_put_attrs,
 
  133        .io_free = bridge_info_free,
 
  136#define IS_BRIDGE_INFO_ASSERT(link)                                                      \ 
  138                if ((link)->l_info_ops != &bridge_info_ops) {                            \ 
  139                        APPBUG("Link is not a bridge link. Set type \"bridge\" first."); \
 
  153                                         uint8_t vlan_filtering)
 
  157        IS_BRIDGE_INFO_ASSERT(link);
 
  159        bi->b_vlan_filtering = vlan_filtering;
 
  161        bi->ce_mask |= BRIDGE_ATTR_VLAN_FILTERING;
 
  176                                        uint8_t *vlan_filtering)
 
  180        IS_BRIDGE_INFO_ASSERT(link);
 
  182        if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_FILTERING))
 
  188        *vlan_filtering = bi->b_vlan_filtering;
 
  203                                        uint16_t vlan_protocol)
 
  207        IS_BRIDGE_INFO_ASSERT(link);
 
  209        bi->b_vlan_protocol = vlan_protocol;
 
  211        bi->ce_mask |= BRIDGE_ATTR_VLAN_PROTOCOL;
 
  226                                       uint16_t *vlan_protocol)
 
  230        IS_BRIDGE_INFO_ASSERT(link);
 
  232        if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_PROTOCOL))
 
  238        *vlan_protocol = bi->b_vlan_protocol;
 
  253                                             uint8_t vlan_stats_enabled)
 
  257        IS_BRIDGE_INFO_ASSERT(link);
 
  259        bi->b_vlan_stats_enabled = vlan_stats_enabled;
 
  261        bi->ce_mask |= BRIDGE_ATTR_VLAN_STATS_ENABLED;
 
  276                                            uint8_t *vlan_stats_enabled)
 
  280        IS_BRIDGE_INFO_ASSERT(link);
 
  282        if (!(bi->ce_mask & BRIDGE_ATTR_VLAN_STATS_ENABLED))
 
  285        if (!vlan_stats_enabled)
 
  288        *vlan_stats_enabled = bi->b_vlan_stats_enabled;
 
  293static void __init bridge_info_init(
void)
 
  298static void __exit bridge_info_exit(
void)
 
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.
 
uint8_t nla_get_u8(const struct nlattr *nla)
Return value of 8 bit integer attribute.
 
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_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.
 
int rtnl_link_bridge_get_vlan_filtering(struct rtnl_link *link, uint8_t *vlan_filtering)
Get VLAN filtering flag.
 
int rtnl_link_bridge_get_vlan_stats_enabled(struct rtnl_link *link, uint8_t *vlan_stats_enabled)
Get VLAN stats enabled flag.
 
void rtnl_link_bridge_set_vlan_protocol(struct rtnl_link *link, uint16_t vlan_protocol)
Set VLAN protocol.
 
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.