Merge branch 'dev/murrelet' of ssh://gerrit.onosproject.org:29418/onos into dev/murrelet
diff --git a/apps/configsync-netconf/pom.xml b/apps/configsync-netconf/pom.xml
index 068d732..98e3868 100644
--- a/apps/configsync-netconf/pom.xml
+++ b/apps/configsync-netconf/pom.xml
@@ -62,7 +62,7 @@
 
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${onos.version}</version>
         </dependency>
 
diff --git a/apps/netconf/client/pom.xml b/apps/netconf/client/pom.xml
index 37f94ce..50de210 100644
--- a/apps/netconf/client/pom.xml
+++ b/apps/netconf/client/pom.xml
@@ -64,7 +64,7 @@
 
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${onos.version}</version>
         </dependency>
 
diff --git a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
index 9f91712..bbbbc3c 100644
--- a/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
+++ b/apps/segmentrouting/src/main/java/org/onosproject/segmentrouting/McastHandler.java
@@ -253,7 +253,7 @@
         }
 
         // Process the ingress device
-        addFilterToDevice(source.deviceId(), source.port(), assignedVlan(source));
+        addFilterToDevice(source.deviceId(), source.port(), assignedVlan(source), mcastIp);
 
         // When source and sink are on the same device
         if (source.deviceId().equals(sink.deviceId())) {
@@ -277,7 +277,7 @@
             links.forEach(link -> {
                 addPortToDevice(link.src().deviceId(), link.src().port(), mcastIp,
                         assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
-                addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null));
+                addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null), mcastIp);
             });
 
             // Process the egress device
@@ -344,7 +344,7 @@
                     links.forEach(link -> {
                         addPortToDevice(link.src().deviceId(), link.src().port(), mcastIp,
                                 assignedVlan(link.src().deviceId().equals(source.deviceId()) ? source : null));
-                        addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null));
+                        addFilterToDevice(link.dst().deviceId(), link.dst().port(), assignedVlan(null), mcastIp);
                     });
                     // Setup new transit mcast role
                     mcastRoleStore.put(new McastStoreKey(mcastIp,
@@ -365,7 +365,7 @@
      * @param port ingress port number
      * @param assignedVlan assigned VLAN ID
      */
-    private void addFilterToDevice(DeviceId deviceId, PortNumber port, VlanId assignedVlan) {
+    private void addFilterToDevice(DeviceId deviceId, PortNumber port, VlanId assignedVlan, IpAddress mcastIp) {
         // Do nothing if the port is configured as suppressed
         ConnectPoint connectPoint = new ConnectPoint(deviceId, port);
         SegmentRoutingAppConfig appConfig = srManager.cfgService
@@ -376,7 +376,7 @@
         }
 
         FilteringObjective.Builder filtObjBuilder =
-                filterObjBuilder(deviceId, port, assignedVlan);
+                filterObjBuilder(deviceId, port, assignedVlan, mcastIp);
         ObjectiveContext context = new DefaultObjectiveContext(
                 (objective) -> log.debug("Successfully add filter on {}/{}, vlan {}",
                         deviceId, port.toLong(), assignedVlan),
@@ -596,9 +596,17 @@
     private ForwardingObjective.Builder fwdObjBuilder(IpAddress mcastIp,
             VlanId assignedVlan, int nextId) {
         TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
-        IpPrefix mcastPrefix = IpPrefix.valueOf(mcastIp, IpPrefix.MAX_INET_MASK_LENGTH);
-        sbuilder.matchEthType(Ethernet.TYPE_IPV4);
-        sbuilder.matchIPDst(mcastPrefix);
+        IpPrefix mcastPrefix = mcastIp.toIpPrefix();
+
+        if (mcastIp.isIp4()) {
+            sbuilder.matchEthType(Ethernet.TYPE_IPV4);
+            sbuilder.matchIPDst(mcastPrefix);
+        } else {
+            sbuilder.matchEthType(Ethernet.TYPE_IPV6);
+            sbuilder.matchIPv6Dst(mcastPrefix);
+        }
+
+
         TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
         metabuilder.matchVlanId(assignedVlan);
 
@@ -621,14 +629,22 @@
      * @return filtering objective builder
      */
     private FilteringObjective.Builder filterObjBuilder(DeviceId deviceId, PortNumber ingressPort,
-            VlanId assignedVlan) {
+            VlanId assignedVlan, IpAddress mcastIp) {
         FilteringObjective.Builder filtBuilder = DefaultFilteringObjective.builder();
-        filtBuilder.withKey(Criteria.matchInPort(ingressPort))
-                .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
-                        MacAddress.IPV4_MULTICAST_MASK))
-                .addCondition(Criteria.matchVlanId(egressVlan()))
-                .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
 
+        if (mcastIp.isIp4()) {
+            filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+            .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV4_MULTICAST,
+                    MacAddress.IPV4_MULTICAST_MASK))
+            .addCondition(Criteria.matchVlanId(egressVlan()))
+            .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+        } else {
+            filtBuilder.withKey(Criteria.matchInPort(ingressPort))
+            .addCondition(Criteria.matchEthDstMasked(MacAddress.IPV6_MULTICAST,
+                     MacAddress.IPV6_MULTICAST_MASK))
+            .addCondition(Criteria.matchVlanId(egressVlan()))
+            .withPriority(SegmentRoutingService.DEFAULT_PRIORITY);
+        }
         TrafficTreatment tt = DefaultTrafficTreatment.builder()
                 .pushVlan().setVlanId(assignedVlan).build();
         filtBuilder.withMeta(tt);
diff --git a/drivers/bmv2/BUCK b/drivers/bmv2/BUCK
index b13a673..d9b09bb 100644
--- a/drivers/bmv2/BUCK
+++ b/drivers/bmv2/BUCK
@@ -14,7 +14,6 @@
 BUNDLES = [
     ':onos-drivers-bmv2',
     '//incubator/bmv2/model:onos-incubator-bmv2-model',
-    '//drivers/default:onos-drivers-default',
 ]
 
 osgi_jar(
@@ -29,9 +28,6 @@
     description = 'Adds support for BMv2 P4 devices.',
     included_bundles = BUNDLES,
     required_apps = [
-        'org.onosproject.generaldeviceprovider',
-        'org.onosproject.protocols.p4runtime',
-        'org.onosproject.p4runtime',
-        'org.onosproject.drivers.p4runtime'
+        'org.onosproject.drivers.p4runtime',
     ],
-)
+)
\ No newline at end of file
diff --git a/drivers/cisco/netconf/features.xml b/drivers/cisco/netconf/features.xml
index 49f4884..9d4a490 100644
--- a/drivers/cisco/netconf/features.xml
+++ b/drivers/cisco/netconf/features.xml
@@ -23,6 +23,6 @@
         <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
 
         <bundle>mvn:${project.groupId}/onos-drivers-utilities/${project.version}</bundle>
-        <bundle>mvn:${project.groupId}/onos-netconf-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}</bundle>
     </feature>
 </features>
