+ // Keep cache for finding router's mac from network uuid -- NOTE: remove is done later, via cleanupRouterCache()
+ }
+
+ private void programFlowForNetworkFromExternal(final Node node,
+ final Long dpid,
+ final String destinationSegmentationId,
+ final String dstMacAddress,
+ final String destIpStr,
+ final int destMask,
+ final Action actionForNode) {
+ programRouterInterfaceStage1(node, dpid, Constants.EXTERNAL_NETWORK, destinationSegmentationId,
+ dstMacAddress, destIpStr, destMask, actionForNode);
+ }
+
+ private void programFlowsForNeutronRouterInterfacePair(final Node node,
+ final Long dpid,
+ final NeutronRouter_Interface srcNeutronRouterInterface,
+ final NeutronRouter_Interface dstNeutronRouterInterface,
+ final NeutronNetwork dstNeutronNetwork,
+ final String destinationSegmentationId,
+ final String dstMacAddress,
+ final String destIpStr,
+ final int destMask,
+ final Action actionForNode,
+ Boolean isReflexsive) {
+ Preconditions.checkNotNull(srcNeutronRouterInterface);
+ Preconditions.checkNotNull(dstNeutronRouterInterface);
+
+ final String sourceSubnetId = srcNeutronRouterInterface.getSubnetUUID();
+ if (sourceSubnetId == null) {
+ LOG.error("Could not get provider Subnet ID from router interface {}",
+ srcNeutronRouterInterface.getID());
+ return;
+ }
+
+ final NeutronSubnet sourceSubnet = neutronSubnetCache.getSubnet(sourceSubnetId);
+ final String sourceNetworkId = sourceSubnet == null ? null : sourceSubnet.getNetworkUUID();
+ if (sourceNetworkId == null) {
+ LOG.error("Could not get provider Network ID from subnet {}", sourceSubnetId);
+ return;
+ }
+
+ final NeutronNetwork sourceNetwork = neutronNetworkCache.getNetwork(sourceNetworkId);
+ if (sourceNetwork == null) {
+ LOG.error("Could not get provider Network for Network ID {}", sourceNetworkId);
+ return;
+ }
+
+ if (! sourceNetwork.getTenantID().equals(dstNeutronNetwork.getTenantID())) {
+ // Isolate subnets from different tenants within the same router
+ return;
+ }
+ final String sourceSegmentationId = sourceNetwork.getProviderSegmentationID();
+ if (sourceSegmentationId == null) {
+ LOG.error("Could not get provider Segmentation ID for Subnet {}", sourceSubnetId);
+ return;
+ }
+ if (sourceSegmentationId.equals(destinationSegmentationId)) {
+ // Skip 'self'
+ return;
+ }
+
+ programRouterInterfaceStage1(node, dpid, sourceSegmentationId, destinationSegmentationId,
+ dstMacAddress, destIpStr, destMask, actionForNode);
+
+ // Flip roles src->dst; dst->src
+ if (isReflexsive) {
+ final NeutronPort sourceNeutronPort = neutronPortCache.getPort(srcNeutronRouterInterface.getPortUUID());
+ final String macAddress2 = sourceNeutronPort != null ? sourceNeutronPort.getMacAddress() : null;
+ final List<Neutron_IPs> ipList2 = sourceNeutronPort != null ? sourceNeutronPort.getFixedIPs() : null;
+ final String cidr2 = sourceSubnet.getCidr();
+ final int mask2 = getMaskLenFromCidr(cidr2);
+
+ if (cidr2 == null || cidr2.isEmpty() ||
+ macAddress2 == null || macAddress2.isEmpty() ||
+ ipList2 == null || ipList2.isEmpty()) {
+ LOG.trace("programFlowsForNeutronRouterInterfacePair reflexive is bailing seg:{} cidr:{} mac:{} ip:{}",
+ sourceSegmentationId, cidr2, macAddress2, ipList2);
+ // done: go no further w/out all the info needed...
+ return;
+ }
+
+ for (Neutron_IPs neutronIP2 : ipList2) {
+ final String ipStr2 = neutronIP2.getIpAddress();
+ if (ipStr2.isEmpty()) {
+ continue;
+ }
+ programFlowsForNeutronRouterInterfacePair(node, dpid, dstNeutronRouterInterface,
+ srcNeutronRouterInterface,
+ sourceNetwork, sourceSegmentationId,
+ macAddress2, ipStr2, mask2, actionForNode,
+ false /*isReflexsive*/);