Merge "Fixed bug in resolving of conditional Revision Aware XPath."
authorGiovanni Meo <gmeo@cisco.com>
Tue, 30 Jul 2013 15:34:21 +0000 (15:34 +0000)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 30 Jul 2013 15:34:21 +0000 (15:34 +0000)
opendaylight/forwarding/staticrouting/src/main/java/org/opendaylight/controller/forwarding/staticrouting/internal/StaticRoutingImplementation.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTracker.java
opendaylight/hosttracker/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/HostTrackerCallable.java
opendaylight/hosttracker_new/api/src/main/java/org/opendaylight/controller/hosttracker/Entity.java
opendaylight/hosttracker_new/implementation/src/main/java/org/opendaylight/controller/hosttracker/internal/DeviceManagerImpl.java
opendaylight/protocol_plugins/openflow/src/main/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6Match.java
opendaylight/protocol_plugins/openflow/src/test/java/org/opendaylight/controller/protocol_plugin/openflow/vendorextension/v6extension/V6ExtensionTest.java
opendaylight/sal/api/src/main/java/org/opendaylight/controller/sal/core/ComponentActivatorAbstractBase.java

index 4afd4fb8e444136562b2d59fff79728c74bc763f..bccdea416208ef27d30294b9f7ddcebf83a77ba2 100644 (file)
@@ -24,8 +24,11 @@ import java.util.Map;
 import java.util.Set;
 import java.util.Timer;
 import java.util.TimerTask;
+import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentMap;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
@@ -55,9 +58,6 @@ import org.slf4j.LoggerFactory;
 
 /**
  * Static Routing feature provides the bridge between SDN and Non-SDN networks.
- *
- *
- *
  */
 public class StaticRoutingImplementation implements IfNewHostNotify,
         IForwardingStaticRouting, IObjectReader, IConfigurationContainerAware,
@@ -75,6 +75,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
     private IClusterContainerServices clusterContainerService = null;
     private Set<IStaticRoutingAware> staticRoutingAware = Collections
             .synchronizedSet(new HashSet<IStaticRoutingAware>());
+    private ExecutorService executor;
 
     void setStaticRoutingAware(IStaticRoutingAware s) {
         if (this.staticRoutingAware != null) {
@@ -235,43 +236,53 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         }
     }
 
