package org.opendaylight.netvirt.openstack.netvirt.impl;
+import com.google.common.base.Preconditions;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Random;
+import java.util.stream.Collectors;
+import org.apache.commons.lang3.tuple.ImmutablePair;
import org.opendaylight.netvirt.openstack.netvirt.NetworkHandler;
+import org.opendaylight.netvirt.openstack.netvirt.VLANProvider;
import org.opendaylight.netvirt.openstack.netvirt.api.OvsdbTables;
import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
import org.opendaylight.netvirt.openstack.netvirt.ConfigInterface;
+import org.opendaylight.netvirt.openstack.netvirt.MdsalHelper;
+import org.opendaylight.netvirt.openstack.netvirt.NetworkHandler;
import org.opendaylight.netvirt.openstack.netvirt.api.BridgeConfigurationManager;
import org.opendaylight.netvirt.openstack.netvirt.api.ConfigurationService;
import org.opendaylight.netvirt.openstack.netvirt.api.Constants;
import org.opendaylight.netvirt.openstack.netvirt.api.NetworkingProviderManager;
+import org.opendaylight.netvirt.openstack.netvirt.api.OvsdbTables;
import org.opendaylight.netvirt.openstack.netvirt.api.Southbound;
+import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronNetwork;
import org.opendaylight.netvirt.utils.config.ConfigProperties;
import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.DatapathTypeBase;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ConnectionInfo;
import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.ovsdb.node.attributes.ManagerEntry;
import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
-
-import com.google.common.base.Preconditions;
-import com.google.common.collect.Lists;
-
-import java.net.InetAddress;
-import java.net.NetworkInterface;
-import java.net.UnknownHostException;
-import java.util.ArrayList;
-import java.util.Enumeration;
-import java.util.List;
-import java.util.Random;
-
-import org.apache.commons.lang3.tuple.ImmutablePair;
import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
try {
if (configurationService.isL3ForwardingEnabled()) {
createExternalBridge(ovsdbNode);
+ } else if (configurationService.isL3MultipleExternalNetworkEnabled()) {
+ String brExt = getMultipleExternalBridge(ovsdbNode);
+ if (brExt == null) {
+ LOG.warn("The provider mapping external network bridge name is null");
+ return;
+ }
+ //get external bridge
+ Node extBridgeNode = southbound.readBridgeNode(ovsdbNode, brExt);
+ LOG.trace("External bridge details in operational data store:extBridgeNode:{}", extBridgeNode);
+ if (extBridgeNode == null) {
+ LOG.warn("External bridge is not created:{}", brExt);
+ return;
+ }
+ //get internal bridge
+ String brInt = configurationService.getIntegrationBridgeName();
+ if (!addBridge(ovsdbNode, brExt, null)) {
+ LOG.warn("Multiple External Bridge Creation failed");
+ return;
+ }
+ configurationService.setExternalBridgeName(brExt);
+ Node internalOvsdbNode = southbound.readConfigBridge(ovsdbNode, brInt);
+ LOG.trace("Internal bridge details in config data store:internalOvsdbNode:{}", internalOvsdbNode);
+ if (internalOvsdbNode == null) {
+ LOG.warn("Internal Bridge is null in config datastore:{}", brInt);
+ return;
+ }
+ //Processing an external bridge
+ String portNameExt = VLANProvider.getPatchPortName(brExt);
+ LOG.trace("prepareNode: portNameExt:{}", portNameExt);
+ final String portNameInt = Constants.PATCH_PORT_TO_INTEGRATION_BRIDGE_NAME;
+ Preconditions.checkNotNull(portNameInt);
+ Preconditions.checkNotNull(portNameExt);
+ if (!addPatchPort(internalOvsdbNode, brInt, portNameExt, portNameInt)) {
+ LOG.error("Add Port {} to Bridge {} failed", portNameInt, brInt);
+ return;
+ }
+ if (!addPatchPort(extBridgeNode, brExt, portNameInt, portNameExt)) {
+ LOG.error("Add Port {} to Bridge {} failed", portNameExt, brExt);
+ return;
+ }
+ LOG.info("Multiple external bridge is successfully created:{}", brExt);
}
} catch (Exception e) {
LOG.error("Error creating External Bridge on {}", ovsdbNode, e);
@Override
public List<String> getAllPhysicalInterfaceNames(Node node) {
- List<String> phyIfName = Lists.newArrayList();
+ List<String> phyIfNames = new ArrayList<>();
String providerMaps = southbound.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
configurationService.getProviderMappingsKey());
if (providerMaps == null) {
+ if (configurationService.isL3MultipleExternalNetworkEnabled()) {
+ return phyIfNames;
+ }
providerMaps = configurationService.getDefaultProviderMapping();
}
if (providerMaps != null) {
for (String map : providerMaps.split(",")) {
String[] pair = map.split(":");
- phyIfName.add(pair[1]);
+ phyIfNames.add(pair[1]);
}
}
- return phyIfName;
+ return phyIfNames;
}
/**
*/
private boolean addPatchPort (Node node, String bridgeName, String portName, String peerPortName) {
boolean rv = true;
-
- if (southbound.extractTerminationPointAugmentation(node, portName) == null) {
+ if (configurationService.isL3MultipleExternalNetworkEnabled() ||
+ southbound.extractTerminationPointAugmentation(node, portName) == null) {
rv = southbound.addPatchTerminationPoint(node, bridgeName, portName, peerPortName);
-
if (rv) {
LOG.info("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: success",
node.getNodeId().getValue(), bridgeName, portName, peerPortName);
LOG.trace("addPatchPort: node: {}, bridge: {}, portname: {} peer: {} status: not_needed",
node.getNodeId().getValue(), bridgeName, portName, peerPortName);
}
-
return rv;
}
*/
private boolean addBridge(Node ovsdbNode, String bridgeName, String mac) {
boolean rv = true;
- if ((!southbound.isBridgeOnOvsdbNode(ovsdbNode, bridgeName)) ||
- (southbound.getBridgeFromConfig(ovsdbNode, bridgeName) == null)) {
+ boolean isBridgeInConfig = (southbound.getBridgeFromConfig(ovsdbNode, bridgeName) != null);
+ Node bridgeNode = southbound.readBridgeNode(ovsdbNode, bridgeName);
+
+ if (bridgeNode == null || !isBridgeInConfig) {
Class<? extends DatapathTypeBase> dpType = null;
if (configurationService.isUserSpaceEnabled()) {
dpType = DatapathTypeNetdev.class;
}
- rv = southbound.addBridge(ovsdbNode, bridgeName, getControllersFromOvsdbNode(ovsdbNode), dpType, mac);
+
+ // if the bridge is already on the OVS node, use the existing MAC address
+ // because changing the MAC causes the dpid to change on the switch, which
+ // in turn causes a connection flap (see bugs 6070, 6944)
+ rv = southbound.addBridge(ovsdbNode, bridgeName, getControllersFromOvsdbNode(ovsdbNode), dpType,
+ bridgeNode == null ? mac : southbound.getOtherConfig(bridgeNode, OvsdbTables.BRIDGE, MdsalHelper.HWADDR));
}
return rv;
}
if (controllersStr.isEmpty()) {
LOG.warn("Failed to determine OpenFlow controller ip address");
} else if (LOG.isDebugEnabled()) {
- controllerIpStr = "";
- for (String currControllerIpStr : controllersStr) {
- controllerIpStr += " " + currControllerIpStr;
- }
- LOG.debug("Found {} OpenFlow Controller(s) :{}", controllersStr.size(), controllerIpStr);
+ LOG.debug("Found {} OpenFlow Controller(s): {}", controllersStr.size(),
+ controllersStr.stream().collect(Collectors.joining(" ")));
}
return controllersStr;
@Override
public void setDependencies(Object impl) {
}
+
+ @Override
+ public String getMultipleExternalBridge(Node ovsdbNode) {
+ String brExt = null;
+ List<String> phyIfNames = this.getAllPhysicalInterfaceNames(ovsdbNode);
+ LOG.debug("getMultipleExternalBridge phyIfName::{}", phyIfNames);
+ if (phyIfNames.size() > 0) {
+ brExt = phyIfNames.get(0);
+ LOG.debug("Provider Mapping: external bridge name:{}", brExt);
+ }
+ if (brExt == null || brExt.isEmpty()) {
+ LOG.warn("The provider mapping external network bridge name is null");
+ return null;
+ }
+ return brExt;
+ }
}