X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=openstack%2Fnet-virt-providers%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fovsdb%2Fopenstack%2Fnetvirt%2Fproviders%2Fopenflow13%2FOF13Provider.java;h=facbd6a31d6ba80ef3c95c6e3c4ae1397e149d1c;hb=7c30cc914c4653fe9bcda8b234e9542552352799;hp=00e28248c7d7e093049d34b31f9085c5a385bbaa;hpb=c5b47e8c13557ac0b63ae09de14c115d130cc6e8;p=netvirt.git diff --git a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java index 00e28248c7..facbd6a31d 100644 --- a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java +++ b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/OF13Provider.java @@ -4,46 +4,42 @@ * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html - * - * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker */ package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13; -import com.google.common.base.Optional; -import com.google.common.util.concurrent.CheckedFuture; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.controller.networkconfig.neutron.NeutronNetwork; -import org.opendaylight.controller.sal.core.Node; -import org.opendaylight.controller.sal.utils.HexEncode; -import org.opendaylight.controller.sal.utils.Status; -import org.opendaylight.controller.sal.utils.StatusCode; -import org.opendaylight.ovsdb.lib.notation.Row; -import org.opendaylight.ovsdb.lib.notation.UUID; -import org.opendaylight.ovsdb.openstack.netvirt.api.Constants; +import org.opendaylight.neutron.spi.NeutronNetwork; +import org.opendaylight.ovsdb.openstack.netvirt.MdsalHelper; import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler; import org.opendaylight.ovsdb.openstack.netvirt.api.BridgeConfigurationManager; +import org.opendaylight.ovsdb.openstack.netvirt.api.ClassifierProvider; +import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService; +import org.opendaylight.ovsdb.openstack.netvirt.api.Constants; +import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider; +import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider; +import org.opendaylight.ovsdb.openstack.netvirt.api.L2ForwardingProvider; import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProvider; +import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager; +import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager; +import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager; +import org.opendaylight.ovsdb.openstack.netvirt.api.Southbound; +import org.opendaylight.ovsdb.openstack.netvirt.api.Status; +import org.opendaylight.ovsdb.openstack.netvirt.api.StatusCode; import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager; -import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService; -import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService; -import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils; +import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface; +import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider; import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils; -import org.opendaylight.ovsdb.plugin.api.StatusWithUuid; -import org.opendaylight.ovsdb.schema.openvswitch.Bridge; -import org.opendaylight.ovsdb.schema.openvswitch.Interface; -import org.opendaylight.ovsdb.schema.openvswitch.Port; +import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.OutputActionCaseBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.PopVlanActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.group.action._case.GroupActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.output.action._case.OutputActionBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action; @@ -56,7 +52,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.ta import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Instructions; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase; @@ -79,46 +74,71 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.group.types.rev131018.group import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.Nodes; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbTerminationPointAugmentation; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; 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.EtherType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import com.google.common.base.Optional; import com.google.common.base.Preconditions; import com.google.common.collect.Lists; import com.google.common.collect.Maps; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; +import com.google.common.util.concurrent.CheckedFuture; -import java.math.BigInteger; import java.net.InetAddress; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.ExecutionException; + /** * Open vSwitch OpenFlow 1.3 Networking Provider for OpenStack Neutron + * + * @author Madhu Venugopal + * @author Brent Salisbury + * @author Dave Tucker + * @author Sam Hague */ -public class OF13Provider implements NetworkingProvider { +public class OF13Provider implements ConfigInterface, NetworkingProvider { private static final Logger logger = LoggerFactory.getLogger(OF13Provider.class); - private DataBroker dataBroker; private static final short TABLE_0_DEFAULT_INGRESS = 0; private static final short TABLE_1_ISOLATE_TENANT = 10; private static final short TABLE_2_LOCAL_FORWARD = 20; - private static final String OPENFLOW = "openflow:"; private static Long groupId = 1L; + private DataBroker dataBroker = null; - private volatile org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService configurationService; + private volatile ConfigurationService configurationService; private volatile BridgeConfigurationManager bridgeConfigurationManager; private volatile TenantNetworkManager tenantNetworkManager; - private volatile OvsdbConfigurationService ovsdbConfigurationService; - private volatile OvsdbConnectionService connectionService; - private volatile MdsalConsumer mdsalConsumer; + private volatile SecurityServicesManager securityServicesManager; + private volatile ClassifierProvider classifierProvider; + private volatile IngressAclProvider ingressAclProvider; + private volatile EgressAclProvider egressAclProvider; + private volatile NodeCacheManager nodeCacheManager; + private volatile L2ForwardingProvider l2ForwardingProvider; + + public static final String NAME = "OF13Provider"; + private volatile NetworkingProviderManager networkingProviderManager; + private volatile BundleContext bundleContext; + private volatile Southbound southbound; + + public OF13Provider() { + this.dataBroker = NetvirtProvidersProvider.getDataBroker(); + } - public OF13Provider(){ + @Override + public String getName() { + return NAME; + } + @Override + public boolean supportsServices() { + return true; } @Override @@ -139,7 +159,7 @@ public class OF13Provider implements NetworkingProvider { } if (!tenantNetworkManager.isTenantNetworkPresentInNode(node, tunnelKey)) { - logger.debug(node+" has no VM corresponding to segment "+ tunnelKey); + logger.debug(node + " has no VM corresponding to segment " + tunnelKey); return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey); } return new Status(StatusCode.SUCCESS); @@ -149,177 +169,59 @@ public class OF13Provider implements NetworkingProvider { return tunnelType+"-"+dst.getHostAddress(); } - private boolean isTunnelPresent(Node node, String tunnelName, String bridgeUUID) throws Exception { - Preconditions.checkNotNull(ovsdbConfigurationService); - Row bridgeRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), bridgeUUID); - Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow); - if (bridge != null) { - Set ports = bridge.getPortsColumn().getData(); - for (UUID portUUID : ports) { - Row portRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Port.class), portUUID.toString()); - Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow); - if (port != null && tunnelName.equalsIgnoreCase(port.getName())) return true; - } - } - return false; - } - - private String getPortUuid(Node node, String name, String bridgeUUID) throws Exception { - Preconditions.checkNotNull(ovsdbConfigurationService); - Row bridgeRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), bridgeUUID); - Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow); - if (bridge != null) { - Set ports = bridge.getPortsColumn().getData(); - for (UUID portUUID : ports) { - Row portRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Port.class), portUUID.toString()); - Port port = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow); - if (port != null && name.equalsIgnoreCase(port.getName())) return portUUID.toString(); - } + private boolean addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) { + String tunnelBridgeName = configurationService.getIntegrationBridgeName(); + String portName = getTunnelName(tunnelType, dst); + logger.info("addTunnelPort enter: portName: {}", portName); + if (southbound.extractTerminationPointAugmentation(node, portName) != null + || southbound.isTunnelTerminationPointExist(node, tunnelBridgeName, portName)) { + logger.info("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node.getNodeId().getValue()); + return true; } - return null; - } - - private Status addTunnelPort (Node node, String tunnelType, InetAddress src, InetAddress dst) { - Preconditions.checkNotNull(ovsdbConfigurationService); - try { - String bridgeUUID = null; - String tunnelBridgeName = configurationService.getIntegrationBridgeName(); - Map bridgeTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class)); - if (bridgeTable != null) { - for (String uuid : bridgeTable.keySet()) { - Bridge bridge = ovsdbConfigurationService.getTypedRow(node,Bridge.class, bridgeTable.get(uuid)); - if (bridge.getName().equals(tunnelBridgeName)) { - bridgeUUID = uuid; - break; - } - } - } - if (bridgeUUID == null) { - logger.error("Could not find Bridge {} in {}", tunnelBridgeName, node); - return new Status(StatusCode.NOTFOUND, "Could not find "+tunnelBridgeName+" in "+node); - } - String portName = getTunnelName(tunnelType, dst); - - if (this.isTunnelPresent(node, portName, bridgeUUID)) { - logger.trace("Tunnel {} is present in {} of {}", portName, tunnelBridgeName, node); - return new Status(StatusCode.SUCCESS); - } - - Port tunnelPort = ovsdbConfigurationService.createTypedRow(node, Port.class); - tunnelPort.setName(portName); - StatusWithUuid statusWithUuid = ovsdbConfigurationService - .insertRow(node, ovsdbConfigurationService.getTableName(node, Port.class), bridgeUUID, tunnelPort.getRow()); - if (!statusWithUuid.isSuccess()) { - logger.error("Failed to insert Tunnel port {} in {}", portName, bridgeUUID); - return statusWithUuid; - } - - String tunnelPortUUID = statusWithUuid.getUuid().toString(); - String interfaceUUID = null; - int timeout = 6; - while ((interfaceUUID == null) && (timeout > 0)) { - Row portRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Port.class), tunnelPortUUID); - tunnelPort = ovsdbConfigurationService.getTypedRow(node, Port.class, portRow); - Set interfaces = tunnelPort.getInterfacesColumn().getData(); - if (interfaces == null || interfaces.size() == 0) { - // Wait for the OVSDB update to sync up the Local cache. - Thread.sleep(500); - timeout--; - continue; - } - interfaceUUID = interfaces.toArray()[0].toString(); - Row intfRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Interface.class), interfaceUUID); - Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, intfRow); - if (intf == null) interfaceUUID = null; - } - if (interfaceUUID == null) { - logger.error("Cannot identify Tunnel Interface for port {}/{}", portName, tunnelPortUUID); - return new Status(StatusCode.INTERNALERROR); - } + Map options = Maps.newHashMap(); + options.put("key", "flow"); + options.put("local_ip", src.getHostAddress()); + options.put("remote_ip", dst.getHostAddress()); - Interface tunInterface = ovsdbConfigurationService.createTypedRow(node, Interface.class); - tunInterface.setType(tunnelType); - Map options = Maps.newHashMap(); - options.put("key", "flow"); - options.put("local_ip", src.getHostAddress()); - options.put("remote_ip", dst.getHostAddress()); - tunInterface.setOptions(options); - Status status = ovsdbConfigurationService - .updateRow(node, ovsdbConfigurationService.getTableName(node, Interface.class), tunnelPortUUID, interfaceUUID, tunInterface.getRow()); - logger.debug("Tunnel {} add status : {}", tunInterface, status); - return status; - } catch (Exception e) { - logger.error("Exception in addTunnelPort", e); - return new Status(StatusCode.INTERNALERROR); + if (!southbound.addTunnelTerminationPoint(node, tunnelBridgeName, portName, tunnelType, options)) { + logger.error("Failed to insert Tunnel port {} in {}", portName, tunnelBridgeName); + return false; } + + logger.info("addTunnelPort exit: portName: {}", portName); + return true; } /* delete port from ovsdb port table */ - private Status deletePort(Node node, String bridgeName, String portName) { - Preconditions.checkNotNull(ovsdbConfigurationService); - try { - String bridgeUUID = null; - Map bridgeTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class)); - if (bridgeTable != null) { - for (String uuid : bridgeTable.keySet()) { - Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeTable.get(uuid)); - if (bridge.getName().equals(bridgeName)) { - bridgeUUID = uuid; - break; - } - } - } - if (bridgeUUID == null) { - logger.debug("Could not find Bridge {} in {}", bridgeName, node); - return new Status(StatusCode.SUCCESS); - } - - String portUUID = this.getPortUuid(node, portName, bridgeUUID); - Status status = new Status(StatusCode.SUCCESS); - if (portUUID != null) { - status = ovsdbConfigurationService - .deleteRow(node, ovsdbConfigurationService.getTableName(node, Port.class), portUUID); - if (!status.isSuccess()) { - logger.error("Failed to delete port {} in {} status : {}", portName, bridgeUUID, - status); - return status; - } - logger.debug("Port {} delete status : {}", portName, status); - } - return status; - } catch (Exception e) { - logger.error("Exception in deletePort", e); - return new Status(StatusCode.INTERNALERROR); - } + private boolean deletePort(Node node, String bridgeName, String portName) { + // TODO SB_MIGRATION + // might need to convert from ovsdb node to bridge node + return southbound.deleteTerminationPoint(node, portName); } - private Status deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) { + private boolean deleteTunnelPort(Node node, String tunnelType, InetAddress src, InetAddress dst) { String tunnelBridgeName = configurationService.getIntegrationBridgeName(); String portName = getTunnelName(tunnelType, dst); return deletePort(node, tunnelBridgeName, portName); } - private Status deletePhysicalPort(Node node, String phyIntfName) { + private boolean deletePhysicalPort(Node node, String phyIntfName) { String intBridgeName = configurationService.getIntegrationBridgeName(); return deletePort(node, intBridgeName, phyIntfName); } - private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) { - /* + private void programLocalBridgeRules(Node node, Long dpid, String segmentationId, + String attachedMac, long localPort) { + /* * Table(0) Rule #3 * ---------------- * Match: VM sMac and Local Ingress Port * Action:Action: Set Tunnel ID and GOTO Local Table (5) */ - handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, true); + handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, + segmentationId, localPort, attachedMac, true); /* * Table(0) Rule #4 @@ -328,51 +230,52 @@ public class OF13Provider implements NetworkingProvider { * Action: Drop w/ a low priority */ - handleDropSrcIface(dpid, localPort, true); - - /* - * Table(2) Rule #1 - * ---------------- - * Match: Match TunID and Destination DL/dMAC Addr - * Action: Output Port - * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2 - */ - - handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true); - - /* - * Table(2) Rule #2 - * ---------------- - * Match: Tunnel ID and dMAC (::::FF:FF) - * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:2,3,4,5 - */ - - handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true); - - /* - * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment. - */ - /* - * Table(1) Rule #3 - * ---------------- - * Match: Any remaining Ingress Local VM Packets - * Action: Drop w/ a low priority - * ------------------------------------------- - * table=1,priority=8192,tun_id=0x5 actions=goto_table:2 - */ - - handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true); - - /* - * Table(2) Rule #3 - * ---------------- - * Match: Any Remaining Flows w/a TunID - * Action: Drop w/ a low priority - * table=2,priority=8192,tun_id=0x5 actions=drop - */ - - handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true); + handleDropSrcIface(dpid, localPort, true); + + /* + * Table(2) Rule #1 + * ---------------- + * Match: Match TunID and Destination DL/dMAC Addr + * Action: Output Port + * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2 + */ + + handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, true); + + /* + * Table(2) Rule #2 + * ---------------- + * Match: Tunnel ID and dMAC (::::FF:FF) + * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:2,3,4,5 + */ + + handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true); + handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, true); + + /* + * TODO : Optimize the following 2 writes to be restricted only for the very first port known in a segment. + */ + /* + * Table(1) Rule #3 + * ---------------- + * Match: Any remaining Ingress Local VM Packets + * Action: Drop w/ a low priority + * ------------------------------------------- + * table=1,priority=8192,tun_id=0x5 actions=goto_table:2 + */ + + handleTunnelMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, true); + + /* + * Table(2) Rule #3 + * ---------------- + * Match: Any Remaining Flows w/a TunID + * Action: Drop w/ a low priority + * table=2,priority=8192,tun_id=0x5 actions=drop + */ + + handleLocalTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, true); } private void removeLocalBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long localPort) { @@ -383,7 +286,7 @@ public class OF13Provider implements NetworkingProvider { * Action:Action: Set Tunnel ID and GOTO Local Table (5) */ - handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false); + handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, segmentationId, localPort, attachedMac, false); /* * Table(0) Rule #4 @@ -392,27 +295,28 @@ public class OF13Provider implements NetworkingProvider { * Action: Drop w/ a low priority */ - handleDropSrcIface(dpid, localPort, false); + handleDropSrcIface(dpid, localPort, false); - /* - * Table(2) Rule #1 - * ---------------- - * Match: Match TunID and Destination DL/dMAC Addr - * Action: Output Port - * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2 - */ + /* + * Table(2) Rule #1 + * ---------------- + * Match: Match TunID and Destination DL/dMAC Addr + * Action: Output Port + * table=2,tun_id=0x5,dl_dst=00:00:00:00:00:01 actions=output:2 + */ - handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false); + handleLocalUcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, attachedMac, false); - /* - * Table(2) Rule #2 - * ---------------- - * Match: Tunnel ID and dMAC (::::FF:FF) - * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:2,3,4,5 - */ + /* + * Table(2) Rule #2 + * ---------------- + * Match: Tunnel ID and dMAC (::::FF:FF) + * table=2,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:2,3,4,5 + */ - handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false); + handleLocalBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false); + handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, false); } private void programLocalIngressTunnelBridgeRules(Node node, Long dpid, String segmentationId, String attachedMac, long tunnelOFPort, long localPort) { @@ -423,19 +327,19 @@ public class OF13Provider implements NetworkingProvider { * Action: GOTO Local Table (20) */ - handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true); + handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true); - /* - * Table(1) Rule #2 - * ---------------- - * Match: Match Tunnel ID and L2 ::::FF:FF Flooding - * Action: Flood to selected destination TEPs - * ------------------------------------------- - * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:10,output:11,goto_table:2 - */ + /* + * Table(1) Rule #2 + * ---------------- + * Match: Match Tunnel ID and L2 ::::FF:FF Flooding + * Action: Flood to selected destination TEPs + * ------------------------------------------- + * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10,output:11,goto_table:2 + */ - handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true); + handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, true); } @@ -502,15 +406,15 @@ public class OF13Provider implements NetworkingProvider { handleTunnelIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false); - /* - * Table(1) Rule #2 - * ---------------- - * Match: Match Tunnel ID and L2 ::::FF:FF Flooding - * Action: Flood to selected destination TEPs - * ------------------------------------------- - * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:10,output:11,goto_table:2 - */ + /* + * Table(1) Rule #2 + * ---------------- + * Match: Match Tunnel ID and L2 ::::FF:FF Flooding + * Action: Flood to selected destination TEPs + * ------------------------------------------- + * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10,output:11,goto_table:2 + */ handleTunnelFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, tunnelOFPort, false); } @@ -519,6 +423,7 @@ public class OF13Provider implements NetworkingProvider { /* * Table(0) Rule #1 * ---------------- + * Tag traffic coming from the local port and vm srcmac * Match: VM sMac and Local Ingress Port * Action: Set VLAN ID and GOTO Local Table 1 */ @@ -530,6 +435,7 @@ public class OF13Provider implements NetworkingProvider { /* * Table(0) Rule #3 * ---------------- + * Drop all other traffic coming from the local port * Match: Drop any remaining Ingress Local VM Packets * Action: Drop w/ a low priority */ @@ -539,6 +445,7 @@ public class OF13Provider implements NetworkingProvider { /* * Table(2) Rule #1 * ---------------- + * Forward unicast traffic destined to the local port after stripping tag * Match: Match VLAN ID and Destination DL/dMAC Addr * Action: strip vlan, output to local port * Example: table=2,vlan_id=0x5,dl_dst=00:00:00:00:00:01 actions= strip vlan, output:2 @@ -556,24 +463,25 @@ public class OF13Provider implements NetworkingProvider { * actions= strip_vlan, output:2,3,4,5 */ - handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, - localPort, true); + //handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, + // localPort, ethPort, true); + //handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, + // segmentationId, localPort, ethport, true); - /* - * Table(2) Rule #3 - * ---------------- - * Match: Any Remaining Flows w/a VLAN ID - * Action: Drop w/ a low priority - * Example: table=2,priority=8192,vlan_id=0x5 actions=drop - */ + /* + * Table(2) Rule #3 + * ---------------- + * Match: Any Remaining Flows w/a VLAN ID + * Action: Drop w/ a low priority + * Example: table=2,priority=8192,vlan_id=0x5 actions=drop + */ - handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, - true); - } + //handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, + // true); + } private void removeLocalVlanRules(Node node, Long dpid, - String segmentationId, String attachedMac, - long localPort) { + String segmentationId, String attachedMac, long localPort) { /* * Table(0) Rule #1 * ---------------- @@ -614,20 +522,94 @@ public class OF13Provider implements NetworkingProvider { * actions= strip_vlan, output:2,3,4,5 */ - handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, - localPort, false); - } + //handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, + // localPort, ethPort, false); + //handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, + // segmentationId, localPort, false); + + } + + private void programLocalIngressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, + long localPort, long ethPort) { + /* + * Table(0) Rule #2 + * ---------------- + * Match: Ingress port = physical interface, Vlan ID + * Action: GOTO Local Table 2 + */ + + handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, + segmentationId, ethPort, true); + + /* + * Table(1) Rule #2 + * ---------------- + * Match: Match VLAN ID and L2 ::::FF:FF Flooding + * Action: Flood to local and remote VLAN members + * ------------------------------------------- + * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10 (eth port),goto_table:2 + * table=110, priority=16384,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4 + */ + + handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, ethPort, true); + + /* + * Table(1) Rule #2 + * ---------------- + * Match: Match VLAN ID and L2 ::::FF:FF Flooding + * Action: Flood to local and remote VLAN members + * ------------------------------------------- + * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10 (eth port),goto_table:2 + */ + + //handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, + // segmentationId, ethPort, true); + } + + private void programRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, + String attachedMac, long ethPort) { + /* + * Table(1) Rule #1 + * ---------------- + * Match: Destination MAC is local VM MAC and vlan id + * Action: go to table 2 + * ------------------------------------------- + * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \ + * actions=goto_table:2 + */ + + //handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, + // segmentationId, ethPort, attachedMac, true); + + /* + * Table(1) Rule #3 + * ---------------- + * Match: VLAN ID + * Action: Go to table 2 + * ------------------------------------------- + * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2 + * table=110,priority=8192,dl_vlan=2001 actions=output:2 + */ + + handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, ethPort, true); + } - private void programLocalIngressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) { - /* - * Table(0) Rule #2 - * ---------------- - * Match: Ingress port = physical interface, Vlan ID - * Action: GOTO Local Table 2 - */ + private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, + String attachedMac, long localPort, long ethPort) { + /* + * Table(1) Rule #1 + * ---------------- + * Match: Destination MAC is local VM MAC and vlan id + * Action: go to table 2 + * ------------------------------------------- + * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \ + * actions=goto_table:2 + */ - handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, true); + //handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, + // segmentationId, ethPort, attachedMac, false); /* * Table(1) Rule #2 @@ -637,65 +619,22 @@ public class OF13Provider implements NetworkingProvider { * ------------------------------------------- * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ * actions=output:10 (eth port),goto_table:2 + * table=110, priority=16384,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4 + */ + + handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, ethPort, false); + } + + private void removePerVlanRules(Node node, Long dpid, String segmentationId, long localPort, long ethPort) { + /* + * Table(2) Rule #3 + * ---------------- + * Match: Any Remaining Flows w/a VLAN ID + * Action: Drop w/ a low priority + * Example: table=2,priority=8192,vlan_id=0x5 actions=drop */ - handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, true); - } - - private void programRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) { - /* - * Table(1) Rule #1 - * ---------------- - * Match: Destination MAC is local VM MAC and vlan id - * Action: go to table 2 - * ------------------------------------------- - * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \ - * actions=goto_table:2 - */ - - handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, attachedMac, true); - - /* - * Table(1) Rule #3 - * ---------------- - * Match: VLAN ID - * Action: Go to table 2 - * ------------------------------------------- - * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2 - */ - - handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, true); - } - - private void removeRemoteEgressVlanRules(Node node, Long dpid, String segmentationId, String attachedMac, long ethPort) { - /* - * Table(1) Rule #1 - * ---------------- - * Match: Destination MAC is local VM MAC and vlan id - * Action: go to table 2 - * ------------------------------------------- - * Example: table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \ - * actions=goto_table:2 - */ - - handleVlanOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, attachedMac, false); - } - - private void removePerVlanRules(Node node, Long dpid, String segmentationId, long ethPort) { - /* - * Table(2) Rule #3 - * ---------------- - * Match: Any Remaining Flows w/a VLAN ID - * Action: Drop w/ a low priority - * Example: table=2,priority=8192,vlan_id=0x5 actions=drop - */ - - handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, - false); + //handleLocalVlanTableMiss(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, false); /* * Table(0) Rule #2 @@ -704,105 +643,93 @@ public class OF13Provider implements NetworkingProvider { * Action: GOTO Local Table 2 */ - handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, false); - - /* - * Table(1) Rule #2 - * ---------------- - * Match: Match VLAN ID and L2 ::::FF:FF Flooding - * Action: Flood to local and remote VLAN members - * ------------------------------------------- - * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:10 (eth port),goto_table:2 - */ - - handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, false); - - /* - * Table(1) Rule #3 - * ---------------- - * Match: VLAN ID - * Action: Go to table 2 - * ------------------------------------------- - * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2 - */ - - handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, - segmentationId, ethPort, false); - } - private Long getDpid (Node node, String bridgeUuid) { - Preconditions.checkNotNull(ovsdbConfigurationService); - try { - Row bridgeRow = ovsdbConfigurationService - .getRow(node, ovsdbConfigurationService.getTableName(node, Bridge.class), bridgeUuid); - Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeRow); - Set dpids = bridge.getDatapathIdColumn().getData(); - if (dpids == null || dpids.size() == 0) return 0L; - return HexEncode.stringToLong((String) dpids.toArray()[0]); - } catch (Exception e) { - logger.error("Error finding Bridge's OF DPID", e); - return 0L; - } - } + handleVlanIn(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_2_LOCAL_FORWARD, segmentationId, ethPort, false); - private Long getIntegrationBridgeOFDPID (Node node) { - try { - String bridgeName = configurationService.getIntegrationBridgeName(); - String brIntId = this.getInternalBridgeUUID(node, bridgeName); - if (brIntId == null) { - logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node); - return 0L; - } + /* + * Table(1) Rule #2 + * ---------------- + * Match: Match VLAN ID and L2 ::::FF:FF Flooding + * Action: Flood to local and remote VLAN members + * ------------------------------------------- + * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10 (eth port),goto_table:2 + * table=110, priority=16384,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4 + */ - return getDpid(node, brIntId); - } catch (Exception e) { - logger.error("Error finding Integration Bridge's OF DPID", e); - return 0L; + //handleLocalVlanBcastOut(dpid, TABLE_2_LOCAL_FORWARD, segmentationId, localPort, ethPort, false); + + /* + * Table(1) Rule #2 + * ---------------- + * Match: Match VLAN ID and L2 ::::FF:FF Flooding + * Action: Flood to local and remote VLAN members + * ------------------------------------------- + * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10 (eth port),goto_table:2 + */ + + //handleVlanFloodOut(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, + // segmentationId, ethPort, false); + + /* + * Table(1) Rule #3 + * ---------------- + * Match: VLAN ID + * Action: Go to table 2 + * ------------------------------------------- + * Example: table=1,priority=8192,vlan_id=0x5 actions=output:1,goto_table:2 + * table=110,priority=8192,dl_vlan=2001 actions=output:2 + */ + + handleVlanMiss(dpid, TABLE_1_ISOLATE_TENANT, TABLE_2_LOCAL_FORWARD, segmentationId, ethPort, false); + } + + private Long getDpid(Node node) { + Long dpid = 0L; + dpid = southbound.getDataPathId(node); + if (dpid == 0) { + logger.warn("getDpid: dpid not found: {}", node); } + return dpid; } - private Long getExternalBridgeDpid (Node node) { - try { - String bridgeName = configurationService.getExternalBridgeName(); - String brUuid = this.getInternalBridgeUUID(node, bridgeName); - if (brUuid == null) { - logger.error("Unable to spot Bridge Identifier for {} in {}", bridgeName, node); - return 0L; - } + private Long getIntegrationBridgeOFDPID(Node node) { + Long dpid = 0L; + if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) { + dpid = getDpid(node); + } + return dpid; + } - return getDpid(node, brUuid); - } catch (Exception e) { - logger.error("Error finding External Bridge's OF DPID", e); - return 0L; + private Long getExternalBridgeDpid(Node node) { + Long dpid = 0L; + if (southbound.getBridgeName(node).equals(configurationService.getExternalBridgeName())) { + dpid = getDpid(node); } + return dpid; } - private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) { + private void programLocalRules (String networkType, String segmentationId, Node node, + OvsdbTerminationPointAugmentation intf) { + logger.debug("programLocalRules: node: {}, intf: {}, networkType: {}, segmentationId: {}", + node.getNodeId(), intf.getName(), networkType, segmentationId); try { - Long dpid = this.getIntegrationBridgeOFDPID(node); + Long dpid = getIntegrationBridgeOFDPID(node); if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } - - Set of_ports = intf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node); + logger.debug("programLocalRules: Openflow Datapath-ID not set for the integration bridge in {}", + node); return; } - long localPort = (Long)of_ports.toArray()[0]; - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + logger.info("programLocalRules: could not find ofPort"); return; } - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + logger.warn("No AttachedMac seen in {}", intf); return; } @@ -810,9 +737,26 @@ public class OF13Provider implements NetworkingProvider { if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) { logger.debug("Program local vlan rules for interface {}", intf.getName()); programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort); - } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || - networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { - logger.debug("Program local bridge rules for interface {}", intf.getName()); + } + /* If the network type is tunnel based (VXLAN/GRRE/etc) with Neutron Port Security ACLs */ + /* TODO SB_MIGRATION */ + /*if ((networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || networkType.equalsIgnoreCase + (NetworkHandler.NETWORK_TYPE_VXLAN)) && securityServicesManager.isPortSecurityReady(intf)) { + logger.debug("Neutron port has a Port Security Group"); + // Retrieve the security group UUID from the Neutron Port + NeutronSecurityGroup securityGroupInPort = securityServicesManager.getSecurityGroupInPort(intf); + logger.debug("Program Local rules for networkType: {} does contain a Port Security Group: {} " + + "to be installed on DPID: {}", networkType, securityGroupInPort, dpid); + ingressAclProvider.programPortSecurityACL(dpid, segmentationId, attachedMac, localPort, + securityGroupInPort); + egressAclProvider.programPortSecurityACL(dpid, segmentationId, attachedMac, localPort, + securityGroupInPort); + }*/ + if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || + networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { + logger.debug("Program local bridge rules for interface {}, " + + "dpid: {}, segmentationId: {}, attachedMac: {}, localPort: {}", + intf.getName(), dpid, segmentationId, attachedMac, localPort); programLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort); } } catch (Exception e) { @@ -820,30 +764,26 @@ public class OF13Provider implements NetworkingProvider { } } - private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) { + private void removeLocalRules (String networkType, String segmentationId, Node node, + OvsdbTerminationPointAugmentation intf) { + logger.debug("removeLocalRules: node: {}, intf: {}, networkType: {}, segmentationId: {}", + node.getNodeId(), intf.getName(), networkType, segmentationId); try { - Long dpid = this.getIntegrationBridgeOFDPID(node); + Long dpid = getIntegrationBridgeOFDPID(node); if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } - - Set of_ports = intf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node); + logger.debug("removeLocalRules: Openflow Datapath-ID not set for the integration bridge in {}", node); return; } - long localPort = (Long)of_ports.toArray()[0]; - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + logger.info("removeLocalRules: could not find ofPort"); return; } - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + logger.warn("No AttachedMac seen in {}", intf); return; } @@ -852,7 +792,7 @@ public class OF13Provider implements NetworkingProvider { logger.debug("Remove local vlan rules for interface {}", intf.getName()); removeLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort); } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || - networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { + networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { logger.debug("Remove local bridge rules for interface {}", intf.getName()); removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort); } @@ -861,65 +801,60 @@ public class OF13Provider implements NetworkingProvider { } } + // TODO SB_MIGRATION + // Need to handle case where a node comes online after a network and tunnels have + // already been created. The interface update is what triggers creating the l2 forwarding flows + // so we don't see those updates in this case - we only see the new nodes interface updates. private void programTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node, - Interface intf, boolean local) { - - Preconditions.checkNotNull(ovsdbConfigurationService); - + OvsdbTerminationPointAugmentation intf, boolean local) { + logger.debug("programTunnelRules: node: {}, intf: {}, local: {}, tunnelType: {}, " + + "segmentationId: {}, dstAddr: {}", + node.getNodeId(), intf.getName(), local, tunnelType, segmentationId, dst); try { - - Long dpid = this.getIntegrationBridgeOFDPID(node); + Long dpid = getIntegrationBridgeOFDPID(node); if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } - - Set of_ports = intf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.debug("Could NOT Identify OF value for port {} on {}", intf.getName(), node); + logger.debug("programTunnelRules: Openflow Datapath-ID not set for the integration bridge in {}", node); return; } - long localPort = (Long)of_ports.toArray()[0]; - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + logger.info("programTunnelRules: could not find ofPort"); return; } - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + logger.warn("programTunnelRules: No AttachedMac seen in {}", intf); return; } - Map intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class)); - if (intfs != null) { - for (Row row : intfs.values()) { - Interface tunIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row); - if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) { - of_ports = tunIntf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.debug("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node); - continue; - } - long tunnelOFPort = (Long)of_ports.toArray()[0]; - - if (tunnelOFPort == -1) { - logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node); - return; - } - logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node); - - if (!local) { - programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort); - } - logger.trace("program local ingress tunnel rules: node" + node.getNodeIDString() + " intf " + intf.getName()); - if (local) { - programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort); - } + List intfs = southbound.getTerminationPointsOfBridge(node); + for (OvsdbTerminationPointAugmentation tunIntf : intfs) { + if (tunIntf.getName().equals(getTunnelName(tunnelType, dst))) { + long tunnelOFPort = southbound.getOFPort(tunIntf); + if (tunnelOFPort == 0) { + logger.error("programTunnelRules: Could not Identify Tunnel port {} -> OF ({}) on {}", + tunIntf.getName(), tunnelOFPort, node); return; } + logger.debug("programTunnelRules: Identified Tunnel port {} -> OF ({}) on {}", + tunIntf.getName(), tunnelOFPort, node); + + if (!local) { + logger.trace("programTunnelRules: program remote egress tunnel rules: node {}, intf {}", + node.getNodeId().getValue(), intf.getName()); + programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, + tunnelOFPort, localPort); + } + + if (local) { + logger.trace("programTunnelRules: program local ingress tunnel rules: node {}, intf {}", + node.getNodeId().getValue(), intf.getName()); + programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, + tunnelOFPort, localPort); + } + return; } } } catch (Exception e) { @@ -928,62 +863,50 @@ public class OF13Provider implements NetworkingProvider { } private void removeTunnelRules (String tunnelType, String segmentationId, InetAddress dst, Node node, - Interface intf, boolean local, boolean isLastInstanceOnNode) { - - Preconditions.checkNotNull(ovsdbConfigurationService); + OvsdbTerminationPointAugmentation intf, + boolean local, boolean isLastInstanceOnNode) { + logger.debug("removeTunnelRules: node: {}, intf: {}, local: {}, tunnelType: {}, " + + "segmentationId: {}, dstAddr: {}, isLastinstanceOnNode: {}", + node.getNodeId(), intf.getName(), local, tunnelType, segmentationId, dst, isLastInstanceOnNode); try { - - Long dpid = this.getIntegrationBridgeOFDPID(node); + Long dpid = getIntegrationBridgeOFDPID(node); if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } - - Set of_ports = intf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node); + logger.debug("removeTunnelRules: Openflow Datapath-ID not set for the integration bridge in {}", node); return; } - long localPort = (Long)of_ports.toArray()[0]; - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + logger.info("removeTunnelRules: could not find ofPort"); return; } - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + logger.error("removeTunnelRules: No AttachedMac seen in {}", intf); return; } - Map intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class)); - if (intfs != null) { - for (Row row : intfs.values()) { - Interface tunIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row); - if (tunIntf.getName().equals(this.getTunnelName(tunnelType, dst))) { - of_ports = tunIntf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.error("Could NOT Identify Tunnel port {} on {}", tunIntf.getName(), node); - continue; - } - long tunnelOFPort = (Long)of_ports.toArray()[0]; - - if (tunnelOFPort == -1) { - logger.error("Could NOT Identify Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node); - return; - } - logger.debug("Identified Tunnel port {} -> OF ({}) on {}", tunIntf.getName(), tunnelOFPort, node); - - if (!local) { - removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, tunnelOFPort, localPort); - } - if (local && isLastInstanceOnNode) { - removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort); - } + List intfs = southbound.getTerminationPointsOfBridge(node); + for (OvsdbTerminationPointAugmentation tunIntf : intfs) { + if (tunIntf.getName().equals(getTunnelName(tunnelType, dst))) { + long tunnelOFPort = southbound.getOFPort(tunIntf); + if (tunnelOFPort == -1) { + logger.error("Could not Identify Tunnel port {} -> OF ({}) on {}", + tunIntf.getName(), tunnelOFPort, node); return; } + logger.debug("Identified Tunnel port {} -> OF ({}) on {}", + tunIntf.getName(), tunnelOFPort, node); + + if (!local) { + removeRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, + tunnelOFPort, localPort); + } + if (local && isLastInstanceOnNode) { + removePerTunnelRules(node, dpid, segmentationId, tunnelOFPort); + } + return; } } } catch (Exception e) { @@ -991,263 +914,213 @@ public class OF13Provider implements NetworkingProvider { } } - private void programVlanRules (NeutronNetwork network, Node node, Interface intf) { - Preconditions.checkNotNull(ovsdbConfigurationService); - logger.debug("Program vlan rules for interface {}", intf.getName()); - try { - - Long dpid = this.getIntegrationBridgeOFDPID(node); - if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } - - Set of_ports = intf.getOpenFlowPortColumn().getData(); - int timeout = 6; - while ((of_ports == null) && (timeout > 0)) { - of_ports = intf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - // Wait for the OVSDB update to sync up the Local cache. - Thread.sleep(500); - timeout--; - } - } - if (of_ports == null || of_ports.size() <= 0) { - logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node); - return; - } - - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); - return; - } - - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); - if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); - return; - } - - Map intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class)); - if (intfs != null) { - for (Row row : intfs.values()) { - Interface ethIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row); - if (ethIntf.getName().equalsIgnoreCase(bridgeConfigurationManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()))) { - of_ports = ethIntf.getOpenFlowPortColumn().getData(); - timeout = 6; - while ((of_ports == null) && (timeout > 0)) { - of_ports = ethIntf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - // Wait for the OVSDB update to sync up the Local cache. - Thread.sleep(500); - timeout--; - } - } + private void programVlanRules (NeutronNetwork network, Node node, OvsdbTerminationPointAugmentation intf) { + logger.debug("programVlanRules: node: {}, network: {}, intf: {}", + node.getNodeId(), network.getNetworkUUID(), intf.getName()); + Long dpid = getIntegrationBridgeOFDPID(node); + if (dpid == 0L) { + logger.debug("programVlanRules: Openflow Datapath-ID not set for the integration bridge in {}", node); + return; + } - if (of_ports == null || of_ports.size() <= 0) { - logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node); - continue; - } - long ethOFPort = (Long)of_ports.toArray()[0]; + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + logger.debug("programVlanRules: could not find ofPort for {}", intf.getName()); + return; + } - if (ethOFPort == -1) { - logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node); - throw new Exception("port number < 0"); - } - logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); + if (attachedMac == null) { + logger.debug("programVlanRules: No AttachedMac seen in {}", intf); + return; + } - programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort); - programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort); - return; - } - } - } - } catch (Exception e) { - logger.error("", e); + String phyIfName = + bridgeConfigurationManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()); + long ethOFPort = southbound.getOFPort(node, phyIfName); + if (ethOFPort == 0) { + logger.warn("programVlanRules: could not find ofPort for physical port {}", phyIfName); + return; } + logger.debug("programVlanRules: Identified eth port {} -> ofPort ({}) on {}", + phyIfName, ethOFPort, node); + // TODO: add logic to only add rule on remote nodes + programRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), + attachedMac, ethOFPort); + programLocalIngressVlanRules(node, dpid, network.getProviderSegmentationID(), + attachedMac, localPort, ethOFPort); } - private void removeVlanRules (NeutronNetwork network, Node node, - Interface intf, boolean isLastInstanceOnNode) { - Preconditions.checkNotNull(ovsdbConfigurationService); - logger.debug("Remove vlan rules for interface {}", intf.getName()); - - try { - - Long dpid = this.getIntegrationBridgeOFDPID(node); - if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } - - Set of_ports = intf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.error("Could NOT Identify OF value for port {} on {}", intf.getName(), node); - return; - } - - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); - return; - } + private void removeVlanRules (NeutronNetwork network, Node node, OvsdbTerminationPointAugmentation intf, + boolean isLastInstanceOnNode) { + logger.debug("removeVlanRules: node: {}, network: {}, intf: {}, isLastInstanceOnNode", + node.getNodeId(), network.getNetworkUUID(), intf.getName(), isLastInstanceOnNode); + Long dpid = getIntegrationBridgeOFDPID(node); + if (dpid == 0L) { + logger.debug("removeVlanRules: Openflow Datapath-ID not set for the integration bridge in {}", node); + return; + } - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); - if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); - return; - } + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + logger.debug("removeVlanRules: programVlanRules: could not find ofPort for {}", intf.getName()); + return; + } - Map intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class)); - if (intfs != null) { - for (Row row : intfs.values()) { - Interface ethIntf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row); - if (ethIntf.getName().equalsIgnoreCase(bridgeConfigurationManager.getPhysicalInterfaceName(node, - network.getProviderPhysicalNetwork()))) { - of_ports = ethIntf.getOpenFlowPortColumn().getData(); - if (of_ports == null || of_ports.size() <= 0) { - logger.error("Could NOT Identify eth port {} on {}", ethIntf.getName(), node); - continue; - } - long ethOFPort = (Long)of_ports.toArray()[0]; + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); + if (attachedMac == null) { + logger.debug("removeVlanRules: No AttachedMac seen in {}", intf); + return; + } - if (ethOFPort == -1) { - logger.error("Could NOT Identify eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node); - throw new Exception("port number < 0"); - } - logger.debug("Identified eth port {} -> OF ({}) on {}", ethIntf.getName(), ethOFPort, node); + String phyIfName = + bridgeConfigurationManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()); + long ethOFPort = southbound.getOFPort(node, phyIfName); + if (ethOFPort == 0) { + logger.warn("removeVlanRules: could not find ofPort for physical port {}", phyIfName); + return; + } + logger.debug("removeVlanRules: Identified eth port {} -> ofPort ({}) on {}", + phyIfName, ethOFPort, node); - removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, ethOFPort); - if (isLastInstanceOnNode) { - removePerVlanRules(node, dpid, network.getProviderSegmentationID(), ethOFPort); - } - return; - } - } - } - } catch (Exception e) { - logger.error("", e); + removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), + attachedMac, localPort, ethOFPort); + if (isLastInstanceOnNode) { + removePerVlanRules(node, dpid, network.getProviderSegmentationID(), localPort, ethOFPort); } } @Override - public Status handleInterfaceUpdate(NeutronNetwork network, Node srcNode, Interface intf) { - Preconditions.checkNotNull(connectionService); - List nodes = connectionService.getNodes(); - nodes.remove(srcNode); - this.programLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf); - - if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) { - this.programVlanRules(network, srcNode, intf); - } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) - || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){ - for (Node dstNode : nodes) { + public boolean handleInterfaceUpdate(NeutronNetwork network, Node srcNode, + OvsdbTerminationPointAugmentation intf) { + Preconditions.checkNotNull(nodeCacheManager); + Map nodes = + nodeCacheManager.getOvsdbNodes(); + nodes.remove(southbound.extractBridgeOvsdbNodeId(srcNode)); + String networkType = network.getProviderNetworkType(); + String segmentationId = network.getProviderSegmentationID(); + Node srcBridgeNode = southbound.getBridgeNode(srcNode, configurationService.getIntegrationBridgeName()); + programLocalRules(networkType, network.getProviderSegmentationID(), srcBridgeNode, intf); + + if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) { + programVlanRules(network, srcNode, intf); + } else if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) + || networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)){ + for (Node dstNode : nodes.values()) { InetAddress src = configurationService.getTunnelEndPoint(srcNode); InetAddress dst = configurationService.getTunnelEndPoint(dstNode); - Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst); - if (status.isSuccess()) { - this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true); - } - addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src); - if (status.isSuccess()) { - this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false); + if ((src != null) && (dst != null)) { + Node dstBridgeNode = southbound.getBridgeNode(dstNode, + configurationService.getIntegrationBridgeName()); + if (addTunnelPort(srcBridgeNode, networkType, src, dst)) { + programTunnelRules(networkType, segmentationId, dst, srcBridgeNode, intf, true); + } + if (addTunnelPort(dstBridgeNode, networkType, dst, src)) { + programTunnelRules(networkType, segmentationId, src, dstBridgeNode, intf, false); + } + } else { + logger.warn("Tunnel end-point configuration missing. Please configure it in OpenVSwitch Table. " + + "Check source {} or destination {}", + src != null ? src.getHostAddress() : "null", + dst != null ? dst.getHostAddress() : "null"); } } } - return new Status(StatusCode.SUCCESS); + return true; } - private Status triggerInterfaceUpdates(Node node) { - Preconditions.checkNotNull(ovsdbConfigurationService); - try { - Map intfs = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class)); - if (intfs != null) { - for (Row row : intfs.values()) { - Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row); - NeutronNetwork network = tenantNetworkManager.getTenantNetwork(intf); - logger.debug("Trigger Interface update for {}", intf); - if (network != null) { - this.handleInterfaceUpdate(network, node, intf); - } + private void triggerInterfaceUpdates(Node node) { + logger.debug("enter triggerInterfaceUpdates for {}", node.getNodeId()); + List ports = southbound.extractTerminationPointAugmentations(node); + if (ports != null && !ports.isEmpty()) { + for (OvsdbTerminationPointAugmentation port : ports) { + NeutronNetwork neutronNetwork = tenantNetworkManager.getTenantNetwork(port); + if (neutronNetwork != null) { + logger.warn("Trigger Interface update for {}", port); + handleInterfaceUpdate(neutronNetwork, node, port); } } - } catch (Exception e) { - logger.error("Error Triggering the lost interface updates for "+ node, e); - return new Status(StatusCode.INTERNALERROR, e.getLocalizedMessage()); + } else { + logger.warn("triggerInterfaceUpdates: tps are null"); } - return new Status(StatusCode.SUCCESS); - } - @Override - public Status handleInterfaceUpdate(String tunnelType, String tunnelKey) { - // TODO Auto-generated method stub - return null; + logger.debug("exit triggerInterfaceUpdates for {}", node.getNodeId()); } @Override - public Status handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, Interface intf, - boolean isLastInstanceOnNode) { - Preconditions.checkNotNull(connectionService); - Status status = new Status(StatusCode.SUCCESS); - List nodes = connectionService.getNodes(); - nodes.remove(srcNode); + public boolean handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, + OvsdbTerminationPointAugmentation intf, boolean isLastInstanceOnNode) { + Map nodes = + nodeCacheManager.getOvsdbNodes(); + nodes.remove(southbound.extractBridgeOvsdbNodeId(srcNode)); logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode); List phyIfName = bridgeConfigurationManager.getAllPhysicalInterfaceNames(srcNode); - if (intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) - || intf.getTypeColumn().getData().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) { - /* Delete tunnel port */ + if (southbound.isTunnel(intf)) { + // Delete tunnel port try { - Map options = intf.getOptionsColumn().getData(); - InetAddress src = InetAddress.getByName(options.get("local_ip")); - InetAddress dst = InetAddress.getByName(options.get("remote_ip")); - status = deleteTunnelPort(srcNode, intf.getTypeColumn().getData(), src, dst); + InetAddress src = InetAddress.getByName( + southbound.getOptionsValue(intf.getOptions(), "local_ip")); + InetAddress dst = InetAddress.getByName( + southbound.getOptionsValue(intf.getOptions(), "remote_ip")); + deleteTunnelPort(srcNode, + MdsalHelper.createOvsdbInterfaceType(intf.getInterfaceType()), + src, dst); } catch (Exception e) { logger.error(e.getMessage(), e); } } else if (phyIfName.contains(intf.getName())) { deletePhysicalPort(srcNode, intf.getName()); } else { - /* delete all other interfaces */ - this.removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), + // delete all other interfaces + removeLocalRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), srcNode, intf); if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) { - this.removeVlanRules(network, srcNode, - intf, isLastInstanceOnNode); + removeVlanRules(network, srcNode, intf, isLastInstanceOnNode); } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) - || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { + || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { - for (Node dstNode : nodes) { + for (Node dstNode : nodes.values()) { InetAddress src = configurationService.getTunnelEndPoint(srcNode); InetAddress dst = configurationService.getTunnelEndPoint(dstNode); - logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode " + srcNode.getNodeIDString()); - this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(), - dst, srcNode, intf, true, isLastInstanceOnNode); - logger.info("Remove tunnel rules for interface " + intf.getName() + " on dstNode " + dstNode.getNodeIDString()); - this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(), - src, dstNode, intf, false, isLastInstanceOnNode); + if ((src != null) && (dst != null)) { + logger.info("Remove tunnel rules for interface " + + intf.getName() + " on srcNode " + srcNode.getNodeId().getValue()); + removeTunnelRules(tunnelType, network.getProviderSegmentationID(), + dst, srcNode, intf, true, isLastInstanceOnNode); + Node dstBridgeNode = southbound.getBridgeNode(dstNode, Constants.INTEGRATION_BRIDGE); + if(dstBridgeNode != null){ + logger.info("Remove tunnel rules for interface " + + intf.getName() + " on dstNode " + dstNode.getNodeId().getValue()); + removeTunnelRules(tunnelType, network.getProviderSegmentationID(), + src, dstBridgeNode, intf, false, isLastInstanceOnNode); + } + } else { + logger.warn("Tunnel end-point configuration missing. Please configure it in " + + "OpenVSwitch Table. " + + "Check source {} or destination {}", + src != null ? src.getHostAddress() : "null", + dst != null ? dst.getHostAddress() : "null"); + } } } } - return status; + return true; } @Override public void initializeFlowRules(Node node) { - this.initializeFlowRules(node, configurationService.getIntegrationBridgeName()); - this.initializeFlowRules(node, configurationService.getExternalBridgeName()); - this.triggerInterfaceUpdates(node); + initializeFlowRules(node, configurationService.getIntegrationBridgeName()); + initializeFlowRules(node, configurationService.getExternalBridgeName()); + triggerInterfaceUpdates(node); } private void initializeFlowRules(Node node, String bridgeName) { - String bridgeUuid = this.getInternalBridgeUUID(node, bridgeName); - if (bridgeUuid == null) { - return; - } - - Long dpid = getDpid(node, bridgeUuid); + Long dpid = southbound.getDataPathId(node); + String datapathId = southbound.getDatapathId(node); + logger.info("initializeFlowRules: bridgeName: {}, dpid: {} - {}", + bridgeName, dpid, datapathId); if (dpid == 0L) { logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); @@ -1261,72 +1134,34 @@ public class OF13Provider implements NetworkingProvider { * Action: Packet_In to Controller Reserved Port */ - writeLLDPRule(dpid); - if (bridgeName.equals(configurationService.getExternalBridgeName())) { - writeNormalRule(dpid); - } + writeLLDPRule(dpid); + + if (bridgeName.equals(configurationService.getExternalBridgeName())) { + writeNormalRule(dpid); + } } /* - * Create an LLDP Flow Rule to encapsulate into - * a packet_in that is sent to the controller - * for topology handling. - * Match: Ethertype 0x88CCL - * Action: Punt to Controller in a Packet_In msg - */ + * Create an LLDP Flow Rule to encapsulate into + * a packet_in that is sent to the controller + * for topology handling. + * Match: Ethertype 0x88CCL + * Action: Punt to Controller in a Packet_In msg + */ private void writeLLDPRule(Long dpidLong) { - - String nodeName = OPENFLOW + dpidLong; - EtherType etherType = new EtherType(0x88CCL); - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch(MatchUtils.createEtherTypeMatch(matchBuilder, etherType).build()); - - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createSendToControllerInstructions(ib); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - String flowId = "LLDP"; - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setBarrier(true); - flowBuilder.setTableId((short) 0); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - writeFlow(flowBuilder, nodeBuilder); + classifierProvider.programLLDPPuntRule(dpidLong); } /* - * Create a NORMAL Table Miss Flow Rule - * Match: any - * Action: forward to NORMAL pipeline - */ + * Create a NORMAL Table Miss Flow Rule + * Match: any + * Action: forward to NORMAL pipeline + */ private void writeNormalRule(Long dpidLong) { - String nodeName = OPENFLOW + dpidLong; + String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong; MatchBuilder matchBuilder = new MatchBuilder(); NodeBuilder nodeBuilder = createNodeBuilder(nodeName); @@ -1340,7 +1175,7 @@ public class OF13Provider implements NetworkingProvider { List instructions = Lists.newArrayList(); // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createNormalInstructions(ib); + InstructionUtils.createNormalInstructions(nodeName, ib); ib.setOrder(0); ib.setKey(new InstructionKey(0)); instructions.add(ib.build()); @@ -1373,58 +1208,9 @@ public class OF13Provider implements NetworkingProvider { */ private void handleTunnelIn(Long dpidLong, Short writeTable, - Short goToTableId, String segmentationId, - Long ofPort, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - BigInteger tunnelId = new BigInteger(segmentationId); - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, tunnelId).build()); - flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, ofPort).build()); - - if (write) { - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - - String flowId = "TunnelIn_"+segmentationId+"_"+ofPort; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + Short goToTableId, String segmentationId, + Long ofPort, boolean write) { + classifierProvider.programTunnelIn(dpidLong, segmentationId, ofPort, write); } /* @@ -1435,124 +1221,22 @@ public class OF13Provider implements NetworkingProvider { */ private void handleVlanIn(Long dpidLong, Short writeTable, Short goToTableId, - String segmentationId, Long ethPort, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))) - .build()) - .setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, ethPort) - .build()); - - if (write) { - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - - String flowId = "VlanIn_"+segmentationId+"_"+ethPort; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + String segmentationId, Long ethPort, boolean write) { + classifierProvider.programVlanIn(dpidLong, segmentationId, ethPort, write); } - /* - * (Table:0) Egress VM Traffic Towards TEP - * Match: Destination Ethernet Addr and OpenFlow InPort - * Instruction: Set TunnelID and GOTO Table Tunnel Table (n) - * table=0,in_port=2,dl_src=00:00:00:00:00:01 \ - * actions=set_field:5->tun_id,goto_table=1" - */ + /* + * (Table:0) Egress VM Traffic Towards TEP + * Match: Destination Ethernet Addr and OpenFlow InPort + * Instruction: Set TunnelID and GOTO Table Tunnel Table (n) + * table=0,in_port=2,dl_src=00:00:00:00:00:01 \ + * actions=set_field:5->tun_id,goto_table=1" + */ private void handleLocalInPort(Long dpidLong, Short writeTable, Short goToTableId, - String segmentationId, Long inPort, String attachedMac, - boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch(MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build()); - // TODO Broken In_Port Match - flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build()); - - String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // GOTO Instructions Need to be added first to the List - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - // TODO Broken SetTunID - InstructionUtils.createSetTunnelIdInstructions(ib, new BigInteger(segmentationId)); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + String segmentationId, Long inPort, String attachedMac, + boolean write) { + classifierProvider.programLocalInPort(dpidLong, segmentationId, inPort, attachedMac, write); } /* @@ -1563,63 +1247,12 @@ public class OF13Provider implements NetworkingProvider { * actions=push_vlan, set_field:5->vlan_id,goto_table=1" */ - private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable, - Short goToTableId, String segmentationId, - Long inPort, String attachedMac, - boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch(MatchUtils.createEthSrcMatch(matchBuilder, new MacAddress(attachedMac)).build()); - flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build()); - - String flowId = "LocalMac_"+segmentationId+"_"+inPort+"_"+attachedMac; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // GOTO Instructions Need to be added first to the List - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - // Set VLAN ID Instruction - InstructionUtils.createSetVlanInstructions(ib, new VlanId(Integer.valueOf(segmentationId))); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } - } + private void handleLocalInPortSetVlan(Long dpidLong, Short writeTable, + Short goToTableId, String segmentationId, + Long inPort, String attachedMac, + boolean write) { + classifierProvider.programLocalInPortSetVlan(dpidLong, segmentationId, inPort, attachedMac, write); + } /* * (Table:0) Drop frames source from a VM that do not @@ -1630,119 +1263,21 @@ public class OF13Provider implements NetworkingProvider { */ private void handleDropSrcIface(Long dpidLong, Long inPort, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch(MatchUtils.createInPortMatch(matchBuilder, dpidLong, inPort).build()); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createDropInstructions(ib); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - - String flowId = "DropFilter_"+inPort; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(TABLE_0_DEFAULT_INGRESS); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setPriority(8192); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + classifierProvider.programDropSrcIface(dpidLong, inPort, write); } - /* - * (Table:1) Egress Tunnel Traffic - * Match: Destination Ethernet Addr and Local InPort - * Instruction: Set TunnelID and GOTO Table Tunnel Table (n) - * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \ - * actions=output:10,goto_table:2" - */ + /* + * (Table:1) Egress Tunnel Traffic + * Match: Destination Ethernet Addr and Local InPort + * Instruction: Set TunnelID and GOTO Table Tunnel Table (n) + * table=1,tun_id=0x5,dl_dst=00:00:00:00:00:08 \ + * actions=output:10,goto_table:2" + */ private void handleTunnelOut(Long dpidLong, Short writeTable, - Short goToTableId, String segmentationId, - Long OFPortOut, String attachedMac, - boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build()); - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build()); - - String flowId = "TunnelOut_"+segmentationId+"_"+OFPortOut+"_"+attachedMac; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // GOTO Instructions - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - // Set the Output Port/Iface - InstructionUtils.createOutputPortInstructions(ib, dpidLong, OFPortOut); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + Short goToTableId, String segmentationId, + Long OFPortOut, String attachedMac, + boolean write) { + l2ForwardingProvider.programTunnelOut(dpidLong, segmentationId, OFPortOut, attachedMac, write); } /* @@ -1753,280 +1288,51 @@ public class OF13Provider implements NetworkingProvider { * actions= goto_table:2" */ - private void handleVlanOut(Long dpidLong, Short writeTable, - Short goToTableId, String segmentationId, - Long ethPort, String attachedMac, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build()); - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build()); - - String flowId = "VlanOut_"+segmentationId+"_"+ethPort+"_"+attachedMac; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // GOTO Instructions - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } - } - - /* - * (Table:1) Egress Tunnel Traffic - * Match: Destination Ethernet Addr and Local InPort - * Instruction: Set TunnelID and GOTO Table Tunnel Table (n) - * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:10,output:11,goto_table:2 - */ - - private void handleTunnelFloodOut(Long dpidLong, Short writeTable, - Short localTable, String segmentationId, - Long OFPortOut, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - // Match TunnelID - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build()); - // Match DMAC - - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), - new MacAddress("01:00:00:00:00:00")).build()); - - String flowId = "TunnelFloodOut_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setBarrier(true); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(16384); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - Flow flow = this.getFlow(flowBuilder, nodeBuilder); - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - List instructions = Lists.newArrayList(); - List existingInstructions = null; - if (flow != null) { - Instructions ins = flow.getInstructions(); - if (ins != null) { - existingInstructions = ins.getInstruction(); - } - } - - if (write) { - // GOTO Instruction - InstructionUtils.createGotoTableInstructions(ib, localTable); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - // Set the Output Port/Iface - //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, OFPortOut, existingInstructions); - createOutputPortInstructions(ib, dpidLong, OFPortOut, existingInstructions); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - /* remove port from action list */ - boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong, - OFPortOut, existingInstructions); - if (flowRemove) { - /* if all port are removed, remove the flow too. */ - removeFlow(flowBuilder, nodeBuilder); - } else { - /* Install instruction with new output port list*/ - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - } + private void handleVlanOut(Long dpidLong, Short writeTable, + Short goToTableId, String segmentationId, + Long ethPort, String attachedMac, boolean write) { + l2ForwardingProvider.programVlanOut(dpidLong, segmentationId, ethPort, attachedMac, write); } /* - * (Table:1) Egress VLAN Traffic - * Match: Destination Ethernet Addr and VLAN id - * Instruction: GOTO table 2 and Output port eth interface - * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ - * actions=output:eth1,goto_table:2 + * (Table:1) Egress Tunnel Traffic + * Match: Destination Ethernet Addr and Local InPort + * Instruction: Set TunnelID and GOTO Table Tunnel Table (n) + * table=1,priority=16384,tun_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:10,output:11,goto_table:2 */ - private void handleVlanFloodOut(Long dpidLong, Short writeTable, - Short localTable, String segmentationId, - Long ethPort, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - // Match Vlan ID - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build()); - // Match DMAC - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), - new MacAddress("01:00:00:00:00:00")).build()); - - String flowId = "VlanFloodOut_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setBarrier(true); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(16384); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - //ToDo: Is there something to be done with result of the call to getFlow? - - Flow flow = this.getFlow(flowBuilder, nodeBuilder); - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - List instructions = Lists.newArrayList(); - - if (write) { - // GOTO Instruction - InstructionUtils.createGotoTableInstructions(ib, localTable); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - // Set the Output Port/Iface - InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort); - ib.setOrder(1); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } - } - - /* - * (Table:1) Table Drain w/ Catch All - * Match: Tunnel ID - * Action: GOTO Local Table (10) - * table=2,priority=8192,tun_id=0x5 actions=drop - */ - - private void handleTunnelMiss(Long dpidLong, Short writeTable, - Short goToTableId, String segmentationId, - boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build()); - - if (write) { - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); + private void handleTunnelFloodOut(Long dpidLong, Short writeTable, + Short localTable, String segmentationId, + Long OFPortOut, boolean write) { + l2ForwardingProvider.programTunnelFloodOut(dpidLong, segmentationId, OFPortOut, write); + } - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createGotoTableInstructions(ib, goToTableId); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); + /* + * (Table:1) Egress VLAN Traffic + * Match: Destination Ethernet Addr and VLAN id + * Instruction: GOTO table 2 and Output port eth interface + * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ + * actions=output:eth1,goto_table:2 + */ - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); + private void handleVlanFloodOut(Long dpidLong, Short writeTable, + Short localTable, String segmentationId, + Long localPort, Long ethPort, boolean write) { + //l2ForwardingProvider.programVlanFloodOut(dpidLong, segmentationId, localPort, ethPort, write); + } - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } + /* + * (Table:1) Table Drain w/ Catch All + * Match: Tunnel ID + * Action: GOTO Local Table (10) + * table=2,priority=8192,tun_id=0x5 actions=drop + */ - String flowId = "TunnelMiss_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(8192); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + private void handleTunnelMiss(Long dpidLong, Short writeTable, + Short goToTableId, String segmentationId, + boolean write) { + l2ForwardingProvider.programTunnelMiss(dpidLong, segmentationId, write); } @@ -2035,66 +1341,14 @@ public class OF13Provider implements NetworkingProvider { * Match: Vlan ID * Action: Output port eth interface * table=1,priority=8192,vlan_id=0x5 actions= output port:eth1 + * table=110,priority=8192,dl_vlan=2001 actions=output:2 */ - private void handleVlanMiss(Long dpidLong, Short writeTable, - Short goToTableId, String segmentationId, - Long ethPort, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build()); - - if (write) { - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - //createGotoTableInstructions(ib, goToTableId); - //ib.setOrder(0); - //ib.setKey(new InstructionKey(0)); - //instructions.add(ib.build()); - // Set the Output Port/Iface - InstructionUtils.createOutputPortInstructions(ib, dpidLong, ethPort); - ib.setOrder(0); - ib.setKey(new InstructionKey(1)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - - String flowId = "VlanMiss_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(8192); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } - } + private void handleVlanMiss(Long dpidLong, Short writeTable, + Short goToTableId, String segmentationId, + Long ethPort, boolean write) { + l2ForwardingProvider.programVlanMiss(dpidLong, segmentationId, ethPort, write); + } /* * (Table:1) Local Broadcast Flood @@ -2104,54 +1358,9 @@ public class OF13Provider implements NetworkingProvider { */ private void handleLocalUcastOut(Long dpidLong, Short writeTable, - String segmentationId, Long localPort, - String attachedMac, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build()); - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build()); - - String flowId = "UcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Set the Output Port/Iface - InstructionUtils.createOutputPortInstructions(ib, dpidLong, localPort); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + String segmentationId, Long localPort, + String attachedMac, boolean write) { + l2ForwardingProvider.programLocalUcastOut(dpidLong, segmentationId, localPort, attachedMac, write); } /* @@ -2162,63 +1371,9 @@ public class OF13Provider implements NetworkingProvider { */ private void handleLocalVlanUcastOut(Long dpidLong, Short writeTable, - String segmentationId, Long localPort, - String attachedMac, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build()); - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress(attachedMac), null).build()); - - String flowId = "VlanUcastOut_"+segmentationId+"_"+localPort+"_"+attachedMac; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - - if (write) { - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - List instructions_tmp = Lists.newArrayList(); - - /* Strip vlan and store to tmp instruction space*/ - InstructionUtils.createPopVlanInstructions(ib); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions_tmp.add(ib.build()); - - // Set the Output Port/Iface - ib = new InstructionBuilder(); - InstructionUtils.addOutputPortInstructions(ib, dpidLong, localPort, instructions_tmp); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + String segmentationId, Long localPort, + String attachedMac, boolean write) { + l2ForwardingProvider.programLocalVlanUcastOut(dpidLong, segmentationId, localPort, attachedMac, write); } /* @@ -2229,80 +1384,9 @@ public class OF13Provider implements NetworkingProvider { */ private void handleLocalBcastOut(Long dpidLong, Short writeTable, - String segmentationId, Long localPort, - boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build()); - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), - new MacAddress("01:00:00:00:00:00")).build()); - - String flowId = "BcastOut_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(16384); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - Flow flow = this.getFlow(flowBuilder, nodeBuilder); - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - List instructions = Lists.newArrayList(); - List existingInstructions = null; - if (flow != null) { - Instructions ins = flow.getInstructions(); - if (ins != null) { - existingInstructions = ins.getInstruction(); - } - } - - if (write) { - // Create output port list - createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong, localPort, - existingInstructions); - if (flowRemove) { - /* if all ports are removed, remove flow */ - removeFlow(flowBuilder, nodeBuilder); - } else { - /* Install instruction with new output port list*/ - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } - } + String segmentationId, Long localPort, + boolean write) { + l2ForwardingProvider.programLocalBcastOut(dpidLong, segmentationId, localPort, write); } /* @@ -2310,113 +1394,12 @@ public class OF13Provider implements NetworkingProvider { * Match: vlan ID and dMAC (::::FF:FF) * table=2,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ * actions=strip_vlan, output:2,3,4,5 + * table=110,dl_vlan=2001,dl_dst=01:00:00:00:00:00/01:00:00:00:00:00 actions=output:2,pop_vlan,output:1,output:3,output:4 */ - private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable, - String segmentationId, Long localPort, - boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create the OF Match using MatchBuilder - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build()); - flowBuilder.setMatch(MatchUtils.createDestEthMatch(matchBuilder, new MacAddress("01:00:00:00:00:00"), - new MacAddress("01:00:00:00:00:00")).build()); - - String flowId = "VlanBcastOut_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(16384); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - Flow flow = this.getFlow(flowBuilder, nodeBuilder); - // Instantiate the Builders for the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - List instructions = Lists.newArrayList(); - List existingInstructions = null; - boolean add_pop_vlan = true; - if (flow != null) { - Instructions ins = flow.getInstructions(); - if (ins != null) { - existingInstructions = ins.getInstruction(); - } - } - - if (write) { - if (existingInstructions != null) { - /* Check if pop vlan is already the first action in action list */ - List existingActions; - for (Instruction in : existingInstructions) { - if (in.getInstruction() instanceof ApplyActionsCase) { - existingActions = (((ApplyActionsCase) - in.getInstruction()).getApplyActions().getAction()); - if (existingActions.get(0).getAction() instanceof PopVlanActionCase) { - add_pop_vlan = false; - break; - } - } - } - } else { - existingInstructions = Lists.newArrayList(); - } - - if (add_pop_vlan) { - /* pop vlan */ - InstructionUtils.createPopVlanInstructions(ib); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - existingInstructions.add(ib.build()); - ib = new InstructionBuilder(); - } - - // Create port list - //createOutputGroupInstructions(nodeBuilder, ib, dpidLong, localPort, existingInstructions); - createOutputPortInstructions(ib, dpidLong, localPort, existingInstructions); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - - writeFlow(flowBuilder, nodeBuilder); - } else { - //boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong, - // localPort, existingInstructions); - boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong, - localPort, existingInstructions); - if (flowRemove) { - /* if all ports are removed, remove flow */ - removeFlow(flowBuilder, nodeBuilder); - } else { - /* Install instruction with new output port list*/ - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - writeFlow(flowBuilder, nodeBuilder); - } - } + private void handleLocalVlanBcastOut(Long dpidLong, Short writeTable, String segmentationId, + Long localPort, Long ethPort, boolean write) { + l2ForwardingProvider.programLocalVlanBcastOut(dpidLong, segmentationId, localPort, ethPort, write); } /* @@ -2427,55 +1410,8 @@ public class OF13Provider implements NetworkingProvider { */ private void handleLocalTableMiss(Long dpidLong, Short writeTable, - String segmentationId, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch(MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId)).build()); - - if (write) { - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createDropInstructions(ib); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - - String flowId = "LocalTableMiss_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(8192); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + String segmentationId, boolean write) { + l2ForwardingProvider.programLocalTableMiss(dpidLong, segmentationId, write); } /* @@ -2486,74 +1422,14 @@ public class OF13Provider implements NetworkingProvider { */ private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable, - String segmentationId, boolean write) { - - String nodeName = OPENFLOW + dpidLong; - - MatchBuilder matchBuilder = new MatchBuilder(); - NodeBuilder nodeBuilder = createNodeBuilder(nodeName); - FlowBuilder flowBuilder = new FlowBuilder(); - - // Create Match(es) and Set them in the FlowBuilder Object - flowBuilder.setMatch( - MatchUtils.createVlanIdMatch(matchBuilder, new VlanId(Integer.valueOf(segmentationId))).build()); - - if (write) { - // Create the OF Actions and Instructions - InstructionBuilder ib = new InstructionBuilder(); - InstructionsBuilder isb = new InstructionsBuilder(); - - // Instructions List Stores Individual Instructions - List instructions = Lists.newArrayList(); - - // Call the InstructionBuilder Methods Containing Actions - InstructionUtils.createDropInstructions(ib); - ib.setOrder(0); - ib.setKey(new InstructionKey(0)); - instructions.add(ib.build()); - - // Add InstructionBuilder to the Instruction(s)Builder List - isb.setInstruction(instructions); - - // Add InstructionsBuilder to FlowBuilder - flowBuilder.setInstructions(isb.build()); - } - - String flowId = "LocalTableMiss_"+segmentationId; - // Add Flow Attributes - flowBuilder.setId(new FlowId(flowId)); - FlowKey key = new FlowKey(new FlowId(flowId)); - flowBuilder.setStrict(true); - flowBuilder.setBarrier(false); - flowBuilder.setTableId(writeTable); - flowBuilder.setKey(key); - flowBuilder.setPriority(8192); - flowBuilder.setFlowName(flowId); - flowBuilder.setHardTimeout(0); - flowBuilder.setIdleTimeout(0); - if (write) { - writeFlow(flowBuilder, nodeBuilder); - } else { - removeFlow(flowBuilder, nodeBuilder); - } + String segmentationId, boolean write) { + l2ForwardingProvider.programLocalVlanTableMiss(dpidLong, segmentationId, write); } private Group getGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) { - Preconditions.checkNotNull(mdsalConsumer); - if (mdsalConsumer == null) { - logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?"); - return null; - } - - dataBroker = mdsalConsumer.getDataBroker(); - if (dataBroker == null) { - logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller."); - return null; - } - InstanceIdentifier path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class, - new GroupKey(groupBuilder.getGroupId())).build(); + new GroupKey(groupBuilder.getGroupId())).build(); ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction(); try { Optional data = readTx.read(LogicalDatastoreType.CONFIGURATION, path1).get(); @@ -2569,22 +1445,10 @@ public class OF13Provider implements NetworkingProvider { } private void writeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) { - Preconditions.checkNotNull(mdsalConsumer); - if (mdsalConsumer == null) { - logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?"); - return; - } - - dataBroker = mdsalConsumer.getDataBroker(); - if (dataBroker == null) { - logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller."); - return; - } - ReadWriteTransaction modification = dataBroker.newReadWriteTransaction(); InstanceIdentifier path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class, - new GroupKey(groupBuilder.getGroupId())).build(); + new GroupKey(groupBuilder.getGroupId())).build(); modification.put(LogicalDatastoreType.CONFIGURATION, path1, groupBuilder.build(), true /*createMissingParents*/); CheckedFuture commitFuture = modification.submit(); @@ -2597,22 +1461,10 @@ public class OF13Provider implements NetworkingProvider { } private void removeGroup(GroupBuilder groupBuilder, NodeBuilder nodeBuilder) { - Preconditions.checkNotNull(mdsalConsumer); - if (mdsalConsumer == null) { - logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?"); - return; - } - - dataBroker = mdsalConsumer.getDataBroker(); - if (dataBroker == null) { - logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller."); - return; - } - WriteTransaction modification = dataBroker.newWriteOnlyTransaction(); InstanceIdentifier path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Group.class, - new GroupKey(groupBuilder.getGroupId())).build(); + new GroupKey(groupBuilder.getGroupId())).build(); modification.delete(LogicalDatastoreType.CONFIGURATION, path1); CheckedFuture commitFuture = modification.submit(); @@ -2623,22 +1475,11 @@ public class OF13Provider implements NetworkingProvider { logger.error(e.getMessage(), e); } } - private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) { - Preconditions.checkNotNull(mdsalConsumer); - if (mdsalConsumer == null) { - logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?"); - return null; - } - - dataBroker = mdsalConsumer.getDataBroker(); - if (dataBroker == null) { - logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller."); - return null; - } + private Flow getFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) { InstanceIdentifier path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class, - new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build(); + new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build(); ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction(); try { @@ -2655,25 +1496,16 @@ public class OF13Provider implements NetworkingProvider { } private void writeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) { - Preconditions.checkNotNull(mdsalConsumer); - if (mdsalConsumer == null) { - logger.error("ERROR finding MDSAL Service. Its possible that writeFlow is called too soon ?"); - return; - } - - dataBroker = mdsalConsumer.getDataBroker(); - if (dataBroker == null) { - logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller."); - return; - } - ReadWriteTransaction modification = dataBroker.newReadWriteTransaction(); - InstanceIdentifier path1 = InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory - .rev130819.nodes.Node.class, nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class, - new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build(); + InstanceIdentifier path1 = + InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory + .rev130819.nodes.Node.class, + nodeBuilder.getKey()).augmentation(FlowCapableNode.class).child(Table.class, + new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build(); //modification.put(LogicalDatastoreType.OPERATIONAL, path1, flowBuilder.build()); - modification.put(LogicalDatastoreType.CONFIGURATION, path1, flowBuilder.build(), true /*createMissingParents*/); + modification.put(LogicalDatastoreType.CONFIGURATION, path1, flowBuilder.build(), + true);//createMissingParents CheckedFuture commitFuture = modification.submit(); @@ -2686,24 +1518,12 @@ public class OF13Provider implements NetworkingProvider { } private void removeFlow(FlowBuilder flowBuilder, NodeBuilder nodeBuilder) { - Preconditions.checkNotNull(mdsalConsumer); - if (mdsalConsumer == null) { - logger.error("ERROR finding MDSAL Service."); - return; - } - - dataBroker = mdsalConsumer.getDataBroker(); - if (dataBroker == null) { - logger.error("ERROR finding reference for DataBroker. Please check MD-SAL support on the Controller."); - return; - } - WriteTransaction modification = dataBroker.newWriteOnlyTransaction(); InstanceIdentifier path1 = InstanceIdentifier.builder(Nodes.class) .child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory - .rev130819.nodes.Node.class, nodeBuilder.getKey()) - .augmentation(FlowCapableNode.class).child(Table.class, - new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build(); + .rev130819.nodes.Node.class, nodeBuilder.getKey()) + .augmentation(FlowCapableNode.class).child(Table.class, + new TableKey(flowBuilder.getTableId())).child(Flow.class, flowBuilder.getKey()).build(); //modification.delete(LogicalDatastoreType.OPERATIONAL, nodeBuilderToInstanceId(nodeBuilder)); //modification.delete(LogicalDatastoreType.OPERATIONAL, path1); //modification.delete(LogicalDatastoreType.CONFIGURATION, nodeBuilderToInstanceId(nodeBuilder)); @@ -2718,62 +1538,6 @@ public class OF13Provider implements NetworkingProvider { } } - /** - * Create Output Port Group Instruction - * - * @param ib Map InstructionBuilder without any instructions - * @param dpidLong Long the datapath ID of a switch/node - * @param port Long representing a port on a switch/node - * @return ib InstructionBuilder Map with instructions - */ - protected InstructionBuilder createOutputPortInstructions(InstructionBuilder ib, - Long dpidLong, Long port , - List instructions) { - NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port); - logger.debug("createOutputPortInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); - - List actionList = Lists.newArrayList(); - ActionBuilder ab = new ActionBuilder(); - - List existingActions; - if (instructions != null) { - for (Instruction in : instructions) { - if (in.getInstruction() instanceof ApplyActionsCase) { - existingActions = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction()); - actionList.addAll(existingActions); - } - } - } - /* Create output action for this port*/ - OutputActionBuilder oab = new OutputActionBuilder(); - oab.setOutputNodeConnector(ncid); - ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build()); - boolean addNew = true; - - /* Find the group action and get the group */ - for (Action action : actionList) { - if (action.getAction() instanceof OutputActionCase) { - OutputActionCase opAction = (OutputActionCase)action.getAction(); - /* If output port action already in the action list of one of the buckets, skip */ - if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid))) { - addNew = false; - break; - } - } - } - if (addNew) { - ab.setOrder(actionList.size()); - ab.setKey(new ActionKey(actionList.size())); - actionList.add(ab.build()); - } - // Create an Apply Action - ApplyActionsBuilder aab = new ApplyActionsBuilder(); - aab.setAction(actionList); - ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build()); - logger.debug("createOutputPortInstructions() : applyAction {}", aab.build()); - return ib; - } - /** * Create Output Port Group Instruction * @@ -2783,10 +1547,10 @@ public class OF13Provider implements NetworkingProvider { * @return ib InstructionBuilder Map with instructions */ protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder, - InstructionBuilder ib, - Long dpidLong, Long port , - List instructions) { - NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port); + InstructionBuilder ib, + Long dpidLong, Long port , + List instructions) { + NodeConnectorId ncid = new NodeConnectorId(Constants.OPENFLOW_NODE_PREFIX + dpidLong + ":" + port); logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); List actionList = Lists.newArrayList(); @@ -2940,9 +1704,9 @@ public class OF13Provider implements NetworkingProvider { * @return ib InstructionBuilder Map with instructions */ protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib, - Long dpidLong, Long port , List instructions) { + Long dpidLong, Long port , List instructions) { - NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port); + NodeConnectorId ncid = new NodeConnectorId(Constants.OPENFLOW_NODE_PREFIX + dpidLong + ":" + port); logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); List actionList = Lists.newArrayList(); @@ -3054,50 +1818,57 @@ public class OF13Provider implements NetworkingProvider { @Override public void initializeOFFlowRules(Node openflowNode) { - Preconditions.checkNotNull(connectionService); - List ovsNodes = connectionService.getNodes(); - if (ovsNodes == null) return; - for (Node ovsNode : ovsNodes) { - Long brIntDpid = this.getIntegrationBridgeOFDPID(ovsNode); - Long brExDpid = this.getExternalBridgeDpid(ovsNode); - logger.debug("Compare openflowNode to OVS node {} vs {} and {}", openflowNode.getID(), brIntDpid, brExDpid); - String openflowID = openflowNode.getID().toString(); - if (openflowID.contains(brExDpid.toString())) { - this.initializeFlowRules(ovsNode, configurationService.getExternalBridgeName()); - this.triggerInterfaceUpdates(ovsNode); - } - if (openflowID.contains(brIntDpid.toString())) { - this.initializeFlowRules(ovsNode, configurationService.getIntegrationBridgeName()); - this.triggerInterfaceUpdates(ovsNode); - } + String bridgeName = southbound.getBridgeName(openflowNode); + logger.info("initializeOFFlowRules: bridgeName: {}", bridgeName); + if (bridgeName.equals(configurationService.getIntegrationBridgeName())) { + initializeFlowRules(openflowNode, configurationService.getIntegrationBridgeName()); + triggerInterfaceUpdates(openflowNode); + } else if (bridgeName.equals(configurationService.getExternalBridgeName())) { + initializeFlowRules(openflowNode, configurationService.getExternalBridgeName()); + logger.info("initializeOFFlowRules after writeFlow: bridgeName: {}", bridgeName); + triggerInterfaceUpdates(openflowNode); + logger.info("initializeOFFlowRules after triggerUpdates: bridgeName: {}", bridgeName); } } - private NodeBuilder createNodeBuilder(String nodeId) { + public static NodeBuilder createNodeBuilder(String nodeId) { NodeBuilder builder = new NodeBuilder(); builder.setId(new NodeId(nodeId)); builder.setKey(new NodeKey(builder.getId())); return builder; } - private InstanceIdentifier nodeBuilderToInstanceId(NodeBuilder - node) { - return InstanceIdentifier.builder(Nodes.class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node.class, - node.getKey()).toInstance(); + @Override + public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) { + this.bundleContext = bundleContext; + configurationService = + (ConfigurationService) ServiceHelper.getGlobalInstance(ConfigurationService.class, this); + tenantNetworkManager = + (TenantNetworkManager) ServiceHelper.getGlobalInstance(TenantNetworkManager.class, this); + bridgeConfigurationManager = + (BridgeConfigurationManager) ServiceHelper.getGlobalInstance(BridgeConfigurationManager.class, this); + nodeCacheManager = + (NodeCacheManager) ServiceHelper.getGlobalInstance(NodeCacheManager.class, this); + classifierProvider = + (ClassifierProvider) ServiceHelper.getGlobalInstance(ClassifierProvider.class, this); + ingressAclProvider = + (IngressAclProvider) ServiceHelper.getGlobalInstance(IngressAclProvider.class, this); + egressAclProvider = + (EgressAclProvider) ServiceHelper.getGlobalInstance(EgressAclProvider.class, this); + l2ForwardingProvider = + (L2ForwardingProvider) ServiceHelper.getGlobalInstance(L2ForwardingProvider.class, this); + securityServicesManager = + (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this); + southbound = + (Southbound) ServiceHelper.getGlobalInstance(Southbound.class, this); } - private String getInternalBridgeUUID (Node node, String bridgeName) { - Preconditions.checkNotNull(ovsdbConfigurationService); - try { - Map bridgeTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Bridge.class)); - if (bridgeTable == null) return null; - for (String key : bridgeTable.keySet()) { - Bridge bridge = ovsdbConfigurationService.getTypedRow(node, Bridge.class, bridgeTable.get(key)); - if (bridge.getName().equals(bridgeName)) return key; - } - } catch (Exception e) { - logger.error("Error getting Bridge Identifier for {} / {}", node, bridgeName, e); + @Override + public void setDependencies(Object impl) { + if (impl instanceof NetworkingProviderManager) { + networkingProviderManager = (NetworkingProviderManager)impl; + networkingProviderManager.providerAdded( + bundleContext.getServiceReference(NetworkingProvider.class.getName()),this); } - return null; } }