Bug 2041 - Fixing bug where the tunnel-id is not set in the LBaaS pipeline rules 68/11468/1
authorSrini Seetharaman <srini.seetharaman@gmail.com>
Tue, 23 Sep 2014 01:38:32 +0000 (18:38 -0700)
committerSrini Seetharaman <srini.seetharaman@gmail.com>
Tue, 23 Sep 2014 01:40:17 +0000 (18:40 -0700)
Change-Id: I552ed7823d06851677fe133f2a750dc590ab52c8
Signed-off-by: Srini Seetharaman <srini.seetharaman@gmail.com>
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/LoadBalancerService.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/Activator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/NeutronCacheUtils.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/LoadBalancerConfiguration.java

index 04b9db18433c1f70faf3e808762359f602ff026d..a6ebf1b22ebdf19a944f3a56c7f01d2897ccd29a 100644 (file)
@@ -17,6 +17,7 @@ import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.Node.NodeIDType;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration;
 import org.opendaylight.ovsdb.openstack.netvirt.api.LoadBalancerConfiguration.LoadBalancerPoolMember;
@@ -45,6 +46,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instru
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
@@ -82,6 +84,14 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load
     @Override
     public Status programLoadBalancerPoolMemberRules(Node node,
             LoadBalancerConfiguration lbConfig, LoadBalancerPoolMember member, org.opendaylight.ovsdb.openstack.netvirt.api.Action action) {
+        if (lbConfig == null || member == null) {
+            logger.error("Null value for LB config {} or Member {}", lbConfig, member);
+            return new Status(StatusCode.BADREQUEST);
+        }
+        if (!lbConfig.isValid()) {
+            logger.error("LB config is invalid: {}", lbConfig);
+            return new Status(StatusCode.BADREQUEST);
+        }
         if (!node.getType().equals(NodeIDType.OPENFLOW)) {
             logger.trace("Ignoring non-OpenFlow node {} from flow programming", node);
             return new Status(StatusCode.BADREQUEST);
@@ -115,6 +125,14 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load
      */
     @Override
     public Status programLoadBalancerRules(Node node, LoadBalancerConfiguration lbConfig, org.opendaylight.ovsdb.openstack.netvirt.api.Action action) {
+        if (lbConfig == null) {
+            logger.error("LB config is invalid: {}", lbConfig);
+            return new Status(StatusCode.BADREQUEST);
+        }
+        if (!lbConfig.isValid()) {
+            logger.error("LB config is invalid: {}", lbConfig);
+            return new Status(StatusCode.BADREQUEST);
+        }
         if (!node.getType().equals(NodeIDType.OPENFLOW)) {
             logger.trace("Ignoring non-OpenFlow node {} from flow programming", node);
             return new Status(StatusCode.BADREQUEST);
@@ -152,7 +170,15 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load
         MatchBuilder matchBuilder = new MatchBuilder();
         FlowBuilder flowBuilder = new FlowBuilder();
 
-        // Match VIP, and Reg0==0
+        // Match Tunnel-ID, VIP, and Reg0==0
+        if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) ||
+            lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE))
+            MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(lbConfig.getProviderSegmentationId()));
+        else if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN))
+            MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(lbConfig.getProviderSegmentationId())), true);
+        else
+            return; //Should not get here. TODO: Other types
+
         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(lbConfig.getVip()));
         MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, FIRST_PASS_REGA_MATCH_VALUE));
 
@@ -243,7 +269,15 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load
         MatchBuilder matchBuilder = new MatchBuilder();
         FlowBuilder flowBuilder = new FlowBuilder();
 
-        // Match VIP, Reg0==1 and Reg1==Index of member
+        // Match Tunnel-ID, VIP, Reg0==1 and Reg1==Index of member
+        if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) ||
+            lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE))
+            MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(lbConfig.getProviderSegmentationId()));
+        else if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN))
+            MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(lbConfig.getProviderSegmentationId())), true);
+        else
+            return; //Should not get here. TODO: Other types
+
         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(vip));
         MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(REG_FIELD_A, SECOND_PASS_REGA_MATCH_VALUE),
                                                new MatchUtils.RegMatch(REG_FIELD_B, (long)member.getIndex()));
