Merge "Enable cancel monitoring"
authorSam Hague <shague@redhat.com>
Mon, 17 Aug 2015 17:53:58 +0000 (17:53 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Mon, 17 Aug 2015 17:53:58 +0000 (17:53 +0000)
15 files changed:
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/Service.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/RoutingService.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpResolverMetadata.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/ArpResolverUtils.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/arp/GatewayMacResolverService.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandler.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/GatewayMacResolver.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/SecurityServicesImpl.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/LBaaSPoolMemberHandlerTest.java
openstack/net-virt/src/test/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3AdapterTest.java

index b957b71860c62b4dd53a854ea70e42c8532e152a..30bec35cdaf0fe620babc66ed073b6ad3d2b1a87 100644 (file)
@@ -21,7 +21,7 @@ public enum Service {
     L3_FORWARDING ((short) 70, "Layer 3 forwarding/lookup service"),
     L2_REWRITE ((short) 80, "Layer2 rewrite service"),
     INGRESS_ACL ((short) 90, "Ingress Acces-control"),
-    OUTBOUND_NAT ((short) 100, "SNAT for traffic accessing external network"),
+    OUTBOUND_NAT ((short) 100, "DNAT for outbound floating-ip traffic"),
     L2_FORWARDING ((short) 110, "Layer2 mac,vlan based forwarding");
 
     short table;
index 68a101e31741de07fcaded79438297827ceeb3b1..152becc3e5a41978f8922e327f6cf70344507cce 100644 (file)
@@ -9,6 +9,7 @@
 package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
 
 import java.math.BigInteger;
+import java.net.Inet6Address;
 import java.net.InetAddress;
 import java.util.List;
 
@@ -43,8 +44,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.N
 import com.google.common.collect.Lists;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class RoutingService extends AbstractServiceInstance implements RoutingProvider, ConfigInterface {
+    private static final Logger LOG = LoggerFactory.getLogger(RoutingService.class);
     public RoutingService() {
         super(Service.ROUTING);
     }
@@ -79,6 +83,13 @@ public class RoutingService extends AbstractServiceInstance implements RoutingPr
             MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(sourceSegId));
         }
 
+        if (address instanceof Inet6Address) {
+            // WORKAROUND: For now ipv6 is not supported
+            // TODO: implement ipv6 case
+            LOG.debug("ipv6 address is not implemented yet. address {}",
+                      address);
+            new Status(StatusCode.NOTIMPLEMENTED);
+        }
         final String prefixString = address.getHostAddress() + "/" + mask;
         MatchUtils.createDstL3IPv4Match(matchBuilder, new Ipv4Prefix(prefixString));
 
index 8947cdfb6f53cb7e90fa2a001bd9389df5454061..0ac0bc0884650f8d253a9b110e7b7069828575d6 100644 (file)
@@ -19,24 +19,21 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.Remo
 
 public final class ArpResolverMetadata {
 
+    private final Ipv4Address gatewayIpAddress;
+    private final Long externalNetworkBridgeDpid;
+    private final Ipv4Address arpRequestSourceIp;
+    private final MacAddress arpRequestSourceMacAddress;
+    private final boolean periodicRefresh;
     private RemoveFlowInput flowToRemove;
-    private Ipv4Address gatewayIpAddress;
     private MacAddress gatewayMacAddress;
-    private boolean periodicRefresh;
 
-    public ArpResolverMetadata(){
-
-    }
-    public ArpResolverMetadata(RemoveFlowInput flowToRemove, Ipv4Address gatewayIpAddress, boolean periodicRefresh){
-        this.flowToRemove = flowToRemove;
+    public ArpResolverMetadata(final Long externalNetworkBridgeDpid,
+            final Ipv4Address gatewayIpAddress, final Ipv4Address arpRequestSourceIp,
+            final MacAddress arpRequestMacAddress, final boolean periodicRefresh){
+        this.externalNetworkBridgeDpid = externalNetworkBridgeDpid;
         this.gatewayIpAddress = gatewayIpAddress;
-        this.periodicRefresh = periodicRefresh;
-    }
-
-    public ArpResolverMetadata(RemoveFlowInput flowToRemove, Ipv4Address gatewayIpAddress, MacAddress gatewayMacAddress, boolean periodicRefresh){
-        this.flowToRemove = flowToRemove;
-        this.gatewayIpAddress = gatewayIpAddress;
-        this.gatewayMacAddress = gatewayMacAddress;
+        this.arpRequestSourceIp = arpRequestSourceIp;
+        this.arpRequestSourceMacAddress = arpRequestMacAddress;
         this.periodicRefresh = periodicRefresh;
     }
 
@@ -46,18 +43,12 @@ public final class ArpResolverMetadata {
     public boolean isPeriodicRefresh() {
         return periodicRefresh;
     }
-    public void setPeriodicRefresh(boolean periodicRefresh) {
-        this.periodicRefresh = periodicRefresh;
-    }
     public void setFlowToRemove(RemoveFlowInput flowToRemove) {
         this.flowToRemove = flowToRemove;
     }
     public Ipv4Address getGatewayIpAddress() {
         return gatewayIpAddress;
     }
-    public void setGatewayIpAddress(Ipv4Address gatewayIpAddress) {
-        this.gatewayIpAddress = gatewayIpAddress;
-    }
     public MacAddress getGatewayMacAddress() {
         return gatewayMacAddress;
     }
@@ -65,4 +56,72 @@ public final class ArpResolverMetadata {
         this.gatewayMacAddress = gatewayMacAddress;
     }
 
+    public Long getExternalNetworkBridgeDpid() {
+        return externalNetworkBridgeDpid;
+    }
+    public Ipv4Address getArpRequestSourceIp() {
+        return arpRequestSourceIp;
+    }
+    public MacAddress getArpRequestMacAddress() {
+        return arpRequestSourceMacAddress;
+    }
+
+    @Override
+    public int hashCode() {
+        final int prime = 31;
+        int result = 1;
+        result = prime
+                * result
+                + ((arpRequestSourceMacAddress == null) ? 0 : arpRequestSourceMacAddress
+                        .hashCode());
+        result = prime
+                * result
+                + ((arpRequestSourceIp == null) ? 0 : arpRequestSourceIp
+                        .hashCode());
+        result = prime
+                * result
+                + ((externalNetworkBridgeDpid == null) ? 0
+                        : externalNetworkBridgeDpid.hashCode());
+        result = prime
+                * result
+                + ((gatewayIpAddress == null) ? 0 : gatewayIpAddress.hashCode());
+        result = prime * result + (periodicRefresh ? 1231 : 1237);
+        return result;
+    }
+
+    @Override
+    public boolean equals(Object obj) {
+        if (this == obj)
+            return true;
+        if (obj == null)
+            return false;
+        if (getClass() != obj.getClass())
+            return false;
+        ArpResolverMetadata other = (ArpResolverMetadata) obj;
+        if (arpRequestSourceMacAddress == null) {
+            if (other.arpRequestSourceMacAddress != null)
+                return false;
+        } else if (!arpRequestSourceMacAddress.equals(other.arpRequestSourceMacAddress))
+            return false;
+        if (arpRequestSourceIp == null) {
+            if (other.arpRequestSourceIp != null)
+                return false;
+        } else if (!arpRequestSourceIp.equals(other.arpRequestSourceIp))
+            return false;
+        if (externalNetworkBridgeDpid == null) {
+            if (other.externalNetworkBridgeDpid != null)
+                return false;
+        } else if (!externalNetworkBridgeDpid
+                .equals(other.externalNetworkBridgeDpid))
+            return false;
+        if (gatewayIpAddress == null) {
+            if (other.gatewayIpAddress != null)
+                return false;
+        } else if (!gatewayIpAddress.equals(other.gatewayIpAddress))
+            return false;
+        if (periodicRefresh != other.periodicRefresh)
+            return false;
+        return true;
+    }
+
 }
index 3f404f684c66308d94b59ba974bd9bdf4b8f8443..7ccbb7de81c802844bf5e919230a5cdeb235445f 100644 (file)
@@ -13,8 +13,12 @@ import org.opendaylight.controller.liblldp.Ethernet;
 import org.opendaylight.controller.liblldp.NetUtils;
 import org.opendaylight.controller.liblldp.PacketException;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.PacketReceived;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class ArpResolverUtils {
+    private static final Logger LOG = LoggerFactory.getLogger(ArpResolverUtils.class);
+
 
     static {
         Ethernet.etherTypeClassMap.put(EtherTypes.ARP.shortValue(), Arp.class);
@@ -26,15 +30,18 @@ public class ArpResolverUtils {
      *
      * @param potentialArp the packet for deserialization
      * @return ARP packet if received packet is ARP and deserialization was successful
-     * @throws PacketException if packet is not ARP or deserialization was not successful
      */
-    public static Arp getArpFrom(PacketReceived potentialArp) throws PacketException {
+    public static Arp getArpFrom(PacketReceived potentialArp) {
         byte[] payload = potentialArp.getPayload();
         Ethernet ethPkt = new Ethernet();
-        ethPkt.deserialize(payload, 0, payload.length * NetUtils.NumBitsInAByte);
+        try {
+            ethPkt.deserialize(payload, 0, payload.length * NetUtils.NumBitsInAByte);
+        } catch (PacketException e) {
+            LOG.trace("Failed to decode the incoming packet. ignoring it.");
+        }
         if (ethPkt.getPayload() instanceof Arp) {
             return (Arp) ethPkt.getPayload();
         }
-        throw new PacketException("Packet is not ARP: " + potentialArp);
+        return null;
     }
 }
index fad23d4b509499158ca3981665dfd57f06573d66..dd6ae714bc4411222cdfb9ce3dd9e327480f9574 100644 (file)
@@ -10,11 +10,14 @@ package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.a
 import static com.google.common.base.Preconditions.checkNotNull;
 
 import java.math.BigInteger;
-import java.util.Map;
+import java.util.Map.Entry;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicLong;
 
@@ -96,12 +99,15 @@ public class GatewayMacResolverService extends AbstractServiceInstance
     private ArpSender arpSender;
     private SalFlowService flowService;
     private final AtomicLong flowCookie = new AtomicLong();
-    private final Map<Ipv4Address, ArpResolverMetadata> arpRemoveFlowInputAndL3EpKeyById =
+    private final ConcurrentMap<Ipv4Address, ArpResolverMetadata> gatewayToArpMetadataMap =
             new ConcurrentHashMap<Ipv4Address, ArpResolverMetadata>();
     private final int ARP_WATCH_BROTHERS = 10;
     private final int WAIT_CYCLES = 3;
     private final int PER_CYCLE_WAIT_DURATION = 1000;
+    private final int REFRESH_INTERVAL = 10;
     private final ListeningExecutorService arpWatcherWall = MoreExecutors.listeningDecorator(Executors.newFixedThreadPool(ARP_WATCH_BROTHERS));
+    private final ScheduledExecutorService gatewayMacRefresherPool = Executors.newScheduledThreadPool(1);
+    private final ScheduledExecutorService refreshRequester = Executors.newSingleThreadScheduledExecutor();
     private AtomicBoolean initializationDone = new AtomicBoolean(false);
 
     static {
@@ -134,6 +140,35 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                 this.arpSender = null;
             }
             flowService = providerContext.getRpcService(SalFlowService.class);
+            refreshRequester.scheduleWithFixedDelay(new Runnable(){
+
+                @Override
+                public void run() {
+                    if (!gatewayToArpMetadataMap.isEmpty()){
+                        for(final Entry<Ipv4Address, ArpResolverMetadata> gatewayToArpMetadataEntry : gatewayToArpMetadataMap.entrySet()){
+                            final Ipv4Address gatewayIp = gatewayToArpMetadataEntry.getKey();
+                            final ArpResolverMetadata gatewayMetaData = gatewayToArpMetadataEntry.getValue();
+                            gatewayMacRefresherPool.schedule(new Runnable(){
+
+                                @Override
+                                public void run() {
+
+                                    final Node externalNetworkBridge = getExternalBridge(gatewayMetaData.getExternalNetworkBridgeDpid());
+                                    if(externalNetworkBridge == null){
+                                        LOG.error("MAC address for gateway {} can not be resolved, because external bridge {} "
+                                                + "is not connected to controller.",gatewayIp.getValue(),gatewayMetaData.getExternalNetworkBridgeDpid() );
+                                    }
+
+                                    LOG.debug("Refresh Gateway Mac for gateway {} using source ip {} and mac {} for ARP request",
+                                            gatewayIp.getValue(),gatewayMetaData.getArpRequestSourceIp().getValue(),gatewayMetaData.getArpRequestMacAddress().getValue());
+
+                                    sendGatewayArpRequest(externalNetworkBridge,gatewayIp,gatewayMetaData.getArpRequestSourceIp(), gatewayMetaData.getArpRequestMacAddress());
+                                }
+                            }, 1, TimeUnit.SECONDS);
+                        }
+                    }
+                }
+            }, REFRESH_INTERVAL, REFRESH_INTERVAL, TimeUnit.SECONDS);
         }
     }
     /**
@@ -162,35 +197,48 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                 gatewayIp.getValue(),sourceIpAddress.getValue(),sourceMacAddress.getValue());
 
         init();
-        if(arpRemoveFlowInputAndL3EpKeyById.containsKey(gatewayIp)){
-            if(arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp).getGatewayMacAddress() != null){
+        if(gatewayToArpMetadataMap.containsKey(gatewayIp)){
+            if(gatewayToArpMetadataMap.get(gatewayIp).getGatewayMacAddress() != null){
                 return arpWatcherWall.submit(new Callable<MacAddress>(){
 
                     @Override
                     public MacAddress call() throws Exception {
-                        return arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp).getGatewayMacAddress();
+                        return gatewayToArpMetadataMap.get(gatewayIp).getGatewayMacAddress();
                     }
                 });
             }
         }else{
-            arpRemoveFlowInputAndL3EpKeyById.put(gatewayIp,
-                    new ArpResolverMetadata(null, gatewayIp,periodicRefresh));
+            gatewayToArpMetadataMap.put(gatewayIp,new ArpResolverMetadata(
+                    externalNetworkBridgeDpid, gatewayIp,sourceIpAddress,sourceMacAddress,periodicRefresh));
         }
 
-        final ArpMessageAddress senderAddress = new ArpMessageAddress(sourceMacAddress,sourceIpAddress);
-
-        final String nodeName = OPENFLOW + externalNetworkBridgeDpid;
 
-        final Node externalNetworkBridge = getOpenFlowNode(nodeName);
+        final Node externalNetworkBridge = getExternalBridge(externalNetworkBridgeDpid);
         if(externalNetworkBridge == null){
             LOG.error("MAC address for gateway {} can not be resolved, because external bridge {} "
                     + "is not connected to controller.",gatewayIp.getValue(),externalNetworkBridgeDpid );
             return null;
         }
+
+        sendGatewayArpRequest(externalNetworkBridge,gatewayIp,sourceIpAddress, sourceMacAddress);
+
+        //Wait for MacAddress population in cache
+        return waitForMacAddress(gatewayIp);
+    }
+
+    private Node getExternalBridge(final Long externalNetworkBridgeDpid){
+        final String nodeName = OPENFLOW + externalNetworkBridgeDpid;
+
+        return getOpenFlowNode(nodeName);
+    }
+
+    private void sendGatewayArpRequest(final Node externalNetworkBridge,final Ipv4Address gatewayIp,
+            final Ipv4Address sourceIpAddress, final MacAddress sourceMacAddress){
+        final ArpMessageAddress senderAddress = new ArpMessageAddress(sourceMacAddress,sourceIpAddress);
+
         //Build arp reply router flow
         final Flow arpReplyToControllerFlow = createArpReplyToControllerFlow(senderAddress, gatewayIp);
 
-
         final InstanceIdentifier<Node> nodeIid = InstanceIdentifier.builder(Nodes.class)
                 .child(Node.class, externalNetworkBridge.getKey())
                 .build();
@@ -213,7 +261,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                 LOG.debug("Flow to route ARP Reply to Controller installed successfully : {}", flowIid);
 
                 //cache metadata
-                arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp).setFlowToRemove(
+                gatewayToArpMetadataMap.get(gatewayIp).setFlowToRemove(
                         new RemoveFlowInputBuilder(arpReplyToControllerFlow).setNode(nodeRef).build());
 
                 //Broadcast ARP request packets
@@ -232,8 +280,6 @@ public class GatewayMacResolverService extends AbstractServiceInstance
             }
             }
         );
-        //Wait for MacAddress population in cache
-        return waitForMacAddress(gatewayIp);
     }
 
     private ListenableFuture<MacAddress> waitForMacAddress(final Ipv4Address gatewayIp){
@@ -246,10 +292,10 @@ public class GatewayMacResolverService extends AbstractServiceInstance
                     //Sleep before checking mac address, so meanwhile ARP request packets
                     // will be broadcasted on the bridge.
                     Thread.sleep(PER_CYCLE_WAIT_DURATION);
-                    ArpResolverMetadata arpResolverMetadata = arpRemoveFlowInputAndL3EpKeyById.get(gatewayIp);
+                    ArpResolverMetadata arpResolverMetadata = gatewayToArpMetadataMap.get(gatewayIp);
                     if(arpResolverMetadata != null && arpResolverMetadata.getGatewayMacAddress() != null){
                         if(!arpResolverMetadata.isPeriodicRefresh()){
-                            return arpRemoveFlowInputAndL3EpKeyById.remove(gatewayIp).getGatewayMacAddress();
+                            return gatewayToArpMetadataMap.remove(gatewayIp).getGatewayMacAddress();
                         }
                         return arpResolverMetadata.getGatewayMacAddress();
                     }
@@ -258,6 +304,7 @@ public class GatewayMacResolverService extends AbstractServiceInstance
             }
         });
     }
+
     private static @Nullable Ipv4Address getIPv4Addresses(IpAddress ipAddress) {
         if (ipAddress.getIpv4Address() == null) {
             return null;
@@ -320,33 +367,28 @@ public class GatewayMacResolverService extends AbstractServiceInstance
 
     @Override
     public void onPacketReceived(PacketReceived potentialArp) {
-        Arp arp = null;
-        try {
-            arp = ArpResolverUtils.getArpFrom(potentialArp);
-        } catch (Exception e) {
-            LOG.trace(
-                    "Failed to decode potential ARP packet. This could occur when other than ARP packet was received.",
-                    e);
-            return;
-        }
-        if (arp.getOperation() != ArpOperation.REPLY.intValue()) {
-            LOG.trace("Packet is not ARP REPLY packet.");
-            return;
-        }
-        if (LOG.isTraceEnabled()) {
-            LOG.trace("ARP REPLY received - {}", ArpUtils.getArpToStringFormat(arp));
-        }
-        NodeKey nodeKey = potentialArp.getIngress().getValue().firstKeyOf(Node.class, NodeKey.class);
-        if (nodeKey == null) {
-            LOG.info("Unknown source node of ARP packet: {}", potentialArp);
-            return;
-        }
-        Ipv4Address gatewayIpAddress = ArpUtils.bytesToIp(arp.getSenderProtocolAddress());
-        MacAddress gatewayMacAddress = ArpUtils.bytesToMac(arp.getSenderHardwareAddress());
-        ArpResolverMetadata removeFlowInputAndL3EpKey = arpRemoveFlowInputAndL3EpKeyById.get(gatewayIpAddress);
-        if(removeFlowInputAndL3EpKey != null){
-            removeFlowInputAndL3EpKey.setGatewayMacAddress(gatewayMacAddress);
-            flowService.removeFlow(removeFlowInputAndL3EpKey.getFlowToRemove());
+        Arp arp = ArpResolverUtils.getArpFrom(potentialArp);
+        if(arp != null){
+            if (arp.getOperation() != ArpOperation.REPLY.intValue()) {
+                LOG.trace("Packet is not ARP REPLY packet.");
+                return;
+            }
+            if (LOG.isTraceEnabled()) {
+                LOG.trace("ARP REPLY received - {}", ArpUtils.getArpToStringFormat(arp));
+            }
+            NodeKey nodeKey = potentialArp.getIngress().getValue().firstKeyOf(Node.class, NodeKey.class);
+            if (nodeKey == null) {
+                LOG.info("Unknown source node of ARP packet: {}", potentialArp);
+                return;
+            }
+            Ipv4Address gatewayIpAddress = ArpUtils.bytesToIp(arp.getSenderProtocolAddress());
+            MacAddress gatewayMacAddress = ArpUtils.bytesToMac(arp.getSenderHardwareAddress());
+            ArpResolverMetadata candidateGatewayIp = gatewayToArpMetadataMap.get(gatewayIpAddress);
+            if(candidateGatewayIp != null){
+                LOG.debug("Resolved MAC for Gateway Ip {} is {}",gatewayIpAddress.getValue(),gatewayMacAddress.getValue());
+                candidateGatewayIp.setGatewayMacAddress(gatewayMacAddress);
+                flowService.removeFlow(candidateGatewayIp.getFlowToRemove());
+            }
         }
     }
 
@@ -361,9 +403,9 @@ public class GatewayMacResolverService extends AbstractServiceInstance
     public void setDependencies(Object impl) {}
 
     @Override
-    public void stopPeriodicReferesh(Ipv4Address gatewayIp) {
+    public void stopPeriodicRefresh(Ipv4Address gatewayIp) {
         init();
-        arpRemoveFlowInputAndL3EpKeyById.remove(gatewayIp);
+        gatewayToArpMetadataMap.remove(gatewayIp);
     }
 
 }
index 2c97bbfe49d973e03fa3eafb82458a3da8846742..764ddc484e090bd203df768d4b7ec118bcf46ec9 100644 (file)
@@ -198,7 +198,7 @@ public class LBaaSHandler extends AbstractHandler
                 String memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
                 if (memberSubnetID != null && memberAdminStateIsUp != null &&
                         memberSubnetID.equals(loadBalancerSubnetID) && memberAdminStateIsUp) {
-                    String memberID = neutronLBPoolMember.getPoolMemberID();
+                    String memberID = neutronLBPoolMember.getID();
                     String memberIP = neutronLBPoolMember.getPoolMemberAddress();
                     Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
                     if (memberID == null || memberIP == null || memberPort == null) {
index 2de90659d6d47b0aedade973d6495195ab79a532..da6ca5f752fed06858d7c74e12fc38903fa256ae 100755 (executable)
@@ -84,11 +84,11 @@ public class LBaaSPoolHandler extends AbstractHandler
         List<LoadBalancerConfiguration> lbConfigList = extractLBConfiguration(neutronLBPool);
         final List<Node> nodes = nodeCacheManager.getBridgeNodes();
         if (lbConfigList == null) {
-            LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+            LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getID());
         } else if (lbConfigList.size() == 0) {
-            LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+            LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getID());
         } else if (nodes.isEmpty()) {
-            LOG.debug("Noop with LB pool {} creation because no nodes available.", neutronLBPool.getLoadBalancerPoolID());
+            LOG.debug("Noop with LB pool {} creation because no nodes available.", neutronLBPool.getID());
         } else {
             for (LoadBalancerConfiguration lbConfig: lbConfigList) {
                 if (!lbConfig.isValid()) {
@@ -139,11 +139,11 @@ public class LBaaSPoolHandler extends AbstractHandler
         List<LoadBalancerConfiguration> lbConfigList = extractLBConfiguration(neutronLBPool);
         final List<Node> nodes = nodeCacheManager.getBridgeNodes();
         if (lbConfigList == null) {
-            LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+            LOG.debug("Neutron LB configuration invalid for pool {} ", neutronLBPool.getID());
         } else if (lbConfigList.size() == 0) {
-            LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getLoadBalancerPoolID());
+            LOG.debug("No Neutron LB VIP not created yet for pool {} ", neutronLBPool.getID());
         } else if (nodes.isEmpty()) {
-            LOG.debug("Noop with LB pool {} deletion because no nodes available.", neutronLBPool.getLoadBalancerPoolID());
+            LOG.debug("Noop with LB pool {} deletion because no nodes available.", neutronLBPool.getID());
         } else {
             for (LoadBalancerConfiguration lbConfig: lbConfigList) {
                 if (!lbConfig.isValid()) {
@@ -239,7 +239,7 @@ public class LBaaSPoolHandler extends AbstractHandler
                 memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
                 if (memberSubnetID != null && memberAdminStateIsUp != null &&
                         memberSubnetID.equals(loadBalancerSubnetID) && memberAdminStateIsUp) {
-                    memberID = neutronLBPoolMember.getPoolMemberID();
+                    memberID = neutronLBPoolMember.getID();
                     memberIP = neutronLBPoolMember.getPoolMemberAddress();
                     memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
                     if (memberID == null || memberIP == null || memberPort == null) {
index b405ae94e42064f0a6da2207bca4298ce8c8b84a..4d3f3662bb4bebc805583f352fc952ed27d9b854 100755 (executable)
@@ -84,16 +84,16 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
         if (lbConfig == null) {
             LOG.debug("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
         } else if (lbConfig.getVip() == null) {
-            LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+            LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getID());
         } else if (!lbConfig.isValid()) {
             LOG.debug("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
         } else if (nodes.isEmpty()) {
-            LOG.debug("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getPoolMemberID());
+            LOG.debug("Noop with LB pool member {} creation because no nodes available.", neutronLBPoolMember.getID());
         } else {
             for (Node node : nodes) {
                 loadBalancerProvider.programLoadBalancerPoolMemberRules(node,
                         lbConfig,
-                        lbConfig.getMembers().get(neutronLBPoolMember.getPoolMemberID()), Action.ADD);
+                        lbConfig.getMembers().get(neutronLBPoolMember.getID()), Action.ADD);
             }
         }
     }
@@ -135,17 +135,17 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
         if (lbConfig == null) {
             LOG.debug("Neutron LB configuration invalid for member {} ", neutronLBPoolMember.getPoolMemberAddress());
         } else if (lbConfig.getVip() == null) {
-            LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getPoolMemberID());
+            LOG.debug("Neutron LB VIP not created yet for member {} ", neutronLBPoolMember.getID());
         } else if (!lbConfig.isValid()) {
             LOG.debug("Neutron LB pool configuration invalid for {} ", lbConfig.getName());
         } else if (nodes.isEmpty()) {
-            LOG.debug("Noop with LB pool member {} deletion because no nodes available.", neutronLBPoolMember.getPoolMemberID());
+            LOG.debug("Noop with LB pool member {} deletion because no nodes available.", neutronLBPoolMember.getID());
         } else {
             /* As of now, deleting a member involves recomputing member indices.
              * This is best done through a complete update of the load balancer instance.
              */
             LoadBalancerConfiguration newLBConfig = new LoadBalancerConfiguration(lbConfig);
-            newLBConfig.removeMember(neutronLBPoolMember.getPoolMemberID());
+            newLBConfig.removeMember(neutronLBPoolMember.getID());
 
             for (Node node : nodes) {
                 loadBalancerProvider.programLoadBalancerRules(node, lbConfig, Action.DELETE);
@@ -193,7 +193,7 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
      * configuration from the neutron LB cache based on member info
      */
     public LoadBalancerConfiguration extractLBConfiguration(NeutronLoadBalancerPoolMember neutronLBPoolMember) {
-        String memberID = neutronLBPoolMember.getPoolMemberID();
+        String memberID = neutronLBPoolMember.getID();
         String memberIP = neutronLBPoolMember.getPoolMemberAddress();
         String memberSubnetID = neutronLBPoolMember.getPoolMemberSubnetID();
         Integer memberPort = neutronLBPoolMember.getPoolMemberProtoPort();
@@ -246,7 +246,7 @@ public class LBaaSPoolMemberHandler extends AbstractHandler
         Integer otherMemberPort;
 
         for (NeutronLoadBalancerPoolMember otherMember: neutronLBPool.getLoadBalancerPoolMembers()) {
-            otherMemberID = otherMember.getPoolMemberID();
+            otherMemberID = otherMember.getID();
             if (otherMemberID.equals(memberID)) {
                 continue; //skip
             }
index 28e6fc1964f1cebbbce9ff9a8b486c29b20abfac..28bf653b19e0c237d7a0ef118e767aabd7f363b3 100644 (file)
@@ -23,11 +23,15 @@ public interface GatewayMacResolver {
 
     /**
      * Method will trigger the mac resolution for gateway IP. If user set periodicRefresh to true,
-     * it will periodically trigger the gateway resolution after a specific time interval. If
-     * periodicRefresh is false, it will just do one time gateway resolution.
-     * @param externalNetworkBridgeDpid
-     * @param gatewayIp
-     * @param periodicReferesh
+     * it will periodically trigger the gateway resolution after a specific time interval using the
+     * given source IP and MAC addresses. It will also cache the source IP & MAC in case of periodicRefresh.
+     * If periodicRefresh is false, it will just do one time gateway resolution and won't cache any internal data.
+     * If user call the same method with different source ip and mac address, GatewayMacResolver service will
+     * update the internally cached data with these new source ip and mac address and will use it as per
+     * periodicRefresh flag.
+     * @param externalNetworkBridgeDpid This bridge will be used for sending ARP request
+     * @param gatewayIp ARP request will be send for this ip address
+     * @param periodicReferesh Do you want to periodically refresh the gateway mac?
      * @return
      */
     public ListenableFuture<MacAddress> resolveMacAddress( final Long externalNetworkBridgeDpid, final Ipv4Address gatewayIp,
@@ -37,5 +41,5 @@ public interface GatewayMacResolver {
      * Method will stop the periodic refresh of the given gateway ip address.
      * @param gatewayIp
      */
-    public void stopPeriodicReferesh(final Ipv4Address gatewayIp);
+    public void stopPeriodicRefresh(final Ipv4Address gatewayIp);
 }
index 651c79519dcade0abf22320b87e0380fe1ea033b..de664cbb803b02c99343b2af78e10d276725c251 100644 (file)
@@ -215,8 +215,10 @@ public class NeutronL3Adapter implements ConfigInterface {
                 if(externalNetwork != null){
                     if(externalNetwork.isRouterExternal()){
                         final NeutronSubnet externalSubnet = getExternalNetworkSubnet(neutronPort);
-                        if(externalSubnet != null){
-                            gatewayMacResolver.stopPeriodicReferesh(new Ipv4Address(externalSubnet.getGatewayIP()));
+                        // TODO support IPv6
+                        if (externalSubnet != null &&
+                            externalSubnet.getIpVersion() == 4) {
+                            gatewayMacResolver.stopPeriodicRefresh(new Ipv4Address(externalSubnet.getGatewayIP()));
                         }
                     }
                 }
@@ -244,11 +246,13 @@ public class NeutronL3Adapter implements ConfigInterface {
             // there.
             //
             if (!isDelete) {
-                for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
-                    NeutronRouter_Interface neutronRouterInterface =
+                if (neutronPort.getFixedIPs() != null) {
+                    for (Neutron_IPs neutronIP : neutronPort.getFixedIPs()) {
+                        NeutronRouter_Interface neutronRouterInterface =
                             subnetIdToRouterInterfaceCache.get(neutronIP.getSubnetUUID());
-                    if (neutronRouterInterface != null) {
-                        this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+                        if (neutronRouterInterface != null) {
+                            this.handleNeutronRouterInterfaceEvent(null /*neutronRouter*/, neutronRouterInterface, action);
+                        }
                     }
                 }
             }
@@ -1252,14 +1256,15 @@ public class NeutronL3Adapter implements ConfigInterface {
     }
 
     private NeutronSubnet getExternalNetworkSubnet(NeutronPort gatewayPort){
-        NeutronSubnet extSubnet = null;
-        for (NeutronSubnet subnet : neutronSubnetCache.getAllSubnets()){
-            if(subnet.getPortsInSubnet().contains(gatewayPort)){
-                extSubnet = subnet;
-                break;
+        for (Neutron_IPs neutronIPs : gatewayPort.getFixedIPs()) {
+            String subnetUUID = neutronIPs.getSubnetUUID();
+            NeutronSubnet extSubnet = neutronSubnetCache.getSubnet(subnetUUID);
+            if (extSubnet.getGatewayIP() == null) {
+                continue;
             }
+            return extSubnet;
         }
-        return extSubnet;
+        return null;
     }
 
     public void triggerGatewayMacResolver(final Node node, final NeutronPort gatewayPort ){
@@ -1271,39 +1276,39 @@ public class NeutronL3Adapter implements ConfigInterface {
         if(externalNetwork != null){
             if(externalNetwork.isRouterExternal()){
                 final NeutronSubnet externalSubnet = getExternalNetworkSubnet(gatewayPort);
-                if(externalSubnet != null){
-                    if(externalSubnet.getGatewayIP() != null){
-                        LOG.info("Trigger MAC resolution for gateway ip {} on Node {}", externalSubnet.getGatewayIP(), node.getNodeId());
-
-                        ListenableFuture<MacAddress> gatewayMacAddress =
-                                gatewayMacResolver.resolveMacAddress(getDpidForExternalBridge(node),
-                                        new Ipv4Address(externalSubnet.getGatewayIP()),
-                                        new Ipv4Address(gatewayPort.getFixedIPs().get(0).getIpAddress()),
-                                        new MacAddress(gatewayPort.getMacAddress()),
-                                        false);
-                        if(gatewayMacAddress != null){
-                            Futures.addCallback(gatewayMacAddress, new FutureCallback<MacAddress>(){
-                                @Override
-                                public void onSuccess(MacAddress result) {
-                                    if(result != null){
+
+                // TODO: address IPv6 case.
+                if (externalSubnet != null &&
+                    externalSubnet.getIpVersion() == 4) {
+                    LOG.info("Trigger MAC resolution for gateway ip {} on Node {}",externalSubnet.getGatewayIP(),node.getNodeId());
+                    ListenableFuture<MacAddress> gatewayMacAddress =
+                        gatewayMacResolver.resolveMacAddress(getDpidForExternalBridge(node),
+                                                             new Ipv4Address(externalSubnet.getGatewayIP()),
+                                                             new Ipv4Address(gatewayPort.getFixedIPs().get(0).getIpAddress()),
+                                                             new MacAddress(gatewayPort.getMacAddress()),
+                                                             true);
+                    if(gatewayMacAddress != null){
+                        Futures.addCallback(gatewayMacAddress, new FutureCallback<MacAddress>(){
+                            @Override
+                            public void onSuccess(MacAddress result) {
+                                if(result != null){
+                                    if(!result.getValue().equals(externalRouterMac)){
                                         updateExternalRouterMac(result.getValue());
-                                        LOG.info("Resolved MAC address for gateway IP {} is {}", externalSubnet.getGatewayIP(), result.getValue());
-                                    }else{
-                                        LOG.warn("MAC address resolution failed for gateway IP {}", externalSubnet.getGatewayIP());
+                                        LOG.info("Resolved MAC address for gateway IP {} is {}", externalSubnet.getGatewayIP(),result.getValue());
                                     }
-                                }
-
-                                @Override
-                                public void onFailure(Throwable t) {
+                                }else{
                                     LOG.warn("MAC address resolution failed for gateway IP {}", externalSubnet.getGatewayIP());
                                 }
-                            }, gatewayMacResolverPool);
-                        }
-                    }else{
-                        LOG.warn("No gateway IP address found for external subnet {}", externalSubnet);
+                            }
+
+                            @Override
+                            public void onFailure(Throwable t) {
+                                LOG.warn("MAC address resolution failed for gateway IP {}", externalSubnet.getGatewayIP());
+                            }
+                        }, gatewayMacResolverPool);
                     }
-                }else{
-                    LOG.warn("Neutron subnet not found for external network {}", externalNetwork);
+                } else {
+                    LOG.warn("No gateway IP address found for external network {}", externalNetwork);
                 }
             }
         }else{
index 0f6a54991b5744862fa59945b157b2a8f8b15a47..bc443c39a3d0cb2ed57a01942087d8ddfa49394c 100644 (file)
@@ -124,11 +124,10 @@ public class SecurityServicesImpl implements ConfigInterface, SecurityServicesMa
             LOG.error("getDHCPServerPort: No fixed ip is assigned");
             return null;
         }
-        String subnetUUID = fixedIps.iterator().next().getSubnetUUID();
-        NeutronSubnet neutronSubnet = neutronSubnetCache.getSubnet(subnetUUID);
-        List<NeutronPort> ports = neutronSubnet.getPortsInSubnet();
-        for (NeutronPort port : ports) {
-            if (port.getDeviceOwner().contains("dhcp")) {
+
+        String networkUUID = neutronPort.getNetworkUUID();
+        for (NeutronPort port : neutronPortCache.getAllPorts()) {
+            if (port.getNetworkUUID() == networkUUID && port.getDeviceOwner().contains("dhcp")) {
                 return port;
             }
         }
index b98dfd202ee758fd5165b24515a530a0a750c364..d2cad128a6d7347bcb47e36b53fa3f02ca8d37cf 100644 (file)
@@ -98,7 +98,7 @@ public class LBaaSHandlerTest {
 
         when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
         when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
-        when(neutronLBPoolMember.getPoolMemberID()).thenReturn("pool_memberID");
+        when(neutronLBPoolMember.getID()).thenReturn("pool_memberID");
         when(neutronLBPoolMember.getPoolMemberAddress()).thenReturn("pool_member_address");
         when(neutronLBPoolMember.getPoolMemberProtoPort()).thenReturn(1);
         members.add(neutronLBPoolMember);
index 47d0dbe36faea0924d574f265eeffb4ac54e8c51..9ed3dbe4aa128b3d96916a3fb79b646cc6d1afd1 100644 (file)
@@ -76,7 +76,7 @@ public class LBaaSPoolHandlerTest {
         NeutronLoadBalancerPoolMember neutronLBPoolMember = mock(NeutronLoadBalancerPoolMember.class);
         when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
         when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
-        when(neutronLBPoolMember.getPoolMemberID()).thenReturn("pool_memberID");
+        when(neutronLBPoolMember.getID()).thenReturn("pool_memberID");
         when(neutronLBPoolMember.getPoolMemberAddress()).thenReturn("pool_member_address");
         when(neutronLBPoolMember.getPoolMemberProtoPort()).thenReturn(1);
         members.add(neutronLBPoolMember);
index 61a507607a517293afec91e3ae4d7a4e065c9cb6..d9575c3b635f2aa0b4ff6294af46e6406a08d8ad 100644 (file)
@@ -71,7 +71,7 @@ public class LBaaSPoolMemberHandlerTest {
     @Before
     public void setUp() {
         neutronLBMember = mock(NeutronLoadBalancerPoolMember.class);
-        when(neutronLBMember.getPoolMemberID()).thenReturn("pool_memberID");
+        when(neutronLBMember.getID()).thenReturn("pool_memberID");
         when(neutronLBMember.getPoolMemberAddress()).thenReturn("pool_member_address");
         when(neutronLBMember.getPoolMemberSubnetID()).thenReturn("pool_member_subnetID");
         when(neutronLBMember.getPoolMemberProtoPort()).thenReturn(1);
@@ -89,7 +89,7 @@ public class LBaaSPoolMemberHandlerTest {
         NeutronLoadBalancerPoolMember neutronLBPoolMember = mock(NeutronLoadBalancerPoolMember.class);
         when(neutronLBPoolMember.getPoolMemberAdminStateIsUp()).thenReturn(true);
         when(neutronLBPoolMember.getPoolMemberSubnetID()).thenReturn("subnetID");
-        when(neutronLBPoolMember.getPoolMemberID()).thenReturn("pool_memberID1");
+        when(neutronLBPoolMember.getID()).thenReturn("pool_memberID1");
         when(neutronLBPoolMember.getPoolMemberProtoPort()).thenReturn(1);
         members.add(neutronLBPoolMember);
 
index ebb39d395b397995951f4f584b32e45a18e0eec2..82ccf2571ec00b5d607eb51aa3d1ab0dd583156d 100644 (file)
@@ -212,7 +212,7 @@ public class NeutronL3AdapterTest {
         NeutronFloatingIP neutronFloatingIP = mock(NeutronFloatingIP.class);
         when(neutronFloatingIP.getFixedIPAddress()).thenReturn(FIXED_IP_ADDRESS);
         when(neutronFloatingIP.getFloatingIPAddress()).thenReturn(FLOATING_IP_ADDRESS);
-        when(neutronFloatingIP.getFloatingIPUUID()).thenReturn(UUID);
+        when(neutronFloatingIP.getID()).thenReturn(UUID);
 
         // Suppress the called to these functions
         MemberModifier.suppress(MemberMatcher.method(NeutronL3Adapter.class, "programFlowsForFloatingIPArpAdd", NeutronFloatingIP.class));