Couple of changes for the BGP Router project:
1. Link Discovery can be turned off completely via configuration
2. PacketService allows applications to hint at table_type when registering for packets

Change-Id: I89f0bbf84dce1b449db5af19868f83503c44f750
diff --git a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java
index 774ede4..2dab132 100644
--- a/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java
+++ b/apps/bgprouter/src/main/java/org/onosproject/bgprouter/TunnellingConnectivityManager.java
@@ -23,6 +23,7 @@
 import org.onosproject.net.ConnectPoint;
 import org.onosproject.net.flow.DefaultTrafficSelector;
 import org.onosproject.net.flow.DefaultTrafficTreatment;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.packet.DefaultOutboundPacket;
@@ -73,7 +74,7 @@
         selector.matchTcpSrc(BGP_PORT);
 
         packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
-                                     appId);
+                                     appId, FlowRule.Type.ACL);
 
         selector = DefaultTrafficSelector.builder();
 
@@ -83,7 +84,7 @@
         selector.matchTcpDst(BGP_PORT);
 
         packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
-                                     appId);
+                                     appId, FlowRule.Type.ACL);
     }
 
     public void stop() {
diff --git a/core/api/src/main/java/org/onosproject/net/packet/PacketService.java b/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
index c6d6837..f9e20a1 100644
--- a/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
+++ b/core/api/src/main/java/org/onosproject/net/packet/PacketService.java
@@ -16,6 +16,7 @@
 package org.onosproject.net.packet;
 
 import org.onosproject.core.ApplicationId;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 
 /**
@@ -58,6 +59,22 @@
     void requestPackets(TrafficSelector selector, PacketPriority priority,
                         ApplicationId appId);
 
+    /**
+     * Requests that packets matching the given selector are punted from the
+     * dataplane to the controller. Clients of the PacketService should use
+     * this call to hint at the tableType in the dataplane valid for the selector.
+     *
+     * @param selector the traffic selector used to match packets
+     * @param priority the priority of the rule
+     * @param appId the application ID of the requester
+     * @param tableType the abstract table Type in the dataplane where flowrules
+     *                  should be inserted to punt the selector packets to the
+     *                  control plane
+     */
+    void requestPackets(TrafficSelector selector, PacketPriority priority,
+                        ApplicationId appId, FlowRule.Type tableType);
+
+
     // TODO add API to allow applications to revoke requests when they deactivate
 
     /**
diff --git a/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java b/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
index 6e97c8f..1bc918c 100644
--- a/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
+++ b/core/net/src/main/java/org/onosproject/net/packet/impl/PacketManager.java
@@ -88,12 +88,14 @@
         private final TrafficSelector selector;
         private final PacketPriority priority;
         private final ApplicationId appId;
+        private final FlowRule.Type tableType;
 
         public PacketRequest(TrafficSelector selector, PacketPriority priority,
-                             ApplicationId appId) {
+                             ApplicationId appId, FlowRule.Type tableType) {
             this.selector = selector;
             this.priority = priority;
             this.appId = appId;
+            this.tableType = tableType;
         }
 
         public TrafficSelector selector() {
@@ -108,6 +110,10 @@
             return appId;
         }
 
+        public FlowRule.Type tableType() {
+            return tableType;
+        }
+
         @Override
         public boolean equals(Object o) {
             if (this == o) {
@@ -170,7 +176,22 @@
         checkNotNull(appId, "Application ID cannot be null");
 
         PacketRequest request =
-                new PacketRequest(selector, priority, appId);
+                new PacketRequest(selector, priority, appId, FlowRule.Type.DEFAULT);
+
+        packetRequests.add(request);
+        pushToAllDevices(request);
+    }
+
+    @Override
+    public void requestPackets(TrafficSelector selector, PacketPriority priority,
+                               ApplicationId appId, FlowRule.Type tableType) {
+        checkNotNull(selector, "Selector cannot be null");
+        checkNotNull(appId, "Application ID cannot be null");
+        checkNotNull(tableType, "Table Type cannot be null. For requesting packets +"
+                + "without table hints, use other methods in the packetService API");
+
+        PacketRequest request =
+                new PacketRequest(selector, priority, appId, tableType);
 
         packetRequests.add(request);
         pushToAllDevices(request);
@@ -204,7 +225,7 @@
                                 treatment,
                                 request.priority().priorityValue(),
                                 request.appId(),
-                                0, true);
+                                0, true, request.tableType());
 
         flowService.applyFlowRules(flow);
     }
diff --git a/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java b/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
index 7152ad9..03276941 100644
--- a/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
+++ b/core/net/src/test/java/org/onosproject/net/host/impl/HostMonitorTest.java
@@ -47,6 +47,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
@@ -266,6 +267,12 @@
         public void requestPackets(TrafficSelector selector,
                                    PacketPriority priority, ApplicationId appId) {
         }
+
+        @Override
+        public void requestPackets(TrafficSelector selector,
+                                   PacketPriority priority, ApplicationId appId,
+                                   FlowRule.Type tableType) {
+        }
     }
 
     class TestDeviceService extends DeviceServiceAdapter {
diff --git a/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java b/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
index ca218c6..6d90971 100644
--- a/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
+++ b/core/net/src/test/java/org/onosproject/net/proxyarp/impl/ProxyArpManagerTest.java
@@ -51,6 +51,7 @@
 import org.onosproject.net.PortNumber;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceService;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.instructions.Instruction;
 import org.onosproject.net.flow.instructions.Instructions.OutputInstruction;
@@ -592,5 +593,11 @@
         public void requestPackets(TrafficSelector selector,
                                    PacketPriority priority, ApplicationId appId) {
         }
+
+        @Override
+        public void requestPackets(TrafficSelector selector,
+                                   PacketPriority priority, ApplicationId appId,
+                                   FlowRule.Type tableType) {
+        }
     }
 }
diff --git a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
index 62eceda..fde80ed 100644
--- a/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
+++ b/openflow/drivers/src/main/java/org/onosproject/openflow/drivers/OFCorsaSwitchDriver.java
@@ -55,7 +55,7 @@
 
     @Override
     public void write(List<OFMessage> msgs) {
-            channel.write(msgs);
+        channel.write(msgs);
     }
 
     @Override
diff --git a/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java b/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
index 264465e..86c9c4c 100644
--- a/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
+++ b/providers/host/src/test/java/org/onosproject/provider/host/impl/HostLocationProviderTest.java
@@ -61,6 +61,7 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.host.HostDescription;
@@ -287,6 +288,12 @@
         public void requestPackets(TrafficSelector selector,
                                    PacketPriority priority, ApplicationId appId) {
         }
+
+        @Override
+        public void requestPackets(TrafficSelector selector,
+                                   PacketPriority priority, ApplicationId appId,
+                                   FlowRule.Type tableType) {
+        }
     }
 
 
diff --git a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java
index 9350410..a855d5a 100644
--- a/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java
+++ b/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LLDPLinkProvider.java
@@ -73,7 +73,7 @@
 public class LLDPLinkProvider extends AbstractProvider implements LinkProvider {
 
     private static final String PROP_USE_BDDP = "useBDDP";
-
+    private static final String PROP_DISABLE_LD = "disableLinkDiscovery";
     private static final String PROP_LLDP_SUPPRESSION = "lldpSuppression";
 
     private static final String DEFAULT_LLDP_SUPPRESSION_CONFIG = "../config/lldp_suppression.json";
@@ -99,14 +99,16 @@
 
     private ScheduledExecutorService executor;
 
-    @Property(name = PROP_USE_BDDP, boolValue = true,
-            label = "use BDDP for link discovery")
+    @Property(name = PROP_USE_BDDP, label = "use BDDP for link discovery")
     private boolean useBDDP = true;
 
+    @Property(name = PROP_DISABLE_LD, label = "permanently disable link discovery")
+    private boolean disableLD = false;
+
     private static final long INIT_DELAY = 5;
     private static final long DELAY = 5;
 
-    @Property(name = PROP_LLDP_SUPPRESSION, value = DEFAULT_LLDP_SUPPRESSION_CONFIG,
+    @Property(name = PROP_LLDP_SUPPRESSION,
             label = "Path to LLDP suppression configuration file")
     private String filePath = DEFAULT_LLDP_SUPPRESSION_CONFIG;
 
@@ -128,11 +130,16 @@
     }
 
     @Activate
-    public void activate() {
+    public void activate(ComponentContext context) {
         appId =
             coreService.registerApplication("org.onosproject.provider.lldp");
 
-        loadSuppressionRules();
+        // to load configuration at startup
+        modified(context);
+        if (disableLD) {
+            log.info("Link Discovery has been permanently disabled by configuration");
+            return;
+        }
 
         providerService = providerRegistry.register(this);
         deviceService.addListener(listener);
@@ -170,6 +177,9 @@
 
     @Deactivate
     public void deactivate() {
+        if (disableLD) {
+            return;
+        }
         executor.shutdownNow();
         for (LinkDiscovery ld : discoverers.values()) {
             ld.stop();
@@ -186,21 +196,22 @@
     @Modified
     public void modified(ComponentContext context) {
         if (context == null) {
+            loadSuppressionRules();
             return;
         }
         @SuppressWarnings("rawtypes")
         Dictionary properties = context.getProperties();
 
-        String s = (String) properties.get(PROP_USE_BDDP);
-        if (Strings.isNullOrEmpty(s)) {
-            useBDDP = true;
-        } else {
+        String s = (String) properties.get(PROP_DISABLE_LD);
+        if (!Strings.isNullOrEmpty(s)) {
+            disableLD = Boolean.valueOf(s);
+        }
+        s = (String) properties.get(PROP_USE_BDDP);
+        if (!Strings.isNullOrEmpty(s)) {
             useBDDP = Boolean.valueOf(s);
         }
         s = (String) properties.get(PROP_LLDP_SUPPRESSION);
-        if (Strings.isNullOrEmpty(s)) {
-            filePath = DEFAULT_LLDP_SUPPRESSION_CONFIG;
-        } else {
+        if (!Strings.isNullOrEmpty(s)) {
             filePath = s;
         }
 
@@ -210,6 +221,7 @@
     private void loadSuppressionRules() {
         SuppressionRulesStore store = new SuppressionRulesStore(filePath);
         try {
+            log.info("Reading suppression rules from {}", filePath);
             rules = store.read();
         } catch (IOException e) {
             log.info("Failed to load {}, using built-in rules", filePath);
diff --git a/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java b/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java
index b48af6a..f7be862 100644
--- a/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java
+++ b/providers/lldp/src/test/java/org/onosproject/provider/lldp/impl/LLDPLinkProviderTest.java
@@ -55,6 +55,7 @@
 import org.onosproject.net.device.DeviceEvent;
 import org.onosproject.net.device.DeviceListener;
 import org.onosproject.net.device.DeviceServiceAdapter;
+import org.onosproject.net.flow.FlowRule;
 import org.onosproject.net.flow.TrafficSelector;
 import org.onosproject.net.flow.TrafficTreatment;
 import org.onosproject.net.link.LinkDescription;
@@ -116,7 +117,7 @@
         provider.masterService = masterService;
 
 
-        provider.activate();
+        provider.activate(null);
     }
 
     @Test
@@ -211,6 +212,7 @@
 
     }
 
+    @SuppressWarnings(value = { "unused" })
     private DeviceEvent portEvent(DeviceEvent.Type type, DeviceId did, PortNumber port) {
         return new  DeviceEvent(type, deviceService.getDevice(did),
                                 deviceService.getPort(did, port));
@@ -400,6 +402,12 @@
         public void requestPackets(TrafficSelector selector,
                                    PacketPriority priority, ApplicationId appId) {
         }
+
+        @Override
+        public void requestPackets(TrafficSelector selector,
+                                   PacketPriority priority, ApplicationId appId,
+                                   FlowRule.Type tableType) {
+        }
     }
 
     private class TestDeviceService extends DeviceServiceAdapter {
diff --git a/tools/package/etc/org.onosproject.provider.lldp.impl.LLDPLinkProvider.cfg b/tools/package/etc/org.onosproject.provider.lldp.impl.LLDPLinkProvider.cfg
new file mode 100644
index 0000000..12f126b
--- /dev/null
+++ b/tools/package/etc/org.onosproject.provider.lldp.impl.LLDPLinkProvider.cfg
@@ -0,0 +1,21 @@
+# Sample configuration for link discovery
+# Note that the current file location (onos/tools/package/etc) is required for packaging onos and launching it in another location.
+# If you are launching onos locally, this configuration file would be placed at: $(KARAF_ROOT)/etc
+
+#
+# Disable Link Dicovery Permanently (Note: changing this property at runtime will have NO effect)
+# WARNING: This should only be used for special projects like bgprouter, where ONOS is controlling
+# a single switch
+#
+#disableLinkDiscovery = true
+
+#
+# Enable Broadcast Discovery Protocol (EthType=0x8942)
+#
+#useBDDP = false
+
+#
+# Disable LLDP's received from specific devices
+# Details of the devices are in the file configured below
+#
+#lldpSuppression = ../config/lldp_suppresion.json