blob: 48cd4baecea12b523fd50f24bc9c7cc815348ae9 [file] [log] [blame]
Frank Wangd7e3b4b2017-09-24 13:37:54 +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 */
16
17package org.onosproject.net.pi.impl;
18
19import org.onosproject.net.Device;
20import org.onosproject.net.meter.Band;
21import org.onosproject.net.meter.Meter;
22import org.onosproject.net.pi.model.PiPipeconf;
Frank Wangd7e3b4b2017-09-24 13:37:54 +090023import org.onosproject.net.pi.runtime.PiMeterCellConfig;
24import org.onosproject.net.pi.runtime.PiMeterCellId;
25import org.onosproject.net.pi.service.PiTranslationException;
26
27import static org.onosproject.net.meter.MeterCellId.MeterCellType.PIPELINE_INDEPENDENT;
28
29/**
30 * Implementation of meter translation logic.
31 */
32final class PiMeterTranslatorImpl {
33
34 private PiMeterTranslatorImpl() {
35 // Hides constructor.
36 }
37
pierventrec0914ec2021-08-27 15:25:02 +020038 private static final int TCM_BANDS = 2;
Frank Wangd7e3b4b2017-09-24 13:37:54 +090039
40 /**
41 * Returns a PI meter config equivalent to the given meter, for the given pipeconf and device.
42 *
43 * @param meter meter
44 * @param pipeconf pipeconf
45 * @param device device
46 * @return PI meter configs
47 * @throws PiTranslationException if the meter cannot be translated
48 */
49 static PiMeterCellConfig translate(Meter meter, PiPipeconf pipeconf, Device device) throws PiTranslationException {
50
51 if (meter.meterCellId().type() != PIPELINE_INDEPENDENT) {
52 throw new PiTranslationException("PI meter cell type must be PIPELINE_INDEPENDENT!");
53 }
54
pierventrec0914ec2021-08-27 15:25:02 +020055 // In general, this check is more of P4Runtime limitation, we should do this check in the low level layer.
56 // At the same time we could extend to support other configurations (for example srTCM).
57 // TODO implement SRTCM and TRTCM helper classes to improve readability of the code.
58 // Or in future when we support other markers we can simply create two different methods.
59 if (meter.bands().size() != TCM_BANDS) {
60 throw new PiTranslationException("PI meter must have 2 bands in order to implement TCM metering!");
Frank Wangd7e3b4b2017-09-24 13:37:54 +090061 }
62
pierventrec0914ec2021-08-27 15:25:02 +020063 final Band[] bands = meter.bands().toArray(new Band[0]);
64 // Validate proper config of the TCM settings.
65 if ((bands[0].type() != Band.Type.MARK_YELLOW && bands[0].type() != Band.Type.MARK_RED) ||
66 (bands[1].type() != Band.Type.MARK_YELLOW && bands[1].type() != Band.Type.MARK_RED) ||
67 (bands[0].type() == bands[1].type())) {
68 throw new PiTranslationException("PI TCM meter must have a MARK_YELLOW band and a MARK_RED band!");
Frank Wangd7e3b4b2017-09-24 13:37:54 +090069 }
70
pierventrec0914ec2021-08-27 15:25:02 +020071 // Validate proper config of the trTCM settings
72 if (bands[0].burst() <= 0 || bands[1].burst() <= 0) {
73 throw new PiTranslationException("PI trTCM meter can not have band with burst <= 0!");
74 }
75 if (bands[0].rate() <= 0 || bands[1].rate() <= 0) {
76 throw new PiTranslationException("PI trTCM meter can not have band with rate <= 0!");
77 }
78
79 long cir, cburst, pir, pburst;
80 if (bands[0].type() == Band.Type.MARK_YELLOW) {
81 cir = bands[0].rate();
82 cburst = bands[0].burst();
83 pir = bands[1].rate();
84 pburst = bands[1].burst();
85 } else {
86 pir = bands[0].rate();
87 pburst = bands[0].burst();
88 cir = bands[1].rate();
89 cburst = bands[1].burst();
90 }
91
92 if (cir > pir) {
93 throw new PiTranslationException("PI trTCM meter must have a pir >= cir!");
94 }
95
96 return PiMeterCellConfig.builder()
97 .withCommittedBand(cir, cburst)
98 .withPeakBand(pir, pburst)
99 .withMeterCellId((PiMeterCellId) meter.meterCellId())
100 .build();
Frank Wangd7e3b4b2017-09-24 13:37:54 +0900101 }
pierventrec0914ec2021-08-27 15:25:02 +0200102
Frank Wangd7e3b4b2017-09-24 13:37:54 +0900103}