+ if (network != null) {
+ final NeutronPort neutronPort = tenantNetworkManager.getTenantPort(port);
+ if (!(Action.UPDATE.equals(action) && isMigratedPort(node, neutronPort))) {
+ if (!network.getRouterExternal()) {
+ handleInterfaceUpdate(node, port, action);
+ } else if (Action.UPDATE.equals(action)) {
+ programVLANNetworkFlowProvider(node, port, network, neutronPort, true);
+ }
+ }
+ } else if (null != port.getInterfaceType() && null != port.getOfport()) {
+ // Filter Vxlan interface request and install table#110 unicast flow (Bug 7392).
+ if(port.getInterfaceType().equals(InterfaceTypeVxlan.class)) {
+ List<Options> optionList = port.getOptions();
+ if (null != optionList && !optionList.isEmpty()) {
+ optionList.stream().filter(option -> isRemoteIp(option)).forEach(option ->
+ handleTunnelOut(node, option.getValue(), port.getOfport()));
+ }
+ }
+ }
+ }
+
+ private boolean isRemoteIp(Options option) {
+ return option.getOption().equals(Constants.TUNNEL_ENDPOINT_KEY_REMOTE);
+ }
+
+ private void handleTunnelOut(Node node, String remoteIp, Long ofPort) {
+ List<Node> nodes = nodeCacheManager.getBridgeNodes();
+ if (null != nodes && !nodes.isEmpty()) {
+ nodes.stream().filter(dstnode -> isDstNode(node, dstnode, remoteIp)).forEach(dstnode ->
+ programTunnelOut(node, dstnode, ofPort));
+ }
+ }
+
+ private boolean isDstNode(Node node, Node dstnode, String remoteIp) {
+ if (!(node.getNodeId().getValue().equals(dstnode.getNodeId().getValue()))) {
+ InetAddress dst = configurationService.getTunnelEndPoint(dstnode);
+ String dstIp = dst.getHostAddress();
+ if (remoteIp.equals(dstIp)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private void programTunnelOut(Node node, Node dstnode, Long ofPort) {
+ List<OvsdbTerminationPointAugmentation> ports = southbound.readTerminationPointAugmentations(dstnode);
+ for (OvsdbTerminationPointAugmentation destport : ports) {
+ NeutronPort neutronPort = tenantNetworkManager.getTenantPort(destport);
+ if (neutronPort != null) {
+ final String networkUUID = neutronPort.getNetworkUUID();
+ NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(networkUUID);
+ if (null == neutronNetwork) {
+ neutronNetwork = neutronL3Adapter.getNetworkFromCleanupCache(networkUUID);
+ }
+ final String segmentationId = neutronNetwork != null ? neutronNetwork.getProviderSegmentationID() : null;
+ final String macAddress = neutronPort.getMacAddress();
+ long dpid = getIntegrationBridgeOFDPID(node);
+ if (null != l2ForwardingProvider) {
+ l2ForwardingProvider.programTunnelOut(dpid, segmentationId, ofPort, macAddress, true);
+ }
+ }
+ }
+ }
+
+ private long getIntegrationBridgeOFDPID(Node node) {
+ long dpid = 0L;
+ if (southbound.getBridgeName(node).equals(configurationService.getIntegrationBridgeName())) {
+ dpid = southbound.getDataPathId(node);
+ }
+ return dpid;
+ }
+
+ private void programVLANNetworkFlowProvider(final Node node, final OvsdbTerminationPointAugmentation port,
+ final NeutronNetwork network, final NeutronPort neutronPort, final Boolean isWrite) {
+ if (neutronPort != null && neutronPort.getDeviceOwner().equalsIgnoreCase(Constants.OWNER_ROUTER_GATEWAY) &&
+ network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN) &&
+ configurationService.isL3MultipleExternalNetworkEnabled()) {
+ vlanProvider.programProviderNetworkFlow(node, port, network, neutronPort, isWrite);