Skip to content

Commit 4ec6207

Browse files
committed
Merge branch 'bridge-mcast-tmp-router-port'
Nikolay Aleksandrov says: ==================== bridge: mcast: add support for temp router port This set adds support for temporary router port which doesn't depend only on the incoming queries. It can be refreshed by setting multicast_router to the same value (3). The first two patches are minor changes that prepare the code for the third which adds this new type of router port. In order to be able to dump its information the mdb router port format is changed in patch 04 and extended similar to how mdb entries format was done recently. The related iproute2 changes will be posted if this is accepted. v2: set val first and adjust router type later in patch 01, patch 03 was split in 2 ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents ec1606c + 59f78f9 commit 4ec6207

File tree

3 files changed

+89
-32
lines changed

3 files changed

+89
-32
lines changed

include/uapi/linux/if_bridge.h

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,10 @@ struct bridge_vlan_info {
144144
* }
145145
* }
146146
* [MDBA_ROUTER] = {
147-
* [MDBA_ROUTER_PORT]
147+
* [MDBA_ROUTER_PORT] = {
148+
* u32 ifindex
149+
* [MDBA_ROUTER_PATTR attributes]
150+
* }
148151
* }
149152
*/
150153
enum {
@@ -177,13 +180,30 @@ enum {
177180
};
178181
#define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
179182

183+
/* multicast router types */
184+
enum {
185+
MDB_RTR_TYPE_DISABLED,
186+
MDB_RTR_TYPE_TEMP_QUERY,
187+
MDB_RTR_TYPE_PERM,
188+
MDB_RTR_TYPE_TEMP
189+
};
190+
180191
enum {
181192
MDBA_ROUTER_UNSPEC,
182193
MDBA_ROUTER_PORT,
183194
__MDBA_ROUTER_MAX,
184195
};
185196
#define MDBA_ROUTER_MAX (__MDBA_ROUTER_MAX - 1)
186197

198+
/* router port attributes */
199+
enum {
200+
MDBA_ROUTER_PATTR_UNSPEC,
201+
MDBA_ROUTER_PATTR_TIMER,
202+
MDBA_ROUTER_PATTR_TYPE,
203+
__MDBA_ROUTER_PATTR_MAX
204+
};
205+
#define MDBA_ROUTER_PATTR_MAX (__MDBA_ROUTER_PATTR_MAX - 1)
206+
187207
struct br_port_msg {
188208
__u8 family;
189209
__u32 ifindex;

net/bridge/br_mdb.c

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
2020
{
2121
struct net_bridge *br = netdev_priv(dev);
2222
struct net_bridge_port *p;
23-
struct nlattr *nest;
23+
struct nlattr *nest, *port_nest;
2424

2525
if (!br->multicast_router || hlist_empty(&br->router_list))
2626
return 0;
@@ -30,8 +30,20 @@ static int br_rports_fill_info(struct sk_buff *skb, struct netlink_callback *cb,
3030
return -EMSGSIZE;
3131

3232
hlist_for_each_entry_rcu(p, &br->router_list, rlist) {
33-
if (p && nla_put_u32(skb, MDBA_ROUTER_PORT, p->dev->ifindex))
33+
if (!p)
34+
continue;
35+
port_nest = nla_nest_start(skb, MDBA_ROUTER_PORT);
36+
if (!port_nest)
3437
goto fail;
38+
if (nla_put_nohdr(skb, sizeof(u32), &p->dev->ifindex) ||
39+
nla_put_u32(skb, MDBA_ROUTER_PATTR_TIMER,
40+
br_timer_value(&p->multicast_router_timer)) ||
41+
nla_put_u8(skb, MDBA_ROUTER_PATTR_TYPE,
42+
p->multicast_router)) {
43+
nla_nest_cancel(skb, port_nest);
44+
goto fail;
45+
}
46+
nla_nest_end(skb, port_nest);
3547
}
3648

3749
nla_nest_end(skb, nest);

net/bridge/br_multicast.c

Lines changed: 54 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -759,13 +759,17 @@ static void br_multicast_router_expired(unsigned long data)
759759
struct net_bridge *br = port->br;
760760

761761
spin_lock(&br->multicast_lock);
762-
if (port->multicast_router != 1 ||
762+
if (port->multicast_router == MDB_RTR_TYPE_DISABLED ||
763+
port->multicast_router == MDB_RTR_TYPE_PERM ||
763764
timer_pending(&port->multicast_router_timer) ||
764765
hlist_unhashed(&port->rlist))
765766
goto out;
766767

767768
hlist_del_init_rcu(&port->rlist);
768769
br_rtr_notify(br->dev, port, RTM_DELMDB);
770+
/* Don't allow timer refresh if the router expired */
771+
if (port->multicast_router == MDB_RTR_TYPE_TEMP)
772+
port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
769773

770774
out:
771775
spin_unlock(&br->multicast_lock);
@@ -912,7 +916,7 @@ static void br_ip6_multicast_port_query_expired(unsigned long data)
912916

913917
void br_multicast_add_port(struct net_bridge_port *port)
914918
{
915-
port->multicast_router = 1;
919+
port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
916920

917921
setup_timer(&port->multicast_router_timer, br_multicast_router_expired,
918922
(unsigned long)port);
@@ -959,7 +963,8 @@ void br_multicast_enable_port(struct net_bridge_port *port)
959963
#if IS_ENABLED(CONFIG_IPV6)
960964
br_multicast_enable(&port->ip6_own_query);
961965
#endif
962-
if (port->multicast_router == 2 && hlist_unhashed(&port->rlist))
966+
if (port->multicast_router == MDB_RTR_TYPE_PERM &&
967+
hlist_unhashed(&port->rlist))
963968
br_multicast_add_router(br, port);
964969

965970
out:
@@ -980,6 +985,9 @@ void br_multicast_disable_port(struct net_bridge_port *port)
980985
if (!hlist_unhashed(&port->rlist)) {
981986
hlist_del_init_rcu(&port->rlist);
982987
br_rtr_notify(br->dev, port, RTM_DELMDB);
988+
/* Don't allow timer refresh if disabling */
989+
if (port->multicast_router == MDB_RTR_TYPE_TEMP)
990+
port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
983991
}
984992
del_timer(&port->multicast_router_timer);
985993
del_timer(&port->ip4_own_query.timer);
@@ -1227,13 +1235,14 @@ static void br_multicast_mark_router(struct net_bridge *br,
12271235
unsigned long now = jiffies;
12281236

12291237
if (!port) {
1230-
if (br->multicast_router == 1)
1238+
if (br->multicast_router == MDB_RTR_TYPE_TEMP_QUERY)
12311239
mod_timer(&br->multicast_router_timer,
12321240
now + br->multicast_querier_interval);
12331241
return;
12341242
}
12351243

1236-
if (port->multicast_router != 1)
1244+
if (port->multicast_router == MDB_RTR_TYPE_DISABLED ||
1245+
port->multicast_router == MDB_RTR_TYPE_PERM)
12371246
return;
12381247

12391248
br_multicast_add_router(br, port);
@@ -1713,7 +1722,7 @@ void br_multicast_init(struct net_bridge *br)
17131722
br->hash_elasticity = 4;
17141723
br->hash_max = 512;
17151724

1716-
br->multicast_router = 1;
1725+
br->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
17171726
br->multicast_querier = 0;
17181727
br->multicast_query_use_ifaddr = 0;
17191728
br->multicast_last_member_count = 2;
@@ -1823,11 +1832,11 @@ int br_multicast_set_router(struct net_bridge *br, unsigned long val)
18231832
spin_lock_bh(&br->multicast_lock);
18241833

18251834
switch (val) {
1826-
case 0:
1827-
case 2:
1835+
case MDB_RTR_TYPE_DISABLED:
1836+
case MDB_RTR_TYPE_PERM:
18281837
del_timer(&br->multicast_router_timer);
18291838
/* fall through */
1830-
case 1:
1839+
case MDB_RTR_TYPE_TEMP_QUERY:
18311840
br->multicast_router = val;
18321841
err = 0;
18331842
break;
@@ -1838,37 +1847,53 @@ int br_multicast_set_router(struct net_bridge *br, unsigned long val)
18381847
return err;
18391848
}
18401849

1850+
static void __del_port_router(struct net_bridge_port *p)
1851+
{
1852+
if (hlist_unhashed(&p->rlist))
1853+
return;
1854+
hlist_del_init_rcu(&p->rlist);
1855+
br_rtr_notify(p->br->dev, p, RTM_DELMDB);
1856+
}
1857+
18411858
int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val)
18421859
{
18431860
struct net_bridge *br = p->br;
1861+
unsigned long now = jiffies;
18441862
int err = -EINVAL;
18451863

18461864
spin_lock(&br->multicast_lock);
1847-
1848-
switch (val) {
1849-
case 0:
1850-
case 1:
1851-
case 2:
1852-
p->multicast_router = val;
1865+
if (p->multicast_router == val) {
1866+
/* Refresh the temp router port timer */
1867+
if (p->multicast_router == MDB_RTR_TYPE_TEMP)
1868+
mod_timer(&p->multicast_router_timer,
1869+
now + br->multicast_querier_interval);
18531870
err = 0;
1854-
1855-
if (val < 2 && !hlist_unhashed(&p->rlist)) {
1856-
hlist_del_init_rcu(&p->rlist);
1857-
br_rtr_notify(br->dev, p, RTM_DELMDB);
1858-
}
1859-
1860-
if (val == 1)
1861-
break;
1862-
1871+
goto unlock;
1872+
}
1873+
switch (val) {
1874+
case MDB_RTR_TYPE_DISABLED:
1875+
p->multicast_router = MDB_RTR_TYPE_DISABLED;
1876+
__del_port_router(p);
1877+
del_timer(&p->multicast_router_timer);
1878+
break;
1879+
case MDB_RTR_TYPE_TEMP_QUERY:
1880+
p->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
1881+
__del_port_router(p);
1882+
break;
1883+
case MDB_RTR_TYPE_PERM:
1884+
p->multicast_router = MDB_RTR_TYPE_PERM;
18631885
del_timer(&p->multicast_router_timer);
1864-
1865-
if (val == 0)
1866-
break;
1867-
18681886
br_multicast_add_router(br, p);
18691887
break;
1888+
case MDB_RTR_TYPE_TEMP:
1889+
p->multicast_router = MDB_RTR_TYPE_TEMP;
1890+
br_multicast_mark_router(br, p);
1891+
break;
1892+
default:
1893+
goto unlock;
18701894
}
1871-
1895+
err = 0;
1896+
unlock:
18721897
spin_unlock(&br->multicast_lock);
18731898

18741899
return err;

0 commit comments

Comments
 (0)