X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fsamples%2Fsimpleforwarding%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fsamples%2Fsimpleforwarding%2Finternal%2FSimpleForwardingImpl.java;h=94e67247c8eaa44696f83d2950bea6650732f89a;hp=043e5c3f0db1768449a5d580af2172f9aa828e12;hb=4ddd587b31a9aeec7d3d5ae0047852a64fbb70c2;hpb=c0252287ec57d8e3a48902519501244ca362687b diff --git a/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java b/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java index 043e5c3f0d..94e67247c8 100644 --- a/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java +++ b/opendaylight/samples/simpleforwarding/src/main/java/org/opendaylight/controller/samples/simpleforwarding/internal/SimpleForwardingImpl.java @@ -9,6 +9,7 @@ package org.opendaylight.controller.samples.simpleforwarding.internal; +import java.net.InetAddress; import java.util.ArrayList; import java.util.EnumSet; import java.util.HashMap; @@ -45,9 +46,17 @@ import org.opendaylight.controller.sal.core.UpdateType; import org.opendaylight.controller.sal.flowprogrammer.Flow; import org.opendaylight.controller.sal.match.Match; import org.opendaylight.controller.sal.match.MatchType; +import org.opendaylight.controller.sal.packet.Ethernet; +import org.opendaylight.controller.sal.packet.IDataPacketService; +import org.opendaylight.controller.sal.packet.IListenDataPacket; +import org.opendaylight.controller.sal.packet.IPv4; +import org.opendaylight.controller.sal.packet.Packet; +import org.opendaylight.controller.sal.packet.PacketResult; +import org.opendaylight.controller.sal.packet.RawPacket; import org.opendaylight.controller.sal.routing.IListenRoutingUpdates; import org.opendaylight.controller.sal.routing.IRouting; import org.opendaylight.controller.sal.utils.EtherTypes; +import org.opendaylight.controller.sal.utils.NetUtils; import org.opendaylight.controller.sal.utils.NodeConnectorCreator; import org.opendaylight.controller.sal.utils.Status; import org.opendaylight.controller.samples.simpleforwarding.HostNodePair; @@ -70,11 +79,10 @@ import org.slf4j.LoggerFactory; * installs those rules using installPerHostRules(). */ public class SimpleForwardingImpl implements IfNewHostNotify, - IListenRoutingUpdates, IInventoryListener { - private static Logger log = LoggerFactory - .getLogger(SimpleForwardingImpl.class); + IListenRoutingUpdates, IInventoryListener, IListenDataPacket { + private static Logger log = LoggerFactory.getLogger(SimpleForwardingImpl.class); private static short DEFAULT_IPSWITCH_PRIORITY = 1; - private static String FORWARDING_RULES_CACHE_NAME = "forwarding.ipswitch.rules"; + static final String FORWARDING_RULES_CACHE_NAME = "forwarding.ipswitch.rules"; private IfIptoHost hostTracker; private IForwardingRulesManager frm; private ITopologyManager topologyManager; @@ -90,6 +98,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify, private Map> tobePrunedPos = new HashMap>(); private IClusterContainerServices clusterContainerService = null; private ISwitchManager switchManager; + private IDataPacketService dataPacketService; /** * Return codes from the programming of the perHost rules in HW @@ -97,8 +106,19 @@ public class SimpleForwardingImpl implements IfNewHostNotify, public enum RulesProgrammingReturnCode { SUCCESS, FAILED_FEW_SWITCHES, FAILED_ALL_SWITCHES, FAILED_WRONG_PARAMS } + public void setDataPacketService(IDataPacketService s) { + log.debug("Setting dataPacketService"); + this.dataPacketService = s; + } + + public void unsetDataPacketService(IDataPacketService s) { + if (this.dataPacketService == s) { + this.dataPacketService = null; + } + } public void setRouting(IRouting routing) { + log.debug("Setting routing"); this.routing = routing; } @@ -108,10 +128,6 @@ public class SimpleForwardingImpl implements IfNewHostNotify, } } - public ITopologyManager getTopologyManager() { - return topologyManager; - } - public void setTopologyManager(ITopologyManager topologyManager) { log.debug("Setting topologyManager"); this.topologyManager = topologyManager; @@ -166,10 +182,9 @@ public class SimpleForwardingImpl implements IfNewHostNotify, destroyCaches(); } - @SuppressWarnings("deprecation") - private void allocateCaches() { + private void allocateCaches() { if (this.clusterContainerService == null) { - log.info("un-initialized clusterContainerService, can't create cache"); + log.trace("un-initialized clusterContainerService, can't create cache"); return; } @@ -183,10 +198,10 @@ public class SimpleForwardingImpl implements IfNewHostNotify, } } - @SuppressWarnings({ "unchecked", "deprecation" }) + @SuppressWarnings({ "unchecked" }) private void retrieveCaches() { if (this.clusterContainerService == null) { - log.info("un-initialized clusterContainerService, can't retrieve cache"); + log.trace("un-initialized clusterContainerService, can't retrieve cache"); return; } @@ -197,10 +212,9 @@ public class SimpleForwardingImpl implements IfNewHostNotify, } } - @SuppressWarnings("deprecation") - private void destroyCaches() { + private void destroyCaches() { if (this.clusterContainerService == null) { - log.info("un-initialized clusterContainerService, can't destroy cache"); + log.trace("un-initialized clusterContainerService, can't destroy cache"); return; } @@ -636,7 +650,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify, po = e.getValue(); if (po != null) { // Populate the Policy field now - Status poStatus = this.frm.installFlowEntry(po); + Status poStatus = this.frm.modifyOrAddFlowEntry(po); if (!poStatus.isSuccess()) { log.error("Failed to install policy: " + po.getGroupName() + " (" @@ -672,8 +686,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify, * * @return a return code that convey the programming status of the HW */ - private RulesProgrammingReturnCode uninstallPerHostRules( - HostNodeConnector host) { + private RulesProgrammingReturnCode uninstallPerHostRules(HostNodeConnector host) { RulesProgrammingReturnCode retCode = RulesProgrammingReturnCode.SUCCESS; Map pos; FlowEntry po; @@ -770,16 +783,12 @@ public class SimpleForwardingImpl implements IfNewHostNotify, for (Node swId : switches) { List pl = tobePrunedPos.get(swId); if (pl != null) { - log - .debug( - "Policies for Switch: {} in the list to be deleted: {}", - swId, pl); + log.debug("Policies for Switch: {} in the list to be deleted: {}", swId, pl); Iterator plIter = pl.iterator(); //for (Policy po: pl) { while (plIter.hasNext()) { FlowEntry po = plIter.next(); - log.error("Removing Policy, Switch: {} Policy: {}", swId, - po); + log.error("Removing Policy, Switch: {} Policy: {}", swId, po); this.frm.uninstallFlowEntry(po); plIter.remove(); } @@ -802,8 +811,7 @@ public class SimpleForwardingImpl implements IfNewHostNotify, log.debug("Host Facing Port in a container came up, install the rules for all hosts from this port !"); Set allHosts = this.hostTracker.getAllHosts(); for (HostNodeConnector host : allHosts) { - if (node.equals(host.getnodeconnectorNode()) - && swPort.equals(host.getnodeConnector())) { + if (node.equals(host.getnodeconnectorNode())) { /* * This host resides behind the same switch and port for which a port up * message is received. Ideally this should not happen, but if it does, @@ -844,8 +852,9 @@ public class SimpleForwardingImpl implements IfNewHostNotify, @Override public void notifyNode(Node node, UpdateType type, Map propMap) { - if (node == null) + if (node == null) { return; + } switch (type) { case REMOVED: @@ -860,8 +869,9 @@ public class SimpleForwardingImpl implements IfNewHostNotify, @Override public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map propMap) { - if (nodeConnector == null) + if (nodeConnector == null) { return; + } boolean up = false; switch (type) { @@ -963,4 +973,60 @@ public class SimpleForwardingImpl implements IfNewHostNotify, this.switchManager = null; } } + + @Override + public PacketResult receiveDataPacket(RawPacket inPkt) { + if (inPkt == null) { + return PacketResult.IGNORED; + } + log.trace("Received a frame of size: {}", inPkt.getPacketData().length); + Packet formattedPak = this.dataPacketService.decodeDataPacket(inPkt); + if (formattedPak instanceof Ethernet) { + Object nextPak = formattedPak.getPayload(); + if (nextPak instanceof IPv4) { + log.trace("Handle punted IP packet: {}", formattedPak); + handlePuntedIPPacket((IPv4) nextPak, inPkt.getIncomingNodeConnector()); + } + } + return PacketResult.IGNORED; + + } + + private void handlePuntedIPPacket(IPv4 pkt, NodeConnector incomingNodeConnector) { + InetAddress dIP = NetUtils.getInetAddress(pkt.getDestinationAddress()); + if (dIP == null || hostTracker == null) { + log.debug("Invalid param(s) in handlePuntedIPPacket.. DestIP: {}. hostTracker: {}", dIP, hostTracker); + return; + } + HostNodeConnector destHost = hostTracker.hostFind(dIP); + /* + * In cases when incoming and outgoing connectors are in the same node, there is no need + * to verify that there is a route. Because of that, we will only need routing.getRoute() + * if we know that src and dst nodes are different. + */ + if (destHost != null + && (incomingNodeConnector.getNode().equals(destHost.getnodeconnectorNode()) || + routing == null || + routing.getRoute(incomingNodeConnector.getNode(), destHost.getnodeconnectorNode()) != null)) { + + log.trace("Host {} is at {}", dIP, destHost.getnodeConnector()); + + // If SimpleForwarding is aware of this host, it will try to install + // a path. Forward packet until it's done. + if (dataPacketService != null) { + + /* + * if we know where the host is and there's a path from where this + * packet was punted to where the host is, then attempt best effort delivery to the host + */ + NodeConnector nc = destHost.getnodeConnector(); + log.trace("Forwarding punted IP received at {} to {}", incomingNodeConnector, nc); + // re-encode the Ethernet packet (the parent of the IPv4 packet) + RawPacket rp = this.dataPacketService.encodeDataPacket(pkt.getParent()); + rp.setOutgoingNodeConnector(nc); + this.dataPacketService.transmitDataPacket(rp); + } + + } + } }