Add support to change and retrieve global vlan multicast router state which is used for the bridge itself. We just need to pass multicast context to br_multicast_set_router instead of bridge device and the rest of the logic remains the same.
Unified · Split
| @@ -561,6 +561,7 @@ enum { · 560 unmodified lines | |||
| 561 | BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL, | 561 | BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL, |
| 562 | BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL, | 562 | BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL, |
| 563 | BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, | 563 | BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, |
| 564 | BRIDGE_VLANDB_GOPTS_MCAST_ROUTER, | ||
| 564 | __BRIDGE_VLANDB_GOPTS_MAX | 565 | __BRIDGE_VLANDB_GOPTS_MAX |
| 565 | }; | 566 | }; |
| 566 | #define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1) | 567 | #define BRIDGE_VLANDB_GOPTS_MAX (__BRIDGE_VLANDB_GOPTS_MAX - 1) |
| @@ -4053,17 +4053,16 @@ void br_multicast_dev_del(struct net_bridge *br) · 4052 unmodified lines | |||
| 4053 | rcu_barrier(); | 4053 | rcu_barrier(); |
| 4054 | } | 4054 | } |
| 4055 | 4055 | ||
| 4056 | int br_multicast_set_router(struct net_bridge *br, unsigned long val) | 4056 | int br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val) |
| 4057 | { | 4057 | { |
| 4058 | struct net_bridge_mcast *brmctx = &br->multicast_ctx; | ||
| 4059 | int err = -EINVAL; | 4058 | int err = -EINVAL; |
| 4060 | 4059 | ||
| 4061 | spin_lock_bh(&br->multicast_lock); | 4060 | spin_lock_bh(&brmctx->br->multicast_lock); |
| 4062 | 4061 | ||
| 4063 | switch (val) { | 4062 | switch (val) { |
| 4064 | case MDB_RTR_TYPE_DISABLED: | 4063 | case MDB_RTR_TYPE_DISABLED: |
| 4065 | case MDB_RTR_TYPE_PERM: | 4064 | case MDB_RTR_TYPE_PERM: |
| 4066 | br_mc_router_state_change(br, val == MDB_RTR_TYPE_PERM); | 4065 | br_mc_router_state_change(brmctx->br, val == MDB_RTR_TYPE_PERM); |
| 4067 | del_timer(&brmctx->ip4_mc_router_timer); | 4066 | del_timer(&brmctx->ip4_mc_router_timer); |
| 4068 | #if IS_ENABLED(CONFIG_IPV6) | 4067 | #if IS_ENABLED(CONFIG_IPV6) |
| 4069 | del_timer(&brmctx->ip6_mc_router_timer); | 4068 | del_timer(&brmctx->ip6_mc_router_timer); |
| @@ -4073,13 +4072,13 @@ int br_multicast_set_router(struct net_bridge *br, unsigned long val) · 3 unmodified lines | |||
| 4073 | break; | 4072 | break; |
| 4074 | case MDB_RTR_TYPE_TEMP_QUERY: | 4073 | case MDB_RTR_TYPE_TEMP_QUERY: |
| 4075 | if (brmctx->multicast_router != MDB_RTR_TYPE_TEMP_QUERY) | 4074 | if (brmctx->multicast_router != MDB_RTR_TYPE_TEMP_QUERY) |
| 4076 | br_mc_router_state_change(br, false); | 4075 | br_mc_router_state_change(brmctx->br, false); |
| 4077 | brmctx->multicast_router = val; | 4076 | brmctx->multicast_router = val; |
| 4078 | err = 0; | 4077 | err = 0; |
| 4079 | break; | 4078 | break; |
| 4080 | } | 4079 | } |
| 4081 | 4080 | ||
| 4082 | spin_unlock_bh(&br->multicast_lock); | 4081 | spin_unlock_bh(&brmctx->br->multicast_lock); |
| 4083 | 4082 | ||
| 4084 | return err; | 4083 | return err; |
| 4085 | } | 4084 | } |
| @@ -1286,7 +1286,8 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[], · 1285 unmodified lines | |||
| 1286 | if (data[IFLA_BR_MCAST_ROUTER]) { | 1286 | if (data[IFLA_BR_MCAST_ROUTER]) { |
| 1287 | u8 multicast_router = nla_get_u8(data[IFLA_BR_MCAST_ROUTER]); | 1287 | u8 multicast_router = nla_get_u8(data[IFLA_BR_MCAST_ROUTER]); |
| 1288 | 1288 | ||
| 1289 | err = br_multicast_set_router(br, multicast_router); | 1289 | err = br_multicast_set_router(&br->multicast_ctx, |
| 1290 | multicast_router); | ||
| 1290 | if (err) | 1291 | if (err) |
| 1291 | return err; | 1292 | return err; |
| 1292 | } | 1293 | } |
| @@ -877,7 +877,7 @@ void br_multicast_dev_del(struct net_bridge *br); · 876 unmodified lines | |||
| 877 | void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb, | 877 | void br_multicast_flood(struct net_bridge_mdb_entry *mdst, struct sk_buff *skb, |
| 878 | struct net_bridge_mcast *brmctx, | 878 | struct net_bridge_mcast *brmctx, |
| 879 | bool local_rcv, bool local_orig); | 879 | bool local_rcv, bool local_orig); |
| 880 | int br_multicast_set_router(struct net_bridge *br, unsigned long val); | 880 | int br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val); |
| 881 | int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val); | 881 | int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val); |
| 882 | int br_multicast_toggle(struct net_bridge *br, unsigned long val, | 882 | int br_multicast_toggle(struct net_bridge *br, unsigned long val, |
| 883 | struct netlink_ext_ack *extack); | 883 | struct netlink_ext_ack *extack); |
| @@ -1191,6 +1191,7 @@ br_multicast_ctx_options_equal(const struct net_bridge_mcast *brmctx1, · 307 unmodified lines | |||
| 1191 | brmctx1->multicast_startup_query_interval == | 1191 | brmctx1->multicast_startup_query_interval == |
| 1192 | brmctx2->multicast_startup_query_interval && | 1192 | brmctx2->multicast_startup_query_interval && |
| 1193 | brmctx1->multicast_querier == brmctx2->multicast_querier && | 1193 | brmctx1->multicast_querier == brmctx2->multicast_querier && |
| 1194 | brmctx1->multicast_router == brmctx2->multicast_router && | ||
| 1194 | #if IS_ENABLED(CONFIG_IPV6) | 1195 | #if IS_ENABLED(CONFIG_IPV6) |
| 1195 | brmctx1->multicast_mld_version == | 1196 | brmctx1->multicast_mld_version == |
| 1196 | brmctx2->multicast_mld_version && | 1197 | brmctx2->multicast_mld_version && |
| @@ -390,7 +390,7 @@ static ssize_t multicast_router_show(struct device *d, · 389 unmodified lines | |||
| 390 | static int set_multicast_router(struct net_bridge *br, unsigned long val, | 390 | static int set_multicast_router(struct net_bridge *br, unsigned long val, |
| 391 | struct netlink_ext_ack *extack) | 391 | struct netlink_ext_ack *extack) |
| 392 | { | 392 | { |
| 393 | return br_multicast_set_router(br, val); | 393 | return br_multicast_set_router(&br->multicast_ctx, val); |
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | static ssize_t multicast_router_store(struct device *d, | 396 | static ssize_t multicast_router_store(struct device *d, |
| @@ -296,7 +296,9 @@ bool br_vlan_global_opts_fill(struct sk_buff *skb, u16 vid, u16 vid_range, · 295 unmodified lines | |||
| 296 | nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT, | 296 | nla_put_u32(skb, BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT, |
| 297 | v_opts->br_mcast_ctx.multicast_startup_query_count) || | 297 | v_opts->br_mcast_ctx.multicast_startup_query_count) || |
| 298 | nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, | 298 | nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_QUERIER, |
| 299 | v_opts->br_mcast_ctx.multicast_querier)) | 299 | v_opts->br_mcast_ctx.multicast_querier) || |
| 300 | nla_put_u8(skb, BRIDGE_VLANDB_GOPTS_MCAST_ROUTER, | ||
| 301 | v_opts->br_mcast_ctx.multicast_router)) | ||
| 300 | goto out_err; | 302 | goto out_err; |
| 301 | 303 | ||
| 302 | clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval); | 304 | clockval = jiffies_to_clock_t(v_opts->br_mcast_ctx.multicast_last_member_interval); |
| @@ -358,6 +360,7 @@ static size_t rtnl_vlan_global_opts_nlmsg_size(void) · 55 unmodified lines | |||
| 358 | + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */ | 360 | + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERY_RESPONSE_INTVL */ |
| 359 | + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */ | 361 | + nla_total_size(sizeof(u64)) /* BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_INTVL */ |
| 360 | + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */ | 362 | + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_QUERIER */ |
| 363 | + nla_total_size(sizeof(u8)) /* BRIDGE_VLANDB_GOPTS_MCAST_ROUTER */ | ||
| 361 | #endif | 364 | #endif |
| 362 | + nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */ | 365 | + nla_total_size(sizeof(u16)); /* BRIDGE_VLANDB_GOPTS_RANGE */ |
| 363 | } | 366 | } |
| @@ -497,6 +500,15 @@ static int br_vlan_process_global_one_opts(const struct net_bridge *br, · 133 unmodified lines | |||
| 497 | return err; | 500 | return err; |
| 498 | *changed = true; | 501 | *changed = true; |
| 499 | } | 502 | } |
| 503 | if (tb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER]) { | ||
| 504 | u8 val; | ||
| 505 | |||
| 506 | val = nla_get_u8(tb[BRIDGE_VLANDB_GOPTS_MCAST_ROUTER]); | ||
| 507 | err = br_multicast_set_router(&v->br_mcast_ctx, val); | ||
| 508 | if (err) | ||
| 509 | return err; | ||
| 510 | *changed = true; | ||
| 511 | } | ||
| 500 | #if IS_ENABLED(CONFIG_IPV6) | 512 | #if IS_ENABLED(CONFIG_IPV6) |
| 501 | if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) { | 513 | if (tb[BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION]) { |
| 502 | u8 ver; | 514 | u8 ver; |
| @@ -520,6 +532,7 @@ static const struct nla_policy br_vlan_db_gpol[BRIDGE_VLANDB_GOPTS_MAX + 1] = { · 17 unmodified lines | |||
| 520 | [BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 }, | 532 | [BRIDGE_VLANDB_GOPTS_MCAST_MLD_VERSION] = { .type = NLA_U8 }, |
| 521 | [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 }, | 533 | [BRIDGE_VLANDB_GOPTS_MCAST_QUERY_INTVL] = { .type = NLA_U64 }, |
| 522 | [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER] = { .type = NLA_U8 }, | 534 | [BRIDGE_VLANDB_GOPTS_MCAST_QUERIER] = { .type = NLA_U8 }, |
| 535 | [BRIDGE_VLANDB_GOPTS_MCAST_ROUTER] = { .type = NLA_U8 }, | ||
| 523 | [BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION] = { .type = NLA_U8 }, | 536 | [BRIDGE_VLANDB_GOPTS_MCAST_IGMP_VERSION] = { .type = NLA_U8 }, |
| 524 | [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 }, | 537 | [BRIDGE_VLANDB_GOPTS_MCAST_LAST_MEMBER_CNT] = { .type = NLA_U32 }, |
| 525 | [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 }, | 538 | [BRIDGE_VLANDB_GOPTS_MCAST_STARTUP_QUERY_CNT] = { .type = NLA_U32 }, |