Jonathan Hart

Added CLI completion for IP protocol types.

Also modified IpProto and EthType field parsing to allow the user to supply
either a string value (e.g. "ICMP", "ARP") or the protocol number.

Change-Id: I8f19bebe53c2a7dbdc7570fdc08f979b2c0851cb
......@@ -15,6 +15,9 @@
*/
package org.onlab.onos.cli.net;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
import java.util.LinkedList;
import java.util.List;
......@@ -29,13 +32,9 @@ import org.onlab.onos.net.intent.constraint.BandwidthConstraint;
import org.onlab.onos.net.intent.constraint.LambdaConstraint;
import org.onlab.onos.net.intent.constraint.LinkTypeConstraint;
import org.onlab.onos.net.resource.Bandwidth;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.onos.net.flow.DefaultTrafficTreatment.builder;
/**
* Base class for command line operations for connectivity based intents.
*/
......@@ -99,11 +98,10 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
*/
protected TrafficSelector buildTrafficSelector() {
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
Short ethType = Ethernet.TYPE_IPV4;
short ethType = EthType.IPV4.value();
if (!isNullOrEmpty(ethTypeString)) {
EthType ethTypeParameter = EthType.valueOf(ethTypeString);
ethType = ethTypeParameter.value();
ethType = EthType.parseFromString(ethTypeString);
}
selectorBuilder.matchEthType(ethType);
......@@ -116,7 +114,8 @@ public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
}
if (!isNullOrEmpty(ipProtoString)) {
selectorBuilder.matchIPProtocol((byte) Short.parseShort(ipProtoString));
short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
selectorBuilder.matchIPProtocol((byte) ipProtoShort);
}
if (!isNullOrEmpty(srcIpString)) {
......
......@@ -38,7 +38,7 @@ public enum EthType {
/**
* Constructs an EthType with the given value.
*
* @param value value to use when this EthType is seen.
* @param value value to use when this EthType is seen
*/
private EthType(short value) {
this.value = value;
......@@ -52,4 +52,31 @@ public enum EthType {
public short value() {
return this.value;
}
/**
* Parse a string input that could contain an EthType value. The value
* may appear in the string either as a known protocol name (one of the
* values of this enum), or a numeric protocol value.
*
* @param input the input string to parse
* @return the numeric value of the parsed Ethernet type
* @throws IllegalArgumentException if the input string does not contain a
* value that can be parsed into an Ethernet type
*/
public static short parseFromString(String input) {
try {
return valueOf(input).value();
} catch (IllegalArgumentException e) {
// The input is not a known Ethernet type name, let's see if it's an
// Ethernet type value (short). We parse with Integer to handle
// unsigned values correctly.
try {
return (short) Integer.parseInt(input);
} catch (NumberFormatException e1) {
throw new IllegalArgumentException(
"EthType value must be either a string protocol name"
+ " or a 16-bit protocol value");
}
}
}
}
......
......@@ -30,11 +30,10 @@ public class EthTypeCompleter implements Completer {
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
SortedSet<String> strings = delegate.getStrings();
strings.add(EthType.ARP.toString());
strings.add(EthType.BSN.toString());
strings.add(EthType.IPV4.toString());
strings.add(EthType.LLDP.toString());
strings.add(EthType.RARP.toString());
for (EthType eth : EthType.values()) {
strings.add(eth.toString());
}
// Now let the completer do the work for figuring out what to offer.
return delegate.complete(buffer, cursor, candidates);
......
/*
* 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.
*/
package org.onlab.onos.cli.net;
import org.onlab.packet.IPv4;
/**
* Known protocol values for IP protocol field that can be supplied to the CLI.
*/
public enum IpProtocol {
/** ICMP. **/
ICMP(IPv4.PROTOCOL_ICMP),
/** TCP. **/
TCP(IPv4.PROTOCOL_TCP),
/** UDP. **/
UDP(IPv4.PROTOCOL_UDP);
private short value;
/**
* Constructs an IpProtocol with the given value.
*
* @param value value to use when this IpProtocol is seen
*/
private IpProtocol(short value) {
this.value = value;
}
/**
* Gets the value to use for this IpProtocol.
*
* @return short value to use for this IpProtocol
*/
public short value() {
return this.value;
}
/**
* Parse a string input that could contain an IpProtocol value. The value
* may appear in the string either as a known protocol name (one of the
* values of this enum), or a numeric protocol value.
*
* @param input the input string to parse
* @return the numeric value of the parsed IP protocol
* @throws IllegalArgumentException if the input string does not contain a
* value that can be parsed into an IP protocol
*/
public static short parseFromString(String input) {
try {
return valueOf(input).value();
} catch (IllegalArgumentException e) {
// The input is not a known IP protocol name, let's see if it's an IP
// protocol value (byte). We parse with Short to handle unsigned values
// correctly.
try {
return Short.parseShort(input);
} catch (NumberFormatException e1) {
throw new IllegalArgumentException(
"IpProtocol value must be either a string protocol name"
+ " or an 8-bit protocol value");
}
}
}
}
/*
* 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.
*/
package org.onlab.onos.cli.net;
import java.util.List;
import java.util.SortedSet;
import org.apache.karaf.shell.console.Completer;
import org.apache.karaf.shell.console.completer.StringsCompleter;
/**
* IP protocol completer.
*/
public class IpProtocolCompleter implements Completer {
@Override
public int complete(String buffer, int cursor, List<String> candidates) {
// Delegate string completer
StringsCompleter delegate = new StringsCompleter();
SortedSet<String> strings = delegate.getStrings();
for (IpProtocol ip : IpProtocol.values()) {
strings.add(ip.toString());
}
// Now let the completer do the work for figuring out what to offer.
return delegate.complete(buffer, cursor, candidates);
}
}
......@@ -133,6 +133,7 @@
</completers>
<optional-completers>
<entry key="-t" value-ref="ethTypeCompleter"/>
<entry key="--ipProto" value-ref="ipProtocolCompleter"/>
</optional-completers>
</command>
<command>
......@@ -156,6 +157,7 @@
</completers>
<optional-completers>
<entry key="-t" value-ref="ethTypeCompleter"/>
<entry key="--ipProto" value-ref="ipProtocolCompleter"/>
</optional-completers>
</command>
<command>
......@@ -236,5 +238,6 @@
<bean id="connectPointCompleter" class="org.onlab.onos.cli.net.ConnectPointCompleter"/>
<bean id="nullCompleter" class="org.apache.karaf.shell.console.completer.NullCompleter"/>
<bean id="ethTypeCompleter" class="org.onlab.onos.cli.net.EthTypeCompleter"/>
<bean id="ipProtocolCompleter" class="org.onlab.onos.cli.net.IpProtocolCompleter"/>
</blueprint>
......