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=f2d687f1066534baca3aa346250a04f256f1e856;hb=7d09c56;hp=7acc4323097f308b31d03960afbcdaa0bf6f99be;hpb=09d1d27d6276a7fa542e43f2381e3ef95b610c1c;p=ovsdb.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 7acc43230..f2d687f10 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 @@ -1,18 +1,16 @@ -/** - * Copyright (C) 2013 Red Hat, Inc. +/* + * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved. * * 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 java.net.InetAddress; import java.util.List; import java.util.Map; -import java.util.Set; import java.util.concurrent.ExecutionException; import org.opendaylight.controller.md.sal.binding.api.DataBroker; @@ -21,31 +19,31 @@ 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.networkconfig.neutron.NeutronSecurityGroup; -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.neutron.spi.NeutronNetwork; +import org.opendaylight.neutron.spi.NeutronPort; +import org.opendaylight.neutron.spi.NeutronSecurityGroup; +import org.opendaylight.neutron.spi.Neutron_IPs; +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.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.openstack.netvirt.providers.ConfigInterface; +import org.opendaylight.ovsdb.openstack.netvirt.providers.NetvirtProvidersProvider; import org.opendaylight.ovsdb.utils.mdsal.openflow.InstructionUtils; +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.opendaylight.action.types.rev131112.action.action.GroupActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.GroupActionCaseBuilder; @@ -87,7 +85,11 @@ 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.inventory.rev130819.nodes.NodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeKey; +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.yangtools.yang.binding.InstanceIdentifier; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -97,34 +99,42 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.util.concurrent.CheckedFuture; + /** * 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 { - private static final Logger logger = LoggerFactory.getLogger(OF13Provider.class); - private DataBroker dataBroker; +// Methods' parameters in this class follow the same pattern to avoid confusion between same-typed parameters +// The patterns need to be preserved even though not all parameters are used in all methods +@SuppressWarnings("UnusedParameters") +public class OF13Provider implements ConfigInterface, NetworkingProvider { + private static final Logger LOG = LoggerFactory.getLogger(OF13Provider.class); 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 ClassifierProvider classifierProvider; + private volatile NodeCacheManager nodeCacheManager; private volatile L2ForwardingProvider l2ForwardingProvider; public static final String NAME = "OF13Provider"; + private volatile BundleContext bundleContext; + private volatile Southbound southbound; - public OF13Provider(){ - + public OF13Provider() { + this.dataBroker = NetvirtProvidersProvider.getDataBroker(); } @Override @@ -142,20 +152,22 @@ public class OF13Provider implements NetworkingProvider { return false; } + // The method is tested for in OF13ProviderTest + @SuppressWarnings("unused") private Status getTunnelReadinessStatus (Node node, String tunnelKey) { InetAddress srcTunnelEndPoint = configurationService.getTunnelEndPoint(node); if (srcTunnelEndPoint == null) { - logger.error("Tunnel Endpoint not configured for Node {}", node); + LOG.error("Tunnel Endpoint not configured for Node {}", node); return new Status(StatusCode.NOTFOUND, "Tunnel Endpoint not configured for "+ node); } if (!bridgeConfigurationManager.isNodeNeutronReady(node)) { - logger.error(node+" is not Overlay ready"); + LOG.error("{} is not Overlay ready", node); return new Status(StatusCode.NOTACCEPTABLE, node+" is not Overlay ready"); } if (!tenantNetworkManager.isTenantNetworkPresentInNode(node, tunnelKey)) { - logger.debug(node+" has no VM corresponding to segment "+ tunnelKey); + LOG.debug("{} has no VM corresponding to segment {}", node, tunnelKey); return new Status(StatusCode.NOTACCEPTABLE, node+" has no VM corresponding to segment "+ tunnelKey); } return new Status(StatusCode.SUCCESS); @@ -165,169 +177,50 @@ 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); + LOG.info("addTunnelPort enter: portName: {}", portName); + if (southbound.extractTerminationPointAugmentation(node, portName) != null + || southbound.isTunnelTerminationPointExist(node, tunnelBridgeName, portName)) { + LOG.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); - } + Map options = Maps.newHashMap(); + options.put("key", "flow"); + options.put("local_ip", src.getHostAddress()); + options.put("remote_ip", dst.getHostAddress()); - 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); - } - - 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)) { + LOG.error("Failed to insert Tunnel port {} in {}", portName, tunnelBridgeName); + return false; } + + LOG.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 * ---------------- @@ -335,7 +228,8 @@ 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, true); + handleLocalInPort(dpid, TABLE_0_DEFAULT_INGRESS, TABLE_1_ISOLATE_TENANT, + segmentationId, localPort, attachedMac, true); /* * Table(0) Rule #4 @@ -798,555 +692,558 @@ public class OF13Provider implements NetworkingProvider { 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; + private long getDpid(Node node) { + long dpid = southbound.getDataPathId(node); + if (dpid == 0) { + LOG.warn("getDpid: dpid not found: {}", node); } + return dpid; } - 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; - } - - return getDpid(node, brIntId); - } catch (Exception e) { - logger.error("Error finding Integration Bridge's OF DPID", e); - return 0L; + private long getIntegrationBridgeOFDPID(Node node) { + long dpid = 0L; + if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) { + dpid = getDpid(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; - } + /** + * Returns true is the network if of type GRE or VXLAN + * + * @param networkType The type of the network + * @return returns true if the network is a tunnel + */ + private boolean isTunnel(String networkType) + { + return (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || networkType.equalsIgnoreCase + (NetworkHandler.NETWORK_TYPE_VXLAN)); + } - return getDpid(node, brUuid); - } catch (Exception e) { - logger.error("Error finding External Bridge's OF DPID", e); - return 0L; - } + /** + * Returns true if the network is of type vlan. + * + * @param networkType The type of the network + * @return returns true if the network is a vlan + */ + private boolean isVlan(String networkType) + { + return networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN); } - private void programLocalRules (String networkType, String segmentationId, Node node, Interface intf) { + private void programLocalRules(String networkType, String segmentationId, Node node, + OvsdbTerminationPointAugmentation intf) { + LOG.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); + LOG.debug("programLocalRules: 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); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + LOG.info("programLocalRules: could not find ofPort for Port {} on Node {}", + intf.getName(), node.getNodeId()); return; } - long localPort = (Long)of_ports.toArray()[0]; - 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); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + LOG.warn("No AttachedMac seen in {}", intf); return; } /* Program local rules based on network type */ - if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) { - logger.debug("Program local vlan rules for interface {}", intf.getName()); + if (isVlan(networkType)) { + LOG.debug("Program local vlan rules for interface {}", intf.getName()); programLocalVlanRules(node, dpid, segmentationId, attachedMac, localPort); } - /* If the network type is tunnel based (VXLAN/GRRE/etc) with Neutron Port Security ACLs */ - 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(node, dpid, segmentationId, attachedMac, localPort, - securityGroupInPort); - egressAclProvider.programPortSecurityACL(node, dpid, segmentationId, attachedMac, localPort, - securityGroupInPort); + if ((isTunnel(networkType) || isVlan(networkType))) { + programLocalSecurityGroupRules(attachedMac, node, intf, dpid, localPort, segmentationId, true); } - if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) || - networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { - logger.debug("Program local bridge rules for interface {}", intf.getName()); + if (isTunnel(networkType)) { + LOG.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) { - logger.error("Exception in programming Local Rules for "+intf+" on "+node, e); + LOG.error("Exception in programming Local Rules for " + intf + " on " + node, e); } } - private void removeLocalRules (String networkType, String segmentationId, Node node, Interface intf) { + private void removeLocalRules(String networkType, String segmentationId, Node node, + OvsdbTerminationPointAugmentation intf) { + LOG.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); + LOG.debug("removeLocalRules: 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); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + LOG.info("removeLocalRules: could not find ofPort"); return; } - long localPort = (Long)of_ports.toArray()[0]; - 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); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + LOG.warn("No AttachedMac seen in {}", intf); return; } /* Program local rules based on network type */ - if (networkType.equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) { - logger.debug("Remove local vlan rules for interface {}", intf.getName()); + if (isVlan(networkType)) { + LOG.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)) { - logger.debug("Remove local bridge rules for interface {}", intf.getName()); + } else if (isTunnel(networkType)) { + LOG.debug("Remove local bridge rules for interface {}", intf.getName()); removeLocalBridgeRules(node, dpid, segmentationId, attachedMac, localPort); } + if (isTunnel(networkType) || isVlan(networkType)) { + programLocalSecurityGroupRules(attachedMac, node, intf, dpid, localPort, segmentationId, false); + } } catch (Exception e) { - logger.error("Exception in removing Local Rules for "+intf+" on "+node, e); + LOG.error("Exception in removing Local Rules for " + intf + " on " + node, e); } } + // 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) { + LOG.debug("programTunnelRules: node: {}, intf: {}, local: {}, tunnelType: {}, " + + "segmentationId: {}, dstAddr: {}", + node.getNodeId(), intf.getName(), local, tunnelType, segmentationId, dst.getHostAddress()); 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); + LOG.debug("programTunnelRules: 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); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + LOG.info("programTunnelRules: could not find ofPort for Port {} on Node{}", intf.getName(), node.getNodeId()); return; } - long localPort = (Long)of_ports.toArray()[0]; - 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); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + LOG.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); - } - return; - } + OvsdbTerminationPointAugmentation tunnelPort= southbound.getTerminationPointOfBridge(node, getTunnelName(tunnelType, dst)); + if(tunnelPort != null){ + long tunnelOFPort = southbound.getOFPort(tunnelPort); + if (tunnelOFPort == 0) { + LOG.error("programTunnelRules: Could not Identify Tunnel port {} -> OF ({}) on {}", + tunnelPort.getName(), tunnelOFPort, node); + return; + } + LOG.debug("programTunnelRules: Identified Tunnel port {} -> OF ({}) on {}", + tunnelPort.getName(), tunnelOFPort, node); + + if (!local) { + LOG.trace("programTunnelRules: program remote egress tunnel rules: node {}, intf {}", + node.getNodeId().getValue(), intf.getName()); + programRemoteEgressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, + tunnelOFPort, localPort); + } else { + LOG.trace("programTunnelRules: program local ingress tunnel rules: node {}, intf {}", + node.getNodeId().getValue(), intf.getName()); + programLocalIngressTunnelBridgeRules(node, dpid, segmentationId, attachedMac, + tunnelOFPort, localPort); } } } catch (Exception e) { - logger.error("", e); + LOG.trace("", e); } } 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) { + LOG.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); + LOG.debug("removeTunnelRules: 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); + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + LOG.info("removeTunnelRules: could not find ofPort"); return; } - long localPort = (Long)of_ports.toArray()[0]; - 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); + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); + LOG.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 == 0) { + LOG.error("Could not Identify Tunnel port {} -> OF ({}) on {}", + tunIntf.getName(), tunnelOFPort, node); return; } + LOG.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) { - logger.error("", e); + LOG.error("", e); } } - private void programVlanRules (NeutronNetwork network, Node node, Interface intf) { - Preconditions.checkNotNull(ovsdbConfigurationService); - logger.debug("Program vlan rules for interface {}", intf.getName()); - try { + private void programVlanRules (NeutronNetwork network, Node node, OvsdbTerminationPointAugmentation intf) { + LOG.debug("programVlanRules: node: {}, network: {}, intf: {}", + node.getNodeId(), network.getNetworkUUID(), intf.getName()); + long dpid = getIntegrationBridgeOFDPID(node); + if (dpid == 0L) { + LOG.debug("programVlanRules: Openflow Datapath-ID not set for the integration bridge in {}", node); + return; + } - Long dpid = this.getIntegrationBridgeOFDPID(node); - if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); - return; - } + long localPort = southbound.getOFPort(intf); + if (localPort == 0) { + LOG.debug("programVlanRules: could not find ofPort for {}", intf.getName()); + 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; - } - long localPort = (Long)of_ports.toArray()[0]; + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); + if (attachedMac == null) { + LOG.debug("programVlanRules: No AttachedMac seen in {}", intf); + return; + } - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); - return; - } + String phyIfName = + bridgeConfigurationManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()); + long ethOFPort = southbound.getOFPort(node, phyIfName); + if (ethOFPort == 0) { + LOG.warn("programVlanRules: could not find ofPort for physical port {}", phyIfName); + return; + } + LOG.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, OvsdbTerminationPointAugmentation intf, + boolean isLastInstanceOnNode) { + LOG.debug("removeVlanRules: node: {}, network: {}, intf: {}, isLastInstanceOnNode", + node.getNodeId(), network.getNetworkUUID(), intf.getName(), isLastInstanceOnNode); + long dpid = getIntegrationBridgeOFDPID(node); + if (dpid == 0L) { + LOG.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) { + LOG.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(); - 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--; - } - } + String attachedMac = southbound.getInterfaceExternalIdsValue(intf, Constants.EXTERNAL_ID_VM_MAC); + if (attachedMac == null) { + LOG.debug("removeVlanRules: No AttachedMac seen in {}", intf); + 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]; + String phyIfName = + bridgeConfigurationManager.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork()); + long ethOFPort = southbound.getOFPort(node, phyIfName); + if (ethOFPort == 0) { + LOG.warn("removeVlanRules: could not find ofPort for physical port {}", phyIfName); + return; + } + LOG.debug("removeVlanRules: Identified eth port {} -> ofPort ({}) on {}", + phyIfName, ethOFPort, node); - 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); - // 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); - return; - } - } - } - } catch (Exception e) { - logger.error("", e); + removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), + attachedMac, localPort, ethOFPort); + if (isLastInstanceOnNode) { + removePerVlanRules(node, dpid, network.getProviderSegmentationID(), 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; - } - long localPort = (Long)of_ports.toArray()[0]; - - Map externalIds = intf.getExternalIdsColumn().getData(); - if (externalIds == null) { - logger.error("No external_ids seen in {}", intf); - return; + private void programLocalSecurityGroupRules(String attachedMac, Node node, OvsdbTerminationPointAugmentation intf, + Long dpid,long localPort, String segmentationId, + boolean write) { + + LOG.debug("programLocalRules: Program fixed security group rules for interface {}", intf.getName()); + NeutronPort dhcpPort = securityServicesManager.getDhcpServerPort(intf); + boolean isComputePort = false; + boolean isLastPortinBridge = false; + boolean isLastPortinSubnet = false; + List srcAddressList = null; + if (null != dhcpPort) { + isComputePort = securityServicesManager.isComputePort(intf); + isLastPortinBridge = securityServicesManager.isLastPortinBridge(node, intf); + isLastPortinSubnet = false; + if (isComputePort) { + isLastPortinSubnet = securityServicesManager.isLastPortinSubnet(node, intf); + srcAddressList = securityServicesManager.getIpAddressList(node, intf); + if (null == srcAddressList) { + LOG.warn("programLocalRules: No Ip address assigned {}", intf); + return; + } } - - String attachedMac = externalIds.get(Constants.EXTERNAL_ID_VM_MAC); - if (attachedMac == null) { - logger.error("No AttachedMac seen in {}", intf); - return; + ingressAclProvider.programFixedSecurityAcl(dpid, segmentationId, dhcpPort.getMacAddress(), localPort, + isLastPortinSubnet, isComputePort, write); + egressAclProvider.programFixedSecurityAcl(dpid, segmentationId, attachedMac, localPort, + srcAddressList, isLastPortinBridge, isComputePort,write); + /* If the network type is tunnel based (VXLAN/GRRE/etc) with Neutron Port Security ACLs */ + /* TODO SB_MIGRATION */ + + LOG.debug("Neutron port has a Port Security Group"); + // Retrieve the security group from the Neutron Port and apply the rules + if (securityServicesManager.isPortSecurityReady(intf)) { + //Associate the security group flows. + List securityGroupListInPort = securityServicesManager + .getSecurityGroupInPortList(intf); + for (NeutronSecurityGroup securityGroupInPort:securityGroupListInPort) { + ingressAclProvider.programPortSecurityAcl(dpid, segmentationId, attachedMac, localPort, + securityGroupInPort,srcAddressList, write); + egressAclProvider.programPortSecurityAcl(dpid, segmentationId, attachedMac, localPort, + securityGroupInPort,srcAddressList, write); + } } + } else { + LOG.warn("programLocalRules: No DCHP port seen in network of {}", intf); + } + } - 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]; - - 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); + /* + * The function is for the new compute node joining the existing network. + * When a new VM is instantiated in the new compute node, neutron port add + * event is generated. This event is processed only for that node. So, + * loop through all the ports of the same network and install unicast mac + * flow for the VM's created on the TEP of the destination node in src node. + * This function will be executed even for any new VM creation in an existing + * network. If a cache is maintained to optimize the below flow addition, it will + * work only for one unstack and restack. For the next unstack and restack, + * it will not work since the cache would have been already deleted. + */ + private void programTunnelRulesInNewNode(NeutronNetwork network, + String networkType, String segmentationId, + InetAddress src, InetAddress dst, + Node srcBridgeNode, Node dstBridgeNode, + OvsdbTerminationPointAugmentation intf){ + try { + long localPort = southbound.getOFPort(intf); + if(localPort != 0) + { + LOG.debug("Interface update details {}", intf); + + /* + * When a network is added and the TEP destination is not present in a + * node C1, tunnelin and broadcast rules will not be programmed, since + * OF port is not created. So, when a new node C2 joins and create a new + * VM, the tunnelin and broadcast rule will not be present in C1. + * So, handling it in the case below to make ping work. + */ + if(securityServicesManager.getNeutronPortFromDhcpIntf(intf) == null){ + programTunnelRules(networkType, segmentationId, src, dstBridgeNode, intf, true); + } - removeRemoteEgressVlanRules(node, dpid, network.getProviderSegmentationID(), attachedMac, localPort, ethOFPort); - if (isLastInstanceOnNode) { - removePerVlanRules(node, dpid, network.getProviderSegmentationID(), localPort, ethOFPort); - } - return; + /* + * FIX for 4208 - loop through all the ports and add the VM's + * unicast mac rule of the destination node in the source node. + * When a new node is added, it needs to configure the VM unicast mac + * flow rules which were created before it was joined to an existing + * network. + */ + List ports = southbound.getTerminationPointsOfBridge(dstBridgeNode); + for (OvsdbTerminationPointAugmentation port : ports) { + if(network == tenantNetworkManager.getTenantNetwork(port)){ + programTunnelRules(networkType, segmentationId, dst, srcBridgeNode, port, false); + } + else{ + LOG.trace("Port {} is not part of network {}", port, network); } } } } catch (Exception e) { - logger.error("", e); + LOG.error("Exception during handlingNeutron network add", e); } } @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 (isVlan(networkType)) { + programVlanRules(network, srcNode, intf); + } else if (isTunnel(networkType)){ + + boolean sourceTunnelStatus = false; + boolean destTunnelStatus = false; + for (Node dstNode : nodes.values()) { InetAddress src = configurationService.getTunnelEndPoint(srcNode); InetAddress dst = configurationService.getTunnelEndPoint(dstNode); if ((src != null) && (dst != null)) { - Status status = addTunnelPort(srcNode, network.getProviderNetworkType(), src, dst); - if (status.isSuccess()) { - this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), dst, srcNode, intf, true); + sourceTunnelStatus = addTunnelPort(srcBridgeNode, networkType, src, dst); + + Node dstBridgeNode = southbound.getBridgeNode(dstNode, + configurationService.getIntegrationBridgeName()); + + if(dstBridgeNode != null){ + destTunnelStatus = addTunnelPort(dstBridgeNode, networkType, dst, src); } - addTunnelPort(dstNode, network.getProviderNetworkType(), dst, src); - if (status.isSuccess()) { - this.programTunnelRules(network.getProviderNetworkType(), network.getProviderSegmentationID(), src, dstNode, intf, false); + + if (sourceTunnelStatus) { + programTunnelRules(networkType, segmentationId, dst, srcBridgeNode, intf, true); + } + if (destTunnelStatus) { + programTunnelRules(networkType, segmentationId, src, dstBridgeNode, intf, false); + programTunnelRulesInNewNode(network, networkType, segmentationId, src, dst, + srcBridgeNode, dstBridgeNode, intf); } } else { - logger.warn("Tunnel end-point configuration missing. Please configure it in OpenVSwitch Table. " + - "Check source {} or destination {}", + LOG.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) { + LOG.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) { + LOG.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 { + LOG.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; + LOG.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); - - logger.info("Delete intf " + intf.getName() + " isLastInstanceOnNode " + isLastInstanceOnNode); + public boolean handleInterfaceDelete(String tunnelType, NeutronNetwork network, Node srcNode, + OvsdbTerminationPointAugmentation intf, boolean isLastInstanceOnNode) { + Map nodes = + nodeCacheManager.getOvsdbNodes(); + nodes.remove(southbound.extractBridgeOvsdbNodeId(srcNode)); + + LOG.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); + LOG.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); - } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE) - || network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN)) { + if (isVlan(network.getProviderNetworkType())) { + removeVlanRules(network, srcNode, intf, isLastInstanceOnNode); + } else if (isTunnel(network.getProviderNetworkType())) { - for (Node dstNode : nodes) { + for (Node dstNode : nodes.values()) { InetAddress src = configurationService.getTunnelEndPoint(srcNode); InetAddress dst = configurationService.getTunnelEndPoint(dstNode); if ((src != null) && (dst != null)) { - logger.info("Remove tunnel rules for interface " + intf.getName() + " on srcNode " + srcNode.getNodeIDString()); - this.removeTunnelRules(tunnelType, network.getProviderSegmentationID(), + LOG.info("Remove tunnel rules for interface " + + intf.getName() + " on srcNode " + srcNode.getNodeId().getValue()); + 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); + Node dstBridgeNode = southbound.getBridgeNode(dstNode, Constants.INTEGRATION_BRIDGE); + if(dstBridgeNode != null){ + LOG.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 {}", + LOG.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); + LOG.info("initializeFlowRules: bridgeName: {}, dpid: {} - {}", + bridgeName, dpid, datapathId); if (dpid == 0L) { - logger.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); + LOG.debug("Openflow Datapath-ID not set for the integration bridge in {}", node); return; } @@ -1358,6 +1255,7 @@ public class OF13Provider implements NetworkingProvider { */ writeLLDPRule(dpid); + if (bridgeName.equals(configurationService.getExternalBridgeName())) { writeNormalRule(dpid); } @@ -1383,7 +1281,7 @@ public class OF13Provider implements NetworkingProvider { private void writeNormalRule(Long dpidLong) { - String nodeName = OPENFLOW + dpidLong; + String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpidLong; MatchBuilder matchBuilder = new MatchBuilder(); NodeBuilder nodeBuilder = createNodeBuilder(nodeName); @@ -1397,7 +1295,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()); @@ -1509,7 +1407,8 @@ public class OF13Provider implements NetworkingProvider { * table=1,vlan_id=0x5,dl_dst=00:00:00:00:00:08 \ * actions= goto_table:2" */ - + // TODO This method is referenced from commented code above (which needs to be checked) + @SuppressWarnings("unused") private void handleVlanOut(Long dpidLong, Short writeTable, Short goToTableId, String segmentationId, Long ethPort, String attachedMac, boolean write) { @@ -1537,7 +1436,8 @@ public class OF13Provider implements NetworkingProvider { * Example: table=1,priority=16384,vlan_id=0x5,dl_dst=ff:ff:ff:ff:ff:ff \ * actions=output:eth1,goto_table:2 */ - + // TODO This method is referenced from commented code above (which needs to be checked) + @SuppressWarnings("unused") private void handleVlanFloodOut(Long dpidLong, Short writeTable, Short localTable, String segmentationId, Long localPort, Long ethPort, boolean write) { @@ -1642,25 +1542,14 @@ public class OF13Provider implements NetworkingProvider { * Action: Drop w/ a low priority * table=2,priority=8192,vlan_id=0x5 actions=drop */ - + // TODO This method is referenced from commented code above (which needs to be checked) + @SuppressWarnings("unused") private void handleLocalVlanTableMiss(Long dpidLong, Short writeTable, 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(); @@ -1671,26 +1560,14 @@ public class OF13Provider implements NetworkingProvider { return data.get(); } } catch (InterruptedException|ExecutionException e) { - logger.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } - logger.debug("Cannot find data for Group " + groupBuilder.getGroupName()); + LOG.debug("Cannot find data for Group " + groupBuilder.getGroupName()); return null; } 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, @@ -1700,25 +1577,13 @@ public class OF13Provider implements NetworkingProvider { CheckedFuture commitFuture = modification.submit(); try { commitFuture.get(); // TODO: Make it async (See bug 1362) - logger.debug("Transaction success for write of Group "+groupBuilder.getGroupName()); + LOG.debug("Transaction success for write of Group " + groupBuilder.getGroupName()); } catch (InterruptedException|ExecutionException e) { - logger.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } } 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, @@ -1728,103 +1593,31 @@ public class OF13Provider implements NetworkingProvider { try { commitFuture.get(); // TODO: Make it async (See bug 1362) - logger.debug("Transaction success for deletion of Group "+groupBuilder.getGroupName()); + LOG.debug("Transaction success for deletion of Group " + groupBuilder.getGroupName()); } catch (InterruptedException|ExecutionException e) { - logger.error(e.getMessage(), e); + LOG.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; - } - - 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(); - - ReadOnlyTransaction readTx = dataBroker.newReadOnlyTransaction(); - try { - Optional data = readTx.read(LogicalDatastoreType.CONFIGURATION, path1).get(); - if (data.isPresent()) { - return data.get(); - } - } catch (InterruptedException|ExecutionException e) { - logger.error(e.getMessage(), e); - } - - logger.debug("Cannot find data for Flow " + flowBuilder.getFlowName()); - return null; - } 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, + 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*/); - - - CheckedFuture commitFuture = modification.submit(); - try { - commitFuture.get(); // TODO: Make it async (See bug 1362) - logger.debug("Transaction success for write of Flow "+flowBuilder.getFlowName()); - } catch (InterruptedException|ExecutionException e) { - logger.error(e.getMessage(), e); - } - } + modification.put(LogicalDatastoreType.CONFIGURATION, path1, flowBuilder.build(), + true);//createMissingParents - 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(); - //modification.delete(LogicalDatastoreType.OPERATIONAL, nodeBuilderToInstanceId(nodeBuilder)); - //modification.delete(LogicalDatastoreType.OPERATIONAL, path1); - //modification.delete(LogicalDatastoreType.CONFIGURATION, nodeBuilderToInstanceId(nodeBuilder)); - modification.delete(LogicalDatastoreType.CONFIGURATION, path1); CheckedFuture commitFuture = modification.submit(); try { commitFuture.get(); // TODO: Make it async (See bug 1362) - logger.debug("Transaction success for deletion of Flow "+flowBuilder.getFlowName()); + LOG.debug("Transaction success for write of Flow " + flowBuilder.getFlowName()); } catch (InterruptedException|ExecutionException e) { - logger.error(e.getMessage(), e); + LOG.error(e.getMessage(), e); } } @@ -1836,12 +1629,14 @@ public class OF13Provider implements NetworkingProvider { * @param port Long representing a port on a switch/node * @return ib InstructionBuilder Map with instructions */ + // TODO This method is referenced from commented code in L2ForwardingService (which needs to be checked) + @SuppressWarnings("unused") protected InstructionBuilder createOutputGroupInstructions(NodeBuilder nodeBuilder, InstructionBuilder ib, Long dpidLong, Long port , List instructions) { - NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port); - logger.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); + NodeConnectorId ncid = new NodeConnectorId(Constants.OPENFLOW_NODE_PREFIX + dpidLong + ":" + port); + LOG.debug("createOutputGroupInstructions() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); List actionList = Lists.newArrayList(); ActionBuilder ab = new ActionBuilder(); @@ -1863,7 +1658,7 @@ public class OF13Provider implements NetworkingProvider { OutputActionBuilder oab = new OutputActionBuilder(); oab.setOutputNodeConnector(ncid); ab.setAction(new OutputActionCaseBuilder().setOutputAction(oab.build()).build()); - logger.debug("createOutputGroupInstructions(): output action {}", ab.build()); + LOG.debug("createOutputGroupInstructions(): output action {}", ab.build()); boolean addNew = true; boolean groupActionAdded = false; @@ -1881,19 +1676,19 @@ public class OF13Provider implements NetworkingProvider { groupBuilder.setGroupType(GroupTypes.GroupAll); groupBuilder.setKey(key); group = getGroup(groupBuilder, nodeBuilder); - logger.debug("createOutputGroupInstructions: group {}", group); + LOG.debug("createOutputGroupInstructions: group {}", group); break; } } - logger.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded); + LOG.debug("createOutputGroupInstructions: groupActionAdded {}", groupActionAdded); if (groupActionAdded) { /* modify the action bucket in group */ groupBuilder = new GroupBuilder(group); Buckets buckets = groupBuilder.getBuckets(); for (Bucket bucket : buckets.getBucket()) { List bucketActions = bucket.getAction(); - logger.debug("createOutputGroupInstructions: bucketActions {}", bucketActions); + LOG.debug("createOutputGroupInstructions: bucketActions {}", bucketActions); for (Action action : bucketActions) { if (action.getAction() instanceof OutputActionCase) { OutputActionCase opAction = (OutputActionCase)action.getAction(); @@ -1905,30 +1700,28 @@ public class OF13Provider implements NetworkingProvider { } } } - logger.debug("createOutputGroupInstructions: addNew {}", addNew); - if (addNew) { + LOG.debug("createOutputGroupInstructions: addNew {}", addNew); + if (addNew && !buckets.getBucket().isEmpty()) { /* the new output action is not in the bucket, add to bucket */ - if (!buckets.getBucket().isEmpty()) { - Bucket bucket = buckets.getBucket().get(0); - List bucketActionList = Lists.newArrayList(); - bucketActionList.addAll(bucket.getAction()); - /* set order for new action and add to action list */ - ab.setOrder(bucketActionList.size()); - ab.setKey(new ActionKey(bucketActionList.size())); - bucketActionList.add(ab.build()); - - /* set bucket and buckets list. Reset groupBuilder with new buckets.*/ - BucketsBuilder bucketsBuilder = new BucketsBuilder(); - List bucketList = Lists.newArrayList(); - BucketBuilder bucketBuilder = new BucketBuilder(); - bucketBuilder.setBucketId(new BucketId((long) 1)); - bucketBuilder.setKey(new BucketKey(new BucketId((long) 1))); - bucketBuilder.setAction(bucketActionList); - bucketList.add(bucketBuilder.build()); - bucketsBuilder.setBucket(bucketList); - groupBuilder.setBuckets(bucketsBuilder.build()); - logger.debug("createOutputGroupInstructions: bucketList {}", bucketList); - } + Bucket bucket = buckets.getBucket().get(0); + List bucketActionList = Lists.newArrayList(); + bucketActionList.addAll(bucket.getAction()); + /* set order for new action and add to action list */ + ab.setOrder(bucketActionList.size()); + ab.setKey(new ActionKey(bucketActionList.size())); + bucketActionList.add(ab.build()); + + /* set bucket and buckets list. Reset groupBuilder with new buckets.*/ + BucketsBuilder bucketsBuilder = new BucketsBuilder(); + List bucketList = Lists.newArrayList(); + BucketBuilder bucketBuilder = new BucketBuilder(); + bucketBuilder.setBucketId(new BucketId((long) 1)); + bucketBuilder.setKey(new BucketKey(new BucketId((long) 1))); + bucketBuilder.setAction(bucketActionList); + bucketList.add(bucketBuilder.build()); + bucketsBuilder.setBucket(bucketList); + groupBuilder.setBuckets(bucketsBuilder.build()); + LOG.debug("createOutputGroupInstructions: bucketList {}", bucketList); } } else { /* create group */ @@ -1969,8 +1762,8 @@ public class OF13Provider implements NetworkingProvider { groupId++; } - logger.debug("createOutputGroupInstructions: group {}", groupBuilder.build()); - logger.debug("createOutputGroupInstructions: actionList {}", actionList); + LOG.debug("createOutputGroupInstructions: group {}", groupBuilder.build()); + LOG.debug("createOutputGroupInstructions: actionList {}", actionList); if (addNew) { /* rewrite the group to group table */ @@ -1993,11 +1786,13 @@ public class OF13Provider implements NetworkingProvider { * @param port Long representing a port on a switch/node * @return ib InstructionBuilder Map with instructions */ + // TODO This method is referenced from commented code in L2ForwardingService (which needs to be checked) + @SuppressWarnings("unused") protected boolean removeOutputPortFromGroup(NodeBuilder nodeBuilder, InstructionBuilder ib, Long dpidLong, Long port , List instructions) { - NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + port); - logger.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); + NodeConnectorId ncid = new NodeConnectorId(Constants.OPENFLOW_NODE_PREFIX + dpidLong + ":" + port); + LOG.debug("removeOutputPortFromGroup() Node Connector ID is - Type=openflow: DPID={} port={} existingInstructions={}", dpidLong, port, instructions); List actionList = Lists.newArrayList(); ActionBuilder ab; @@ -2088,7 +1883,7 @@ public class OF13Provider implements NetworkingProvider { bucketList.add(bucketBuilder.build()); bucketsBuilder.setBucket(bucketList); groupBuilder.setBuckets(bucketsBuilder.build()); - logger.debug("removeOutputPortFromGroup: bucketList {}", bucketList); + LOG.debug("removeOutputPortFromGroup: bucketList {}", bucketList); writeGroup(groupBuilder, nodeBuilder); ApplyActionsBuilder aab = new ApplyActionsBuilder(); @@ -2108,22 +1903,16 @@ 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); + LOG.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()); + LOG.info("initializeOFFlowRules after writeFlow: bridgeName: {}", bridgeName); + triggerInterfaceUpdates(openflowNode); + LOG.info("initializeOFFlowRules after triggerUpdates: bridgeName: {}", bridgeName); } } @@ -2134,24 +1923,37 @@ public class OF13Provider implements NetworkingProvider { 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 = (NetworkingProviderManager) impl; + networkingProviderManager.providerAdded( + bundleContext.getServiceReference(NetworkingProvider.class.getName()), this); } - return null; } }