@@ -325,13 +359,22 @@ public class LoadBalancerService extends AbstractServiceInstance implements Load
 
     private void manageLoadBalancerMemberReverseRules(NodeBuilder nodeBuilder, LoadBalancerConfiguration lbConfig,
             LoadBalancerPoolMember member, boolean write) {
+
         String vip = lbConfig.getVip();
         String vmac = lbConfig.getVmac();
 
         MatchBuilder matchBuilder = new MatchBuilder();
         FlowBuilder flowBuilder = new FlowBuilder();
 
-        // Match MemberIP, and Protocol/Port
+        // Match Tunnel-ID, MemberIP, and Protocol/Port
+        if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) ||
+                   lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE))
+            MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(lbConfig.getProviderSegmentationId()));
+        else if (lbConfig.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN))
+            MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(lbConfig.getProviderSegmentationId())), true);
+        else
+            return; //Should not get here. TODO: Other types
+
         MatchUtils.createSrcL3IPv4Match(matchBuilder, new Ipv4Prefix(member.getIP()));
         MatchUtils.createSetSrcTcpMatch(matchBuilder, new PortNumber(member.getPort()));
 
index 48bc3fd14ae628e0b737f0d3f5974634bcfbfa81..3767a5a6593da88d4b188b5ee5fa21a97fdcf56a 100644 (file)
@@ -261,6 +261,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.add(createServiceDependency().setService(INeutronLoadBalancerPoolCRUD.class).setRequired(true));
             c.add(createServiceDependency().setService(LoadBalancerProvider.class).setRequired(true));
             c.add(createServiceDependency().setService(ISwitchManager.class).setRequired(true));
+            c.add(createServiceDependency().setService(INeutronNetworkCRUD.class).setRequired(true));
+            c.add(createServiceDependency().setService(INeutronSubnetCRUD.class).setRequired(true));
         }
 
         if (imp.equals(LBaaSPoolHandler.class)) {
@@ -273,9 +275,10 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.add(createServiceDependency().setService(EventDispatcher.class).setRequired(true));
             c.add(createServiceDependency().setService(INeutronPortCRUD.class).setRequired(true));
             c.add(createServiceDependency().setService(INeutronLoadBalancerCRUD.class).setRequired(true));
-            c.add(createServiceDependency().setService(INeutronLoadBalancerPoolCRUD.class).setRequired(true));
             c.add(createServiceDependency().setService(LoadBalancerProvider.class).setRequired(true));
             c.add(createServiceDependency().setService(ISwitchManager.class).setRequired(true));
+            c.add(createServiceDependency().setService(INeutronNetworkCRUD.class).setRequired(true));
+            c.add(createServiceDependency().setService(INeutronSubnetCRUD.class).setRequired(true));
         }
 
         if (imp.equals(LBaaSPoolMemberHandler.class)) {
@@ -291,6 +294,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             c.add(createServiceDependency().setService(INeutronLoadBalancerPoolCRUD.class).setRequired(true));
             c.add(createServiceDependency().setService(LoadBalancerProvider.class).setRequired(true));
             c.add(createServiceDependency().setService(ISwitchManager.class).setRequired(true));
+            c.add(createServiceDependency().setService(INeutronNetworkCRUD.class).setRequired(true));
+            c.add(createServiceDependency().setService(INeutronSubnetCRUD.class).setRequired(true));
         }
 
         if (imp.equals(PortSecurityHandler.class)) {
index ec286e68cd13e2fc7bc9dd0d93811668956429fe..b958113a650d6988e673afe104ee1b91f95c53d6 100644 (file)
@@ -13,7 +13,9 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerAware;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
@@ -50,6 +52,8 @@ public class LBaaSHandler extends AbstractHandler
     private volatile INeutronLoadBalancerCRUD neutronLBCache;
     private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache;
     private volatile INeutronPortCRUD neutronPortsCache;
+    private volatile INeutronNetworkCRUD neutronNetworkCache;
+    private volatile INeutronSubnetCRUD neutronSubnetCache;
     private volatile LoadBalancerProvider loadBalancerProvider;
     private volatile ISwitchManager switchManager;
 
@@ -165,7 +169,13 @@ public class LBaaSHandler extends AbstractHandler
         String loadBalancerName = neutronLB.getLoadBalancerName();
         String loadBalancerVip = neutronLB.getLoadBalancerVipAddress();
         String loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
+
         LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
+        Map.Entry<String,String> providerInfo = NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, loadBalancerSubnetID);
+        if (providerInfo != null) {
+            lbConfig.setProviderNetworkType(providerInfo.getKey());
+            lbConfig.setProviderSegmentationId(providerInfo.getValue());
+        }
         lbConfig.setVmac(NeutronCacheUtils.getMacAddress(neutronPortsCache, loadBalancerVip));
 
         String memberID, memberIP, memberMAC, memberProtocol, memberSubnetID;