diff --git a/drivers/cisco/netconf/pom.xml b/drivers/cisco/netconf/pom.xml
index dbddedd..622e4a7 100644
--- a/drivers/cisco/netconf/pom.xml
+++ b/drivers/cisco/netconf/pom.xml
@@ -49,7 +49,7 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
     </dependencies>
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
index 95dcfa1..9f2e84c 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/CpqdOfdpa2Pipeline.java
@@ -18,6 +18,7 @@
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
 import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.VlanId;
 import org.onosproject.core.ApplicationId;
@@ -491,10 +492,30 @@
                         + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
             }
         } else if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
-            if (buildIpv6Selector(filteredSelector, fwd) < 0) {
-                return Collections.emptyList();
+            IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
+            if (ipv6Dst.isMulticast()) {
+                if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
+                    log.debug("Multicast specific IPv6 forwarding objective can only be /128");
+                    fail(fwd, ObjectiveError.BADPARAMS);
+                    return ImmutableSet.of();
+                }
+                VlanId assignedVlan = readVlanFromSelector(fwd.meta());
+                if (assignedVlan == null) {
+                    log.debug("VLAN ID required by multicast specific fwd obj is missing. Abort.");
+                    fail(fwd, ObjectiveError.BADPARAMS);
+                    return ImmutableSet.of();
+                }
+                filteredSelector.matchVlanId(assignedVlan);
+                filteredSelector.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
+                forTableId = MULTICAST_ROUTING_TABLE;
+                log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}"
+                        + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+            } else {
+                if (buildIpv6Selector(filteredSelector, fwd) < 0) {
+                    return Collections.emptyList();
+                }
+                forTableId = UNICAST_ROUTING_TABLE;
             }
