blob: 6c33f45c2f129edfa43e2ac94902fe27f14df3a6 [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;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -070027import org.onlab.packet.IpPrefix;
28import org.onlab.packet.MacAddress;
29import org.onlab.packet.TpPort;
Dusan Pajin6b887c92015-07-01 18:32:49 +020030import org.onlab.packet.VlanId;
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070031import org.onlab.util.Bandwidth;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.cli.AbstractShellCommand;
Ray Milkey95c50872015-04-14 14:32:31 -070033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.Link;
36import org.onosproject.net.flow.DefaultTrafficSelector;
Brian O'Connor11ff8702015-04-29 19:37:15 -070037import org.onosproject.net.flow.DefaultTrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080038import org.onosproject.net.flow.TrafficSelector;
39import org.onosproject.net.flow.TrafficTreatment;
40import org.onosproject.net.intent.Constraint;
Ray Milkeyc24cde32015-03-10 18:20:18 -070041import org.onosproject.net.intent.Intent;
Ray Milkey5b3717e2015-02-05 11:44:08 -080042import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080043import org.onosproject.net.intent.constraint.BandwidthConstraint;
44import org.onosproject.net.intent.constraint.LambdaConstraint;
45import org.onosproject.net.intent.constraint.LinkTypeConstraint;
Jonathan Hart96c5a4a2015-07-31 14:23:33 -070046import org.onosproject.net.intent.constraint.PartialFailureConstraint;
Brian O'Connor6de2e202015-05-21 14:30:41 -070047import org.onosproject.net.resource.link.BandwidthResource;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070048
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070049/**
50 * Base class for command line operations for connectivity based intents.
51 */
52public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
53
Jonathan Hart2c25e362014-11-17 18:14:19 -080054 // Selectors
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070055 @Option(name = "-s", aliases = "--ethSrc", description = "Source MAC Address",
56 required = false, multiValued = false)
57 private String srcMacString = null;
58
59 @Option(name = "-d", aliases = "--ethDst", description = "Destination MAC Address",
60 required = false, multiValued = false)
61 private String dstMacString = null;
62
63 @Option(name = "-t", aliases = "--ethType", description = "Ethernet Type",
64 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -080065 private String ethTypeString = null;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070066
Dusan Pajin6b887c92015-07-01 18:32:49 +020067 @Option(name = "-v", aliases = "--vlan", description = "VLAN ID",
68 required = false, multiValued = false)
69 private String vlanString = null;
70
Jonathan Hart5f7097e2014-11-11 11:50:28 -080071 @Option(name = "--ipProto", description = "IP Protocol",
72 required = false, multiValued = false)
73 private String ipProtoString = null;
74
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070075 @Option(name = "--ipSrc", description = "Source IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080076 required = false, multiValued = false)
77 private String srcIpString = null;
78
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070079 @Option(name = "--ipDst", description = "Destination IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080080 required = false, multiValued = false)
81 private String dstIpString = null;
82
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +080083 @Option(name = "--fLabel", description = "IPv6 Flow Label",
84 required = false, multiValued = false)
85 private String fLabelString = null;
86
87 @Option(name = "--icmp6Type", description = "ICMPv6 Type",
88 required = false, multiValued = false)
89 private String icmp6TypeString = null;
90
91 @Option(name = "--icmp6Code", description = "ICMPv6 Code",
92 required = false, multiValued = false)
93 private String icmp6CodeString = null;
94
95 @Option(name = "--ndTarget", description = "IPv6 Neighbor Discovery Target Address",
96 required = false, multiValued = false)
97 private String ndTargetString = null;
98
99 @Option(name = "--ndSLL", description = "IPv6 Neighbor Discovery Source Link-Layer",
100 required = false, multiValued = false)
101 private String ndSLLString = null;
102
103 @Option(name = "--ndTLL", description = "IPv6 Neighbor Discovery Target Link-Layer",
104 required = false, multiValued = false)
105 private String ndTLLString = null;
106
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800107 @Option(name = "--tcpSrc", description = "Source TCP Port",
108 required = false, multiValued = false)
109 private String srcTcpString = null;
110
111 @Option(name = "--tcpDst", description = "Destination TCP Port",
112 required = false, multiValued = false)
113 private String dstTcpString = null;
114
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800115 @Option(name = "--extHdr", description = "IPv6 Extension Header Pseudo-field",
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800116 required = false, multiValued = true)
117 private List<String> extHdrStringList = null;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800118
Ray Milkey460f4022014-11-05 15:41:43 -0800119 @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
120 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -0800121 private String bandwidthString = null;
Ray Milkey460f4022014-11-05 15:41:43 -0800122
123 @Option(name = "-l", aliases = "--lambda", description = "Lambda",
124 required = false, multiValued = false)
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700125 private boolean lambda = false;
Ray Milkey460f4022014-11-05 15:41:43 -0800126
Ray Milkey95c50872015-04-14 14:32:31 -0700127 @Option(name = "-a", aliases = "--appId", description = "Application Id",
128 required = false, multiValued = false)
129 private String appId = null;
130
Ray Milkey5b3717e2015-02-05 11:44:08 -0800131 @Option(name = "-k", aliases = "--key", description = "Intent Key",
132 required = false, multiValued = false)
133 private String intentKey = null;
134
Jonathan Hart96c5a4a2015-07-31 14:23:33 -0700135 @Option(name = "--partial", description = "Allow partial installation",
136 required = false, multiValued = false)
137 private boolean partial = false;
138
Jonathan Hart2c25e362014-11-17 18:14:19 -0800139
140 // Treatments
141 @Option(name = "--setEthSrc", description = "Rewrite Source MAC Address",
142 required = false, multiValued = false)
143 private String setEthSrcString = null;
144
145 @Option(name = "--setEthDst", description = "Rewrite Destination MAC Address",
146 required = false, multiValued = false)
147 private String setEthDstString = null;
148
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800149 @Option(name = "--setIpSrc", description = "Rewrite Source IP Address",
150 required = false, multiValued = false)
151 private String setIpSrcString = null;
152
153 @Option(name = "--setIpDst", description = "Rewrite Destination IP Address",
154 required = false, multiValued = false)
155 private String setIpDstString = null;
156
Dusan Pajin6b887c92015-07-01 18:32:49 +0200157 @Option(name = "--setVlan", description = "Rewrite VLAN ID",
158 required = false, multiValued = false)
159 private String setVlan = null;
160
161 @Option(name = "--popVlan", description = "Pop VLAN Tag",
162 required = false, multiValued = false)
163 private boolean popVlan = false;
164
165 @Option(name = "--pushVlan", description = "Push VLAN ID",
166 required = false, multiValued = false)
167 private String pushVlan = null;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800168
Ray Milkeyc24cde32015-03-10 18:20:18 -0700169 // Priorities
170 @Option(name = "-p", aliases = "--priority", description = "Priority",
171 required = false, multiValued = false)
172 private int priority = Intent.DEFAULT_INTENT_PRIORITY;
173
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700174 /**
175 * Constructs a traffic selector based on the command line arguments
176 * presented to the command.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800177 * @return traffic selector
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700178 */
179 protected TrafficSelector buildTrafficSelector() {
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700180 IpPrefix srcIpPrefix = null;
181 IpPrefix dstIpPrefix = null;
Ray Milkeycaa450b2014-10-29 15:54:24 -0700182
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700183 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
184
185 if (!isNullOrEmpty(srcIpString)) {
186 srcIpPrefix = IpPrefix.valueOf(srcIpString);
187 if (srcIpPrefix.isIp4()) {
188 selectorBuilder.matchIPSrc(srcIpPrefix);
189 } else {
190 selectorBuilder.matchIPv6Src(srcIpPrefix);
191 }
192 }
193
194 if (!isNullOrEmpty(dstIpString)) {
195 dstIpPrefix = IpPrefix.valueOf(dstIpString);
196 if (dstIpPrefix.isIp4()) {
197 selectorBuilder.matchIPDst(dstIpPrefix);
198 } else {
199 selectorBuilder.matchIPv6Dst(dstIpPrefix);
200 }
201 }
202
203 if ((srcIpPrefix != null) && (dstIpPrefix != null) &&
204 (srcIpPrefix.version() != dstIpPrefix.version())) {
205 // ERROR: IP src/dst version mismatch
206 throw new IllegalArgumentException(
207 "IP source and destination version mismatch");
208 }
209
210 //
211 // Set the default EthType based on the IP version if the matching
212 // source or destination IP prefixes.
213 //
Ayaka Koshibe8117f362015-06-02 13:44:01 -0700214 Short ethType = null;
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700215 if ((srcIpPrefix != null) && srcIpPrefix.isIp6()) {
216 ethType = EthType.IPV6.value();
217 }
218 if ((dstIpPrefix != null) && dstIpPrefix.isIp6()) {
219 ethType = EthType.IPV6.value();
220 }
Ray Milkey460f4022014-11-05 15:41:43 -0800221 if (!isNullOrEmpty(ethTypeString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800222 ethType = EthType.parseFromString(ethTypeString);
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700223 }
Ayaka Koshibe8117f362015-06-02 13:44:01 -0700224 if (ethType != null) {
225 selectorBuilder.matchEthType(ethType);
226 }
Dusan Pajin6b887c92015-07-01 18:32:49 +0200227 if (!isNullOrEmpty(vlanString)) {
228 selectorBuilder.matchVlanId(VlanId.vlanId(Short.parseShort(vlanString)));
229 }
Ray Milkey460f4022014-11-05 15:41:43 -0800230 if (!isNullOrEmpty(srcMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700231 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
232 }
233
Ray Milkey460f4022014-11-05 15:41:43 -0800234 if (!isNullOrEmpty(dstMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700235 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
236 }
237
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800238 if (!isNullOrEmpty(ipProtoString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800239 short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
240 selectorBuilder.matchIPProtocol((byte) ipProtoShort);
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800241 }
242
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800243 if (!isNullOrEmpty(fLabelString)) {
244 selectorBuilder.matchIPv6FlowLabel(Integer.parseInt(fLabelString));
245 }
246
247 if (!isNullOrEmpty(icmp6TypeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800248 byte icmp6Type = Icmp6Type.parseFromString(icmp6TypeString);
249 selectorBuilder.matchIcmpv6Type(icmp6Type);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800250 }
251
252 if (!isNullOrEmpty(icmp6CodeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800253 byte icmp6Code = Icmp6Code.parseFromString(icmp6CodeString);
254 selectorBuilder.matchIcmpv6Code(icmp6Code);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800255 }
256
257 if (!isNullOrEmpty(ndTargetString)) {
258 selectorBuilder.matchIPv6NDTargetAddress(Ip6Address.valueOf(ndTargetString));
259 }
260
261 if (!isNullOrEmpty(ndSLLString)) {
262 selectorBuilder.matchIPv6NDSourceLinkLayerAddress(MacAddress.valueOf(ndSLLString));
263 }
264
265 if (!isNullOrEmpty(ndTLLString)) {
266 selectorBuilder.matchIPv6NDTargetLinkLayerAddress(MacAddress.valueOf(ndTLLString));
267 }
268
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800269 if (!isNullOrEmpty(srcTcpString)) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700270 selectorBuilder.matchTcpSrc(TpPort.tpPort(Integer.parseInt(srcTcpString)));
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800271 }
272
273 if (!isNullOrEmpty(dstTcpString)) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700274 selectorBuilder.matchTcpDst(TpPort.tpPort(Integer.parseInt(dstTcpString)));
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800275 }
276
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800277 if (extHdrStringList != null) {
278 short extHdr = 0;
279 for (String extHdrString : extHdrStringList) {
280 extHdr = (short) (extHdr | ExtHeader.parseFromString(extHdrString));
281 }
282 selectorBuilder.matchIPv6ExthdrFlags(extHdr);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800283 }
284
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700285 return selectorBuilder.build();
286 }
287
Ray Milkey460f4022014-11-05 15:41:43 -0800288 /**
Jonathan Hart2c25e362014-11-17 18:14:19 -0800289 * Generates a traffic treatment for this intent based on command line
290 * arguments presented to the command.
291 *
292 * @return traffic treatment
293 */
294 protected TrafficTreatment buildTrafficTreatment() {
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800295 final TrafficTreatment.Builder treatmentBuilder = builder();
Brian O'Connor11ff8702015-04-29 19:37:15 -0700296 boolean emptyTreatment = true;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800297
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800298 if (!isNullOrEmpty(setEthSrcString)) {
299 treatmentBuilder.setEthSrc(MacAddress.valueOf(setEthSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700300 emptyTreatment = false;
Brian O'Connor4f5a98a2015-03-14 19:50:09 -0700301 }
302
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800303 if (!isNullOrEmpty(setEthDstString)) {
304 treatmentBuilder.setEthDst(MacAddress.valueOf(setEthDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700305 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800306 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800307
308 if (!isNullOrEmpty(setIpSrcString)) {
309 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700310 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800311 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800312
313 if (!isNullOrEmpty(setIpDstString)) {
314 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700315 emptyTreatment = false;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800316 }
Dusan Pajin6b887c92015-07-01 18:32:49 +0200317 if (!isNullOrEmpty(setVlan)) {
318 treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(setVlan)));
319 emptyTreatment = false;
320 }
321 if (popVlan) {
322 treatmentBuilder.popVlan();
323 emptyTreatment = false;
324 }
325 if (!isNullOrEmpty(pushVlan)) {
326 treatmentBuilder.pushVlan();
327 treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(pushVlan)));
328 emptyTreatment = false;
329 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800330
Brian O'Connor11ff8702015-04-29 19:37:15 -0700331 if (emptyTreatment) {
332 return DefaultTrafficTreatment.emptyTreatment();
333 } else {
334 return treatmentBuilder.build();
335 }
Jonathan Hart2c25e362014-11-17 18:14:19 -0800336 }
337
338 /**
Ray Milkey460f4022014-11-05 15:41:43 -0800339 * Builds the constraint list for this command based on the command line
340 * parameters.
341 *
342 * @return List of constraint objects describing the constraints requested
343 */
344 protected List<Constraint> buildConstraints() {
345 final List<Constraint> constraints = new LinkedList<>();
346
347 // Check for a bandwidth specification
348 if (!isNullOrEmpty(bandwidthString)) {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700349 final Bandwidth bandwidth = Bandwidth.bps(Double.parseDouble(bandwidthString));
350 constraints.add(new BandwidthConstraint(new BandwidthResource(bandwidth)));
Ray Milkey460f4022014-11-05 15:41:43 -0800351 }
352
353 // Check for a lambda specification
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700354 if (lambda) {
355 constraints.add(new LambdaConstraint(null));
Ray Milkey460f4022014-11-05 15:41:43 -0800356 }
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700357 constraints.add(new LinkTypeConstraint(lambda, Link.Type.OPTICAL));
358
Jonathan Hart96c5a4a2015-07-31 14:23:33 -0700359 if (partial) {
360 constraints.add(new PartialFailureConstraint());
361 }
362
Ray Milkey460f4022014-11-05 15:41:43 -0800363 return constraints;
364 }
Ray Milkey5b3717e2015-02-05 11:44:08 -0800365
Ray Milkey95c50872015-04-14 14:32:31 -0700366 @Override
367 protected ApplicationId appId() {
368 ApplicationId appIdForIntent;
369 if (appId == null) {
370 appIdForIntent = super.appId();
371 } else {
372 CoreService service = get(CoreService.class);
373 appIdForIntent = service.getAppId(appId);
374 }
375 return appIdForIntent;
376 }
377
Ray Milkey5b3717e2015-02-05 11:44:08 -0800378 /**
379 * Creates a key for an intent based on command line arguments. If a key
380 * has been specified, it is returned. If no key is specified, null
381 * is returned.
382 *
383 * @return intent key if specified, null otherwise
384 */
385 protected Key key() {
386 Key key = null;
Ray Milkey95c50872015-04-14 14:32:31 -0700387 ApplicationId appIdForIntent;
388
Ray Milkey5b3717e2015-02-05 11:44:08 -0800389 if (intentKey != null) {
390 key = Key.of(intentKey, appId());
391 }
392 return key;
393 }
Ray Milkeyc24cde32015-03-10 18:20:18 -0700394
395 /**
396 * Gets the priority to use for the intent.
397 *
398 * @return priority
399 */
400 protected int priority() {
401 return priority;
402 }
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700403}