bridge: mdb: add support for more attributes and export timer
Currently mdb entries are exported directly as a structure inside MDBA_MDB_ENTRY_INFO attribute, we can't really extend it without breaking user-space. In order to export new mdb fields, I've converted the MDBA_MDB_ENTRY_INFO into a nested attribute which starts like before with struct br_mdb_entry (without header, as it's casted directly in iproute2) and continues with MDBA_MDB_EATTR_ attributes. This way we keep compatibility with older users and can export new data. I've tested this with iproute2, both with and without support for the added attribute and it works fine. So basically we again have MDBA_MDB_ENTRY_INFO with struct br_mdb_entry inside but it may contain also some additional MDBA_MDB_EATTR_ attributes such as MDBA_MDB_EATTR_TIMER which can be parsed by user-space. So the new structure is: [MDBA_MDB] = { [MDBA_MDB_ENTRY] = { [MDBA_MDB_ENTRY_INFO] [MDBA_MDB_ENTRY_INFO] { <- Nested attribute struct br_mdb_entry <- nla_put_nohdr() [MDBA_MDB_ENTRY attributes] <- normal netlink attributes } } } Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
76cc173d48
Коммит
2125715635
|
@ -137,7 +137,10 @@ struct bridge_vlan_info {
|
|||
/* Bridge multicast database attributes
|
||||
* [MDBA_MDB] = {
|
||||
* [MDBA_MDB_ENTRY] = {
|
||||
* [MDBA_MDB_ENTRY_INFO]
|
||||
* [MDBA_MDB_ENTRY_INFO] {
|
||||
* struct br_mdb_entry
|
||||
* [MDBA_MDB_EATTR attributes]
|
||||
* }
|
||||
* }
|
||||
* }
|
||||
* [MDBA_ROUTER] = {
|
||||
|
@ -166,6 +169,14 @@ enum {
|
|||
};
|
||||
#define MDBA_MDB_ENTRY_MAX (__MDBA_MDB_ENTRY_MAX - 1)
|
||||
|
||||
/* per mdb entry additional attributes */
|
||||
enum {
|
||||
MDBA_MDB_EATTR_UNSPEC,
|
||||
MDBA_MDB_EATTR_TIMER,
|
||||
__MDBA_MDB_EATTR_MAX
|
||||
};
|
||||
#define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
|
||||
|
||||
enum {
|
||||
MDBA_ROUTER_UNSPEC,
|
||||
MDBA_ROUTER_PORT,
|
||||
|
|
|
@ -88,11 +88,13 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
for (pp = &mp->ports;
|
||||
(p = rcu_dereference(*pp)) != NULL;
|
||||
pp = &p->next) {
|
||||
struct nlattr *nest_ent;
|
||||
struct br_mdb_entry e;
|
||||
|
||||
port = p->port;
|
||||
if (!port)
|
||||
continue;
|
||||
|
||||
memset(&e, 0, sizeof(e));
|
||||
e.ifindex = port->dev->ifindex;
|
||||
e.vid = p->addr.vid;
|
||||
|
@ -104,11 +106,23 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
|
|||
e.addr.u.ip6 = p->addr.u.ip6;
|
||||
#endif
|
||||
e.addr.proto = p->addr.proto;
|
||||
if (nla_put(skb, MDBA_MDB_ENTRY_INFO, sizeof(e), &e)) {
|
||||
nest_ent = nla_nest_start(skb,
|
||||
MDBA_MDB_ENTRY_INFO);
|
||||
if (!nest_ent) {
|
||||
nla_nest_cancel(skb, nest2);
|
||||
err = -EMSGSIZE;
|
||||
goto out;
|
||||
}
|
||||
if (nla_put_nohdr(skb, sizeof(e), &e) ||
|
||||
nla_put_u32(skb,
|
||||
MDBA_MDB_EATTR_TIMER,
|
||||
br_timer_value(&p->timer))) {
|
||||
nla_nest_cancel(skb, nest_ent);
|
||||
nla_nest_cancel(skb, nest2);
|
||||
err = -EMSGSIZE;
|
||||
goto out;
|
||||
}
|
||||
nla_nest_end(skb, nest_ent);
|
||||
}
|
||||
nla_nest_end(skb, nest2);
|
||||
skip:
|
||||
|
|
Загрузка…
Ссылка в новой задаче