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;
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;
@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);
*/
@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);
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));
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()));
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()));
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)) {
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)) {
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)) {
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;
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;
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;
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;
import java.net.HttpURLConnection;
import java.util.List;
+import java.util.Map;
/**
* Handle requests for OpenStack Neutron v2.0 LBaaS API calls for
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;
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
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;
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
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;
* 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
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 {
}
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;
+ }
}
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() {
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;
}
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 + "]";
}
}