blob: 89a2e1418846dc4b230ce1adbf9fcc54990ddd77 [file] [log] [blame]
Jian Li4aa17642019-01-30 00:01:11 +09001/*
2 * Copyright 2019-present Open Networking Foundation
3 *
4 * 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
7 *
8 * 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.
15 */
16package org.onosproject.k8snetworking.util;
17
18import org.onlab.packet.Ip4Address;
Jian Li2cc2b632019-02-18 00:56:40 +090019import org.onlab.packet.IpAddress;
20import org.onlab.packet.TpPort;
Jian Li4aa17642019-01-30 00:01:11 +090021import org.onosproject.net.Device;
22import org.onosproject.net.DeviceId;
Jian Li2cc2b632019-02-18 00:56:40 +090023import org.onosproject.net.behaviour.ExtensionSelectorResolver;
Jian Li4aa17642019-01-30 00:01:11 +090024import org.onosproject.net.behaviour.ExtensionTreatmentResolver;
25import org.onosproject.net.device.DeviceService;
Jian Li2cc2b632019-02-18 00:56:40 +090026import org.onosproject.net.driver.DriverHandler;
27import org.onosproject.net.driver.DriverService;
28import org.onosproject.net.flow.TrafficTreatment;
29import org.onosproject.net.flow.criteria.ExtensionSelector;
30import org.onosproject.net.flow.criteria.ExtensionSelectorType;
Jian Li4aa17642019-01-30 00:01:11 +090031import org.onosproject.net.flow.instructions.ExtensionPropertyException;
32import org.onosproject.net.flow.instructions.ExtensionTreatment;
Jian Li2cc2b632019-02-18 00:56:40 +090033import org.onosproject.net.flow.instructions.ExtensionTreatmentType;
34import org.onosproject.net.group.DefaultGroupBucket;
35import org.onosproject.net.group.GroupBucket;
36import org.onosproject.net.group.GroupDescription.Type;
Jian Li4aa17642019-01-30 00:01:11 +090037import org.slf4j.Logger;
38
Jian Li2cc2b632019-02-18 00:56:40 +090039import java.util.ArrayList;
40import java.util.List;
41
Jian Li140d8a22019-04-24 23:41:44 +090042import static org.onosproject.k8snetworking.api.Constants.A_CLASS;
43import static org.onosproject.k8snetworking.api.Constants.B_CLASS;
Jian Li5e8a22a2019-02-27 11:48:42 +090044import static org.onosproject.k8snetworking.api.Constants.DST;
45import static org.onosproject.k8snetworking.api.Constants.SRC;
Jian Li004526d2019-02-25 16:26:27 +090046import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_LOAD;
Jian Lieb488ea2019-04-16 01:50:02 +090047import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SHA_TO_THA;
48import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ARP_SPA_TO_TPA;
49import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_MOV_ETH_SRC_TO_DST;
Jian Li2cc2b632019-02-18 00:56:40 +090050import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_RESUBMIT_TABLE;
Jian Li4aa17642019-01-30 00:01:11 +090051import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
52import static org.slf4j.LoggerFactory.getLogger;
53
54/**
55 * Provides common methods to help populating flow rules for SONA applications.
56 */
57public final class RulePopulatorUtil {
58
59 private static final Logger log = getLogger(RulePopulatorUtil.class);
60
61 private static final String TUNNEL_DST = "tunnelDst";
62
Jian Li2cc2b632019-02-18 00:56:40 +090063 private static final String CT_FLAGS = "flags";
64 private static final String CT_ZONE = "zone";
65 private static final String CT_TABLE = "recircTable";
66 private static final String CT_STATE = "ctState";
67 private static final String CT_STATE_MASK = "ctStateMask";
68 private static final String CT_PRESENT_FLAGS = "presentFlags";
69 private static final String CT_IPADDRESS_MIN = "ipAddressMin";
70 private static final String CT_IPADDRESS_MAX = "ipAddressMax";
71 private static final String CT_PORT_MIN = "portMin";
72 private static final String CT_PORT_MAX = "portMax";
73 private static final String CT_NESTED_ACTIONS = "nestedActions";
74
75 public static final int CT_NAT_SRC_FLAG = 0;
76 public static final int CT_NAT_DST_FLAG = 1;
77 public static final int CT_NAT_PERSISTENT_FLAG = 2;
78 public static final int CT_NAT_PROTO_HASH_FLAG = 3;
79 public static final int CT_NAT_PROTO_RANDOM_FLAG = 4;
80
81 private static final int ADDRESS_V4_MIN_FLAG = 0;
82 private static final int ADDRESS_V4_MAX_FLAG = 1;
83 private static final int ADDRESS_V6_MIN_FLAG = 2;
84 private static final int ADDRESS_V6_MAX_FLAG = 3;
85 private static final int PORT_MIN_FLAG = 4;
86 private static final int PORT_MAX_FLAG = 5;
87
Jian Li004526d2019-02-25 16:26:27 +090088 private static final long CT_STATE_NONE = 0;
89 private static final long CT_STATE_NEW = 0x01;
90 private static final long CT_STATE_EST = 0x02;
91 private static final long CT_STATE_NOT_TRK = 0x20;
92 private static final long CT_STATE_TRK = 0x20;
Jian Li2cc2b632019-02-18 00:56:40 +090093
94 private static final String TABLE_EXTENSION = "table";
95
Jian Li004526d2019-02-25 16:26:27 +090096 private static final String OFF_SET_N_BITS = "ofsNbits";
97 private static final String DESTINATION = "dst";
98 private static final String VALUE = "value";
99
100 private static final int SRC_IP = 0x00000e04;
101 private static final int DST_IP = 0x00001004;
102
Jian Li140d8a22019-04-24 23:41:44 +0900103 private static final int A_CLASS_OFF_SET_BIT = 8;
104 private static final int B_CLASS_OFF_SET_BIT = 16;
Jian Li004526d2019-02-25 16:26:27 +0900105 private static final int REMAINDER_BIT = 16;
106
Jian Li2cc2b632019-02-18 00:56:40 +0900107 // not intended for direct invocation from external
Jian Li4aa17642019-01-30 00:01:11 +0900108 private RulePopulatorUtil() {
109 }
110
111 /**
Jian Li2cc2b632019-02-18 00:56:40 +0900112 * Returns a builder for OVS Connection Tracking feature actions.
113 *
114 * @param ds DriverService
115 * @param id DeviceId
116 * @return a builder for OVS Connection Tracking feature actions
117 */
118 public static NiciraConnTrackTreatmentBuilder
119 niciraConnTrackTreatmentBuilder(DriverService ds, DeviceId id) {
120 return new NiciraConnTrackTreatmentBuilder(ds, id);
121 }
122
123 /**
124 * Builds OVS ConnTrack matches.
125 *
126 * @param driverService driver service
127 * @param deviceId device ID
128 * @param ctState connection tracking sate masking value
129 * @param ctSateMask connection tracking sate masking value
130 * @return OVS ConnTrack extension match
131 */
132 public static ExtensionSelector buildCtExtensionSelector(DriverService driverService,
133 DeviceId deviceId,
134 long ctState,
135 long ctSateMask) {
136 DriverHandler handler = driverService.createHandler(deviceId);
137 ExtensionSelectorResolver esr = handler.behaviour(ExtensionSelectorResolver.class);
138
139 ExtensionSelector extensionSelector = esr.getExtensionSelector(
140 ExtensionSelectorType.ExtensionSelectorTypes.NICIRA_MATCH_CONNTRACK_STATE.type());
141 try {
142 extensionSelector.setPropertyValue(CT_STATE, ctState);
143 extensionSelector.setPropertyValue(CT_STATE_MASK, ctSateMask);
144 } catch (Exception e) {
145 log.error("Failed to set nicira match CT state because of {}", e);
146 return null;
147 }
148
149 return extensionSelector;
150 }
151
152 /**
153 * Computes ConnTack State flag values.
154 *
155 * @param isTracking true for +trk, false for -trk
156 * @param isNew true for +new, false for -new
157 * @param isEstablished true for +est, false for -est
158 * @return ConnTrack State flags
159 */
160 public static long computeCtStateFlag(boolean isTracking,
161 boolean isNew,
162 boolean isEstablished) {
163 long ctStateFlag = 0x00;
164
165 if (isTracking) {
166 ctStateFlag = ctStateFlag | CT_STATE_TRK;
167 }
168
169 if (isNew) {
170 ctStateFlag = ctStateFlag | CT_STATE_TRK;
171 ctStateFlag = ctStateFlag | CT_STATE_NEW;
172 }
173
174 if (isEstablished) {
175 ctStateFlag = ctStateFlag | CT_STATE_TRK;
176 ctStateFlag = ctStateFlag | CT_STATE_EST;
177 }
178
179 return ctStateFlag;
180 }
181
182 /**
183 * Computes ConnTrack State mask values.
184 *
185 * @param isTracking true for setting +trk/-trk value, false for otherwise
186 * @param isNew true for setting +new/-new value, false for otherwise
187 * @param isEstablished true for setting +est/-est value, false for otherwise
188 * @return ConnTrack State Mask value
189 */
190 public static long computeCtMaskFlag(boolean isTracking,
191 boolean isNew,
192 boolean isEstablished) {
193 long ctMaskFlag = 0x00;
194
195 if (isTracking) {
196 ctMaskFlag = ctMaskFlag | CT_STATE_TRK;
197 }
198
199 if (isNew) {
200 ctMaskFlag = ctMaskFlag | CT_STATE_TRK;
201 ctMaskFlag = ctMaskFlag | CT_STATE_NEW;
202 }
203
204 if (isEstablished) {
205 ctMaskFlag = ctMaskFlag | CT_STATE_TRK;
206 ctMaskFlag = ctMaskFlag | CT_STATE_EST;
207 }
208
209 return ctMaskFlag;
210 }
211
212 /**
Jian Li4aa17642019-01-30 00:01:11 +0900213 * Returns tunnel destination extension treatment object.
214 *
215 * @param deviceService driver service
216 * @param deviceId device id to apply this treatment
217 * @param remoteIp tunnel destination ip address
218 * @return extension treatment
219 */
220 public static ExtensionTreatment buildExtension(DeviceService deviceService,
221 DeviceId deviceId,
222 Ip4Address remoteIp) {
223 Device device = deviceService.getDevice(deviceId);
Jian Lieb488ea2019-04-16 01:50:02 +0900224
225 if (!checkTreatmentResolver(device)) {
Jian Li4aa17642019-01-30 00:01:11 +0900226 return null;
227 }
228
229 if (device == null) {
230 return null;
231 }
232
233 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
234 ExtensionTreatment treatment =
235 resolver.getExtensionInstruction(NICIRA_SET_TUNNEL_DST.type());
236 try {
237 treatment.setPropertyValue(TUNNEL_DST, remoteIp);
238 return treatment;
239 } catch (ExtensionPropertyException e) {
240 log.warn("Failed to get tunnelDst extension treatment for {} " +
241 "because of {}", deviceId, e);
242 return null;
243 }
244 }
Jian Li2cc2b632019-02-18 00:56:40 +0900245
246 /**
247 * Returns the group bucket with given traffic treatment and group type.
248 *
249 * @param treatment traffic treatment
250 * @param type group type
251 * @param weight weight (only for select type)
252 * @return group bucket
253 */
254 public static GroupBucket buildGroupBucket(TrafficTreatment treatment,
255 Type type, short weight) {
256 switch (type) {
257 case ALL:
258 return DefaultGroupBucket.createAllGroupBucket(treatment);
259 case SELECT:
260 if (weight == -1) {
261 return DefaultGroupBucket.createSelectGroupBucket(treatment);
262 } else {
263 return DefaultGroupBucket.createSelectGroupBucket(treatment, weight);
264 }
265 case INDIRECT:
266 return DefaultGroupBucket.createIndirectGroupBucket(treatment);
267 default:
268 return null;
269 }
270 }
271
272 /**
273 * Returns the nicira resubmit extension treatment with given table ID.
274 *
Jian Li004526d2019-02-25 16:26:27 +0900275 * @param device device instance
Jian Li2cc2b632019-02-18 00:56:40 +0900276 * @param tableId table identifier
277 * @return resubmit extension treatment
278 */
279 public static ExtensionTreatment buildResubmitExtension(Device device, int tableId) {
Jian Lieb488ea2019-04-16 01:50:02 +0900280 if (!checkTreatmentResolver(device)) {
Jian Li2cc2b632019-02-18 00:56:40 +0900281 return null;
282 }
283
284 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
285 ExtensionTreatment treatment =
286 resolver.getExtensionInstruction(NICIRA_RESUBMIT_TABLE.type());
287
288 try {
289 treatment.setPropertyValue(TABLE_EXTENSION, ((short) tableId));
290 return treatment;
291 } catch (ExtensionPropertyException e) {
292 log.error("Failed to set nicira resubmit extension treatment for {}",
293 device.id());
294 return null;
295 }
296 }
297
298 /**
Jian Li004526d2019-02-25 16:26:27 +0900299 * Returns the nicira load extension treatment.
300 *
301 * @param device device instance
Jian Li140d8a22019-04-24 23:41:44 +0900302 * @param cidrClass CIDR class (a | b)
Jian Li004526d2019-02-25 16:26:27 +0900303 * @param ipType IP type (src|dst)
Jian Li140d8a22019-04-24 23:41:44 +0900304 * @param shift shift (e.g., 10.10., 20.20., 10, 20,)
Jian Li004526d2019-02-25 16:26:27 +0900305 * @return load extension treatment
306 */
307 public static ExtensionTreatment buildLoadExtension(Device device,
Jian Li140d8a22019-04-24 23:41:44 +0900308 String cidrClass,
Jian Li004526d2019-02-25 16:26:27 +0900309 String ipType,
310 String shift) {
Jian Lieb488ea2019-04-16 01:50:02 +0900311 if (!checkTreatmentResolver(device)) {
Jian Li004526d2019-02-25 16:26:27 +0900312 return null;
313 }
314
315 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
316 ExtensionTreatment treatment =
317 resolver.getExtensionInstruction(NICIRA_LOAD.type());
318
319 long dst = 0L;
320
321 if (SRC.equalsIgnoreCase(ipType)) {
322 dst = SRC_IP;
323 } else if (DST.equals(ipType)) {
324 dst = DST_IP;
325 }
326
Jian Li140d8a22019-04-24 23:41:44 +0900327 long value = calculateUpperBit(cidrClass, shift);
Jian Li004526d2019-02-25 16:26:27 +0900328
Jian Li140d8a22019-04-24 23:41:44 +0900329 // we only rewrite the upper x bits with value
330 int ofsNbits = 0;
331
332 if (A_CLASS.equals(cidrClass)) {
333 ofsNbits = A_CLASS_OFF_SET_BIT << 6 | (REMAINDER_BIT - 1);
334 } else if (B_CLASS.equals(cidrClass)) {
335 ofsNbits = B_CLASS_OFF_SET_BIT << 6 | (REMAINDER_BIT - 1);
336 }
Jian Li004526d2019-02-25 16:26:27 +0900337
338 try {
339 treatment.setPropertyValue(OFF_SET_N_BITS, ofsNbits);
340 treatment.setPropertyValue(DESTINATION, dst);
341 treatment.setPropertyValue(VALUE, value);
342 return treatment;
343 } catch (ExtensionPropertyException e) {
344 log.error("Failed to set nicira load extension treatment for {}",
345 device.id());
346 return null;
347 }
348 }
349
Jian Lieb488ea2019-04-16 01:50:02 +0900350 /**
351 * Returns the nicira move source MAC to destination MAC extension treatment.
352 *
353 * @param device device instance
354 * @return move extension treatment
355 */
356 public static ExtensionTreatment buildMoveEthSrcToDstExtension(Device device) {
357 if (!checkTreatmentResolver(device)) {
358 return null;
359 }
360
361 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
362 return resolver.getExtensionInstruction(NICIRA_MOV_ETH_SRC_TO_DST.type());
363 }
364
365 /**
366 * Returns the nicira move ARP SHA to THA extension treatment.
367 *
368 * @param device device instance
369 * @return move extension treatment
370 */
371 public static ExtensionTreatment buildMoveArpShaToThaExtension(Device device) {
372 if (!checkTreatmentResolver(device)) {
373 return null;
374 }
375
376 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
377 return resolver.getExtensionInstruction(NICIRA_MOV_ARP_SHA_TO_THA.type());
378 }
379
380 /**
381 * Returns the nicira move ARP SPA to TPA extension treatment.
382 *
383 * @param device device instance
384 * @return move extension treatment
385 */
386 public static ExtensionTreatment buildMoveArpSpaToTpaExtension(Device device) {
387 if (!checkTreatmentResolver(device)) {
388 return null;
389 }
390
391 ExtensionTreatmentResolver resolver = device.as(ExtensionTreatmentResolver.class);
392 return resolver.getExtensionInstruction(NICIRA_MOV_ARP_SPA_TO_TPA.type());
393 }
394
Jian Li004526d2019-02-25 16:26:27 +0900395 /**
396 * Calculate IP address upper string into integer.
397 *
Jian Li140d8a22019-04-24 23:41:44 +0900398 * @param cidrClass CIDR class type
Jian Li004526d2019-02-25 16:26:27 +0900399 * @param shift IP address upper two octets with dot
400 * @return calculated integer
401 */
Jian Li140d8a22019-04-24 23:41:44 +0900402 private static int calculateUpperBit(String cidrClass, String shift) {
Jian Li004526d2019-02-25 16:26:27 +0900403
Jian Li140d8a22019-04-24 23:41:44 +0900404 if (A_CLASS.equals(cidrClass)) {
405 return Integer.valueOf(shift);
406 }
Jian Li004526d2019-02-25 16:26:27 +0900407
Jian Li140d8a22019-04-24 23:41:44 +0900408 if (B_CLASS.equals(cidrClass)) {
409 String[] strArray = shift.split("\\.");
410 int firstOctet = Integer.valueOf(strArray[0]);
411 int secondOctet = Integer.valueOf(strArray[1]);
412 return firstOctet << 8 | secondOctet;
413 }
414
415 return 0;
Jian Li004526d2019-02-25 16:26:27 +0900416 }
417
Jian Lieb488ea2019-04-16 01:50:02 +0900418 private static boolean checkTreatmentResolver(Device device) {
419 if (device == null || !device.is(ExtensionTreatmentResolver.class)) {
420 log.warn("Nicira extension treatment is not supported");
421 return false;
422 }
423
424 return true;
425 }
426
Jian Li004526d2019-02-25 16:26:27 +0900427 /**
Jian Li2cc2b632019-02-18 00:56:40 +0900428 * Builder class for OVS Connection Tracking feature actions.
429 */
430 public static final class NiciraConnTrackTreatmentBuilder {
431
432 private DriverService driverService;
433 private DeviceId deviceId;
434 private IpAddress natAddress = null;
Jian Lieb488ea2019-04-16 01:50:02 +0900435 private TpPort natPortMin = null;
436 private TpPort natPortMax = null;
Jian Li2cc2b632019-02-18 00:56:40 +0900437 private int zone;
438 private boolean commit;
439 private short table = -1;
440 private boolean natAction;
441 private int natFlag;
442
443 // private constructor
444 private NiciraConnTrackTreatmentBuilder(DriverService driverService,
445 DeviceId deviceId) {
446 this.driverService = driverService;
447 this.deviceId = deviceId;
448 }
449
450 /**
451 * Sets commit flag.
452 *
453 * @param c true if commit, false if not.
454 * @return NiciraConnTrackTreatmentBuilder object
455 */
456 public NiciraConnTrackTreatmentBuilder commit(boolean c) {
457 this.commit = c;
458 return this;
459 }
460
461 /**
462 * Sets zone number.
463 *
464 * @param z zone number
465 * @return NiciraConnTrackTreatmentBuilder object
466 */
467 public NiciraConnTrackTreatmentBuilder zone(int z) {
468 this.zone = z;
469 return this;
470 }
471
472 /**
473 * Sets recirculation table number.
474 *
475 * @param t table number to restart
476 * @return NiciraConnTrackTreatmentBuilder object
477 */
478 public NiciraConnTrackTreatmentBuilder table(short t) {
479 this.table = t;
480 return this;
481 }
482
483 /**
484 * Sets IP address for NAT.
485 *
486 * @param ip NAT IP address
487 * @return NiciraConnTrackTreatmentBuilder object
488 */
489 public NiciraConnTrackTreatmentBuilder natIp(IpAddress ip) {
490 this.natAddress = ip;
491 return this;
492 }
493
494 /**
Jian Lieb488ea2019-04-16 01:50:02 +0900495 * Sets min port for NAT.
Jian Li2cc2b632019-02-18 00:56:40 +0900496 *
497 * @param port port number
498 * @return NiciraConnTrackTreatmentBuilder object
499 */
Jian Lieb488ea2019-04-16 01:50:02 +0900500 public NiciraConnTrackTreatmentBuilder natPortMin(TpPort port) {
501 this.natPortMin = port;
502 return this;
503 }
504
505 /**
506 * Sets max port for NAT.
507 *
508 * @param port port number
509 * @return NiciraConnTrackTreatmentBuilder object
510 */
511 public NiciraConnTrackTreatmentBuilder natPortMax(TpPort port) {
512 this.natPortMax = port;
Jian Li2cc2b632019-02-18 00:56:40 +0900513 return this;
514 }
515
516 /**
517 * Sets NAT flags.
518 * SRC NAT: 1 << 0
519 * DST NAT: 1 << 1
520 * PERSISTENT NAT: 1 << 2
521 * PROTO_HASH NAT: 1 << 3
522 * PROTO_RANDOM NAT : 1 << 4
523 *
524 * @param flag flag value
525 * @return NiciraConnTrackTreatmentBuilder object
526 */
527 public NiciraConnTrackTreatmentBuilder natFlag(int flag) {
528 this.natFlag = 1 << flag;
529 return this;
530 }
531
532 /**
533 * Sets the flag for NAT action.
534 *
535 * @param nat nat action is included if true, no nat action otherwise
536 * @return NiciraConnTrackTreatmentBuilder object
537 */
538 public NiciraConnTrackTreatmentBuilder natAction(boolean nat) {
539 this.natAction = nat;
540 return this;
541 }
542
543 /**
544 * Builds extension treatment for OVS ConnTack and NAT feature.
545 *
546 * @return ExtensionTreatment object
547 */
548 public ExtensionTreatment build() {
549 DriverHandler handler = driverService.createHandler(deviceId);
550 ExtensionTreatmentResolver etr =
551 handler.behaviour(ExtensionTreatmentResolver.class);
552
553 ExtensionTreatment natTreatment = etr.getExtensionInstruction(
554 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_NAT.type());
555 try {
556
Jian Lieb488ea2019-04-16 01:50:02 +0900557 if (natAddress == null && natPortMin == null && natPortMax == null) {
558 natTreatment.setPropertyValue(CT_FLAGS, 0);
559 natTreatment.setPropertyValue(CT_PRESENT_FLAGS, 0);
560 } else {
561 natTreatment.setPropertyValue(CT_FLAGS, this.natFlag);
Jian Li2cc2b632019-02-18 00:56:40 +0900562
Jian Lieb488ea2019-04-16 01:50:02 +0900563 natTreatment.setPropertyValue(CT_PRESENT_FLAGS,
564 buildPresentFlag((natPortMin != null && natPortMax != null),
565 natAddress != null));
566 }
Jian Li2cc2b632019-02-18 00:56:40 +0900567
568 if (natAddress != null) {
569 natTreatment.setPropertyValue(CT_IPADDRESS_MIN, natAddress);
570 natTreatment.setPropertyValue(CT_IPADDRESS_MAX, natAddress);
571 }
572
Jian Lieb488ea2019-04-16 01:50:02 +0900573 if (natPortMin != null) {
574 natTreatment.setPropertyValue(CT_PORT_MIN, natPortMin.toInt());
575 }
576
577 if (natPortMax != null) {
578 natTreatment.setPropertyValue(CT_PORT_MAX, natPortMax.toInt());
Jian Li2cc2b632019-02-18 00:56:40 +0900579 }
580
581 } catch (Exception e) {
582 log.error("Failed to set NAT due to error : {}", e);
583 return null;
584 }
585
586 ExtensionTreatment ctTreatment = etr.getExtensionInstruction(
587 ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_CT.type());
588 try {
589 List<ExtensionTreatment> nat = new ArrayList<>();
590 if (natAction) {
591 nat.add(natTreatment);
592 }
593 ctTreatment.setPropertyValue(CT_FLAGS, commit ? 1 : 0);
594 ctTreatment.setPropertyValue(CT_ZONE, zone);
595 ctTreatment.setPropertyValue(CT_TABLE, table > -1 ? table : 0xff);
596 ctTreatment.setPropertyValue(CT_NESTED_ACTIONS, nat);
597 } catch (Exception e) {
598 log.error("Failed to set CT due to error : {}", e);
599 return null;
600 }
601
602 return ctTreatment;
603 }
604
605 private int buildPresentFlag(boolean isPortPresent, boolean isAddressPresent) {
606
607 int presentFlag = 0;
608
609 if (isPortPresent) {
610 presentFlag = 1 << PORT_MIN_FLAG | 1 << PORT_MAX_FLAG;
611 }
612
613 if (isAddressPresent) {
614 // TODO: need to support IPv6 address
615 presentFlag = presentFlag | 1 << ADDRESS_V4_MIN_FLAG | 1 << ADDRESS_V4_MAX_FLAG;
616 }
617
618 return presentFlag;
619 }
620 }
Jian Li4aa17642019-01-30 00:01:11 +0900621}