Demo waypoint for path redirection service: Add flow upon setting a waypoint address... 81/1681/2
authorSuchi Raman <suchi.raman@plexxi.com>
Fri, 4 Oct 2013 17:46:33 +0000 (13:46 -0400)
committerGerrit Code Review <gerrit@opendaylight.org>
Fri, 4 Oct 2013 17:58:33 +0000 (17:58 +0000)
Signed-off-by: Suchi Raman <suchi.raman@plexxi.com>
affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/Activator.java
affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/AffinityManagerImpl.java
affinity/northbound/src/main/java/org/opendaylight/affinity/affinity/northbound/AffinityNorthbound.java
analytics/implementation/src/main/java/org/opendaylight/affinity/analytics/internal/AnalyticsManager.java
l2agent/src/main/java/org/opendaylight/l2agent/Activator.java
l2agent/src/main/java/org/opendaylight/l2agent/IfL2Agent.java [new file with mode: 0644]
l2agent/src/main/java/org/opendaylight/l2agent/L2Agent.java
scripts/affinity-topo.py
scripts/affinity.py

index a8ff077a43d2fa3434c8cf5551df1d68598631b9..1eff38f2046e2eda8a501e2a3825d185472f7614 100644 (file)
@@ -21,8 +21,11 @@ import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.sal.core.ComponentActivatorAbstractBase;
 import org.opendaylight.affinity.affinity.IAffinityManager;
 import org.opendaylight.affinity.affinity.IAffinityManagerAware;
+import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.opendaylight.affinity.l2agent.IfL2Agent;
+import org.opendaylight.controller.sal.flowprogrammer.IFlowProgrammerService;
 
 /**
  * AffinityManager Bundle Activator
@@ -93,16 +96,27 @@ public class Activator extends ComponentActivatorAbstractBase {
 
             // Now lets add a service dependency to make sure the
             // provider of service exists
-            c.add(createContainerServiceDependency(containerName).setService(
-                    IAffinityManagerAware.class).setCallbacks(
-                    "setAffinityManagerAware", "unsetAffinityManagerAware")
-                    .setRequired(false));
+            /* L2agent dependency causes the service to fail activation. tbd. */
+            c.add(createContainerServiceDependency(containerName)
+                  .setService(IfL2Agent.class)
+                  .setCallbacks("setL2Agent", "unsetL2Agent")
+                  .setRequired(true));
+            c.add(createContainerServiceDependency(containerName).setService(IFlowProgrammerService.class)
+                    .setCallbacks("setFlowProgrammerService", "unsetFlowProgrammerService").setRequired(true));
             c.add(createContainerServiceDependency(containerName).setService(
                     IClusterContainerServices.class).setCallbacks(
                     "setClusterContainerService",
                     "unsetClusterContainerService").setRequired(true));
             c.add(createContainerServiceDependency(containerName).setService(IfIptoHost.class)
                   .setCallbacks("setHostTracker", "unsetHostTracker").setRequired(true));
+            c.add(createContainerServiceDependency(containerName)
+                    .setService(ISwitchManager.class)
+                    .setCallbacks("setSwitchManager", "unsetSwitchManager")
+                    .setRequired(true));
+            c.add(createContainerServiceDependency(containerName).setService(
+                    IAffinityManagerAware.class).setCallbacks(
+                    "setAffinityManagerAware", "unsetAffinityManagerAware")
+                    .setRequired(false));
         }
     }
 }
index ce0325d0727114de303dacd3e5f610dce848d8b1..713e2042121a9991208c1f826c43b11848157ad5 100644 (file)
@@ -89,7 +89,7 @@ import org.opendaylight.affinity.affinity.IAffinityManagerAware;
 import org.opendaylight.controller.hosttracker.IfIptoHost;
 import org.opendaylight.controller.hosttracker.hostAware.HostNodeConnector;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
-import org.opendaylight.affinity.l2agent.L2Agent;
+import org.opendaylight.affinity.l2agent.IfL2Agent;
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -107,13 +107,13 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
     private String affinityGroupFileName = null;
     private IFlowProgrammerService fps = null;
     private ISwitchManager switchManager = null;
-    private L2Agent l2agent = null;
+    private IfL2Agent l2agent = null;
+    private IfIptoHost hostTracker = null;
 
     private ConcurrentMap<String, AffinityGroup> affinityGroupList;
     private ConcurrentMap<String, AffinityLink> affinityLinkList;
     private ConcurrentMap<Long, String> configSaveEvent;
 
