blob: 10889fee2c617e88efaaf8d8639f871961f03800 [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;
32import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.flow.TrafficTreatment;
34import org.onosproject.net.intent.Constraint;
Ray Milkeyc24cde32015-03-10 18:20:18 -070035import org.onosproject.net.intent.Intent;
Ray Milkey5b3717e2015-02-05 11:44:08 -080036import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080037import org.onosproject.net.intent.constraint.BandwidthConstraint;
38import org.onosproject.net.intent.constraint.LambdaConstraint;
39import org.onosproject.net.intent.constraint.LinkTypeConstraint;
40import org.onosproject.net.resource.Bandwidth;
Jonathan Hart5f7097e2014-11-11 11:50:28 -080041import org.onlab.packet.IpPrefix;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070042import org.onlab.packet.MacAddress;
43
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070044/**
45 * Base class for command line operations for connectivity based intents.
46 */
47public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
48
Jonathan Hart2c25e362014-11-17 18:14:19 -080049 // Selectors
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070050 @Option(name = "-s", aliases = "--ethSrc", description = "Source MAC Address",
51 required = false, multiValued = false)
52 private String srcMacString = null;
53
54 @Option(name = "-d", aliases = "--ethDst", description = "Destination MAC Address",
55 required = false, multiValued = false)
56 private String dstMacString = null;
57
58 @Option(name = "-t", aliases = "--ethType", description = "Ethernet Type",
59 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -080060 private String ethTypeString = null;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070061
Jonathan Hart5f7097e2014-11-11 11:50:28 -080062 @Option(name = "--ipProto", description = "IP Protocol",
63 required = false, multiValued = false)
64 private String ipProtoString = null;
65
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070066 @Option(name = "--ipSrc", description = "Source IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080067 required = false, multiValued = false)
68 private String srcIpString = null;
69
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070070 @Option(name = "--ipDst", description = "Destination IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080071 required = false, multiValued = false)
72 private String dstIpString = null;
73
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +080074 @Option(name = "--fLabel", description = "IPv6 Flow Label",
75 required = false, multiValued = false)
76 private String fLabelString = null;
77
78 @Option(name = "--icmp6Type", description = "ICMPv6 Type",
79 required = false, multiValued = false)
80 private String icmp6TypeString = null;
81
82 @Option(name = "--icmp6Code", description = "ICMPv6 Code",
83 required = false, multiValued = false)
84 private String icmp6CodeString = null;
85
86 @Option(name = "--ndTarget", description = "IPv6 Neighbor Discovery Target Address",
87 required = false, multiValued = false)
88 private String ndTargetString = null;
89
90 @Option(name = "--ndSLL", description = "IPv6 Neighbor Discovery Source Link-Layer",
91 required = false, multiValued = false)
92 private String ndSLLString = null;
93
94 @Option(name = "--ndTLL", description = "IPv6 Neighbor Discovery Target Link-Layer",
95 required = false, multiValued = false)
96 private String ndTLLString = null;
97
Jonathan Hart5f7097e2014-11-11 11:50:28 -080098 @Option(name = "--tcpSrc", description = "Source TCP Port",
99 required = false, multiValued = false)
100 private String srcTcpString = null;
101
102 @Option(name = "--tcpDst", description = "Destination TCP Port",
103 required = false, multiValued = false)
104 private String dstTcpString = null;
105
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800106 @Option(name = "--extHdr", description = "IPv6 Extension Header Pseudo-field",
107 required = false, multiValued = false)
108 private String extHdrString = null;
109
Ray Milkey460f4022014-11-05 15:41:43 -0800110 @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
111 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -0800112 private String bandwidthString = null;
Ray Milkey460f4022014-11-05 15:41:43 -0800113
114 @Option(name = "-l", aliases = "--lambda", description = "Lambda",
115 required = false, multiValued = false)
116 private boolean lambda = false;
117
Ray Milkey95c50872015-04-14 14:32:31 -0700118 @Option(name = "-a", aliases = "--appId", description = "Application Id",
119 required = false, multiValued = false)
120 private String appId = null;
121
Ray Milkey5b3717e2015-02-05 11:44:08 -0800122 @Option(name = "-k", aliases = "--key", description = "Intent Key",
123 required = false, multiValued = false)
124 private String intentKey = null;
125
Jonathan Hart2c25e362014-11-17 18:14:19 -0800126
127 // Treatments
128 @Option(name = "--setEthSrc", description = "Rewrite Source MAC Address",
129 required = false, multiValued = false)
130 private String setEthSrcString = null;
131
132 @Option(name = "--setEthDst", description = "Rewrite Destination MAC Address",
133 required = false, multiValued = false)
134 private String setEthDstString = null;
135
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800136 @Option(name = "--setIpSrc", description = "Rewrite Source IP Address",
137 required = false, multiValued = false)
138 private String setIpSrcString = null;
139
140 @Option(name = "--setIpDst", description = "Rewrite Destination IP Address",
141 required = false, multiValued = false)
142 private String setIpDstString = null;
143
144
Ray Milkeyc24cde32015-03-10 18:20:18 -0700145 // Priorities
146 @Option(name = "-p", aliases = "--priority", description = "Priority",
147 required = false, multiValued = false)
148 private int priority = Intent.DEFAULT_INTENT_PRIORITY;
149
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700150 /**
151 * Constructs a traffic selector based on the command line arguments
152 * presented to the command.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800153 * @return traffic selector
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700154 */
155 protected TrafficSelector buildTrafficSelector() {
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700156 IpPrefix srcIpPrefix = null;
157 IpPrefix dstIpPrefix = null;
Ray Milkeycaa450b2014-10-29 15:54:24 -0700158
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700159 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
160
161 if (!isNullOrEmpty(srcIpString)) {
162 srcIpPrefix = IpPrefix.valueOf(srcIpString);
163 if (srcIpPrefix.isIp4()) {
164 selectorBuilder.matchIPSrc(srcIpPrefix);
165 } else {
166 selectorBuilder.matchIPv6Src(srcIpPrefix);
167 }
168 }
169
170 if (!isNullOrEmpty(dstIpString)) {
171 dstIpPrefix = IpPrefix.valueOf(dstIpString);
172 if (dstIpPrefix.isIp4()) {
173 selectorBuilder.matchIPDst(dstIpPrefix);
174 } else {
175 selectorBuilder.matchIPv6Dst(dstIpPrefix);
176 }
177 }
178
179 if ((srcIpPrefix != null) && (dstIpPrefix != null) &&
180 (srcIpPrefix.version() != dstIpPrefix.version())) {
181 // ERROR: IP src/dst version mismatch
182 throw new IllegalArgumentException(
183 "IP source and destination version mismatch");
184 }
185
186 //
187 // Set the default EthType based on the IP version if the matching
188 // source or destination IP prefixes.
189 //
190 short ethType = EthType.IPV4.value();
191 if ((srcIpPrefix != null) && srcIpPrefix.isIp6()) {
192 ethType = EthType.IPV6.value();
193 }
194 if ((dstIpPrefix != null) && dstIpPrefix.isIp6()) {
195 ethType = EthType.IPV6.value();
196 }
Ray Milkey460f4022014-11-05 15:41:43 -0800197 if (!isNullOrEmpty(ethTypeString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800198 ethType = EthType.parseFromString(ethTypeString);
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700199 }
200 selectorBuilder.matchEthType(ethType);
201
Ray Milkey460f4022014-11-05 15:41:43 -0800202 if (!isNullOrEmpty(srcMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700203 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
204 }
205
Ray Milkey460f4022014-11-05 15:41:43 -0800206 if (!isNullOrEmpty(dstMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700207 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
208 }
209
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800210 if (!isNullOrEmpty(ipProtoString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800211 short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
212 selectorBuilder.matchIPProtocol((byte) ipProtoShort);
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800213 }
214
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800215 if (!isNullOrEmpty(fLabelString)) {
216 selectorBuilder.matchIPv6FlowLabel(Integer.parseInt(fLabelString));
217 }
218
219 if (!isNullOrEmpty(icmp6TypeString)) {
220 selectorBuilder.matchIcmpv6Type((byte) Integer.parseInt(icmp6TypeString));
221 }
222
223 if (!isNullOrEmpty(icmp6CodeString)) {
224 selectorBuilder.matchIcmpv6Code((byte) Integer.parseInt(icmp6CodeString));
225 }
226
227 if (!isNullOrEmpty(ndTargetString)) {
228 selectorBuilder.matchIPv6NDTargetAddress(Ip6Address.valueOf(ndTargetString));
229 }
230
231 if (!isNullOrEmpty(ndSLLString)) {
232 selectorBuilder.matchIPv6NDSourceLinkLayerAddress(MacAddress.valueOf(ndSLLString));
233 }
234
235 if (!isNullOrEmpty(ndTLLString)) {
236 selectorBuilder.matchIPv6NDTargetLinkLayerAddress(MacAddress.valueOf(ndTLLString));
237 }
238
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800239 if (!isNullOrEmpty(srcTcpString)) {
240 selectorBuilder.matchTcpSrc((short) Integer.parseInt(srcTcpString));
241 }
242
243 if (!isNullOrEmpty(dstTcpString)) {
Jonathan Hart5dfa43f2014-11-17 15:35:54 -0800244 selectorBuilder.matchTcpDst((short) Integer.parseInt(dstTcpString));
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800245 }
246
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800247 if (!isNullOrEmpty(extHdrString)) {
248 selectorBuilder.matchIPv6ExthdrFlags(Integer.parseInt(extHdrString));
249 }
250
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700251 return selectorBuilder.build();
252 }
253
Ray Milkey460f4022014-11-05 15:41:43 -0800254 /**
Jonathan Hart2c25e362014-11-17 18:14:19 -0800255 * Generates a traffic treatment for this intent based on command line
256 * arguments presented to the command.
257 *
258 * @return traffic treatment
259 */
260 protected TrafficTreatment buildTrafficTreatment() {
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800261 final TrafficTreatment.Builder treatmentBuilder = builder();
Jonathan Hart2c25e362014-11-17 18:14:19 -0800262
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800263 if (!isNullOrEmpty(setEthSrcString)) {
264 treatmentBuilder.setEthSrc(MacAddress.valueOf(setEthSrcString));
Brian O'Connor4f5a98a2015-03-14 19:50:09 -0700265 }
266
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800267 if (!isNullOrEmpty(setEthDstString)) {
268 treatmentBuilder.setEthDst(MacAddress.valueOf(setEthDstString));
Jonathan Hart2c25e362014-11-17 18:14:19 -0800269 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800270
271 if (!isNullOrEmpty(setIpSrcString)) {
272 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpSrcString));
Jonathan Hart2c25e362014-11-17 18:14:19 -0800273 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800274
275 if (!isNullOrEmpty(setIpDstString)) {
276 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpDstString));
277 }
278
279 return treatmentBuilder.build();
Jonathan Hart2c25e362014-11-17 18:14:19 -0800280 }
281
282 /**
Ray Milkey460f4022014-11-05 15:41:43 -0800283 * Builds the constraint list for this command based on the command line
284 * parameters.
285 *
286 * @return List of constraint objects describing the constraints requested
287 */
288 protected List<Constraint> buildConstraints() {
289 final List<Constraint> constraints = new LinkedList<>();
290
291 // Check for a bandwidth specification
292 if (!isNullOrEmpty(bandwidthString)) {
293 final double bandwidthValue = Double.parseDouble(bandwidthString);
Sho SHIMIZU0ce220a2015-01-23 15:54:47 -0800294 constraints.add(new BandwidthConstraint(Bandwidth.bps(bandwidthValue)));
Ray Milkey460f4022014-11-05 15:41:43 -0800295 }
296
297 // Check for a lambda specification
298 if (lambda) {
299 constraints.add(new LambdaConstraint(null));
300 }
Thomas Vachuskadea45ff2014-11-12 18:35:46 -0800301 constraints.add(new LinkTypeConstraint(lambda, Link.Type.OPTICAL));
Ray Milkey460f4022014-11-05 15:41:43 -0800302
303 return constraints;
304 }
Ray Milkey5b3717e2015-02-05 11:44:08 -0800305
Ray Milkey95c50872015-04-14 14:32:31 -0700306 @Override
307 protected ApplicationId appId() {
308 ApplicationId appIdForIntent;
309 if (appId == null) {
310 appIdForIntent = super.appId();
311 } else {
312 CoreService service = get(CoreService.class);
313 appIdForIntent = service.getAppId(appId);
314 }
315 return appIdForIntent;
316 }
317
Ray Milkey5b3717e2015-02-05 11:44:08 -0800318 /**
319 * Creates a key for an intent based on command line arguments. If a key
320 * has been specified, it is returned. If no key is specified, null
321 * is returned.
322 *
323 * @return intent key if specified, null otherwise
324 */
325 protected Key key() {
326 Key key = null;
Ray Milkey95c50872015-04-14 14:32:31 -0700327 ApplicationId appIdForIntent;
328
Ray Milkey5b3717e2015-02-05 11:44:08 -0800329 if (intentKey != null) {
330 key = Key.of(intentKey, appId());
331 }
332 return key;
333 }
Ray Milkeyc24cde32015-03-10 18:20:18 -0700334
335 /**
336 * Gets the priority to use for the intent.
337 *
338 * @return priority
339 */
340 protected int priority() {
341 return priority;
342 }
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700343}