[ovs-dev] [PATCH] tunneling: Reduce priority of multicast tunnels.

Jesse Gross jesse at nicira.com
Sun Nov 6 20:32:45 UTC 2011


It's possible to have an incoming packet that matches both a unicast
and multicast tunnel if the source address corresponds to the remote_ip
of a unicast tunnel and the destination is multicast.  Currently this
will match the multicast tunnel but in reality the unicast tunnel
should probably be considered more specific.  This is actually a
common situation in protocols that use a combination of multicast
for flooding and unicast for responses.

Signed-off-by: Jesse Gross <jesse at nicira.com>
---
 datapath/tunnel.c |   44 ++++++++++++++++++++++----------------------
 1 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/datapath/tunnel.c b/datapath/tunnel.c
index 372d90e..372b678 100644
--- a/datapath/tunnel.c
+++ b/datapath/tunnel.c
@@ -288,26 +288,7 @@ struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key,
 {
 	struct port_lookup_key lookup;
 	struct vport *vport;
-
-	if (ipv4_is_multicast(saddr)) {
-		lookup.saddr = 0;
-		lookup.daddr = saddr;
-		if (key_remote_ports) {
-			lookup.tunnel_type = tunnel_type | TNL_T_KEY_EXACT;
-			lookup.in_key = key;
-			vport = port_table_lookup(&lookup, mutable);
-			if (vport)
-				return vport;
-		}
-		if (remote_ports) {
-			lookup.tunnel_type = tunnel_type | TNL_T_KEY_MATCH;
-			lookup.in_key = 0;
-			vport = port_table_lookup(&lookup, mutable);
-			if (vport)
-				return vport;
-		}
-		return NULL;
-	}
+	bool is_multicast = ipv4_is_multicast(saddr);
 
 	lookup.saddr = saddr;
 	lookup.daddr = daddr;
@@ -315,7 +296,7 @@ struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key,
 	/* First try for exact match on in_key. */
 	lookup.in_key = key;
 	lookup.tunnel_type = tunnel_type | TNL_T_KEY_EXACT;
-	if (key_local_remote_ports) {
+	if (!is_multicast && key_local_remote_ports) {
 		vport = port_table_lookup(&lookup, mutable);
 		if (vport)
 			return vport;
@@ -332,7 +313,7 @@ struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key,
 	/* Then try matches that wildcard in_key. */
 	lookup.in_key = 0;
 	lookup.tunnel_type = tunnel_type | TNL_T_KEY_MATCH;
-	if (local_remote_ports) {
+	if (!is_multicast && local_remote_ports) {
 		vport = port_table_lookup(&lookup, mutable);
 		if (vport)
 			return vport;
@@ -344,6 +325,25 @@ struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key,
 			return vport;
 	}
 
+	if (is_multicast) {
+		lookup.saddr = 0;
+		lookup.daddr = saddr;
+		if (key_remote_ports) {
+			lookup.tunnel_type = tunnel_type | TNL_T_KEY_EXACT;
+			lookup.in_key = key;
+			vport = port_table_lookup(&lookup, mutable);
+			if (vport)
+				return vport;
+		}
+		if (remote_ports) {
+			lookup.tunnel_type = tunnel_type | TNL_T_KEY_MATCH;
+			lookup.in_key = 0;
+			vport = port_table_lookup(&lookup, mutable);
+			if (vport)
+				return vport;
+		}
+	}
+
 	return NULL;
 }
 
-- 
1.7.5.4




More information about the dev mailing list