-            forTableId = UNICAST_ROUTING_TABLE;
         } else {
             filteredSelector
                 .matchEthType(Ethernet.MPLS_UNICAST)
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
index cc85cbf..c0c6639 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa2Pipeline.java
@@ -19,6 +19,7 @@
 import com.google.common.collect.Sets;
 import org.onlab.osgi.ServiceDirectory;
 import org.onlab.packet.Ethernet;
+import org.onlab.packet.IpAddress;
 import org.onlab.packet.IpPrefix;
 import org.onlab.packet.VlanId;
 import org.onlab.util.KryoNamespace;
@@ -857,6 +858,7 @@
 
     protected List<FlowRule> processMcastEthDstFilter(EthCriterion ethCriterion,
                                                       ApplicationId applicationId) {
+        ImmutableList.Builder<FlowRule> builder = ImmutableList.builder();
         TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
         TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
         selector.matchEthType(Ethernet.TYPE_IPV4);
@@ -870,7 +872,22 @@
                 .fromApp(applicationId)
                 .makePermanent()
                 .forTable(TMAC_TABLE).build();
-        return ImmutableList.<FlowRule>builder().add(rule).build();
+        builder.add(rule);
+
+        selector = DefaultTrafficSelector.builder();
+        treatment = DefaultTrafficTreatment.builder();
+        selector.matchEthType(Ethernet.TYPE_IPV6);
+        selector.matchEthDstMasked(ethCriterion.mac(), ethCriterion.mask());
+        treatment.transition(MULTICAST_ROUTING_TABLE);
+        rule = DefaultFlowRule.builder()
+                .forDevice(deviceId)
+                .withSelector(selector.build())
+                .withTreatment(treatment.build())
+                .withPriority(DEFAULT_PRIORITY)
+                .fromApp(applicationId)
+                .makePermanent()
+                .forTable(TMAC_TABLE).build();
+        return builder.add(rule).build();
     }
 
     private Collection<FlowRule> processForward(ForwardingObjective fwd) {
@@ -1281,16 +1298,34 @@
 
         IpPrefix ipv6Dst = ((IPCriterion) selector.getCriterion(Criterion.Type.IPV6_DST)).ip();
         if (ipv6Dst.isMulticast()) {
-            log.warn("IPv6 Multicast is currently not supported");
-            fail(fwd, ObjectiveError.BADPARAMS);
-            return -1;
-        }
-        if (ipv6Dst.prefixLength() != 0) {
-            builderToUpdate.matchIPv6Dst(ipv6Dst);
-        }
+            if (ipv6Dst.prefixLength() != IpAddress.INET6_BIT_LENGTH) {
+                log.warn("Multicast specific forwarding objective can only be /128");
+                fail(fwd, ObjectiveError.BADPARAMS);
+                return -1;
+            }
+            VlanId assignedVlan = readVlanFromSelector(fwd.meta());
+            if (assignedVlan == null) {
+                log.warn("VLAN ID required by multicast specific fwd obj is missing. Abort.");
+                fail(fwd, ObjectiveError.BADPARAMS);
+                return -1;
+            }
+            if (requireVlanExtensions()) {
+                OfdpaMatchVlanVid ofdpaMatchVlanVid = new OfdpaMatchVlanVid(assignedVlan);
+                builderToUpdate.extension(ofdpaMatchVlanVid, deviceId);
+            } else {
+                builderToUpdate.matchVlanId(assignedVlan);
+            }
+            builderToUpdate.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Dst(ipv6Dst);
+            log.debug("processing IPv6 multicast specific forwarding objective {} -> next:{}"
+                              + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+        } else {
+           if (ipv6Dst.prefixLength() != 0) {
+               builderToUpdate.matchIPv6Dst(ipv6Dst);
+           }
         builderToUpdate.matchEthType(Ethernet.TYPE_IPV6);
         log.debug("processing IPv6 unicast specific forwarding objective {} -> next:{}"
                               + " in dev:{}", fwd.id(), fwd.nextId(), deviceId);
+        }
         return 0;
     }
 
diff --git a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3QmxPipeline.java b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3QmxPipeline.java
index cc7c23d..4c6664b 100644
--- a/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3QmxPipeline.java
+++ b/drivers/default/src/main/java/org/onosproject/driver/pipeline/ofdpa/Ofdpa3QmxPipeline.java
@@ -18,19 +18,8 @@
 
 import static org.slf4j.LoggerFactory.getLogger;
 
-import java.util.Collection;
-import org.onlab.packet.Ethernet;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.TrafficSelector;
-import org.onosproject.net.flow.criteria.Criterion;
-import org.onosproject.net.flow.criteria.EthTypeCriterion;
-import org.onosproject.net.flow.criteria.IPCriterion;
-import org.onosproject.net.flowobjective.ForwardingObjective;
-import org.onosproject.net.flowobjective.ObjectiveError;
 import org.slf4j.Logger;
 
-import com.google.common.collect.ImmutableSet;
-
 /**
  * Pipeliner for Broadcom OF-DPA 3.0 TTP, specifically for Qumran based switches.
  */
@@ -47,50 +36,4 @@
     protected boolean matchInPortTmacTable() {
         return false;
     }
-
-    @Override
-    protected Collection<FlowRule> processEthTypeSpecific(ForwardingObjective fwd) {
-        TrafficSelector selector = fwd.selector();
-        EthTypeCriterion ethType =
-                (EthTypeCriterion) selector.getCriterion(Criterion.Type.ETH_TYPE);
-        //XXX remove when support is added to Qumran based OF-DPA
-        if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4 ||
-                ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
-            log.warn("Routing table is currently unsupported in dev:{}", deviceId);
-            return ImmutableSet.of();
-        }
-
-        return super.processEthTypeSpecific(fwd);
-    }
-
-    @Override
-    protected Collection<FlowRule> processVersatile(ForwardingObjective fwd) {
-         EthTypeCriterion ethType =
-                 (EthTypeCriterion) fwd.selector().getCriterion(Criterion.Type.ETH_TYPE);
-         if (ethType == null) {
-             log.error("Versatile forwarding objective:{} must include ethType",
-                       fwd.id());
-             fail(fwd, ObjectiveError.BADPARAMS);
-             return ImmutableSet.of();
-         }
-         //XXX remove when support is added to Qumran based OF-DPA
-         if (ethType.ethType().toShort() == Ethernet.TYPE_IPV6) {
-             log.warn("ACL table for IPv6 is currently unsupported in dev:{}", deviceId);
-             return ImmutableSet.of();
-         }
-
-         if (ethType.ethType().toShort() == Ethernet.TYPE_IPV4) {
-             for (Criterion c : fwd.selector().criteria()) {
-                 if (c instanceof IPCriterion) {
-                     if (((IPCriterion) c).type() == Criterion.Type.IPV4_DST) {
-                         log.warn("ACL table for Dst IPv4 is currently "
-                                 + "unsupported in dev:{}", deviceId);
-                         return ImmutableSet.of();
-                     }
-                 }
-             }
-         }
-
-         return super.processVersatile(fwd);
-    }
 }
