aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/onos/providers
diff options
context:
space:
mode:
authorAshlee Young <ashlee@wildernessvoice.com>2015-12-06 07:15:03 -0800
committerAshlee Young <ashlee@wildernessvoice.com>2015-12-08 10:55:21 -0800
commit76dc892491948adae5e5e62cf94448967e8d865b (patch)
tree7a33ef05cc583946db21edad627060f280a53549 /framework/src/onos/providers
parentd333c63fdec8b064184b0a26f8d777f267577fde (diff)
Fixes bad POM file with ONOS commit 8c68536972f63069c263635c9d9f4f31d7f3e9a2
Change-Id: I7adb5a2d3738d53dbc41db7577768b0e7ced5450 Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/onos/providers')
-rwxr-xr-xframework/src/onos/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java12
-rw-r--r--framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java2
-rw-r--r--framework/src/onos/providers/netcfghost/pom.xml65
-rw-r--r--framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java196
-rw-r--r--framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/package-info.java20
-rw-r--r--framework/src/onos/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java132
-rw-r--r--framework/src/onos/providers/netconf/app/pom.xml7
-rw-r--r--framework/src/onos/providers/netconf/flow/pom.xml259
-rw-r--r--framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfFlowRuleProvider.java403
-rw-r--r--framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfOperation.java141
-rw-r--r--framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/XmlBuilder.java223
-rw-r--r--framework/src/onos/providers/netconf/pom.xml1
-rw-r--r--framework/src/onos/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java4
-rw-r--r--framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java21
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java67
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java76
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java1
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java65
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java1764
-rw-r--r--framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowValueMapper.java38
-rw-r--r--framework/src/onos/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/OpenFlowGroupProvider.java3
-rw-r--r--framework/src/onos/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java2
-rw-r--r--framework/src/onos/providers/pom.xml2
-rw-r--r--framework/src/onos/providers/snmp/alarm/pom.xml34
-rw-r--r--framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/SNMPAlarmProvider.java57
-rw-r--r--framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/package-info.java (renamed from framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/package-info.java)5
-rw-r--r--framework/src/onos/providers/snmp/pom.xml38
27 files changed, 1699 insertions, 1939 deletions
diff --git a/framework/src/onos/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java b/framework/src/onos/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
index 30bb4470..37576e44 100755
--- a/framework/src/onos/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
+++ b/framework/src/onos/providers/bgp/topology/src/test/java/org/onosproject/provider/bgp/topology/impl/BgpTopologyProviderTest.java
@@ -31,6 +31,7 @@ import org.onosproject.bgp.controller.BgpCfg;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpId;
import org.onosproject.bgp.controller.BgpPeer;
+import org.onosproject.bgp.controller.BgpLocalRib;
import org.onosproject.bgp.controller.BgpNodeListener;
import org.onosproject.bgp.controller.BgpPeerManager;
import org.onosproject.bgpio.exceptions.BgpParseException;
@@ -208,6 +209,17 @@ public class BgpTopologyProviderTest {
return 0;
}
+ @Override
+ public BgpLocalRib bgpLocalRibVpn() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Override
+ public BgpLocalRib bgpLocalRib() {
+ // TODO Auto-generated method stub
+ return null;
+ }
@Override
public BgpPeerManager peerManager() {
diff --git a/framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java b/framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
index 94abebaa..668d59c0 100644
--- a/framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
+++ b/framework/src/onos/providers/lldp/src/main/java/org/onosproject/provider/lldp/impl/LldpLinkProvider.java
@@ -570,7 +570,7 @@ public class LldpLinkProvider extends AbstractProvider implements LinkProvider {
case DEVICE_AVAILABILITY_CHANGED:
if (deviceService.isAvailable(deviceId)) {
log.debug("Device up {}", deviceId);
- updateDevice(device);
+ updateDevice(device).ifPresent(ld -> updatePorts(ld, deviceId));
} else {
log.debug("Device down {}", deviceId);
removeDevice(deviceId);
diff --git a/framework/src/onos/providers/netcfghost/pom.xml b/framework/src/onos/providers/netcfghost/pom.xml
new file mode 100644
index 00000000..15363c8d
--- /dev/null
+++ b/framework/src/onos/providers/netcfghost/pom.xml
@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2014 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <parent>
+ <artifactId>onos-providers</artifactId>
+ <groupId>org.onosproject</groupId>
+ <version>1.4.0-SNAPSHOT</version>
+ </parent>
+ <modelVersion>4.0.0</modelVersion>
+
+ <artifactId>onos-netcfg-host-provider</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>
+ Host provider that uses network config service to discover hosts.
+ </description>
+ <url>http://onosproject.org</url>
+
+ <properties>
+ <onos.app.name>org.onosproject.netcfghostprovider</onos.app.name>
+ <onos.app.origin>ON.Lab</onos.app.origin>
+ </properties>
+
+ <dependencies>
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onlab-osgi</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ <version>4.11</version>
+ <scope>test</scope>
+ </dependency>
+
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
+ </dependencies>
+
+</project>
diff --git a/framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java b/framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java
new file mode 100644
index 00000000..767cfb7f
--- /dev/null
+++ b/framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/NetworkConfigHostProvider.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.netcfghost;
+
+import org.apache.felix.scr.annotations.Activate;
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Deactivate;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.ReferenceCardinality;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.core.ApplicationId;
+import org.onosproject.core.CoreService;
+import org.onosproject.net.ConnectPoint;
+import org.onosproject.net.Host;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.config.NetworkConfigEvent;
+import org.onosproject.net.config.NetworkConfigListener;
+import org.onosproject.net.config.NetworkConfigRegistry;
+import org.onosproject.net.config.basics.BasicHostConfig;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderRegistry;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import java.util.Set;
+
+/**
+ * Host provider that uses network config service to discover hosts.
+ */
+@Component(immediate = true)
+public class NetworkConfigHostProvider extends AbstractProvider implements HostProvider {
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected CoreService coreService;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected HostProviderRegistry providerRegistry;
+
+ @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
+ protected NetworkConfigRegistry networkConfigRegistry;
+
+ private static final String APP_NAME = "org.onosproject.provider.netcfghost";
+ private ApplicationId appId;
+ protected HostProviderService providerService;
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+ private final InternalNetworkConfigListener networkConfigListener =
+ new InternalNetworkConfigListener();
+
+ /**
+ * Creates an network config host location provider.
+ */
+ public NetworkConfigHostProvider() {
+ super(new ProviderId("host", APP_NAME));
+ }
+
+ @Activate
+ protected void activate() {
+ appId = coreService.registerApplication(APP_NAME);
+ providerService = providerRegistry.register(this);
+ networkConfigRegistry.addListener(networkConfigListener);
+ readInitialConfig();
+ log.info("Started");
+ }
+
+ @Deactivate
+ protected void deactivate() {
+ networkConfigRegistry.removeListener(networkConfigListener);
+ providerRegistry.unregister(this);
+ providerService = null;
+ log.info("Stopped");
+ }
+
+ @Override
+ public void triggerProbe(Host host) {
+ /*
+ * Note: In CORD deployment, we assume that all hosts are configured.
+ * Therefore no probe is required.
+ */
+ }
+
+ /**
+ * Adds host information.
+ * IP information will be appended if host exists.
+ *
+ * @param mac MAC address of the host
+ * @param vlan VLAN ID of the host
+ * @param hloc Location of the host
+ * @param ips Set of IP addresses of the host
+ */
+ protected void addHost(MacAddress mac, VlanId vlan, HostLocation hloc, Set<IpAddress> ips) {
+ HostId hid = HostId.hostId(mac, vlan);
+ HostDescription desc = new DefaultHostDescription(mac, vlan, hloc, ips);
+ providerService.hostDetected(hid, desc, false);
+ }
+
+ /**
+ * Updates host information.
+ * IP information will be replaced if host exists.
+ *
+ * @param mac MAC address of the host
+ * @param vlan VLAN ID of the host
+ * @param hloc Location of the host
+ * @param ips Set of IP addresses of the host
+ */
+ protected void updateHost(MacAddress mac, VlanId vlan, HostLocation hloc, Set<IpAddress> ips) {
+ HostId hid = HostId.hostId(mac, vlan);
+ HostDescription desc = new DefaultHostDescription(mac, vlan, hloc, ips);
+ providerService.hostDetected(hid, desc, true);
+ }
+
+ /**
+ * Removes host information.
+ *
+ * @param mac MAC address of the host
+ * @param vlan VLAN ID of the host
+ */
+ protected void removeHost(MacAddress mac, VlanId vlan) {
+ HostId hid = HostId.hostId(mac, vlan);
+ providerService.hostVanished(hid);
+ }
+
+ private void readInitialConfig() {
+ networkConfigRegistry.getSubjects(HostId.class).forEach(hostId -> {
+ MacAddress mac = hostId.mac();
+ VlanId vlan = hostId.vlanId();
+ BasicHostConfig hostConfig =
+ networkConfigRegistry.getConfig(hostId, BasicHostConfig.class);
+ Set<IpAddress> ipAddresses = hostConfig.ipAddresses();
+ ConnectPoint location = hostConfig.location();
+ HostLocation hloc = new HostLocation(location, System.currentTimeMillis());
+ addHost(mac, vlan, hloc, ipAddresses);
+ });
+ }
+
+ private class InternalNetworkConfigListener implements NetworkConfigListener {
+ @Override
+ public void event(NetworkConfigEvent event) {
+ // Do not process non-host, register and unregister events
+ if (!event.configClass().equals(BasicHostConfig.class) ||
+ event.type() == NetworkConfigEvent.Type.CONFIG_REGISTERED ||
+ event.type() == NetworkConfigEvent.Type.CONFIG_UNREGISTERED) {
+ return;
+ }
+
+ HostId hostId = (HostId) event.subject();
+ MacAddress mac = hostId.mac();
+ VlanId vlan = hostId.vlanId();
+ BasicHostConfig hostConfig =
+ networkConfigRegistry.getConfig(hostId, BasicHostConfig.class);
+ Set<IpAddress> ipAddresses = null;
+ HostLocation hloc = null;
+
+ // Note: There will be no config presented in the CONFIG_REMOVE case
+ if (hostConfig != null) {
+ ipAddresses = hostConfig.ipAddresses();
+ ConnectPoint location = hostConfig.location();
+ hloc = new HostLocation(location, System.currentTimeMillis());
+ }
+
+ switch (event.type()) {
+ case CONFIG_ADDED:
+ addHost(mac, vlan, hloc, ipAddresses);
+ break;
+ case CONFIG_UPDATED:
+ updateHost(mac, vlan, hloc, ipAddresses);
+ break;
+ case CONFIG_REMOVED:
+ removeHost(mac, vlan);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+}
diff --git a/framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/package-info.java b/framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/package-info.java
new file mode 100644
index 00000000..a56b9a80
--- /dev/null
+++ b/framework/src/onos/providers/netcfghost/src/main/java/org/onosproject/provider/netcfghost/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Host provider that uses network config service to discover hosts.
+ */
+package org.onosproject.provider.netcfghost;
diff --git a/framework/src/onos/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java b/framework/src/onos/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java
new file mode 100644
index 00000000..a4f057cf
--- /dev/null
+++ b/framework/src/onos/providers/netcfghost/src/test/java/org/onosproject/provider/netcfghost/NetworkConfigHostProviderTest.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.provider.netcfghost;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.onlab.packet.IpAddress;
+import org.onlab.packet.MacAddress;
+import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
+import org.onosproject.net.HostId;
+import org.onosproject.net.HostLocation;
+import org.onosproject.net.PortNumber;
+import org.onosproject.net.host.DefaultHostDescription;
+import org.onosproject.net.host.HostDescription;
+import org.onosproject.net.host.HostProvider;
+import org.onosproject.net.host.HostProviderService;
+import org.onosproject.net.provider.AbstractProviderService;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import static org.hamcrest.Matchers.is;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
+
+/**
+ * Set of tests of the host location provider for CORD.
+ */
+public class NetworkConfigHostProviderTest {
+ private NetworkConfigHostProvider provider = new NetworkConfigHostProvider();
+ private MockHostProviderService providerService = new MockHostProviderService(provider);
+
+ private MacAddress mac = MacAddress.valueOf("c0:ff:ee:c0:ff:ee");
+ private VlanId vlan = VlanId.vlanId(VlanId.UNTAGGED);
+ private DeviceId deviceId = DeviceId.deviceId("of:0000000000000001");
+ private PortNumber port = PortNumber.portNumber(5);
+ private HostLocation hloc = new HostLocation(deviceId, port, 100);
+ private Set<IpAddress> ips = new HashSet<>();
+ private HostId hostId = HostId.hostId(mac, vlan);
+ private HostDescription hostDescription;
+
+ @Before
+ public void setUp() {
+ provider.providerService = providerService;
+
+ // Initialize test variables
+ ips.add(IpAddress.valueOf("10.0.0.1"));
+ ips.add(IpAddress.valueOf("192.168.0.1"));
+ hostDescription = new DefaultHostDescription(mac, vlan, hloc, ips);
+ }
+
+ @Test
+ public void testAddHost() throws Exception {
+ provider.addHost(mac, vlan, hloc, ips);
+ assertThat(providerService.hostId, is(hostId));
+ assertThat(providerService.hostDescription, is(hostDescription));
+ assertThat(providerService.event, is("hostDetected"));
+ providerService.clear();
+ }
+
+ @Test
+ public void testUpdateHost() throws Exception {
+ provider.updateHost(mac, vlan, hloc, ips);
+ assertThat(providerService.hostId, is(hostId));
+ assertThat(providerService.hostDescription, is(hostDescription));
+ assertThat(providerService.event, is("hostDetected"));
+ providerService.clear();
+ }
+
+ @Test
+ public void testRemoveHost() throws Exception {
+ provider.removeHost(mac, vlan);
+ assertThat(providerService.hostId, is(hostId));
+ assertNull(providerService.hostDescription);
+ assertThat(providerService.event, is("hostVanished"));
+ providerService.clear();
+ }
+
+ /**
+ * Mock HostProviderService.
+ */
+ private class MockHostProviderService
+ extends AbstractProviderService<HostProvider>
+ implements HostProviderService {
+ private HostId hostId = null;
+ private HostDescription hostDescription = null;
+ private String event = null;
+
+ public MockHostProviderService(HostProvider provider) {
+ super(provider);
+ }
+
+ @Override
+ public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
+ this.hostId = hostId;
+ this.hostDescription = hostDescription;
+ this.event = "hostDetected";
+ }
+
+ @Override
+ public void hostVanished(HostId hostId) {
+ this.hostId = hostId;
+ this.event = "hostVanished";
+ }
+
+ @Override
+ public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
+ // Note: This method is never used.
+ }
+
+ public void clear() {
+ this.hostId = null;
+ this.hostDescription = null;
+ this.event = null;
+ }
+ }
+}
diff --git a/framework/src/onos/providers/netconf/app/pom.xml b/framework/src/onos/providers/netconf/app/pom.xml
index 4a19ae8e..0aa55ff5 100644
--- a/framework/src/onos/providers/netconf/app/pom.xml
+++ b/framework/src/onos/providers/netconf/app/pom.xml
@@ -37,12 +37,7 @@
<artifactId>onos-netconf-provider-device</artifactId>
<version>${project.version}</version>
</dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-netconf-provider-flow</artifactId>
- <version>${project.version}</version>
- </dependency>
- <!-- TODO: add other dependencies here as more bundles are added to the app -->
+ <!-- Add other dependencies here as more bundles are added to the app -->
</dependencies>
</project>
diff --git a/framework/src/onos/providers/netconf/flow/pom.xml b/framework/src/onos/providers/netconf/flow/pom.xml
deleted file mode 100644
index 7ccd552f..00000000
--- a/framework/src/onos/providers/netconf/flow/pom.xml
+++ /dev/null
@@ -1,259 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright 2014 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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-netconf-providers</artifactId>
- <version>1.4.0-SNAPSHOT</version>
- <relativePath>../pom.xml</relativePath>
- </parent>
-
- <artifactId>onos-netconf-provider-flow</artifactId>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </dependency>
- <dependency>
- <groupId>ch.ethz.ganymed</groupId>
- <artifactId>ganymed-ssh2</artifactId>
- <version>262</version>
- </dependency>
- <dependency>
- <!-- TODO: change this appropriately when the official TailF JNC is available -->
- <groupId>org.onosproject</groupId>
- <artifactId>jnc</artifactId>
- <version>1.0</version>
- </dependency>
- <dependency>
- <groupId>org.jdom</groupId>
- <artifactId>jdom2</artifactId>
- <version>2.0.5</version>
- </dependency>
- <dependency>
- <groupId>jaxen</groupId>
- <artifactId>jaxen</artifactId>
- <version>1.1.4</version>
- <optional>true</optional>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onlab-junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.easymock</groupId>
- <artifactId>easymock</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-yang-tool</artifactId>
- <version>1.3</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>com.tailf:JNC</artifact>
- <includes>
- <include>com/tailf/jnc/**</include>
- </includes>
- </filter>
- <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>
- <filter>
- <artifact>org.onosproject:onos-yang-tool</artifact>
- <includes>
- <include>org/opendaylight/yang/gen/**</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-scr-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <configuration>
- <instructions>
- <Export-Package>
- com.tailf.jnc,
- ch.ethz.ssh2,
- ch.ethz.ssh2.auth,
- ch.ethz.ssh2.channel,
- ch.ethz.ssh2.crypto,
- ch.ethz.ssh2.crypto.cipher,
- ch.ethz.ssh2.crypto.dh,
- ch.ethz.ssh2.crypto.digest,
- ch.ethz.ssh2.log,
- ch.ethz.ssh2.packets,
- ch.ethz.ssh2.server,
- ch.ethz.ssh2.sftp,
- ch.ethz.ssh2.signature,
- ch.ethz.ssh2.transport,
- ch.ethz.ssh2.util,
- org.jdom2,
- org.jdom2.input,
- org.jdom2.output,
- org.jdom2.adapters,
- org.jdom2.filter,
- org.jdom2.internal,
- org.jdom2.located,
- org.jdom2.transform,
- org.jdom2.util,
- org.jdom2.xpath,
- org.jdom2.input.sax,
- org.jdom2.input.stax,
- org.jdom2.output.support,
- org.jdom2.xpath.jaxen,
- org.jdom2.xpath.util,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520,
- org.opendaylight.yangtools.yang.data.impl.schema.tree,
- org.opendaylight.yangtools.yang.data.impl.codec,
- org.opendaylight.yangtools.yang.model.parser.api,
- org.opendaylight.yangtools.yang.data.impl.schema.nodes,
- org.opendaylight.yangtools.yang.binding.util,
- org.opendaylight.yangtools.yang.data.impl,
- org.opendaylight.yangtools.sal.binding.generator.impl,
- org.opendaylight.yangtools.yang.parser.impl.util,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625,
- org.opendaylight.yangtools.yang.data.api,
- org.opendaylight.yangtools.objcache.spi,
- org.opendaylight.yangtools.yang.data.impl.schema.transform.base.parser,
- org.opendaylight.yangtools.maven.sal.api.gen.plugin,
- org.opendaylight.yangtools.yang.data.impl.schema.builder.impl,
- org.opendaylight.yangtools.yang.data.api.schema.tree,
- org.opendaylight.yangtools.binding.generator.util,
- org.opendaylight.yangtools.sal.binding.generator.spi,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715,
- org.opendaylight.yangtools.yang2sources.spi,
- org.opendaylight.yangtools.yang.model.repo.api,
- org.opendaylight.yangtools.util,
- org.opendaylight.yangtools.yang.parser.util,
- org.opendaylight.yangtools.yang.data.api.schema.stream,
- org.opendaylight.yangtools.yang.data.impl.schema.transform.base.serializer,
- org.opendaylight.yangtools.concepts,
- org.opendaylight.yangtools.yang.binding,
- org.opendaylight.yangtools.yang.model.util.repo,
- org.opendaylight.yangtools.yang.wadl.generator.maven,
- org.opendaylight.yangtools.yang.data.api.schema,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type,
- org.opendaylight.yangtools.concepts.util,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip.ace.ip.version,
- org.opendaylight.yangtools.sal.binding.model.api,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip,
- org.opendaylight.yangtools.yang.data.impl.schema.builder.api,
- org.opendaylight.yangtools.util.concurrent,
- org.opendaylight.yangtools.yang.parser.builder.impl,
- org.opendaylight.yangtools.yang.data.impl.schema.transform.base,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.actions.packet.handling,
- org.opendaylight.yangtools.sal.binding.model.api.type.builder,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields,
- org.opendaylight.yangtools.yang2sources.plugin,
- org.opendaylight.yangtools.yang.data.impl.codec.xml,
- org.opendaylight.yangtools.antlrv4.code.gen,
- org.opendaylight.yangtools.yang.parser.builder.util,
- org.opendaylight.yangtools.yang.data.impl.schema.transform,
- org.opendaylight.yangtools.yang.model.api.type,
- org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.serializer,
- org.opendaylight.yangtools.yang.data.api.schema.tree.spi,
- org.opendaylight.yangtools.yang.data.impl.schema.transform.dom.parser,
- org.opendaylight.yangtools.sal.binding.yang.types,
- org.opendaylight.yangtools.yang.data.impl.schema.transform.dom,
- org.opendaylight.yangtools.yang.data.impl.util,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.timerange,
- org.opendaylight.yangtools.sal.binding.generator.api,
- org.opendaylight.yangtools.sal.java.api.generator,
- org.opendaylight.yangtools.yang.binding.annotations,
- org.opendaylight.yangtools.sal.binding.generator.util,
- org.opendaylight.yangtools.yang.model.repo.util,
- org.opendaylight.yangtools.yang.model.api,
- org.opendaylight.yangtools.yang.common,
- org.opendaylight.yangtools.yang.wadl.generator,
- org.opendaylight.yangtools.yang.parser.builder.api,
- org.opendaylight.yangtools.yang.model.util,
- org.opendaylight.yangtools.yang.parser.impl,
- org.opendaylight.yangtools.yang.data.impl.schema,
- org.opendaylight.yangtools.yang.data.api.codec,
- org.opendaylight.yangtools.yang.unified.doc.generator,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list,
- org.opendaylight.yangtools.objcache,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.actions,
- org.opendaylight.yangtools.yang.data.util,
- org.opendaylight.yangtools.yang.unified.doc.generator.maven,
- org.opendaylight.yangtools.binding.generator.util.generated.type.builder,
- org.opendaylight.yangtools.yang.model.repo.spi,
- org.opendaylight.yangtools.yang.parser.repo,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715,
- org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches,
- org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.valid,
- com.romix.scala,
- com.romix.scala.collection,
- com.romix.scala.collection.concurrent,
- org.opendaylight.yangtools.objcache.impl
- </Export-Package>
- </instructions>
- </configuration>
- </plugin>
- <plugin>
- <groupId>org.onosproject</groupId>
- <artifactId>onos-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
-
-</project>
diff --git a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfFlowRuleProvider.java b/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfFlowRuleProvider.java
deleted file mode 100644
index b29d687e..00000000
--- a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfFlowRuleProvider.java
+++ /dev/null
@@ -1,403 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.provider.netconf.flow.impl;
-
-import static com.google.common.base.Strings.isNullOrEmpty;
-import static org.onlab.util.Tools.get;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Dictionary;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.felix.scr.annotations.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-import org.apache.felix.scr.annotations.Modified;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.ReferenceCardinality;
-import org.jboss.netty.util.HashedWheelTimer;
-import org.jboss.netty.util.Timeout;
-import org.jboss.netty.util.TimerTask;
-import org.onlab.util.Timer;
-import org.onosproject.core.ApplicationId;
-import org.onosproject.net.DeviceId;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.FlowRuleBatchOperation;
-import org.onosproject.net.flow.FlowRuleProvider;
-import org.onosproject.net.flow.FlowRuleProviderRegistry;
-import org.onosproject.net.flow.FlowRuleProviderService;
-import org.onosproject.net.provider.AbstractProvider;
-import org.onosproject.net.provider.ProviderId;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.AccessList;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.AccessListBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.AccessListEntries;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.AccessListEntriesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.ActionsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.Matches;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.MatchesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.actions.packet.handling.DenyBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.actions.packet.handling.PermitBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.AceIp;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.AceIpBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip.ace.ip.version.AceIpv4Builder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.DestinationPortRange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.DestinationPortRangeBuilder;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.SourcePortRange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.SourcePortRangeBuilder;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-
-/**
- * Netconf provider to accept any flow and report them.
- */
-@Component(immediate = true)
-public class NetconfFlowRuleProvider extends AbstractProvider
- implements FlowRuleProvider {
- private final Logger log = getLogger(getClass());
-
- @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
- protected FlowRuleProviderRegistry providerRegistry;
-
- private ConcurrentMap<DeviceId, Set<FlowEntry>> flowTable = new ConcurrentHashMap<>();
-
- private FlowRuleProviderService providerService;
-
- private XmlBuilder xmlBuilder;
-
- private AceIp aceIp;
- private SourcePortRange srcPortRange;
- private DestinationPortRange destPortRange;
- private Matches matches;
- private HashedWheelTimer timer = Timer.getTimer();
- private Timeout timeout;
- private static final String ACL_NAME_KEY = "acl-name";
- private static final String ACL_LIST_ENTRIES_RULE_NAME_KEY = "access-list-entries.rule-name";
- private static final String ACL_LIST_SP_LOWER_KEY = "source-port-range.lower-port";
- private static final String ACL_LIST_SP_UPPER_KEY = "source-port-range.upper-port";
- private static final String ACL_LIST_DP_LOWER_KEY = "destination-port-range.lower-port";
- private static final String ACL_LIST_DP_UPPER_KEY = "destination-port-range.upper-port";
- private static final String ACL_LIST_DEST_IPV4_KEY = "matches.destination-ipv4-address";
- private static final String ACL_LIST_SRC_IPV4_KEY = "matches.source-ipv4-address";
- private static final String ACL_LIST_ACTIONS_KEY = "actions";
-
- public NetconfFlowRuleProvider() {
- super(new ProviderId("netconf", "org.onosproject.provider.netconf"));
- }
-
- @Activate
- public void activate(ComponentContext context) {
- providerService = providerRegistry.register(this);
- timeout = timer.newTimeout(new StatisticTask(), 5, TimeUnit.SECONDS);
- applyRule();
- modified(context);
- log.info("Started");
- }
-
- @Deactivate
- public void deactivate() {
- providerRegistry.unregister(this);
- providerService = null;
- timeout.cancel();
- log.info("Stopped");
- }
-
- @Modified
- public void modified(ComponentContext context) {
- if (xmlBuilder == null) {
- xmlBuilder = new XmlBuilder();
- }
- if (context == null) {
- log.info("No configuration file");
- return;
- }
- Dictionary<?, ?> properties = context.getProperties();
- String deviceEntry = get(properties, "devConfigs");
- log.info("Settings: devConfigs={}", deviceEntry);
- Enumeration<?> elements = properties.keys();
- Object nextElement = elements.nextElement();
- while (elements.hasMoreElements()) {
- if (nextElement instanceof String) {
- log.info("key::" + nextElement + ", value::"
- + get(properties, (String) nextElement));
- }
- nextElement = elements.nextElement();
- }
- if (!isNullOrEmpty(deviceEntry)) {
- Map<String, String> deviceMap = processDeviceEntry(deviceEntry);
- AccessList accessList = buildAccessList(properties);
- String xmlMsg = xmlBuilder.buildAclRequestXml(accessList);
- log.info("The resultant xml from the builder\n" + xmlMsg);
- NetconfOperation netconfOperation = new NetconfOperation();
- netconfOperation.sendXmlMessage(xmlMsg, deviceMap.get("username"),
- deviceMap.get("password"),
- deviceMap.get("hostIp"), Integer
- .parseInt(deviceMap
- .get("hostPort")));
- }
- }
-
- /**
- * @param properties
- * @return accessList
- */
- private AccessList buildAccessList(Dictionary<?, ?> properties) {
- /**
- * Populating Access List.
- */
- AccessListBuilder abuilder = new AccessListBuilder();
- String aclName = get(properties, ACL_NAME_KEY);
- if (aclName != null) {
- abuilder.setAclName(aclName);
- }
- AccessList accessList = abuilder.build();
- abuilder.setAccessListEntries(getAccessListEntries(properties, matches));
- srcPortRange = getSourcePortRange(properties);
- destPortRange = getDestinationPortRange(properties);
- aceIp = getAceIp(properties, srcPortRange, destPortRange);
- matches = getMatches(properties);
- return accessList;
- }
-
- /**
- * @param properties
- * @return matches
- */
- private Matches getMatches(Dictionary<?, ?> properties) {
- /**
- * Building Matches for given ACL model.
- */
- MatchesBuilder matchesBuilder = new MatchesBuilder();
- if (aceIp != null) {
- matchesBuilder.setAceType(aceIp);
- }
- matches = matchesBuilder.build();
- return matches;
- }
-
- /**
- * @param properties
- * @return srcPortRange
- */
- private SourcePortRange getSourcePortRange(Dictionary<?, ?> properties) {
- /**
- * Building Source Port Range for given ACL model.
- */
- String spRangeLowerStr = get(properties, ACL_LIST_SP_LOWER_KEY);
- String spRangeUpperStr = get(properties, ACL_LIST_SP_UPPER_KEY);
- SourcePortRangeBuilder srcPortRangeBuilder = new SourcePortRangeBuilder();
- if (spRangeLowerStr != null) {
- int spRangeLower = Integer.parseInt(spRangeLowerStr);
- srcPortRangeBuilder.setLowerPort(new PortNumber(spRangeLower));
- }
- if (spRangeUpperStr != null) {
- int spRangeUpper = Integer.parseInt(spRangeUpperStr);
- srcPortRangeBuilder.setUpperPort(new PortNumber(spRangeUpper));
- }
- srcPortRange = srcPortRangeBuilder.build();
- return srcPortRange;
- }
-
- /**
- * @param properties
- * @return destPortRange
- */
- private DestinationPortRange getDestinationPortRange(Dictionary<?, ?> properties) {
- /**
- * Building Destination Port Range for given ACL model.
- */
- String dpRangeLowerStr = get(properties, ACL_LIST_DP_LOWER_KEY);
- String dpRangeUpperStr = get(properties, ACL_LIST_DP_UPPER_KEY);
- DestinationPortRangeBuilder destPortRangeBuilder = new DestinationPortRangeBuilder();
- if (dpRangeLowerStr != null) {
- int dpRangeLower = Integer.parseInt(dpRangeLowerStr);
- destPortRangeBuilder.setLowerPort(new PortNumber(dpRangeLower));
- }
- if (dpRangeUpperStr != null) {
- int dpRangeUpper = Integer.parseInt(dpRangeUpperStr);
- destPortRangeBuilder.setUpperPort(new PortNumber(dpRangeUpper));
- }
- destPortRange = destPortRangeBuilder.build();
- return destPortRange;
- }
-
- /**
- * @param properties
- * @return accessListEntries
- */
- private List<AccessListEntries> getAccessListEntries(Dictionary<?, ?> properties,
- Matches matches) {
- /**
- * Build and Populate Access List Entries.
- */
- AccessListEntriesBuilder acLListEntriesBuilder = new AccessListEntriesBuilder();
- String aclListEntriesRuleName = get(properties,
- ACL_LIST_ENTRIES_RULE_NAME_KEY);
- if (aclListEntriesRuleName != null) {
- acLListEntriesBuilder.setRuleName(aclListEntriesRuleName);
- }
- acLListEntriesBuilder.setMatches(matches);
- String aclActions = get(properties, ACL_LIST_ACTIONS_KEY);
- if (aclActions != null) {
- ActionsBuilder actionBuilder = new ActionsBuilder();
- if (aclActions.equalsIgnoreCase("deny")) {
- DenyBuilder denyBuilder = new DenyBuilder();
- actionBuilder.setPacketHandling(denyBuilder.build());
- } else if (aclActions.equalsIgnoreCase("permit")) {
- PermitBuilder permitBuilder = new PermitBuilder();
- actionBuilder.setPacketHandling(permitBuilder.build());
- }
- acLListEntriesBuilder.setActions(actionBuilder.build());
- }
- AccessListEntries aclListEntries = acLListEntriesBuilder.build();
- List<AccessListEntries> accessListEntries = new ArrayList<AccessListEntries>();
- accessListEntries.add(aclListEntries);
- return accessListEntries;
- }
-
- /**
- * @param properties
- * @return aceIp
- */
- private AceIp getAceIp(Dictionary<?, ?> properties,
- SourcePortRange srcPortRange,
- DestinationPortRange destPortRange) {
- /**
- * Building Ace IPV4 Type
- */
- String destIpv4 = get(properties, ACL_LIST_DEST_IPV4_KEY);
- String srcIpv4 = get(properties, ACL_LIST_SRC_IPV4_KEY);
- AceIpv4Builder aceIpv4Builder = new AceIpv4Builder();
- aceIp = null;
- if (destIpv4 != null) {
- Ipv4Prefix destinationIp = new Ipv4Prefix(destIpv4);
- aceIpv4Builder.setDestinationIpv4Address(destinationIp);
- }
- if (srcIpv4 != null) {
- Ipv4Prefix sourceIp = new Ipv4Prefix(srcIpv4);
- aceIpv4Builder.setSourceIpv4Address(sourceIp);
- }
- if (destIpv4 != null || srcIpv4 != null) {
- AceIpv4 aceIpv4 = aceIpv4Builder.build();
- AceIpBuilder aceIpBuilder = new AceIpBuilder();
- aceIpBuilder.setAceIpVersion(aceIpv4);
- aceIpBuilder.setSourcePortRange(srcPortRange);
- aceIpBuilder.setDestinationPortRange(destPortRange);
- aceIp = aceIpBuilder.build();
- }
- return aceIp;
- }
-
- /**
- * @param deviceEntry
- * @return deviceMap
- */
- private Map<String, String> processDeviceEntry(String deviceEntry) {
- if (deviceEntry == null) {
- log.info("No content for Device Entry, so cannot proceed further.");
- return null;
- }
-
- Map<String, String> deviceMap = new HashMap<String, String>();
- log.info("Trying to convert Device Entry String: " + deviceEntry
- + " to a Netconf Device Object");
- try {
- URI uri = new URI(deviceEntry);
- String path = uri.getPath();
- String userInfo = path.substring(path.lastIndexOf('@'));
- String hostInfo = path.substring(path.lastIndexOf('@') + 1);
- String[] infoSplit = userInfo.split(":");
- String username = infoSplit[0];
- String password = infoSplit[1];
- infoSplit = hostInfo.split(":");
- String hostIp = infoSplit[0];
- String hostPort = infoSplit[1];
- if (isNullOrEmpty(username) || isNullOrEmpty(password)
- || isNullOrEmpty(hostIp) || isNullOrEmpty(hostPort)) {
- log.warn("Bad Configuration Data: both user and device"
- + " information parts of Configuration " + deviceEntry
- + " should be non-nullable");
- } else {
- deviceMap.put("hostIp", hostIp);
- deviceMap.put("hostPort", hostPort);
- deviceMap.put("username", username);
- deviceMap.put("password", password);
- }
- } catch (ArrayIndexOutOfBoundsException aie) {
- log.error("Error while reading config infromation from the config file: "
- + "The user, host and device state infomation should be "
- + "in the order 'userInfo@hostInfo:deviceState'"
- + deviceEntry, aie);
- } catch (URISyntaxException urie) {
- log.error("Error while parsing config information for the device entry: "
- + "Illegal character in path " + deviceEntry,
- urie);
- } catch (Exception e) {
- log.error("Error while parsing config information for the device entry: "
- + deviceEntry, e);
- }
- return deviceMap;
- }
-
- @Override
- public void applyFlowRule(FlowRule... flowRules) {
- }
-
- @Override
- public void removeFlowRule(FlowRule... flowRules) {
- }
-
- private void applyRule() {
- // applyFlowRule(flowRules);//currentl
- }
-
- @Override
- public void removeRulesById(ApplicationId id, FlowRule... flowRules) {
- log.info("removal by app id not supported in null provider");
- }
-
- @Override
- public void executeBatch(FlowRuleBatchOperation batch) {
-
- }
-
- private class StatisticTask implements TimerTask {
-
- @Override
- public void run(Timeout to) throws Exception {
- for (DeviceId devId : flowTable.keySet()) {
- providerService.pushFlowMetrics(devId, flowTable
- .getOrDefault(devId, Collections.emptySet()));
- }
- timeout = timer.newTimeout(to.getTask(), 5, TimeUnit.SECONDS);
-
- }
- }
-}
diff --git a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfOperation.java b/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfOperation.java
deleted file mode 100644
index 4e5a2752..00000000
--- a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/NetconfOperation.java
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.provider.netconf.flow.impl;
-
-import static org.onlab.util.Tools.delay;
-import static org.slf4j.LoggerFactory.getLogger;
-
-import java.io.IOException;
-
-import org.slf4j.Logger;
-
-import com.tailf.jnc.Capabilities;
-import com.tailf.jnc.JNCException;
-import com.tailf.jnc.SSHConnection;
-import com.tailf.jnc.SSHSession;
-
-/**
- * This is to carry necessary information to connect and execute NETCONF
- * operations.
- */
-public class NetconfOperation {
- private final Logger log = getLogger(NetconfOperation.class);
- private static final int EVENTINTERVAL = 2000;
- private static final int CONNECTION_CHECK_INTERVAL = 3;
- private static final String INPUT_HELLO_XML_MSG = new StringBuilder(
- "<?xml version=\"1.0\" encoding=\"UTF-8\"?>")
- .append("<hello xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">")
- .append("<capabilities><capability>urn:ietf:params:netconf:base:1.0</capability>")
- .append("</capabilities></hello>").toString();
-
- /**
- * This will send a Xml message to the device.
- * @param xmlMsg XML to send
- * @param username user name
- * @param password pass word
- * @param deviceIp ip address of the device
- * @param devicePort port on the device
- */
- protected void sendXmlMessage(String xmlMsg, String username,
- String password, String deviceIp,
- Integer devicePort) {
- SSHSession ssh = null;
- try {
- SSHConnection sshConnection = getConnection(username, password,
- deviceIp, devicePort);
- ssh = new SSHSession(sshConnection);
- executeMessage(ssh, INPUT_HELLO_XML_MSG);
- /*
- * execute acl message
- */
- executeMessage(ssh, xmlMsg);
-
- } catch (IOException e) {
- log.error("Unable to send Hello Message to the device: ", e);
- } catch (JNCException e) {
- log.error("Authentication fail while sending Hello Message to the device: ",
- e);
- } catch (Exception e) {
- log.error("Unable to send Hello Message to the device: ", e);
- } finally {
- log.debug("Closing the session after successful execution");
- if (ssh != null) {
- ssh.close();
- }
- }
- }
-
- private void executeMessage(SSHSession ssh, String xmlMsg)
- throws IOException, JNCException {
- String helloRequestXML = xmlMsg.trim();
-
- log.debug("Sending Hello");
- ssh.print(helloRequestXML);
- ssh.flush();
- String xmlResponse = null;
- int i = CONNECTION_CHECK_INTERVAL;
- while (!ssh.ready() && i > 0) {
- delay(EVENTINTERVAL);
- i--;
- }
-
- if (ssh.ready()) {
- StringBuffer readOne = ssh.readOne();
- if (readOne == null) {
- log.error("The Hello Contains No Capabilites");
- throw new JNCException(
- JNCException.SESSION_ERROR,
- "server does not support NETCONF base capability: "
- + Capabilities.NETCONF_BASE_CAPABILITY);
- } else {
- xmlResponse = readOne.toString().trim();
-
- log.debug("Reading Capabilities: "
- + ssh.getSSHConnection().getGanymedConnection()
- .getHostname());
- }
- }
- }
-
- /**
- * To establish SSH Connection.
- *
- * @param username user name
- * @param password pass word
- * @param sshHost host
- * @param sshPort port
- * @return new SSH connection
- * @throws IOException if connection fails
- * @throws JNCException if connection causes an error
- */
- public SSHConnection getConnection(String username, String password,
- String sshHost, Integer sshPort)
- throws IOException, JNCException {
- SSHConnection sshConnection;
- try {
- sshConnection = new SSHConnection(sshHost, sshPort);
- sshConnection.authenticateWithPassword(username, password);
- } catch (IOException e) {
- log.error("Unable to create a connection to the device: ");
- throw e;
- } catch (JNCException e) {
- log.error("Failed to connect to the device: ");
- throw e;
- }
- return sshConnection;
- }
-
-}
diff --git a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/XmlBuilder.java b/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/XmlBuilder.java
deleted file mode 100644
index 389f1669..00000000
--- a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/XmlBuilder.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * Copyright 2015 Open Networking Laboratory
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.onosproject.provider.netconf.flow.impl;
-
-import static org.slf4j.LoggerFactory.getLogger;
-
-import org.jdom2.Document;
-import org.jdom2.Element;
-import org.jdom2.Namespace;
-import org.jdom2.output.Format;
-import org.jdom2.output.XMLOutputter;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.AccessList;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.AceType;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.AceEth;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.AceIp;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip.AceIpVersion;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip.ace.ip.version.AceIpv4;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.acl.rev140520.access.list.access.list.entries.matches.ace.type.ace.ip.ace.ip.version.AceIpv6;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.PortNumber;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.DestinationPortRange;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.packet.fields.rev140625.acl.transport.header.fields.SourcePortRange;
-import org.slf4j.Logger;
-
-/**
- * Xml Builder to generate the xml according to given ACL model.
- */
-public class XmlBuilder {
- private final Logger log = getLogger(XmlBuilder.class);
-
- public String buildAclRequestXml(AccessList accessList) {
- Document doc = new Document();
- Namespace namespaceRpc = Namespace
- .getNamespace("urn:ietf:params:xml:ns:netconf:base:1.0");
- Namespace accessNamespaceRpc = Namespace
- .getNamespace("urn:ietf:params:xml:ns:yang:ietf-acl");
- doc.setRootElement(new Element("rpc", namespaceRpc)
- .setAttribute("message-id", "101"));
-
- /**
- * Access list elements of given ACL model.
- */
- Element access = new Element("access-list", accessNamespaceRpc);
- access.addContent(new Element("acl-name", accessNamespaceRpc)
- .setText(accessList.getAclName()));
- // access.addContent(accessEntries);
-
- if (!accessList.getAccessListEntries().isEmpty()
- && accessList.getAccessListEntries() != null) {
- for (int accessEntryIntVlu = 0; accessEntryIntVlu < accessList
- .getAccessListEntries().size(); accessEntryIntVlu++) {
- access.addContent(getAccessEntries(accessEntryIntVlu,
- accessList,
- accessNamespaceRpc));
- }
- }
-
- /**
- * edit-config operation for given ACL model.
- */
- Element editConfig = new Element("edit-config", namespaceRpc);
- editConfig.addContent(new Element("target", namespaceRpc)
- .addContent(new Element("running", namespaceRpc)));
- editConfig.addContent(new Element("config", Namespace
- .getNamespace("urn:ietf:params:xml:ns:netconf:base:1.0"))
- .addContent(access));
-
- doc.getRootElement().addContent(editConfig);
- XMLOutputter xmlOutputter = new XMLOutputter(Format.getPrettyFormat());
- String outputString = xmlOutputter.outputString(doc);
-
- return outputString;
- }
-
- /**
- * access entries operation for given ACL model.
- */
- private Element getAccessEntries(int accessEntryIntVlu,
- AccessList accessList,
- Namespace accessNamespaceRpc) {
-
- /**
- * Port Number
- */
-
- int srcPortRangeLower = 0;
- int srcPortRangeUpper = 0;
- int destPortRangeLower = 0;
- int destPortRangeUpper = 0;
-
- String sourceIpAdd = "";
- String destinationIpAdd = "";
-
- /*
- * checking accessList is null or not
- */
- if (accessList != null) {
- /*
- * checking list entries are empty or null
- */
- if (!accessList.getAccessListEntries().isEmpty()
- && accessList.getAccessListEntries() != null) {
- AceType aceType = accessList.getAccessListEntries()
- .get(accessEntryIntVlu).getMatches().getAceType();
-
- if (aceType instanceof AceIp) {
- AceIp aceIp = (AceIp) aceType;
- SourcePortRange sourcePortRange = aceIp
- .getSourcePortRange();
- if (sourcePortRange != null) {
- PortNumber lowerPort = sourcePortRange.getLowerPort();
- PortNumber upperPort = sourcePortRange.getUpperPort();
-
- if (lowerPort != null) {
- srcPortRangeLower = lowerPort.getValue();
- }
- if (upperPort != null) {
- srcPortRangeUpper = upperPort.getValue();
- }
- }
- DestinationPortRange destinationPortRange = aceIp
- .getDestinationPortRange();
-
- if (destinationPortRange != null) {
- PortNumber lowerPort = destinationPortRange
- .getLowerPort();
- if (lowerPort != null) {
- destPortRangeLower = lowerPort.getValue();
- }
-
- PortNumber upperPort = destinationPortRange
- .getUpperPort();
- if (upperPort != null) {
- destPortRangeUpper = upperPort.getValue();
- }
-
- }
-
- AceIpVersion aceIpVersion = aceIp.getAceIpVersion();
- if (aceIpVersion instanceof AceIpv4) {
- AceIpv4 obj = (AceIpv4) aceIpVersion;
- destinationIpAdd = obj.getDestinationIpv4Address()
- .getValue();
- sourceIpAdd = obj.getSourceIpv4Address().getValue();
- } else if (aceIpVersion instanceof AceIpv6) {
- AceIpv6 obj = (AceIpv6) aceIpVersion;
- destinationIpAdd = obj.getDestinationIpv6Address()
- .getValue();
- sourceIpAdd = obj.getSourceIpv6Address().getValue();
- }
- } else if (aceType instanceof AceEth) {
- log.debug("Need to add execution loging for Ace Type Ethernet");
- }
- }
- }
-
- /**
- * Matches elements to define IP address & Port range for given ACL
- * model.
- */
- Element matchesElement = new Element("matches", accessNamespaceRpc);
- if (String.valueOf(srcPortRangeLower) != null
- && !String.valueOf(srcPortRangeLower).isEmpty()) {
-
- matchesElement.addContent(new Element("source-port-range",
- accessNamespaceRpc)
- .addContent(new Element("lower-port", accessNamespaceRpc)
- .setText(String.valueOf(srcPortRangeLower))));
-
- matchesElement.addContent(new Element("source-port-range",
- accessNamespaceRpc)
- .addContent(new Element("upper-port", accessNamespaceRpc)
- .setText(String.valueOf(srcPortRangeUpper))));
-
- matchesElement.addContent(new Element("destination-port-range",
- accessNamespaceRpc)
- .addContent(new Element("lower-port", accessNamespaceRpc)
- .setText(String.valueOf(destPortRangeLower))));
-
- matchesElement.addContent(new Element("destination-port-range",
- accessNamespaceRpc)
- .addContent(new Element("upper-port", accessNamespaceRpc)
- .setText(String.valueOf(destPortRangeUpper))));
- }
-
- if (destinationIpAdd != null && !destinationIpAdd.isEmpty()) {
- matchesElement.addContent(new Element("destination-ipv4-address",
- accessNamespaceRpc)
- .setText(destinationIpAdd));
- }
- if (sourceIpAdd != null && !sourceIpAdd.isEmpty()) {
- matchesElement.addContent(new Element("source-ipv4-address",
- accessNamespaceRpc)
- .setText(sourceIpAdd));
- }
-
- /**
- * Access entries elements for given ACL model.
- */
- Element accessEntries = new Element("access-list-entries",
- accessNamespaceRpc);
- accessEntries.addContent(new Element("rule-name", accessNamespaceRpc)
- .setText(accessList.getAccessListEntries()
- .get(accessEntryIntVlu).getRuleName()));
- accessEntries.addContent(matchesElement);
- accessEntries.addContent(new Element("actions", accessNamespaceRpc)
- .addContent(new Element("deny", accessNamespaceRpc)));
-
- return accessEntries;
- }
-}
diff --git a/framework/src/onos/providers/netconf/pom.xml b/framework/src/onos/providers/netconf/pom.xml
index f73940fe..8c4681df 100644
--- a/framework/src/onos/providers/netconf/pom.xml
+++ b/framework/src/onos/providers/netconf/pom.xml
@@ -34,7 +34,6 @@
<modules>
<module>device</module>
<module>app</module>
- <module>flow</module>
</modules>
<dependencies>
diff --git a/framework/src/onos/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java b/framework/src/onos/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
index c5688419..68c536b9 100644
--- a/framework/src/onos/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
+++ b/framework/src/onos/providers/null/src/main/java/org/onosproject/provider/nil/NullProviders.java
@@ -168,7 +168,7 @@ public class NullProviders {
@Activate
- public void activate(ComponentContext context) {
+ public void activate() {
cfgService.registerProperties(getClass());
deviceProviderService = deviceProviderRegistry.register(deviceProvider);
@@ -180,7 +180,7 @@ public class NullProviders {
}
@Deactivate
- public void deactivate(ComponentContext context) {
+ public void deactivate() {
cfgService.unregisterProperties(getClass(), false);
tearDown();
diff --git a/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java b/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
index a7e334f4..4ceb425c 100644
--- a/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
+++ b/framework/src/onos/providers/openflow/device/src/main/java/org/onosproject/provider/of/device/impl/OpenFlowDeviceProvider.java
@@ -516,7 +516,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
&& !port.getConfig().contains(OFPortConfig.PORT_DOWN);
- SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+ SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
OFExpPortDescPropOpticalTransport firstProp = port.getProperties().get(0);
OFPortOpticalTransportSignalType sigType = firstProp.getPortSignalType();
@@ -560,16 +560,19 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
/**
* Creates an annotation for the port name if one is available.
*
- * @param port description of the port
+ * @param portName the port name
+ * @param portMac the port mac
* @return annotation containing the port name if one is found,
* null otherwise
*/
- private SparseAnnotations makePortNameAnnotation(String port) {
+ private SparseAnnotations makePortAnnotation(String portName, String portMac) {
SparseAnnotations annotations = null;
- String portName = Strings.emptyToNull(port);
+ String pName = Strings.emptyToNull(portName);
+ String pMac = Strings.emptyToNull(portMac);
if (portName != null) {
annotations = DefaultAnnotations.builder()
- .set(AnnotationKeys.PORT_NAME, portName).build();
+ .set(AnnotationKeys.PORT_NAME, pName)
+ .set(AnnotationKeys.PORT_MAC, pMac).build();
}
return annotations;
}
@@ -586,7 +589,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
!port.getState().contains(OFPortState.LINK_DOWN) &&
!port.getConfig().contains(OFPortConfig.PORT_DOWN);
Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
- SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+ SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
return new DefaultPortDescription(portNo, enabled, type,
portSpeed(port), annotations);
}
@@ -607,7 +610,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
&& !port.getConfig().contains(OFPortConfig.PORT_DOWN);
- SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+ SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
if (port.getVersion() == OFVersion.OF_13
&& ptype == PortDescPropertyType.OPTICAL_TRANSPORT) {
@@ -649,7 +652,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
// FIXME when Calient OF agent reports port status
boolean enabled = true;
- SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+ SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
// S160 data sheet
// Wavelength range: 1260 - 1630 nm, grid is irrelevant for this type of switch
@@ -664,7 +667,7 @@ public class OpenFlowDeviceProvider extends AbstractProvider implements DevicePr
} else {
PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
- SparseAnnotations annotations = makePortNameAnnotation(port.getName());
+ SparseAnnotations annotations = makePortAnnotation(port.getName(), port.getHwAddr().toString());
return new DefaultPortDescription(portNo, false, type,
portSpeed(port), annotations);
}
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
index d4494f18..b12d8a60 100644
--- a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowEntryBuilder.java
@@ -27,6 +27,7 @@ import org.onlab.packet.VlanId;
import org.onosproject.core.DefaultGroupId;
import org.onosproject.net.DeviceId;
import org.onosproject.net.Lambda;
+import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.DefaultDriverData;
import org.onosproject.net.driver.DefaultDriverHandler;
@@ -83,15 +84,21 @@ import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.U8;
import org.projectfloodlight.openflow.types.VlanPcp;
+import org.projectfloodlight.openflow.types.OduSignalID;
import org.slf4j.Logger;
import java.util.List;
import static org.onosproject.net.flow.criteria.Criteria.matchLambda;
import static org.onosproject.net.flow.criteria.Criteria.matchOchSignalType;
+import static org.onosproject.net.flow.criteria.Criteria.matchOduSignalType;
+import static org.onosproject.net.flow.criteria.Criteria.matchOduSignalId;
+import static org.onosproject.net.flow.instructions.Instructions.modL0Lambda;
+import static org.onosproject.net.flow.instructions.Instructions.modL1OduSignalId;
import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupChannelSpacing;
import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupGridType;
import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupOchSignalType;
+import static org.onosproject.provider.of.flow.impl.OpenFlowValueMapper.lookupOduSignalType;
import static org.slf4j.LoggerFactory.getLogger;
public class FlowEntryBuilder {
@@ -454,6 +461,29 @@ public class FlowEntryBuilder {
builder.extension(interpreter.mapAction(action), DeviceId.deviceId(Dpid.uri(dpid)));
}
break;
+ case EXP_ODU_SIG_ID:
+ @SuppressWarnings("unchecked")
+ OFOxm<OduSignalID> oduID = (OFOxm<OduSignalID>) oxm;
+ OduSignalID oduSignalID = oduID.getValue();
+ OduSignalId oduSignalId = OduSignalId.oduSignalId(oduSignalID.getTpn(),
+ oduSignalID.getTslen(),
+ oduSignalID.getTsmap());
+ builder.add(modL1OduSignalId(oduSignalId));
+ break;
+ case EXP_OCH_SIG_ID:
+ try {
+ @SuppressWarnings("unchecked")
+ OFOxm<CircuitSignalID> ochId = (OFOxm<CircuitSignalID>) oxm;
+ CircuitSignalID circuitSignalID = ochId.getValue();
+ builder.add(modL0Lambda(Lambda.ochSignal(
+ lookupGridType(circuitSignalID.getGridType()),
+ lookupChannelSpacing(circuitSignalID.getChannelSpacing()),
+ circuitSignalID.getChannelNumber(), circuitSignalID.getSpectralWidth())));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ break;
+ }
+ break;
case ARP_OP:
case ARP_SHA:
case ARP_SPA:
@@ -501,6 +531,8 @@ public class FlowEntryBuilder {
case OCH_SIGTYPE_BASIC:
case SCTP_DST:
case SCTP_SRC:
+ case EXP_ODU_SIGTYPE:
+ case EXP_OCH_SIGTYPE:
default:
log.warn("Set field type {} not yet implemented.", oxm.getMatchField().id);
break;
@@ -704,6 +736,41 @@ public class FlowEntryBuilder {
U8 sigType = match.get(MatchField.OCH_SIGTYPE);
builder.add(matchOchSignalType(lookupOchSignalType((byte) sigType.getValue())));
break;
+ case EXP_OCH_SIG_ID:
+ try {
+ CircuitSignalID expSigId = match.get(MatchField.EXP_OCH_SIG_ID);
+ builder.add(matchLambda(Lambda.ochSignal(
+ lookupGridType(expSigId.getGridType()), lookupChannelSpacing(expSigId.getChannelSpacing()),
+ expSigId.getChannelNumber(), expSigId.getSpectralWidth())));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ break;
+ }
+ break;
+ case EXP_OCH_SIGTYPE:
+ try {
+ U8 expOchSigType = match.get(MatchField.EXP_OCH_SIGTYPE);
+ builder.add(matchOchSignalType(lookupOchSignalType((byte) expOchSigType.getValue())));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ break;
+ }
+ break;
+ case EXP_ODU_SIG_ID:
+ OduSignalId oduSignalId = OduSignalId.oduSignalId(match.get(MatchField.EXP_ODU_SIG_ID).getTpn(),
+ match.get(MatchField.EXP_ODU_SIG_ID).getTslen(),
+ match.get(MatchField.EXP_ODU_SIG_ID).getTsmap());
+ builder.add(matchOduSignalId(oduSignalId));
+ break;
+ case EXP_ODU_SIGTYPE:
+ try {
+ U8 oduSigType = match.get(MatchField.EXP_ODU_SIGTYPE);
+ builder.add(matchOduSignalType(lookupOduSignalType((byte) oduSigType.getValue())));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ break;
+ }
+ break;
case TUNNEL_ID:
long tunnelId = match.get(MatchField.TUNNEL_ID).getValue();
builder.matchTunnelId(tunnelId);
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
index 2a8d2010..dcd7b0fc 100644
--- a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilder.java
@@ -20,8 +20,13 @@ import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.Ip6Prefix;
import org.onlab.packet.VlanId;
+import org.onosproject.net.DeviceId;
import org.onosproject.net.OchSignal;
+import org.onosproject.net.driver.DefaultDriverData;
+import org.onosproject.net.driver.DefaultDriverHandler;
+import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverService;
+import org.onosproject.net.OduSignalId;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.criteria.ArpHaCriterion;
@@ -30,6 +35,8 @@ import org.onosproject.net.flow.criteria.ArpPaCriterion;
import org.onosproject.net.flow.criteria.Criterion;
import org.onosproject.net.flow.criteria.EthCriterion;
import org.onosproject.net.flow.criteria.EthTypeCriterion;
+import org.onosproject.net.flow.criteria.ExtensionCriterion;
+import org.onosproject.net.flow.criteria.ExtensionSelector;
import org.onosproject.net.flow.criteria.IPCriterion;
import org.onosproject.net.flow.criteria.IPDscpCriterion;
import org.onosproject.net.flow.criteria.IPEcnCriterion;
@@ -47,6 +54,8 @@ import org.onosproject.net.flow.criteria.MplsBosCriterion;
import org.onosproject.net.flow.criteria.MplsCriterion;
import org.onosproject.net.flow.criteria.OchSignalCriterion;
import org.onosproject.net.flow.criteria.OchSignalTypeCriterion;
+import org.onosproject.net.flow.criteria.OduSignalIdCriterion;
+import org.onosproject.net.flow.criteria.OduSignalTypeCriterion;
import org.onosproject.net.flow.criteria.PortCriterion;
import org.onosproject.net.flow.criteria.SctpPortCriterion;
import org.onosproject.net.flow.criteria.TcpPortCriterion;
@@ -54,12 +63,14 @@ import org.onosproject.net.flow.criteria.TunnelIdCriterion;
import org.onosproject.net.flow.criteria.UdpPortCriterion;
import org.onosproject.net.flow.criteria.VlanIdCriterion;
import org.onosproject.net.flow.criteria.VlanPcpCriterion;
+import org.onosproject.openflow.controller.ExtensionSelectorInterpreter;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFFlowDelete;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.match.MatchField;
+import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
import org.projectfloodlight.openflow.types.ArpOpcode;
import org.projectfloodlight.openflow.types.CircuitSignalID;
import org.projectfloodlight.openflow.types.EthType;
@@ -84,6 +95,7 @@ import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.U8;
import org.projectfloodlight.openflow.types.VlanPcp;
import org.projectfloodlight.openflow.types.VlanVid;
+import org.projectfloodlight.openflow.types.OduSignalID;
import org.slf4j.Logger;
import java.util.Optional;
@@ -102,6 +114,7 @@ public abstract class FlowModBuilder {
private final TrafficSelector selector;
protected final Long xid;
protected final Optional<DriverService> driverService;
+ protected final DeviceId deviceId;
/**
* Creates a new flow mod builder.
@@ -142,6 +155,7 @@ public abstract class FlowModBuilder {
this.selector = flowRule.selector();
this.xid = xid.orElse(0L);
this.driverService = driverService;
+ this.deviceId = flowRule.deviceId();
}
/**
@@ -398,7 +412,7 @@ public abstract class FlowModBuilder {
OchSignal signal = ochSignalCriterion.lambda();
byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
- mBuilder.setExact(MatchField.OCH_SIGID,
+ mBuilder.setExact(MatchField.EXP_OCH_SIG_ID,
new CircuitSignalID(gridType, channelSpacing,
(short) signal.spacingMultiplier(), (short) signal.slotGranularity()));
} catch (NoMappingFoundException e) {
@@ -406,9 +420,30 @@ public abstract class FlowModBuilder {
}
break;
case OCH_SIGTYPE:
- OchSignalTypeCriterion sc = (OchSignalTypeCriterion) c;
- byte signalType = OpenFlowValueMapper.lookupOchSignalType(sc.signalType());
- mBuilder.setExact(MatchField.OCH_SIGTYPE, U8.of(signalType));
+ try {
+ OchSignalTypeCriterion sc = (OchSignalTypeCriterion) c;
+ byte signalType = OpenFlowValueMapper.lookupOchSignalType(sc.signalType());
+ mBuilder.setExact(MatchField.EXP_OCH_SIGTYPE, U8.of(signalType));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ }
+ break;
+ case ODU_SIGID:
+ OduSignalIdCriterion oduSignalIdCriterion = (OduSignalIdCriterion) c;
+ OduSignalId oduSignalId = oduSignalIdCriterion.oduSignalId();
+ mBuilder.setExact(MatchField.EXP_ODU_SIG_ID,
+ new OduSignalID((short) oduSignalId.tributaryPortNumber(),
+ (short) oduSignalId.tributarySlotLength(),
+ oduSignalId.tributarySlotBitmap()));
+ break;
+ case ODU_SIGTYPE:
+ try {
+ OduSignalTypeCriterion oduSignalTypeCriterion = (OduSignalTypeCriterion) c;
+ byte oduSigType = OpenFlowValueMapper.lookupOduSignalType(oduSignalTypeCriterion.signalType());
+ mBuilder.setExact(MatchField.EXP_ODU_SIGTYPE, U8.of(oduSigType));
+ } catch (NoMappingFoundException e) {
+ log.warn(e.getMessage());
+ }
break;
case TUNNEL_ID:
TunnelIdCriterion tunnelId = (TunnelIdCriterion) c;
@@ -446,8 +481,24 @@ public abstract class FlowModBuilder {
mBuilder.setExact(MatchField.ARP_TPA,
IPv4Address.of(arpPaCriterion.ip().toInt()));
break;
+ case EXTENSION:
+ ExtensionCriterion extensionCriterion = (ExtensionCriterion) c;
+ OFOxm oxm = buildExtensionOxm(extensionCriterion.extensionSelector());
+ if (oxm == null) {
+ log.warn("Unable to build extension selector");
+ break;
+ }
+
+ if (oxm.isMasked()) {
+ mBuilder.setMasked(oxm.getMatchField(), oxm.getValue(), oxm.getMask());
+ } else {
+ mBuilder.setExact(oxm.getMatchField(), oxm.getValue());
+ }
+
+ break;
case MPLS_TC:
case PBB_ISID:
+ // TODO: need to implement PBB-ISID case when OpenFlowJ is ready
default:
log.warn("Match type {} not yet implemented.", c.type());
}
@@ -473,4 +524,21 @@ public abstract class FlowModBuilder {
return factory;
}
+ private OFOxm buildExtensionOxm(ExtensionSelector extension) {
+ if (!driverService.isPresent()) {
+ log.error("No driver service present");
+ return null;
+ }
+ Driver driver = driverService.get().getDriver(deviceId);
+ if (driver.hasBehaviour(ExtensionSelectorInterpreter.class)) {
+ DefaultDriverHandler handler =
+ new DefaultDriverHandler(new DefaultDriverData(driver, deviceId));
+ ExtensionSelectorInterpreter interpreter = handler.behaviour(ExtensionSelectorInterpreter.class);
+
+ return interpreter.mapSelector(factory(), extension);
+ }
+
+ return null;
+ }
+
}
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
index bdea09da..d4ebb4fd 100644
--- a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
@@ -181,6 +181,7 @@ public class FlowModBuilderVer10 extends FlowModBuilder {
acts.add(queueBuilder.build());
break;
case L0MODIFICATION:
+ case L1MODIFICATION:
case GROUP:
case TABLE:
case METADATA:
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
index 90def432..a3182e72 100644
--- a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
@@ -18,8 +18,8 @@ package org.onosproject.provider.of.flow.impl;
import com.google.common.collect.Lists;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
-import org.onosproject.net.DeviceId;
import org.onosproject.net.OchSignal;
+import org.onosproject.net.OduSignalId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.driver.DefaultDriverData;
import org.onosproject.net.driver.DefaultDriverHandler;
@@ -36,6 +36,8 @@ import org.onosproject.net.flow.instructions.Instructions.SetQueueInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModLambdaInstruction;
import org.onosproject.net.flow.instructions.L0ModificationInstruction.ModOchSignalInstruction;
+import org.onosproject.net.flow.instructions.L1ModificationInstruction;
+import org.onosproject.net.flow.instructions.L1ModificationInstruction.ModOduSignalIdInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModMplsBosInstruction;
@@ -46,6 +48,9 @@ import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanPc
import org.onosproject.net.flow.instructions.L2ModificationInstruction.PushHeaderInstructions;
import org.onosproject.net.flow.instructions.L3ModificationInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpIPInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpEthInstruction;
+import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModArpOpInstruction;
import org.onosproject.net.flow.instructions.L3ModificationInstruction.ModIPv6FlowLabelInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction;
import org.onosproject.net.flow.instructions.L4ModificationInstruction.ModTransportPortInstruction;
@@ -62,6 +67,7 @@ import org.projectfloodlight.openflow.protocol.action.OFActionSetQueue;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.oxm.OFOxm;
+import org.projectfloodlight.openflow.types.ArpOpcode;
import org.projectfloodlight.openflow.types.CircuitSignalID;
import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.IPv4Address;
@@ -73,6 +79,7 @@ import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFGroup;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
+import org.projectfloodlight.openflow.types.OduSignalID;
import org.projectfloodlight.openflow.types.TableId;
import org.projectfloodlight.openflow.types.TransportPort;
import org.projectfloodlight.openflow.types.U32;
@@ -95,7 +102,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
private static final int OFPCML_NO_BUFFER = 0xffff;
private final TrafficTreatment treatment;
- private final DeviceId deviceId;
/**
* Constructor for a flow mod builder for OpenFlow 1.3.
@@ -110,7 +116,6 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
super(flowRule, factory, xid, driverService);
this.treatment = flowRule.treatment();
- this.deviceId = flowRule.deviceId();
}
@Override
@@ -233,6 +238,9 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
case L0MODIFICATION:
actions.add(buildL0Modification(i));
break;
+ case L1MODIFICATION:
+ actions.add(buildL1Modification(i));
+ break;
case L2MODIFICATION:
actions.add(buildL2Modification(i));
break;
@@ -302,20 +310,31 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
private OFAction buildL0Modification(Instruction i) {
L0ModificationInstruction l0m = (L0ModificationInstruction) i;
+ OFOxm<?> oxm = null;
switch (l0m.subtype()) {
case LAMBDA:
return buildModLambdaInstruction((ModLambdaInstruction) i);
case OCH:
try {
- return buildModOchSignalInstruction((ModOchSignalInstruction) i);
+ ModOchSignalInstruction modOchSignalInstruction = (ModOchSignalInstruction) l0m;
+ OchSignal signal = modOchSignalInstruction.lambda();
+ byte gridType = OpenFlowValueMapper.lookupGridType(signal.gridType());
+ byte channelSpacing = OpenFlowValueMapper.lookupChannelSpacing(signal.channelSpacing());
+ oxm = factory().oxms().expOchSigId(
+ new CircuitSignalID(gridType, channelSpacing,
+ (short) signal.spacingMultiplier(), (short) signal.slotGranularity()));
} catch (NoMappingFoundException e) {
log.warn(e.getMessage());
break;
}
+ break;
default:
log.warn("Unimplemented action type {}.", l0m.subtype());
break;
}
+ if (oxm != null) {
+ return factory().actions().buildSetField().setField(oxm).build();
+ }
return null;
}
@@ -335,6 +354,31 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
));
}
+ private OFAction buildL1Modification(Instruction i) {
+ L1ModificationInstruction l1m = (L1ModificationInstruction) i;
+ OFOxm<?> oxm = null;
+ switch (l1m.subtype()) {
+ case ODU_SIGID:
+ ModOduSignalIdInstruction modOduSignalIdInstruction = (ModOduSignalIdInstruction) l1m;
+ OduSignalId oduSignalId = modOduSignalIdInstruction.oduSignalId();
+
+ OduSignalID oduSignalID = new OduSignalID((short) oduSignalId.tributaryPortNumber(),
+ (short) oduSignalId.tributarySlotLength(),
+ oduSignalId.tributarySlotBitmap());
+
+ oxm = factory().oxms().expOduSigId(oduSignalID);
+ break;
+ default:
+ log.warn("Unimplemented action type {}.", l1m.subtype());
+ break;
+ }
+
+ if (oxm != null) {
+ return factory().actions().buildSetField().setField(oxm).build();
+ }
+ return null;
+ }
+
private OFAction buildL2Modification(Instruction i) {
L2ModificationInstruction l2m = (L2ModificationInstruction) i;
ModEtherInstruction eth;
@@ -433,6 +477,19 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
int flowLabel = flowLabelInstruction.flowLabel();
oxm = factory().oxms().ipv6Flabel(IPv6FlowLabel.of(flowLabel));
break;
+ case ARP_SPA:
+ ModArpIPInstruction aip = (ModArpIPInstruction) i;
+ ip4 = aip.ip().getIp4Address();
+ oxm = factory().oxms().arpSpa(IPv4Address.of(ip4.toInt()));
+ break;
+ case ARP_SHA:
+ ModArpEthInstruction ei = (ModArpEthInstruction) i;
+ oxm = factory().oxms().arpSha(MacAddress.of(ei.mac().toLong()));
+ break;
+ case ARP_OP:
+ ModArpOpInstruction oi = (ModArpOpInstruction) i;
+ oxm = factory().oxms().arpOp(ArpOpcode.of((int) oi.op()));
+ break;
case DEC_TTL:
return factory().actions().decNwTtl();
case TTL_IN:
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
index d5186fa9..aa8df947 100644
--- a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/NewAdaptiveFlowStatsCollector.java
@@ -1,882 +1,882 @@
-/*
- * 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.provider.of.flow.impl;
-
-import com.google.common.base.Objects;
-import com.google.common.collect.ImmutableSet;
-import com.google.common.collect.Maps;
-import com.google.common.collect.Sets;
-import org.onosproject.net.flow.DefaultTypedFlowEntry;
-import org.onosproject.net.flow.FlowEntry;
-import org.onosproject.net.flow.FlowId;
-import org.onosproject.net.flow.FlowRule;
-import org.onosproject.net.flow.StoredFlowEntry;
-import org.onosproject.net.flow.TypedStoredFlowEntry;
-import org.onosproject.net.flow.instructions.Instruction;
-import org.onosproject.net.flow.instructions.Instructions;
-import org.onosproject.openflow.controller.OpenFlowSwitch;
-import org.onosproject.openflow.controller.RoleState;
-import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest;
-import org.projectfloodlight.openflow.protocol.match.Match;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.TableId;
-import org.slf4j.Logger;
-
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.Executors;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledFuture;
-import java.util.concurrent.TimeUnit;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static org.onlab.util.Tools.groupedThreads;
-import static org.onosproject.net.flow.TypedStoredFlowEntry.FlowLiveType;
-import static org.slf4j.LoggerFactory.getLogger;
-
-/**
- * Efficiently and adaptively collects flow statistics for the specified switch.
- */
-public class NewAdaptiveFlowStatsCollector {
-
- private final Logger log = getLogger(getClass());
-
- private final OpenFlowSwitch sw;
-
- private ScheduledExecutorService adaptiveFlowStatsScheduler =
- Executors.newScheduledThreadPool(4, groupedThreads("onos/flow", "device-stats-collector-%d"));
- private ScheduledFuture<?> calAndShortFlowsThread;
- private ScheduledFuture<?> midFlowsThread;
- private ScheduledFuture<?> longFlowsThread;
-
- // Task that calculates all flowEntries' FlowLiveType and collects stats IMMEDIATE flows every calAndPollInterval
- private CalAndShortFlowsTask calAndShortFlowsTask;
- // Task that collects stats MID flows every 2*calAndPollInterval
- private MidFlowsTask midFlowsTask;
- // Task that collects stats LONG flows every 3*calAndPollInterval
- private LongFlowsTask longFlowsTask;
-
- private static final int CAL_AND_POLL_TIMES = 1; // must be always 0
- private static final int MID_POLL_TIMES = 2; // variable greater or equal than 1
- private static final int LONG_POLL_TIMES = 3; // variable greater or equal than MID_POLL_TIMES
- //TODO: make ENTIRE_POLL_TIMES configurable with enable or disable
- // must be variable greater or equal than common multiple of MID_POLL_TIMES and LONG_POLL_TIMES
- private static final int ENTIRE_POLL_TIMES = 6;
-
- private static final int DEFAULT_CAL_AND_POLL_FREQUENCY = 5;
- private static final int MIN_CAL_AND_POLL_FREQUENCY = 2;
- private static final int MAX_CAL_AND_POLL_FREQUENCY = 60;
-
- private int calAndPollInterval; // CAL_AND_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
- private int midPollInterval; // MID_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
- private int longPollInterval; // LONG_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
- // only used for checking condition at each task if it collects entire flows from a given switch or not
- private int entirePollInterval; // ENTIRE_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
-
- // Number of call count of each Task,
- // for undoing collection except only entire flows collecting task in CalAndShortFlowsTask
- private int callCountCalAndShortFlowsTask = 0; // increased CAL_AND_POLL_TIMES whenever Task is called
- private int callCountMidFlowsTask = 0; // increased MID_POLL_TIMES whenever Task is called
- private int callCountLongFlowsTask = 0; // increased LONG_POLL_TIMES whenever Task is called
-
- private InternalDeviceFlowTable deviceFlowTable = new InternalDeviceFlowTable();
-
- private boolean isFirstTimeStart = true;
-
- public static final long NO_FLOW_MISSING_XID = (-1);
- private long flowMissingXid = NO_FLOW_MISSING_XID;
-
- /**
- * Creates a new adaptive collector for the given switch and default cal_and_poll frequency.
- *
- * @param sw switch to pull
- * @param pollInterval cal and immediate poll frequency in seconds
- */
- NewAdaptiveFlowStatsCollector(OpenFlowSwitch sw, int pollInterval) {
- this.sw = sw;
-
- initMemberVars(pollInterval);
- }
-
- // check calAndPollInterval validity and set all pollInterval values and finally initialize each task call count
- private void initMemberVars(int pollInterval) {
- if (pollInterval < MIN_CAL_AND_POLL_FREQUENCY) {
- this.calAndPollInterval = MIN_CAL_AND_POLL_FREQUENCY;
- } else if (pollInterval >= MAX_CAL_AND_POLL_FREQUENCY) {
- this.calAndPollInterval = MAX_CAL_AND_POLL_FREQUENCY;
- } else {
- this.calAndPollInterval = pollInterval;
- }
-
- calAndPollInterval = CAL_AND_POLL_TIMES * calAndPollInterval;
- midPollInterval = MID_POLL_TIMES * calAndPollInterval;
- longPollInterval = LONG_POLL_TIMES * calAndPollInterval;
- entirePollInterval = ENTIRE_POLL_TIMES * calAndPollInterval;
-
- callCountCalAndShortFlowsTask = 0;
- callCountMidFlowsTask = 0;
- callCountLongFlowsTask = 0;
-
- flowMissingXid = NO_FLOW_MISSING_XID;
- }
-
- /**
- * Adjusts adaptive poll frequency.
- *
- * @param pollInterval poll frequency in seconds
- */
- synchronized void adjustCalAndPollInterval(int pollInterval) {
- initMemberVars(pollInterval);
-
- if (calAndShortFlowsThread != null) {
- calAndShortFlowsThread.cancel(false);
- }
- if (midFlowsThread != null) {
- midFlowsThread.cancel(false);
- }
- if (longFlowsThread != null) {
- longFlowsThread.cancel(false);
- }
-
- calAndShortFlowsTask = new CalAndShortFlowsTask();
- calAndShortFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
- calAndShortFlowsTask,
- 0,
- calAndPollInterval,
- TimeUnit.SECONDS);
-
- midFlowsTask = new MidFlowsTask();
- midFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
- midFlowsTask,
- 0,
- midPollInterval,
- TimeUnit.SECONDS);
-
- longFlowsTask = new LongFlowsTask();
- longFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
- longFlowsTask,
- 0,
- longPollInterval,
- TimeUnit.SECONDS);
-
- log.debug("calAndPollInterval=" + calAndPollInterval + "is adjusted");
- }
-
- private class CalAndShortFlowsTask implements Runnable {
- @Override
- public void run() {
- if (sw.getRole() == RoleState.MASTER) {
- log.trace("CalAndShortFlowsTask Collecting AdaptiveStats for {}", sw.getStringId());
-
- if (isFirstTimeStart) {
- // isFirstTimeStart, get entire flow stats from a given switch sw
- log.trace("CalAndShortFlowsTask Collecting Entire AdaptiveStats at first time start for {}",
- sw.getStringId());
- ofFlowStatsRequestAllSend();
-
- callCountCalAndShortFlowsTask += CAL_AND_POLL_TIMES;
- isFirstTimeStart = false;
- } else if (callCountCalAndShortFlowsTask == ENTIRE_POLL_TIMES) {
- // entire_poll_times, get entire flow stats from a given switch sw
- log.trace("CalAndShortFlowsTask Collecting Entire AdaptiveStats for {}", sw.getStringId());
- ofFlowStatsRequestAllSend();
-
- callCountCalAndShortFlowsTask = CAL_AND_POLL_TIMES;
- //TODO: check flows deleted in switch, but exist in controller flow table, then remove them
- //
- } else {
- calAndShortFlowsTaskInternal();
- callCountCalAndShortFlowsTask += CAL_AND_POLL_TIMES;
- }
- }
- }
- }
-
- // send openflow flow stats request message with getting all flow entries to a given switch sw
- private void ofFlowStatsRequestAllSend() {
- OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest()
- .setMatch(sw.factory().matchWildcardAll())
- .setTableId(TableId.ALL)
- .setOutPort(OFPort.NO_MASK)
- .build();
-
- synchronized (this) {
- // set the request xid to check the reply in OpenFlowRuleProvider
- // After processing the reply of this request message,
- // this must be set to NO_FLOW_MISSING_XID(-1) by provider
- setFlowMissingXid(request.getXid());
- log.debug("ofFlowStatsRequestAllSend,Request={},for {}", request.toString(), sw.getStringId());
-
- sw.sendMsg(request);
- }
- }
-
- // send openflow flow stats request message with getting the specific flow entry(fe) to a given switch sw
- private void ofFlowStatsRequestFlowSend(FlowEntry fe) {
- // set find match
- Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty(),
- Optional.empty()).buildMatch();
- // set find tableId
- TableId tableId = TableId.of(fe.tableId());
- // set output port
- Instruction ins = fe.treatment().allInstructions().stream()
- .filter(i -> (i.type() == Instruction.Type.OUTPUT))
- .findFirst()
- .orElse(null);
- OFPort ofPort = OFPort.NO_MASK;
- if (ins != null) {
- Instructions.OutputInstruction out = (Instructions.OutputInstruction) ins;
- ofPort = OFPort.of((int) ((out.port().toLong())));
- }
-
- OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest()
- .setMatch(match)
- .setTableId(tableId)
- .setOutPort(ofPort)
- .build();
-
- synchronized (this) {
- if (getFlowMissingXid() != NO_FLOW_MISSING_XID) {
- log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll does not be processed yet,"
- + " set no flow missing xid anyway, for {}",
- sw.getStringId());
- setFlowMissingXid(NO_FLOW_MISSING_XID);
- }
-
- sw.sendMsg(request);
- }
- }
-
- private void calAndShortFlowsTaskInternal() {
- deviceFlowTable.checkAndMoveLiveFlowAll();
-
- deviceFlowTable.getShortFlows().forEach(fe -> {
- ofFlowStatsRequestFlowSend(fe);
- });
- }
-
- private class MidFlowsTask implements Runnable {
- @Override
- public void run() {
- if (sw.getRole() == RoleState.MASTER) {
- log.trace("MidFlowsTask Collecting AdaptiveStats for {}", sw.getStringId());
-
- // skip collecting because CalAndShortFlowsTask collects entire flow stats from a given switch sw
- if (callCountMidFlowsTask == ENTIRE_POLL_TIMES) {
- callCountMidFlowsTask = MID_POLL_TIMES;
- } else {
- midFlowsTaskInternal();
- callCountMidFlowsTask += MID_POLL_TIMES;
- }
- }
- }
- }
-
- private void midFlowsTaskInternal() {
- deviceFlowTable.getMidFlows().forEach(fe -> {
- ofFlowStatsRequestFlowSend(fe);
- });
- }
-
- private class LongFlowsTask implements Runnable {
- @Override
- public void run() {
- if (sw.getRole() == RoleState.MASTER) {
- log.trace("LongFlowsTask Collecting AdaptiveStats for {}", sw.getStringId());
-
- // skip collecting because CalAndShortFlowsTask collects entire flow stats from a given switch sw
- if (callCountLongFlowsTask == ENTIRE_POLL_TIMES) {
- callCountLongFlowsTask = LONG_POLL_TIMES;
- } else {
- longFlowsTaskInternal();
- callCountLongFlowsTask += LONG_POLL_TIMES;
- }
- }
- }
- }
-
- private void longFlowsTaskInternal() {
- deviceFlowTable.getLongFlows().forEach(fe -> {
- ofFlowStatsRequestFlowSend(fe);
- });
- }
-
- /**
- * start adaptive flow statistic collection.
- *
- */
- public synchronized void start() {
- log.debug("Starting AdaptiveStats collection thread for {}", sw.getStringId());
- callCountCalAndShortFlowsTask = 0;
- callCountMidFlowsTask = 0;
- callCountLongFlowsTask = 0;
-
- isFirstTimeStart = true;
-
- // Initially start polling quickly. Then drop down to configured value
- calAndShortFlowsTask = new CalAndShortFlowsTask();
- calAndShortFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
- calAndShortFlowsTask,
- 1,
- calAndPollInterval,
- TimeUnit.SECONDS);
-
- midFlowsTask = new MidFlowsTask();
- midFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
- midFlowsTask,
- 1,
- midPollInterval,
- TimeUnit.SECONDS);
-
- longFlowsTask = new LongFlowsTask();
- longFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
- longFlowsTask,
- 1,
- longPollInterval,
- TimeUnit.SECONDS);
-
- log.info("Started");
- }
-
- /**
- * stop adaptive flow statistic collection.
- *
- */
- public synchronized void stop() {
- log.debug("Stopping AdaptiveStats collection thread for {}", sw.getStringId());
- if (calAndShortFlowsThread != null) {
- calAndShortFlowsThread.cancel(true);
- }
- if (midFlowsThread != null) {
- midFlowsThread.cancel(true);
- }
- if (longFlowsThread != null) {
- longFlowsThread.cancel(true);
- }
-
- adaptiveFlowStatsScheduler.shutdownNow();
-
- isFirstTimeStart = false;
-
- log.info("Stopped");
- }
-
- /**
- * add typed flow entry from flow rule into the internal flow table.
- *
- * @param flowRules the flow rules
- *
- */
- public synchronized void addWithFlowRule(FlowRule... flowRules) {
- for (FlowRule fr : flowRules) {
- // First remove old entry unconditionally, if exist
- deviceFlowTable.remove(fr);
-
- // add new flow entry, we suppose IMMEDIATE_FLOW
- TypedStoredFlowEntry newFlowEntry = new DefaultTypedFlowEntry(fr,
- FlowLiveType.IMMEDIATE_FLOW);
- deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
- }
- }
-
- /**
- * add or update typed flow entry from flow entry into the internal flow table.
- *
- * @param flowEntries the flow entries
- *
- */
- public synchronized void addOrUpdateFlows(FlowEntry... flowEntries) {
- for (FlowEntry fe : flowEntries) {
- // check if this new rule is an update to an existing entry
- TypedStoredFlowEntry stored = deviceFlowTable.getFlowEntry(fe);
-
- if (stored != null) {
- // duplicated flow entry is collected!, just skip
- if (fe.bytes() == stored.bytes() && fe.packets() == stored.packets()
- && fe.life() == stored.life()) {
- log.debug("addOrUpdateFlows:, FlowId=" + Long.toHexString(fe.id().value())
- + ",is DUPLICATED stats collection, just skip."
- + " AdaptiveStats collection thread for {}",
- sw.getStringId());
-
- stored.setLastSeen();
- continue;
- } else if (fe.life() < stored.life()) {
- // Invalid updates the stats values, i.e., bytes, packets, durations ...
- log.debug("addOrUpdateFlows():" +
- " Invalid Flow Update! The new life is SMALLER than the previous one, jus skip." +
- " new flowId=" + Long.toHexString(fe.id().value()) +
- ", old flowId=" + Long.toHexString(stored.id().value()) +
- ", new bytes=" + fe.bytes() + ", old bytes=" + stored.bytes() +
- ", new life=" + fe.life() + ", old life=" + stored.life() +
- ", new lastSeen=" + fe.lastSeen() + ", old lastSeen=" + stored.lastSeen());
- // go next
- stored.setLastSeen();
- continue;
- }
-
- // update now
- stored.setLife(fe.life());
- stored.setPackets(fe.packets());
- stored.setBytes(fe.bytes());
- stored.setLastSeen();
- if (stored.state() == FlowEntry.FlowEntryState.PENDING_ADD) {
- // flow is really RULE_ADDED
- stored.setState(FlowEntry.FlowEntryState.ADDED);
- }
- // flow is RULE_UPDATED, skip adding and just updating flow live table
- //deviceFlowTable.calAndSetFlowLiveType(stored);
- continue;
- }
-
- // add new flow entry, we suppose IMMEDIATE_FLOW
- TypedStoredFlowEntry newFlowEntry = new DefaultTypedFlowEntry(fe,
- FlowLiveType.IMMEDIATE_FLOW);
- deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
- }
- }
-
- /**
- * remove typed flow entry from the internal flow table.
- *
- * @param flowRules the flow entries
- *
- */
- public synchronized void removeFlows(FlowRule... flowRules) {
- for (FlowRule rule : flowRules) {
- deviceFlowTable.remove(rule);
- }
- }
-
- // same as removeFlows() function
- /**
- * remove typed flow entry from the internal flow table.
- *
- * @param flowRules the flow entries
- *
- */
- public void flowRemoved(FlowRule... flowRules) {
- removeFlows(flowRules);
- }
-
- // same as addOrUpdateFlows() function
- /**
- * add or update typed flow entry from flow entry into the internal flow table.
- *
- * @param flowEntries the flow entry list
- *
- */
- public void pushFlowMetrics(List<FlowEntry> flowEntries) {
- flowEntries.forEach(fe -> {
- addOrUpdateFlows(fe);
- });
- }
-
- /**
- * returns flowMissingXid that indicates the execution of flowMissing process or not(NO_FLOW_MISSING_XID(-1)).
- *
- * @return xid of missing flow
- */
- public long getFlowMissingXid() {
- return flowMissingXid;
- }
-
- /**
- * set flowMissingXid, namely OFFlowStatsRequest match any ALL message Id.
- *
- * @param flowMissingXid the OFFlowStatsRequest message Id
- *
- */
- public void setFlowMissingXid(long flowMissingXid) {
- this.flowMissingXid = flowMissingXid;
- }
-
- private class InternalDeviceFlowTable {
-
- private final Map<FlowId, Set<TypedStoredFlowEntry>>
- flowEntries = Maps.newConcurrentMap();
-
- private final Set<StoredFlowEntry> shortFlows = new HashSet<>();
- private final Set<StoredFlowEntry> midFlows = new HashSet<>();
- private final Set<StoredFlowEntry> longFlows = new HashSet<>();
-
- // Assumed latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
- private final long latencyFlowStatsRequestAndReplyMillis = 500;
-
-
- // Statistics for table operation
- private long addCount = 0, addWithSetFlowLiveTypeCount = 0;
- private long removeCount = 0;
-
- /**
- * Resets all count values with zero.
- *
- */
- public void resetAllCount() {
- addCount = 0;
- addWithSetFlowLiveTypeCount = 0;
- removeCount = 0;
- }
-
- // get set of flow entries for the given flowId
- private Set<TypedStoredFlowEntry> getFlowEntriesInternal(FlowId flowId) {
- return flowEntries.computeIfAbsent(flowId, id -> Sets.newCopyOnWriteArraySet());
- }
-
- // get flow entry for the given flow rule
- private TypedStoredFlowEntry getFlowEntryInternal(FlowRule rule) {
- Set<TypedStoredFlowEntry> flowEntries = getFlowEntriesInternal(rule.id());
- return flowEntries.stream()
- .filter(entry -> Objects.equal(entry, rule))
- .findAny()
- .orElse(null);
- }
-
- // get the flow entries for all flows in flow table
- private Set<TypedStoredFlowEntry> getFlowEntriesInternal() {
- Set<TypedStoredFlowEntry> result = Sets.newHashSet();
-
- flowEntries.values().forEach(result::addAll);
- return result;
- }
-
- /**
- * Gets the number of flow entry in flow table.
- *
- * @return the number of flow entry.
- *
- */
- public long getFlowCount() {
- return flowEntries.values().stream().mapToLong(Set::size).sum();
- }
-
- /**
- * Gets the number of flow entry in flow table.
- *
- * @param rule the flow rule
- * @return the typed flow entry.
- *
- */
- public TypedStoredFlowEntry getFlowEntry(FlowRule rule) {
- checkNotNull(rule);
-
- return getFlowEntryInternal(rule);
- }
-
- /**
- * Gets the all typed flow entries in flow table.
- *
- * @return the set of typed flow entry.
- *
- */
- public Set<TypedStoredFlowEntry> getFlowEntries() {
- return getFlowEntriesInternal();
- }
-
- /**
- * Gets the short typed flow entries in flow table.
- *
- * @return the set of typed flow entry.
- *
- */
- public Set<StoredFlowEntry> getShortFlows() {
- return ImmutableSet.copyOf(shortFlows); //Sets.newHashSet(shortFlows);
- }
-
- /**
- * Gets the mid typed flow entries in flow table.
- *
- * @return the set of typed flow entry.
- *
- */
- public Set<StoredFlowEntry> getMidFlows() {
- return ImmutableSet.copyOf(midFlows); //Sets.newHashSet(midFlows);
- }
-
- /**
- * Gets the long typed flow entries in flow table.
- *
- * @return the set of typed flow entry.
- *
- */
- public Set<StoredFlowEntry> getLongFlows() {
- return ImmutableSet.copyOf(longFlows); //Sets.newHashSet(longFlows);
- }
-
- /**
- * Add typed flow entry into table only.
- *
- * @param rule the flow rule
- *
- */
- public synchronized void add(TypedStoredFlowEntry rule) {
- checkNotNull(rule);
-
- //rule have to be new DefaultTypedFlowEntry
- boolean result = getFlowEntriesInternal(rule.id()).add(rule);
-
- if (result) {
- addCount++;
- }
- }
-
- /**
- * Calculates and set the flow live type at the first time,
- * and then add it into a corresponding typed flow table.
- *
- * @param rule the flow rule
- *
- */
- public void calAndSetFlowLiveType(TypedStoredFlowEntry rule) {
- checkNotNull(rule);
-
- calAndSetFlowLiveTypeInternal(rule);
- }
-
- /**
- * Add the typed flow entry into table, and calculates and set the flow live type,
- * and then add it into a corresponding typed flow table.
- *
- * @param rule the flow rule
- *
- */
- public synchronized void addWithCalAndSetFlowLiveType(TypedStoredFlowEntry rule) {
- checkNotNull(rule);
-
- //rule have to be new DefaultTypedFlowEntry
- boolean result = getFlowEntriesInternal(rule.id()).add(rule);
- if (result) {
- calAndSetFlowLiveTypeInternal(rule);
- addWithSetFlowLiveTypeCount++;
- } else {
- log.debug("addWithCalAndSetFlowLiveType, FlowId=" + Long.toHexString(rule.id().value())
- + " ADD Failed, cause it may already exists in table !!!,"
- + " AdaptiveStats collection thread for {}",
- sw.getStringId());
- }
- }
-
- // In real, calculates and set the flow live type at the first time,
- // and then add it into a corresponding typed flow table
- private void calAndSetFlowLiveTypeInternal(TypedStoredFlowEntry rule) {
- long life = rule.life();
- FlowLiveType prevFlowLiveType = rule.flowLiveType();
-
- if (life >= longPollInterval) {
- rule.setFlowLiveType(FlowLiveType.LONG_FLOW);
- longFlows.add(rule);
- } else if (life >= midPollInterval) {
- rule.setFlowLiveType(FlowLiveType.MID_FLOW);
- midFlows.add(rule);
- } else if (life >= calAndPollInterval) {
- rule.setFlowLiveType(FlowLiveType.SHORT_FLOW);
- shortFlows.add(rule);
- } else if (life >= 0) {
- rule.setFlowLiveType(FlowLiveType.IMMEDIATE_FLOW);
- } else { // life < 0
- rule.setFlowLiveType(FlowLiveType.UNKNOWN_FLOW);
- }
-
- if (rule.flowLiveType() != prevFlowLiveType) {
- switch (prevFlowLiveType) {
- // delete it from previous flow table
- case SHORT_FLOW:
- shortFlows.remove(rule);
- break;
- case MID_FLOW:
- midFlows.remove(rule);
- break;
- case LONG_FLOW:
- longFlows.remove(rule);
- break;
- default:
- break;
- }
- }
- }
-
-
- // check the flow live type based on current time, then set and add it into corresponding table
- private boolean checkAndMoveLiveFlowInternal(TypedStoredFlowEntry fe, long cTime) {
- long curTime = (cTime > 0 ? cTime : System.currentTimeMillis());
- // For latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
- long fromLastSeen = ((curTime - fe.lastSeen() + latencyFlowStatsRequestAndReplyMillis) / 1000);
- // fe.life() unit is SECOND!
- long liveTime = fe.life() + fromLastSeen;
-
-
- switch (fe.flowLiveType()) {
- case IMMEDIATE_FLOW:
- if (liveTime >= longPollInterval) {
- fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
- longFlows.add(fe);
- } else if (liveTime >= midPollInterval) {
- fe.setFlowLiveType(FlowLiveType.MID_FLOW);
- midFlows.add(fe);
- } else if (liveTime >= calAndPollInterval) {
- fe.setFlowLiveType(FlowLiveType.SHORT_FLOW);
- shortFlows.add(fe);
- }
- break;
- case SHORT_FLOW:
- if (liveTime >= longPollInterval) {
- fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
- shortFlows.remove(fe);
- longFlows.add(fe);
- } else if (liveTime >= midPollInterval) {
- fe.setFlowLiveType(FlowLiveType.MID_FLOW);
- shortFlows.remove(fe);
- midFlows.add(fe);
- }
- break;
- case MID_FLOW:
- if (liveTime >= longPollInterval) {
- fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
- midFlows.remove(fe);
- longFlows.add(fe);
- }
- break;
- case LONG_FLOW:
- if (fromLastSeen > entirePollInterval) {
- log.trace("checkAndMoveLiveFlowInternal, flow is already removed at switch.");
- return false;
- }
- break;
- case UNKNOWN_FLOW: // Unknown flow is an internal error flow type, just fall through
- default :
- // Error Unknown Live Type
- log.error("checkAndMoveLiveFlowInternal, Unknown Live Type error!"
- + "AdaptiveStats collection thread for {}",
- sw.getStringId());
- return false;
- }
-
- log.debug("checkAndMoveLiveFlowInternal, FlowId=" + Long.toHexString(fe.id().value())
- + ", state=" + fe.state()
- + ", After liveType=" + fe.flowLiveType()
- + ", liveTime=" + liveTime
- + ", life=" + fe.life()
- + ", bytes=" + fe.bytes()
- + ", packets=" + fe.packets()
- + ", fromLastSeen=" + fromLastSeen
- + ", priority=" + fe.priority()
- + ", selector=" + fe.selector().criteria()
- + ", treatment=" + fe.treatment()
- + " AdaptiveStats collection thread for {}",
- sw.getStringId());
-
- return true;
- }
-
- /**
- * Check and move live type for all type flow entries in table at every calAndPollInterval time.
- *
- */
- public void checkAndMoveLiveFlowAll() {
- Set<TypedStoredFlowEntry> typedFlowEntries = getFlowEntriesInternal();
-
- long calCurTime = System.currentTimeMillis();
- typedFlowEntries.forEach(fe -> {
- if (!checkAndMoveLiveFlowInternal(fe, calCurTime)) {
- remove(fe);
- }
- });
-
- // print table counts for debug
- if (log.isDebugEnabled()) {
- synchronized (this) {
- long totalFlowCount = getFlowCount();
- long shortFlowCount = shortFlows.size();
- long midFlowCount = midFlows.size();
- long longFlowCount = longFlows.size();
- long immediateFlowCount = totalFlowCount - shortFlowCount - midFlowCount - longFlowCount;
- long calTotalCount = addCount + addWithSetFlowLiveTypeCount - removeCount;
-
- log.debug("--------------------------------------------------------------------------- for {}",
- sw.getStringId());
- log.debug("checkAndMoveLiveFlowAll, Total Flow_Count=" + totalFlowCount
- + ", add - remove_Count=" + calTotalCount
- + ", IMMEDIATE_FLOW_Count=" + immediateFlowCount
- + ", SHORT_FLOW_Count=" + shortFlowCount
- + ", MID_FLOW_Count=" + midFlowCount
- + ", LONG_FLOW_Count=" + longFlowCount
- + ", add_Count=" + addCount
- + ", addWithSetFlowLiveType_Count=" + addWithSetFlowLiveTypeCount
- + ", remove_Count=" + removeCount
- + " AdaptiveStats collection thread for {}", sw.getStringId());
- log.debug("--------------------------------------------------------------------------- for {}",
- sw.getStringId());
- if (totalFlowCount != calTotalCount) {
- log.error("checkAndMoveLiveFlowAll, Real total flow count and "
- + "calculated total flow count do NOT match, something is wrong internally "
- + "or check counter value bound is over!");
- }
- if (immediateFlowCount < 0) {
- log.error("checkAndMoveLiveFlowAll, IMMEDIATE_FLOW count is negative, "
- + "something is wrong internally "
- + "or check counter value bound is over!");
- }
- }
- }
- log.trace("checkAndMoveLiveFlowAll, AdaptiveStats for {}", sw.getStringId());
- }
-
- /**
- * Remove the typed flow entry from table.
- *
- * @param rule the flow rule
- *
- */
- public synchronized void remove(FlowRule rule) {
- checkNotNull(rule);
-
- TypedStoredFlowEntry removeStore = getFlowEntryInternal(rule);
- if (removeStore != null) {
- removeLiveFlowsInternal((TypedStoredFlowEntry) removeStore);
- boolean result = getFlowEntriesInternal(rule.id()).remove(removeStore);
-
- if (result) {
- removeCount++;
- }
- }
- }
-
- // Remove the typed flow entry from corresponding table
- private void removeLiveFlowsInternal(TypedStoredFlowEntry fe) {
- switch (fe.flowLiveType()) {
- case IMMEDIATE_FLOW:
- // do nothing
- break;
- case SHORT_FLOW:
- shortFlows.remove(fe);
- break;
- case MID_FLOW:
- midFlows.remove(fe);
- break;
- case LONG_FLOW:
- longFlows.remove(fe);
- break;
- default: // error in Flow Live Type
- log.error("removeLiveFlowsInternal, Unknown Live Type error!");
- break;
- }
- }
- }
-}
+/*
+ * 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.provider.of.flow.impl;
+
+import com.google.common.base.Objects;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import org.onosproject.net.flow.DefaultTypedFlowEntry;
+import org.onosproject.net.flow.FlowEntry;
+import org.onosproject.net.flow.FlowId;
+import org.onosproject.net.flow.FlowRule;
+import org.onosproject.net.flow.StoredFlowEntry;
+import org.onosproject.net.flow.TypedStoredFlowEntry;
+import org.onosproject.net.flow.instructions.Instruction;
+import org.onosproject.net.flow.instructions.Instructions;
+import org.onosproject.openflow.controller.OpenFlowSwitch;
+import org.onosproject.openflow.controller.RoleState;
+import org.projectfloodlight.openflow.protocol.OFFlowStatsRequest;
+import org.projectfloodlight.openflow.protocol.match.Match;
+import org.projectfloodlight.openflow.types.OFPort;
+import org.projectfloodlight.openflow.types.TableId;
+import org.slf4j.Logger;
+
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
+import java.util.concurrent.ScheduledFuture;
+import java.util.concurrent.TimeUnit;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static org.onlab.util.Tools.groupedThreads;
+import static org.onosproject.net.flow.TypedStoredFlowEntry.FlowLiveType;
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Efficiently and adaptively collects flow statistics for the specified switch.
+ */
+public class NewAdaptiveFlowStatsCollector {
+
+ private final Logger log = getLogger(getClass());
+
+ private final OpenFlowSwitch sw;
+
+ private ScheduledExecutorService adaptiveFlowStatsScheduler =
+ Executors.newScheduledThreadPool(4, groupedThreads("onos/flow", "device-stats-collector-%d"));
+ private ScheduledFuture<?> calAndShortFlowsThread;
+ private ScheduledFuture<?> midFlowsThread;
+ private ScheduledFuture<?> longFlowsThread;
+
+ // Task that calculates all flowEntries' FlowLiveType and collects stats IMMEDIATE flows every calAndPollInterval
+ private CalAndShortFlowsTask calAndShortFlowsTask;
+ // Task that collects stats MID flows every 2*calAndPollInterval
+ private MidFlowsTask midFlowsTask;
+ // Task that collects stats LONG flows every 3*calAndPollInterval
+ private LongFlowsTask longFlowsTask;
+
+ private static final int CAL_AND_POLL_TIMES = 1; // must be always 0
+ private static final int MID_POLL_TIMES = 2; // variable greater or equal than 1
+ private static final int LONG_POLL_TIMES = 3; // variable greater or equal than MID_POLL_TIMES
+ //TODO: make ENTIRE_POLL_TIMES configurable with enable or disable
+ // must be variable greater or equal than common multiple of MID_POLL_TIMES and LONG_POLL_TIMES
+ private static final int ENTIRE_POLL_TIMES = 6;
+
+ private static final int DEFAULT_CAL_AND_POLL_FREQUENCY = 5;
+ private static final int MIN_CAL_AND_POLL_FREQUENCY = 2;
+ private static final int MAX_CAL_AND_POLL_FREQUENCY = 60;
+
+ private int calAndPollInterval; // CAL_AND_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
+ private int midPollInterval; // MID_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
+ private int longPollInterval; // LONG_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
+ // only used for checking condition at each task if it collects entire flows from a given switch or not
+ private int entirePollInterval; // ENTIRE_POLL_TIMES * DEFAULT_CAL_AND_POLL_FREQUENCY;
+
+ // Number of call count of each Task,
+ // for undoing collection except only entire flows collecting task in CalAndShortFlowsTask
+ private int callCountCalAndShortFlowsTask = 0; // increased CAL_AND_POLL_TIMES whenever Task is called
+ private int callCountMidFlowsTask = 0; // increased MID_POLL_TIMES whenever Task is called
+ private int callCountLongFlowsTask = 0; // increased LONG_POLL_TIMES whenever Task is called
+
+ private InternalDeviceFlowTable deviceFlowTable = new InternalDeviceFlowTable();
+
+ private boolean isFirstTimeStart = true;
+
+ public static final long NO_FLOW_MISSING_XID = (-1);
+ private long flowMissingXid = NO_FLOW_MISSING_XID;
+
+ /**
+ * Creates a new adaptive collector for the given switch and default cal_and_poll frequency.
+ *
+ * @param sw switch to pull
+ * @param pollInterval cal and immediate poll frequency in seconds
+ */
+ NewAdaptiveFlowStatsCollector(OpenFlowSwitch sw, int pollInterval) {
+ this.sw = sw;
+
+ initMemberVars(pollInterval);
+ }
+
+ // check calAndPollInterval validity and set all pollInterval values and finally initialize each task call count
+ private void initMemberVars(int pollInterval) {
+ if (pollInterval < MIN_CAL_AND_POLL_FREQUENCY) {
+ this.calAndPollInterval = MIN_CAL_AND_POLL_FREQUENCY;
+ } else if (pollInterval >= MAX_CAL_AND_POLL_FREQUENCY) {
+ this.calAndPollInterval = MAX_CAL_AND_POLL_FREQUENCY;
+ } else {
+ this.calAndPollInterval = pollInterval;
+ }
+
+ calAndPollInterval = CAL_AND_POLL_TIMES * calAndPollInterval;
+ midPollInterval = MID_POLL_TIMES * calAndPollInterval;
+ longPollInterval = LONG_POLL_TIMES * calAndPollInterval;
+ entirePollInterval = ENTIRE_POLL_TIMES * calAndPollInterval;
+
+ callCountCalAndShortFlowsTask = 0;
+ callCountMidFlowsTask = 0;
+ callCountLongFlowsTask = 0;
+
+ flowMissingXid = NO_FLOW_MISSING_XID;
+ }
+
+ /**
+ * Adjusts adaptive poll frequency.
+ *
+ * @param pollInterval poll frequency in seconds
+ */
+ synchronized void adjustCalAndPollInterval(int pollInterval) {
+ initMemberVars(pollInterval);
+
+ if (calAndShortFlowsThread != null) {
+ calAndShortFlowsThread.cancel(false);
+ }
+ if (midFlowsThread != null) {
+ midFlowsThread.cancel(false);
+ }
+ if (longFlowsThread != null) {
+ longFlowsThread.cancel(false);
+ }
+
+ calAndShortFlowsTask = new CalAndShortFlowsTask();
+ calAndShortFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
+ calAndShortFlowsTask,
+ 0,
+ calAndPollInterval,
+ TimeUnit.SECONDS);
+
+ midFlowsTask = new MidFlowsTask();
+ midFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
+ midFlowsTask,
+ 0,
+ midPollInterval,
+ TimeUnit.SECONDS);
+
+ longFlowsTask = new LongFlowsTask();
+ longFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
+ longFlowsTask,
+ 0,
+ longPollInterval,
+ TimeUnit.SECONDS);
+
+ log.debug("calAndPollInterval=" + calAndPollInterval + "is adjusted");
+ }
+
+ private class CalAndShortFlowsTask implements Runnable {
+ @Override
+ public void run() {
+ if (sw.getRole() == RoleState.MASTER) {
+ log.trace("CalAndShortFlowsTask Collecting AdaptiveStats for {}", sw.getStringId());
+
+ if (isFirstTimeStart) {
+ // isFirstTimeStart, get entire flow stats from a given switch sw
+ log.trace("CalAndShortFlowsTask Collecting Entire AdaptiveStats at first time start for {}",
+ sw.getStringId());
+ ofFlowStatsRequestAllSend();
+
+ callCountCalAndShortFlowsTask += CAL_AND_POLL_TIMES;
+ isFirstTimeStart = false;
+ } else if (callCountCalAndShortFlowsTask == ENTIRE_POLL_TIMES) {
+ // entire_poll_times, get entire flow stats from a given switch sw
+ log.trace("CalAndShortFlowsTask Collecting Entire AdaptiveStats for {}", sw.getStringId());
+ ofFlowStatsRequestAllSend();
+
+ callCountCalAndShortFlowsTask = CAL_AND_POLL_TIMES;
+ //TODO: check flows deleted in switch, but exist in controller flow table, then remove them
+ //
+ } else {
+ calAndShortFlowsTaskInternal();
+ callCountCalAndShortFlowsTask += CAL_AND_POLL_TIMES;
+ }
+ }
+ }
+ }
+
+ // send openflow flow stats request message with getting all flow entries to a given switch sw
+ private void ofFlowStatsRequestAllSend() {
+ OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest()
+ .setMatch(sw.factory().matchWildcardAll())
+ .setTableId(TableId.ALL)
+ .setOutPort(OFPort.NO_MASK)
+ .build();
+
+ synchronized (this) {
+ // set the request xid to check the reply in OpenFlowRuleProvider
+ // After processing the reply of this request message,
+ // this must be set to NO_FLOW_MISSING_XID(-1) by provider
+ setFlowMissingXid(request.getXid());
+ log.debug("ofFlowStatsRequestAllSend,Request={},for {}", request.toString(), sw.getStringId());
+
+ sw.sendMsg(request);
+ }
+ }
+
+ // send openflow flow stats request message with getting the specific flow entry(fe) to a given switch sw
+ private void ofFlowStatsRequestFlowSend(FlowEntry fe) {
+ // set find match
+ Match match = FlowModBuilder.builder(fe, sw.factory(), Optional.empty(),
+ Optional.empty()).buildMatch();
+ // set find tableId
+ TableId tableId = TableId.of(fe.tableId());
+ // set output port
+ Instruction ins = fe.treatment().allInstructions().stream()
+ .filter(i -> (i.type() == Instruction.Type.OUTPUT))
+ .findFirst()
+ .orElse(null);
+ OFPort ofPort = OFPort.NO_MASK;
+ if (ins != null) {
+ Instructions.OutputInstruction out = (Instructions.OutputInstruction) ins;
+ ofPort = OFPort.of((int) ((out.port().toLong())));
+ }
+
+ OFFlowStatsRequest request = sw.factory().buildFlowStatsRequest()
+ .setMatch(match)
+ .setTableId(tableId)
+ .setOutPort(ofPort)
+ .build();
+
+ synchronized (this) {
+ if (getFlowMissingXid() != NO_FLOW_MISSING_XID) {
+ log.debug("ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll does not be processed yet,"
+ + " set no flow missing xid anyway, for {}",
+ sw.getStringId());
+ setFlowMissingXid(NO_FLOW_MISSING_XID);
+ }
+
+ sw.sendMsg(request);
+ }
+ }
+
+ private void calAndShortFlowsTaskInternal() {
+ deviceFlowTable.checkAndMoveLiveFlowAll();
+
+ deviceFlowTable.getShortFlows().forEach(fe -> {
+ ofFlowStatsRequestFlowSend(fe);
+ });
+ }
+
+ private class MidFlowsTask implements Runnable {
+ @Override
+ public void run() {
+ if (sw.getRole() == RoleState.MASTER) {
+ log.trace("MidFlowsTask Collecting AdaptiveStats for {}", sw.getStringId());
+
+ // skip collecting because CalAndShortFlowsTask collects entire flow stats from a given switch sw
+ if (callCountMidFlowsTask == ENTIRE_POLL_TIMES) {
+ callCountMidFlowsTask = MID_POLL_TIMES;
+ } else {
+ midFlowsTaskInternal();
+ callCountMidFlowsTask += MID_POLL_TIMES;
+ }
+ }
+ }
+ }
+
+ private void midFlowsTaskInternal() {
+ deviceFlowTable.getMidFlows().forEach(fe -> {
+ ofFlowStatsRequestFlowSend(fe);
+ });
+ }
+
+ private class LongFlowsTask implements Runnable {
+ @Override
+ public void run() {
+ if (sw.getRole() == RoleState.MASTER) {
+ log.trace("LongFlowsTask Collecting AdaptiveStats for {}", sw.getStringId());
+
+ // skip collecting because CalAndShortFlowsTask collects entire flow stats from a given switch sw
+ if (callCountLongFlowsTask == ENTIRE_POLL_TIMES) {
+ callCountLongFlowsTask = LONG_POLL_TIMES;
+ } else {
+ longFlowsTaskInternal();
+ callCountLongFlowsTask += LONG_POLL_TIMES;
+ }
+ }
+ }
+ }
+
+ private void longFlowsTaskInternal() {
+ deviceFlowTable.getLongFlows().forEach(fe -> {
+ ofFlowStatsRequestFlowSend(fe);
+ });
+ }
+
+ /**
+ * start adaptive flow statistic collection.
+ *
+ */
+ public synchronized void start() {
+ log.debug("Starting AdaptiveStats collection thread for {}", sw.getStringId());
+ callCountCalAndShortFlowsTask = 0;
+ callCountMidFlowsTask = 0;
+ callCountLongFlowsTask = 0;
+
+ isFirstTimeStart = true;
+
+ // Initially start polling quickly. Then drop down to configured value
+ calAndShortFlowsTask = new CalAndShortFlowsTask();
+ calAndShortFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
+ calAndShortFlowsTask,
+ 1,
+ calAndPollInterval,
+ TimeUnit.SECONDS);
+
+ midFlowsTask = new MidFlowsTask();
+ midFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
+ midFlowsTask,
+ 1,
+ midPollInterval,
+ TimeUnit.SECONDS);
+
+ longFlowsTask = new LongFlowsTask();
+ longFlowsThread = adaptiveFlowStatsScheduler.scheduleWithFixedDelay(
+ longFlowsTask,
+ 1,
+ longPollInterval,
+ TimeUnit.SECONDS);
+
+ log.info("Started");
+ }
+
+ /**
+ * stop adaptive flow statistic collection.
+ *
+ */
+ public synchronized void stop() {
+ log.debug("Stopping AdaptiveStats collection thread for {}", sw.getStringId());
+ if (calAndShortFlowsThread != null) {
+ calAndShortFlowsThread.cancel(true);
+ }
+ if (midFlowsThread != null) {
+ midFlowsThread.cancel(true);
+ }
+ if (longFlowsThread != null) {
+ longFlowsThread.cancel(true);
+ }
+
+ adaptiveFlowStatsScheduler.shutdownNow();
+
+ isFirstTimeStart = false;
+
+ log.info("Stopped");
+ }
+
+ /**
+ * add typed flow entry from flow rule into the internal flow table.
+ *
+ * @param flowRules the flow rules
+ *
+ */
+ public synchronized void addWithFlowRule(FlowRule... flowRules) {
+ for (FlowRule fr : flowRules) {
+ // First remove old entry unconditionally, if exist
+ deviceFlowTable.remove(fr);
+
+ // add new flow entry, we suppose IMMEDIATE_FLOW
+ TypedStoredFlowEntry newFlowEntry = new DefaultTypedFlowEntry(fr,
+ FlowLiveType.IMMEDIATE_FLOW);
+ deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
+ }
+ }
+
+ /**
+ * add or update typed flow entry from flow entry into the internal flow table.
+ *
+ * @param flowEntries the flow entries
+ *
+ */
+ public synchronized void addOrUpdateFlows(FlowEntry... flowEntries) {
+ for (FlowEntry fe : flowEntries) {
+ // check if this new rule is an update to an existing entry
+ TypedStoredFlowEntry stored = deviceFlowTable.getFlowEntry(fe);
+
+ if (stored != null) {
+ // duplicated flow entry is collected!, just skip
+ if (fe.bytes() == stored.bytes() && fe.packets() == stored.packets()
+ && fe.life() == stored.life()) {
+ log.debug("addOrUpdateFlows:, FlowId=" + Long.toHexString(fe.id().value())
+ + ",is DUPLICATED stats collection, just skip."
+ + " AdaptiveStats collection thread for {}",
+ sw.getStringId());
+
+ stored.setLastSeen();
+ continue;
+ } else if (fe.life() < stored.life()) {
+ // Invalid updates the stats values, i.e., bytes, packets, durations ...
+ log.debug("addOrUpdateFlows():" +
+ " Invalid Flow Update! The new life is SMALLER than the previous one, jus skip." +
+ " new flowId=" + Long.toHexString(fe.id().value()) +
+ ", old flowId=" + Long.toHexString(stored.id().value()) +
+ ", new bytes=" + fe.bytes() + ", old bytes=" + stored.bytes() +
+ ", new life=" + fe.life() + ", old life=" + stored.life() +
+ ", new lastSeen=" + fe.lastSeen() + ", old lastSeen=" + stored.lastSeen());
+ // go next
+ stored.setLastSeen();
+ continue;
+ }
+
+ // update now
+ stored.setLife(fe.life());
+ stored.setPackets(fe.packets());
+ stored.setBytes(fe.bytes());
+ stored.setLastSeen();
+ if (stored.state() == FlowEntry.FlowEntryState.PENDING_ADD) {
+ // flow is really RULE_ADDED
+ stored.setState(FlowEntry.FlowEntryState.ADDED);
+ }
+ // flow is RULE_UPDATED, skip adding and just updating flow live table
+ //deviceFlowTable.calAndSetFlowLiveType(stored);
+ continue;
+ }
+
+ // add new flow entry, we suppose IMMEDIATE_FLOW
+ TypedStoredFlowEntry newFlowEntry = new DefaultTypedFlowEntry(fe,
+ FlowLiveType.IMMEDIATE_FLOW);
+ deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
+ }
+ }
+
+ /**
+ * remove typed flow entry from the internal flow table.
+ *
+ * @param flowRules the flow entries
+ *
+ */
+ public synchronized void removeFlows(FlowRule... flowRules) {
+ for (FlowRule rule : flowRules) {
+ deviceFlowTable.remove(rule);
+ }
+ }
+
+ // same as removeFlows() function
+ /**
+ * remove typed flow entry from the internal flow table.
+ *
+ * @param flowRules the flow entries
+ *
+ */
+ public void flowRemoved(FlowRule... flowRules) {
+ removeFlows(flowRules);
+ }
+
+ // same as addOrUpdateFlows() function
+ /**
+ * add or update typed flow entry from flow entry into the internal flow table.
+ *
+ * @param flowEntries the flow entry list
+ *
+ */
+ public void pushFlowMetrics(List<FlowEntry> flowEntries) {
+ flowEntries.forEach(fe -> {
+ addOrUpdateFlows(fe);
+ });
+ }
+
+ /**
+ * returns flowMissingXid that indicates the execution of flowMissing process or not(NO_FLOW_MISSING_XID(-1)).
+ *
+ * @return xid of missing flow
+ */
+ public long getFlowMissingXid() {
+ return flowMissingXid;
+ }
+
+ /**
+ * set flowMissingXid, namely OFFlowStatsRequest match any ALL message Id.
+ *
+ * @param flowMissingXid the OFFlowStatsRequest message Id
+ *
+ */
+ public void setFlowMissingXid(long flowMissingXid) {
+ this.flowMissingXid = flowMissingXid;
+ }
+
+ private class InternalDeviceFlowTable {
+
+ private final Map<FlowId, Set<TypedStoredFlowEntry>>
+ flowEntries = Maps.newConcurrentMap();
+
+ private final Set<StoredFlowEntry> shortFlows = new HashSet<>();
+ private final Set<StoredFlowEntry> midFlows = new HashSet<>();
+ private final Set<StoredFlowEntry> longFlows = new HashSet<>();
+
+ // Assumed latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
+ private final long latencyFlowStatsRequestAndReplyMillis = 500;
+
+
+ // Statistics for table operation
+ private long addCount = 0, addWithSetFlowLiveTypeCount = 0;
+ private long removeCount = 0;
+
+ /**
+ * Resets all count values with zero.
+ *
+ */
+ public void resetAllCount() {
+ addCount = 0;
+ addWithSetFlowLiveTypeCount = 0;
+ removeCount = 0;
+ }
+
+ // get set of flow entries for the given flowId
+ private Set<TypedStoredFlowEntry> getFlowEntriesInternal(FlowId flowId) {
+ return flowEntries.computeIfAbsent(flowId, id -> Sets.newCopyOnWriteArraySet());
+ }
+
+ // get flow entry for the given flow rule
+ private TypedStoredFlowEntry getFlowEntryInternal(FlowRule rule) {
+ Set<TypedStoredFlowEntry> flowEntries = getFlowEntriesInternal(rule.id());
+ return flowEntries.stream()
+ .filter(entry -> Objects.equal(entry, rule))
+ .findAny()
+ .orElse(null);
+ }
+
+ // get the flow entries for all flows in flow table
+ private Set<TypedStoredFlowEntry> getFlowEntriesInternal() {
+ Set<TypedStoredFlowEntry> result = Sets.newHashSet();
+
+ flowEntries.values().forEach(result::addAll);
+ return result;
+ }
+
+ /**
+ * Gets the number of flow entry in flow table.
+ *
+ * @return the number of flow entry.
+ *
+ */
+ public long getFlowCount() {
+ return flowEntries.values().stream().mapToLong(Set::size).sum();
+ }
+
+ /**
+ * Gets the number of flow entry in flow table.
+ *
+ * @param rule the flow rule
+ * @return the typed flow entry.
+ *
+ */
+ public TypedStoredFlowEntry getFlowEntry(FlowRule rule) {
+ checkNotNull(rule);
+
+ return getFlowEntryInternal(rule);
+ }
+
+ /**
+ * Gets the all typed flow entries in flow table.
+ *
+ * @return the set of typed flow entry.
+ *
+ */
+ public Set<TypedStoredFlowEntry> getFlowEntries() {
+ return getFlowEntriesInternal();
+ }
+
+ /**
+ * Gets the short typed flow entries in flow table.
+ *
+ * @return the set of typed flow entry.
+ *
+ */
+ public Set<StoredFlowEntry> getShortFlows() {
+ return ImmutableSet.copyOf(shortFlows); //Sets.newHashSet(shortFlows);
+ }
+
+ /**
+ * Gets the mid typed flow entries in flow table.
+ *
+ * @return the set of typed flow entry.
+ *
+ */
+ public Set<StoredFlowEntry> getMidFlows() {
+ return ImmutableSet.copyOf(midFlows); //Sets.newHashSet(midFlows);
+ }
+
+ /**
+ * Gets the long typed flow entries in flow table.
+ *
+ * @return the set of typed flow entry.
+ *
+ */
+ public Set<StoredFlowEntry> getLongFlows() {
+ return ImmutableSet.copyOf(longFlows); //Sets.newHashSet(longFlows);
+ }
+
+ /**
+ * Add typed flow entry into table only.
+ *
+ * @param rule the flow rule
+ *
+ */
+ public synchronized void add(TypedStoredFlowEntry rule) {
+ checkNotNull(rule);
+
+ //rule have to be new DefaultTypedFlowEntry
+ boolean result = getFlowEntriesInternal(rule.id()).add(rule);
+
+ if (result) {
+ addCount++;
+ }
+ }
+
+ /**
+ * Calculates and set the flow live type at the first time,
+ * and then add it into a corresponding typed flow table.
+ *
+ * @param rule the flow rule
+ *
+ */
+ public void calAndSetFlowLiveType(TypedStoredFlowEntry rule) {
+ checkNotNull(rule);
+
+ calAndSetFlowLiveTypeInternal(rule);
+ }
+
+ /**
+ * Add the typed flow entry into table, and calculates and set the flow live type,
+ * and then add it into a corresponding typed flow table.
+ *
+ * @param rule the flow rule
+ *
+ */
+ public synchronized void addWithCalAndSetFlowLiveType(TypedStoredFlowEntry rule) {
+ checkNotNull(rule);
+
+ //rule have to be new DefaultTypedFlowEntry
+ boolean result = getFlowEntriesInternal(rule.id()).add(rule);
+ if (result) {
+ calAndSetFlowLiveTypeInternal(rule);
+ addWithSetFlowLiveTypeCount++;
+ } else {
+ log.debug("addWithCalAndSetFlowLiveType, FlowId=" + Long.toHexString(rule.id().value())
+ + " ADD Failed, cause it may already exists in table !!!,"
+ + " AdaptiveStats collection thread for {}",
+ sw.getStringId());
+ }
+ }
+
+ // In real, calculates and set the flow live type at the first time,
+ // and then add it into a corresponding typed flow table
+ private void calAndSetFlowLiveTypeInternal(TypedStoredFlowEntry rule) {
+ long life = rule.life();
+ FlowLiveType prevFlowLiveType = rule.flowLiveType();
+
+ if (life >= longPollInterval) {
+ rule.setFlowLiveType(FlowLiveType.LONG_FLOW);
+ longFlows.add(rule);
+ } else if (life >= midPollInterval) {
+ rule.setFlowLiveType(FlowLiveType.MID_FLOW);
+ midFlows.add(rule);
+ } else if (life >= calAndPollInterval) {
+ rule.setFlowLiveType(FlowLiveType.SHORT_FLOW);
+ shortFlows.add(rule);
+ } else if (life >= 0) {
+ rule.setFlowLiveType(FlowLiveType.IMMEDIATE_FLOW);
+ } else { // life < 0
+ rule.setFlowLiveType(FlowLiveType.UNKNOWN_FLOW);
+ }
+
+ if (rule.flowLiveType() != prevFlowLiveType) {
+ switch (prevFlowLiveType) {
+ // delete it from previous flow table
+ case SHORT_FLOW:
+ shortFlows.remove(rule);
+ break;
+ case MID_FLOW:
+ midFlows.remove(rule);
+ break;
+ case LONG_FLOW:
+ longFlows.remove(rule);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+
+
+ // check the flow live type based on current time, then set and add it into corresponding table
+ private boolean checkAndMoveLiveFlowInternal(TypedStoredFlowEntry fe, long cTime) {
+ long curTime = (cTime > 0 ? cTime : System.currentTimeMillis());
+ // For latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
+ long fromLastSeen = ((curTime - fe.lastSeen() + latencyFlowStatsRequestAndReplyMillis) / 1000);
+ // fe.life() unit is SECOND!
+ long liveTime = fe.life() + fromLastSeen;
+
+
+ switch (fe.flowLiveType()) {
+ case IMMEDIATE_FLOW:
+ if (liveTime >= longPollInterval) {
+ fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
+ longFlows.add(fe);
+ } else if (liveTime >= midPollInterval) {
+ fe.setFlowLiveType(FlowLiveType.MID_FLOW);
+ midFlows.add(fe);
+ } else if (liveTime >= calAndPollInterval) {
+ fe.setFlowLiveType(FlowLiveType.SHORT_FLOW);
+ shortFlows.add(fe);
+ }
+ break;
+ case SHORT_FLOW:
+ if (liveTime >= longPollInterval) {
+ fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
+ shortFlows.remove(fe);
+ longFlows.add(fe);
+ } else if (liveTime >= midPollInterval) {
+ fe.setFlowLiveType(FlowLiveType.MID_FLOW);
+ shortFlows.remove(fe);
+ midFlows.add(fe);
+ }
+ break;
+ case MID_FLOW:
+ if (liveTime >= longPollInterval) {
+ fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
+ midFlows.remove(fe);
+ longFlows.add(fe);
+ }
+ break;
+ case LONG_FLOW:
+ if (fromLastSeen > entirePollInterval) {
+ log.trace("checkAndMoveLiveFlowInternal, flow is already removed at switch.");
+ return false;
+ }
+ break;
+ case UNKNOWN_FLOW: // Unknown flow is an internal error flow type, just fall through
+ default :
+ // Error Unknown Live Type
+ log.error("checkAndMoveLiveFlowInternal, Unknown Live Type error!"
+ + "AdaptiveStats collection thread for {}",
+ sw.getStringId());
+ return false;
+ }
+
+ log.debug("checkAndMoveLiveFlowInternal, FlowId=" + Long.toHexString(fe.id().value())
+ + ", state=" + fe.state()
+ + ", After liveType=" + fe.flowLiveType()
+ + ", liveTime=" + liveTime
+ + ", life=" + fe.life()
+ + ", bytes=" + fe.bytes()
+ + ", packets=" + fe.packets()
+ + ", fromLastSeen=" + fromLastSeen
+ + ", priority=" + fe.priority()
+ + ", selector=" + fe.selector().criteria()
+ + ", treatment=" + fe.treatment()
+ + " AdaptiveStats collection thread for {}",
+ sw.getStringId());
+
+ return true;
+ }
+
+ /**
+ * Check and move live type for all type flow entries in table at every calAndPollInterval time.
+ *
+ */
+ public void checkAndMoveLiveFlowAll() {
+ Set<TypedStoredFlowEntry> typedFlowEntries = getFlowEntriesInternal();
+
+ long calCurTime = System.currentTimeMillis();
+ typedFlowEntries.forEach(fe -> {
+ if (!checkAndMoveLiveFlowInternal(fe, calCurTime)) {
+ remove(fe);
+ }
+ });
+
+ // print table counts for debug
+ if (log.isDebugEnabled()) {
+ synchronized (this) {
+ long totalFlowCount = getFlowCount();
+ long shortFlowCount = shortFlows.size();
+ long midFlowCount = midFlows.size();
+ long longFlowCount = longFlows.size();
+ long immediateFlowCount = totalFlowCount - shortFlowCount - midFlowCount - longFlowCount;
+ long calTotalCount = addCount + addWithSetFlowLiveTypeCount - removeCount;
+
+ log.debug("--------------------------------------------------------------------------- for {}",
+ sw.getStringId());
+ log.debug("checkAndMoveLiveFlowAll, Total Flow_Count=" + totalFlowCount
+ + ", add - remove_Count=" + calTotalCount
+ + ", IMMEDIATE_FLOW_Count=" + immediateFlowCount
+ + ", SHORT_FLOW_Count=" + shortFlowCount
+ + ", MID_FLOW_Count=" + midFlowCount
+ + ", LONG_FLOW_Count=" + longFlowCount
+ + ", add_Count=" + addCount
+ + ", addWithSetFlowLiveType_Count=" + addWithSetFlowLiveTypeCount
+ + ", remove_Count=" + removeCount
+ + " AdaptiveStats collection thread for {}", sw.getStringId());
+ log.debug("--------------------------------------------------------------------------- for {}",
+ sw.getStringId());
+ if (totalFlowCount != calTotalCount) {
+ log.error("checkAndMoveLiveFlowAll, Real total flow count and "
+ + "calculated total flow count do NOT match, something is wrong internally "
+ + "or check counter value bound is over!");
+ }
+ if (immediateFlowCount < 0) {
+ log.error("checkAndMoveLiveFlowAll, IMMEDIATE_FLOW count is negative, "
+ + "something is wrong internally "
+ + "or check counter value bound is over!");
+ }
+ }
+ }
+ log.trace("checkAndMoveLiveFlowAll, AdaptiveStats for {}", sw.getStringId());
+ }
+
+ /**
+ * Remove the typed flow entry from table.
+ *
+ * @param rule the flow rule
+ *
+ */
+ public synchronized void remove(FlowRule rule) {
+ checkNotNull(rule);
+
+ TypedStoredFlowEntry removeStore = getFlowEntryInternal(rule);
+ if (removeStore != null) {
+ removeLiveFlowsInternal((TypedStoredFlowEntry) removeStore);
+ boolean result = getFlowEntriesInternal(rule.id()).remove(removeStore);
+
+ if (result) {
+ removeCount++;
+ }
+ }
+ }
+
+ // Remove the typed flow entry from corresponding table
+ private void removeLiveFlowsInternal(TypedStoredFlowEntry fe) {
+ switch (fe.flowLiveType()) {
+ case IMMEDIATE_FLOW:
+ // do nothing
+ break;
+ case SHORT_FLOW:
+ shortFlows.remove(fe);
+ break;
+ case MID_FLOW:
+ midFlows.remove(fe);
+ break;
+ case LONG_FLOW:
+ longFlows.remove(fe);
+ break;
+ default: // error in Flow Live Type
+ log.error("removeLiveFlowsInternal, Unknown Live Type error!");
+ break;
+ }
+ }
+ }
+}
diff --git a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowValueMapper.java b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowValueMapper.java
index 2f0831c6..556f76f5 100644
--- a/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowValueMapper.java
+++ b/framework/src/onos/providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/OpenFlowValueMapper.java
@@ -20,6 +20,7 @@ import com.google.common.collect.EnumHashBiMap;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.GridType;
import org.onosproject.net.OchSignalType;
+import org.onosproject.net.OduSignalType;
/**
* Collection of helper methods to convert protocol agnostic models to values used in OpenFlow spec.
@@ -54,6 +55,17 @@ final class OpenFlowValueMapper {
OCH_SIGNAL_TYPES.put(OchSignalType.FLEX_GRID, (byte) 2); // OFPOCHT_FLEX_GRID of enum ofp_och_signal_type
}
+ private static final BiMap<OduSignalType, Byte> ODU_SIGNAL_TYPES = EnumHashBiMap.create(OduSignalType.class);
+ static {
+ // See ONF "Optical Transport Protocol Extensions Version 1.0" for the following values
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU1, (byte) 1); // OFPODUT_ODU1 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU2, (byte) 2); // OFPODUT_ODU2 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU3, (byte) 3); // OFPODUT_ODU3 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU4, (byte) 4); // OFPODUT_ODU4 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU0, (byte) 10); // OFPODUT_ODU0 of enum ofp_odu_signal_type
+ ODU_SIGNAL_TYPES.put(OduSignalType.ODU2e, (byte) 11); // OFPODUT_ODU2E of enum ofp_odu_signal_type
+ }
+
/**
* Looks up the specified input value to the corresponding value with the specified map.
*
@@ -149,4 +161,30 @@ final class OpenFlowValueMapper {
static OchSignalType lookupOchSignalType(byte signalType) {
return lookup(OCH_SIGNAL_TYPES.inverse(), signalType, OchSignalType.class);
}
+
+ /**
+ * Looks up the corresponding byte value for ODU signal type defined in
+ * ONF "Optical Transport Protocol Extensions Version 1.0"
+ * from the specified {@link OchSignalType} instance.
+ *
+ * @param signalType ODU (Optical channel Data Unit) signal type
+ * @return byte value corresponding to the specified ODU signal type
+ * @throws NoMappingFoundException if the specified ODU signal type is not found
+ */
+ static byte lookupOduSignalType(OduSignalType signalType) {
+ return lookup(ODU_SIGNAL_TYPES, signalType, Byte.class);
+ }
+
+ /**
+ * Looks up the the corresponding {@link OchSignalType} instance
+ * from the specified byte value for ODU signal type defined in
+ * ONF "Optical Transport Protocol Extensions Version 1.0".
+ *
+ * @param signalType byte value as ODU (Optical channel Data Unit) signal type defined the spec
+ * @return the corresponding OchSignalType instance
+ * @throws NoMappingFoundException if the specified ODU signal type is not found
+ */
+ static OduSignalType lookupOduSignalType(byte signalType) {
+ return lookup(ODU_SIGNAL_TYPES.inverse(), signalType, OduSignalType.class);
+ }
}
diff --git a/framework/src/onos/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/OpenFlowGroupProvider.java b/framework/src/onos/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/OpenFlowGroupProvider.java
index e69fd6b9..6c646d0d 100644
--- a/framework/src/onos/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/OpenFlowGroupProvider.java
+++ b/framework/src/onos/providers/openflow/group/src/main/java/org/onosproject/provider/of/group/impl/OpenFlowGroupProvider.java
@@ -128,7 +128,8 @@ public class OpenFlowGroupProvider extends AbstractProvider implements GroupProv
public void deactivate() {
providerRegistry.unregister(this);
providerService = null;
-
+ collectors.values().forEach(GroupStatsCollector::stop);
+ collectors.clear();
log.info("Stopped");
}
diff --git a/framework/src/onos/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java b/framework/src/onos/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java
index f5a777be..e4113790 100644
--- a/framework/src/onos/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java
+++ b/framework/src/onos/providers/openflow/meter/src/main/java/org/onosproject/provider/of/meter/impl/OpenFlowMeterProvider.java
@@ -132,6 +132,8 @@ public class OpenFlowMeterProvider extends AbstractProvider implements MeterProv
@Deactivate
public void deactivate() {
providerRegistry.unregister(this);
+ collectors.values().forEach(MeterStatsCollector::stop);
+ collectors.clear();
controller.removeEventListener(listener);
controller.removeListener(listener);
providerService = null;
diff --git a/framework/src/onos/providers/pom.xml b/framework/src/onos/providers/pom.xml
index 32890b92..5665d324 100644
--- a/framework/src/onos/providers/pom.xml
+++ b/framework/src/onos/providers/pom.xml
@@ -35,11 +35,13 @@
<module>openflow</module>
<module>lldp</module>
<module>host</module>
+ <module>netcfghost</module>
<module>netconf</module>
<module>null</module>
<module>pcep</module>
<module>ovsdb</module>
<module>bgp</module>
+ <module>snmp</module>
</modules>
<dependencies>
diff --git a/framework/src/onos/providers/snmp/alarm/pom.xml b/framework/src/onos/providers/snmp/alarm/pom.xml
new file mode 100644
index 00000000..f0a292e9
--- /dev/null
+++ b/framework/src/onos/providers/snmp/alarm/pom.xml
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2014 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-snmp-providers</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-snmp-provider-alarm</artifactId>
+ <packaging>bundle</packaging>
+
+ <description>ONOS SNMP protocol alarm provider</description>
+
+</project> \ No newline at end of file
diff --git a/framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/SNMPAlarmProvider.java b/framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/SNMPAlarmProvider.java
new file mode 100644
index 00000000..dc82a2cf
--- /dev/null
+++ b/framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/SNMPAlarmProvider.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2014-2015 Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.onosproject.provider.snmp.alarm.impl;
+
+import org.apache.felix.scr.annotations.Component;
+import org.onosproject.net.DeviceId;
+import org.onosproject.incubator.net.faultmanagement.alarm.AlarmProvider;
+import org.onosproject.net.provider.AbstractProvider;
+import org.onosproject.net.provider.ProviderId;
+import org.slf4j.Logger;
+
+import static org.slf4j.LoggerFactory.getLogger;
+
+/**
+ * Provider which uses an SNMP controller to detect network device alarms. The class leverages functionality from
+ *
+ * @see <a href="https://github.com/btisystems/snmp-core">https://github.com/btisystems/snmp-core</a>
+ * @see <a href="https://github.com/btisystems/mibbler">https://github.com/btisystems/mibbler</a>
+ */
+@Component(immediate = true)
+public class SNMPAlarmProvider extends AbstractProvider implements AlarmProvider {
+
+ private static final Logger LOG = getLogger(SNMPAlarmProvider.class);
+
+ /**
+ * Creates a SNMP alarm provider, dummy class provided as template, tbd later.
+ */
+ public SNMPAlarmProvider() {
+ super(new ProviderId("snmp", "org.onosproject.provider.alarm"));
+ }
+
+ @Override
+ public void triggerProbe(final DeviceId deviceId) {
+
+ // TODO in shout term should this just be synchronous and return result?
+ LOG.info("Run a SNMP discovery for device at {} when done invoke on AlarmProviderService", deviceId);
+
+ // TODO Look up AlarmProviderService
+ // TODO Decide threading
+ // TODO Decide shouldn't it be generic not alarm-specific ? Its user responsible for passing in OID list ?
+ // Same for its callack AlarmProviderService ?
+ }
+
+}
diff --git a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/package-info.java b/framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/package-info.java
index b095fc9a..2c138cbb 100644
--- a/framework/src/onos/providers/netconf/flow/src/main/java/org/onosproject/provider/netconf/flow/impl/package-info.java
+++ b/framework/src/onos/providers/snmp/alarm/src/main/java/org/onosproject/provider/snmp/alarm/impl/package-info.java
@@ -15,7 +15,6 @@
*/
/**
- * Provider that will accept any flow rules.
+ * Provider that uses SNMP as a means of discovering alarms on devices.
*/
-package org.onosproject.provider.netconf.flow.impl;
-
+package org.onosproject.provider.snmp.alarm.impl;
diff --git a/framework/src/onos/providers/snmp/pom.xml b/framework/src/onos/providers/snmp/pom.xml
new file mode 100644
index 00000000..21031d98
--- /dev/null
+++ b/framework/src/onos/providers/snmp/pom.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2014 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.
+ -->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-providers</artifactId>
+ <version>1.4.0-SNAPSHOT</version>
+ <relativePath>../pom.xml</relativePath>
+ </parent>
+
+ <artifactId>onos-snmp-providers</artifactId>
+ <packaging>pom</packaging>
+
+ <description>ONOS SNMP Protocol Adapters</description>
+
+ <modules>
+ <module>alarm</module>
+ </modules>
+
+</project> \ No newline at end of file