diff options
Diffstat (limited to 'framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java')
-rw-r--r-- | framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java b/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java new file mode 100644 index 00000000..e33d5aa1 --- /dev/null +++ b/framework/src/onos/apps/pim/src/main/java/org/onosproject/pim/impl/PIMInterfaces.java @@ -0,0 +1,260 @@ +/* + * 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) { + 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 |