diff --git a/drivers/default/src/main/resources/onos-drivers.xml b/drivers/default/src/main/resources/onos-drivers.xml
index 4fce46f..3d5f6d0 100644
--- a/drivers/default/src/main/resources/onos-drivers.xml
+++ b/drivers/default/src/main/resources/onos-drivers.xml
@@ -105,7 +105,7 @@
     </driver>
 
     <driver name="accton-ofdpa3" extends="ofdpa3"
-            manufacturer="Accton Corp\." hwVersion=".*" swVersion="ofdpa 3.*">
+            manufacturer="Accton Corp\." hwVersion=".*" swVersion="ofdpa .*">
     </driver>
 
     <driver name="znyx-ofdpa" extends="ofdpa3"
diff --git a/drivers/fujitsu/features.xml b/drivers/fujitsu/features.xml
index 66b0bce..5f2b7c4 100644
--- a/drivers/fujitsu/features.xml
+++ b/drivers/fujitsu/features.xml
@@ -23,6 +23,6 @@
 
         <bundle>mvn:${project.groupId}/onos-drivers-utilities/${project.version}</bundle>
 
-        <bundle>mvn:${project.groupId}/onos-netconf-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}</bundle>
     </feature>
 </features>
diff --git a/drivers/fujitsu/pom.xml b/drivers/fujitsu/pom.xml
index 9a3d81a..32d766f 100644
--- a/drivers/fujitsu/pom.xml
+++ b/drivers/fujitsu/pom.xml
@@ -51,12 +51,12 @@
 
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-ctl</artifactId>
+            <artifactId>onos-protocols-netconf-ctl</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
@@ -77,7 +77,6 @@
         <dependency>
             <groupId>commons-io</groupId>
             <artifactId>commons-io</artifactId>
-            <version>2.4</version>
         </dependency>
     </dependencies>
 
