From: Suchi Raman Date: Fri, 4 Oct 2013 17:46:33 +0000 (-0400) Subject: Demo waypoint for path redirection service: Add flow upon setting a waypoint address... X-Git-Tag: jenkins-affinity-bulk-release-prepare-only-1~58 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=58dacd9059c0ded8d16f4d4823a27e513003f178;p=affinity.git Demo waypoint for path redirection service: Add flow upon setting a waypoint address on an affinity link. Signed-off-by: Suchi Raman --- diff --git a/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/Activator.java b/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/Activator.java index a8ff077..1eff38f 100644 --- a/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/Activator.java +++ b/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/Activator.java @@ -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)); } } } diff --git a/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/AffinityManagerImpl.java b/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/AffinityManagerImpl.java index ce0325d..713e204 100644 --- a/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/AffinityManagerImpl.java +++ b/affinity/implementation/src/main/java/org/opendaylight/affinity/affinity/internal/AffinityManagerImpl.java @@ -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 affinityGroupList; private ConcurrentMap affinityLinkList; private ConcurrentMap configSaveEvent; - private IfIptoHost hostTracker; private final Set affinityManagerAware = Collections .synchronizedSet(new HashSet()); @@ -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> hostPairList= getAllFlowsByHost(al); for (Entry 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 hp1=new AbstractMap.SimpleEntry(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 hp1=new AbstractMap.SimpleEntry(h1, h2); + log.debug("Adding hostPair {} -> {}", h1, h2); hostPairList.add(hp1); } } diff --git a/affinity/northbound/src/main/java/org/opendaylight/affinity/affinity/northbound/AffinityNorthbound.java b/affinity/northbound/src/main/java/org/opendaylight/affinity/affinity/northbound/AffinityNorthbound.java index eba5207..bbf7cae 100644 --- a/affinity/northbound/src/main/java/org/opendaylight/affinity/affinity/northbound/AffinityNorthbound.java +++ b/affinity/northbound/src/main/java/org/opendaylight/affinity/affinity/northbound/AffinityNorthbound.java @@ -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(); } diff --git a/analytics/implementation/src/main/java/org/opendaylight/affinity/analytics/internal/AnalyticsManager.java b/analytics/implementation/src/main/java/org/opendaylight/affinity/analytics/internal/AnalyticsManager.java index 2c4086c..4da5136 100644 --- a/analytics/implementation/src/main/java/org/opendaylight/affinity/analytics/internal/AnalyticsManager.java +++ b/analytics/implementation/src/main/java/org/opendaylight/affinity/analytics/internal/AnalyticsManager.java @@ -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 } diff --git a/l2agent/src/main/java/org/opendaylight/l2agent/Activator.java b/l2agent/src/main/java/org/opendaylight/l2agent/Activator.java index 3ade6e7..2549dcb 100644 --- a/l2agent/src/main/java/org/opendaylight/l2agent/Activator.java +++ b/l2agent/src/main/java/org/opendaylight/l2agent/Activator.java @@ -76,7 +76,8 @@ public class Activator extends ComponentActivatorAbstractBase { // export the services Dictionary props = new Hashtable(); 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 index 0000000..e7e28ae --- /dev/null +++ b/l2agent/src/main/java/org/opendaylight/l2agent/IfL2Agent.java @@ -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); + +} diff --git a/l2agent/src/main/java/org/opendaylight/l2agent/L2Agent.java b/l2agent/src/main/java/org/opendaylight/l2agent/L2Agent.java index 172b562..112e90b 100644 --- a/l2agent/src/main/java/org/opendaylight/l2agent/L2Agent.java +++ b/l2agent/src/main/java/org/opendaylight/l2agent/L2Agent.java @@ -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()); + 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; } } diff --git a/scripts/affinity-topo.py b/scripts/affinity-topo.py index 77699a3..8d0559b 100644 --- a/scripts/affinity-topo.py +++ b/scripts/affinity-topo.py @@ -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 diff --git a/scripts/affinity.py b/scripts/affinity.py index a70eb69..0b4f099 100644 --- a/scripts/affinity.py +++ b/scripts/affinity.py @@ -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__":