blob: d22f14711a11fdae4f145d1003bcfa020ea9466e [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;
Dusan Pajin6b887c92015-07-01 18:32:49 +020027import org.onlab.packet.VlanId;
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070028import org.onlab.util.Bandwidth;
Brian O'Connorabafb502014-12-02 22:26:20 -080029import org.onosproject.cli.AbstractShellCommand;
Ray Milkey95c50872015-04-14 14:32:31 -070030import org.onosproject.core.ApplicationId;
31import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080032import org.onosproject.net.Link;
33import org.onosproject.net.flow.DefaultTrafficSelector;
Brian O'Connor11ff8702015-04-29 19:37:15 -070034import org.onosproject.net.flow.DefaultTrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080035import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
37import org.onosproject.net.intent.Constraint;
Ray Milkeyc24cde32015-03-10 18:20:18 -070038import org.onosproject.net.intent.Intent;
Ray Milkey5b3717e2015-02-05 11:44:08 -080039import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080040import org.onosproject.net.intent.constraint.BandwidthConstraint;
41import org.onosproject.net.intent.constraint.LambdaConstraint;
42import org.onosproject.net.intent.constraint.LinkTypeConstraint;
Brian O'Connor6de2e202015-05-21 14:30:41 -070043import org.onosproject.net.resource.link.BandwidthResource;
Jonathan Hart5f7097e2014-11-11 11:50:28 -080044import org.onlab.packet.IpPrefix;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070045import org.onlab.packet.MacAddress;
46
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070047/**
48 * Base class for command line operations for connectivity based intents.
49 */
50public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
51
Jonathan Hart2c25e362014-11-17 18:14:19 -080052 // Selectors
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070053 @Option(name = "-s", aliases = "--ethSrc", description = "Source MAC Address",
54 required = false, multiValued = false)
55 private String srcMacString = null;
56
57 @Option(name = "-d", aliases = "--ethDst", description = "Destination MAC Address",
58 required = false, multiValued = false)
59 private String dstMacString = null;
60
61 @Option(name = "-t", aliases = "--ethType", description = "Ethernet Type",
62 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -080063 private String ethTypeString = null;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070064
Dusan Pajin6b887c92015-07-01 18:32:49 +020065 @Option(name = "-v", aliases = "--vlan", description = "VLAN ID",
66 required = false, multiValued = false)
67 private String vlanString = null;
68
Jonathan Hart5f7097e2014-11-11 11:50:28 -080069 @Option(name = "--ipProto", description = "IP Protocol",
70 required = false, multiValued = false)
71 private String ipProtoString = null;
72
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070073 @Option(name = "--ipSrc", description = "Source IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080074 required = false, multiValued = false)
75 private String srcIpString = null;
76
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070077 @Option(name = "--ipDst", description = "Destination IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080078 required = false, multiValued = false)
79 private String dstIpString = null;
80
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +080081 @Option(name = "--fLabel", description = "IPv6 Flow Label",
82 required = false, multiValued = false)
83 private String fLabelString = null;
84
85 @Option(name = "--icmp6Type", description = "ICMPv6 Type",
86 required = false, multiValued = false)
87 private String icmp6TypeString = null;
88
89 @Option(name = "--icmp6Code", description = "ICMPv6 Code",
90 required = false, multiValued = false)
91 private String icmp6CodeString = null;
92
93 @Option(name = "--ndTarget", description = "IPv6 Neighbor Discovery Target Address",
94 required = false, multiValued = false)
95 private String ndTargetString = null;
96
97 @Option(name = "--ndSLL", description = "IPv6 Neighbor Discovery Source Link-Layer",
98 required = false, multiValued = false)
99 private String ndSLLString = null;
100
101 @Option(name = "--ndTLL", description = "IPv6 Neighbor Discovery Target Link-Layer",
102 required = false, multiValued = false)
103 private String ndTLLString = null;
104
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800105 @Option(name = "--tcpSrc", description = "Source TCP Port",
106 required = false, multiValued = false)
107 private String srcTcpString = null;
108
109 @Option(name = "--tcpDst", description = "Destination TCP Port",
110 required = false, multiValued = false)
111 private String dstTcpString = null;
112
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800113 @Option(name = "--extHdr", description = "IPv6 Extension Header Pseudo-field",
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800114 required = false, multiValued = true)
115 private List<String> extHdrStringList = null;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800116
Ray Milkey460f4022014-11-05 15:41:43 -0800117 @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
118 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -0800119 private String bandwidthString = null;
Ray Milkey460f4022014-11-05 15:41:43 -0800120
121 @Option(name = "-l", aliases = "--lambda", description = "Lambda",
122 required = false, multiValued = false)
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700123 private boolean lambda = false;
Ray Milkey460f4022014-11-05 15:41:43 -0800124
Ray Milkey95c50872015-04-14 14:32:31 -0700125 @Option(name = "-a", aliases = "--appId", description = "Application Id",
126 required = false, multiValued = false)
127 private String appId = null;
128
Ray Milkey5b3717e2015-02-05 11:44:08 -0800129 @Option(name = "-k", aliases = "--key", description = "Intent Key",
130 required = false, multiValued = false)
131 private String intentKey = null;
132
Jonathan Hart2c25e362014-11-17 18:14:19 -0800133
134 // Treatments
135 @Option(name = "--setEthSrc", description = "Rewrite Source MAC Address",
136 required = false, multiValued = false)
137 private String setEthSrcString = null;
138
139 @Option(name = "--setEthDst", description = "Rewrite Destination MAC Address",
140 required = false, multiValued = false)
141 private String setEthDstString = null;
142
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800143 @Option(name = "--setIpSrc", description = "Rewrite Source IP Address",
144 required = false, multiValued = false)
145 private String setIpSrcString = null;
146
147 @Option(name = "--setIpDst", description = "Rewrite Destination IP Address",
148 required = false, multiValued = false)
149 private String setIpDstString = null;
150
Dusan Pajin6b887c92015-07-01 18:32:49 +0200151 @Option(name = "--setVlan", description = "Rewrite VLAN ID",
152 required = false, multiValued = false)
153 private String setVlan = null;
154
155 @Option(name = "--popVlan", description = "Pop VLAN Tag",
156 required = false, multiValued = false)
157 private boolean popVlan = false;
158
159 @Option(name = "--pushVlan", description = "Push VLAN ID",
160 required = false, multiValued = false)
161 private String pushVlan = null;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800162
Ray Milkeyc24cde32015-03-10 18:20:18 -0700163 // Priorities
164 @Option(name = "-p", aliases = "--priority", description = "Priority",
165 required = false, multiValued = false)
166 private int priority = Intent.DEFAULT_INTENT_PRIORITY;
167
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700168 /**
169 * Constructs a traffic selector based on the command line arguments
170 * presented to the command.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800171 * @return traffic selector
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700172 */
173 protected TrafficSelector buildTrafficSelector() {
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700174 IpPrefix srcIpPrefix = null;
175 IpPrefix dstIpPrefix = null;
Ray Milkeycaa450b2014-10-29 15:54:24 -0700176
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700177 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
178
179 if (!isNullOrEmpty(srcIpString)) {
180 srcIpPrefix = IpPrefix.valueOf(srcIpString);
181 if (srcIpPrefix.isIp4()) {
182 selectorBuilder.matchIPSrc(srcIpPrefix);
183 } else {
184 selectorBuilder.matchIPv6Src(srcIpPrefix);
185 }
186 }
187
188 if (!isNullOrEmpty(dstIpString)) {
189 dstIpPrefix = IpPrefix.valueOf(dstIpString);
190 if (dstIpPrefix.isIp4()) {
191 selectorBuilder.matchIPDst(dstIpPrefix);
192 } else {
193 selectorBuilder.matchIPv6Dst(dstIpPrefix);
194 }
195 }
196
197 if ((srcIpPrefix != null) && (dstIpPrefix != null) &&
198 (srcIpPrefix.version() != dstIpPrefix.version())) {
199 // ERROR: IP src/dst version mismatch
200 throw new IllegalArgumentException(
201 "IP source and destination version mismatch");
202 }
203
204 //
205 // Set the default EthType based on the IP version if the matching
206 // source or destination IP prefixes.
207 //
Ayaka Koshibe8117f362015-06-02 13:44:01 -0700208 Short ethType = null;
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700209 if ((srcIpPrefix != null) && srcIpPrefix.isIp6()) {
210 ethType = EthType.IPV6.value();
211 }
212 if ((dstIpPrefix != null) && dstIpPrefix.isIp6()) {
213 ethType = EthType.IPV6.value();
214 }
Ray Milkey460f4022014-11-05 15:41:43 -0800215 if (!isNullOrEmpty(ethTypeString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800216 ethType = EthType.parseFromString(ethTypeString);
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700217 }
Ayaka Koshibe8117f362015-06-02 13:44:01 -0700218 if (ethType != null) {
219 selectorBuilder.matchEthType(ethType);
220 }
Dusan Pajin6b887c92015-07-01 18:32:49 +0200221 if (!isNullOrEmpty(vlanString)) {
222 selectorBuilder.matchVlanId(VlanId.vlanId(Short.parseShort(vlanString)));
223 }
Ray Milkey460f4022014-11-05 15:41:43 -0800224 if (!isNullOrEmpty(srcMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700225 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
226 }
227
Ray Milkey460f4022014-11-05 15:41:43 -0800228 if (!isNullOrEmpty(dstMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700229 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
230 }
231
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800232 if (!isNullOrEmpty(ipProtoString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800233 short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
234 selectorBuilder.matchIPProtocol((byte) ipProtoShort);
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800235 }
236
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800237 if (!isNullOrEmpty(fLabelString)) {
238 selectorBuilder.matchIPv6FlowLabel(Integer.parseInt(fLabelString));
239 }
240
241 if (!isNullOrEmpty(icmp6TypeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800242 byte icmp6Type = Icmp6Type.parseFromString(icmp6TypeString);
243 selectorBuilder.matchIcmpv6Type(icmp6Type);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800244 }
245
246 if (!isNullOrEmpty(icmp6CodeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800247 byte icmp6Code = Icmp6Code.parseFromString(icmp6CodeString);
248 selectorBuilder.matchIcmpv6Code(icmp6Code);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800249 }
250
251 if (!isNullOrEmpty(ndTargetString)) {
252 selectorBuilder.matchIPv6NDTargetAddress(Ip6Address.valueOf(ndTargetString));
253 }
254
255 if (!isNullOrEmpty(ndSLLString)) {
256 selectorBuilder.matchIPv6NDSourceLinkLayerAddress(MacAddress.valueOf(ndSLLString));
257 }
258
259 if (!isNullOrEmpty(ndTLLString)) {
260 selectorBuilder.matchIPv6NDTargetLinkLayerAddress(MacAddress.valueOf(ndTLLString));
261 }
262
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800263 if (!isNullOrEmpty(srcTcpString)) {
264 selectorBuilder.matchTcpSrc((short) Integer.parseInt(srcTcpString));
265 }
266
267 if (!isNullOrEmpty(dstTcpString)) {
Jonathan Hart5dfa43f2014-11-17 15:35:54 -0800268 selectorBuilder.matchTcpDst((short) Integer.parseInt(dstTcpString));
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800269 }
270
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800271 if (extHdrStringList != null) {
272 short extHdr = 0;
273 for (String extHdrString : extHdrStringList) {
274 extHdr = (short) (extHdr | ExtHeader.parseFromString(extHdrString));
275 }
276 selectorBuilder.matchIPv6ExthdrFlags(extHdr);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800277 }
278
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700279 return selectorBuilder.build();
280 }
281
Ray Milkey460f4022014-11-05 15:41:43 -0800282 /**
Jonathan Hart2c25e362014-11-17 18:14:19 -0800283 * Generates a traffic treatment for this intent based on command line
284 * arguments presented to the command.
285 *
286 * @return traffic treatment
287 */
288 protected TrafficTreatment buildTrafficTreatment() {
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800289 final TrafficTreatment.Builder treatmentBuilder = builder();
Brian O'Connor11ff8702015-04-29 19:37:15 -0700290 boolean emptyTreatment = true;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800291
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800292 if (!isNullOrEmpty(setEthSrcString)) {
293 treatmentBuilder.setEthSrc(MacAddress.valueOf(setEthSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700294 emptyTreatment = false;
Brian O'Connor4f5a98a2015-03-14 19:50:09 -0700295 }
296
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800297 if (!isNullOrEmpty(setEthDstString)) {
298 treatmentBuilder.setEthDst(MacAddress.valueOf(setEthDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700299 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800300 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800301
302 if (!isNullOrEmpty(setIpSrcString)) {
303 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700304 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800305 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800306
307 if (!isNullOrEmpty(setIpDstString)) {
308 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700309 emptyTreatment = false;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800310 }
Dusan Pajin6b887c92015-07-01 18:32:49 +0200311 if (!isNullOrEmpty(setVlan)) {
312 treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(setVlan)));
313 emptyTreatment = false;
314 }
315 if (popVlan) {
316 treatmentBuilder.popVlan();
317 emptyTreatment = false;
318 }
319 if (!isNullOrEmpty(pushVlan)) {
320 treatmentBuilder.pushVlan();
321 treatmentBuilder.setVlanId(VlanId.vlanId(Short.parseShort(pushVlan)));
322 emptyTreatment = false;
323 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800324
Brian O'Connor11ff8702015-04-29 19:37:15 -0700325 if (emptyTreatment) {
326 return DefaultTrafficTreatment.emptyTreatment();
327 } else {
328 return treatmentBuilder.build();
329 }
Jonathan Hart2c25e362014-11-17 18:14:19 -0800330 }
331
332 /**
Ray Milkey460f4022014-11-05 15:41:43 -0800333 * Builds the constraint list for this command based on the command line
334 * parameters.
335 *
336 * @return List of constraint objects describing the constraints requested
337 */
338 protected List<Constraint> buildConstraints() {
339 final List<Constraint> constraints = new LinkedList<>();
340
341 // Check for a bandwidth specification
342 if (!isNullOrEmpty(bandwidthString)) {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700343 final Bandwidth bandwidth = Bandwidth.bps(Double.parseDouble(bandwidthString));
344 constraints.add(new BandwidthConstraint(new BandwidthResource(bandwidth)));
Ray Milkey460f4022014-11-05 15:41:43 -0800345 }
346
347 // Check for a lambda specification
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700348 if (lambda) {
349 constraints.add(new LambdaConstraint(null));
Ray Milkey460f4022014-11-05 15:41:43 -0800350 }
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700351 constraints.add(new LinkTypeConstraint(lambda, Link.Type.OPTICAL));
352
Ray Milkey460f4022014-11-05 15:41:43 -0800353 return constraints;
354 }
Ray Milkey5b3717e2015-02-05 11:44:08 -0800355
Ray Milkey95c50872015-04-14 14:32:31 -0700356 @Override
357 protected ApplicationId appId() {
358 ApplicationId appIdForIntent;
359 if (appId == null) {
360 appIdForIntent = super.appId();
361 } else {
362 CoreService service = get(CoreService.class);
363 appIdForIntent = service.getAppId(appId);
364 }
365 return appIdForIntent;
366 }
367
Ray Milkey5b3717e2015-02-05 11:44:08 -0800368 /**
369 * Creates a key for an intent based on command line arguments. If a key
370 * has been specified, it is returned. If no key is specified, null
371 * is returned.
372 *
373 * @return intent key if specified, null otherwise
374 */
375 protected Key key() {
376 Key key = null;
Ray Milkey95c50872015-04-14 14:32:31 -0700377 ApplicationId appIdForIntent;
378
Ray Milkey5b3717e2015-02-05 11:44:08 -0800379 if (intentKey != null) {
380 key = Key.of(intentKey, appId());
381 }
382 return key;
383 }
Ray Milkeyc24cde32015-03-10 18:20:18 -0700384
385 /**
386 * Gets the priority to use for the intent.
387 *
388 * @return priority
389 */
390 protected int priority() {
391 return priority;
392 }
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700393}