diff --git a/drivers/huawei/driver/pom.xml b/drivers/huawei/driver/pom.xml
index 778e87a..0d3a9fe 100644
--- a/drivers/huawei/driver/pom.xml
+++ b/drivers/huawei/driver/pom.xml
@@ -61,7 +61,7 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/drivers/juniper/features.xml b/drivers/juniper/features.xml
index 2a5e81b..c6e4911 100644
--- a/drivers/juniper/features.xml
+++ b/drivers/juniper/features.xml
@@ -29,7 +29,7 @@
             mvn:${project.groupId}/onos-drivers-utilities/${project.version}
         </bundle>
 
-        <bundle>mvn:${project.groupId}/onos-netconf-api/${project.version}
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}
         </bundle>
     </feature>
 </features>
diff --git a/drivers/juniper/pom.xml b/drivers/juniper/pom.xml
index eb1c12c..8c17f8d 100644
--- a/drivers/juniper/pom.xml
+++ b/drivers/juniper/pom.xml
@@ -29,7 +29,7 @@
     <dependencies>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/drivers/microsemi/pom.xml b/drivers/microsemi/pom.xml
index 8d3889a..6459186 100644
--- a/drivers/microsemi/pom.xml
+++ b/drivers/microsemi/pom.xml
@@ -66,7 +66,7 @@
 
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
 
diff --git a/drivers/netconf/features.xml b/drivers/netconf/features.xml
index 66b0bce..5f2b7c4 100644
--- a/drivers/netconf/features.xml
+++ b/drivers/netconf/features.xml
@@ -23,6 +23,6 @@
 
         <bundle>mvn:${project.groupId}/onos-drivers-utilities/${project.version}</bundle>
 
-        <bundle>mvn:${project.groupId}/onos-netconf-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}</bundle>
     </feature>
 </features>
diff --git a/drivers/netconf/pom.xml b/drivers/netconf/pom.xml
index 5dd841c..81cf922 100644
--- a/drivers/netconf/pom.xml
+++ b/drivers/netconf/pom.xml
@@ -44,7 +44,7 @@
     <dependencies>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/drivers/oplink/features.xml b/drivers/oplink/features.xml
index 1e16fa0..a716991 100644
--- a/drivers/oplink/features.xml
+++ b/drivers/oplink/features.xml
@@ -23,6 +23,6 @@
 
         <bundle>mvn:${project.groupId}/onos-drivers-utilities/${project.version}</bundle>
 
-        <bundle>mvn:${project.groupId}/onos-netconf-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}</bundle>
     </feature>
 </features>
diff --git a/drivers/oplink/pom.xml b/drivers/oplink/pom.xml
index 6041356..ce4eaf0 100644
--- a/drivers/oplink/pom.xml
+++ b/drivers/oplink/pom.xml
@@ -51,7 +51,7 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/drivers/p4runtime/BUCK b/drivers/p4runtime/BUCK
index 59a5d60..57079be 100644
--- a/drivers/p4runtime/BUCK
+++ b/drivers/p4runtime/BUCK
@@ -26,5 +26,6 @@
         'org.onosproject.generaldeviceprovider',
         'org.onosproject.protocols.p4runtime',
         'org.onosproject.p4runtime',
+        'org.onosproject.drivers',
     ],
 )
diff --git a/lib/pom.xml b/lib/pom.xml
index af013ea..55eea9a 100644
--- a/lib/pom.xml
+++ b/lib/pom.xml
@@ -49,6 +49,7 @@
         <slf4j.version>1.7.21</slf4j.version>
         <guava.version>22.0</guava.version>
         <commons.io.version>2.4</commons.io.version>
+        <bouncycastle.version>1.58</bouncycastle.version>
         <!-- TODO argLine was originally added maven-surfire-plugin configuration
                   to fix locale errors for non-US developers. However, it breaks
                   SonarQube's test coverage, so moving here for now. -->
@@ -184,6 +185,25 @@
                 <scope>test</scope>
             </dependency>
 
+            <dependency>
+                <groupId>org.apache.sshd</groupId>
+                <artifactId>sshd-core</artifactId>
+                <version>1.4.0</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.bouncycastle</groupId>
+                <artifactId>bcpkix-jdk15on</artifactId>
+                <version>${bouncycastle.version}</version>
+            </dependency>
+
+            <dependency>
+                <groupId>org.bouncycastle</groupId>
+                <artifactId>bcprov-jdk15on</artifactId>
+                <version>${bouncycastle.version}</version>
+            </dependency>
+
+
             <!-- Web related -->
             <dependency>
                 <groupId>javax.servlet</groupId>
