blob: 17705768a391407706378a6c10598bcdce0f1baf [file] [log] [blame]
Jonghwan Hyuned478dc2018-08-06 15:35:18 +09001/*
2 * Copyright 2017-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.pipelines.fabric;
17
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090018import com.google.common.collect.Sets;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090019import org.onosproject.core.ApplicationId;
20import org.onosproject.core.CoreService;
21import org.onosproject.inbandtelemetry.api.IntConfig;
22import org.onosproject.inbandtelemetry.api.IntIntent;
23import org.onosproject.inbandtelemetry.api.IntObjective;
24import org.onosproject.inbandtelemetry.api.IntProgrammable;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090025import org.onosproject.net.DeviceId;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090026import org.onosproject.net.PortNumber;
Carmelo Casconefa421582018-09-13 10:05:57 -070027import org.onosproject.net.config.NetworkConfigService;
Carmelo Cascone3977ea42019-02-28 13:43:42 -080028import org.onosproject.net.device.DeviceService;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090029import org.onosproject.net.flow.DefaultFlowRule;
30import org.onosproject.net.flow.DefaultTrafficSelector;
31import org.onosproject.net.flow.DefaultTrafficTreatment;
32import org.onosproject.net.flow.FlowRule;
33import org.onosproject.net.flow.FlowRuleService;
Carmelo Casconefa421582018-09-13 10:05:57 -070034import org.onosproject.net.flow.TableId;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090035import org.onosproject.net.flow.TrafficSelector;
36import org.onosproject.net.flow.TrafficTreatment;
37import org.onosproject.net.flow.criteria.Criterion;
38import org.onosproject.net.flow.criteria.IPCriterion;
39import org.onosproject.net.flow.criteria.PiCriterion;
40import org.onosproject.net.flow.criteria.TcpPortCriterion;
41import org.onosproject.net.flow.criteria.UdpPortCriterion;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090042import org.onosproject.net.pi.model.PiTableId;
43import org.onosproject.net.pi.runtime.PiAction;
44import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Cascone3977ea42019-02-28 13:43:42 -080045import org.osgi.service.component.annotations.Reference;
46import org.osgi.service.component.annotations.ReferenceCardinality;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090047
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090048import java.util.Set;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090049import java.util.stream.Collectors;
Carmelo Casconefa421582018-09-13 10:05:57 -070050import java.util.stream.StreamSupport;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090051
Carmelo Casconefa421582018-09-13 10:05:57 -070052import static org.onlab.util.ImmutableByteSequence.copyFrom;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090053
Carmelo Casconefa421582018-09-13 10:05:57 -070054/**
55 * Implementation of INT programmable behavior for fabric.p4. Currently supports
56 * only SOURCE and TRANSIT functionalities.
57 */
Carmelo Casconeb5324e72018-11-25 02:26:32 -080058public class FabricIntProgrammable extends AbstractFabricHandlerBehavior
59 implements IntProgrammable {
Carmelo Casconefa421582018-09-13 10:05:57 -070060
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090061 // TODO: change this value to the value of diameter of a network.
Carmelo Casconefa421582018-09-13 10:05:57 -070062 private static final int DEFAULT_PRIORITY = 10000;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090063 private static final int MAXHOP = 64;
64 private static final int PORTMASK = 0xffff;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090065 private static final int PKT_INSTANCE_TYPE_INGRESS_CLONE = 1;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090066
67 private static final Set<Criterion.Type> SUPPORTED_CRITERION = Sets.newHashSet(
68 Criterion.Type.IPV4_DST, Criterion.Type.IPV4_SRC,
69 Criterion.Type.UDP_SRC, Criterion.Type.UDP_DST,
70 Criterion.Type.TCP_SRC, Criterion.Type.TCP_DST,
71 Criterion.Type.IP_PROTO);
72
Carmelo Casconefa421582018-09-13 10:05:57 -070073 private static final Set<PiTableId> TABLES_TO_CLEANUP = Sets.newHashSet(
74 FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT,
75 FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE,
76 FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK,
77 FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE,
78 FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT
79 );
80
Ray Milkeyd84f89b2018-08-17 14:54:17 -070081 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090082 private FlowRuleService flowRuleService;
83
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090084 private CoreService coreService;
Carmelo Casconefa421582018-09-13 10:05:57 -070085 private NetworkConfigService cfgService;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090086 private DeviceId deviceId;
Carmelo Casconefa421582018-09-13 10:05:57 -070087 private ApplicationId appId;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090088
Daniele Moro77ef35c2019-07-30 10:43:10 -070089 /**
90 * Creates a new instance of this behavior with the given capabilities.
91 *
92 * @param capabilities capabilities
93 */
94 protected FabricIntProgrammable(FabricCapabilities capabilities) {
95 super(capabilities);
96 }
97
98 /**
99 * Create a new instance of this behaviour. Used by the abstract projectable
100 * model (i.e., {@link org.onosproject.net.Device#as(Class)}.
101 */
102 public FabricIntProgrammable() {
103 super();
104 }
105
Carmelo Casconefa421582018-09-13 10:05:57 -0700106 private boolean setupBehaviour() {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900107 deviceId = this.data().deviceId();
108 flowRuleService = handler().get(FlowRuleService.class);
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900109 coreService = handler().get(CoreService.class);
Carmelo Casconefa421582018-09-13 10:05:57 -0700110 cfgService = handler().get(NetworkConfigService.class);
111 appId = coreService.getAppId(PipeconfLoader.PIPELINE_APP_NAME);
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900112 if (appId == null) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700113 log.warn("Application ID is null. Cannot initialize behaviour.");
114 return false;
115 }
116 return true;
117 }
118
119 @Override
120 public boolean init() {
121
122 if (!setupBehaviour()) {
123 return false;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900124 }
125
Carmelo Cascone3977ea42019-02-28 13:43:42 -0800126 // FIXME: create config class for INT to allow specifying arbitrary
127 // switch IDs. The one for the GeneralDeviceProvider was temporary and
128 // now has been removed. For now we use the chassis ID.
129 // final GeneralProviderDeviceConfig cfg = cfgService.getConfig(
130 // deviceId, GeneralProviderDeviceConfig.class);
131 // if (cfg == null) {
132 // log.warn("Missing GeneralProviderDevice config for {}", deviceId);
133 // return false;
134 // }
135 // final String switchId = cfg.protocolsInfo().containsKey("int") ?
136 // cfg.protocolsInfo().get("int").configValues().get("switchId")
137 // : null;
138 // if (switchId == null || switchId.isEmpty()) {
139 // log.warn("Missing INT device config for {}", deviceId);
140 // return false;
141 // }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900142
Carmelo Cascone3977ea42019-02-28 13:43:42 -0800143 PiActionParam transitIdParam = new PiActionParam(
144 FabricConstants.SWITCH_ID,
145 copyFrom(handler().get(DeviceService.class)
146 .getDevice(deviceId).chassisId().id()));
Carmelo Casconefa421582018-09-13 10:05:57 -0700147
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900148 PiAction transitAction = PiAction.builder()
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700149 .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_INIT_METADATA)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900150 .withParameter(transitIdParam)
151 .build();
152 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
153 .piTableAction(transitAction)
154 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700155 TrafficSelector selector = DefaultTrafficSelector.builder()
156 .matchPi(PiCriterion.builder().matchExact(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800157 FabricConstants.HDR_INT_IS_VALID, (byte) 0x01)
Carmelo Casconefa421582018-09-13 10:05:57 -0700158 .build())
159 .build();
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900160
161 FlowRule transitFlowRule = DefaultFlowRule.builder()
Carmelo Casconefa421582018-09-13 10:05:57 -0700162 .withSelector(selector)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900163 .withTreatment(treatment)
164 .fromApp(appId)
165 .withPriority(DEFAULT_PRIORITY)
166 .makePermanent()
167 .forDevice(deviceId)
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700168 .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900169 .build();
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900170
Carmelo Casconefa421582018-09-13 10:05:57 -0700171 flowRuleService.applyFlowRules(transitFlowRule);
172 return true;
173 }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900174
Carmelo Casconefa421582018-09-13 10:05:57 -0700175 @Override
176 public boolean setSourcePort(PortNumber port) {
177
178 if (!setupBehaviour()) {
179 return false;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900180 }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900181
Carmelo Casconefa421582018-09-13 10:05:57 -0700182 PiCriterion ingressCriterion = PiCriterion.builder()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800183 .matchExact(FabricConstants.HDR_IG_PORT, port.toLong())
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900184 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700185 TrafficSelector srcSelector = DefaultTrafficSelector.builder()
186 .matchPi(ingressCriterion)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900187 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700188 PiAction setSourceAct = PiAction.builder()
189 .withId(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SOURCE)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900190 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700191 TrafficTreatment srcTreatment = DefaultTrafficTreatment.builder()
192 .piTableAction(setSourceAct)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900193 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700194 FlowRule srcFlowRule = DefaultFlowRule.builder()
195 .withSelector(srcSelector)
196 .withTreatment(srcTreatment)
197 .fromApp(appId)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900198 .withPriority(DEFAULT_PRIORITY)
199 .makePermanent()
200 .forDevice(deviceId)
Carmelo Casconefa421582018-09-13 10:05:57 -0700201 .forTable(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900202 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700203 flowRuleService.applyFlowRules(srcFlowRule);
204 return true;
205 }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900206
Carmelo Casconefa421582018-09-13 10:05:57 -0700207 @Override
208 public boolean setSinkPort(PortNumber port) {
209
210 if (!setupBehaviour()) {
211 return false;
212 }
213
214 PiCriterion egressCriterion = PiCriterion.builder()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800215 .matchExact(FabricConstants.HDR_EG_PORT, port.toLong())
Carmelo Casconefa421582018-09-13 10:05:57 -0700216 .build();
217 TrafficSelector sinkSelector = DefaultTrafficSelector.builder()
218 .matchPi(egressCriterion)
219 .build();
220 PiAction setSinkAct = PiAction.builder()
221 .withId(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SINK)
222 .build();
223 TrafficTreatment sinkTreatment = DefaultTrafficTreatment.builder()
224 .piTableAction(setSinkAct)
225 .build();
226 FlowRule sinkFlowRule = DefaultFlowRule.builder()
227 .withSelector(sinkSelector)
228 .withTreatment(sinkTreatment)
229 .fromApp(appId)
230 .withPriority(DEFAULT_PRIORITY)
231 .makePermanent()
232 .forDevice(deviceId)
233 .forTable(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK)
234 .build();
235 flowRuleService.applyFlowRules(sinkFlowRule);
236 return true;
237 }
238
239 @Override
240 public boolean addIntObjective(IntObjective obj) {
241
242 if (!setupBehaviour()) {
243 return false;
244 }
245
246 return processIntObjective(obj, true);
247 }
248
249 @Override
250 public boolean removeIntObjective(IntObjective obj) {
251
252 if (!setupBehaviour()) {
253 return false;
254 }
255
256 return processIntObjective(obj, false);
257 }
258
259 @Override
260 public boolean setupIntConfig(IntConfig config) {
261
262 if (!setupBehaviour()) {
263 return false;
264 }
265
266 return setupIntReportInternal(config);
267 }
268
269 @Override
270 public void cleanup() {
271
272 if (!setupBehaviour()) {
273 return;
274 }
275
276 StreamSupport.stream(flowRuleService.getFlowEntries(
277 data().deviceId()).spliterator(), false)
278 .filter(f -> f.table().type() == TableId.Type.PIPELINE_INDEPENDENT)
279 .filter(f -> TABLES_TO_CLEANUP.contains((PiTableId) f.table()))
280 .forEach(flowRuleService::removeFlowRules);
281 }
282
283 @Override
284 public boolean supportsFunctionality(IntFunctionality functionality) {
285 // Sink not fully supported yet.
286 return functionality == IntFunctionality.SOURCE || functionality == IntFunctionality.TRANSIT;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900287 }
288
289 private FlowRule buildWatchlistEntry(IntObjective obj) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900290 int instructionBitmap = buildInstructionBitmap(obj.metadataTypes());
291 PiActionParam maxHopParam = new PiActionParam(
292 FabricConstants.MAX_HOP,
Carmelo Casconefa421582018-09-13 10:05:57 -0700293 copyFrom(MAXHOP));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900294 PiActionParam instCntParam = new PiActionParam(
295 FabricConstants.INS_CNT,
Carmelo Casconefa421582018-09-13 10:05:57 -0700296 copyFrom(Integer.bitCount(instructionBitmap)));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900297 PiActionParam inst0003Param = new PiActionParam(
298 FabricConstants.INS_MASK0003,
Carmelo Casconefa421582018-09-13 10:05:57 -0700299 copyFrom((instructionBitmap >> 12) & 0xF));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900300 PiActionParam inst0407Param = new PiActionParam(
301 FabricConstants.INS_MASK0407,
Carmelo Casconefa421582018-09-13 10:05:57 -0700302 copyFrom((instructionBitmap >> 8) & 0xF));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900303
304 PiAction intSourceAction = PiAction.builder()
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700305 .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_INT_SOURCE_DSCP)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900306 .withParameter(maxHopParam)
307 .withParameter(instCntParam)
308 .withParameter(inst0003Param)
309 .withParameter(inst0407Param)
310 .build();
311
312 TrafficTreatment instTreatment = DefaultTrafficTreatment.builder()
313 .piTableAction(intSourceAction)
314 .build();
315
316 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
317 for (Criterion criterion : obj.selector().criteria()) {
318 switch (criterion.type()) {
319 case IPV4_SRC:
320 sBuilder.matchIPSrc(((IPCriterion) criterion).ip());
321 break;
322 case IPV4_DST:
323 sBuilder.matchIPDst(((IPCriterion) criterion).ip());
324 break;
325 case TCP_SRC:
326 sBuilder.matchPi(
327 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800328 FabricConstants.HDR_L4_SPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900329 ((TcpPortCriterion) criterion).tcpPort().toInt(), PORTMASK)
330 .build());
331 break;
332 case UDP_SRC:
333 sBuilder.matchPi(
334 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800335 FabricConstants.HDR_L4_SPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900336 ((UdpPortCriterion) criterion).udpPort().toInt(), PORTMASK)
337 .build());
338 break;
339 case TCP_DST:
340 sBuilder.matchPi(
341 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800342 FabricConstants.HDR_L4_DPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900343 ((TcpPortCriterion) criterion).tcpPort().toInt(), PORTMASK)
344 .build());
345 break;
346 case UDP_DST:
347 sBuilder.matchPi(
348 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800349 FabricConstants.HDR_L4_DPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900350 ((UdpPortCriterion) criterion).udpPort().toInt(), PORTMASK)
351 .build());
352 break;
353 default:
354 log.warn("Unsupported criterion type: {}", criterion.type());
355 }
356 }
357
358 return DefaultFlowRule.builder()
Carmelo Casconefa421582018-09-13 10:05:57 -0700359 .forDevice(deviceId)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900360 .withSelector(sBuilder.build())
361 .withTreatment(instTreatment)
362 .withPriority(DEFAULT_PRIORITY)
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700363 .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900364 .fromApp(appId)
Carmelo Casconefa421582018-09-13 10:05:57 -0700365 .makePermanent()
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900366 .build();
367 }
368
369 private int buildInstructionBitmap(Set<IntIntent.IntMetadataType> metadataTypes) {
370 int instBitmap = 0;
371 for (IntIntent.IntMetadataType metadataType : metadataTypes) {
372 switch (metadataType) {
373 case SWITCH_ID:
374 instBitmap |= (1 << 15);
375 break;
376 case L1_PORT_ID:
377 instBitmap |= (1 << 14);
378 break;
379 case HOP_LATENCY:
380 instBitmap |= (1 << 13);
381 break;
382 case QUEUE_OCCUPANCY:
383 instBitmap |= (1 << 12);
384 break;
385 case INGRESS_TIMESTAMP:
386 instBitmap |= (1 << 11);
387 break;
388 case EGRESS_TIMESTAMP:
389 instBitmap |= (1 << 10);
390 break;
391 case L2_PORT_ID:
392 instBitmap |= (1 << 9);
393 break;
394 case EGRESS_TX_UTIL:
395 instBitmap |= (1 << 8);
396 break;
397 default:
398 log.info("Unsupported metadata type {}. Ignoring...", metadataType);
399 break;
400 }
401 }
402 return instBitmap;
403 }
404
405 /**
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700406 * Returns a subset of Criterion from given selector, which is unsupported
407 * by this INT pipeline.
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900408 *
409 * @param selector a traffic selector
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700410 * @return a subset of Criterion from given selector, unsupported by this
411 * INT pipeline, empty if all criteria are supported.
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900412 */
413 private Set<Criterion> unsupportedSelectors(TrafficSelector selector) {
414 return selector.criteria().stream()
415 .filter(criterion -> !SUPPORTED_CRITERION.contains(criterion.type()))
416 .collect(Collectors.toSet());
417 }
418
419 private boolean processIntObjective(IntObjective obj, boolean install) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900420 if (install && !unsupportedSelectors(obj.selector()).isEmpty()) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700421 log.warn("Criteria {} not supported by {} for INT watchlist",
422 unsupportedSelectors(obj.selector()), deviceId);
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900423 return false;
424 }
425
426 FlowRule flowRule = buildWatchlistEntry(obj);
427 if (flowRule != null) {
428 if (install) {
429 flowRuleService.applyFlowRules(flowRule);
430 } else {
431 flowRuleService.removeFlowRules(flowRule);
432 }
433 log.debug("IntObjective {} has been {} {}",
434 obj, install ? "installed to" : "removed from", deviceId);
435 return true;
436 } else {
437 log.warn("Failed to {} IntObjective {} on {}",
438 install ? "install" : "remove", obj, deviceId);
439 return false;
440 }
441 }
442
443 private boolean setupIntReportInternal(IntConfig cfg) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700444 // Report not fully supported yet.
445 return true;
446 // FlowRule reportRule = buildReportEntry(cfg, PKT_INSTANCE_TYPE_INGRESS_CLONE);
447 // if (reportRule != null) {
448 // flowRuleService.applyFlowRules(reportRule);
449 // log.info("Report entry {} has been added to {}", reportRule, this.data().deviceId());
450 // return true;
451 // } else {
452 // log.warn("Failed to add report entry on {}", this.data().deviceId());
453 // return false;
454 // }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900455 }
456
457 private FlowRule buildReportEntry(IntConfig cfg, int type) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700458
459 if (!setupBehaviour()) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900460 return null;
461 }
462
463 PiActionParam srcMacParam = new PiActionParam(
464 FabricConstants.SRC_MAC,
Carmelo Casconefa421582018-09-13 10:05:57 -0700465 copyFrom(cfg.sinkMac().toBytes()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900466 PiActionParam nextHopMacParam = new PiActionParam(
467 FabricConstants.MON_MAC,
Carmelo Casconefa421582018-09-13 10:05:57 -0700468 copyFrom(cfg.collectorNextHopMac().toBytes()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900469 PiActionParam srcIpParam = new PiActionParam(
470 FabricConstants.SRC_IP,
Carmelo Casconefa421582018-09-13 10:05:57 -0700471 copyFrom(cfg.sinkIp().toOctets()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900472 PiActionParam monIpParam = new PiActionParam(
473 FabricConstants.MON_IP,
Carmelo Casconefa421582018-09-13 10:05:57 -0700474 copyFrom(cfg.collectorIp().toOctets()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900475 PiActionParam monPortParam = new PiActionParam(
476 FabricConstants.MON_PORT,
Carmelo Casconefa421582018-09-13 10:05:57 -0700477 copyFrom(cfg.collectorPort().toInt()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900478 PiAction reportAction = PiAction.builder()
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700479 .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_DO_REPORT_ENCAPSULATION)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900480 .withParameter(srcMacParam)
481 .withParameter(nextHopMacParam)
482 .withParameter(srcIpParam)
483 .withParameter(monIpParam)
484 .withParameter(monPortParam)
485 .build();
486 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
487 .piTableAction(reportAction)
488 .build();
489
490 return DefaultFlowRule.builder()
491 .withTreatment(treatment)
492 .fromApp(appId)
493 .withPriority(DEFAULT_PRIORITY)
494 .makePermanent()
495 .forDevice(this.data().deviceId())
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700496 .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900497 .build();
498 }
499
500}