Blew away old version of PIM to restructure. And:
1) Added packetService to register for PIM packets.
2) Added PIMPacketHandler to process PIM packets.
3) Added NetworkConfig Listener
4) Added PIMInterfaceService / PIMInterfaceManager
5) Added Process incoming hello packets to PIMInterfaceManager
6) Code Review inspired changes
Change-Id: I753880c954b9a6a91544903b613305ff9aa78cd0
diff --git a/apps/pim/src/main/java/org/onosproject/pim/cli/PIMShowCommand.java b/apps/pim/src/main/java/org/onosproject/pim/cli/PIMShowCommand.java
deleted file mode 100644
index 6bd563b..0000000
--- a/apps/pim/src/main/java/org/onosproject/pim/cli/PIMShowCommand.java
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.pim.cli;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import org.apache.karaf.shell.commands.Command;
-import org.onosproject.cli.AbstractShellCommand;
-import org.onosproject.pim.impl.PIMInterface;
-import org.onosproject.pim.impl.PIMInterfaces;
-import org.onosproject.pim.impl.PIMInterfacesCodec;
-
-import java.util.Collection;
-
-@Command(scope = "onos", name = "pim-interfaces", description = "Displays the pim interfaces")
-public class PIMShowCommand extends AbstractShellCommand {
-
- // prints either the json or cli version of the hash map connect point
- // neighbors from the PIMInterfaces class.
- @Override
- protected void execute() {
- // grab connect point neighbors hash map to send in to json encoder.
- Collection<PIMInterface> pimIntfs = PIMInterfaces.getInstance().getInterfaces();
- if (outputJson()) {
- print("%s", json(pimIntfs));
- } else {
- print(PIMInterfaces.getInstance().printInterfaces());
- }
- }
-
- private JsonNode json(Collection<PIMInterface> pimIntfs) {
- return new PIMInterfacesCodec().encode(pimIntfs, this);
- }
-
-}
\ No newline at end of file
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMApplication.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMApplication.java
new file mode 100644
index 0000000..a286726
--- /dev/null
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMApplication.java
@@ -0,0 +1,229 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pim.impl;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.Ethernet;
+import org.onlab.packet.IPv4;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.incubator.net.config.basics.ConfigException;
+import org.onosproject.incubator.net.config.basics.InterfaceConfig;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigService;
+import org.onosproject.net.flow.DefaultTrafficSelector;
+import org.onosproject.net.flow.TrafficSelector;
+import org.onosproject.net.mcast.MulticastRouteService;
+import org.onosproject.net.packet.InboundPacket;
+import org.onosproject.net.packet.PacketContext;
+import org.onosproject.net.packet.PacketProcessor;
+import org.onosproject.net.packet.PacketService;
+import org.slf4j.Logger;
+
+import java.util.Set;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * The main PIM controller class.
+ */
+@Component(immediate = true)
+public class PIMApplication {
+ private final Logger log = getLogger(getClass());
+
+ // Used to get the appId
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ // Our application ID
+ private static ApplicationId appId;
+
+ // Register to receive PIM packets, used to send packets as well
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PacketService packetService;
+
+ // Use the MulticastRouteService to manage incoming PIM Join/Prune state as well as
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected MulticastRouteService ms;
+
+ // Create an instance of the PIM packet handler
+ protected PIMPacketHandler pimPacketHandler;
+
+ // Get the network configuration updates
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigService configService;
+
+ // Access defined network (IP) interfaces
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected InterfaceService interfaceService;
+
+ // Internal class used to listen for network configuration changes
+ private InternalConfigListener configListener = new InternalConfigListener();
+
+ // Provide interfaces to the pimInterface manager as a result of Netconfig updates.
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected PIMInterfaceService pimInterfaceManager;
+
+ /**
+ * Activate the PIM component.
+ */
+ @Activate
+ public void activate() {
+
+ // Get our application ID
+ appId = coreService.registerApplication("org.onosproject.pim");
+
+ // Build the traffic selector for PIM packets
+ TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
+ selector.matchEthType(Ethernet.TYPE_IPV4);
+ selector.matchIPProtocol(IPv4.PROTOCOL_PIM);
+
+ // Use the traffic selector to tell the packet service which packets we want.
+ // PIMPacketService is an inner class defined below
+ PIMPacketProcessor processor = new PIMPacketProcessor();
+ packetService.addProcessor(processor, PacketProcessor.director(5));
+
+ // Register for notifications from the Network config & Interface services.
+ // We'll use these services to represent "PIMInterfaces"
+
+ // Get a copy of the PIM Packet Handler
+ pimPacketHandler = new PIMPacketHandler();
+
+ // Listen for network configuration changes
+ configService.addListener(configListener);
+
+ log.info("Started");
+ }
+
+ /**
+ * Deactivate the PIM component.
+ */
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+
+ /**
+ * The class that will receive PIM packets, sanitize them, determine the PIMInterface
+ * they arrived on, then forward them on to be processed by the appropriate entity.
+ */
+ public class PIMPacketProcessor implements PacketProcessor {
+ private final Logger log = getLogger(getClass());
+
+ @Override
+ public void process(PacketContext context) {
+
+ // return if this packet has already been handled
+ if (context.isHandled()) {
+ return;
+ }
+
+ // get the inbound packet
+ InboundPacket pkt = context.inPacket();
+ if (pkt == null) {
+ // problem getting the inbound pkt. Log it debug to avoid spamming log file
+ log.debug("Could not retrieve packet from context");
+ return;
+ }
+
+ // Get the ethernet header
+ Ethernet eth = pkt.parsed();
+ if (eth == null) {
+ // problem getting the ethernet pkt. Log it debug to avoid spamming log file
+ log.debug("Could not retrieve ethnernet packet from the parsed packet");
+ return;
+ }
+
+ // Get the PIM Interface the packet was received on.
+ PIMInterface pimi = pimInterfaceManager.getPIMInterface(pkt.receivedFrom());
+ if (pimi == null) {
+ log.debug("We received PIM packet from a non PIM interface: " + pkt.receivedFrom().toString());
+ return;
+ }
+
+ /*
+ * Pass the packet processing off to the PIMInterface for processing.
+ *
+ * TODO: Is it possible that PIM interface processing should move to the
+ * PIMInterfaceManager directly?
+ */
+ PIMPacketHandler ph = new PIMPacketHandler();
+ ph.processPacket(eth, pimi);
+ }
+ }
+
+ /*
+ * This class receives all events from the network config services, then hands the
+ * event off to the PIMInterfaceManager for proper handling.
+ *
+ * TODO: should this move to PIMInterfaceManager?
+ */
+ private class InternalConfigListener implements NetworkConfigListener {
+
+ @Override
+ public void event(NetworkConfigEvent event) {
+
+ log.debug(event.toString());
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ case CONFIG_UPDATED:
+
+ if (event.configClass() == InterfaceConfig.class) {
+ InterfaceConfig config = configService.getConfig(
+ (ConnectPoint) event.subject(),
+ InterfaceConfig.class);
+
+ log.debug("Got a network configuration event");
+
+ // Walk the interfaces and feed them to the PIMInterfaceManager
+ Set<Interface> intfs;
+ try {
+ intfs = config.getInterfaces();
+ for (Interface intf : intfs) {
+ pimInterfaceManager.updateInterface(intf);
+ }
+ } catch (ConfigException e) {
+ log.error(e.toString());
+ return;
+ }
+ }
+ break;
+
+ case CONFIG_REMOVED:
+ if (event.configClass() == InterfaceConfig.class) {
+ ConnectPoint cp = (ConnectPoint) event.subject();
+ //assertNotNull(cp);
+ pimInterfaceManager.deleteInterface(cp);
+ }
+ break;
+
+ case CONFIG_REGISTERED:
+ case CONFIG_UNREGISTERED:
+ default:
+ log.debug("\tWe are not handling this event type");
+ break;
+ }
+ }
+ }
+}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMComponent.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMComponent.java
deleted file mode 100644
index 1a2d6f5..0000000
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMComponent.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.pim.impl;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.core.CoreService;
-import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.config.NetworkConfigService;
-import org.onosproject.net.packet.PacketService;
-import org.slf4j.Logger;
-
-/**
- * Protocol Independent Multicast (PIM) Emulation. This component is responsible
- * for reference the services this PIM module is going to need, then initializing
- * the corresponding utility classes.
- */
-@Component(immediate = true)
-public class PIMComponent {
- private final Logger log = getLogger(getClass());
-
- // Register to receive PIM packets, used to send packets as well
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected PacketService packetService;
-
- // Get the appId
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected CoreService coreService;
-
- // Get the network configuration updates
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected NetworkConfigService configService;
-
- // Access defined network (IP) interfaces
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected InterfaceService interfaceService;
-
- private static ApplicationId appId;
-
- private PIMInterfaces pimInterfaces;
- private PIMPacketHandler pimPacketHandler;
-
- @Activate
- public void activate() {
- appId = coreService.registerApplication("org.onosproject.pim");
-
- // Initialize the Packet Handler class
- pimPacketHandler = PIMPacketHandler.getInstance();
- pimPacketHandler.initialize(packetService, appId);
-
- // Initialize the Interface class
- pimInterfaces = PIMInterfaces.getInstance();
- pimInterfaces.initialize(configService, interfaceService);
-
- log.info("Started");
- }
-
- @Deactivate
- public void deactivate() {
- PIMPacketHandler.getInstance().stop();
- log.info("Stopped");
- }
-}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java
index 5da5c2b..4d8d05e 100644
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java
@@ -17,88 +17,90 @@
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
-import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.PIM;
import org.onlab.packet.pim.PIMHello;
import org.onlab.packet.pim.PIMHelloOption;
import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.net.ConnectPoint;
import org.onosproject.net.host.InterfaceIpAddress;
import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
+import java.util.Set;
-import static com.google.common.base.Preconditions.checkNotNull;
+import static org.slf4j.LoggerFactory.getLogger;
/**
- * The PIM Interface is a wrapper around a ConnectPoint and used to provide
- * hello options values when "talking" with PIM other PIM routers.
+ * PIM Interface represents an ONOS Interface with IP & MAC addresses for
+ * a given ConnectPoint.
*/
public class PIMInterface {
- private static Logger log = LoggerFactory.getLogger("PIMInterfaces");
- // Interface from the interface subsystem
- private Interface theInterface;
+ private final Logger log = getLogger(getClass());
- // The list of PIM neighbors adjacent to this interface
- private Map<IpAddress, PIMNeighbor> neighbors = new HashMap<>();
+ private Interface onosInterface;
- // The designatedRouter for this LAN
- private PIMNeighbor designatedRouter;
+ // Our hello opt holdtime
+ private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
- // The priority we use on this ConnectPoint.
- private int priority = PIMHelloOption.DEFAULT_PRIORITY;
+ // Our hello opt prune delay
+ private int pruneDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
- // The holdtime we are sending out.
- private int holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
+ // Neighbor priority
+ private int priority = PIMHelloOption.DEFAULT_PRIORITY;
- // Then generation ID we are sending out. 0 means we need to generate a new random ID
- private int genid = PIMHelloOption.DEFAULT_GENID;
-
- // Our default prune delay
- private int prunedelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
+ // Our current genid
+ private int genid = PIMHelloOption.DEFAULT_GENID; // Needs to be assigned.
/**
- * Create a PIMInterface.
+ * Create a PIMInterface from an ONOS Interface.
*
- * @param intf the network interface configuration
+ * @param intf the ONOS Interface.
*/
public PIMInterface(Interface intf) {
-
- log.debug("Adding an interface: " + intf.toString() + "\n");
- this.theInterface = intf;
-
- // Send a hello to let our neighbors know we are alive
- sendHello();
+ onosInterface = intf;
}
/**
- * Get the PIM Interface.
+ * Return the ONOS Interface.
*
- * @return the PIM Interface
+ * @return ONOS Interface.
*/
public Interface getInterface() {
- return theInterface;
+ return this.onosInterface;
}
/**
- * Getter for our IP address.
+ * Set the ONOS Interface, it will override a previous value.
*
- * @return our IP address.
+ * @param intf ONOS Interface.
+ */
+ public PIMInterface setInterface(Interface intf) {
+ this.onosInterface = intf;
+ return this;
+ }
+
+ /**
+ * Get the set of IP Addresses associated with this interface.
+ *
+ * @return a set of Ip Addresses on this interface
+ */
+ public Set<InterfaceIpAddress> getIpAddresses() {
+ return this.onosInterface.ipAddresses();
+ }
+
+ /**
+ * Return a single "best" IP address.
+ *
+ * @return the choosen IP address or null if none
*/
public IpAddress getIpAddress() {
- if (theInterface.ipAddresses().isEmpty()) {
+ if (onosInterface.ipAddresses().isEmpty()) {
return null;
}
- // We will just assume the first interface on the list
IpAddress ipaddr = null;
- for (InterfaceIpAddress ifipaddr : theInterface.ipAddresses()) {
+ for (InterfaceIpAddress ifipaddr : onosInterface.ipAddresses()) {
ipaddr = ifipaddr.ipAddress();
break;
}
@@ -106,236 +108,87 @@
}
/**
- * Get our priority.
+ * Get the holdtime.
*
- * @return our priority.
+ * @return the holdtime
+ */
+ public short getHoldtime() {
+ return this.holdtime;
+ }
+
+ /**
+ * Get the prune delay.
+ *
+ * @return The prune delay
+ */
+ public int getPruneDelay() {
+ return this.pruneDelay;
+ }
+
+ /**
+ * Get our hello priority.
+ *
+ * @return our priority
*/
public int getPriority() {
return this.priority;
}
/**
- * Get the designated router on this connection.
+ * Get our generation ID.
*
- * @return the PIMNeighbor representing the DR
+ * @return our generation ID
*/
- public PIMNeighbor getDesignatedRouter() {
- return designatedRouter;
+ public int getGenid() {
+ return this.genid;
}
/**
- * Are we the DR on this CP?
+ * Process an incoming PIM Hello message.
*
- * @return true if we are, false if not
+ * @param ethPkt the Ethernet packet header
*/
- public boolean areWeDr() {
- return (designatedRouter != null &&
- designatedRouter.getPrimaryAddr().equals(this.getIpAddress()));
- }
+ public void processHello(Ethernet ethPkt) {
- /**
- * Return a collection of PIM Neighbors.
- *
- * @return the collection of PIM Neighbors
- */
- public Collection<PIMNeighbor> getNeighbors() {
- return this.neighbors.values();
- }
+ // We'll need to save our neighbors MAC address
+ MacAddress nbrmac = ethPkt.getSourceMAC();
- /**
- * Find the neighbor with the given IP address on this CP.
- *
- * @param ipaddr the IP address of the neighbor we are interested in
- * @return the pim neighbor if it exists
- */
- public PIMNeighbor findNeighbor(IpAddress ipaddr) {
- PIMNeighbor nbr = neighbors.get(ipaddr);
- return nbr;
- }
+ // And we'll need to save neighbors IP Address.
+ IPv4 iphdr = (IPv4) ethPkt.getPayload();
+ IpAddress srcip = IpAddress.valueOf(iphdr.getSourceAddress());
- /**
- * Add a new PIM neighbor to this list.
- *
- * @param nbr the neighbor to be added.
- */
- public void addNeighbor(PIMNeighbor nbr) {
- if (neighbors.containsKey(nbr.getPrimaryAddr())) {
-
- log.debug("We are adding a neighbor that already exists: {}", nbr.toString());
- neighbors.remove(nbr.getPrimaryAddr());
- }
- neighbors.put(nbr.getPrimaryAddr(), nbr);
- }
-
- /**
- * Remove the neighbor from our neighbor list.
- *
- * @param ipaddr the IP address of the neighbor to remove
- */
- public void removeNeighbor(IpAddress ipaddr) {
-
- if (neighbors.containsKey(ipaddr)) {
- neighbors.remove(ipaddr);
- }
- this.electDR();
- }
-
- /**
- * Remove the given neighbor from the neighbor list.
- *
- * @param nbr the nbr to be removed.
- */
- public void removeNeighbor(PIMNeighbor nbr) {
-
- neighbors.remove(nbr.getPrimaryAddr(), nbr);
- this.electDR();
- }
-
- /**
- * Elect a new DR on this ConnectPoint.
- *
- * @return the PIM Neighbor that wins
- */
- public PIMNeighbor electDR() {
-
- for (PIMNeighbor nbr : this.neighbors.values()) {
- if (this.designatedRouter == null) {
- this.designatedRouter = nbr;
- continue;
- }
-
- if (nbr.getPriority() > this.designatedRouter.getPriority()) {
- this.designatedRouter = nbr;
- continue;
- }
-
- // We could sort in ascending order
- if (this.designatedRouter.getPrimaryAddr().compareTo(nbr.getPrimaryAddr()) > 0) {
- this.designatedRouter = nbr;
- continue;
- }
- }
-
- return this.designatedRouter;
- }
-
- /**
- * Elect a new DR given the new neighbor.
- *
- * @param nbr the new neighbor to use in DR election.
- * @return the PIM Neighbor that wins DR election
- */
- public PIMNeighbor electDR(PIMNeighbor nbr) {
-
- // Make sure I have
- if (this.designatedRouter == null ||
- this.designatedRouter.getPriority() < nbr.getPriority() ||
- this.designatedRouter.getPrimaryAddr().compareTo(nbr.getPrimaryAddr()) > 0) {
- this.designatedRouter = nbr;
- }
- return this.designatedRouter;
- }
-
- /**
- * Find or create a pim neighbor with a given ip address and connect point.
- *
- * @param ipaddr of the pim neighbor
- * @param mac The mac address of our sending neighbor
- * @return an existing or new PIM neighbor
- */
- public PIMNeighbor findOrCreate(IpAddress ipaddr, MacAddress mac) {
- PIMNeighbor nbr = this.findNeighbor(ipaddr);
- if (nbr == null) {
- nbr = new PIMNeighbor(ipaddr, mac, this);
- this.addNeighbor(nbr);
- this.electDR(nbr);
- }
- return nbr;
- }
-
- /**
- * Process a hello packet received on this Interface.
- *
- * @param ethPkt the ethernet packet containing the hello message
- * @param cp the ConnectPoint of this interface
- */
- public void processHello(Ethernet ethPkt, ConnectPoint cp) {
- checkNotNull(ethPkt);
- checkNotNull(cp);
-
- MacAddress srcmac = ethPkt.getSourceMAC();
- IPv4 ip = (IPv4) ethPkt.getPayload();
- Ip4Address srcip = Ip4Address.valueOf(ip.getSourceAddress());
-
- PIM pim = (PIM) ip.getPayload();
- checkNotNull(pim);
-
- PIMHello hello = (PIMHello) pim.getPayload();
- checkNotNull(hello);
-
- PIMNeighbor nbr = this.findOrCreate(srcip, srcmac);
- if (nbr == null) {
- log.error("Could not create a neighbor for: {1}", srcip.toString());
+ PIM pimhdr = (PIM) iphdr.getPayload();
+ if (pimhdr.getPimMsgType() != PIM.TYPE_HELLO) {
+ log.error("process Hello has received a non hello packet type: " + pimhdr.getPimMsgType());
return;
}
- ConnectPoint icp = theInterface.connectPoint();
- checkNotNull(icp);
- if (!cp.equals(icp)) {
- log.error("PIM Hello message received from {} on incorrect interface {}",
- nbr.getPrimaryAddr(), this.toString());
- return;
+ // TODO: Maybe a good idea to check the checksum. Let's jump into the hello options.
+ PIMHello hello = (PIMHello) pimhdr.getPayload();
+
+ // TODO: this is about where we find or create our PIMNeighbor
+
+ boolean reElectDr = false;
+
+ // Start walking through all the hello options to handle accordingly.
+ for (PIMHelloOption opt : hello.getOptions().values()) {
+
+ // TODO: This is where we handle the options and modify the neighbor accordingly.
+ // We'll need to create the PIMNeighbor class next. Depending on what happens
+ // we may need to re-elect a DR
}
- nbr.refresh(hello);
+
+ if (reElectDr) {
+ // TODO: create an election() method and call it here with a PIMNeighbor
+ }
}
/**
- * Send a hello packet from this interface.
- */
- public void sendHello() {
- PIM pim = new PIM();
- PIMHello hello = new PIMHello();
-
- // Create a PIM Hello
- pim = new PIM();
- pim.setVersion((byte) 2);
- pim.setPIMType((byte) PIM.TYPE_HELLO);
- pim.setChecksum((short) 0);
-
- hello = new PIMHello();
- hello.createDefaultOptions();
- pim.setPayload(hello);
- hello.setParent(pim);
-
- log.debug("Sending hello: \n");
- PIMPacketHandler.getInstance().sendPacket(pim, this);
- }
-
- /**
- * prints the connectPointNeighbors list with each neighbor list.
+ * Process an incoming PIM JoinPrune message.
*
- * @return string of neighbors.
+ * @param ethPkt the Ethernet packet header.
*/
- public String printNeighbors() {
- String out = "PIM Neighbors Table: \n";
- for (PIMNeighbor nbr : this.neighbors.values()) {
- out += "\t" + nbr.toString();
- }
- return out;
- }
+ public void processJoinPrune(Ethernet ethPkt) {
- @Override
- public String toString() {
- IpAddress ipaddr = this.getIpAddress();
- String out = "PIM Neighbors: ";
- if (ipaddr != null) {
- out += "IP: " + ipaddr.toString();
- } else {
- out += "IP: *Null*";
- }
- out += "\tPR: " + String.valueOf(this.priority) + "\n";
- return out;
}
-
}
-
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceManager.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceManager.java
new file mode 100644
index 0000000..8b8e2e6
--- /dev/null
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceManager.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pim.impl;
+
+import com.google.common.collect.Maps;
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.apache.felix.scr.annotations.Service;
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.incubator.net.intf.InterfaceService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import java.util.Map;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Manages PIMInterfaces.
+ *
+ * TODO: Do we need to add a ServiceListener?
+ */
+@Component(immediate = true)
+@Service
+public class PIMInterfaceManager implements PIMInterfaceService {
+
+ private final Logger log = getLogger(getClass());
+
+ // Create ourselves a provider ID
+ private static final ProviderId PID = new ProviderId("pim", "org.onosproject.pim");
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected InterfaceService interfaceService;
+
+ // Store PIM Interfaces in a map key'd by ConnectPoint
+ private final Map<ConnectPoint, PIMInterface> pimInterfaces = Maps.newConcurrentMap();
+
+ @Activate
+ public void activate() {
+ // Query the Interface service to see if Interfaces already exist.
+ log.info("Started");
+
+ // Create PIM Interfaces for each of the existing ONOS Interfaces.
+ for (Interface intf : interfaceService.getInterfaces()) {
+ pimInterfaces.put(intf.connectPoint(), new PIMInterface(intf));
+ }
+ }
+
+ @Deactivate
+ public void deactivate() {
+ log.info("Stopped");
+ }
+
+ /**
+ * Update the ONOS Interface with the new Interface. If the PIMInterface does
+ * not exist we'll create a new one and store it.
+ *
+ * @param intf ONOS Interface.
+ */
+ @Override
+ public void updateInterface(Interface intf) {
+ ConnectPoint cp = intf.connectPoint();
+
+ log.debug("Updating Interface for " + intf.connectPoint().toString());
+ pimInterfaces.compute(cp, (k, v) -> (v == null) ?
+ new PIMInterface(intf) :
+ v.setInterface(intf));
+ }
+
+ /**
+ * Delete the PIM Interface to the corresponding ConnectPoint.
+ *
+ * @param cp The connect point associated with this interface we want to delete
+ */
+ @Override
+ public void deleteInterface(ConnectPoint cp) {
+
+ PIMInterface pi = pimInterfaces.remove(cp);
+ if (pi == null) {
+ log.warn("We've been asked to remove an interface we3 don't have: " + cp.toString());
+ return;
+ }
+ }
+
+ /**
+ * Return the PIMInterface that corresponds to the given ConnectPoint.
+ *
+ * @param cp The ConnectPoint we want to get the PIMInterface for
+ * @return The PIMInterface if it exists, NULL if it does not exist.
+ */
+ @Override
+ public PIMInterface getPIMInterface(ConnectPoint cp) {
+ PIMInterface pi = pimInterfaces.getOrDefault(cp, null);
+ if (pi == null) {
+ log.warn("We have been asked for an Interface we don't have: " + cp.toString());
+ }
+ return pi;
+ }
+}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceService.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceService.java
new file mode 100644
index 0000000..528c51d
--- /dev/null
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceService.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.pim.impl;
+
+import org.onosproject.incubator.net.intf.Interface;
+import org.onosproject.net.ConnectPoint;
+
+/**
+ * Define the PIMInterfaceService. PIM will use ONOS Interfaces to
+ * define PIM Interfaces. The PIM Application signed up as a Netconfig
+ * listener.
+ *
+ * TODO: Do we need a PIMInterfaceListenerService? Who sould listen to Interfaces changes?
+ */
+public interface PIMInterfaceService {
+
+ /**
+ * Update the corresponding PIMInterface. If the PIMInterface
+ * does not exist it will be created.
+ *
+ * @param intf ONOS Interface.
+ */
+ public void updateInterface(Interface intf);
+
+ /**
+ * Delete the PIMInterface that corresponds to the given ConnectPoint.
+ *
+ * @param cp The connect point associated with this interface.
+ */
+ public void deleteInterface(ConnectPoint cp);
+
+ /**
+ * Return the PIMInterface associated with the given ConnectPoint.
+ *
+ * @param cp The ConnectPoint we want to get the PIMInterface for.
+ * @return the PIMInterface if it exists, NULL if it does not exist.
+ */
+ public PIMInterface getPIMInterface(ConnectPoint cp);
+}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java
deleted file mode 100644
index 70ade23..0000000
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java
+++ /dev/null
@@ -1,260 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.pim.impl;
-
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
-import org.onosproject.incubator.net.config.basics.ConfigException;
-import org.onosproject.incubator.net.config.basics.InterfaceConfig;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.incubator.net.intf.InterfaceService;
-import org.onosproject.net.ConnectPoint;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.TimeUnit;
-
-import org.onosproject.net.config.NetworkConfigEvent;
-import org.onosproject.net.config.NetworkConfigListener;
-import org.onosproject.net.config.NetworkConfigService;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * PIMInterfaces is a collection of all neighbors we have received
- * PIM hello messages from. The main structure is a HashMap indexed
- * by ConnectPoint with another HashMap indexed on the PIM neighbors
- * IPAddress, it contains all PIM neighbors attached on that ConnectPoint.
- */
-public final class PIMInterfaces {
-
- private Logger log = LoggerFactory.getLogger("PIMInterfaces");
-
- private static PIMInterfaces instance = null;
-
- // Used to listen to network configuration changes
- private NetworkConfigService configService;
-
- // Used to access IP Interface definitions for our segment
- private InterfaceService interfaceService;
-
- // Internal class used to listen for network configuration changes
- private InternalConfigListener configListener = new InternalConfigListener();
-
- // This is the global container for all PIM Interfaces indexed by ConnectPoints.
- private Map<ConnectPoint, PIMInterface> interfaces = new HashMap<>();
-
- // Default hello message interval
- private int helloMessageInterval = 60;
-
- // Timer used to send hello messages on this interface
- private Timeout helloTimer;
-
- // Required by a utility class
- private PIMInterfaces() {}
-
- /**
- * Get the instance of PIMInterfaces. Create the instance if needed.
- *
- * @return PIMInterface instance
- */
- public static PIMInterfaces getInstance() {
- if (null == instance) {
- instance = new PIMInterfaces();
- }
- return instance;
- }
-
- // Initialize the services
- public void initialize(NetworkConfigService cs, InterfaceService is) {
- configService = cs;
- interfaceService = is;
-
- // Initialize interfaces if they already exist
- initInterfaces();
-
- // Listen for network config changes
- configService.addListener(configListener);
- }
-
- /**
- * Listener for network config events.
- */
- private class InternalConfigListener implements NetworkConfigListener {
-
- private void updateInterfaces(InterfaceConfig config) {
- Set<Interface> intfs;
- try {
- intfs = config.getInterfaces();
- } catch (ConfigException e) {
- log.error(e.toString());
- return;
- }
- for (Interface intf : intfs) {
- addInterface(intf);
- }
- }
-
- /**
- * Remove the PIMInterface represented by the ConnectPoint. If the
- * PIMInterface does not exist this function is a no-op.
- *
- * @param cp The connectPoint representing the PIMInterface to be removed.
- */
- private void removeInterface(ConnectPoint cp) {
- PIMInterfaces.this.removeInterface(cp);
- }
-
- @Override
- public void event(NetworkConfigEvent event) {
- switch (event.type()) {
- case CONFIG_ADDED:
- case CONFIG_UPDATED:
- log.debug("Config updated: " + event.toString() + "\n");
- if (event.configClass() == InterfaceConfig.class) {
- InterfaceConfig config =
- configService.getConfig((ConnectPoint) event.subject(), InterfaceConfig.class);
- updateInterfaces(config);
- }
- break;
- case CONFIG_REMOVED:
- if (event.configClass() == InterfaceConfig.class) {
- removeInterface((ConnectPoint) event.subject());
- }
- break;
- case CONFIG_REGISTERED:
- case CONFIG_UNREGISTERED:
- default:
- break;
- }
- }
- }
-
- // Configure interfaces if they already exist.
- private void initInterfaces() {
- Set<Interface> intfs = interfaceService.getInterfaces();
- for (Interface intf : intfs) {
- log.debug("Adding interface: " + intf.toString() + "\n");
- addInterface(intf);
- }
- }
-
- /**
- * Create a PIM Interface and add to our interfaces list.
- *
- * @param intf the interface to add
- * @return the PIMInterface
- */
- public PIMInterface addInterface(Interface intf) {
- PIMInterface pif = new PIMInterface(intf);
- interfaces.put(intf.connectPoint(), pif);
-
- // If we have added our first interface start the hello timer.
- if (interfaces.size() == 1) {
- startHelloTimer();
- }
-
- // Return this interface
- return pif;
- }
-
- /**
- * Remove the PIMInterface from the given ConnectPoint.
- *
- * @param cp the ConnectPoint indexing the PIMInterface to be removed.
- */
- public void removeInterface(ConnectPoint cp) {
- if (interfaces.containsKey(cp)) {
- interfaces.remove(cp);
- }
-
- if (interfaces.size() == 0) {
- PIMTimer.stop();
- }
- }
-
- /**
- * Return a collection of PIMInterfaces for use by the PIM Interface codec.
- *
- * @return the collection of PIMInterfaces
- */
- public Collection<PIMInterface> getInterfaces() {
- return interfaces.values();
- }
-
- /**
- * Get the PIM Interface indexed by the given ConnectPoint.
- *
- * @param cp the connect point
- * @return the PIMInterface if it exists, NULL if not
- */
- public PIMInterface getInterface(ConnectPoint cp) {
- return interfaces.get(cp);
- }
-
- /**
- * Return a string of PIMInterfaces for the cli command.
- *
- * @return a string representing PIM interfaces
- */
- public String printInterfaces() {
- String str = "";
- for (PIMInterface pi : interfaces.values()) {
- str += pi.toString();
- }
- return str;
- }
-
- /* ---------------------------------- PIM Hello Timer ----------------------------------- */
-
- /**
- * Start a new hello timer for this interface.
- */
- private void startHelloTimer() {
- helloTimer = PIMTimer.getTimer().newTimeout(
- new HelloTimer(),
- helloMessageInterval,
- TimeUnit.SECONDS);
-
- log.debug("Started Hello Timer");
- }
-
- /**
- * This inner class handles transmitting a PIM hello message on this ConnectPoint.
- */
- private final class HelloTimer implements TimerTask {
-
- HelloTimer() {
- }
-
- @Override
- public void run(Timeout timeout) throws Exception {
-
- log.debug("Running Hello Timer\n");
- // Technically we should not send all hello's in synch..
- for (PIMInterface pi : interfaces.values()) {
- pi.sendHello();
- }
-
- // restart the hello timer
- if (interfaces.size() > 0) {
- startHelloTimer();
- }
- }
- }
-}
\ No newline at end of file
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfacesCodec.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfacesCodec.java
deleted file mode 100644
index ddd7a59..0000000
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfacesCodec.java
+++ /dev/null
@@ -1,96 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.pim.impl;
-
-import com.fasterxml.jackson.databind.node.ArrayNode;
-import com.fasterxml.jackson.databind.node.ObjectNode;
-import org.onosproject.codec.CodecContext;
-import org.onosproject.codec.JsonCodec;
-
-import java.util.Collection;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * PIM neighbors Codec.
- */
-public class PIMInterfacesCodec extends JsonCodec<Collection<PIMInterface>> {
- // JSON field names
- //Return Name
- private static final String CPNBRLIST = "connect_point_list";
-
- // PIM Neightbors Fields
- private static final String IP = "ip";
- private static final String PRIORITY = "priority";
- private static final String NBRLIST = "neighbor_list";
-
- // PIM neighbor Files
- private static final String DR = "designated";
- private static final String NBR_IP = "ip";
- private static final String PR = "priority";
- private static final String HOLDTIME = "hold_time";
-
- /**
- * Encode the PIM Neighbors.
- *
- * @param cpn ConnectPoint neighbors
- * @param context encoding context
- *
- * @return Encoded neighbors used by CLI and REST
- */
- @Override
- public ObjectNode encode(Collection<PIMInterface> cpn, CodecContext context) {
- checkNotNull(cpn, "Pim Neighbors cannot be null");
-
- ObjectNode pimNbrJsonCodec = context.mapper().createObjectNode();
- ArrayNode cpnList = context.mapper().createArrayNode();
-
- for (PIMInterface pn: cpn) {
- // get the PimNeighbors Obj, contains Neighbors list
- // create the json object for a single Entry in the Neighbors list
- ObjectNode cp = context.mapper().createObjectNode();
- cp.put(IP, pn.getIpAddress().toString());
- cp.put(PRIORITY, String.valueOf(pn.getPriority()));
-
- // create the array for the neighbors list
- ArrayNode nbrsList = context.mapper().createArrayNode();
- for (PIMNeighbor nbr : pn.getNeighbors()) {
- nbrsList.add(neighbor(nbr, context));
- }
- // adds pim neighbor to list
- cp.set(NBRLIST, nbrsList);
- // adds to arraynode which will represent the connect point neighbors hash map.
- cpnList.add(cp);
- }
- pimNbrJsonCodec.set(CPNBRLIST, cpnList);
- return pimNbrJsonCodec;
- }
-
- /**
- * Encode a single PIM Neighbor.
- *
- * @param nbr the neighbor to be encoded
- * @param context encoding context
- * @return the encoded neighbor
- */
- private ObjectNode neighbor(PIMNeighbor nbr, CodecContext context) {
- return context.mapper().createObjectNode()
- .put(DR, Boolean.toString(nbr.isDr()))
- .put(NBR_IP, nbr.getPrimaryAddr().toString())
- .put(PR, String.valueOf(nbr.getPriority()))
- .put(HOLDTIME, String.valueOf(nbr.getHoldtime()));
- }
-}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMNeighbor.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMNeighbor.java
deleted file mode 100644
index 73d1598..0000000
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMNeighbor.java
+++ /dev/null
@@ -1,320 +0,0 @@
-/*
- * Copyright 2014-2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in reliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.pim.impl;
-
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
-import org.onlab.packet.IpAddress;
-import org.onlab.packet.MacAddress;
-import org.onlab.packet.pim.PIMHello;
-import org.onlab.packet.pim.PIMHelloOption;
-import org.onosproject.net.ConnectPoint;
-import org.slf4j.Logger;
-
-import java.nio.ByteBuffer;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * PIMNeighbor represents all the PIM routers that have sent us
- * hello messages, or that possibly have been statically configured.
- */
-public class PIMNeighbor {
- private final Logger log = getLogger(getClass());
-
- // The primary address of this PIM neighbor
- private IpAddress primaryAddr;
-
- // The MacAddress of this neighbor
- private MacAddress macAddress;
-
- // The ConnectPoint this PIM neighbor is connected to.
- private ConnectPoint connectPoint;
-
- // Is this neighbor us?
- private boolean isThisUs = false;
-
- // The option values this neighbor has sent us.
- private int priority = 0;
- private int genId = 0;
- private short holdtime = 0;
-
- // Is this pim neighbor the DR?
- private boolean isDr = false;
-
- // Timeout for this neighbor
- private volatile Timeout timeout;
-
- // A back pointer the neighbors list this neighbor belongs to.
- private PIMInterface pimInterface;
-
- /**
- * Construct this neighbor from the address and connect point.
- *
- * @param ipaddr IP Address of neighbor
- * @param macaddr MAC Address of the neighbor
- * @param pimInterface The PIMInterface of this neighbor
- */
- public PIMNeighbor(IpAddress ipaddr, MacAddress macaddr, PIMInterface pimInterface) {
- this.macAddress = macaddr;
- this.primaryAddr = ipaddr;
- this.pimInterface = pimInterface;
- this.resetTimeout();
- }
-
- /**
- * Get the primary address of this neighbor.
- *
- * @return the primary IP address.
- */
- public IpAddress getPrimaryAddr() {
- return primaryAddr;
- }
-
- /**
- * Set the primary address of this neighbor.
- *
- * @param primaryAddr the address we'll use when sending hello messages
- */
- public void setPrimaryAddr(IpAddress primaryAddr) {
- this.primaryAddr = primaryAddr;
- }
-
- /**
- * Get the priority this neighbor has advertised to us.
- *
- * @return the priority
- */
- public int getPriority() {
- return priority;
- }
-
- /**
- * Set the priority for this neighbor.
- *
- * @param priority This neighbors priority.
- */
- public void setPriority(int priority) {
- this.priority = priority;
- }
-
- /**
- * Get the generation ID.
- *
- * @return the generation ID.
- */
- public int getGenId() {
- return genId;
- }
-
- /**
- * Set the generation ID.
- *
- * @param genId the generation ID.
- */
- public void setGenId(int genId) {
- this.genId = genId;
- }
-
- /**
- * Get the holdtime for this neighbor.
- *
- * @return the holdtime
- */
- public short getHoldtime() {
- return holdtime;
- }
-
- /**
- * Set the holdtime for this neighbor.
- *
- * @param holdtime the holdtime.
- */
- public void setholdtime(short holdtime) {
- this.holdtime = holdtime;
- }
-
- /**
- * Is this neighbor the designated router on this connect point?
- *
- * @return true if so, false if not.
- */
- public boolean isDr() {
- return isDr;
- }
-
- /**
- * Set this router as the designated router on this connect point.
- *
- * @param isDr True is this neighbor is the DR false otherwise
- */
- public void setIsDr(boolean isDr) {
- this.isDr = isDr;
- }
-
- /**
- * The ConnectPoint this neighbor is connected to.
- *
- * @return the ConnectPoint
- */
- public PIMInterface getPimInterface() {
- return pimInterface;
- }
-
- /**
- * We have received a fresh hello from this neighbor, now we need to process it.
- * Depending on the values received in the the hello options may force a
- * re-election process.
- *
- * We will also refresh the timeout for this neighbor.
- *
- * @param hello copy of the hello we'll be able to extract options from.
- */
- public void refresh(PIMHello hello) {
- checkNotNull(hello);
-
- boolean reelect = false;
- for (PIMHelloOption opt : hello.getOptions().values()) {
-
- int len = opt.getOptLength();
- ByteBuffer bb = ByteBuffer.wrap(opt.getValue());
-
- switch (opt.getOptType()) {
- case PIMHelloOption.OPT_GENID:
- int newid = bb.getInt();
- if (this.genId != newid) {
-
- // We have a newly rebooted neighbor, this is where we would
- // send them our joins.
- this.genId = newid;
- }
- break;
-
- case PIMHelloOption.OPT_PRIORITY:
- int newpri = bb.getInt();
- if (this.priority != newpri) {
-
- // The priorities have changed. We may need to re-elect a new DR?
- if (this.isDr || pimInterface.getDesignatedRouter().getPriority() < priority) {
- reelect = true;
- }
- this.priority = newpri;
- }
- break;
-
- case PIMHelloOption.OPT_HOLDTIME:
- short holdtime = bb.getShort();
- if (this.holdtime != holdtime) {
- this.holdtime = holdtime;
- if (holdtime == 0) {
- // We have a neighbor going down. We can remove all joins
- // we have learned from them.
-
- log.debug("PIM Neighbor has timed out: {}", this.primaryAddr.toString());
- return;
- }
- }
- break;
-
- case PIMHelloOption.OPT_PRUNEDELAY:
- case PIMHelloOption.OPT_ADDRLIST:
- // TODO: implement prune delay and addr list. Fall through for now.
-
- default:
- log.debug("PIM Hello option type: {} not yet supported or unknown.", opt.getOptType());
- break;
- }
- }
-
- if (reelect) {
- pimInterface.electDR(this);
- }
-
- // Reset the next timeout timer
- this.resetTimeout();
- }
-
- /* --------------------------------------- Timer functions -------------------------- */
-
- /**
- * Restart the timeout task for this neighbor.
- */
- private void resetTimeout() {
-
- if (this.holdtime == 0) {
-
- // Prepare to die.
- log.debug("shutting down timer for nbr {}", this.primaryAddr.toString());
- if (this.timeout != null) {
- this.timeout.cancel();
- this.timeout = null;
- }
- return;
- }
-
- // Cancel the existing timeout and start a fresh new one.
- if (this.timeout != null) {
- this.timeout.cancel();
- }
-
- this.timeout = PIMTimer.getTimer().newTimeout(new NeighborTimeoutTask(this), holdtime, TimeUnit.SECONDS);
- }
-
- /**
- * The task to run when a neighbor timeout expires.
- */
- private final class NeighborTimeoutTask implements TimerTask {
- PIMNeighbor nbr;
-
- NeighborTimeoutTask(PIMNeighbor nbr) {
- this.nbr = nbr;
- }
-
- @Override
- public void run(Timeout timeout) throws Exception {
-
- log.debug("PIM Neighbor {} has timed out: ", nbr.toString());
- nbr.pimInterface.removeNeighbor(nbr);
- }
- }
-
- /**
- * Stop the timeout timer.
- *
- * This happens when we remove the neighbor.
- */
- private final void stopTimeout() {
- this.timeout.cancel();
- this.timeout = null;
- }
-
- @Override
- public String toString() {
- String out = "";
- if (this.isDr) {
- out += "*NBR:";
- } else {
- out += "NBR:";
- }
- out += "\tIP: " + this.primaryAddr.toString();
- out += "\tPr: " + String.valueOf(this.priority);
- out += "\tHoldTime: " + String.valueOf(this.holdtime);
- out += "\tGenID: " + String.valueOf(this.genId) + "\n";
- return out;
- }
-}
\ No newline at end of file
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMPacketHandler.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMPacketHandler.java
index c1ad2cf..afc57fd 100644
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMPacketHandler.java
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMPacketHandler.java
@@ -17,213 +17,74 @@
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPv4;
-import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
-import org.onlab.packet.MacAddress;
import org.onlab.packet.PIM;
-import org.onlab.packet.VlanId;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.incubator.net.intf.Interface;
-import org.onosproject.net.ConnectPoint;
-import org.onosproject.net.flow.DefaultTrafficSelector;
-import org.onosproject.net.flow.DefaultTrafficTreatment;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.TrafficTreatment;
-import org.onosproject.net.packet.DefaultOutboundPacket;
-import org.onosproject.net.packet.InboundPacket;
-import org.onosproject.net.packet.OutboundPacket;
-import org.onosproject.net.packet.PacketContext;
-import org.onosproject.net.packet.PacketPriority;
-import org.onosproject.net.packet.PacketProcessor;
-import org.onosproject.net.packet.PacketService;
import org.slf4j.Logger;
-import java.nio.ByteBuffer;
-
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
/**
- * Handing Incoming and outgoing PIM packets.
+ * This class will process PIM packets.
*/
-public final class PIMPacketHandler {
+public class PIMPacketHandler {
+
private final Logger log = getLogger(getClass());
- private static PIMPacketHandler instance = null;
-
- private PacketService packetService;
- private PIMPacketProcessor processor = new PIMPacketProcessor();
- private MacAddress pimDestinationMac = MacAddress.valueOf("01:00:5E:00:00:0d");
-
- // Utility class
- private PIMPacketHandler() {}
-
- public static PIMPacketHandler getInstance() {
- if (null == instance) {
- instance = new PIMPacketHandler();
- }
- return instance;
+ /**
+ * Constructor for this class.
+ */
+ public PIMPacketHandler() {
}
/**
- * Initialize the packet handling service.
+ * Sanitize and process the packet.
+ * TODO: replace ConnectPoint with PIMInterface when PIMInterface has been added.
*
- * @param ps the packetService
- * @param appId our application ID
+ * @param ethPkt the packet starting with the Ethernet header.
+ * @param pimi the PIM Interface the packet arrived on.
*/
- public void initialize(PacketService ps, ApplicationId appId) {
- packetService = ps;
+ public void processPacket(Ethernet ethPkt, PIMInterface pimi) {
+ checkNotNull(ethPkt);
+ checkNotNull(pimi);
- // Build a traffic selector for all multicast traffic
- TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
- selector.matchEthType(Ethernet.TYPE_IPV4);
- selector.matchIPProtocol(IPv4.PROTOCOL_PIM);
- packetService.requestPackets(selector.build(), PacketPriority.REACTIVE, appId);
-
- packetService.addProcessor(processor, PacketProcessor.director(1));
- }
-
- /**
- * Shutdown the packet handling service.
- */
- public void stop() {
- packetService.removeProcessor(processor);
- processor = null;
- }
-
- /**
- * Packet processor responsible for handling IGMP packets.
- */
- public class PIMPacketProcessor implements PacketProcessor {
- private final Logger log = getLogger(getClass());
-
- @Override
- public void process(PacketContext context) {
- // Stop processing if the packet has been handled, since we
- // can't do any more to it.
- if (context.isHandled()) {
- return;
- }
-
- InboundPacket pkt = context.inPacket();
- if (pkt == null) {
- return;
- }
-
- Ethernet ethPkt = pkt.parsed();
- if (ethPkt == null) {
- return;
- }
-
- /*
- * IPv6 MLD packets are handled by ICMP6. We'll only deal
- * with IPv4.
- */
- if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
- return;
- }
-
- IPv4 ip = (IPv4) ethPkt.getPayload();
- IpAddress gaddr = IpAddress.valueOf(ip.getDestinationAddress());
- IpAddress saddr = Ip4Address.valueOf(ip.getSourceAddress());
- log.debug("Packet (" + saddr.toString() + ", " + gaddr.toString() +
- "\tingress port: " + context.inPacket().receivedFrom().toString());
-
- if (ip.getProtocol() != IPv4.PROTOCOL_PIM) {
- log.debug("PIM Picked up a non PIM packet: IP protocol: " + ip.getProtocol());
- return;
- }
-
- // TODO: check incoming to be PIM.PIM_ADDRESS or "Our" address.
- IpPrefix spfx = IpPrefix.valueOf(saddr, 32);
- IpPrefix gpfx = IpPrefix.valueOf(gaddr, 32);
-
- PIM pim = (PIM) ip.getPayload();
- switch (pim.getPimMsgType()) {
-
- case PIM.TYPE_HELLO:
- processHello(ethPkt, context.inPacket().receivedFrom());
- break;
-
- case PIM.TYPE_JOIN_PRUNE_REQUEST:
- // Create the function
- break;
-
- case PIM.TYPE_ASSERT:
- case PIM.TYPE_BOOTSTRAP:
- case PIM.TYPE_CANDIDATE_RP_ADV:
- case PIM.TYPE_GRAFT:
- case PIM.TYPE_GRAFT_ACK:
- case PIM.TYPE_REGISTER:
- case PIM.TYPE_REGISTER_STOP:
- log.debug("Unsupported PIM message type: " + pim.getPimMsgType());
- break;
-
- default:
- log.debug("Unkown PIM message type: " + pim.getPimMsgType());
- break;
- }
+ // Sanitize the ethernet header to ensure it is IPv4. IPv6 we'll deal with later
+ if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
+ log.debug("Recieved a non IPv4 packet");
+ return;
}
- /**
- * Process incoming hello message, we will need the Macaddress and IP address of the sender.
- *
- * @param ethPkt the ethernet header
- * @param receivedFrom the connect point we recieved this message from
- */
- private void processHello(Ethernet ethPkt, ConnectPoint receivedFrom) {
- checkNotNull(ethPkt);
- checkNotNull(receivedFrom);
-
- // It is a problem if we don't have the
- PIMInterfaces pintfs = PIMInterfaces.getInstance();
- PIMInterface intf = pintfs.getInterface(receivedFrom);
- if (intf == null) {
- log.error("We received a PIM message on an interface we were not supposed to");
- return;
- }
- intf.processHello(ethPkt, receivedFrom);
- }
- }
-
- // Create an ethernet header and serialize then send
- public void sendPacket(PIM pim, PIMInterface pimIntf) {
-
- Interface theInterface = pimIntf.getInterface();
-
- // Create the ethernet packet
- Ethernet eth = new Ethernet();
- eth.setDestinationMACAddress(pimDestinationMac);
- eth.setSourceMACAddress(theInterface.mac());
- eth.setEtherType(Ethernet.TYPE_IPV4);
- if (theInterface.vlan() != VlanId.NONE) {
- eth.setVlanID(theInterface.vlan().toShort());
+ // Get the IP header
+ IPv4 ip = (IPv4) ethPkt.getPayload();
+ if (ip.getProtocol() != IPv4.PROTOCOL_PIM) {
+ log.debug("Received a non PIM IP packet");
+ return;
}
- // Create the IP Packet
- IPv4 ip = new IPv4();
- ip.setVersion((byte) 4);
- ip.setTtl((byte) 20);
- ip.setProtocol(IPv4.PROTOCOL_PIM);
- ip.setChecksum((short) 0);
- ip.setSourceAddress(checkNotNull(pimIntf.getIpAddress()).getIp4Address().toInt());
- ip.setDestinationAddress(PIM.PIM_ADDRESS.getIp4Address().toInt());
- eth.setPayload(ip);
- ip.setParent(eth);
+ // Get the address of our the neighbor that sent this packet to us.
+ IpAddress nbraddr = IpAddress.valueOf(ip.getDestinationAddress());
+ log.debug("Packet " + nbraddr.toString() + " received on port " + pimi.toString());
- // Now set pim
- ip.setPayload(pim);
- pim.setParent(ip);
+ // Get the PIM header
+ PIM pim = (PIM) ip.getPayload();
+ checkNotNull(pim);
- ConnectPoint cp = theInterface.connectPoint();
- checkNotNull(cp);
+ // Process the pim packet
+ switch (pim.getPimMsgType()) {
- TrafficTreatment treat = DefaultTrafficTreatment.builder().setOutput(cp.port()).build();
- ByteBuffer bb = ByteBuffer.wrap(eth.serialize());
- OutboundPacket packet = new DefaultOutboundPacket(cp.deviceId(), treat, bb);
- checkNotNull(packet);
+ case PIM.TYPE_HELLO:
+ pimi.processHello(ethPkt);
+ log.debug("Received a PIM hello packet");
+ break;
- packetService.emit(packet);
+ case PIM.TYPE_JOIN_PRUNE_REQUEST:
+ pimi.processJoinPrune(ethPkt);
+ log.debug("Received a PIM Join/Prune message");
+ break;
+
+ default:
+ log.debug("Recieved unsupported PIM type: " + pim.getPimMsgType());
+ break;
+ }
}
}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMTimer.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMTimer.java
deleted file mode 100644
index c2a3303..0000000
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMTimer.java
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.pim.impl;
-
-import org.jboss.netty.util.HashedWheelTimer;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-
-/**
- * PIM Timer used for PIM Neighbors.
- */
-public final class PIMTimer {
-
- private static volatile HashedWheelTimer timer;
-
- // Ban public construction
- private PIMTimer() {
- }
-
- /**
- * Returns the singleton hashed-wheel timer.
- *
- * @return hashed-wheel timer
- */
- public static HashedWheelTimer getTimer() {
- if (PIMTimer.timer == null) {
- initTimer();
- }
- return PIMTimer.timer;
- }
-
- // Start the PIM timer.
- private static synchronized void initTimer() {
- if (PIMTimer.timer == null) {
-
- // Create and start a new hashed wheel timer, if it does not exist.
- HashedWheelTimer hwTimer = new HashedWheelTimer();
- hwTimer.start();
- PIMTimer.timer = hwTimer;
- }
- }
-
- public static void start() {
- if (PIMTimer.timer == null) {
- getTimer();
- }
- checkNotNull(timer);
- timer.start();
- }
-
- public static void stop() {
- if (PIMTimer.timer == null) {
- // No need to stop
- return;
- }
- checkNotNull(timer);
- timer.stop();
- }
-}
diff --git a/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java b/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
index 793b636..fa92204 100644
--- a/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
+++ b/incubator/net/src/main/java/org/onosproject/incubator/net/meter/impl/MeterManager.java
@@ -53,7 +53,6 @@
import static org.slf4j.LoggerFactory.getLogger;
-
/**
* Provides implementation of the meter service APIs.
*/