Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a55d8246 authored by Nikolay Aleksandrov's avatar Nikolay Aleksandrov Committed by David S. Miller
Browse files

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: default avatarNikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 4950cfd1
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -182,6 +182,7 @@ enum {
	MDB_RTR_TYPE_DISABLED,
	MDB_RTR_TYPE_TEMP_QUERY,
	MDB_RTR_TYPE_PERM,
	MDB_RTR_TYPE_TEMP
};

enum {
+19 −2
Original line number Diff line number Diff line
@@ -759,13 +759,17 @@ static void br_multicast_router_expired(unsigned long data)
	struct net_bridge *br = port->br;

	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) ||
	    hlist_unhashed(&port->rlist))
		goto out;

	hlist_del_init_rcu(&port->rlist);
	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:
	spin_unlock(&br->multicast_lock);
@@ -981,6 +985,9 @@ void br_multicast_disable_port(struct net_bridge_port *port)
	if (!hlist_unhashed(&port->rlist)) {
		hlist_del_init_rcu(&port->rlist);
		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->ip4_own_query.timer);
@@ -1234,7 +1241,8 @@ static void br_multicast_mark_router(struct net_bridge *br,
		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;

	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)
{
	struct net_bridge *br = p->br;
	unsigned long now = jiffies;
	int err = -EINVAL;

	spin_lock(&br->multicast_lock);
	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;
		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);
		br_multicast_add_router(br, p);
		break;
	case MDB_RTR_TYPE_TEMP:
		p->multicast_router = MDB_RTR_TYPE_TEMP;
		br_multicast_mark_router(br, p);
		break;
	default:
		goto unlock;
	}