diff options
| author | Nikolay Aleksandrov <nikolay@cumulusnetworks.com> | 2019-08-17 07:22:12 -0400 |
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2019-08-17 15:36:57 -0400 |
| commit | e77b0c84e33c766728991fb637ce0ffe41be2fb1 (patch) | |
| tree | f010b9c462431e262e6151ca458be86a46aa6229 /net | |
| parent | 6545916ed9f4b805515a7546908a6b2ff2d060b5 (diff) | |
net: bridge: mdb: dump host-joined entries as well
Currently we dump only the port mdb entries but we can have host-joined
entries on the bridge itself and they should be treated as normal temp
mdbs, they're already notified:
$ bridge monitor all
[MDB]dev br0 port br0 grp ff02::8 temp
The group will not be shown in the bridge mdb output, but it takes 1 slot
and it's timing out. If it's only host-joined then the mdb show output
can even be empty.
After this patch we show the host-joined groups:
$ bridge mdb show
dev br0 port br0 grp ff02::8 temp
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
| -rw-r--r-- | net/bridge/br_mdb.c | 41 |
1 files changed, 31 insertions, 10 deletions
diff --git a/net/bridge/br_mdb.c b/net/bridge/br_mdb.c index 77730983097e..985273425117 100644 --- a/net/bridge/br_mdb.c +++ b/net/bridge/br_mdb.c | |||
| @@ -78,22 +78,35 @@ static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip) | |||
| 78 | } | 78 | } |
| 79 | 79 | ||
| 80 | static int __mdb_fill_info(struct sk_buff *skb, | 80 | static int __mdb_fill_info(struct sk_buff *skb, |
| 81 | struct net_bridge_mdb_entry *mp, | ||
| 81 | struct net_bridge_port_group *p) | 82 | struct net_bridge_port_group *p) |
| 82 | { | 83 | { |
| 84 | struct timer_list *mtimer; | ||
| 83 | struct nlattr *nest_ent; | 85 | struct nlattr *nest_ent; |
| 84 | struct br_mdb_entry e; | 86 | struct br_mdb_entry e; |
| 87 | u8 flags = 0; | ||
| 88 | int ifindex; | ||
| 85 | 89 | ||
| 86 | memset(&e, 0, sizeof(e)); | 90 | memset(&e, 0, sizeof(e)); |
| 87 | __mdb_entry_fill_flags(&e, p->flags); | 91 | if (p) { |
| 88 | e.ifindex = p->port->dev->ifindex; | 92 | ifindex = p->port->dev->ifindex; |
| 89 | e.vid = p->addr.vid; | 93 | mtimer = &p->timer; |
| 90 | if (p->addr.proto == htons(ETH_P_IP)) | 94 | flags = p->flags; |
| 91 | e.addr.u.ip4 = p->addr.u.ip4; | 95 | } else { |
| 96 | ifindex = mp->br->dev->ifindex; | ||
| 97 | mtimer = &mp->timer; | ||
| 98 | } | ||
| 99 | |||
| 100 | __mdb_entry_fill_flags(&e, flags); | ||
| 101 | e.ifindex = ifindex; | ||
| 102 | e.vid = mp->addr.vid; | ||
| 103 | if (mp->addr.proto == htons(ETH_P_IP)) | ||
| 104 | e.addr.u.ip4 = mp->addr.u.ip4; | ||
| 92 | #if IS_ENABLED(CONFIG_IPV6) | 105 | #if IS_ENABLED(CONFIG_IPV6) |
| 93 | if (p->addr.proto == htons(ETH_P_IPV6)) | 106 | if (mp->addr.proto == htons(ETH_P_IPV6)) |
| 94 | e.addr.u.ip6 = p->addr.u.ip6; | 107 | e.addr.u.ip6 = mp->addr.u.ip6; |
| 95 | #endif | 108 | #endif |
| 96 | e.addr.proto = p->addr.proto; | 109 | e.addr.proto = mp->addr.proto; |
| 97 | nest_ent = nla_nest_start_noflag(skb, | 110 | nest_ent = nla_nest_start_noflag(skb, |
| 98 | MDBA_MDB_ENTRY_INFO); | 111 | MDBA_MDB_ENTRY_INFO); |
| 99 | if (!nest_ent) | 112 | if (!nest_ent) |
| @@ -102,7 +115,7 @@ static int __mdb_fill_info(struct sk_buff *skb, | |||
| 102 | if (nla_put_nohdr(skb, sizeof(e), &e) || | 115 | if (nla_put_nohdr(skb, sizeof(e), &e) || |
| 103 | nla_put_u32(skb, | 116 | nla_put_u32(skb, |
| 104 | MDBA_MDB_EATTR_TIMER, | 117 | MDBA_MDB_EATTR_TIMER, |
| 105 | br_timer_value(&p->timer))) { | 118 | br_timer_value(mtimer))) { |
| 106 | nla_nest_cancel(skb, nest_ent); | 119 | nla_nest_cancel(skb, nest_ent); |
| 107 | return -EMSGSIZE; | 120 | return -EMSGSIZE; |
| 108 | } | 121 | } |
| @@ -139,12 +152,20 @@ static int br_mdb_fill_info(struct sk_buff *skb, struct netlink_callback *cb, | |||
| 139 | break; | 152 | break; |
| 140 | } | 153 | } |
| 141 | 154 | ||
| 155 | if (mp->host_joined) { | ||
| 156 | err = __mdb_fill_info(skb, mp, NULL); | ||
| 157 | if (err) { | ||
| 158 | nla_nest_cancel(skb, nest2); | ||
| 159 | break; | ||
| 160 | } | ||
| 161 | } | ||
| 162 | |||
| 142 | for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL; | 163 | for (pp = &mp->ports; (p = rcu_dereference(*pp)) != NULL; |
| 143 | pp = &p->next) { | 164 | pp = &p->next) { |
| 144 | if (!p->port) | 165 | if (!p->port) |
| 145 | continue; | 166 | continue; |
| 146 | 167 | ||
| 147 | err = __mdb_fill_info(skb, p); | 168 | err = __mdb_fill_info(skb, mp, p); |
| 148 | if (err) { | 169 | if (err) { |
| 149 | nla_nest_cancel(skb, nest2); | 170 | nla_nest_cancel(skb, nest2); |
| 150 | goto out; | 171 | goto out; |