index 81e191d5b9bbb2633857b7e800893050bb7e6018..fb86650a51ce737f7097d1a3303b805fa868fb14 100755 (executable)
@@ -12,8 +12,9 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolAware;
-import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
@@ -30,6 +31,7 @@ import com.google.common.collect.Lists;
 
 import java.net.HttpURLConnection;
 import java.util.List;
+import java.util.Map;
 
 /**
  * Handle requests for OpenStack Neutron v2.0 LBaaS API calls for
@@ -43,9 +45,10 @@ public class LBaaSPoolHandler extends AbstractHandler
     private static final Logger logger = LoggerFactory.getLogger(LBaaSPoolHandler.class);
 
     // The implementation for each of these services is resolved by the OSGi Service Manager
-    private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache;
     private volatile INeutronLoadBalancerCRUD neutronLBCache;
     private volatile INeutronPortCRUD neutronPortsCache;
+    private volatile INeutronNetworkCRUD neutronNetworkCache;
+    private volatile INeutronSubnetCRUD neutronSubnetCache;
     private volatile LoadBalancerProvider loadBalancerProvider;
     private volatile ISwitchManager switchManager;
 
@@ -209,7 +212,13 @@ public class LBaaSPoolHandler extends AbstractHandler
             loadBalancerSubnetID = neutronLB.getLoadBalancerVipSubnetID();
             loadBalancerName = neutronLB.getLoadBalancerName();
             loadBalancerVip = neutronLB.getLoadBalancerVipAddress();
+
             LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
+            Map.Entry<String,String> providerInfo = NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, loadBalancerSubnetID);
+            if (providerInfo != null) {
+                lbConfig.setProviderNetworkType(providerInfo.getKey());
+                lbConfig.setProviderSegmentationId(providerInfo.getValue());
+            }
             lbConfig.setVmac(NeutronCacheUtils.getMacAddress(neutronPortsCache, loadBalancerVip));
 
             /* Iterate over all the members in this pool and find those in same
index 9f6198c937c2408f3b753054f57fa86fa473e42b..bb3d9a0e4fab83648147041e398d08e71496543d 100755 (executable)
@@ -13,7 +13,9 @@ package org.opendaylight.ovsdb.openstack.netvirt;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronLoadBalancerPoolMemberAware;
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancer;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPool;
 import org.opendaylight.controller.networkconfig.neutron.NeutronLoadBalancerPoolMember;
@@ -28,6 +30,7 @@ import org.slf4j.LoggerFactory;
 import com.google.common.base.Preconditions;
 
 import java.net.HttpURLConnection;
+import java.util.Map;
 
 /**
  * Handle requests for OpenStack Neutron v2.0 LBaaS API calls for
@@ -43,6 +46,8 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
     private volatile INeutronLoadBalancerPoolCRUD neutronLBPoolCache;
     private volatile INeutronLoadBalancerCRUD neutronLBCache;
     private volatile INeutronPortCRUD neutronPortsCache;
+    private volatile INeutronNetworkCRUD neutronNetworkCache;
+    private volatile INeutronSubnetCRUD neutronSubnetCache;
     private volatile LoadBalancerProvider loadBalancerProvider;
     private volatile ISwitchManager switchManager;
 
@@ -218,6 +223,11 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
          * In that case, we create dummy configuration that will not program rules.
          */
         LoadBalancerConfiguration lbConfig = new LoadBalancerConfiguration(loadBalancerName, loadBalancerVip);
