Skip to content

Commit 85b4108

Browse files
Nikolay Aleksandrovdavem330
authored andcommitted
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 <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c7fa1d9 commit 85b4108

File tree

2 files changed

+35
-4
lines changed

2 files changed

+35
-4
lines changed

include/uapi/linux/if_bridge.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,9 @@ enum {
777777
BRIDGE_QUERIER_IP_PORT,
778778
BRIDGE_QUERIER_IP_OTHER_TIMER,
779779
BRIDGE_QUERIER_PAD,
780+
BRIDGE_QUERIER_IPV6_ADDRESS,
781+
BRIDGE_QUERIER_IPV6_PORT,
782+
BRIDGE_QUERIER_IPV6_OTHER_TIMER,
780783
__BRIDGE_QUERIER_MAX
781784
};
782785
#define BRIDGE_QUERIER_MAX (__BRIDGE_QUERIER_MAX - 1)

net/bridge/br_multicast.c

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2943,15 +2943,15 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
29432943
struct net_bridge_port *p;
29442944
struct nlattr *nest;
29452945

2946-
if (!brmctx->multicast_querier &&
2947-
!timer_pending(&brmctx->ip4_other_query.timer))
2948-
return 0;
2949-
29502946
nest = nla_nest_start(skb, nest_attr);
29512947
if (!nest)
29522948
return -EMSGSIZE;
29532949

29542950
rcu_read_lock();
2951+
if (!brmctx->multicast_querier &&
2952+
!timer_pending(&brmctx->ip4_other_query.timer))
2953+
goto out_v6;
2954+
29552955
br_multicast_read_querier(&brmctx->ip4_querier, &querier);
29562956
if (nla_put_in_addr(skb, BRIDGE_QUERIER_IP_ADDRESS,
29572957
querier.addr.src.ip4)) {
@@ -2968,8 +2968,36 @@ int br_multicast_dump_querier_state(struct sk_buff *skb,
29682968
rcu_read_unlock();
29692969
goto out_err;
29702970
}
2971+
2972+
out_v6:
2973+
#if IS_ENABLED(CONFIG_IPV6)
2974+
if (!brmctx->multicast_querier &&
2975+
!timer_pending(&brmctx->ip6_other_query.timer))
2976+
goto out;
2977+
2978+
br_multicast_read_querier(&brmctx->ip6_querier, &querier);
2979+
if (nla_put_in6_addr(skb, BRIDGE_QUERIER_IPV6_ADDRESS,
2980+
&querier.addr.src.ip6)) {
2981+
rcu_read_unlock();
2982+
goto out_err;
2983+
}
2984+
2985+
p = __br_multicast_get_querier_port(brmctx->br, &querier);
2986+
if (timer_pending(&brmctx->ip6_other_query.timer) &&
2987+
(nla_put_u64_64bit(skb, BRIDGE_QUERIER_IPV6_OTHER_TIMER,
2988+
br_timer_value(&brmctx->ip6_other_query.timer),
2989+
BRIDGE_QUERIER_PAD) ||
2990+
(p && nla_put_u32(skb, BRIDGE_QUERIER_IPV6_PORT,
2991+
p->dev->ifindex)))) {
2992+
rcu_read_unlock();
2993+
goto out_err;
2994+
}
2995+
out:
2996+
#endif
29712997
rcu_read_unlock();
29722998
nla_nest_end(skb, nest);
2999+
if (!nla_len(nest))
3000+
nla_nest_cancel(skb, nest);
29733001

29743002
return 0;
29753003

0 commit comments

Comments
 (0)