blob: 7f9e35efe06b0210e609b314f68b62504b97c6bd [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 */
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070016package org.onosproject.pipelines.fabric.impl.behaviour;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090017
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;
Carmelo Casconeb330fc72020-07-17 15:27:02 -070021import org.onosproject.net.behaviour.inbandtelemetry.IntMetadataType;
22import org.onosproject.net.behaviour.inbandtelemetry.IntDeviceConfig;
23import org.onosproject.net.behaviour.inbandtelemetry.IntObjective;
24import org.onosproject.net.behaviour.inbandtelemetry.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 Cascone2102bfb2020-12-04 16:54:24 -080045import org.onosproject.pipelines.fabric.FabricConstants;
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070046import org.onosproject.pipelines.fabric.impl.FabricPipeconfLoader;
Carmelo Cascone3977ea42019-02-28 13:43:42 -080047import org.osgi.service.component.annotations.Reference;
48import org.osgi.service.component.annotations.ReferenceCardinality;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090049
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090050import java.util.Set;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090051import java.util.stream.Collectors;
Carmelo Casconefa421582018-09-13 10:05:57 -070052import java.util.stream.StreamSupport;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090053
Carmelo Casconefa421582018-09-13 10:05:57 -070054import static org.onlab.util.ImmutableByteSequence.copyFrom;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090055
Carmelo Casconefa421582018-09-13 10:05:57 -070056/**
57 * Implementation of INT programmable behavior for fabric.p4. Currently supports
58 * only SOURCE and TRANSIT functionalities.
59 */
Carmelo Casconeb5324e72018-11-25 02:26:32 -080060public class FabricIntProgrammable extends AbstractFabricHandlerBehavior
61 implements IntProgrammable {
Carmelo Casconefa421582018-09-13 10:05:57 -070062
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090063 // TODO: change this value to the value of diameter of a network.
Carmelo Casconefa421582018-09-13 10:05:57 -070064 private static final int DEFAULT_PRIORITY = 10000;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090065 private static final int MAXHOP = 64;
66 private static final int PORTMASK = 0xffff;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090067 private static final int PKT_INSTANCE_TYPE_INGRESS_CLONE = 1;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090068
69 private static final Set<Criterion.Type> SUPPORTED_CRITERION = Sets.newHashSet(
70 Criterion.Type.IPV4_DST, Criterion.Type.IPV4_SRC,
71 Criterion.Type.UDP_SRC, Criterion.Type.UDP_DST,
72 Criterion.Type.TCP_SRC, Criterion.Type.TCP_DST,
73 Criterion.Type.IP_PROTO);
74
Carmelo Casconefa421582018-09-13 10:05:57 -070075 private static final Set<PiTableId> TABLES_TO_CLEANUP = Sets.newHashSet(
76 FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT,
77 FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE,
78 FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK,
79 FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE,
80 FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT
81 );
82
Ray Milkeyd84f89b2018-08-17 14:54:17 -070083 @Reference(cardinality = ReferenceCardinality.MANDATORY)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090084 private FlowRuleService flowRuleService;
85
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090086 private CoreService coreService;
Carmelo Casconefa421582018-09-13 10:05:57 -070087 private NetworkConfigService cfgService;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090088 private DeviceId deviceId;
Carmelo Casconefa421582018-09-13 10:05:57 -070089 private ApplicationId appId;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +090090
Daniele Morof51d0c12019-07-30 10:43:10 -070091 /**
92 * Creates a new instance of this behavior with the given capabilities.
93 *
94 * @param capabilities capabilities
95 */
96 protected FabricIntProgrammable(FabricCapabilities capabilities) {
97 super(capabilities);
98 }
99
100 /**
101 * Create a new instance of this behaviour. Used by the abstract projectable
102 * model (i.e., {@link org.onosproject.net.Device#as(Class)}.
103 */
104 public FabricIntProgrammable() {
105 super();
106 }
107
Carmelo Casconefa421582018-09-13 10:05:57 -0700108 private boolean setupBehaviour() {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900109 deviceId = this.data().deviceId();
110 flowRuleService = handler().get(FlowRuleService.class);
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900111 coreService = handler().get(CoreService.class);
Carmelo Casconefa421582018-09-13 10:05:57 -0700112 cfgService = handler().get(NetworkConfigService.class);
Carmelo Cascone356ab8b2019-09-25 01:02:53 -0700113 appId = coreService.getAppId(FabricPipeconfLoader.PIPELINE_APP_NAME);
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900114 if (appId == null) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700115 log.warn("Application ID is null. Cannot initialize behaviour.");
116 return false;
117 }
118 return true;
119 }
120
121 @Override
122 public boolean init() {
123
124 if (!setupBehaviour()) {
125 return false;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900126 }
127
Carmelo Cascone3977ea42019-02-28 13:43:42 -0800128 // FIXME: create config class for INT to allow specifying arbitrary
129 // switch IDs. The one for the GeneralDeviceProvider was temporary and
130 // now has been removed. For now we use the chassis ID.
131 // final GeneralProviderDeviceConfig cfg = cfgService.getConfig(
132 // deviceId, GeneralProviderDeviceConfig.class);
133 // if (cfg == null) {
134 // log.warn("Missing GeneralProviderDevice config for {}", deviceId);
135 // return false;
136 // }
137 // final String switchId = cfg.protocolsInfo().containsKey("int") ?
138 // cfg.protocolsInfo().get("int").configValues().get("switchId")
139 // : null;
140 // if (switchId == null || switchId.isEmpty()) {
141 // log.warn("Missing INT device config for {}", deviceId);
142 // return false;
143 // }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900144
Carmelo Cascone3977ea42019-02-28 13:43:42 -0800145 PiActionParam transitIdParam = new PiActionParam(
146 FabricConstants.SWITCH_ID,
147 copyFrom(handler().get(DeviceService.class)
148 .getDevice(deviceId).chassisId().id()));
Carmelo Casconefa421582018-09-13 10:05:57 -0700149
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900150 PiAction transitAction = PiAction.builder()
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700151 .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_INIT_METADATA)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900152 .withParameter(transitIdParam)
153 .build();
154 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
155 .piTableAction(transitAction)
156 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700157 TrafficSelector selector = DefaultTrafficSelector.builder()
158 .matchPi(PiCriterion.builder().matchExact(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800159 FabricConstants.HDR_INT_IS_VALID, (byte) 0x01)
Carmelo Casconefa421582018-09-13 10:05:57 -0700160 .build())
161 .build();
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900162
163 FlowRule transitFlowRule = DefaultFlowRule.builder()
Carmelo Casconefa421582018-09-13 10:05:57 -0700164 .withSelector(selector)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900165 .withTreatment(treatment)
166 .fromApp(appId)
167 .withPriority(DEFAULT_PRIORITY)
168 .makePermanent()
169 .forDevice(deviceId)
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700170 .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_TRANSIT_TB_INT_INSERT)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900171 .build();
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900172
Carmelo Casconefa421582018-09-13 10:05:57 -0700173 flowRuleService.applyFlowRules(transitFlowRule);
174 return true;
175 }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900176
Carmelo Casconefa421582018-09-13 10:05:57 -0700177 @Override
178 public boolean setSourcePort(PortNumber port) {
179
180 if (!setupBehaviour()) {
181 return false;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900182 }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900183
Carmelo Casconefa421582018-09-13 10:05:57 -0700184 PiCriterion ingressCriterion = PiCriterion.builder()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800185 .matchExact(FabricConstants.HDR_IG_PORT, port.toLong())
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900186 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700187 TrafficSelector srcSelector = DefaultTrafficSelector.builder()
188 .matchPi(ingressCriterion)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900189 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700190 PiAction setSourceAct = PiAction.builder()
191 .withId(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SOURCE)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900192 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700193 TrafficTreatment srcTreatment = DefaultTrafficTreatment.builder()
194 .piTableAction(setSourceAct)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900195 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700196 FlowRule srcFlowRule = DefaultFlowRule.builder()
197 .withSelector(srcSelector)
198 .withTreatment(srcTreatment)
199 .fromApp(appId)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900200 .withPriority(DEFAULT_PRIORITY)
201 .makePermanent()
202 .forDevice(deviceId)
Carmelo Casconefa421582018-09-13 10:05:57 -0700203 .forTable(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SOURCE)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900204 .build();
Carmelo Casconefa421582018-09-13 10:05:57 -0700205 flowRuleService.applyFlowRules(srcFlowRule);
206 return true;
207 }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900208
Carmelo Casconefa421582018-09-13 10:05:57 -0700209 @Override
210 public boolean setSinkPort(PortNumber port) {
211
212 if (!setupBehaviour()) {
213 return false;
214 }
215
216 PiCriterion egressCriterion = PiCriterion.builder()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800217 .matchExact(FabricConstants.HDR_EG_PORT, port.toLong())
Carmelo Casconefa421582018-09-13 10:05:57 -0700218 .build();
219 TrafficSelector sinkSelector = DefaultTrafficSelector.builder()
220 .matchPi(egressCriterion)
221 .build();
222 PiAction setSinkAct = PiAction.builder()
223 .withId(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_INT_SET_SINK)
224 .build();
225 TrafficTreatment sinkTreatment = DefaultTrafficTreatment.builder()
226 .piTableAction(setSinkAct)
227 .build();
228 FlowRule sinkFlowRule = DefaultFlowRule.builder()
229 .withSelector(sinkSelector)
230 .withTreatment(sinkTreatment)
231 .fromApp(appId)
232 .withPriority(DEFAULT_PRIORITY)
233 .makePermanent()
234 .forDevice(deviceId)
235 .forTable(FabricConstants.FABRIC_INGRESS_PROCESS_SET_SOURCE_SINK_TB_SET_SINK)
236 .build();
237 flowRuleService.applyFlowRules(sinkFlowRule);
238 return true;
239 }
240
241 @Override
242 public boolean addIntObjective(IntObjective obj) {
243
244 if (!setupBehaviour()) {
245 return false;
246 }
247
248 return processIntObjective(obj, true);
249 }
250
251 @Override
252 public boolean removeIntObjective(IntObjective obj) {
253
254 if (!setupBehaviour()) {
255 return false;
256 }
257
258 return processIntObjective(obj, false);
259 }
260
261 @Override
Carmelo Casconeb330fc72020-07-17 15:27:02 -0700262 public boolean setupIntConfig(IntDeviceConfig config) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700263
264 if (!setupBehaviour()) {
265 return false;
266 }
267
268 return setupIntReportInternal(config);
269 }
270
271 @Override
272 public void cleanup() {
273
274 if (!setupBehaviour()) {
275 return;
276 }
277
278 StreamSupport.stream(flowRuleService.getFlowEntries(
279 data().deviceId()).spliterator(), false)
280 .filter(f -> f.table().type() == TableId.Type.PIPELINE_INDEPENDENT)
281 .filter(f -> TABLES_TO_CLEANUP.contains((PiTableId) f.table()))
282 .forEach(flowRuleService::removeFlowRules);
283 }
284
285 @Override
286 public boolean supportsFunctionality(IntFunctionality functionality) {
287 // Sink not fully supported yet.
288 return functionality == IntFunctionality.SOURCE || functionality == IntFunctionality.TRANSIT;
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900289 }
290
291 private FlowRule buildWatchlistEntry(IntObjective obj) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900292 int instructionBitmap = buildInstructionBitmap(obj.metadataTypes());
293 PiActionParam maxHopParam = new PiActionParam(
294 FabricConstants.MAX_HOP,
Carmelo Casconefa421582018-09-13 10:05:57 -0700295 copyFrom(MAXHOP));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900296 PiActionParam instCntParam = new PiActionParam(
297 FabricConstants.INS_CNT,
Carmelo Casconefa421582018-09-13 10:05:57 -0700298 copyFrom(Integer.bitCount(instructionBitmap)));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900299 PiActionParam inst0003Param = new PiActionParam(
300 FabricConstants.INS_MASK0003,
Carmelo Casconefa421582018-09-13 10:05:57 -0700301 copyFrom((instructionBitmap >> 12) & 0xF));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900302 PiActionParam inst0407Param = new PiActionParam(
303 FabricConstants.INS_MASK0407,
Carmelo Casconefa421582018-09-13 10:05:57 -0700304 copyFrom((instructionBitmap >> 8) & 0xF));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900305
306 PiAction intSourceAction = PiAction.builder()
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700307 .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_INT_SOURCE_DSCP)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900308 .withParameter(maxHopParam)
309 .withParameter(instCntParam)
310 .withParameter(inst0003Param)
311 .withParameter(inst0407Param)
312 .build();
313
314 TrafficTreatment instTreatment = DefaultTrafficTreatment.builder()
315 .piTableAction(intSourceAction)
316 .build();
317
318 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
319 for (Criterion criterion : obj.selector().criteria()) {
320 switch (criterion.type()) {
321 case IPV4_SRC:
322 sBuilder.matchIPSrc(((IPCriterion) criterion).ip());
323 break;
324 case IPV4_DST:
325 sBuilder.matchIPDst(((IPCriterion) criterion).ip());
326 break;
327 case TCP_SRC:
328 sBuilder.matchPi(
329 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800330 FabricConstants.HDR_L4_SPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900331 ((TcpPortCriterion) criterion).tcpPort().toInt(), PORTMASK)
332 .build());
333 break;
334 case UDP_SRC:
335 sBuilder.matchPi(
336 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800337 FabricConstants.HDR_L4_SPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900338 ((UdpPortCriterion) criterion).udpPort().toInt(), PORTMASK)
339 .build());
340 break;
341 case TCP_DST:
342 sBuilder.matchPi(
343 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800344 FabricConstants.HDR_L4_DPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900345 ((TcpPortCriterion) criterion).tcpPort().toInt(), PORTMASK)
346 .build());
347 break;
348 case UDP_DST:
349 sBuilder.matchPi(
350 PiCriterion.builder().matchTernary(
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800351 FabricConstants.HDR_L4_DPORT,
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900352 ((UdpPortCriterion) criterion).udpPort().toInt(), PORTMASK)
353 .build());
354 break;
355 default:
356 log.warn("Unsupported criterion type: {}", criterion.type());
357 }
358 }
359
360 return DefaultFlowRule.builder()
Carmelo Casconefa421582018-09-13 10:05:57 -0700361 .forDevice(deviceId)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900362 .withSelector(sBuilder.build())
363 .withTreatment(instTreatment)
364 .withPriority(DEFAULT_PRIORITY)
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700365 .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_SOURCE_TB_INT_SOURCE)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900366 .fromApp(appId)
Carmelo Casconefa421582018-09-13 10:05:57 -0700367 .makePermanent()
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900368 .build();
369 }
370
Carmelo Casconeb330fc72020-07-17 15:27:02 -0700371 private int buildInstructionBitmap(Set<IntMetadataType> metadataTypes) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900372 int instBitmap = 0;
Carmelo Casconeb330fc72020-07-17 15:27:02 -0700373 for (IntMetadataType metadataType : metadataTypes) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900374 switch (metadataType) {
375 case SWITCH_ID:
376 instBitmap |= (1 << 15);
377 break;
378 case L1_PORT_ID:
379 instBitmap |= (1 << 14);
380 break;
381 case HOP_LATENCY:
382 instBitmap |= (1 << 13);
383 break;
384 case QUEUE_OCCUPANCY:
385 instBitmap |= (1 << 12);
386 break;
387 case INGRESS_TIMESTAMP:
388 instBitmap |= (1 << 11);
389 break;
390 case EGRESS_TIMESTAMP:
391 instBitmap |= (1 << 10);
392 break;
393 case L2_PORT_ID:
394 instBitmap |= (1 << 9);
395 break;
396 case EGRESS_TX_UTIL:
397 instBitmap |= (1 << 8);
398 break;
399 default:
400 log.info("Unsupported metadata type {}. Ignoring...", metadataType);
401 break;
402 }
403 }
404 return instBitmap;
405 }
406
407 /**
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700408 * Returns a subset of Criterion from given selector, which is unsupported
409 * by this INT pipeline.
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900410 *
411 * @param selector a traffic selector
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700412 * @return a subset of Criterion from given selector, unsupported by this
413 * INT pipeline, empty if all criteria are supported.
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900414 */
415 private Set<Criterion> unsupportedSelectors(TrafficSelector selector) {
416 return selector.criteria().stream()
417 .filter(criterion -> !SUPPORTED_CRITERION.contains(criterion.type()))
418 .collect(Collectors.toSet());
419 }
420
421 private boolean processIntObjective(IntObjective obj, boolean install) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900422 if (install && !unsupportedSelectors(obj.selector()).isEmpty()) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700423 log.warn("Criteria {} not supported by {} for INT watchlist",
424 unsupportedSelectors(obj.selector()), deviceId);
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900425 return false;
426 }
427
428 FlowRule flowRule = buildWatchlistEntry(obj);
429 if (flowRule != null) {
430 if (install) {
431 flowRuleService.applyFlowRules(flowRule);
432 } else {
433 flowRuleService.removeFlowRules(flowRule);
434 }
435 log.debug("IntObjective {} has been {} {}",
436 obj, install ? "installed to" : "removed from", deviceId);
437 return true;
438 } else {
439 log.warn("Failed to {} IntObjective {} on {}",
440 install ? "install" : "remove", obj, deviceId);
441 return false;
442 }
443 }
444
Carmelo Casconeb330fc72020-07-17 15:27:02 -0700445 private boolean setupIntReportInternal(IntDeviceConfig cfg) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700446 // Report not fully supported yet.
447 return true;
448 // FlowRule reportRule = buildReportEntry(cfg, PKT_INSTANCE_TYPE_INGRESS_CLONE);
449 // if (reportRule != null) {
450 // flowRuleService.applyFlowRules(reportRule);
451 // log.info("Report entry {} has been added to {}", reportRule, this.data().deviceId());
452 // return true;
453 // } else {
454 // log.warn("Failed to add report entry on {}", this.data().deviceId());
455 // return false;
456 // }
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900457 }
458
Carmelo Casconeb330fc72020-07-17 15:27:02 -0700459 private FlowRule buildReportEntry(IntDeviceConfig cfg, int type) {
Carmelo Casconefa421582018-09-13 10:05:57 -0700460
461 if (!setupBehaviour()) {
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900462 return null;
463 }
464
465 PiActionParam srcMacParam = new PiActionParam(
466 FabricConstants.SRC_MAC,
Carmelo Casconefa421582018-09-13 10:05:57 -0700467 copyFrom(cfg.sinkMac().toBytes()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900468 PiActionParam nextHopMacParam = new PiActionParam(
469 FabricConstants.MON_MAC,
Carmelo Casconefa421582018-09-13 10:05:57 -0700470 copyFrom(cfg.collectorNextHopMac().toBytes()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900471 PiActionParam srcIpParam = new PiActionParam(
472 FabricConstants.SRC_IP,
Carmelo Casconefa421582018-09-13 10:05:57 -0700473 copyFrom(cfg.sinkIp().toOctets()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900474 PiActionParam monIpParam = new PiActionParam(
475 FabricConstants.MON_IP,
Carmelo Casconefa421582018-09-13 10:05:57 -0700476 copyFrom(cfg.collectorIp().toOctets()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900477 PiActionParam monPortParam = new PiActionParam(
478 FabricConstants.MON_PORT,
Carmelo Casconefa421582018-09-13 10:05:57 -0700479 copyFrom(cfg.collectorPort().toInt()));
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900480 PiAction reportAction = PiAction.builder()
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700481 .withId(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_DO_REPORT_ENCAPSULATION)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900482 .withParameter(srcMacParam)
483 .withParameter(nextHopMacParam)
484 .withParameter(srcIpParam)
485 .withParameter(monIpParam)
486 .withParameter(monPortParam)
487 .build();
488 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
489 .piTableAction(reportAction)
490 .build();
491
492 return DefaultFlowRule.builder()
493 .withTreatment(treatment)
494 .fromApp(appId)
495 .withPriority(DEFAULT_PRIORITY)
496 .makePermanent()
497 .forDevice(this.data().deviceId())
Carmelo Cascone79a3a312018-08-16 17:14:43 -0700498 .forTable(FabricConstants.FABRIC_EGRESS_PROCESS_INT_MAIN_PROCESS_INT_REPORT_TB_GENERATE_REPORT)
Jonghwan Hyuned478dc2018-08-06 15:35:18 +0900499 .build();
500 }
501
502}