-    private class NotifyStaticRouteThread extends Thread {
+    private class NotifyStaticRouteWorker implements Callable<Object> {
         private StaticRoute staticRoute;
         private boolean added;
 
-        public NotifyStaticRouteThread(StaticRoute s, boolean update) {
+        public NotifyStaticRouteWorker(StaticRoute s, boolean update) {
             this.staticRoute = s;
             this.added = update;
         }
 
-        public void run() {
+        @Override
+        public Object call() throws Exception {
             if (!added
                     || (staticRoute.getType() == StaticRoute.NextHopType.SWITCHPORT)) {
                 notifyStaticRouteUpdate(staticRoute, added);
             } else {
-                HostNodeConnector host = hostTracker.hostQuery(staticRoute
-                        .getNextHopAddress());
+                InetAddress nh = staticRoute.getNextHopAddress();
+                HostNodeConnector host = hostTracker.hostQuery(nh);
                 if (host == null) {
-                    Future<HostNodeConnector> future = hostTracker
-                            .discoverHost(staticRoute.getNextHopAddress());
+                    log.debug("Next hop {}  is not present, try to discover it", nh.getHostAddress());
+                    Future<HostNodeConnector> future = hostTracker.discoverHost(nh);
                     if (future != null) {
                         try {
                             host = future.get();
                         } catch (Exception e) {
-                            log.error("",e);
+                            log.error("", e);
                         }
                     }
                 }
                 if (host != null) {
+                    log.debug("Next hop {} is found", nh.getHostAddress());
                     staticRoute.setHost(host);
                     notifyStaticRouteUpdate(staticRoute, added);
+                } else {
+                    log.debug("Next hop {}  is still not present, try again later", nh.getHostAddress());
                 }
             }
+            return null;
         }
     }
 
     private void checkAndUpdateListeners(StaticRoute staticRoute, boolean added) {
-        new NotifyStaticRouteThread(staticRoute, added).start();
+        NotifyStaticRouteWorker worker = new NotifyStaticRouteWorker(staticRoute, added);
+        try {
+            executor.submit(worker);
+        } catch (Exception e) {
+            log.error("got Exception ", e);
+        }
     }
 
     private void notifyHostUpdate(HostNodeConnector host, boolean added) {
@@ -440,7 +451,7 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
         //staticRoutes = new ConcurrentHashMap<String, StaticRoute>();
         allocateCaches();
         retrieveCaches();
-
+        this.executor = Executors.newFixedThreadPool(1);
         if (staticRouteConfigs.isEmpty())
             loadConfiguration();
 
@@ -494,10 +505,12 @@ public class StaticRoutingImplementation implements IfNewHostNotify,
      *
      */
     void stop() {
+        executor.shutdown();
     }
 
     @Override
     public Status saveConfiguration() {
         return this.saveConfig();
     }
+
 }
index 6b7bac03e9bdcfc472ad3dce7cc2c10d1f8dd096..f600e6b2acc3afbe456b616ae97aadecfd7f056e 100644 (file)
@@ -97,7 +97,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     private Timer timer;
     private Timer arp_refresh_timer;
     private String containerName = null;
-
+    private ExecutorService executor;
     private static class ARPPending {
         protected InetAddress hostIP;
         protected short sent_count;
@@ -158,7 +158,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
         timer = new Timer();
         timer.schedule(new OutStandingARPHandler(), 4000, 4000);
-
+        executor = Executors.newFixedThreadPool(2);
         /* ARP Refresh Timer to go off every 5 seconds to implement ARP aging */
         arp_refresh_timer = new Timer();
         arp_refresh_timer.schedule(new ARPRefreshHandler(), 5000, 5000);
@@ -296,7 +296,6 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
 
     @Override
     public Future<HostNodeConnector> discoverHost(InetAddress networkAddress) {
-        ExecutorService executor = Executors.newFixedThreadPool(1);
         if (executor == null) {
             logger.error("discoverHost: Null executor");
             return null;
@@ -324,9 +323,13 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             logger.debug("hostFind(): Host found for IP: {}", networkAddress.getHostAddress());
             return host;
         }
+
         /* host is not found, initiate a discovery */
+
         hostFinder.find(networkAddress);
+
         /* Also add this host to ARPPending List for any potential retries */
+
         AddtoARPPendingList(networkAddress);
         logger.debug("hostFind(): Host Not Found for IP: {}, Inititated Host Discovery ...",
                 networkAddress.getHostAddress());
@@ -448,7 +451,13 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     private void replaceHost(InetAddress networkAddr, HostNodeConnector removedHost, HostNodeConnector newHost) {
         newHost.initArpSendCountDown();
         if (hostsDB.replace(networkAddr, removedHost, newHost)) {
-            logger.debug("Host move occurred. Old Host:{}, New Host: {}", removedHost, newHost);
+            logger.debug("Host move occurred: Old Host IP:{}, New Host IP: {}", removedHost.getNetworkAddress()
+                    .getHostAddress(), newHost.getNetworkAddress().getHostAddress());
+            logger.debug("Old Host MAC: {}, New Host MAC: {}",
+                    HexEncode.bytesToHexString(removedHost.getDataLayerAddressBytes()),
+                    HexEncode.bytesToHexString(newHost.getDataLayerAddressBytes()));
+            // Display the Old and New HostNodeConnectors also
+            logger.debug("Old {}, New {}", removedHost, newHost);
         } else {
             /*
              * Host replacement has failed, do the recovery
@@ -519,8 +528,9 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     @Override
     public void hostListener(HostNodeConnector host) {
 
+        logger.debug("ARP received for Host: IP {}, MAC {}, {}", host.getNetworkAddress().getHostAddress(),
+                HexEncode.bytesToHexString(host.getDataLayerAddressBytes()), host);
         if (hostExists(host)) {
-            logger.debug("ARP received for Host: {}", host);
             HostNodeConnector existinghost = hostsDB.get(host.getNetworkAddress());
             existinghost.initArpSendCountDown();
             return;
@@ -533,6 +543,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
     private void notifyHostLearnedOrRemoved(HostNodeConnector host, boolean add) {
         // Update listeners if any
         if (newHostNotify != null) {
+            logger.debug("Notifying Applications for Host {} Being {}", host.getNetworkAddress().getHostAddress(),
+                    add ? "Added" : "Deleted");
             synchronized (this.newHostNotify) {
                 for (IfNewHostNotify ta : newHostNotify) {
                     try {
@@ -564,6 +576,8 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         }
 
         if (topologyManager != null && p != null && h != null) {
+            logger.debug("Notifying Topology Manager for Host {} Being {}", h.getNetworkAddress().getHostAddress(),
+                    add ? "Added" : "Deleted");
             if (add == true) {
                 Tier tier = new Tier(1);
                 switchManager.setNodeProp(node, tier);
@@ -882,8 +896,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
             for (int i = 0; i < failedARPReqList.size(); i++) {
                 ARPPending arphost;
                 arphost = failedARPReqList.get(i);
-                logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
-                hostFinder.find(arphost.getHostIP());
+                if (hostFinder == null) {
+                    logger.warn("ARPHandler Services are not available on subnet addition");
+                    continue;
+                }
+               logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+               hostFinder.find(arphost.getHostIP());
             }
         }
     }
@@ -899,18 +917,23 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                 if (arphost.getSent_count() < switchManager.getHostRetryCount()) {
                     /*
                      * No reply has been received of first ARP Req, send the
-                     * next one
+                     * next one. Before sending the ARP, check if ARPHandler
+                     * is available or not
                      */
+                    if (hostFinder == null) {
+                        logger.warn("ARPHandler Services are not available for Outstanding ARPs");
+                        continue;
+                    }
                     hostFinder.find(arphost.getHostIP());
                     arphost.sent_count++;
                     logger.debug("ARP Sent from ARPPending List, IP: {}", arphost.getHostIP().getHostAddress());
                 } else if (arphost.getSent_count() >= switchManager.getHostRetryCount()) {
                     /*
-                     * Two ARP requests have been sent without receiving a
+                     * ARP requests have been sent without receiving a
                      * reply, remove this from the pending list
                      */
                     removePendingARPFromList(i);
-                    logger.debug("ARP reply not received after two attempts, removing from Pending List IP: {}",
+                    logger.debug("ARP reply not received after multiple attempts, removing from Pending List IP: {}",
                             arphost.getHostIP().getHostAddress());
                     /*
                      * Add this host to a different list which will be processed
@@ -974,6 +997,15 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
                                         HexEncode.bytesToHexString(host.getDataLayerAddressBytes()) });
                     }
                     host.setArpSendCountDown(arp_cntdown);
+                    if (hostFinder == null) {
+                        /*
+                         * If hostfinder is not available, then can't send the
+                         * probe. However, continue the age out the hosts since
+                         * we don't know if the host is indeed out there or not.
+                         */
+                        logger.warn("ARPHandler is not avaialable, can't send the probe");
+                        continue;
+                    }
                     hostFinder.probe(host);
                 }
             }
@@ -1255,6 +1287,12 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
         for (int i = 0; i < failedARPReqList.size(); i++) {
             arphost = failedARPReqList.get(i);
             logger.debug("Sending the ARP from FailedARPReqList fors IP: {}", arphost.getHostIP().getHostAddress());
+            if (hostFinder == null) {
+                logger.warn("ARPHandler is not available at interface  up");
+                logger.warn("Since this event is missed, host(s) connected to interface {} may not be discovered",
+                        nodeConnector);
+                continue;
+            }
             hostFinder.find(arphost.getHostIP());
         }
         HostNodeConnector host = inactiveStaticHosts.get(nodeConnector);
@@ -1349,6 +1387,7 @@ public class HostTracker implements IfIptoHost, IfHostListener, ISwitchManagerAw
      *
      */
     void stop() {
+        executor.shutdown();
     }
 
     @Override
index 06311a5206268ae79fe8ebe32970a395423cf162..303308270d77d36eb803b42feca3096bbfeed0fb 100644 (file)
@@ -42,7 +42,7 @@ public class HostTrackerCallable implements Callable<HostNodeConnector> {
         if (h != null)
             return h;
         hostTracker.setCallableOnPendingARP(trackedHost, this);
-        latch.await();
+        Thread.sleep(2000); // wait 2sec to see if the host responds
         return hostTracker.hostQuery(trackedHost);
     }
 
index 7c98e9505b28b1b51098a9d9c9c3e29ab9af6a2c..924d0717e966aa4731aa340e67a54efe18cbf991 100644 (file)
 
 package org.opendaylight.controller.hosttracker;
 
+import java.net.InetAddress;
 import java.util.Date;
 
+import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.utils.NetUtils;
 
 /**
  * An entity on the network is a visible trace of a device that corresponds to a
@@ -218,6 +221,19 @@ public class Entity implements Comparable<Entity> {
         return true;
     }
 
+    public HostNodeConnector toHostNodeConnector() {
+        try {
+            NodeConnector n = this.getPort();
+            InetAddress ip = InetAddress.getByAddress(NetUtils.intToByteArray4(this.getIpv4Address()));
+            byte[] macAddr = NetUtils.longToByteArray6(this.getMacAddress());
+            HostNodeConnector nc = new HostNodeConnector(macAddr, ip, n,
+                    (short) 0);
+            return nc;
+        } catch (Exception e) {
+            return null;
+        }
+    }
+
     @Override
     public String toString() {
         return "Entity [macAddress=" + macAddress + ", ipv4Address="
index 0a6c2713dde0a2e6a0087f7d7c889e5d77668765..95d33ceef90fcaf019cead9ffe9a2a97858e8e47 100755 (executable)
@@ -52,6 +52,7 @@ import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
+import java.util.Map.Entry;
 import java.util.Queue;
 import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
@@ -77,6 +78,8 @@ import org.opendaylight.controller.sal.core.Host;
 import org.opendaylight.controller.sal.core.Node;
 import org.opendaylight.controller.sal.core.NodeConnector;
 import org.opendaylight.controller.sal.core.NodeConnector.NodeConnectorIDType;
+import org.opendaylight.controller.sal.core.Property;
+import org.opendaylight.controller.sal.core.State;
 import org.opendaylight.controller.sal.core.Tier;
 import org.opendaylight.controller.sal.core.UpdateType;
 import org.opendaylight.controller.sal.packet.ARP;
@@ -96,6 +99,7 @@ import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.sal.utils.SingletonTask;
 import org.opendaylight.controller.sal.utils.Status;
 import org.opendaylight.controller.sal.utils.StatusCode;
+import org.opendaylight.controller.switchmanager.IInventoryListener;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.topologymanager.ITopologyManager;
 import org.opendaylight.controller.topologymanager.ITopologyManagerAware;
@@ -110,7 +114,8 @@ import org.slf4j.LoggerFactory;
  * @author readams
  */
 public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
-        IListenDataPacket, ITopologyManagerAware, IfIptoHost {
+        IListenDataPacket, ITopologyManagerAware, IfIptoHost,
+        IInventoryListener {
     protected static Logger logger = LoggerFactory
             .getLogger(DeviceManagerImpl.class);
 
@@ -222,6 +227,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
      */
     protected ConcurrentHashMap<Long, Device> deviceMap;
 
+    protected ConcurrentHashMap<NodeConnector, Entity> inactiveStaticDevices;
     /**
      * Counter used to generate device keys
      */
@@ -305,7 +311,9 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
     /**
      * Using the IfNewHostNotify to notify listeners of host changes.
      */
-    private Set<IfNewHostNotify> newHostNotify = Collections.synchronizedSet(new HashSet<IfNewHostNotify>());
+    private Set<IfNewHostNotify> newHostNotify = Collections
+            .synchronizedSet(new HashSet<IfNewHostNotify>());
+
     /**
      * A device update event to be dispatched
      */
@@ -445,11 +453,11 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
     // Dependency injection
     // ********************
 
-    void setNewHostNotify(IfNewHostNotify obj){
+    void setNewHostNotify(IfNewHostNotify obj) {
         this.newHostNotify.add(obj);
     }
 
-    void unsetNewHostNotify(IfNewHostNotify obj){
+    void unsetNewHostNotify(IfNewHostNotify obj) {
         this.newHostNotify.remove(obj);
     }
 
@@ -496,6 +504,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
         secondaryIndexMap = new HashMap<EnumSet<DeviceField>, DeviceIndex>();
 
         deviceMap = new ConcurrentHashMap<Long, Device>();
+        inactiveStaticDevices = new ConcurrentHashMap<NodeConnector, Entity>();
         classStateMap = new ConcurrentHashMap<String, ClassState>();
         apComparator = new AttachmentPointComparator();
 
@@ -804,11 +813,11 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
         if (inPkt == null) {
             return PacketResult.IGNORED;
         }
-//        try {
-//            throw new Exception("Sample");
-//        } catch (Exception e) {
-//            logger.error("Sample stack trace", e);
-//        }
+        // try {
+        // throw new Exception("Sample");
+        // } catch (Exception e) {
+        // logger.error("Sample stack trace", e);
+        // }
 
         Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt);
         Ethernet eth;
@@ -1469,14 +1478,16 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
 
     protected void notifyListeners(List<IDeviceListener> listeners,
             DeviceUpdate update) {
-       // Topology update is for some reason outside of listeners registry
-       // logic
+        // Topology update is for some reason outside of listeners registry
+        // logic
         Entity[] ents = update.device.getEntities();
-        Entity e = ents[ents.length-1];
+        Entity e = ents[ents.length - 1];
+
         NodeConnector p = e.getPort();
         Node node = p.getNode();
         Host h = null;
         try {
+
             byte[] mac = NetUtils.longToByteArray6(e.getMacAddress());
             DataLinkAddress dla = new EthernetAddress(
                     mac);
@@ -1487,7 +1498,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
         } catch (ConstructionException ce) {
             p = null;
             h = null;
-        } catch (UnknownHostException ue){
+        } catch (UnknownHostException ue) {
             p = null;
             h = null;
         }
@@ -1512,19 +1523,20 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
             return;
         }
         /**
-         * TODO: IfNewHostNotify is needed for current controller API.
-         * Adding logic so that existing apps (like SimpleForwardingManager)
-         * work.  IDeviceListener adds additional methods and uses IListener's
-         * callback ordering.  The two interfaces need to be merged.
+         * TODO: IfNewHostNotify is needed for current controller API. Adding
+         * logic so that existing apps (like SimpleForwardingManager) work.
+         * IDeviceListener adds additional methods and uses IListener's callback
+         * ordering. The two interfaces need to be merged.
          */
 
-        for (IfNewHostNotify notify : newHostNotify){
+        for (IfNewHostNotify notify : newHostNotify) {
             switch (update.change) {
             case ADD:
                 notify.notifyHTClient(update.device.toHostNodeConnector());
                 break;
             case DELETE:
-                notify.notifyHTClientHostRemoved(update.device.toHostNodeConnector());
+                notify.notifyHTClientHostRemoved(update.device
+                        .toHostNodeConnector());
                 break;
             case CHANGE:
             }
@@ -1953,19 +1965,21 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
             }
         }
     }
+
     /**
-     * Send update notifications to listeners.
-     * IfNewHostNotify listeners need to remove old device and add new device.
+     * Send update notifications to listeners. IfNewHostNotify listeners need to
+     * remove old device and add new device.
+     *
      * @param device
      * @param oldDevice
      */
-    protected void sendDeviceMovedNotification(Device device, Device oldDevice){
-        for (IfNewHostNotify notify : newHostNotify){
-                notify.notifyHTClientHostRemoved(oldDevice.toHostNodeConnector());
-                notify.notifyHTClient(device.toHostNodeConnector());
-            }
-        sendDeviceMovedNotification(device);
+    protected void sendDeviceMovedNotification(Device device, Device oldDevice) {
+        for (IfNewHostNotify notify : newHostNotify) {
+            notify.notifyHTClientHostRemoved(oldDevice.toHostNodeConnector());
+            notify.notifyHTClient(device.toHostNodeConnector());
         }
+        sendDeviceMovedNotification(device);
+    }
 
     /**
      * this method will reclassify and reconcile a device - possibilities are -
@@ -2041,7 +2055,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
         return mac;
     }
 
-    /**
+     /**
      * Accepts an IPv4 address in a byte array and returns the corresponding
      * 32-bit integer value.
      *
@@ -2205,7 +2219,7 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
         Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
         while (i.hasNext()) {
             Device device = i.next();
-            if(device.isStaticHost())
+            if (device.isStaticHost())
                 nc.add(device.toHostNodeConnector());
         }
         return nc;
@@ -2213,22 +2227,38 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
 
     @Override
     public Set<HostNodeConnector> getInactiveStaticHosts() {
-        // TODO Auto-generated method stub
-        return null;
+        Collection<Entity> devices = Collections
+                .unmodifiableCollection(inactiveStaticDevices.values());
+        Iterator<Entity> i = devices.iterator();
+        Set<HostNodeConnector> nc = new HashSet<HostNodeConnector>();
+        while (i.hasNext()) {
+            Entity ent = i.next();
+                nc.add(ent.toHostNodeConnector());
+
+        }
+        return nc;
     }
 
     @Override
     public Status addStaticHost(String networkAddress, String dataLayerAddress,
             NodeConnector nc, String vlan) {
         Long mac = HexEncode.stringToLong(dataLayerAddress);
-        try{
+        try {
             InetAddress addr = InetAddress.getByName(networkAddress);
             int ip = toIPv4Address(addr.getAddress());
             Entity e = new Entity(mac, Short.valueOf(vlan), ip, nc, new Date());
-            Device d = this.learnDeviceByEntity(e);
-            d.setStaticHost(true);
+
+            if (switchManager.isNodeConnectorEnabled(e.getPort())) {
+                Device d = this.learnDeviceByEntity(e);
+                d.setStaticHost(true);
+            } else {
+                logger.debug(
+                        "Switch or switchport is not up, adding host {} to inactive list",
+                        addr.getHostName());
+                 inactiveStaticDevices.put(e.getPort(), e);
+            }
             return new Status(StatusCode.SUCCESS);
-        }catch(UnknownHostException e){
+        } catch (UnknownHostException e) {
             return new Status(StatusCode.INTERNALERROR);
         }
     }
@@ -2237,26 +2267,122 @@ public class DeviceManagerImpl implements IDeviceService, IEntityClassListener,
     public Status removeStaticHost(String networkAddress) {
         Integer addr;
         try {
-            addr = toIPv4Address(InetAddress.getByName(networkAddress).getAddress());
+            addr = toIPv4Address(InetAddress.getByName(networkAddress)
+                    .getAddress());
         } catch (UnknownHostException e) {
             return new Status(StatusCode.NOTFOUND, "Host does not exist");
         }
-        Iterator<Device> di = this.getDeviceIteratorForQuery(null, null, addr, null);
-        List<IDeviceListener> listeners = deviceListeners
-                .getOrderedListeners();
-        while(di.hasNext()){
+        Iterator<Device> di = this.getDeviceIteratorForQuery(null, null, addr,
+                null);
+        List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+        while (di.hasNext()) {
             Device d = di.next();
-            if(d.isStaticHost()){
+            if (d.isStaticHost()) {
                 deleteDevice(d);
                 for (IfNewHostNotify notify : newHostNotify)
                     notify.notifyHTClientHostRemoved(d.toHostNodeConnector());
                 for (IDeviceListener listener : listeners)
-                        listener.deviceRemoved(d);
+                    listener.deviceRemoved(d);
+            }
+        }
+        //go through inactive entites.
+        Set<HostNodeConnector> inactive = this.getInactiveStaticHosts();
+        for(HostNodeConnector nc : inactive){
+            Integer ip =toIPv4Address(nc.getNetworkAddress().getAddress());
+            if(ip.equals(addr)){
+                this.inactiveStaticDevices.remove(nc.getnodeConnector());
             }
         }
+
+
         return new Status(StatusCode.SUCCESS);
     }
 
+    @Override
+    public void notifyNode(Node node, UpdateType type,
+            Map<String, Property> propMap) {
+        if (node == null)
+            return;
+        List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+        switch (type) {
+        case REMOVED:
+            logger.debug("Received removed node {}", node);
+            for (Entry<Long, Device> d : deviceMap.entrySet()) {
+                Device device = d.getValue();
+                HostNodeConnector host = device.toHostNodeConnector();
+                if (host.getnodeconnectorNode().equals(node)) {
+                    logger.debug("Node: {} is down, remove from Hosts_DB", node);
+                    deleteDevice(device);
+                    for (IfNewHostNotify notify : newHostNotify)
+                        notify.notifyHTClientHostRemoved(host);
+                    for (IDeviceListener listener : listeners)
+                        listener.deviceRemoved(device);
+                }
+            }
+            break;
+        default:
+            break;
+        }
+    }
+
+    @Override
+    public void notifyNodeConnector(NodeConnector nodeConnector,
+            UpdateType type, Map<String, Property> propMap) {
+        if (nodeConnector == null)
+            return;
+        List<IDeviceListener> listeners = deviceListeners.getOrderedListeners();
+        boolean up = false;
+        switch (type) {
+        case ADDED:
+            up = true;
+            break;
+        case REMOVED:
+            break;
+        case CHANGED:
+            State state = (State) propMap.get(State.StatePropName);
+            if ((state != null) && (state.getValue() == State.EDGE_UP)) {
+                up = true;
+            }
+            break;
+        default:
+            return;
+        }
+
+        if (up) {
+            logger.debug("handleNodeConnectorStatusUp {}", nodeConnector);
+
+            Entity ent = inactiveStaticDevices.get(nodeConnector);
+            Device device = this.learnDeviceByEntity(ent);
+            if(device!=null){
+                HostNodeConnector host = device.toHostNodeConnector();
+                if (host != null) {
+                    inactiveStaticDevices.remove(nodeConnector);
+                    for (IfNewHostNotify notify : newHostNotify)
+                        notify.notifyHTClient(host);
+                    for (IDeviceListener listener : listeners)
+                        listener.deviceAdded(device);
+                } else {
+                    logger.debug("handleNodeConnectorStatusDown {}", nodeConnector);
+                }
+            }
+        }else{
+                // remove all devices on the node that went down.
+                for (Entry<Long, Device> entry : deviceMap.entrySet()) {
+                    Device device = entry.getValue();
+                    HostNodeConnector host = device.toHostNodeConnector();
+                    if (host.getnodeConnector().equals(nodeConnector)) {
+                        deleteDevice(device);
+                        for (IfNewHostNotify notify : newHostNotify)
+                            notify.notifyHTClientHostRemoved(host);
+                        for (IDeviceListener listener : listeners)
+                            listener.deviceRemoved(device);
+                    }
+                }
+
+            }
+        }
+
+
     /**
      * For testing: consolidate the store NOW
      */
index 6c26af2dc710e91eb8bcc6e11d9b4fef2bac8f14..4daa591ba1e1811c9262b5c1a806d7fa7180a763 100644 (file)
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
  *
@@ -27,9 +26,8 @@ import org.slf4j.LoggerFactory;
  * This Class forms the vendor specific IPv6 Flow Match messages as well as
  * processes the vendor specific IPv6 Stats Reply message.
  *
- * For message creation, it parses the user entered IPv6 match fields, creates
- * a sub-message for each field which are later used to form the complete
- * message.
+ * For message creation, it parses the user entered IPv6 match fields, creates a
+ * sub-message for each field which are later used to form the complete message.
  *
  * For message processing, it parses the incoming message and reads each field
  * of the message and stores in appropriate field of V6Match object.
@@ -44,8 +42,7 @@ public class V6Match extends OFMatch implements Cloneable {
     protected short inputPortMask;
     protected byte[] dataLayerSourceMask;
     protected byte[] dataLayerDestinationMask;
-    protected short dataLayerVirtualLanMask;
-    protected byte dataLayerVirtualLanPriorityCodePointMask;
+    protected int dataLayerVirtualLanTCIMask;
     protected short dataLayerTypeMask;
     protected byte networkTypeOfServiceMask;
     protected byte networkProtocolMask;
@@ -57,7 +54,9 @@ public class V6Match extends OFMatch implements Cloneable {
     protected MatchFieldState inputPortState;
     protected MatchFieldState dlSourceState;
     protected MatchFieldState dlDestState;
-    protected MatchFieldState dlVlanState;
+    protected MatchFieldState dlVlanIDState;
+    protected MatchFieldState dlVlanPCPState;
+    protected MatchFieldState dlVlanTCIState;
     protected MatchFieldState ethTypeState;
     protected MatchFieldState nwTosState;
     protected MatchFieldState nwProtoState;
@@ -131,8 +130,7 @@ public class V6Match extends OFMatch implements Cloneable {
         this.dataLayerSourceMask = null;
         this.dataLayerDestinationMask = null;
         this.dataLayerTypeMask = 0;
-        this.dataLayerVirtualLanMask = 0;
-        this.dataLayerVirtualLanPriorityCodePointMask = 0;
+        this.dataLayerVirtualLanTCIMask = 0;
         this.networkTypeOfServiceMask = 0;
         this.networkProtocolMask = 0;
         this.transportSourceMask = 0;
@@ -141,7 +139,9 @@ public class V6Match extends OFMatch implements Cloneable {
         this.inputPortState = MatchFieldState.MATCH_ABSENT;
         this.dlSourceState = MatchFieldState.MATCH_ABSENT;
         this.dlDestState = MatchFieldState.MATCH_ABSENT;
-        this.dlVlanState = MatchFieldState.MATCH_ABSENT;
+        this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
+        this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
+        this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
         this.ethTypeState = MatchFieldState.MATCH_ABSENT;
         this.nwTosState = MatchFieldState.MATCH_ABSENT;
         this.nwProtoState = MatchFieldState.MATCH_ABSENT;
@@ -162,7 +162,7 @@ public class V6Match extends OFMatch implements Cloneable {
         if (match.getNetworkSource() != 0) {
             InetAddress address = NetUtils.getInetAddress(match.getNetworkSource());
             InetAddress mask = NetUtils.getInetNetworkMask(match.getNetworkSourceMaskLen(), false);
-            this.setNetworkDestination(address, mask);
+            this.setNetworkSource(address, mask);
         } else {
             this.nwSrcState = MatchFieldState.MATCH_ABSENT;
         }
@@ -184,13 +184,15 @@ public class V6Match extends OFMatch implements Cloneable {
         }
 
         this.dataLayerSourceMask = null;
-        if (match.getDataLayerSource() != null && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
+        if (match.getDataLayerSource() != null
+                && !NetUtils.isZeroMAC(match.getDataLayerSource())) {
             this.setDataLayerSource(match.getDataLayerSource(), null);
         } else {
             this.dlSourceState = MatchFieldState.MATCH_ABSENT;
         }
         this.dataLayerDestinationMask = null;
-        if (match.getDataLayerDestination() != null && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
+        if (match.getDataLayerDestination() != null
+                && !NetUtils.isZeroMAC(match.getDataLayerDestination())) {
             this.setDataLayerDestination(match.getDataLayerDestination(), null);
         } else {
             this.dlDestState = MatchFieldState.MATCH_ABSENT;
@@ -204,27 +206,28 @@ public class V6Match extends OFMatch implements Cloneable {
             this.ethTypeState = MatchFieldState.MATCH_ABSENT;
         }
 
-        this.dataLayerVirtualLanMask = 0;
+        this.dataLayerVirtualLanTCIMask = 0;
+        this.dlVlanTCIState = MatchFieldState.MATCH_ABSENT;
         if (match.getDataLayerVirtualLan() != 0) {
             this.setDataLayerVirtualLan(match.getDataLayerVirtualLan(),
                     (short) 0);
         } else {
             this.dataLayerVirtualLan = 0;
-            this.dlVlanState = MatchFieldState.MATCH_ABSENT;
+            this.dlVlanIDState = MatchFieldState.MATCH_ABSENT;
         }
 
-        this.dataLayerVirtualLanPriorityCodePointMask = 0;
         if (match.getDataLayerVirtualLanPriorityCodePoint() != 0) {
-            this.setDataLayerVirtualLanPriorityCodePoint(match
-                    .getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
+            this.setDataLayerVirtualLanPriorityCodePoint(
+                    match.getDataLayerVirtualLanPriorityCodePoint(), (byte) 0);
         } else {
             this.dataLayerVirtualLanPriorityCodePoint = 0;
+            this.dlVlanPCPState = MatchFieldState.MATCH_ABSENT;
         }
 
         this.networkProtocolMask = 0;
         if (match.getNetworkProtocol() != 0) {
-            this.setNetworkProtocol(this.networkProtocol = match
-                    .getNetworkProtocol(), (byte) 0);
+            this.setNetworkProtocol(
+                    this.networkProtocol = match.getNetworkProtocol(), (byte) 0);
         } else {
             this.networkProtocol = 0;
             this.nwProtoState = MatchFieldState.MATCH_ABSENT;
@@ -232,8 +235,9 @@ public class V6Match extends OFMatch implements Cloneable {
 
         this.networkTypeOfServiceMask = 0;
         if (match.getNetworkTypeOfService() != 0) {
-            this.setNetworkTypeOfService(this.networkTypeOfService = match
-                    .getNetworkTypeOfService(), (byte) 0);
+            this.setNetworkTypeOfService(
+                    this.networkTypeOfService = match.getNetworkTypeOfService(),
+                    (byte) 0);
         } else {
             this.networkTypeOfService = match.getNetworkTypeOfService();
             this.nwTosState = MatchFieldState.MATCH_ABSENT;
@@ -327,13 +331,47 @@ public class V6Match extends OFMatch implements Cloneable {
         return (ipv6ext_etype_msg.array());
     }
 
-    private byte[] getIPv6ExtensionVlanIDMatchMsg(short VLAN) {
-        ByteBuffer ipv6ext_vlanid_msg = ByteBuffer.allocate(6);
+    private byte[] getVlanTCI(short dataLayerVirtualLanID,
+            byte dataLayerVirtualLanPriorityCodePoint) {
+        ByteBuffer vlan_tci = ByteBuffer.allocate(2);
+        int cfi = 1 << 12; // the cfi bit is in position 12
+        int pcp = dataLayerVirtualLanPriorityCodePoint << 13; // the pcp fields
+                                                              // have to move by
+                                                              // 13
+        int vlan_tci_int = pcp + cfi + dataLayerVirtualLanID;
+        vlan_tci.put((byte) (vlan_tci_int >> 8)); // bits 8 to 15
+        vlan_tci.put((byte) vlan_tci_int); // bits 0 to 7
+        return vlan_tci.array();
+    }
+
+    private byte[] getIPv6ExtensionVlanTCIMatchMsg(short dataLayerVirtualLanID,
+            byte dataLayerVirtualLanPriorityCodePoint) {
+        ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(6);
         int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
                 OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 0, 2);
-        ipv6ext_vlanid_msg.putInt(nxm_header);
-        ipv6ext_vlanid_msg.putShort(VLAN);
-        return (ipv6ext_vlanid_msg.array());
+        ipv6ext_vlan_tci_msg.putInt(nxm_header);
+        ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLanID,
+                dataLayerVirtualLanPriorityCodePoint));
+        return (ipv6ext_vlan_tci_msg.array());
+    }
+
+    private byte[] getIPv6ExtensionVlanTCIMatchWithMaskMsg(
+            short dataLayerVirtualLan,
+            byte dataLayerVirtualLanPriorityCodePoint,
+            int dataLayerVirtualLanTCIMask) {
+        ByteBuffer ipv6ext_vlan_tci_msg = ByteBuffer.allocate(8);
+        int nxm_header = getIPv6ExtensionMatchHeader(Extension_Types.OF_10,
+                OF_Match_Types.MATCH_OF_VLAN_TCI.getValue(), 1, 4);
+        ipv6ext_vlan_tci_msg.putInt(nxm_header);
+        ipv6ext_vlan_tci_msg.put(getVlanTCI(dataLayerVirtualLan,
+                dataLayerVirtualLanPriorityCodePoint));
+        ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask >> 8)); // bits
+                                                                            // 8
+                                                                            // to
+                                                                            // 15
+        ipv6ext_vlan_tci_msg.put((byte) (dataLayerVirtualLanTCIMask)); // bits 0
+                                                                       // to 7
+        return (ipv6ext_vlan_tci_msg.array());
     }
 
     private byte[] getIPv6ExtensionSrcIPv6MatchMsg(byte[] srcIpv6) {
@@ -392,11 +430,10 @@ public class V6Match extends OFMatch implements Cloneable {
         ipv6ext_proto_msg.putInt(nxm_header);
         if (protocol == IPProtocols.ICMP.getValue()) {
             /*
-             * The front end  passes the same protocol type values for IPv4
-             * and IPv6 flows. For the Protocol types we allow in our GUI
-             * (ICMP, TCP, UDP), ICMP is the only one which is different for
-             * IPv6. It is 1 for v4 and 58 for v6 Therefore, we overwrite it
-             * here.
+             * The front end passes the same protocol type values for IPv4 and
+             * IPv6 flows. For the Protocol types we allow in our GUI (ICMP,
+             * TCP, UDP), ICMP is the only one which is different for IPv6. It
+             * is 1 for v4 and 58 for v6 Therefore, we overwrite it here.
              */
             protocol = IPProtocols.ICMPV6.getValue();
         }
@@ -450,9 +487,11 @@ public class V6Match extends OFMatch implements Cloneable {
     }
 
     /**
-     * Sets this (V6Match) object's member variables based on a comma-separated key=value pair similar to OFMatch's fromString.
+     * Sets this (V6Match) object's member variables based on a comma-separated
+     * key=value pair similar to OFMatch's fromString.
      *
-     * @param match a key=value comma separated string.
+     * @param match
+     *            a key=value comma separated string.
      */
     @Override
     public void fromString(String match) throws IllegalArgumentException {
@@ -497,17 +536,45 @@ public class V6Match extends OFMatch implements Cloneable {
                     this.dataLayerType = U16.t(Integer.valueOf(values[1]
                             .replaceFirst("0x", ""), 16));
                 } else {
+
                     this.dataLayerType = U16.t(Integer.valueOf(values[1]));
                 }
                 ethTypeState = MatchFieldState.MATCH_FIELD_ONLY;
                 match_len += 6;
             } else if (values[0].equals(STR_DL_VLAN)) {
                 this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1]));
-                dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
-                match_len += 6;
+                this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
+                // the variable dlVlanIDState is not really used as a flag
+                // for serializing and deserializing. Rather it is used as a
+                // flag
+                // to check if the vlan id is being set so that we can set the
+                // dlVlanTCIState appropriately.
+                if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
+                    this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+                    match_len -= 2;
+                } else {
+                    this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+                    this.dataLayerVirtualLanTCIMask = 0x1fff;
+                    match_len += 8;
+                }
+                this.wildcards &= ~OFPFW_DL_VLAN;
             } else if (values[0].equals(STR_DL_VLAN_PCP)) {
                 this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short
                         .valueOf(values[1]));
+                this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
+                // the variable dlVlanPCPState is not really used as a flag
+                // for serializing and deserializing. Rather it is used as a
+                // flag
+                // to check if the vlan pcp is being set so that we can set the
+                // dlVlanTCIState appropriately.
+                if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
+                    this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+                    match_len -= 2;
+                } else {
+                    this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+                    this.dataLayerVirtualLanTCIMask = 0xf000;
+                    match_len += 8;
+                }
                 this.wildcards &= ~OFPFW_DL_VLAN_PCP;
             } else if (values[0].equals(STR_NW_DST)
                     || values[0].equals("ip_dst")) {
@@ -524,7 +591,7 @@ public class V6Match extends OFMatch implements Cloneable {
                     }
                     this.setNetworkDestination(address, mask);
                 } catch (UnknownHostException e) {
-                    logger.error("",e);
+                    logger.error("", e);
                 }
             } else if (values[0].equals(STR_NW_SRC)
                     || values[0].equals("ip_src")) {
@@ -541,7 +608,7 @@ public class V6Match extends OFMatch implements Cloneable {
                     }
                     this.setNetworkSource(address, mask);
                 } catch (UnknownHostException e) {
-                    logger.error("",e);
+                    logger.error("", e);
                 }
             } else if (values[0].equals(STR_NW_PROTO)) {
                 this.networkProtocol = U8.t(Short.valueOf(values[1]));
@@ -571,8 +638,8 @@ public class V6Match extends OFMatch implements Cloneable {
         }
 
         /*
-         * In a V6 extension message action list should be preceded by a padding of 0 to
-         * 7 bytes based upon following formula.
+         * In a V6 extension message action list should be preceded by a padding
+         * of 0 to 7 bytes based upon following formula.
          */
 
         pad_size = (short) (((match_len + 7) / 8) * 8 - match_len);
@@ -602,9 +669,17 @@ public class V6Match extends OFMatch implements Cloneable {
             byte[] ipv6ext_srcmac_msg = getIPv6ExtensionSrcMacMatchMsg(this.dataLayerSource);
             data.put(ipv6ext_srcmac_msg);
         }
-        if (dlVlanState == MatchFieldState.MATCH_FIELD_ONLY) {
-            byte[] ipv6ext_vlan_id_msg = getIPv6ExtensionVlanIDMatchMsg(this.dataLayerVirtualLan);
-            data.put(ipv6ext_vlan_id_msg);
+        if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_ONLY) {
+            byte[] ipv6ext_vlan_tci_msg = getIPv6ExtensionVlanTCIMatchMsg(
+                    this.dataLayerVirtualLan,
+                    this.dataLayerVirtualLanPriorityCodePoint);
+            data.put(ipv6ext_vlan_tci_msg);
+        } else if (dlVlanTCIState == MatchFieldState.MATCH_FIELD_WITH_MASK) {
+            byte[] ipv6ext_vlan_tci_msg_with_mask = getIPv6ExtensionVlanTCIMatchWithMaskMsg(
+                    this.dataLayerVirtualLan,
+                    this.dataLayerVirtualLanPriorityCodePoint,
+                    this.dataLayerVirtualLanTCIMask);
+            data.put(ipv6ext_vlan_tci_msg_with_mask);
         }
         if (nwSrcState == MatchFieldState.MATCH_FIELD_ONLY) {
             byte[] ipv6ext_src_ipv6_msg = getIPv6ExtensionSrcIPv6MatchMsg(this.nwSrc
@@ -728,33 +803,69 @@ public class V6Match extends OFMatch implements Cloneable {
         this.match_len += 6;
     }
 
+    private short getVlanID(byte firstByte, byte secondByte) {
+        short vlan_id_mask_firstByte = 0x0f;// this is the mask for the first
+                                            // byte
+        short vlan_id_mask_secondByte = 0xff;// this is the mask for the second
+                                             // byte
+        int vlanPart1 = (firstByte & vlan_id_mask_firstByte) << 8;
+        int vlanPart2 = secondByte & vlan_id_mask_secondByte;
+        return (short) (vlanPart1 + vlanPart2);
+    }
+
+    private byte getVlanPCP(byte pcpByte) {
+        short vlan_pcp_mask = 0xe0;// this is the vlan pcp mask
+        int pcp_int = pcpByte & vlan_pcp_mask;
+        return (byte) (pcp_int >> 5);
+    }
+
     private void readVlanTci(ByteBuffer data, int nxmLen, boolean hasMask) {
-        short vlan_mask = 0xfff;
         if (hasMask) {
             if ((nxmLen != 2 * 2) || (data.remaining() < 2 * 2)) {
                 return;
-            } else {
-                short vlan = data.getShort();
-                vlan &= vlan_mask;
-                super.setDataLayerVirtualLan(vlan);
-                this.dataLayerVirtualLanMask = data.getShort();
-                this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+            }
+            else {
+                byte firstByte = data.get();
+                byte secondByte = data.get();
+                this.dataLayerVirtualLanTCIMask = data.getShort() & 0xffff; // we
+                                                                            // need
+                                                                            // the
+                                                                            // last
+                                                                            // 16
+                                                                            // bits
+                // check the mask now
+                if ((this.dataLayerVirtualLanTCIMask & 0x0fff) != 0) {
+                    // if its a vlan id mask
+                    // extract the vlan id
+                    super.setDataLayerVirtualLan(getVlanID(firstByte,
+                            secondByte));
+                } else {
+                    this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
+                }
+                if ((this.dataLayerVirtualLanTCIMask & 0xe000) != 0) {
+                    // else if its a vlan pcp mask
+                    // extract the vlan pcp
+                    super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
+                } else {
+                    this.wildcards ^= (1 << 20);
+                }
+                this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
                 this.match_len += 8;
-                this.wildcards ^= (1 << 20);
             }
         } else {
             if ((nxmLen != 2) || (data.remaining() < 2)) {
                 return;
-            } else {
-                short vlan = data.getShort();
-                vlan &= vlan_mask;
-                super.setDataLayerVirtualLan(vlan);
-                this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
+            }
+            else {
+                // get the vlan pcp
+                byte firstByte = data.get();
+                byte secondByte = data.get();
+                super.setDataLayerVirtualLanPriorityCodePoint(getVlanPCP(firstByte));
+                super.setDataLayerVirtualLan(getVlanID(firstByte, secondByte));
+                this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
                 this.match_len += 6;
             }
         }
-
-        this.wildcards ^= (1 << 1); // Sync with 0F 1.0 Match
     }
 
     private void readIpTos(ByteBuffer data, int nxmLen, boolean hasMask) {
@@ -812,7 +923,8 @@ public class V6Match extends OFMatch implements Cloneable {
                 super.setNetworkSource(address);
                 this.nwSrcState = MatchFieldState.MATCH_FIELD_ONLY;
                 this.match_len += 8;
-                this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0 Match
+                this.wildcards ^= (((1 << 6) - 1) << 8); // Sync with 0F 1.0
+                                                         // Match
             }
         }
     }
@@ -832,8 +944,10 @@ public class V6Match extends OFMatch implements Cloneable {
                 this.nwDstState = MatchFieldState.MATCH_FIELD_WITH_MASK;
                 this.match_len += 12;
                 int prefixlen = getNetworkMaskPrefixLength(mbytes);
-                this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
-                this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0 Match
+                this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
+                                                          // Match
+                this.wildcards |= ((32 - prefixlen) << 14); // Sync with 0F 1.0
+                                                            // Match
             }
         } else {
             if ((nxmLen != 4) || (data.remaining() < 4)) {
@@ -844,7 +958,8 @@ public class V6Match extends OFMatch implements Cloneable {
                 int address = NetUtils.byteArray4ToInt(dbytes);
                 super.setNetworkDestination(address);
                 this.nwDstState = MatchFieldState.MATCH_FIELD_ONLY;
-                this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0 Match
+                this.wildcards ^= (((1 << 6) - 1) << 14); // Sync with 0F 1.0
+                                                          // Match
                 this.match_len += 8;
             }
         }
@@ -979,9 +1094,7 @@ public class V6Match extends OFMatch implements Cloneable {
                 + HexEncode.bytesToHexStringFormat(dataLayerSourceMask)
                 + ", dataLayerDestinationMask="
                 + HexEncode.bytesToHexStringFormat(dataLayerDestinationMask)
-                + ", dataLayerVirtualLanMask=" + dataLayerVirtualLanMask
-                + ", dataLayerVirtualLanPriorityCodePointMask="
-                + dataLayerVirtualLanPriorityCodePointMask
+                + ", dataLayerVirtualLanTCIMask=" + dataLayerVirtualLanTCIMask
                 + ", dataLayerTypeMask=" + dataLayerTypeMask
                 + ", networkTypeOfServiceMask=" + networkTypeOfServiceMask
                 + ", networkProtocolMask=" + networkProtocolMask
@@ -991,7 +1104,7 @@ public class V6Match extends OFMatch implements Cloneable {
                 + ", dstIPv6SubnetMaskbits=" + dstIPv6SubnetMaskbits
                 + ", inputPortState=" + inputPortState + ", dlSourceState="
                 + dlSourceState + ", dlDestState=" + dlDestState
-                + ", dlVlanState=" + dlVlanState + ", ethTypeState="
+                + ", dlVlanTCIState=" + dlVlanTCIState + ", ethTypeState="
                 + ethTypeState + ", nwTosState=" + nwTosState
                 + ", nwProtoState=" + nwProtoState + ", nwSrcState="
                 + nwSrcState + ", nwDstState=" + nwDstState + ", tpSrcState="
@@ -1001,8 +1114,9 @@ public class V6Match extends OFMatch implements Cloneable {
 
     /**
      * Read the data corresponding to the match field (received from the wire)
-     * Input: data: match field(s). Since match field is of variable length, the whole data that are passed in
-     * are assumed to fem0tbd.be the match fields.
+     * Input: data: match field(s). Since match field is of variable length, the
+     * whole data that are passed in are assumed to fem0tbd.be the match fields.
+     *
      * @param data
      */
     @Override
@@ -1018,8 +1132,8 @@ public class V6Match extends OFMatch implements Cloneable {
                 /*
                  * at least 4 bytes for each match header
                  */
-                logger.error("Invalid Vendor Extension Header. Size {}", data
-                        .remaining());
+                logger.error("Invalid Vendor Extension Header. Size {}",
+                        data.remaining());
                 return;
             }
             /*
@@ -1095,11 +1209,11 @@ public class V6Match extends OFMatch implements Cloneable {
         // Sync with 0F 1.0 Match
         if (super.getDataLayerType() == 0x800) {
             if (((this.wildcards >> 8) & 0x3f) == 0x3f) {
-                //ipv4 src processing
+                // ipv4 src processing
                 this.wildcards ^= (((1 << 5) - 1) << 8);
             }
             if (((this.wildcards >> 14) & 0x3f) == 0x3f) {
-                //ipv4 dest processing
+                // ipv4 dest processing
                 this.wildcards ^= (((1 << 5) - 1) << 14);
             }
         } else {
@@ -1204,24 +1318,40 @@ public class V6Match extends OFMatch implements Cloneable {
         }
     }
 
-    public short getDataLayerVirtualLanMask() {
-        return dataLayerVirtualLanMask;
-    }
-
     public void setDataLayerVirtualLan(short vlan, short mask) {
+        // mask is ignored as the code sets the appropriate mask
         super.dataLayerVirtualLan = vlan;
-        if (mask == 0) {
-            this.dlVlanState = MatchFieldState.MATCH_FIELD_ONLY;
-            this.match_len += 6;
+        this.dlVlanIDState = MatchFieldState.MATCH_FIELD_ONLY;
+        // the variable dlVlanIDState is not really used as a flag
+        // for serializing and deserializing. Rather it is used as a flag
+        // to check if the vlan id is being set so that we can set the
+        // dlVlanTCIState appropriately.
+        if (this.dlVlanPCPState != MatchFieldState.MATCH_ABSENT) {
+            this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+            match_len -= 2;
         } else {
-            this.dataLayerVirtualLanMask = mask;
-            this.dlVlanState = MatchFieldState.MATCH_FIELD_WITH_MASK;
-            this.match_len += 8;
+            this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+            this.dataLayerVirtualLanTCIMask = 0x1fff;
+            match_len += 8;
         }
     }
 
     public void setDataLayerVirtualLanPriorityCodePoint(byte pcp, byte mask) {
+        // mask is ignored as the code sets the appropriate mask
         super.dataLayerVirtualLanPriorityCodePoint = pcp;
+        this.dlVlanPCPState = MatchFieldState.MATCH_FIELD_ONLY;
+        // the variable dlVlanPCPState is not really used as a flag
+        // for serializing and deserializing. Rather it is used as a flag
+        // to check if the vlan pcp is being set so that we can set the
+        // dlVlanTCIState appropriately.
+        if (this.dlVlanIDState != MatchFieldState.MATCH_ABSENT) {
+            this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_ONLY;
+            match_len -= 2;
+        } else {
+            this.dlVlanTCIState = MatchFieldState.MATCH_FIELD_WITH_MASK;
+            this.dataLayerVirtualLanTCIMask = 0xf000;
+            match_len += 8;
+        }
     }
 
     public void setDataLayerType(short ethType, short mask) {
@@ -1347,28 +1477,38 @@ public class V6Match extends OFMatch implements Cloneable {
         result = prime * result + Arrays.hashCode(dataLayerDestinationMask);
         result = prime * result + Arrays.hashCode(dataLayerSourceMask);
         result = prime * result + dataLayerTypeMask;
-        result = prime * result + dataLayerVirtualLanMask;
-        result = prime * result + dataLayerVirtualLanPriorityCodePointMask;
-        result = prime * result + ((dlDestState == null) ? 0 : dlDestState.hashCode());
-        result = prime * result + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
-        result = prime * result + ((dlVlanState == null) ? 0 : dlVlanState.hashCode());
+        result = prime * result + dataLayerVirtualLanTCIMask;
+        result = prime * result
+                + ((dlDestState == null) ? 0 : dlDestState.hashCode());
+        result = prime * result
+                + ((dlSourceState == null) ? 0 : dlSourceState.hashCode());
+        result = prime * result
+                + ((dlVlanTCIState == null) ? 0 : dlVlanTCIState.hashCode());
         result = prime * result + dstIPv6SubnetMaskbits;
-        result = prime * result + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
+        result = prime * result
+                + ((ethTypeState == null) ? 0 : ethTypeState.hashCode());
         result = prime * result + inputPortMask;
-        result = prime * result + ((inputPortState == null) ? 0 : inputPortState.hashCode());
+        result = prime * result
+                + ((inputPortState == null) ? 0 : inputPortState.hashCode());
         result = prime * result + match_len;
         result = prime * result + networkProtocolMask;
         result = prime * result + networkTypeOfServiceMask;
         result = prime * result + ((nwDst == null) ? 0 : nwDst.hashCode());
-        result = prime * result + ((nwDstState == null) ? 0 : nwDstState.hashCode());
-        result = prime * result + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
+        result = prime * result
+                + ((nwDstState == null) ? 0 : nwDstState.hashCode());
+        result = prime * result
+                + ((nwProtoState == null) ? 0 : nwProtoState.hashCode());
         result = prime * result + ((nwSrc == null) ? 0 : nwSrc.hashCode());
-        result = prime * result + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
-        result = prime * result + ((nwTosState == null) ? 0 : nwTosState.hashCode());
+        result = prime * result
+                + ((nwSrcState == null) ? 0 : nwSrcState.hashCode());
+        result = prime * result
+                + ((nwTosState == null) ? 0 : nwTosState.hashCode());
         result = prime * result + pad_size;
         result = prime * result + srcIPv6SubnetMaskbits;
-        result = prime * result + ((tpDstState == null) ? 0 : tpDstState.hashCode());
-        result = prime * result + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
+        result = prime * result
+                + ((tpDstState == null) ? 0 : tpDstState.hashCode());
+        result = prime * result
+                + ((tpSrcState == null) ? 0 : tpSrcState.hashCode());
         result = prime * result + transportDestinationMask;
         result = prime * result + transportSourceMask;
         return result;
@@ -1395,21 +1535,15 @@ public class V6Match extends OFMatch implements Cloneable {
         if (dataLayerTypeMask != other.dataLayerTypeMask) {
             return false;
         }
-        if (dataLayerVirtualLanMask != other.dataLayerVirtualLanMask) {
+        if (dataLayerVirtualLanTCIMask != other.dataLayerVirtualLanTCIMask) {
             return false;
         }
-        if (dataLayerVirtualLanPriorityCodePointMask != other.dataLayerVirtualLanPriorityCodePointMask) {
-            return false;
-        }
-        if (dlDestState != other.dlDestState) {
+        if (dlVlanTCIState != other.dlVlanTCIState) {
             return false;
         }
         if (dlSourceState != other.dlSourceState) {
             return false;
         }
-        if (dlVlanState != other.dlVlanState) {
-            return false;
-        }
         if (dstIPv6SubnetMaskbits != other.dstIPv6SubnetMaskbits) {
             return false;
         }
index 6afaf5f67531ace92c1cebf282bc5d2d632c6773..2898dde363b01b605212a13004b38e47d3c5e76a 100644 (file)
@@ -6,9 +6,9 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.nio.ByteBuffer;
 import java.util.Arrays;
+
 import org.junit.Assert;
 import org.junit.Test;
-import org.opendaylight.controller.protocol_plugin.openflow.vendorextension.v6extension.V6Match;
 import org.openflow.protocol.OFMatch;
 
 public class V6ExtensionTest {
@@ -119,6 +119,7 @@ public class V6ExtensionTest {
         match.fromString("ip_src=2001:ddd:3e1:1234:0000:1111:2222:3333/64");
         match.fromString("ip_dst=2001:123:222:abc:111:aaa:1111:2222/64");
         match.fromString("dl_vlan=10");
+        match.fromString("dl_vpcp=1");
         match.fromString("nw_proto=6");
         match.fromString("nw_tos=100");
         match.fromString("tp_dst=8080");
@@ -142,7 +143,8 @@ public class V6ExtensionTest {
 
         Assert.assertTrue(match.getDataLayerVirtualLan() == match2
                 .getDataLayerVirtualLan());
-        // vlan pcp isn't part of write/read buffer
+        Assert.assertTrue(match.getDataLayerVirtualLanPriorityCodePoint() == match2
+                .getDataLayerVirtualLanPriorityCodePoint());
         Assert.assertTrue(match.getNetworkProtocol() == match2
                 .getNetworkProtocol());
         Assert.assertTrue(match.getNetworkTypeOfService() == match2
index 66882af5d3098d95b97fb7eee530ce57d834974c..de77837c34a1472249b7fe69cd9ac64d10ba129a 100644 (file)
@@ -152,6 +152,11 @@ abstract public class ComponentActivatorAbstractBase implements
 
         @Override
         public void stopped(Component component) {
+            // do nothing
+        }
+
+        @Override
+        public void stopping(Component component) {
             if (component == null) {
                 return;
             }
@@ -160,11 +165,6 @@ abstract public class ComponentActivatorAbstractBase implements
                     { Component.class }, {} }, new Object[][] { { component },
                     {} });
         }
-
-        @Override
-        public void stopping(Component component) {
-            // do nothing
-        }
     }
 
     /**