blob: 9ddbee193e3fc22cfdfe041fd85b1f2050baaf33 [file] [log] [blame]
Thomas Vachuska7d693f52014-10-21 19:17:57 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 Open Networking Laboratory
Thomas Vachuska7d693f52014-10-21 19:17:57 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska7d693f52014-10-21 19:17:57 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska7d693f52014-10-21 19:17:57 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.cli.net;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070017
Jonathan Hart6e948282014-11-17 22:50:42 -080018import static com.google.common.base.Strings.isNullOrEmpty;
Brian O'Connorabafb502014-12-02 22:26:20 -080019import static org.onosproject.net.flow.DefaultTrafficTreatment.builder;
Jonathan Hart6e948282014-11-17 22:50:42 -080020
Ray Milkey460f4022014-11-05 15:41:43 -080021import java.util.LinkedList;
22import java.util.List;
23
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070024import org.apache.karaf.shell.commands.Option;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +080025import org.onlab.packet.Ip6Address;
26import org.onlab.packet.IpAddress;
Brian O'Connorabafb502014-12-02 22:26:20 -080027import org.onosproject.cli.AbstractShellCommand;
Ray Milkey95c50872015-04-14 14:32:31 -070028import org.onosproject.core.ApplicationId;
29import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.Link;
31import org.onosproject.net.flow.DefaultTrafficSelector;
Brian O'Connor11ff8702015-04-29 19:37:15 -070032import org.onosproject.net.flow.DefaultTrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080033import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.flow.TrafficTreatment;
35import org.onosproject.net.intent.Constraint;
Ray Milkeyc24cde32015-03-10 18:20:18 -070036import org.onosproject.net.intent.Intent;
Ray Milkey5b3717e2015-02-05 11:44:08 -080037import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.intent.constraint.BandwidthConstraint;
39import org.onosproject.net.intent.constraint.LambdaConstraint;
40import org.onosproject.net.intent.constraint.LinkTypeConstraint;
41import org.onosproject.net.resource.Bandwidth;
Jonathan Hart5f7097e2014-11-11 11:50:28 -080042import org.onlab.packet.IpPrefix;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070043import org.onlab.packet.MacAddress;
44
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070045/**
46 * Base class for command line operations for connectivity based intents.
47 */
48public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
49
Jonathan Hart2c25e362014-11-17 18:14:19 -080050 // Selectors
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070051 @Option(name = "-s", aliases = "--ethSrc", description = "Source MAC Address",
52 required = false, multiValued = false)
53 private String srcMacString = null;
54
55 @Option(name = "-d", aliases = "--ethDst", description = "Destination MAC Address",
56 required = false, multiValued = false)
57 private String dstMacString = null;
58
59 @Option(name = "-t", aliases = "--ethType", description = "Ethernet Type",
60 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -080061 private String ethTypeString = null;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070062
Jonathan Hart5f7097e2014-11-11 11:50:28 -080063 @Option(name = "--ipProto", description = "IP Protocol",
64 required = false, multiValued = false)
65 private String ipProtoString = null;
66
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070067 @Option(name = "--ipSrc", description = "Source IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080068 required = false, multiValued = false)
69 private String srcIpString = null;
70
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070071 @Option(name = "--ipDst", description = "Destination IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080072 required = false, multiValued = false)
73 private String dstIpString = null;
74
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +080075 @Option(name = "--fLabel", description = "IPv6 Flow Label",
76 required = false, multiValued = false)
77 private String fLabelString = null;
78
79 @Option(name = "--icmp6Type", description = "ICMPv6 Type",
80 required = false, multiValued = false)
81 private String icmp6TypeString = null;
82
83 @Option(name = "--icmp6Code", description = "ICMPv6 Code",
84 required = false, multiValued = false)
85 private String icmp6CodeString = null;
86
87 @Option(name = "--ndTarget", description = "IPv6 Neighbor Discovery Target Address",
88 required = false, multiValued = false)
89 private String ndTargetString = null;
90
91 @Option(name = "--ndSLL", description = "IPv6 Neighbor Discovery Source Link-Layer",
92 required = false, multiValued = false)
93 private String ndSLLString = null;
94
95 @Option(name = "--ndTLL", description = "IPv6 Neighbor Discovery Target Link-Layer",
96 required = false, multiValued = false)
97 private String ndTLLString = null;
98
Jonathan Hart5f7097e2014-11-11 11:50:28 -080099 @Option(name = "--tcpSrc", description = "Source TCP Port",
100 required = false, multiValued = false)
101 private String srcTcpString = null;
102
103 @Option(name = "--tcpDst", description = "Destination TCP Port",
104 required = false, multiValued = false)
105 private String dstTcpString = null;
106
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800107 @Option(name = "--extHdr", description = "IPv6 Extension Header Pseudo-field",
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800108 required = false, multiValued = true)
109 private List<String> extHdrStringList = null;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800110
Ray Milkey460f4022014-11-05 15:41:43 -0800111 @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
112 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -0800113 private String bandwidthString = null;
Ray Milkey460f4022014-11-05 15:41:43 -0800114
115 @Option(name = "-l", aliases = "--lambda", description = "Lambda",
116 required = false, multiValued = false)
117 private boolean lambda = false;
118
Ray Milkey95c50872015-04-14 14:32:31 -0700119 @Option(name = "-a", aliases = "--appId", description = "Application Id",
120 required = false, multiValued = false)
121 private String appId = null;
122
Ray Milkey5b3717e2015-02-05 11:44:08 -0800123 @Option(name = "-k", aliases = "--key", description = "Intent Key",
124 required = false, multiValued = false)
125 private String intentKey = null;
126
Jonathan Hart2c25e362014-11-17 18:14:19 -0800127
128 // Treatments
129 @Option(name = "--setEthSrc", description = "Rewrite Source MAC Address",
130 required = false, multiValued = false)
131 private String setEthSrcString = null;
132
133 @Option(name = "--setEthDst", description = "Rewrite Destination MAC Address",
134 required = false, multiValued = false)
135 private String setEthDstString = null;
136
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800137 @Option(name = "--setIpSrc", description = "Rewrite Source IP Address",
138 required = false, multiValued = false)
139 private String setIpSrcString = null;
140
141 @Option(name = "--setIpDst", description = "Rewrite Destination IP Address",
142 required = false, multiValued = false)
143 private String setIpDstString = null;
144
145
Ray Milkeyc24cde32015-03-10 18:20:18 -0700146 // Priorities
147 @Option(name = "-p", aliases = "--priority", description = "Priority",
148 required = false, multiValued = false)
149 private int priority = Intent.DEFAULT_INTENT_PRIORITY;
150
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700151 /**
152 * Constructs a traffic selector based on the command line arguments
153 * presented to the command.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800154 * @return traffic selector
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700155 */
156 protected TrafficSelector buildTrafficSelector() {
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700157 IpPrefix srcIpPrefix = null;
158 IpPrefix dstIpPrefix = null;
Ray Milkeycaa450b2014-10-29 15:54:24 -0700159
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700160 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
161
162 if (!isNullOrEmpty(srcIpString)) {
163 srcIpPrefix = IpPrefix.valueOf(srcIpString);
164 if (srcIpPrefix.isIp4()) {
165 selectorBuilder.matchIPSrc(srcIpPrefix);
166 } else {
167 selectorBuilder.matchIPv6Src(srcIpPrefix);
168 }
169 }
170
171 if (!isNullOrEmpty(dstIpString)) {
172 dstIpPrefix = IpPrefix.valueOf(dstIpString);
173 if (dstIpPrefix.isIp4()) {
174 selectorBuilder.matchIPDst(dstIpPrefix);
175 } else {
176 selectorBuilder.matchIPv6Dst(dstIpPrefix);
177 }
178 }
179
180 if ((srcIpPrefix != null) && (dstIpPrefix != null) &&
181 (srcIpPrefix.version() != dstIpPrefix.version())) {
182 // ERROR: IP src/dst version mismatch
183 throw new IllegalArgumentException(
184 "IP source and destination version mismatch");
185 }
186
187 //
188 // Set the default EthType based on the IP version if the matching
189 // source or destination IP prefixes.
190 //
191 short ethType = EthType.IPV4.value();
192 if ((srcIpPrefix != null) && srcIpPrefix.isIp6()) {
193 ethType = EthType.IPV6.value();
194 }
195 if ((dstIpPrefix != null) && dstIpPrefix.isIp6()) {
196 ethType = EthType.IPV6.value();
197 }
Ray Milkey460f4022014-11-05 15:41:43 -0800198 if (!isNullOrEmpty(ethTypeString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800199 ethType = EthType.parseFromString(ethTypeString);
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700200 }
201 selectorBuilder.matchEthType(ethType);
202
Ray Milkey460f4022014-11-05 15:41:43 -0800203 if (!isNullOrEmpty(srcMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700204 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
205 }
206
Ray Milkey460f4022014-11-05 15:41:43 -0800207 if (!isNullOrEmpty(dstMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700208 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
209 }
210
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800211 if (!isNullOrEmpty(ipProtoString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800212 short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
213 selectorBuilder.matchIPProtocol((byte) ipProtoShort);
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800214 }
215
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800216 if (!isNullOrEmpty(fLabelString)) {
217 selectorBuilder.matchIPv6FlowLabel(Integer.parseInt(fLabelString));
218 }
219
220 if (!isNullOrEmpty(icmp6TypeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800221 byte icmp6Type = Icmp6Type.parseFromString(icmp6TypeString);
222 selectorBuilder.matchIcmpv6Type(icmp6Type);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800223 }
224
225 if (!isNullOrEmpty(icmp6CodeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800226 byte icmp6Code = Icmp6Code.parseFromString(icmp6CodeString);
227 selectorBuilder.matchIcmpv6Code(icmp6Code);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800228 }
229
230 if (!isNullOrEmpty(ndTargetString)) {
231 selectorBuilder.matchIPv6NDTargetAddress(Ip6Address.valueOf(ndTargetString));
232 }
233
234 if (!isNullOrEmpty(ndSLLString)) {
235 selectorBuilder.matchIPv6NDSourceLinkLayerAddress(MacAddress.valueOf(ndSLLString));
236 }
237
238 if (!isNullOrEmpty(ndTLLString)) {
239 selectorBuilder.matchIPv6NDTargetLinkLayerAddress(MacAddress.valueOf(ndTLLString));
240 }
241
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800242 if (!isNullOrEmpty(srcTcpString)) {
243 selectorBuilder.matchTcpSrc((short) Integer.parseInt(srcTcpString));
244 }
245
246 if (!isNullOrEmpty(dstTcpString)) {
Jonathan Hart5dfa43f2014-11-17 15:35:54 -0800247 selectorBuilder.matchTcpDst((short) Integer.parseInt(dstTcpString));
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800248 }
249
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800250 if (extHdrStringList != null) {
251 short extHdr = 0;
252 for (String extHdrString : extHdrStringList) {
253 extHdr = (short) (extHdr | ExtHeader.parseFromString(extHdrString));
254 }
255 selectorBuilder.matchIPv6ExthdrFlags(extHdr);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800256 }
257
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700258 return selectorBuilder.build();
259 }
260
Ray Milkey460f4022014-11-05 15:41:43 -0800261 /**
Jonathan Hart2c25e362014-11-17 18:14:19 -0800262 * Generates a traffic treatment for this intent based on command line
263 * arguments presented to the command.
264 *
265 * @return traffic treatment
266 */
267 protected TrafficTreatment buildTrafficTreatment() {
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800268 final TrafficTreatment.Builder treatmentBuilder = builder();
Brian O'Connor11ff8702015-04-29 19:37:15 -0700269 boolean emptyTreatment = true;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800270
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800271 if (!isNullOrEmpty(setEthSrcString)) {
272 treatmentBuilder.setEthSrc(MacAddress.valueOf(setEthSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700273 emptyTreatment = false;
Brian O'Connor4f5a98a2015-03-14 19:50:09 -0700274 }
275
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800276 if (!isNullOrEmpty(setEthDstString)) {
277 treatmentBuilder.setEthDst(MacAddress.valueOf(setEthDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700278 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800279 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800280
281 if (!isNullOrEmpty(setIpSrcString)) {
282 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700283 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800284 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800285
286 if (!isNullOrEmpty(setIpDstString)) {
287 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700288 emptyTreatment = false;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800289 }
290
Brian O'Connor11ff8702015-04-29 19:37:15 -0700291 if (emptyTreatment) {
292 return DefaultTrafficTreatment.emptyTreatment();
293 } else {
294 return treatmentBuilder.build();
295 }
Jonathan Hart2c25e362014-11-17 18:14:19 -0800296 }
297
298 /**
Ray Milkey460f4022014-11-05 15:41:43 -0800299 * Builds the constraint list for this command based on the command line
300 * parameters.
301 *
302 * @return List of constraint objects describing the constraints requested
303 */
304 protected List<Constraint> buildConstraints() {
305 final List<Constraint> constraints = new LinkedList<>();
306
307 // Check for a bandwidth specification
308 if (!isNullOrEmpty(bandwidthString)) {
309 final double bandwidthValue = Double.parseDouble(bandwidthString);
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800310 constraints.add(new BandwidthConstraint(Bandwidth.bps(bandwidthValue)));
Ray Milkey460f4022014-11-05 15:41:43 -0800311 }
312
313 // Check for a lambda specification
314 if (lambda) {
315 constraints.add(new LambdaConstraint(null));
316 }
Thomas Vachuskadea45ff2014-11-12 18:35:46 -0800317 constraints.add(new LinkTypeConstraint(lambda, Link.Type.OPTICAL));
Ray Milkey460f4022014-11-05 15:41:43 -0800318
319 return constraints;
320 }
Ray Milkey5b3717e2015-02-05 11:44:08 -0800321
Ray Milkey95c50872015-04-14 14:32:31 -0700322 @Override
323 protected ApplicationId appId() {
324 ApplicationId appIdForIntent;
325 if (appId == null) {
326 appIdForIntent = super.appId();
327 } else {
328 CoreService service = get(CoreService.class);
329 appIdForIntent = service.getAppId(appId);
330 }
331 return appIdForIntent;
332 }
333
Ray Milkey5b3717e2015-02-05 11:44:08 -0800334 /**
335 * Creates a key for an intent based on command line arguments. If a key
336 * has been specified, it is returned. If no key is specified, null
337 * is returned.
338 *
339 * @return intent key if specified, null otherwise
340 */
341 protected Key key() {
342 Key key = null;
Ray Milkey95c50872015-04-14 14:32:31 -0700343 ApplicationId appIdForIntent;
344
Ray Milkey5b3717e2015-02-05 11:44:08 -0800345 if (intentKey != null) {
346 key = Key.of(intentKey, appId());
347 }
348 return key;
349 }
Ray Milkeyc24cde32015-03-10 18:20:18 -0700350
351 /**
352 * Gets the priority to use for the intent.
353 *
354 * @return priority
355 */
356 protected int priority() {
357 return priority;
358 }
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700359}