aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorNikolay Aleksandrov <nikolay@cumulusnetworks.com>2019-08-17 07:22:12 -0400
committerDavid S. Miller <davem@davemloft.net>2019-08-17 15:36:57 -0400
commite77b0c84e33c766728991fb637ce0ffe41be2fb1 (patch)
treef010b9c462431e262e6151ca458be86a46aa6229 /net
parent6545916ed9f4b805515a7546908a6b2ff2d060b5 (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.c41
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
80static int __mdb_fill_info(struct sk_buff *skb, 80static 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;