diff --git a/protocols/netconf/api/pom.xml b/protocols/netconf/api/pom.xml
index c758a8e..d1609a4 100644
--- a/protocols/netconf/api/pom.xml
+++ b/protocols/netconf/api/pom.xml
@@ -21,11 +21,11 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onosproject</groupId>
-        <artifactId>onos-netconf</artifactId>
+        <artifactId>onos-protocols-netconf</artifactId>
         <version>1.12.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>onos-netconf-api</artifactId>
+    <artifactId>onos-protocols-netconf-api</artifactId>
     <packaging>bundle</packaging>
 
     <description>ONOS NETCONF plugin API</description>
diff --git a/protocols/netconf/ctl/pom.xml b/protocols/netconf/ctl/pom.xml
index 0306e181..736d62f 100644
--- a/protocols/netconf/ctl/pom.xml
+++ b/protocols/netconf/ctl/pom.xml
@@ -20,11 +20,11 @@
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>org.onosproject</groupId>
-        <artifactId>onos-netconf</artifactId>
+        <artifactId>onos-protocols-netconf</artifactId>
         <version>1.12.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>onos-netconf-ctl</artifactId>
+    <artifactId>onos-protocols-netconf-ctl</artifactId>
     <packaging>bundle</packaging>
 
     <description>ONOS NETCONF plugin controller</description>
@@ -41,7 +41,7 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
@@ -64,7 +64,6 @@
         <dependency>
             <groupId>org.apache.sshd</groupId>
             <artifactId>sshd-core</artifactId>
-            <version>1.4.0</version>
         </dependency>
 
         <dependency>
@@ -81,62 +80,13 @@
         <dependency>
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcpkix-jdk15on</artifactId>
-            <version>1.58</version>
         </dependency>
 
         <dependency>
             <groupId>org.bouncycastle</groupId>
             <artifactId>bcprov-jdk15on</artifactId>
-            <version>1.58</version>
         </dependency>
 
     </dependencies>
 
-    <build>
-        <plugins>
-            <!--plugin>
-                <groupId>org.apache.maven.plugins</groupId>
-                <artifactId>maven-shade-plugin</artifactId>
-                <version>2.3</version>
-                <configuration>
-                    <filters>
-                        <filter>
-                            <artifact>ch.ethz.ganymed:ganymed-ssh2</artifact>
-                            <includes>
-                                <include>ch/ethz/ssh2/**</include>
-                            </includes>
-                        </filter>
-                        <filter>
-                            <artifact>org.jdom:jdom2</artifact>
-                            <includes>
-                                <include>org/jdom2/**</include>
-                            </includes>
-                        </filter>
-                    </filters>
-                </configuration>
-                <executions>
-                    <execution>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>shade</goal>
-                        </goals>
-                    </execution>
-                </executions>
-            </plugin-->
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-bundle-plugin</artifactId>
-                <configuration>
-                    <instructions>
-                        <Private-Package>ch.ethz.ssh2.*</Private-Package>
-                        <Embed-Dependecy>ganymed-ssh2</Embed-Dependecy>
-                    </instructions>
-                </configuration>
-            </plugin>
-            <plugin>
-                <groupId>org.apache.felix</groupId>
-                <artifactId>maven-scr-plugin</artifactId>
-            </plugin>
-        </plugins>
-    </build>
 </project>
diff --git a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java
index 241ea23..c8a4604 100644
--- a/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java
+++ b/protocols/netconf/ctl/src/main/java/org/onosproject/netconf/ctl/impl/NetconfSessionMinaImpl.java
@@ -211,14 +211,15 @@
         session = connectFuture.getSession();
         //Using the device ssh key if possible
         if (deviceInfo.getKey() != null) {
-            PEMParser pemParser = new PEMParser(new CharArrayReader(deviceInfo.getKey()));
-            JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
-            try {
-                KeyPair kp = converter.getKeyPair((PEMKeyPair) pemParser.readObject());
-                session.addPublicKeyIdentity(kp);
-            } catch (java.io.IOException e) {
-                throw new NetconfException("Failed to authenticate session with device " +
-                                           deviceInfo + "check key to be a valid key", e);
+            try (PEMParser pemParser = new PEMParser(new CharArrayReader(deviceInfo.getKey()))) {
+                JcaPEMKeyConverter converter = new JcaPEMKeyConverter().setProvider(BouncyCastleProvider.PROVIDER_NAME);
+                try {
+                    KeyPair kp = converter.getKeyPair((PEMKeyPair) pemParser.readObject());
+                    session.addPublicKeyIdentity(kp);
+                } catch (IOException e) {
+                    throw new NetconfException("Failed to authenticate session with device " +
+                            deviceInfo + "check key to be a valid key", e);
+                }
             }
         } else {
             session.addPasswordIdentity(deviceInfo.password());
@@ -447,9 +448,11 @@
      */
     private String formatChunkedMessage(String message) {
         if (message.endsWith(ENDPATTERN)) {
+            // message given had Netconf 1.0 EOM pattern -> remove
             message = message.substring(0, message.length() - ENDPATTERN.length());
         }
         if (!message.startsWith(LF + HASH)) {
+            // chunk encode message
             message = LF + HASH + message.getBytes(UTF_8).length + LF + message + LF + HASH + HASH + LF;
         }
         return message;
@@ -482,6 +485,7 @@
     }
 
     private String sendRequest(String request) throws NetconfException {
+        // FIXME probably chunk-encoding too early
         request = formatNetconfMessage(request);
         return sendRequest(request, false);
     }
