blob: 8bc0bc4aa02ae1a2fb400269b284db6e5fccc84e [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;
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -070027import org.onlab.util.Bandwidth;
Brian O'Connorabafb502014-12-02 22:26:20 -080028import org.onosproject.cli.AbstractShellCommand;
Ray Milkey95c50872015-04-14 14:32:31 -070029import org.onosproject.core.ApplicationId;
30import org.onosproject.core.CoreService;
Brian O'Connorabafb502014-12-02 22:26:20 -080031import org.onosproject.net.Link;
32import org.onosproject.net.flow.DefaultTrafficSelector;
Brian O'Connor11ff8702015-04-29 19:37:15 -070033import org.onosproject.net.flow.DefaultTrafficTreatment;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.flow.TrafficSelector;
35import org.onosproject.net.flow.TrafficTreatment;
36import org.onosproject.net.intent.Constraint;
Ray Milkeyc24cde32015-03-10 18:20:18 -070037import org.onosproject.net.intent.Intent;
Ray Milkey5b3717e2015-02-05 11:44:08 -080038import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.intent.constraint.BandwidthConstraint;
40import org.onosproject.net.intent.constraint.LambdaConstraint;
41import org.onosproject.net.intent.constraint.LinkTypeConstraint;
Brian O'Connor6de2e202015-05-21 14:30:41 -070042import org.onosproject.net.resource.link.BandwidthResource;
Jonathan Hart5f7097e2014-11-11 11:50:28 -080043import org.onlab.packet.IpPrefix;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070044import org.onlab.packet.MacAddress;
45
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070046/**
47 * Base class for command line operations for connectivity based intents.
48 */
49public abstract class ConnectivityIntentCommand extends AbstractShellCommand {
50
Jonathan Hart2c25e362014-11-17 18:14:19 -080051 // Selectors
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070052 @Option(name = "-s", aliases = "--ethSrc", description = "Source MAC Address",
53 required = false, multiValued = false)
54 private String srcMacString = null;
55
56 @Option(name = "-d", aliases = "--ethDst", description = "Destination MAC Address",
57 required = false, multiValued = false)
58 private String dstMacString = null;
59
60 @Option(name = "-t", aliases = "--ethType", description = "Ethernet Type",
61 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -080062 private String ethTypeString = null;
Ray Milkey9fdf1ea2014-10-21 09:48:02 -070063
Jonathan Hart5f7097e2014-11-11 11:50:28 -080064 @Option(name = "--ipProto", description = "IP Protocol",
65 required = false, multiValued = false)
66 private String ipProtoString = null;
67
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070068 @Option(name = "--ipSrc", description = "Source IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080069 required = false, multiValued = false)
70 private String srcIpString = null;
71
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -070072 @Option(name = "--ipDst", description = "Destination IP Prefix",
Jonathan Hart5f7097e2014-11-11 11:50:28 -080073 required = false, multiValued = false)
74 private String dstIpString = null;
75
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +080076 @Option(name = "--fLabel", description = "IPv6 Flow Label",
77 required = false, multiValued = false)
78 private String fLabelString = null;
79
80 @Option(name = "--icmp6Type", description = "ICMPv6 Type",
81 required = false, multiValued = false)
82 private String icmp6TypeString = null;
83
84 @Option(name = "--icmp6Code", description = "ICMPv6 Code",
85 required = false, multiValued = false)
86 private String icmp6CodeString = null;
87
88 @Option(name = "--ndTarget", description = "IPv6 Neighbor Discovery Target Address",
89 required = false, multiValued = false)
90 private String ndTargetString = null;
91
92 @Option(name = "--ndSLL", description = "IPv6 Neighbor Discovery Source Link-Layer",
93 required = false, multiValued = false)
94 private String ndSLLString = null;
95
96 @Option(name = "--ndTLL", description = "IPv6 Neighbor Discovery Target Link-Layer",
97 required = false, multiValued = false)
98 private String ndTLLString = null;
99
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800100 @Option(name = "--tcpSrc", description = "Source TCP Port",
101 required = false, multiValued = false)
102 private String srcTcpString = null;
103
104 @Option(name = "--tcpDst", description = "Destination TCP Port",
105 required = false, multiValued = false)
106 private String dstTcpString = null;
107
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800108 @Option(name = "--extHdr", description = "IPv6 Extension Header Pseudo-field",
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800109 required = false, multiValued = true)
110 private List<String> extHdrStringList = null;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800111
Ray Milkey460f4022014-11-05 15:41:43 -0800112 @Option(name = "-b", aliases = "--bandwidth", description = "Bandwidth",
113 required = false, multiValued = false)
Ray Milkey04c78322015-01-21 14:57:58 -0800114 private String bandwidthString = null;
Ray Milkey460f4022014-11-05 15:41:43 -0800115
116 @Option(name = "-l", aliases = "--lambda", description = "Lambda",
117 required = false, multiValued = false)
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700118 private boolean lambda = false;
Ray Milkey460f4022014-11-05 15:41:43 -0800119
Ray Milkey95c50872015-04-14 14:32:31 -0700120 @Option(name = "-a", aliases = "--appId", description = "Application Id",
121 required = false, multiValued = false)
122 private String appId = null;
123
Ray Milkey5b3717e2015-02-05 11:44:08 -0800124 @Option(name = "-k", aliases = "--key", description = "Intent Key",
125 required = false, multiValued = false)
126 private String intentKey = null;
127
Jonathan Hart2c25e362014-11-17 18:14:19 -0800128
129 // Treatments
130 @Option(name = "--setEthSrc", description = "Rewrite Source MAC Address",
131 required = false, multiValued = false)
132 private String setEthSrcString = null;
133
134 @Option(name = "--setEthDst", description = "Rewrite Destination MAC Address",
135 required = false, multiValued = false)
136 private String setEthDstString = null;
137
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800138 @Option(name = "--setIpSrc", description = "Rewrite Source IP Address",
139 required = false, multiValued = false)
140 private String setIpSrcString = null;
141
142 @Option(name = "--setIpDst", description = "Rewrite Destination IP Address",
143 required = false, multiValued = false)
144 private String setIpDstString = null;
145
146
Ray Milkeyc24cde32015-03-10 18:20:18 -0700147 // Priorities
148 @Option(name = "-p", aliases = "--priority", description = "Priority",
149 required = false, multiValued = false)
150 private int priority = Intent.DEFAULT_INTENT_PRIORITY;
151
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700152 /**
153 * Constructs a traffic selector based on the command line arguments
154 * presented to the command.
Yuta HIGUCHI5c947272014-11-03 21:39:21 -0800155 * @return traffic selector
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700156 */
157 protected TrafficSelector buildTrafficSelector() {
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700158 IpPrefix srcIpPrefix = null;
159 IpPrefix dstIpPrefix = null;
Ray Milkeycaa450b2014-10-29 15:54:24 -0700160
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700161 TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
162
163 if (!isNullOrEmpty(srcIpString)) {
164 srcIpPrefix = IpPrefix.valueOf(srcIpString);
165 if (srcIpPrefix.isIp4()) {
166 selectorBuilder.matchIPSrc(srcIpPrefix);
167 } else {
168 selectorBuilder.matchIPv6Src(srcIpPrefix);
169 }
170 }
171
172 if (!isNullOrEmpty(dstIpString)) {
173 dstIpPrefix = IpPrefix.valueOf(dstIpString);
174 if (dstIpPrefix.isIp4()) {
175 selectorBuilder.matchIPDst(dstIpPrefix);
176 } else {
177 selectorBuilder.matchIPv6Dst(dstIpPrefix);
178 }
179 }
180
181 if ((srcIpPrefix != null) && (dstIpPrefix != null) &&
182 (srcIpPrefix.version() != dstIpPrefix.version())) {
183 // ERROR: IP src/dst version mismatch
184 throw new IllegalArgumentException(
185 "IP source and destination version mismatch");
186 }
187
188 //
189 // Set the default EthType based on the IP version if the matching
190 // source or destination IP prefixes.
191 //
Ayaka Koshibe8117f362015-06-02 13:44:01 -0700192 Short ethType = null;
Pavlin Radoslavov6ba7efc2015-03-20 16:26:10 -0700193 if ((srcIpPrefix != null) && srcIpPrefix.isIp6()) {
194 ethType = EthType.IPV6.value();
195 }
196 if ((dstIpPrefix != null) && dstIpPrefix.isIp6()) {
197 ethType = EthType.IPV6.value();
198 }
Ray Milkey460f4022014-11-05 15:41:43 -0800199 if (!isNullOrEmpty(ethTypeString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800200 ethType = EthType.parseFromString(ethTypeString);
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700201 }
Ayaka Koshibe8117f362015-06-02 13:44:01 -0700202 if (ethType != null) {
203 selectorBuilder.matchEthType(ethType);
204 }
Ray Milkey460f4022014-11-05 15:41:43 -0800205 if (!isNullOrEmpty(srcMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700206 selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMacString));
207 }
208
Ray Milkey460f4022014-11-05 15:41:43 -0800209 if (!isNullOrEmpty(dstMacString)) {
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700210 selectorBuilder.matchEthDst(MacAddress.valueOf(dstMacString));
211 }
212
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800213 if (!isNullOrEmpty(ipProtoString)) {
Jonathan Hart6e948282014-11-17 22:50:42 -0800214 short ipProtoShort = IpProtocol.parseFromString(ipProtoString);
215 selectorBuilder.matchIPProtocol((byte) ipProtoShort);
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800216 }
217
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800218 if (!isNullOrEmpty(fLabelString)) {
219 selectorBuilder.matchIPv6FlowLabel(Integer.parseInt(fLabelString));
220 }
221
222 if (!isNullOrEmpty(icmp6TypeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800223 byte icmp6Type = Icmp6Type.parseFromString(icmp6TypeString);
224 selectorBuilder.matchIcmpv6Type(icmp6Type);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800225 }
226
227 if (!isNullOrEmpty(icmp6CodeString)) {
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800228 byte icmp6Code = Icmp6Code.parseFromString(icmp6CodeString);
229 selectorBuilder.matchIcmpv6Code(icmp6Code);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800230 }
231
232 if (!isNullOrEmpty(ndTargetString)) {
233 selectorBuilder.matchIPv6NDTargetAddress(Ip6Address.valueOf(ndTargetString));
234 }
235
236 if (!isNullOrEmpty(ndSLLString)) {
237 selectorBuilder.matchIPv6NDSourceLinkLayerAddress(MacAddress.valueOf(ndSLLString));
238 }
239
240 if (!isNullOrEmpty(ndTLLString)) {
241 selectorBuilder.matchIPv6NDTargetLinkLayerAddress(MacAddress.valueOf(ndTLLString));
242 }
243
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800244 if (!isNullOrEmpty(srcTcpString)) {
245 selectorBuilder.matchTcpSrc((short) Integer.parseInt(srcTcpString));
246 }
247
248 if (!isNullOrEmpty(dstTcpString)) {
Jonathan Hart5dfa43f2014-11-17 15:35:54 -0800249 selectorBuilder.matchTcpDst((short) Integer.parseInt(dstTcpString));
Jonathan Hart5f7097e2014-11-11 11:50:28 -0800250 }
251
Charles M.C. Chan2184de12015-04-26 02:24:53 +0800252 if (extHdrStringList != null) {
253 short extHdr = 0;
254 for (String extHdrString : extHdrStringList) {
255 extHdr = (short) (extHdr | ExtHeader.parseFromString(extHdrString));
256 }
257 selectorBuilder.matchIPv6ExthdrFlags(extHdr);
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800258 }
259
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700260 return selectorBuilder.build();
261 }
262
Ray Milkey460f4022014-11-05 15:41:43 -0800263 /**
Jonathan Hart2c25e362014-11-17 18:14:19 -0800264 * Generates a traffic treatment for this intent based on command line
265 * arguments presented to the command.
266 *
267 * @return traffic treatment
268 */
269 protected TrafficTreatment buildTrafficTreatment() {
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800270 final TrafficTreatment.Builder treatmentBuilder = builder();
Brian O'Connor11ff8702015-04-29 19:37:15 -0700271 boolean emptyTreatment = true;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800272
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800273 if (!isNullOrEmpty(setEthSrcString)) {
274 treatmentBuilder.setEthSrc(MacAddress.valueOf(setEthSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700275 emptyTreatment = false;
Brian O'Connor4f5a98a2015-03-14 19:50:09 -0700276 }
277
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800278 if (!isNullOrEmpty(setEthDstString)) {
279 treatmentBuilder.setEthDst(MacAddress.valueOf(setEthDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700280 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800281 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800282
283 if (!isNullOrEmpty(setIpSrcString)) {
284 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpSrcString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700285 emptyTreatment = false;
Jonathan Hart2c25e362014-11-17 18:14:19 -0800286 }
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800287
288 if (!isNullOrEmpty(setIpDstString)) {
289 treatmentBuilder.setIpSrc(IpAddress.valueOf(setIpDstString));
Brian O'Connor11ff8702015-04-29 19:37:15 -0700290 emptyTreatment = false;
Charles M.C. Chane9c8bbc2015-04-24 05:03:02 +0800291 }
292
Brian O'Connor11ff8702015-04-29 19:37:15 -0700293 if (emptyTreatment) {
294 return DefaultTrafficTreatment.emptyTreatment();
295 } else {
296 return treatmentBuilder.build();
297 }
Jonathan Hart2c25e362014-11-17 18:14:19 -0800298 }
299
300 /**
Ray Milkey460f4022014-11-05 15:41:43 -0800301 * Builds the constraint list for this command based on the command line
302 * parameters.
303 *
304 * @return List of constraint objects describing the constraints requested
305 */
306 protected List<Constraint> buildConstraints() {
307 final List<Constraint> constraints = new LinkedList<>();
308
309 // Check for a bandwidth specification
310 if (!isNullOrEmpty(bandwidthString)) {
Sho SHIMIZU6d01d3d2015-05-08 14:08:36 -0700311 final Bandwidth bandwidth = Bandwidth.bps(Double.parseDouble(bandwidthString));
312 constraints.add(new BandwidthConstraint(new BandwidthResource(bandwidth)));
Ray Milkey460f4022014-11-05 15:41:43 -0800313 }
314
315 // Check for a lambda specification
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700316 if (lambda) {
317 constraints.add(new LambdaConstraint(null));
Ray Milkey460f4022014-11-05 15:41:43 -0800318 }
Sho SHIMIZU792c26b2015-06-08 19:08:32 -0700319 constraints.add(new LinkTypeConstraint(lambda, Link.Type.OPTICAL));
320
Ray Milkey460f4022014-11-05 15:41:43 -0800321 return constraints;
322 }
Ray Milkey5b3717e2015-02-05 11:44:08 -0800323
Ray Milkey95c50872015-04-14 14:32:31 -0700324 @Override
325 protected ApplicationId appId() {
326 ApplicationId appIdForIntent;
327 if (appId == null) {
328 appIdForIntent = super.appId();
329 } else {
330 CoreService service = get(CoreService.class);
331 appIdForIntent = service.getAppId(appId);
332 }
333 return appIdForIntent;
334 }
335
Ray Milkey5b3717e2015-02-05 11:44:08 -0800336 /**
337 * Creates a key for an intent based on command line arguments. If a key
338 * has been specified, it is returned. If no key is specified, null
339 * is returned.
340 *
341 * @return intent key if specified, null otherwise
342 */
343 protected Key key() {
344 Key key = null;
Ray Milkey95c50872015-04-14 14:32:31 -0700345 ApplicationId appIdForIntent;
346
Ray Milkey5b3717e2015-02-05 11:44:08 -0800347 if (intentKey != null) {
348 key = Key.of(intentKey, appId());
349 }
350 return key;
351 }
Ray Milkeyc24cde32015-03-10 18:20:18 -0700352
353 /**
354 * Gets the priority to use for the intent.
355 *
356 * @return priority
357 */
358 protected int priority() {
359 return priority;
360 }
Ray Milkey9fdf1ea2014-10-21 09:48:02 -0700361}