net: bridge: mcast: dump ipv6 querier state
Add support for dumping global IPv6 querier state, we dump the state only if our own querier is enabled or there has been another external querier which has won the election. For the bridge global state we use a new attribute IFLA_BR_MCAST_QUERIER_STATE and embed the state inside. The structure is: [IFLA_BR_MCAST_QUERIER_STATE] `[BRIDGE_QUERIER_IPV6_ADDRESS] - ip address of the querier `[BRIDGE_QUERIER_IPV6_PORT] - bridge port ifindex where the querier was seen (set only if external querier) `[BRIDGE_QUERIER_IPV6_OTHER_TIMER] - other querier timeout IPv4 and IPv6 attributes are embedded at the same level of IFLA_BR_MCAST_QUERIER_STATE. If we didn't dump anything we cancel the nest and return. Signed-off-by: Nikolay Aleksandrov <nikolay@nvidia.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c7fa1d9b1f
commit
85b4108211
@ -777,6 +777,9 @@ enum {
|
||||
BRIDGE_QUERIER_IP_PORT,
|
||||
BRIDGE_QUERIER_IP_OTHER_TIMER,
|
||||
BRIDGE_QUERIER_PAD,
|
||||
BRIDGE_QUERIER_IPV6_ADDRESS,
|
||||
BRIDGE_QUERIER_IPV6_PORT,
|
||||
BRIDGE_QUERIER_IPV6_OTHER_TIMER,
|
||||
__BRIDGE_QUERIER_MAX
|
||||
};
|
||||
#define BRIDGE_QUERIER_MAX (__BRIDGE_QUERIER_MAX - 1)
|
||||
|
@ -2943,15 +2943,15 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
|
||||
struct net_bridge_port *p;
|
||||
struct nlattr *nest;
|
||||
|
||||
if (!brmctx->multicast_querier &&
|
||||
!timer_pending(&brmctx->ip4_other_query.timer))
|
||||
return 0;
|
||||
|
||||
nest = nla_nest_start(skb, nest_attr);
|
||||
if (!nest)
|
||||
return -EMSGSIZE;
|
||||
|
||||
rcu_read_lock();
|
||||
if (!brmctx->multicast_querier &&
|
||||
!timer_pending(&brmctx->ip4_other_query.timer))
|
||||
goto out_v6;
|
||||
|
||||
br_multicast_read_querier(&brmctx->ip4_querier, &querier);
|
||||
if (nla_put_in_addr(skb, BRIDGE_QUERIER_IP_ADDRESS,
|
||||
querier.addr.src.ip4)) {
|
||||
@ -2968,8 +2968,36 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
|
||||
rcu_read_unlock();
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
out_v6:
|
||||
#if IS_ENABLED(CONFIG_IPV6)
|
||||
if (!brmctx->multicast_querier &&
|
||||
!timer_pending(&brmctx->ip6_other_query.timer))
|
||||
goto out;
|
||||
|
||||
br_multicast_read_querier(&brmctx->ip6_querier, &querier);
|
||||
if (nla_put_in6_addr(skb, BRIDGE_QUERIER_IPV6_ADDRESS,
|
||||
&querier.addr.src.ip6)) {
|
||||
rcu_read_unlock();
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
p = __br_multicast_get_querier_port(brmctx->br, &querier);
|
||||
if (timer_pending(&brmctx->ip6_other_query.timer) &&
|
||||
(nla_put_u64_64bit(skb, BRIDGE_QUERIER_IPV6_OTHER_TIMER,
|
||||
br_timer_value(&brmctx->ip6_other_query.timer),
|
||||
BRIDGE_QUERIER_PAD) ||
|
||||
(p && nla_put_u32(skb, BRIDGE_QUERIER_IPV6_PORT,
|
||||
p->dev->ifindex)))) {
|
||||
rcu_read_unlock();
|
||||
goto out_err;
|
||||
}
|
||||
out:
|
||||
#endif
|
||||
rcu_read_unlock();
|
||||
nla_nest_end(skb, nest);
|
||||
if (!nla_len(nest))
|
||||
nla_nest_cancel(skb, nest);
|
||||
|
||||
return 0;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user