@@ -492,6 +496,7 @@
         if (!isHello) {
             messageId = messageIdInteger.getAndIncrement();
         }
+        // FIXME potentially re-writing chunked encoded String?
         request = formatXmlHeader(request);
         request = formatRequestMessageId(request, messageId);
         CompletableFuture<String> futureReply = request(request, messageId);
diff --git a/protocols/netconf/pom.xml b/protocols/netconf/pom.xml
index e27ee31..9cf595d 100644
--- a/protocols/netconf/pom.xml
+++ b/protocols/netconf/pom.xml
@@ -24,7 +24,7 @@
         <version>1.12.0-SNAPSHOT</version>
     </parent>
 
-    <artifactId>onos-netconf</artifactId>
+    <artifactId>onos-protocols-netconf</artifactId>
     <packaging>pom</packaging>
 
     <modules>
diff --git a/providers/netconf/alarm/pom.xml b/providers/netconf/alarm/pom.xml
index 8187ec3..931f5a9 100644
--- a/providers/netconf/alarm/pom.xml
+++ b/providers/netconf/alarm/pom.xml
@@ -22,12 +22,12 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-ctl</artifactId>
+            <artifactId>onos-protocols-netconf-ctl</artifactId>
             <version>${project.version}</version>
         </dependency>
     </dependencies>
diff --git a/providers/netconf/app/app.xml b/providers/netconf/app/app.xml
index 01dbb42..00ce4ff 100644
--- a/providers/netconf/app/app.xml
+++ b/providers/netconf/app/app.xml
@@ -20,8 +20,8 @@
      apps="org.onosproject.faultmanagement"
      features="${project.artifactId}">
     <description>${project.description}</description>
-    <artifact>mvn:${project.groupId}/onos-netconf-api/${project.version}</artifact>
-    <artifact>mvn:${project.groupId}/onos-netconf-ctl/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}</artifact>
+    <artifact>mvn:${project.groupId}/onos-protocols-netconf-ctl/${project.version}</artifact>
 
     <artifact>mvn:${project.groupId}/onos-netconf-provider-device/${project.version}</artifact>
     <artifact>mvn:${project.groupId}/onos-netconf-provider-alarm/${project.version}</artifact>
diff --git a/providers/netconf/app/features.xml b/providers/netconf/app/features.xml
index c8b6fa1..84d0c3b 100644
--- a/providers/netconf/app/features.xml
+++ b/providers/netconf/app/features.xml
@@ -19,8 +19,8 @@
              description="${project.description}">
         <feature>onos-api</feature>
         <bundle>mvn:io.netty/netty/3.9.2.Final</bundle>
-        <bundle>mvn:${project.groupId}/onos-netconf-api/${project.version}</bundle>
-        <bundle>mvn:${project.groupId}/onos-netconf-ctl/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-api/${project.version}</bundle>
+        <bundle>mvn:${project.groupId}/onos-protocols-netconf-ctl/${project.version}</bundle>
 
         <bundle>mvn:${project.groupId}/onos-netconf-provider-device/${project.version}</bundle>
         <bundle>mvn:${project.groupId}/onos-netconf-provider-alarm/${project.version}</bundle>
