mirror of
https://github.com/torvalds/linux.git
synced 2024-10-30 00:32:38 +00:00
bridge: mcast: add support for temporary port router
Add support for a temporary router port which doesn't depend only on the incoming query. It can be refreshed if set to the same value, which is a no-op for the rest. Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
4950cfd1e6
commit
a55d8246ab
@ -182,6 +182,7 @@ enum {
|
|||||||
MDB_RTR_TYPE_DISABLED,
|
MDB_RTR_TYPE_DISABLED,
|
||||||
MDB_RTR_TYPE_TEMP_QUERY,
|
MDB_RTR_TYPE_TEMP_QUERY,
|
||||||
MDB_RTR_TYPE_PERM,
|
MDB_RTR_TYPE_PERM,
|
||||||
|
MDB_RTR_TYPE_TEMP
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
@ -759,13 +759,17 @@ static void br_multicast_router_expired(unsigned long data)
|
|||||||
struct net_bridge *br = port->br;
|
struct net_bridge *br = port->br;
|
||||||
|
|
||||||
spin_lock(&br->multicast_lock);
|
spin_lock(&br->multicast_lock);
|
||||||
if (port->multicast_router != MDB_RTR_TYPE_TEMP_QUERY ||
|
if (port->multicast_router == MDB_RTR_TYPE_DISABLED ||
|
||||||
|
port->multicast_router == MDB_RTR_TYPE_PERM ||
|
||||||
timer_pending(&port->multicast_router_timer) ||
|
timer_pending(&port->multicast_router_timer) ||
|
||||||
hlist_unhashed(&port->rlist))
|
hlist_unhashed(&port->rlist))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
hlist_del_init_rcu(&port->rlist);
|
hlist_del_init_rcu(&port->rlist);
|
||||||
br_rtr_notify(br->dev, port, RTM_DELMDB);
|
br_rtr_notify(br->dev, port, RTM_DELMDB);
|
||||||
|
/* Don't allow timer refresh if the router expired */
|
||||||
|
if (port->multicast_router == MDB_RTR_TYPE_TEMP)
|
||||||
|
port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
spin_unlock(&br->multicast_lock);
|
spin_unlock(&br->multicast_lock);
|
||||||
@ -981,6 +985,9 @@ void br_multicast_disable_port(struct net_bridge_port *port)
|
|||||||
if (!hlist_unhashed(&port->rlist)) {
|
if (!hlist_unhashed(&port->rlist)) {
|
||||||
hlist_del_init_rcu(&port->rlist);
|
hlist_del_init_rcu(&port->rlist);
|
||||||
br_rtr_notify(br->dev, port, RTM_DELMDB);
|
br_rtr_notify(br->dev, port, RTM_DELMDB);
|
||||||
|
/* Don't allow timer refresh if disabling */
|
||||||
|
if (port->multicast_router == MDB_RTR_TYPE_TEMP)
|
||||||
|
port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
|
||||||
}
|
}
|
||||||
del_timer(&port->multicast_router_timer);
|
del_timer(&port->multicast_router_timer);
|
||||||
del_timer(&port->ip4_own_query.timer);
|
del_timer(&port->ip4_own_query.timer);
|
||||||
@ -1234,7 +1241,8 @@ static void br_multicast_mark_router(struct net_bridge *br,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (port->multicast_router != MDB_RTR_TYPE_TEMP_QUERY)
|
if (port->multicast_router == MDB_RTR_TYPE_DISABLED ||
|
||||||
|
port->multicast_router == MDB_RTR_TYPE_PERM)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
br_multicast_add_router(br, port);
|
br_multicast_add_router(br, port);
|
||||||
@ -1850,10 +1858,15 @@ static void __del_port_router(struct net_bridge_port *p)
|
|||||||
int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val)
|
int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val)
|
||||||
{
|
{
|
||||||
struct net_bridge *br = p->br;
|
struct net_bridge *br = p->br;
|
||||||
|
unsigned long now = jiffies;
|
||||||
int err = -EINVAL;
|
int err = -EINVAL;
|
||||||
|
|
||||||
spin_lock(&br->multicast_lock);
|
spin_lock(&br->multicast_lock);
|
||||||
if (p->multicast_router == val) {
|
if (p->multicast_router == val) {
|
||||||
|
/* Refresh the temp router port timer */
|
||||||
|
if (p->multicast_router == MDB_RTR_TYPE_TEMP)
|
||||||
|
mod_timer(&p->multicast_router_timer,
|
||||||
|
now + br->multicast_querier_interval);
|
||||||
err = 0;
|
err = 0;
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
@ -1872,6 +1885,10 @@ int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val)
|
|||||||
del_timer(&p->multicast_router_timer);
|
del_timer(&p->multicast_router_timer);
|
||||||
br_multicast_add_router(br, p);
|
br_multicast_add_router(br, p);
|
||||||
break;
|
break;
|
||||||
|
case MDB_RTR_TYPE_TEMP:
|
||||||
|
p->multicast_router = MDB_RTR_TYPE_TEMP;
|
||||||
|
br_multicast_mark_router(br, p);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
goto unlock;
|
goto unlock;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user