Added configuration for PIM interfaces.
Now the PIM application requires PIM Interface configuration for each interface
that will have PIM enabled (no longer uses all ONOS interfaces). The
interface-specific PIM parameters can be tuned.
Change-Id: Ibc284fdbe1b3aa4da48097b3e92470bce4f349a7
diff --git a/apps/pim/pom.xml b/apps/pim/pom.xml
index 3973351..80283e4 100644
--- a/apps/pim/pom.xml
+++ b/apps/pim/pom.xml
@@ -82,37 +82,4 @@
</dependency>
</dependencies>
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Bundle-SymbolicName>
- ${project.groupId}.${project.artifactId}
- </Bundle-SymbolicName>
- <Import-Package>
- org.slf4j,
- org.osgi.framework,
- com.google.common.*,
- org.apache.karaf.shell.commands,
- org.apache.karaf.shell.console,
- org.onlab.packet.*,
- org.onosproject.*,
- </Import-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-compiler-plugin</artifactId>
- <configuration>
- <source>1.8</source>
- <target>1.8</target>
- </configuration>
- </plugin>
- </plugins>
- </build>
</project>
diff --git a/apps/pim/src/main/java/org/onosproject/pim/cli/PimInterfacesListCommand.java b/apps/pim/src/main/java/org/onosproject/pim/cli/PimInterfacesListCommand.java
new file mode 100644
index 0000000..c83871e
--- /dev/null
+++ b/apps/pim/src/main/java/org/onosproject/pim/cli/PimInterfacesListCommand.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2016 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 org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+import org.onosproject.pim.impl.PIMInterface;
+import org.onosproject.pim.impl.PIMInterfaceService;
+
+import java.util.Set;
+
+/**
+ * Lists the interfaces where PIM is enabled.
+ */
+@Command(scope = "onos", name = "pim-interfaces",
+ description = "Lists the interfaces where PIM is enabled")
+public class PimInterfacesListCommand extends AbstractShellCommand {
+
+ private static final String FORMAT = "interfaceName=%s, holdTime=%s, priority=%s, genId=%s";
+
+ @Override
+ protected void execute() {
+ PIMInterfaceService interfaceService = get(PIMInterfaceService.class);
+
+ Set<PIMInterface> interfaces = interfaceService.getPimInterfaces();
+
+ interfaces.forEach(
+ pimIntf -> print(FORMAT, pimIntf.getInterface().name(),
+ pimIntf.getHoldtime(), pimIntf.getPriority(),
+ pimIntf.getGenerationId()));
+ }
+
+}
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
index 6aa935e..82adfad 100644
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMApplication.java
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMApplication.java
@@ -24,14 +24,6 @@
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;
@@ -43,7 +35,6 @@
import org.slf4j.Logger;
import java.util.Optional;
-import java.util.Set;
import static org.slf4j.LoggerFactory.getLogger;
@@ -72,17 +63,6 @@
// 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;
@@ -94,7 +74,6 @@
*/
@Activate
public void activate() {
-
// Get our application ID
appId = coreService.registerApplication("org.onosproject.pim");
@@ -109,15 +88,9 @@
packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
appId, Optional.empty());
- // 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");
}
@@ -180,57 +153,4 @@
}
}
- /*
- * 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/PIMInterface.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterface.java
index 454c431..ca82052 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
@@ -34,8 +34,10 @@
import java.nio.ByteBuffer;
import java.util.HashMap;
import java.util.Map;
+import java.util.Random;
import java.util.Set;
+import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;
@@ -43,7 +45,7 @@
* PIM Interface represents an ONOS Interface with IP and MAC addresses for
* a given ConnectPoint.
*/
-public class PIMInterface {
+public final class PIMInterface {
private final Logger log = getLogger(getClass());
@@ -62,10 +64,10 @@
private int priority = PIMHelloOption.DEFAULT_PRIORITY;
// Our current genid
- private int genid = PIMHelloOption.DEFAULT_GENID; // Needs to be assigned.
+ private final int generationId;
// The IP address of the DR
- IpAddress drIpaddress;
+ private IpAddress drIpaddress;
// A map of all our PIM neighbors keyed on our neighbors IP address
private Map<IpAddress, PIMNeighbor> pimNeighbors = new HashMap<>();
@@ -74,14 +76,28 @@
* Create a PIMInterface from an ONOS Interface.
*
* @param intf the ONOS Interface.
+ * @param holdTime hold time
+ * @param priority priority
+ * @param propagationDelay propagation delay
+ * @param overrideInterval override interval
+ * @param packetService reference to the packet service
*/
- public PIMInterface(Interface intf, PacketService packetService) {
+ private PIMInterface(Interface intf,
+ short holdTime,
+ int priority,
+ short propagationDelay,
+ short overrideInterval,
+ PacketService packetService) {
+
onosInterface = intf;
outputTreatment = createOutputTreatment();
+ this.holdtime = holdTime;
this.packetService = packetService;
IpAddress ourIp = getIpAddress();
MacAddress mac = intf.mac();
+ generationId = new Random().nextInt();
+
// Create a PIM Neighbor to represent ourselves for DR election.
PIMNeighbor us = new PIMNeighbor(ourIp, mac);
@@ -178,8 +194,8 @@
*
* @return our generation ID
*/
- public int getGenid() {
- return genid;
+ public int getGenerationId() {
+ return generationId;
}
/**
@@ -188,7 +204,6 @@
* result of a newly created interface.
*/
public void sendHello() {
-
// Create the base PIM Packet and mark it a hello packet
PIMPacket pimPacket = new PIMPacket(PIM.TYPE_HELLO);
@@ -199,6 +214,9 @@
// Create the hello message with options
PIMHello hello = new PIMHello();
hello.createDefaultOptions();
+ hello.addOption(PIMHelloOption.createHoldTime(holdtime));
+ hello.addOption(PIMHelloOption.createPriority(priority));
+ hello.addOption(PIMHelloOption.createGenID(generationId));
// Now set the hello option payload
pimPacket.setPIMPayload(hello);
@@ -266,7 +284,7 @@
nbr.refreshTimestamp();
/*
- * the election method will frist determine if an election
+ * the election method will first determine if an election
* needs to be run, if so it will run the election. The
* IP address of the DR will be returned. If the IP address
* of the DR is different from what we already have we know a
@@ -280,17 +298,17 @@
}
// Run an election if we need to. Return the elected IP address.
- private IpAddress election(PIMNeighbor nbr, IpAddress drip, int drpri) {
+ private IpAddress election(PIMNeighbor nbr, IpAddress drIp, int drPriority) {
- IpAddress nbrip = nbr.getIpaddr();
- if (nbr.getPriority() > drpri) {
- return nbrip;
+ IpAddress nbrIp = nbr.getIpaddr();
+ if (nbr.getPriority() > drPriority) {
+ return nbrIp;
}
- if (nbrip.compareTo(drip) > 0) {
- return nbrip;
+ if (nbrIp.compareTo(drIp) > 0) {
+ return nbrIp;
}
- return drip;
+ return drIp;
}
/**
@@ -301,4 +319,105 @@
public void processJoinPrune(Ethernet ethPkt) {
// TODO: add Join/Prune processing code.
}
+
+ /**
+ * Returns a builder for a PIM interface.
+ *
+ * @return PIM interface builder
+ */
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ /**
+ * Builder for a PIM interface.
+ */
+ public static class Builder {
+ private Interface intf;
+ private PacketService packetService;
+ private short holdtime = PIMHelloOption.DEFAULT_HOLDTIME;
+ private int priority = PIMHelloOption.DEFAULT_PRIORITY;
+ private short propagationDelay = PIMHelloOption.DEFAULT_PRUNEDELAY;
+ private short overrideInterval = PIMHelloOption.DEFAULT_OVERRIDEINTERVAL;
+
+ /**
+ * Uses the specified ONOS interface.
+ *
+ * @param intf ONOS interface
+ * @return this PIM interface builder
+ */
+ public Builder withInterface(Interface intf) {
+ this.intf = checkNotNull(intf);
+ return this;
+ }
+
+ /**
+ * Sets the reference to the packet service.
+ *
+ * @param packetService packet service
+ * @return this PIM interface builder
+ */
+ public Builder withPacketService(PacketService packetService) {
+ this.packetService = checkNotNull(packetService);
+ return this;
+ }
+
+ /**
+ * Uses the specified hold time.
+ *
+ * @param holdTime hold time in seconds
+ * @return this PIM interface builder
+ */
+ public Builder withHoldTime(short holdTime) {
+ this.holdtime = holdTime;
+ return this;
+ }
+
+ /**
+ * Uses the specified DR priority.
+ *
+ * @param priority DR priority
+ * @return this PIM interface builder
+ */
+ public Builder withPriority(int priority) {
+ this.priority = priority;
+ return this;
+ }
+
+ /**
+ * Uses the specified propagation delay.
+ *
+ * @param propagationDelay propagation delay in ms
+ * @return this PIM interface builder
+ */
+ public Builder withPropagationDelay(short propagationDelay) {
+ this.propagationDelay = propagationDelay;
+ return this;
+ }
+
+ /**
+ * Uses the specified override interval.
+ *
+ * @param overrideInterval override interval in ms
+ * @return this PIM interface builder
+ */
+ public Builder withOverrideInterval(short overrideInterval) {
+ this.overrideInterval = overrideInterval;
+ return this;
+ }
+
+ /**
+ * Builds the PIM interface.
+ *
+ * @return PIM interface
+ */
+ public PIMInterface build() {
+ checkArgument(intf != null, "Must provide an interface");
+ checkArgument(packetService != null, "Must provide a packet service");
+
+ return new PIMInterface(intf, holdtime, priority, propagationDelay,
+ overrideInterval, packetService);
+ }
+
+ }
}
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
index 711db6c..bcaeb2c 100644
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceManager.java
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceManager.java
@@ -15,6 +15,7 @@
*/
package org.onosproject.pim.impl;
+import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
@@ -23,12 +24,20 @@
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.InterfaceEvent;
+import org.onosproject.incubator.net.intf.InterfaceListener;
import org.onosproject.incubator.net.intf.InterfaceService;
import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.config.ConfigFactory;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.packet.PacketService;
-import org.onosproject.net.provider.ProviderId;
import org.slf4j.Logger;
+
import java.util.Map;
+import java.util.Set;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -46,8 +55,8 @@
private final Logger log = getLogger(getClass());
- // Create ourselves a provider ID
- private static final ProviderId PID = new ProviderId("pim", "org.onosproject.pim");
+ private static final Class<PimInterfaceConfig> PIM_INTERFACE_CONFIG_CLASS = PimInterfaceConfig.class;
+ private static final String PIM_INTERFACE_CONFIG_KEY = "pimInterface";
// Create a Scheduled Executor service to send PIM hellos
private final ScheduledExecutorService helloScheduler =
@@ -55,43 +64,76 @@
// Wait for a bout 3 seconds before sending the initial hello messages.
// TODO: make this tunnable.
- private final long initialHelloDelay = (long) 3;
+ private final long initialHelloDelay = 3;
// Send PIM hello packets: 30 seconds.
- private final long pimHelloPeriod = (long) 30;
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected InterfaceService interfaceService;
+ private final long pimHelloPeriod = 30;
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
protected PacketService packetService;
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry networkConfig;
+
+ @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();
+ private final InternalNetworkConfigListener configListener =
+ new InternalNetworkConfigListener();
+ private final InternalInterfaceListener interfaceListener =
+ new InternalInterfaceListener();
+
+ private final ConfigFactory<ConnectPoint, PimInterfaceConfig> pimConfigFactory
+ = new ConfigFactory<ConnectPoint, PimInterfaceConfig>(
+ SubjectFactories.CONNECT_POINT_SUBJECT_FACTORY, PIM_INTERFACE_CONFIG_CLASS,
+ PIM_INTERFACE_CONFIG_KEY) {
+
+ @Override
+ public PimInterfaceConfig createConfig() {
+ return new PimInterfaceConfig();
+ }
+ };
+
@Activate
public void activate() {
- // Query the Interface service to see if Interfaces already exist.
- log.info("Started");
+ networkConfig.registerConfigFactory(pimConfigFactory);
- // Create PIM Interfaces for each of the existing ONOS Interfaces.
- for (Interface intf : interfaceService.getInterfaces()) {
- pimInterfaces.put(intf.connectPoint(), new PIMInterface(intf, packetService));
+ // Create PIM Interfaces for each of the existing configured interfaces.
+ Set<ConnectPoint> subjects = networkConfig.getSubjects(
+ ConnectPoint.class, PIM_INTERFACE_CONFIG_CLASS);
+ for (ConnectPoint cp : subjects) {
+ PimInterfaceConfig config = networkConfig.getConfig(cp, PIM_INTERFACE_CONFIG_CLASS);
+ updateInterface(config);
}
+ networkConfig.addListener(configListener);
+ interfaceService.addListener(interfaceListener);
+
// Schedule the periodic hello sender.
helloScheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
- for (PIMInterface pif : pimInterfaces.values()) {
- pif.sendHello();
+ try {
+ for (PIMInterface pif : pimInterfaces.values()) {
+ pif.sendHello();
+ }
+ } catch (Exception e) {
+ log.warn("exception", e);
}
}
}, initialHelloDelay, pimHelloPeriod, TimeUnit.SECONDS);
+
+ log.info("Started");
}
@Deactivate
public void deactivate() {
+ interfaceService.removeListener(interfaceListener);
+ networkConfig.removeListener(configListener);
+ networkConfig.unregisterConfigFactory(pimConfigFactory);
// Shutdown the periodic hello task.
helloScheduler.shutdown();
@@ -100,37 +142,6 @@
}
/**
- * 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, packetService) :
- 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
@@ -144,4 +155,115 @@
}
return pi;
}
+
+ @Override
+ public Set<PIMInterface> getPimInterfaces() {
+ return ImmutableSet.copyOf(pimInterfaces.values());
+ }
+
+ private void updateInterface(PimInterfaceConfig config) {
+ ConnectPoint cp = config.subject();
+
+ if (!config.isEnabled()) {
+ removeInterface(cp);
+ return;
+ }
+
+ String intfName = config.getInterfaceName();
+ Interface intf = interfaceService.getInterfaceByName(cp, intfName);
+
+ if (intf == null) {
+ log.debug("Interface configuration missing: {}", config.getInterfaceName());
+ return;
+ }
+
+
+ log.debug("Updating Interface for " + intf.connectPoint().toString());
+ pimInterfaces.computeIfAbsent(cp, k -> buildPimInterface(config, intf));
+ }
+
+ private void removeInterface(ConnectPoint cp) {
+ pimInterfaces.remove(cp);
+ }
+
+ private PIMInterface buildPimInterface(PimInterfaceConfig config, Interface intf) {
+ PIMInterface.Builder builder = PIMInterface.builder()
+ .withPacketService(packetService)
+ .withInterface(intf);
+
+ if (config.getHoldTime().isPresent()) {
+ builder.withHoldTime(config.getHoldTime().get());
+ }
+ if (config.getPriority().isPresent()) {
+ builder.withPriority(config.getPriority().get());
+ }
+ if (config.getPropagationDelay().isPresent()) {
+ builder.withPropagationDelay(config.getPropagationDelay().get());
+ }
+ if (config.getOverrideInterval().isPresent()) {
+ builder.withOverrideInterval(config.getOverrideInterval().get());
+ }
+
+ return builder.build();
+ }
+
+ /**
+ * Listener for network config events.
+ */
+ private class InternalNetworkConfigListener implements NetworkConfigListener {
+
+ @Override
+ public void event(NetworkConfigEvent event) {
+ if (event.configClass() != PIM_INTERFACE_CONFIG_CLASS) {
+ return;
+ }
+
+ switch (event.type()) {
+ case CONFIG_REGISTERED:
+ case CONFIG_UNREGISTERED:
+ break;
+ case CONFIG_ADDED:
+ case CONFIG_UPDATED:
+ ConnectPoint cp = (ConnectPoint) event.subject();
+ PimInterfaceConfig config = networkConfig.getConfig(
+ cp, PIM_INTERFACE_CONFIG_CLASS);
+
+ updateInterface(config);
+ break;
+ case CONFIG_REMOVED:
+ removeInterface((ConnectPoint) event.subject());
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+ /**
+ * Listener for interface events.
+ */
+ private class InternalInterfaceListener implements InterfaceListener {
+
+ @Override
+ public void event(InterfaceEvent event) {
+ switch (event.type()) {
+ case INTERFACE_ADDED:
+ PimInterfaceConfig config = networkConfig.getConfig(
+ event.subject().connectPoint(), PIM_INTERFACE_CONFIG_CLASS);
+
+ if (config != null) {
+ updateInterface(config);
+ }
+ break;
+ case INTERFACE_UPDATED:
+ break;
+ case INTERFACE_REMOVED:
+ removeInterface(event.subject().connectPoint());
+ break;
+ default:
+ break;
+
+ }
+ }
+ }
}
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
index 528c51d..53db001 100644
--- a/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceService.java
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaceService.java
@@ -15,9 +15,10 @@
*/
package org.onosproject.pim.impl;
-import org.onosproject.incubator.net.intf.Interface;
import org.onosproject.net.ConnectPoint;
+import java.util.Set;
+
/**
* Define the PIMInterfaceService. PIM will use ONOS Interfaces to
* define PIM Interfaces. The PIM Application signed up as a Netconfig
@@ -28,25 +29,17 @@
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);
+
+ /**
+ * Retrieves the set of all interfaces running PIM.
+ *
+ * @return set of PIM interfaces
+ */
+ Set<PIMInterface> getPimInterfaces();
}
diff --git a/apps/pim/src/main/java/org/onosproject/pim/impl/PimInterfaceConfig.java b/apps/pim/src/main/java/org/onosproject/pim/impl/PimInterfaceConfig.java
new file mode 100644
index 0000000..8d8ad78
--- /dev/null
+++ b/apps/pim/src/main/java/org/onosproject/pim/impl/PimInterfaceConfig.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2016 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.net.ConnectPoint;
+import org.onosproject.net.config.Config;
+
+import java.util.Optional;
+
+/**
+ * Configuration for a PIM interface.
+ */
+public class PimInterfaceConfig extends Config<ConnectPoint> {
+
+ private static final String INTERFACE_NAME = "interfaceName";
+ private static final String ENABLED = "enabled";
+ private static final String HOLD_TIME = "holdTime";
+ private static final String PRIORITY = "priority";
+ private static final String PROPAGATION_DELAY = "propagationDelay";
+ private static final String OVERRIDE_INTERVAL = "overrideInterval";
+
+ /**
+ * Gets the name of the interface. This links the PIM configuration with
+ * an existing ONOS interface.
+ *
+ * @return interface name
+ */
+ public String getInterfaceName() {
+ return node.path(INTERFACE_NAME).asText();
+ }
+
+ /**
+ * Returns whether PIM is enabled on the interface or not.
+ *
+ * @return true if PIM is enabled, otherwise false
+ */
+ public boolean isEnabled() {
+ return node.path(ENABLED).asBoolean(false);
+ }
+
+ /**
+ * Gets the HELLO hold time of the interface.
+ *
+ * @return hold time
+ */
+ public Optional<Short> getHoldTime() {
+ if (node.path(HOLD_TIME).isMissingNode()) {
+ return Optional.empty();
+ }
+ return Optional.of(Short.parseShort(node.path(HOLD_TIME).asText()));
+ }
+
+ /**
+ * Gets the priority of the interface.
+ *
+ * @return priority
+ */
+ public Optional<Integer> getPriority() {
+ if (node.path(PRIORITY).isMissingNode()) {
+ return Optional.empty();
+ }
+ return Optional.of(node.path(PRIORITY).asInt());
+ }
+
+ /**
+ * Gets the propagation delay of the interface.
+ *
+ * @return propagation delay
+ */
+ public Optional<Short> getPropagationDelay() {
+ if (node.path(PROPAGATION_DELAY).isMissingNode()) {
+ return Optional.empty();
+ }
+ return Optional.of(Short.parseShort(node.path(PROPAGATION_DELAY).asText()));
+ }
+
+ /**
+ * Gets the override interval of the interface.
+ *
+ * @return override interval
+ */
+ public Optional<Short> getOverrideInterval() {
+ if (node.path(OVERRIDE_INTERVAL).isMissingNode()) {
+ return Optional.empty();
+ }
+ return Optional.of(Short.parseShort(node.path(OVERRIDE_INTERVAL).asText()));
+ }
+}
diff --git a/apps/pim/src/main/resources/OSGI-INF.blueprint/shell-config.xml b/apps/pim/src/main/resources/OSGI-INF/blueprint/shell-config.xml
similarity index 91%
rename from apps/pim/src/main/resources/OSGI-INF.blueprint/shell-config.xml
rename to apps/pim/src/main/resources/OSGI-INF/blueprint/shell-config.xml
index c30e379..780ad9f 100644
--- a/apps/pim/src/main/resources/OSGI-INF.blueprint/shell-config.xml
+++ b/apps/pim/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -17,7 +17,7 @@
<command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
<command>
- <action class="org.onosproject.pim.cli.PIMShowCommand"/>
+ <action class="org.onosproject.pim.cli.PimInterfacesListCommand"/>
</command>
</command-bundle>
diff --git a/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java b/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java
index 7d05d92..2372e1a 100644
--- a/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java
+++ b/utils/misc/src/main/java/org/onlab/packet/pim/PIMHelloOption.java
@@ -23,29 +23,43 @@
import static org.onlab.packet.PacketUtils.checkBufferLength;
import static org.onlab.packet.PacketUtils.checkInput;
+/**
+ * PIM HELLO option.
+ */
public class PIMHelloOption {
- /**
+ /*
* PIM Option types.
*/
public static final short OPT_HOLDTIME = 1;
- public static final short OPT_PRUNEDELAY = 2;
- public static final short OPT_PRIORITY = 19;
- public static final short OPT_GENID = 20;
- public static final short OPT_ADDRLIST = 24;
-
+ public static final short HOLDTIME_LENGTH = 2;
public static final short DEFAULT_HOLDTIME = 105;
- public static final int DEFAULT_PRUNEDELAY = 2000; // 2,000 ms
+
+ public static final short OPT_PRUNEDELAY = 2;
+ public static final short PRUNEDELAY_LENGTH = 4;
+ public static final short DEFAULT_PRUNEDELAY = 500; // 500 ms
+ public static final short DEFAULT_OVERRIDEINTERVAL = 2500; // 2500 ms
+
+ public static final short OPT_PRIORITY = 19;
+ public static final short PRIORITY_LENGTH = 4;
public static final int DEFAULT_PRIORITY = 1;
+
+ public static final short OPT_GENID = 20;
+ public static final short GENID_LENGTH = 4;
public static final int DEFAULT_GENID = 0;
+ public static final short OPT_ADDRLIST = 24;
+
public static final int MINIMUM_OPTION_LEN_BYTES = 4;
// Values for this particular hello option.
- private short optType;
- private short optLength;
+ private short optType = 0;
+ private short optLength = 0;
private byte[] optValue;
+ /**
+ * Constructs a new hello option with no fields set.
+ */
public PIMHelloOption() {
}
@@ -59,25 +73,25 @@
this.optType = type;
switch (type) {
case OPT_HOLDTIME:
- this.optLength = 2;
+ this.optLength = HOLDTIME_LENGTH;
this.optValue = new byte[optLength];
ByteBuffer.wrap(this.optValue).putShort(PIMHelloOption.DEFAULT_HOLDTIME);
break;
case OPT_PRUNEDELAY:
- this.optLength = 4;
+ this.optLength = PRUNEDELAY_LENGTH;
this.optValue = new byte[this.optLength];
ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRUNEDELAY);
break;
case OPT_PRIORITY:
- this.optLength = 4;
+ this.optLength = PRIORITY_LENGTH;
this.optValue = new byte[this.optLength];
ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_PRIORITY);
break;
case OPT_GENID:
- this.optLength = 4;
+ this.optLength = GENID_LENGTH;
this.optValue = new byte[this.optLength];
ByteBuffer.wrap(this.optValue).putInt(PIMHelloOption.DEFAULT_GENID);
break;
@@ -109,17 +123,85 @@
return this.optLength;
}
- public void setValue(ByteBuffer bb) throws DeserializationException {
+ public void setValue(ByteBuffer bb) {
this.optValue = new byte[this.optLength];
bb.get(this.optValue, 0, this.optLength);
}
+ public void setValue(byte[] value) {
+ this.optValue = value;
+ }
+
public byte[] getValue() {
return this.optValue;
}
+ /**
+ * Creates a new PIM Hello option with the specified values.
+ *
+ * @param type hello option type
+ * @param length option length
+ * @param value option value
+ * @return new PIM Hello option
+ */
+ public static PIMHelloOption create(short type, short length, ByteBuffer value) {
+ PIMHelloOption option = new PIMHelloOption();
+ option.setOptType(type);
+ option.setOptLength(length);
+ value.rewind();
+ option.setValue(value);
+ return option;
+ }
+
+ /**
+ * Creates a new priority option.
+ *
+ * @param priority priority
+ * @return priority option
+ */
+ public static PIMHelloOption createPriority(int priority) {
+ return create(OPT_PRIORITY, PRIORITY_LENGTH,
+ ByteBuffer.allocate(PRIORITY_LENGTH).putInt(priority));
+ }
+
+ /**
+ * Creates a new hold time option.
+ *
+ * @param holdTime hold time
+ * @return hold time option
+ */
+ public static PIMHelloOption createHoldTime(short holdTime) {
+ return create(OPT_HOLDTIME, HOLDTIME_LENGTH,
+ ByteBuffer.allocate(HOLDTIME_LENGTH).putShort(holdTime));
+ }
+
+ /**
+ * Creates a new generation ID option with a particular generation ID.
+ *
+ * @param genId generation ID value
+ * @return generation ID option
+ */
+ public static PIMHelloOption createGenID(int genId) {
+ return create(OPT_GENID, GENID_LENGTH,
+ ByteBuffer.allocate(GENID_LENGTH).putInt(genId));
+ }
+
+ /**
+ * Creates a new LAN Prune Delay option.
+ *
+ * @param propagationDelay prune delay
+ * @param overrideInterval override interval
+ * @return prune delay option
+ */
+ public static PIMHelloOption createPruneDelay(short propagationDelay, short overrideInterval) {
+ return create(OPT_PRUNEDELAY, PRUNEDELAY_LENGTH,
+ ByteBuffer.allocate(PRUNEDELAY_LENGTH)
+ .putShort(propagationDelay)
+ .putShort(overrideInterval));
+ }
+
public static PIMHelloOption deserialize(ByteBuffer bb) throws DeserializationException {
- checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), 4);
+ checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), MINIMUM_OPTION_LEN_BYTES);
PIMHelloOption opt = new PIMHelloOption();
opt.setOptType(bb.getShort());
@@ -132,7 +214,7 @@
}
public byte[] serialize() {
- int len = 4 + this.optLength;
+ int len = MINIMUM_OPTION_LEN_BYTES + this.optLength;
ByteBuffer bb = ByteBuffer.allocate(len);
bb.putShort(this.optType);
bb.putShort(this.optLength);