+        Map.Entry<String,String> providerInfo = NeutronCacheUtils.getProviderInformation(neutronNetworkCache, neutronSubnetCache, memberSubnetID);
+        if (providerInfo != null) {
+            lbConfig.setProviderNetworkType(providerInfo.getKey());
+            lbConfig.setProviderSegmentationId(providerInfo.getValue());
+        }
         lbConfig.setVmac(NeutronCacheUtils.getMacAddress(neutronPortsCache, loadBalancerVip));
 
         /* Extract all other active members and include in LB config
index 9f0984a94992ed51f34f773aafefc5e8087d31ab..bed81ab6dccc1057c8986dc152810a6df9a01312 100755 (executable)
 
 package org.opendaylight.ovsdb.openstack.netvirt;
 
+import org.opendaylight.controller.networkconfig.neutron.INeutronNetworkCRUD;
 import org.opendaylight.controller.networkconfig.neutron.INeutronPortCRUD;
+import org.opendaylight.controller.networkconfig.neutron.INeutronSubnetCRUD;
+import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork;
 import org.opendaylight.controller.networkconfig.neutron.NeutronPort;
+import org.opendaylight.controller.networkconfig.neutron.NeutronSubnet;
 import org.opendaylight.controller.networkconfig.neutron.Neutron_IPs;
+
+import java.util.AbstractMap;
 import java.util.Iterator;
 import java.util.List;
+import java.util.Map;
 
 public class NeutronCacheUtils {
 
@@ -47,4 +54,36 @@ public class NeutronCacheUtils {
         }
         return null;
     }
+
+    /**
+     * Look up in the NeutronNetworkCRUD cache and NeutronSubnetCRUD cache for
+     * extracting the provider segmentation_type and segmentation_id
+     * @param subnetId Subnet UUID
+     * @return {Type: ID} pair for that subnet ID
+     */
+    public static Map.Entry<String,String> getProviderInformation(INeutronNetworkCRUD neutronNetworkCache,
+                INeutronSubnetCRUD neutronSubnetCache, String subnetID) {
+
+        String networkID = null;
+
+        List<NeutronSubnet> allSubnets = neutronSubnetCache.getAllSubnets();
+        for (NeutronSubnet subnet: allSubnets) {
+            if (subnet.getID().equals(subnetID)) {
+                networkID = subnet.getNetworkUUID();
+                break;
+            }
+        }
+        if (networkID == null)
+            return null;
+
+        List<NeutronNetwork> allNetworks = neutronNetworkCache.getAllNetworks();
+        for (NeutronNetwork network: allNetworks) {
+            if (network.getID().equals(networkID)) {
+                Map.Entry<String,String> entry = new AbstractMap.SimpleEntry<String, String>(
+                        network.getProviderNetworkType(), network.getProviderSegmentationID());
+                return entry;
+            }
+        }
+        return null;
+    }
 }
index ac275347ec13a8cb574e2aa37038cf412d96dad0..e34320ec9bf555c591fe315d6ce54a785df4d8d7 100755 (executable)
@@ -97,6 +97,8 @@ public class LoadBalancerConfiguration {
     private String name;
     private String vip;
     private String vmac; //Used when a dummy neutron port is created for the VIP
+    private String providerNetworkType;
+    private String providerSegmentationId;
     private Map <String, LoadBalancerPoolMember> members;
 
     public LoadBalancerConfiguration() {
@@ -153,8 +155,11 @@ public class LoadBalancerConfiguration {
     public boolean isValid() {
         if (members.size() == 0)
             return false;
+        else if (providerNetworkType == null)
+            return false;
         return true;
     }
+
     public void setVip(String vip) {
         this.vip = vip;
     }
@@ -179,9 +184,27 @@ public class LoadBalancerConfiguration {
         return this.name;
     }
 
+    public void setProviderSegmentationId(String providerSegmentationId) {
+        this.providerSegmentationId = providerSegmentationId;
+    }
+
+    public String getProviderSegmentationId() {
+        return this.providerSegmentationId;
+    }
+    public void setProviderNetworkType(String providerNetworkType) {
+        this.providerNetworkType = providerNetworkType;
+    }
+
+    public String getProviderNetworkType() {
+        return this.providerNetworkType;
+    }
+
     @Override
     public String toString() {
-        return "LoadBalancerConfiguration [name=" + name + ", vip=" +
-            vip + ", vmac=" + vmac + ", members=" + members + "]";
+        return "LoadBalancerConfiguration [name=" + name +
+                ", vip=" + vip + ", vmac=" + vmac +
+                ", networkType=" + providerNetworkType +
+                ", segmentationId=" + providerSegmentationId +
+                ", members=" + members + "]";
     }
 }