tunneling: Separate out multicast port pools.
authorJesse Gross <jesse@nicira.com>
Tue, 8 Nov 2011 04:01:52 +0000 (20:01 -0800)
committerJesse Gross <jesse@nicira.com>
Tue, 8 Nov 2011 06:21:12 +0000 (22:21 -0800)
Currently multicast and unicast tunnel ports share port pools but
there's no overlap between the two in the lookup, which means that
we can do a lookup that has no chance of ever finding a port.  This
separates them out.

Suggested-by: Ben Pfaff <blp@nicira.com>
Signed-off-by: Jesse Gross <jesse@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
datapath/tunnel.c

index 6c0e9b7e35e9d0f64ae66632cfd7f1e4655ec064..024861fc4f03677f8b44b72636f955ee796c8a6d 100644 (file)
@@ -86,8 +86,10 @@ static DECLARE_DELAYED_WORK(cache_cleaner_wq, cache_cleaner);
  */
 static unsigned int key_local_remote_ports __read_mostly;
 static unsigned int key_remote_ports __read_mostly;
+static unsigned int key_multicast_ports __read_mostly;
 static unsigned int local_remote_ports __read_mostly;
 static unsigned int remote_ports __read_mostly;
+static unsigned int multicast_ports __read_mostly;
 
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,36)
 #define rt_dst(rt) (rt->dst)
@@ -191,14 +193,20 @@ static void assign_cache_rcu(struct vport *vport, struct tnl_cache *new_cache)
 
 static unsigned int *find_port_pool(const struct tnl_mutable_config *mutable)
 {
+       bool is_multicast = ipv4_is_multicast(mutable->key.daddr);
+
        if (mutable->flags & TNL_F_IN_KEY_MATCH) {
                if (mutable->key.saddr)
                        return &local_remote_ports;
+               else if (is_multicast)
+                       return &multicast_ports;
                else
                        return &remote_ports;
        } else {
                if (mutable->key.saddr)
                        return &key_local_remote_ports;
+               else if (is_multicast)
+                       return &key_multicast_ports;
                else
                        return &key_remote_ports;
        }
@@ -328,14 +336,14 @@ struct vport *tnl_find_port(__be32 saddr, __be32 daddr, __be64 key,
        if (is_multicast) {
                lookup.saddr = 0;
                lookup.daddr = saddr;
-               if (key_remote_ports) {
+               if (key_multicast_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) {
+               if (multicast_ports) {
                        lookup.tunnel_type = tunnel_type | TNL_T_KEY_MATCH;
                        lookup.in_key = 0;
                        vport = port_table_lookup(&lookup, mutable);