-    private IfIptoHost hostTracker;
 
     private final Set<IAffinityManagerAware> affinityManagerAware = Collections
             .synchronizedSet(new HashSet<IAffinityManagerAware>());
@@ -227,6 +227,7 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
 
 
     void setHostTracker(IfIptoHost h) {
+        log.info("Setting hosttracker {}", h);
         this.hostTracker = h;
     }
 
@@ -235,27 +236,39 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
             this.hostTracker = null;
         }
     }
-    public void setFlowProgrammerService(IFlowProgrammerService s)
+    void setFlowProgrammerService(IFlowProgrammerService s)
     {
         this.fps = s;
     }
 
-    public void unsetFlowProgrammerService(IFlowProgrammerService s) {
+    void unsetFlowProgrammerService(IFlowProgrammerService s) {
         if (this.fps == s) {
             this.fps = null;
         }
     }
-    public void setL2Agent(L2Agent s)
+    void setL2Agent(IfL2Agent s)
     {
+        log.info("Setting l2agent {}", s);
         this.l2agent = s;
     }
 
-    public void unsetL2Agent(L2Agent s) {
+    void unsetL2Agent(IfL2Agent s) {
         if (this.l2agent == s) {
             this.l2agent = null;
         }
     }
 
+    void setSwitchManager(ISwitchManager s)
+    {
+        this.switchManager = s;
+    }
+
+    void unsetSwitchManager(ISwitchManager s) {
+        if (this.switchManager == s) {
+            this.switchManager = null;
+        }
+    }
+
     /*
     public void setForwardingRulesManager(
             IForwardingRulesManager forwardingRulesManager) {
@@ -292,7 +305,7 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
            String msg = "Cluster conflict: Conflict while adding the subnet " + al.getName();
            return new Status(StatusCode.CONFLICT, msg);
        }
-       
+
         return new Status(StatusCode.SUCCESS);
     }
 
@@ -314,14 +327,17 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
         } 
         for (Node node: nodes) {
             /* Look up the output port leading to the waypoint. */
-            NodeConnector dst_connector = l2agent.lookup(node, waypointMAC);
-            Action action = new Output(dst_connector);
-            flow.addAction(action);
-
-            Status status = fps.addFlow(node, flow);
-            if (!status.isSuccess()) {
-                log.debug("Error during addFlow: {} on {}. The failure is: {}",
-                          flow, node, status.getDescription());
+            NodeConnector dst_connector = l2agent.lookup_output_port(node, waypointMAC);
+
+            log.debug("Waypoint direction: node {} and connector {}", node, dst_connector);
+            if (dst_connector != null) {
+                flow.addAction(new Output(dst_connector));
+                log.debug("flow push flow = {} to node = {} using fps = {} ", flow, node, fps);
+                Status status = fps.addFlow(node, flow);
+                if (!status.isSuccess()) {
+                    log.debug("Error during addFlow: {} on {}. The failure is: {}",
+                              flow, node, status.getDescription());
+                }
             }
         }
         return success;
@@ -341,15 +357,17 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
         Flow f = new Flow(match, actions);
         String waypoint = al.getWaypoint();
 
+        log.debug("addFlowRulesForRedirect link = {} waypoint = {}", al.getName(), al.getWaypoint());
         List<Entry<Host,Host>> hostPairList= getAllFlowsByHost(al);
         for (Entry<Host,Host> hostPair : hostPairList) {
             /* Create a match for each host pair in the affinity link. */
-
+            log.debug("Processing next hostPair {}", hostPair);
             Host host1 = hostPair.getKey();
             Host host2 = hostPair.getValue();
+            log.debug("Adding a flow for host pair {} -> {}", host1, host2);
             address1 = host1.getNetworkAddress();
             address2 = host2.getNetworkAddress();
-            
+            log.debug("Adding a flow for {} -> {}", address1, address2);
             match.setField(MatchType.NW_SRC, address1, mask);
             match.setField(MatchType.NW_DST, address2, mask);
             
@@ -362,7 +380,8 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
 
     public byte [] InetAddressToMAC(String ipaddress) {
         InetAddress inetAddr = NetUtils.parseInetAddress(ipaddress);
-        HostNodeConnector host = hostTracker.hostFind(inetAddr);
+        HostNodeConnector host = (HostNodeConnector) hostTracker.hostFind(inetAddr);
+        log.debug("Find {} -> {} using hostTracker {}", inetAddr, host, hostTracker);
         byte [] dst_mac = host.getDataLayerAddressBytes();
         return dst_mac;
     }
@@ -498,6 +517,7 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
                if (hostTracker != null) {
                    Host host1 = hostTracker.hostFind((InetAddress) h1.get());
                    Host host2 = hostTracker.hostFind((InetAddress) h2.get());
+                    log.debug("Flow between {}, {}", host1, host2);
                    Entry<Host, Host> hp1=new AbstractMap.SimpleEntry<Host, Host>(host1, host2);
                    hostPairList.add(hp1);
                }
@@ -516,6 +536,7 @@ public class AffinityManagerImpl implements IAffinityManager, IConfigurationCont
        for (AffinityIdentifier h1 : fromGroup.getAllElements()) {
            for (AffinityIdentifier h2 : toGroup.getAllElements()) {
                Entry<AffinityIdentifier, AffinityIdentifier> hp1=new AbstractMap.SimpleEntry<AffinityIdentifier, AffinityIdentifier>(h1, h2);
+                log.debug("Adding hostPair {} -> {}", h1, h2);
                hostPairList.add(hp1);
            }
        }
index eba5207c182cd10e9d21a32a095dc09b9f053989..bbf7cae1c1ac5f2540ae807ee3d02daaa56cc82e 100644 (file)
@@ -274,6 +274,12 @@ public class AffinityNorthbound {
 
         AffinityLink al1 = affinityManager.getAffinityLink(affinityLinkName);
         al1.setWaypoint(waypointIP);
+        try {
+            affinityManager.addFlowRulesForRedirect(al1);
+        } catch (Exception e) {
+            String message = "An error occurred during flow programming.";
+            log.error(message, e);
+        }
         return Response.status(Response.Status.CREATED).build();
     }
 
index 2c4086cfc3272aa302db3f53b08c6a81e755b51d..4da5136ddef5bc1c832eada629b37147ce0ee911 100644 (file)
@@ -83,14 +83,16 @@ public class AnalyticsManager implements IReadServiceListener, IAnalyticsManager
         // TODO: Testing
         AffinityGroup ag1 = new AffinityGroup("testAG1");
         ag1.add("10.0.0.1");
-        ag1.add("10.0.0.2");
+        //        ag1.add("10.0.0.2");
         AffinityGroup ag2 = new AffinityGroup("testAG2");
         ag2.add("10.0.0.3");
-        ag2.add("10.0.0.4");
+        //        ag2.add("10.0.0.4");
         this.affinityManager.addAffinityGroup(ag1);
         this.affinityManager.addAffinityGroup(ag2);
         AffinityLink al = new AffinityLink("testAL", ag1, ag2);
         this.affinityManager.addAffinityLink(al);
+        al.setAttribute("redirect");
+        al.setWaypoint("10.0.0.4");
         // TODO: End testing
     }
 
index 3ade6e7e6c6a87e89c4b7d7640880b9c1415b3be..2549dcbeb93b09879612d876ed61966092e0827a 100644 (file)
@@ -76,7 +76,8 @@ public class Activator extends ComponentActivatorAbstractBase {
             // export the services
             Dictionary<String, String> props = new Hashtable<String, String>();
             props.put("salListenerName", "L2Agent");
-            c.setInterface(new String[] { IListenDataPacket.class.getName() }, props);
+            c.setInterface(new String[] { IListenDataPacket.class.getName(),                    
+                                          IfL2Agent.class.getName() }, props);
 
             // register dependent modules
             c.add(createContainerServiceDependency(containerName).setService(
diff --git a/l2agent/src/main/java/org/opendaylight/l2agent/IfL2Agent.java b/l2agent/src/main/java/org/opendaylight/l2agent/IfL2Agent.java
new file mode 100644 (file)
index 0000000..e7e28ae
--- /dev/null
@@ -0,0 +1,29 @@
+/*
+ * Copyright (c) 2013 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+/*
+ * Copyright (c) 2013 Plexxi, Inc. and others.  All rights reserved.
+ */
+
+
+package org.opendaylight.affinity.l2agent;
+
+import java.net.InetAddress;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.Future;
+
+import org.opendaylight.controller.sal.utils.Status;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.core.Node;
+
+public interface IfL2Agent {
+
+    public NodeConnector lookup_output_port(Node node, byte [] dstMAC);
+
+}
index 172b562a76475ff22c18dc619ee92bad1afdeda9..112e90bf1565e339811b085de9dcc5615356b645 100644 (file)
@@ -57,7 +57,7 @@ import org.opendaylight.controller.sal.utils.NetUtils;
 import org.opendaylight.controller.switchmanager.ISwitchManager;
 import org.opendaylight.controller.switchmanager.Subnet;
 
-public class L2Agent implements IListenDataPacket {
+public class L2Agent implements IListenDataPacket, IfL2Agent {
     private static final Logger logger = LoggerFactory
             .getLogger(L2Agent.class);
     private ISwitchManager switchManager = null;
@@ -200,6 +200,7 @@ public class L2Agent implements IListenDataPacket {
                 // Set up the mapping: switch -> src MAC address -> incoming port
                 if (this.mac_to_ports.get(incoming_node) == null) {
                     this.mac_to_ports.put(incoming_node, new HashMap<Long, NodeConnector>());
+                    logger.info("Added new node = {} to mac_to_ports", incoming_node);
                 }
 
                 // Only replace if we don't know the mapping.  This
@@ -209,6 +210,7 @@ public class L2Agent implements IListenDataPacket {
                 // TODO: this should never happen..
                 if (this.mac_to_ports.get(incoming_node).get(srcMAC_val) == null) {
                     this.mac_to_ports.get(incoming_node).put(srcMAC_val, incoming_connector);
+                    logger.info("Added new learned MAC = {} on incoming connector = {} to mac_to_ports", srcMAC_val, incoming_connector);
                 }
 
                 NodeConnector dst_connector = this.mac_to_ports.get(incoming_node).get(dstMAC_val);
@@ -241,8 +243,12 @@ public class L2Agent implements IListenDataPacket {
         }
         return PacketResult.IGNORED;
     }
-    
-    public NodeConnector lookup(Node node, byte [] dstMAC) {
-        return this.mac_to_ports.get(node).get(dstMAC);
+
+    @Override
+    public NodeConnector lookup_output_port(Node node, byte [] dstMAC) {
+        long dstMAC_val = BitBufferHelper.toNumber(dstMAC);
+        NodeConnector nc = this.mac_to_ports.get(node).get(dstMAC_val);
+        logger.debug("lookup_output_port: Node = {}, dst mac = {}, Nodeconnector = {}", node, dstMAC_val, nc);
+        return nc;
     }
 }
index 77699a373f7728397f4aceb712a71761b17d1176..8d0559b644d7749866e7d60c2627b9d3c5d6414f 100644 (file)
@@ -27,6 +27,11 @@ class CustomTopo(Topo):
         h2 = self.addHost('h2')
         h3 = self.addHost('h3')
         h4 = self.addHost('h4')
+        h1.setIP('10.0.0.10')
+        h1.setIP('10.0.0.20')
+        h1.setIP('10.0.0.30')
+        h1.setIP('10.0.0.40')
+
 
         # Connect hosts to switches
         self.addLink(h1, s2, bw=10) # These two links get limited
index a70eb69b282080e8261e5f921dee31d8a14c19ea..0b4f099c82c8439147b571eb2e9d3489e5e02230 100644 (file)
@@ -19,6 +19,13 @@ def rest_method(url, verb):
     print "done"
     
 
+def list_all_hosts(): 
+
+    print "list all hosts"
+    put_url = 'http://localhost:8080/controller/nb/v2/hosttracker/default/hosts/active'
+    rest_method(put_url, "GET")
+    
+
 def waypoint_init():
     # Create two affinity groups
 
@@ -66,6 +73,11 @@ def set_waypoint_address():
     put_url = 'http://localhost:8080/affinity/nb/v2/affinity/default/link/inflows/setwaypoint/' + wp
     rest_method(put_url, "PUT")
 
+def demo_set_waypoint_address():
+    wp = "10.0.0.4"
+    put_url = 'http://localhost:8080/affinity/nb/v2/affinity/default/link/testAL/setwaypoint/' + wp
+    rest_method(put_url, "PUT")
+
 # Add waypoint IP to an affinity link.
 def main():
     global h
@@ -73,13 +85,15 @@ def main():
     h.add_credentials('admin', 'admin')
 
 #    waypoint_init()
-    set_waypoint_address()
+    demo_set_waypoint_address()
 #    unset_waypoint_address()
 
-    get_affinity_group('webservers')
-    get_affinity_group('clients')
+#    get_affinity_group('webservers')
+#    get_affinity_group('clients')
+
+#    get_all_affinity_groups()
 
-    get_all_affinity_groups()
+    list_all_hosts()
 #    get_all_affinity_links()
 
 if __name__ == "__main__":