diff --git a/providers/netconf/device/pom.xml b/providers/netconf/device/pom.xml
index 7860785..57cfaa1 100644
--- a/providers/netconf/device/pom.xml
+++ b/providers/netconf/device/pom.xml
@@ -38,12 +38,12 @@
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-api</artifactId>
+            <artifactId>onos-protocols-netconf-api</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
             <groupId>org.onosproject</groupId>
-            <artifactId>onos-netconf-ctl</artifactId>
+            <artifactId>onos-protocols-netconf-ctl</artifactId>
             <version>${project.version}</version>
         </dependency>
         <dependency>
diff --git a/utils/misc/src/main/java/org/onlab/packet/MacAddress.java b/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
index e41fb05..b048794 100644
--- a/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
+++ b/utils/misc/src/main/java/org/onlab/packet/MacAddress.java
@@ -56,6 +56,14 @@
      */
     public static final MacAddress IPV4_MULTICAST_MASK = valueOf("ff:ff:ff:80:00:00");
     /**
+     * IPv6 multicast MAC address.
+     */
+    public static final MacAddress IPV6_MULTICAST = valueOf("33:33:00:00:00:00");
+    /**
+     * IPv6 multicast MAC mask.
+     */
+    public static final MacAddress IPV6_MULTICAST_MASK = valueOf("FF:FF:00:00:00:00");
+    /**
      * A set of LLDP MAC addresses.
      */
     public static final Set<MacAddress> LLDP = ImmutableSet.of(
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2Host.js b/web/gui/src/main/webapp/app/view/topo2/topo2Host.js
index a2f2124..bd04c7b 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2Host.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2Host.js
@@ -49,7 +49,8 @@
     .factory('Topo2HostService', [
         'Topo2Collection', 'Topo2NodeModel', 'Topo2ViewService',
         'IconService', 'Topo2ZoomService', 'Topo2HostsPanelService', 'PrefsService',
-        function (_c_, NodeModel, _t2vs_, is, zs, t2hds, ps) {
+        'Topo2PrefsService',
+        function (_c_, NodeModel, _t2vs_, is, zs, t2hds, ps, t2ps) {
 
             Collection = _c_;
 
@@ -76,8 +77,18 @@
                     var type = this.get('type');
                     return remappedDeviceTypes[type] || type || 'm_endstation';
                 },
+                labelIndex: function () {
+                    return t2ps.get('hlbls');
+                },
                 label: function () {
-                    return this.get('ips')[0] || 'unknown';
+                    var props = this.get('props'),
+                        id = this.get('ips')[0] || 'unknown',
+                        friendlyName = props && props.name ? props.name : id,
+                        labels = ['', friendlyName || id, id, this.get('id')],
+                        nli = this.labelIndex(),
+                        idx = (nli < labels.length) ? nli : 0;
+
+                    return labels[idx];
                 },
                 setScale: function () {
 
diff --git a/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js b/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
index a3b75f5..b396f30 100644
--- a/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
+++ b/web/gui/src/main/webapp/app/view/topo2/topo2KeyCommands.js
@@ -35,6 +35,7 @@
             H: [toggleHosts, 'Toggle host visibility'],
             M: [toggleOfflineDevices, 'Toggle offline visibility'],
             dot: [toggleToolbar, 'Toggle Toolbar'],
+            'shift-L': [cycleHostLabels, 'Cycle host labels'],
 
             esc: handleEscape,
 
@@ -114,6 +115,15 @@
         }
     }
 
+    function hostLabelFlashMessage(index) {
+        switch (index) {
+            case 0: return 'Hide host labels';
+            case 1: return 'Show friendly host labels';
+            case 2: return 'Show host IP labels';
+            case 3: return 'Show host MAC Address labels';
+        }
+    }
+
     function cycleDeviceLabels() {
         var deviceLabelIndex = t2ps.get('dlbls') + 1,
             newDeviceLabelIndex = deviceLabelIndex % 3;
@@ -123,6 +133,15 @@
         flash.flash(deviceLabelFlashMessage(newDeviceLabelIndex));
     }
 
+    function cycleHostLabels() {
+        var hostLabelIndex = t2ps.get('hlbls') + 1,
+            newHostLabelIndex = hostLabelIndex % 4;
+
+        t2ps.set('hlbls', newHostLabelIndex);
+        t2fs.updateNodes();
+        flash.flash(hostLabelFlashMessage(newHostLabelIndex));
+    }
+
     function toggleBackground(x) {
         t2bgs.toggle(x);
     }