Updates of SimpleFabric applcation
- add CLI and REST interfaces
- add l2Network.l2Broadcast flag
- debug on borderRoutes
- minor method name changes
Change-Id: Idabcac99b6046844c7751949a5067850835c5f6a
diff --git a/apps/simplefabric/BUCK b/apps/simplefabric/BUCK
index 8125580..b215c46 100644
--- a/apps/simplefabric/BUCK
+++ b/apps/simplefabric/BUCK
@@ -2,6 +2,10 @@
'//lib:CORE_DEPS',
'//lib:JACKSON',
'//lib:concurrent-trees',
+ '//lib:javax.ws.rs-api',
+ '//lib:org.apache.karaf.shell.console',
+ '//cli:onos-cli',
+ '//utils/rest:onlab-rest',
]
BUNDLES = [
@@ -15,6 +19,7 @@
osgi_jar_with_tests (
deps = COMPILE_DEPS,
test_deps = TEST_DEPS,
+ web_context = '/onos/v1/simplefabric',
)
onos_app (
diff --git a/apps/simplefabric/app.xml b/apps/simplefabric/app.xml
index df5cc60..1984e56 100644
--- a/apps/simplefabric/app.xml
+++ b/apps/simplefabric/app.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright 2017-present Open Networking Laboratory
+ ~ Copyright 2017-present Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
diff --git a/apps/simplefabric/features.xml b/apps/simplefabric/features.xml
index 9ab23de..fd67ef1 100644
--- a/apps/simplefabric/features.xml
+++ b/apps/simplefabric/features.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
- ~ Copyright 2017-present Open Networking Laboratory
+ ~ Copyright 2017-present Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
diff --git a/apps/simplefabric/network-cfg.json b/apps/simplefabric/network-cfg.json
index f988497..c8e118b 100644
--- a/apps/simplefabric/network-cfg.json
+++ b/apps/simplefabric/network-cfg.json
@@ -38,8 +38,8 @@
"org.onosproject.simplefabric" : {
"simpleFabric" : {
"l2Networks" : [
- { "name" : "LEAF1", "interfaces" : ["h11", "h12", "h13", "h14", "d11", "d12" ], "l2Forward" : true },
- { "name" : "LEAF2", "interfaces" : ["h21", "h22", "h23", "h24", "d21", "d22" ], "l2Forward" : true }
+ { "name" : "LEAF1", "interfaces" : ["h11", "h12", "h13", "h14", "d11", "d12" ], "l2Forward" : true, "l2Broadcast" : true },
+ { "name" : "LEAF2", "interfaces" : ["h21", "h22", "h23", "h24", "d21", "d22" ], "l2Forward" : true, "l2Broadcast" : true }
],
"ipSubnets" : [
{ "ipPrefix" : "10.0.1.0/24", "gatewayIp" : "10.0.1.1", "gatewayMac" : "00:00:10:00:01:01", "l2NetworkName" : "LEAF1" },
diff --git a/apps/simplefabric/pom.xml b/apps/simplefabric/pom.xml
index 8954d24..e276ca7 100644
--- a/apps/simplefabric/pom.xml
+++ b/apps/simplefabric/pom.xml
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
- ~ Copyright 2017-present Open Networking Laboratory
+ ~ Copyright 2017-present Open Networking Foundation
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
diff --git a/apps/simplefabric/rest-simplefabric b/apps/simplefabric/rest-simplefabric
new file mode 100755
index 0000000..130fa3b
--- /dev/null
+++ b/apps/simplefabric/rest-simplefabric
@@ -0,0 +1,62 @@
+#!/bin/bash
+
+#
+# Copyright 2017-present Open Networking Foundation
+#
+# 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.
+#
+
+# -----------------------------------------------------------------------------
+# Tool to manage ONOS applications using REST API.
+# -----------------------------------------------------------------------------
+
+# If ONOS_HOME is set, respect its value.
+# If ONOS_HOME is not set (e.g. in the init or service environment),
+# set it based on this script's path.
+ONOS_HOME=${ONOS_HOME:-$(cd $(dirname $0)/.. >/dev/null 2>&1 && pwd)}
+ONOS_WEB_USER=${ONOS_WEB_USER:-onos} # ONOS WEB User defaults to 'onos'
+ONOS_WEB_PASS=${ONOS_WEB_PASS:-rocks} # ONOS WEB Password defaults to 'rocks'
+
+. ${ONOS_HOME}/bin/_find-node
+
+node=$(find_node ${1:-localhost})
+cmd=${2:-show}
+
+export URL=http://$node:8181/onos/v1/simplefabric/$cmd
+#export HDR="-HContent-Type:application/octet-stream"
+#export HAJ="-HContent-Type:application/json"
+export curl="curl -sS --user $ONOS_WEB_USER:$ONOS_WEB_PASS --noproxy localhost "
+
+# Prints usage help
+function usage {
+ echo "usage: onos-simplefabric <node-ip> status|show|intents|reactive-intents|refresh|flush" >&2
+ exit 1
+}
+
+[ -z $node -o "$node" = "-h" -o "$node" = "--help" -o "$node" = "-?" ] && usage
+
+case $cmd in
+ status) $curl -X GET $URL;;
+ show) $curl -X GET $URL;;
+ intents) $curl -X GET $URL;;
+ reactive-intents) $curl -X GET $URL;;
+ refresh) $curl -X PUT $URL;;
+ flush) $curl -X PUT $URL;;
+
+ *) usage;;
+esac
+
+
+status=$?
+echo # new line for prompt
+exit $status
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java
index 31e8cc0..5579159 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/L2Network.java
@@ -41,6 +41,7 @@
private Set<String> interfaceNames; // also for network configuration
private EncapsulationType encapsulation; // also for network configuration
private boolean l2Forward; // do l2Forward (default:true) or not
+ private boolean l2Broadcast; // do l2Broadcast (default:true) or not
/* status variables */
private Set<Interface> interfaces; // available interfaces from interfaceNames
@@ -54,13 +55,16 @@
* @param ifaceNames the interface names
* @param encapsulation the encapsulation type
* @param l2Forward flag for l2Forward intents to be installed or not
+ * @param l2Broadcast flag for l2Broadcast intents to be installed or not
*/
- L2Network(String name, Collection<String> ifaceNames, EncapsulationType encapsulation, boolean l2Forward) {
+ L2Network(String name, Collection<String> ifaceNames, EncapsulationType encapsulation,
+ boolean l2Forward, boolean l2Broadcast) {
this.name = name;
this.interfaceNames = Sets.newHashSet();
this.interfaceNames.addAll(ifaceNames);
this.encapsulation = encapsulation;
this.l2Forward = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? l2Forward : false;
+ this.l2Broadcast = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? l2Broadcast : false;
this.interfaces = Sets.newHashSet();
this.hostIds = Sets.newHashSet();
this.dirty = false;
@@ -77,6 +81,7 @@
this.interfaceNames = Sets.newHashSet();
this.encapsulation = encapsulation;
this.l2Forward = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? true : false;
+ this.l2Broadcast = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? true : false;
this.interfaces = Sets.newHashSet();
this.hostIds = Sets.newHashSet();
this.dirty = false;
@@ -105,6 +110,7 @@
L2Network l2NetworkCopy = new L2Network(l2Network.name(), l2Network.encapsulation());
l2NetworkCopy.interfaceNames.addAll(l2Network.interfaceNames());
l2NetworkCopy.l2Forward = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? l2Network.l2Forward() : false;
+ l2NetworkCopy.l2Broadcast = (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) ? l2Network.l2Broadcast() : false;
l2NetworkCopy.interfaces.addAll(l2Network.interfaces());
l2NetworkCopy.hostIds.addAll(l2Network.hostIds());
l2NetworkCopy.setDirty(l2Network.dirty());
@@ -150,6 +156,15 @@
}
/**
+ * Gets L2Network l2Broadcast flag.
+ *
+ * @return the l2Broadcast flag of L2Network
+ */
+ public boolean l2Broadcast() {
+ return l2Broadcast;
+ }
+
+ /**
* Gets L2Network interfaces.
*
* @return the interfaces of L2Network
@@ -257,6 +272,7 @@
.add("interfaceNames", interfaceNames)
.add("encapsulation", encapsulation)
.add("l2Forward", l2Forward)
+ .add("l2Broadcast", l2Broadcast)
.add("interfaces", interfaces)
.add("hostIds", hostIds)
.add("dirty", dirty)
@@ -276,12 +292,13 @@
&& Objects.equals(other.interfaceNames, this.interfaceNames)
&& Objects.equals(other.encapsulation, this.encapsulation)
&& Objects.equals(other.l2Forward, this.l2Forward)
+ && Objects.equals(other.l2Broadcast, this.l2Broadcast)
&& Objects.equals(other.interfaces, this.interfaces)
&& Objects.equals(other.hostIds, this.hostIds);
}
@Override
public int hashCode() {
- return Objects.hash(name, interfaces, encapsulation, l2Forward);
+ return Objects.hash(name, interfaces, encapsulation, l2Forward, l2Broadcast);
}
}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricCommand.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricCommand.java
new file mode 100644
index 0000000..e5ed60e
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricCommand.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import org.apache.karaf.shell.commands.Argument;
+import org.apache.karaf.shell.commands.Command;
+import org.onosproject.cli.AbstractShellCommand;
+
+/**
+ * CLI to interact with the SIMPLE_FABRIC application.
+ */
+@Command(scope = "onos", name = "simpleFabric",
+ description = "Manages the SimpleFabric application")
+public class SimpleFabricCommand extends AbstractShellCommand {
+
+ protected static SimpleFabricService simpleFabric;
+
+ @Argument(index = 0, name = "command",
+ description = "Command: show|intents|reactive-intents|refresh|flush",
+ required = true, multiValued = false)
+ String command = null;
+
+ @Override
+ protected void execute() {
+ if (simpleFabric == null) {
+ simpleFabric = get(SimpleFabricService.class);
+ }
+ if (command == null) {
+ print("command not found", command);
+ return;
+ }
+ switch (command) {
+ case "show":
+ simpleFabric.dumpToStream("show", System.out);
+ break;
+ case "intents":
+ simpleFabric.dumpToStream("intents", System.out);
+ break;
+ case "reactive-intents":
+ simpleFabric.dumpToStream("reactive-intents", System.out);
+ break;
+ case "refresh":
+ simpleFabric.triggerRefresh();
+ System.out.println("simple fabric refresh triggered");
+ break;
+ case "flush":
+ simpleFabric.triggerFlush();
+ System.out.println("simple fabric flush triggered");
+ break;
+ default:
+ System.out.println("unknown command: " + command);
+ break;
+ }
+ }
+
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricCommandCompleter.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricCommandCompleter.java
new file mode 100644
index 0000000..b810d73
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricCommandCompleter.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import com.google.common.collect.Lists;
+import org.apache.karaf.shell.console.completer.ArgumentCompleter;
+import org.onosproject.cli.AbstractChoicesCompleter;
+
+import java.util.List;
+import java.util.Arrays;
+import java.util.Collections;
+
+/**
+ * SimpleFabric command completer.
+ */
+public class SimpleFabricCommandCompleter extends AbstractChoicesCompleter {
+
+ public static final List<String> COMMAND_LIST =
+ Arrays.asList("show", "intents", "reactive-intents", "refresh", "flush");
+
+ @Override
+ public List<String> choices() {
+ ArgumentCompleter.ArgumentList argumentList = getArgumentList();
+ if (argumentList == null) {
+ return Collections.emptyList();
+ }
+ List<String> argList = Lists.newArrayList(argumentList.getArguments());
+ String argOne = null;
+ if (argList.size() > 1) {
+ argOne = argList.get(1);
+ }
+ if (COMMAND_LIST.contains(argOne)) {
+ return Collections.emptyList();
+ } else {
+ return COMMAND_LIST;
+ }
+ }
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
index a6d83b1..7bae152 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricConfig.java
@@ -40,6 +40,7 @@
private static final String INTERFACES = "interfaces";
private static final String ENCAPSULATION = "encapsulation";
private static final String L2FORWARD = "l2Forward";
+ private static final String L2BROADCAST = "l2Broadcast";
private static final String IPSUBNETS = "ipSubnets";
private static final String BORDERROUTES = "borderRoutes";
private static final String IPPREFIX = "ipPrefix";
@@ -78,12 +79,14 @@
if (jsonNode.hasNonNull(L2FORWARD)) {
l2Forward = jsonNode.get(L2FORWARD).asBoolean();
}
+ boolean l2Broadcast = true;
+ if (jsonNode.hasNonNull(L2BROADCAST)) {
+ l2Broadcast = jsonNode.get(L2BROADCAST).asBoolean();
+ }
try {
l2Networks.add(new L2Network(
- jsonNode.get(NAME).asText(),
- ifaces,
- EncapsulationType.enumFromString(encapsulation),
- l2Forward));
+ jsonNode.get(NAME).asText(), ifaces, EncapsulationType.enumFromString(encapsulation),
+ l2Forward, l2Broadcast));
} catch (Exception e) {
log.warn("simple fabric network config l2Network parse failed; skip: error={} jsonNode={}", jsonNode);
}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
index 0839cf9..a67ed1a 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricL2Forward.java
@@ -256,15 +256,15 @@
private Set<Intent> generateL2NetworkIntents(L2Network l2Network) {
return new ImmutableSet.Builder<Intent>()
- .addAll(buildBrcIntents(l2Network))
- .addAll(buildUniIntents(l2Network, hostsFromL2Network(l2Network)))
- .build();
+ .addAll(buildBrcIntents(l2Network))
+ .addAll(buildUniIntents(l2Network, hostsFromL2Network(l2Network)))
+ .build();
}
// Build Boadcast Intents for a L2 Network.
private Set<SinglePointToMultiPointIntent> buildBrcIntents(L2Network l2Network) {
Set<Interface> interfaces = l2Network.interfaces();
- if (!l2Network.l2Forward() || interfaces.size() < 2) {
+ if (interfaces.size() < 2 || !l2Network.l2Forward() || !l2Network.l2Broadcast()) {
return ImmutableSet.of();
}
Set<SinglePointToMultiPointIntent> brcIntents = Sets.newHashSet();
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
index b1e6c96..81dd602 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricManager.java
@@ -71,7 +71,6 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.ByteBuffer;
-import java.util.Iterator;
import java.util.HashSet;
import java.util.Collection;
import java.util.Set;
@@ -243,7 +242,7 @@
for (Host host : hostService.getHosts()) {
// consider host with ip only
if (!host.ipAddresses().isEmpty()) {
- Interface iface = getAvailableDeviceHostInterface(host);
+ Interface iface = findAvailableDeviceHostInterface(host);
if (iface != null && newL2Network.contains(iface)) {
newL2Network.addHost(host);
}
@@ -358,11 +357,6 @@
}
@Override
- public MacAddress getVMacForIp(IpAddress ip) {
- return virtualGatewayIpMacMap.get(ip);
- }
-
- @Override
public boolean isVMac(MacAddress mac) {
return virtualGatewayIpMacMap.containsValue(mac);
}
@@ -373,6 +367,11 @@
}
@Override
+ public MacAddress findVMacForIp(IpAddress ip) {
+ return virtualGatewayIpMacMap.get(ip);
+ }
+
+ @Override
public L2Network findL2Network(ConnectPoint port, VlanId vlanId) {
for (L2Network l2Network : l2Networks) {
if (l2Network.contains(port, vlanId)) {
@@ -394,34 +393,30 @@
@Override
public IpSubnet findIpSubnet(IpAddress ip) {
- Iterator<IpSubnet> it;
if (ip.isIp4()) {
- it = ip4SubnetTable.getValuesForKeysPrefixing(
- createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH))).iterator();
+ return ip4SubnetTable.getValueForLongestKeyPrefixing(
+ createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)));
} else {
- it = ip6SubnetTable.getValuesForKeysPrefixing(
- createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH))) .iterator();
+ return ip6SubnetTable.getValueForLongestKeyPrefixing(
+ createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)));
}
- return (it.hasNext()) ? it.next() : null;
}
@Override
public Route findBorderRoute(IpAddress ip) {
// ASSUME: ipAddress is out of ipSubnet
- Iterator<Route> it;
if (ip.isIp4()) {
- it = ip4BorderRouteTable.getValuesForKeysPrefixing(
- createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH))) .iterator();
+ return ip4BorderRouteTable.getValueForLongestKeyPrefixing(
+ createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)));
} else {
- it = ip6BorderRouteTable.getValuesForKeysPrefixing(
- createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH))) .iterator();
+ return ip6BorderRouteTable.getValueForLongestKeyPrefixing(
+ createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)));
}
- return (it.hasNext()) ? it.next() : null;
}
@Override
- public Interface getHostInterface(Host host) {
+ public Interface findHostInterface(Host host) {
return interfaceService.getInterfaces().stream()
.filter(iface -> iface.connectPoint().equals(host.location()) &&
iface.vlan().equals(host.vlan()))
@@ -429,7 +424,7 @@
.orElse(null);
}
- private Interface getAvailableDeviceHostInterface(Host host) {
+ private Interface findAvailableDeviceHostInterface(Host host) {
return interfaceService.getInterfaces().stream()
.filter(iface -> iface.connectPoint().equals(host.location()) &&
iface.vlan().equals(host.vlan()))
@@ -439,29 +434,6 @@
}
@Override
- public boolean isIpAddressLocal(IpAddress ip) {
- boolean result;
- if (ip.isIp4()) {
- return ip4SubnetTable.getValuesForKeysPrefixing(
- createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)))
- .iterator().hasNext();
- } else {
- return ip6SubnetTable.getValuesForKeysPrefixing(
- createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)))
- .iterator().hasNext();
- }
- }
-
- @Override
- public boolean isIpPrefixLocal(IpPrefix ipPrefix) {
- if (ipPrefix.isIp4()) {
- return (ip4SubnetTable.getValueForExactKey(createBinaryString(ipPrefix)) != null);
- } else {
- return (ip6SubnetTable.getValueForExactKey(createBinaryString(ipPrefix)) != null);
- }
- }
-
- @Override
public boolean requestMac(IpAddress ip) {
IpSubnet ipSubnet = findIpSubnet(ip);
if (ipSubnet == null) {
@@ -512,6 +484,8 @@
protected void dump(String subject, PrintStream out) {
if ("show".equals(subject)) {
out.println("Static Configuration Flag:");
+ out.println(" ALLOW_IPV6="
+ + SimpleFabricService.ALLOW_IPV6);
out.println(" ALLOW_ETH_ADDRESS_SELECTOR="
+ SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR);
out.println(" REACTIVE_SINGLE_TO_SINGLE="
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
index 9d0b3fc..d796346 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricNeighbour.java
@@ -130,7 +130,7 @@
* @param context the message context
*/
protected void handleRequest(NeighbourMessageContext context) {
- MacAddress mac = simpleFabric.getVMacForIp(context.target());
+ MacAddress mac = simpleFabric.findVMacForIp(context.target());
if (mac != null) {
log.trace("simple fabric neightbour request on virtualGatewayAddress {}; response to {} {} mac={}",
context.target(), context.inPort(), context.vlan(), mac);
@@ -181,7 +181,7 @@
L2Network l2Network = simpleFabric.findL2Network(context.inPort(), context.vlan());
if (l2Network != null) {
// TODO: need to check and update simpleFabric.L2Network
- MacAddress mac = simpleFabric.getVMacForIp(context.target());
+ MacAddress mac = simpleFabric.findVMacForIp(context.target());
if (mac != null) {
log.trace("simple fabric neightbour response message to virtual gateway; drop: {} {} target={}",
context.inPort(), context.vlan(), context.target());
@@ -192,7 +192,7 @@
log.trace("simple fabric neightbour response message forward: {} {} target={} -> {}",
context.inPort(), context.vlan(), context.target(), hosts);
hosts.stream()
- .map(host -> simpleFabric.getHostInterface(host))
+ .map(host -> simpleFabric.findHostInterface(host))
.filter(Objects::nonNull)
.forEach(context::forward);
}
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
index 4ce0480..1a9d64f 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricReactiveRouting.java
@@ -60,6 +60,7 @@
import org.onosproject.net.intent.IntentService;
import org.onosproject.net.intent.Key;
import org.onosproject.net.intent.MultiPointToSinglePointIntent;
+import org.onosproject.net.intf.Interface;
import org.onosproject.net.link.LinkService;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.InboundPacket;
@@ -68,7 +69,6 @@
import org.onosproject.net.packet.PacketPriority;
import org.onosproject.net.packet.PacketProcessor;
import org.onosproject.net.packet.PacketService;
-import org.onosproject.net.Port;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -226,7 +226,8 @@
// check if this devices has the ipSubnet, then add ip broadcast flue rule
L2Network l2Network = simpleFabric.findL2Network(subnet.l2NetworkName());
if (l2Network != null && l2Network.contains(device.id())) {
- newInterceptFlowRules.add(generateLocalSubnetIpBctFlowRule(device.id(), subnet.ipPrefix()));
+ newInterceptFlowRules.add(generateLocalSubnetIpBctFlowRule(device.id(), subnet.ipPrefix(),
+ l2Network));
}
// JUST FOR FLOW RULE TEST ONLY
//newInterceptFlowRules.add(generateTestFlowRule(device.id(), subnet.ipPrefix()));
@@ -256,7 +257,7 @@
}
}
- private FlowRule generateInterceptFlowRule(boolean isLocalSubnet, DeviceId deviceId, IpPrefix prefix) {
+ private FlowRule generateInterceptFlowRule(boolean isDstLocalSubnet, DeviceId deviceId, IpPrefix prefix) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
if (prefix.isIp4()) {
selector.matchEthType(Ethernet.TYPE_IPV4);
@@ -271,7 +272,7 @@
}
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
- .withPriority(reactivePriority(false, isLocalSubnet, prefix.prefixLength()))
+ .withPriority(reactivePriority(false, isDstLocalSubnet, prefix.prefixLength()))
.withSelector(selector.build())
.withTreatment(DefaultTrafficTreatment.builder().punt().build())
.fromApp(reactiveAppId)
@@ -280,7 +281,7 @@
return rule;
}
- private FlowRule generateLocalSubnetIpBctFlowRule(DeviceId deviceId, IpPrefix prefix) {
+ private FlowRule generateLocalSubnetIpBctFlowRule(DeviceId deviceId, IpPrefix prefix, L2Network l2Network) {
TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
IpPrefix bctPrefix;
if (prefix.isIp4()) {
@@ -301,8 +302,10 @@
}
TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
Set<ConnectPoint> newEgressPoints = new HashSet<>();
- for (Port port : deviceService.getPorts(deviceId)) {
- treatment.setOutput(port.number());
+ for (Interface iface : l2Network.interfaces()) {
+ if (iface.connectPoint().deviceId().equals(deviceId)) {
+ treatment.setOutput(iface.connectPoint().port());
+ }
}
FlowRule rule = DefaultFlowRule.builder()
.forDevice(deviceId)
@@ -548,8 +551,9 @@
private boolean checkVirtualGatewayIpPacket(InboundPacket pkt, IpAddress srcIp, IpAddress dstIp) {
Ethernet ethPkt = pkt.parsed(); // assume valid
- MacAddress mac = simpleFabric.getVMacForIp(dstIp);
- if (mac == null || !ethPkt.getDestinationMAC().equals(mac)) {
+ MacAddress mac = simpleFabric.findVMacForIp(dstIp);
+ if (mac == null || !simpleFabric.isVMac(ethPkt.getDestinationMAC())) {
+ /* Destination MAC should be any of virtual gateway macs */
return false;
} else if (dstIp.isIp4()) {
IPv4 ipv4Packet = (IPv4) ethPkt.getPayload();
@@ -616,7 +620,6 @@
IpAddress dstNextHop = dstIp;
MacAddress treatmentSrcMac = ethPkt.getDestinationMAC();
int borderRoutePrefixLength = 0;
- boolean isLocalSubnet = true;
boolean updateMac = simpleFabric.isVMac(ethPkt.getDestinationMAC());
// check subnet local or route
@@ -624,25 +627,25 @@
if (srcSubnet == null) {
Route route = simpleFabric.findBorderRoute(srcIp);
if (route == null) {
- log.warn("route unknown: srcIp={}", srcIp);
+ log.warn("unknown srcIp; drop: srcCp={} srcIp={} dstIp={} ipProto={}",
+ srcCp, srcIp, dstIp, ipProto);
return;
}
srcPrefix = route.prefix();
srcNextHop = route.nextHop();
borderRoutePrefixLength = route.prefix().prefixLength();
- isLocalSubnet = false;
}
IpSubnet dstSubnet = simpleFabric.findIpSubnet(dstIp);
if (dstSubnet == null) {
Route route = simpleFabric.findBorderRoute(dstIp);
if (route == null) {
- log.warn("route unknown: dstIp={}", dstIp);
+ log.warn("unknown dstIp; drop: srcCp={} srcIp={} dstIp={} ipProto={}",
+ srcCp, srcIp, dstIp, ipProto);
return;
}
dstPrefix = route.prefix();
dstNextHop = route.nextHop();
borderRoutePrefixLength = route.prefix().prefixLength();
- isLocalSubnet = false;
}
if (dstSubnet != null) {
@@ -687,7 +690,7 @@
srcIp, dstIp, ethPkt.getSourceMAC(), ethPkt.getDestinationMAC(),
ethPkt.getVlanID(), ipProto, updateMac);
setUpConnectivity(srcCp, ipProto, srcPrefix, dstPrefix, dstNextHop, treatmentSrcMac, encap, updateMac,
- isLocalSubnet, borderRoutePrefixLength);
+ dstSubnet != null, borderRoutePrefixLength);
forwardPacketToDstIp(context, dstNextHop, treatmentSrcMac, updateMac);
}
@@ -737,18 +740,7 @@
private boolean setUpConnectivity(ConnectPoint srcCp, byte ipProto, IpPrefix srcPrefix, IpPrefix dstPrefix,
IpAddress nextHopIp, MacAddress treatmentSrcMac,
EncapsulationType encap, boolean updateMac,
- boolean isLocalSubnet, int borderRoutePrefixLength) {
- Key key;
- String keyProtoTag = "";
- if (simpleFabric.REACTIVE_MATCH_IP_PROTO) {
- keyProtoTag = "-p" + ipProto;
- }
- if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE) {
- key = Key.of(srcPrefix.toString() + "-to-" + dstPrefix.toString() + keyProtoTag, reactiveAppId);
- } else {
- key = Key.of(dstPrefix.toString() + keyProtoTag, reactiveAppId);
- }
-
+ boolean isDstLocalSubnet, int borderRoutePrefixLength) {
if (!(simpleFabric.findL2Network(srcCp, VlanId.NONE) != null ||
(simpleFabric.REACTIVE_ALLOW_LINK_CP && !linkService.getIngressLinks(srcCp).isEmpty()))) {
log.warn("NO REGI for srcCp not in L2Network; srcCp={} srcPrefix={} dstPrefix={} nextHopIp={}",
@@ -804,6 +796,19 @@
}
}
+ Key key;
+ String keyProtoTag = "";
+ if (simpleFabric.REACTIVE_MATCH_IP_PROTO) {
+ keyProtoTag = "-p" + ipProto;
+ }
+ if (simpleFabric.REACTIVE_SINGLE_TO_SINGLE) {
+ // allocate intent per (srcPrefix, dstPrefix)
+ key = Key.of(srcPrefix.toString() + "-to-" + dstPrefix.toString() + keyProtoTag, reactiveAppId);
+ } else {
+ // allocate intent per (srcDeviceId, dstPrefix)
+ key = Key.of(srcCp.deviceId().toString() + "-to-" + dstPrefix.toString() + keyProtoTag, reactiveAppId);
+ }
+
// check and merge already existing ingress points
Set<ConnectPoint> ingressPoints = new HashSet<>();
MultiPointToSinglePointIntent existingIntent = (MultiPointToSinglePointIntent) intentService.getIntent(key);
@@ -825,7 +830,7 @@
}
// priority for forwarding case
- int priority = reactivePriority(true, isLocalSubnet, borderRoutePrefixLength);
+ int priority = reactivePriority(true, isDstLocalSubnet, borderRoutePrefixLength);
MultiPointToSinglePointIntent newIntent = MultiPointToSinglePointIntent.builder()
.key(key)
@@ -863,14 +868,14 @@
}
// priority calculator
- private int reactivePriority(boolean isForward, boolean isLocalSubnet, int borderRoutePrefixLength) {
- if (isLocalSubnet) { // localSubnet <-> localSubnet
+ private int reactivePriority(boolean isForward, boolean isDstLocalSubnet, int borderRoutePrefixLength) {
+ if (isDstLocalSubnet) { // -> dst:localSubnet
if (isForward) {
return simpleFabric.PRI_REACTIVE_LOCAL_FORWARD;
} else { // isInterncept
return simpleFabric.PRI_REACTIVE_LOCAL_INTERCEPT;
}
- } else { // isBorder: localSubnet <-> boarderRouteGateway
+ } else { // -> dst:boarderRouteNextHop
int offset;
if (isForward) {
offset = simpleFabric.PRI_REACTIVE_BORDER_FORWARD;
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java
index c27a828..be2bed3 100644
--- a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricService.java
@@ -16,7 +16,6 @@
package org.onosproject.simplefabric;
import org.onlab.packet.IpAddress;
-import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onosproject.core.ApplicationId;
@@ -96,14 +95,6 @@
Set<Route> getBorderRoutes();
/**
- * Gets Virtual Gateway Mac Address for Local Subnet Virtual Gateway Ip.
- *
- * @param ip the ip to check for Virtual Gateway Ip
- * @return mac address of virtual gateway
- */
- MacAddress getVMacForIp(IpAddress ip);
-
- /**
* Evaluates whether a mac is of Virtual Gateway Mac Addresses.
*
* @param mac the MacAddress to evaluate
@@ -120,6 +111,14 @@
boolean isL2NetworkInterface(Interface intf);
/**
+ * Find Virtual Gateway Mac Address for Local Subnet Virtual Gateway Ip.
+ *
+ * @param ip the ip to check for Virtual Gateway Ip
+ * @return mac address of virtual gateway
+ */
+ MacAddress findVMacForIp(IpAddress ip);
+
+ /**
* Finds the L2 Network with given port and vlanId.
*
* @param port the port to be matched
@@ -159,23 +158,7 @@
* @param host the host
* @return the interface related to the host
*/
- Interface getHostInterface(Host host);
-
- /**
- * Evaluates whether an IP address belongs to local SDN network.
- *
- * @param ipAddress the IP address to evaluate
- * @return true if the IP address belongs to local SDN network, otherwise false
- */
- boolean isIpAddressLocal(IpAddress ipAddress);
-
- /**
- * Evaluates whether an IP prefix belongs to local SDN network.
- *
- * @param ipPrefix the IP prefix to evaluate
- * @return true if the IP prefix belongs to local SDN network, otherwise false
- */
- boolean isIpPrefixLocal(IpPrefix ipPrefix);
+ Interface findHostInterface(Host host);
/**
* Sends Neighbour Query (ARP or NDP) to Find Host Location.
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricWebApplication.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricWebApplication.java
new file mode 100644
index 0000000..d82de73
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricWebApplication.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import org.onlab.rest.AbstractWebApplication;
+
+import java.util.Set;
+
+/**
+ * SIMPLE_FABRIC REST API web application.
+ */
+public class SimpleFabricWebApplication extends AbstractWebApplication {
+ @Override
+ public Set<Class<?>> getClasses() {
+ return getClasses(SimpleFabricWebResource.class);
+ }
+}
+
diff --git a/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricWebResource.java b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricWebResource.java
new file mode 100644
index 0000000..f1e9af7
--- /dev/null
+++ b/apps/simplefabric/src/main/java/org/onosproject/simplefabric/SimpleFabricWebResource.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.simplefabric;
+
+import org.onosproject.rest.AbstractWebResource;
+
+import java.io.ByteArrayOutputStream;
+import javax.ws.rs.GET;
+import javax.ws.rs.PUT;
+import javax.ws.rs.Path;
+import javax.ws.rs.core.Response;
+
+/**
+ * Manage SIMPLE_FABRIC Status.
+ */
+@Path("")
+public class SimpleFabricWebResource extends AbstractWebResource {
+
+ /**
+ * SIMPLE_FABRIC Show Status; dummy for now.
+ *
+ * @return 200 OK
+ */
+ @GET
+ @Path("status")
+ public Response queryStatus() {
+ return Response.ok("ok").build();
+ }
+
+ /**
+ * SIMPLE_FABRIC Show Configurations.
+ *
+ * @return 200 OK
+ */
+ @GET
+ @Path("show")
+ public Response queryShow() {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ get(SimpleFabricService.class).dumpToStream("show", outputStream);
+ return Response.ok(outputStream.toString()).build();
+ }
+
+ /**
+ * SIMPLE_FABRIC Intents Infos.
+ *
+ * @return 200 OK
+ */
+ @GET
+ @Path("intents")
+ public Response queryIntents() {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ get(SimpleFabricService.class).dumpToStream("intents", outputStream);
+ return Response.ok(outputStream.toString()).build();
+ }
+
+ /**
+ * SIMPLE_FABRIC Reactive Intents Infos.
+ *
+ * @return 200 OK
+ */
+ @GET
+ @Path("reactive-intents")
+ public Response queryReactiveIntents() {
+ ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
+ get(SimpleFabricService.class).dumpToStream("reactive-intents", outputStream);
+ return Response.ok(outputStream.toString()).build();
+ }
+
+ /**
+ * Trigger SimpleFabric Service Refresh.
+ *
+ * @return 204 No Content
+ */
+ @PUT
+ @Path("refresh")
+ public Response triggerRefresh() {
+ get(SimpleFabricService.class).triggerRefresh();
+ return Response.status(204).build();
+ }
+
+ /**
+ * Trigger SimpleFabric Service Flush Reactive Intents.
+ *
+ * @return 204 No Content
+ */
+ @PUT
+ @Path("flush")
+ public Response triggerFlush() {
+ get(SimpleFabricService.class).triggerFlush();
+ return Response.status(204).build();
+ }
+
+}
+
diff --git a/apps/simplefabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml b/apps/simplefabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml
new file mode 100644
index 0000000..7b6893b
--- /dev/null
+++ b/apps/simplefabric/src/main/resources/OSGI-INF/blueprint/shell-config.xml
@@ -0,0 +1,28 @@
+<!--
+ ~ Copyright 2017-present Open Networking Foundation
+ ~
+ ~ 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.
+ -->
+<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
+
+ <command-bundle xmlns="http://karaf.apache.org/xmlns/shell/v1.1.0">
+ <command>
+ <action class="org.onosproject.simplefabric.SimpleFabricCommand"/>
+ <completers>
+ <ref component-id="SimpleFabricCommandCompleter"/>
+ </completers>
+ </command>
+ </command-bundle>
+
+ <bean id="SimpleFabricCommandCompleter" class="org.onosproject.simplefabric.SimpleFabricCommandCompleter"/>
+</blueprint>
diff --git a/apps/simplefabric/src/main/webapp/WEB-INF/web.xml b/apps/simplefabric/src/main/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..a0e0004
--- /dev/null
+++ b/apps/simplefabric/src/main/webapp/WEB-INF/web.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ Copyright 2017-present Open Networking Foundation
+ ~
+ ~ 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.
+ -->
+<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee"
+ xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
+ id="ONOS" version="2.5">
+ <display-name>Simple Fabric application REST API</display-name>
+
+ <security-constraint>
+ <web-resource-collection>
+ <web-resource-name>Secured</web-resource-name>
+ <url-pattern>/*</url-pattern>
+ </web-resource-collection>
+ <auth-constraint>
+ <role-name>admin</role-name>
+ </auth-constraint>
+ </security-constraint>
+
+ <security-role>
+ <role-name>admin</role-name>
+ </security-role>
+
+ <login-config>
+ <auth-method>BASIC</auth-method>
+ <realm-name>karaf</realm-name>
+ </login-config>
+
+ <servlet>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
+ <init-param>
+ <param-name>javax.ws.rs.Application</param-name>
+ <param-value>org.onosproject.simplefabric.SimpleFabricWebApplication</param-value>
+ </init-param>
+ <load-on-startup>1</load-on-startup>
+ </servlet>
+
+ <servlet-mapping>
+ <servlet-name>JAX-RS Service</servlet-name>
+ <url-pattern>/*</url-pattern>
+ </servlet-mapping>
+
+</web-app>