net: bridge: vlan: dump mcast ctx querier state
[linux-2.6-microblaze.git] / net / bridge / br_vlan_options.c
index cd8320b..49dec53 100644 (file)
@@ -272,6 +272,7 @@ bool br_vlan_global_opts_can_enter_range(const struct net_bridge_vlan *v_curr,
 bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
                              const struct net_bridge_vlan *v_opts)
 {
+       struct nlattr *nest2 __maybe_unused;
        u64 clockval __maybe_unused;
        struct nlattr *nest;
 
@@ -294,7 +295,13 @@ bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
            nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT,
                        v_opts->br_mcast_ctx.multicast_last_member_count) ||
            nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT,
-                       v_opts->br_mcast_ctx.multicast_startup_query_count))
+                       v_opts->br_mcast_ctx.multicast_startup_query_count) ||
+           nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER,
+                      v_opts->br_mcast_ctx.multicast_querier) ||
+           nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_ROUTER,
+                      v_opts->br_mcast_ctx.multicast_router) ||
+           br_multicast_dump_querier_state(skb, &v_opts->br_mcast_ctx,
+                                           BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE))
                goto out_err;
 
        clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval);
@@ -317,6 +324,27 @@ bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range,
        if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL,
                              clockval, BRIDGE_VLANDB_GOPTS_PAD))
                goto out_err;
+       clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_startup_query_interval);
+       if (nla_put_u64_64bit(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL,
+                             clockval, BRIDGE_VLANDB_GOPTS_PAD))
+               goto out_err;
+
+       if (br_rports_have_mc_router(&v_opts->br_mcast_ctx)) {
+               nest2 = nla_nest_start(skb,
+                                      BRIDGE_VLANDB_GOPTS_MCAST_ROUTER_PORTS);
+               if (!nest2)
+                       goto out_err;
+
+               rcu_read_lock();
+               if (br_rports_fill_info(skb, &v_opts->br_mcast_ctx)) {
+                       rcu_read_unlock();
+                       nla_nest_cancel(skb, nest2);
+                       goto out_err;
+               }
+               rcu_read_unlock();
+
+               nla_nest_end(skb, nest2);
+       }
 
 #if IS_ENABLED(CONFIG_IPV6)
        if (nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION,
@@ -350,6 +378,10 @@ static size_t rtnl_vlan_global_opts_nlmsg_size(void)
                + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL */
                + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL */
                + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */
+               + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */
+               + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */
+               + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER */
+               + br_multicast_querier_state_size() /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_STATE */
 #endif
                + nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */
 }
@@ -473,6 +505,31 @@ static int br_vlan_process_global_one_opts(const struct net_bridge *br,
                v->br_mcast_ctx.multicast_query_response_interval = clock_t_to_jiffies(val);
                *changed = true;
        }
+       if (tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]) {
+               u64 val;
+
+               val = nla_get_u64(tb[BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL]);
+               v->br_mcast_ctx.multicast_startup_query_interval = clock_t_to_jiffies(val);
+               *changed = true;
+       }
+       if (tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]) {
+               u8 val;
+
+               val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]);
+               err = br_multicast_set_querier(&v->br_mcast_ctx, val);
+               if (err)
+                       return err;
+               *changed = true;
+       }
+       if (tb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER]) {
+               u8 val;
+
+               val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER]);
+               err = br_multicast_set_router(&v->br_mcast_ctx, val);
+               if (err)
+                       return err;
+               *changed = true;
+       }
 #if IS_ENABLED(CONFIG_IPV6)
        if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) {
                u8 ver;
@@ -495,12 +552,15 @@ static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = {
        [BRIDGE_VLANDB_GOPTS_MCAST_SNOOPING]    = { .type = NLA_U8 },
        [BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 },
        [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 },
+       [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER]     = { .type = NLA_U8 },
+       [BRIDGE_VLANDB_GOPTS_MCAST_ROUTER]      = { .type = NLA_U8 },
        [BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION]        = { .type = NLA_U8 },
        [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT]     = { .type = NLA_U32 },
        [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT]   = { .type = NLA_U32 },
        [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_INTVL]   = { .type = NLA_U64 },
        [BRIDGE_VLANDB_GOPTS_MCAST_MEMBERSHIP_INTVL]    = { .type = NLA_U64 },
        [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER_INTVL]       = { .type = NLA_U64 },
+       [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL] = { .type = NLA_U64 },
        [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL] = { .type = NLA_U64 },
 };