mirror of
				git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
				synced 2025-09-18 22:14:16 +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
					
				
					 2 changed files with 20 additions and 2 deletions
				
			
		|  | @ -182,6 +182,7 @@ enum { | |||
| 	MDB_RTR_TYPE_DISABLED, | ||||
| 	MDB_RTR_TYPE_TEMP_QUERY, | ||||
| 	MDB_RTR_TYPE_PERM, | ||||
| 	MDB_RTR_TYPE_TEMP | ||||
| }; | ||||
| 
 | ||||
| enum { | ||||
|  |  | |||
|  | @ -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; | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Nikolay Aleksandrov
						Nikolay Aleksandrov