blob: 2da12d161a7d58f70de102812d558bced1d17907 [file] [log] [blame]
Carmelo Cascone4c289b72019-01-22 15:30:45 -08001/*
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 */
16
17package org.onosproject.p4runtime.ctl.codec;
18
19import org.onosproject.net.pi.model.PiMeterId;
20import org.onosproject.net.pi.model.PiPipeconf;
21import org.onosproject.net.pi.runtime.PiMeterBand;
22import org.onosproject.net.pi.runtime.PiMeterCellConfig;
23import org.onosproject.net.pi.runtime.PiMeterCellHandle;
24import org.onosproject.net.pi.runtime.PiMeterCellId;
25import org.onosproject.p4runtime.ctl.utils.P4InfoBrowser;
26import p4.v1.P4RuntimeOuterClass;
27
28/**
29 * Codec for P4Runtime MeterEntry.
30 */
31public final class MeterEntryCodec
32 extends AbstractEntityCodec<PiMeterCellConfig, PiMeterCellHandle,
33 P4RuntimeOuterClass.MeterEntry, Object> {
34
35 static P4RuntimeOuterClass.MeterConfig getP4Config(PiMeterCellConfig piConfig)
36 throws CodecException {
Wailok Shum96642092021-08-06 16:23:36 +080037 // A reset config has no band
38 if (piConfig.isReset()) {
39 return null;
40 }
41 // A modify config has exactly 2 bands
42 if (!piConfig.isModify()) {
43 throw new CodecException("Number of meter bands should be 2 (Modify) or 0 (Reset)");
Carmelo Cascone4c289b72019-01-22 15:30:45 -080044 }
45 final PiMeterBand[] bands = piConfig.meterBands().toArray(new PiMeterBand[0]);
46 long cir, cburst, pir, pburst;
47 // The band with bigger burst is peak if rate of them is equal.
48 if (bands[0].rate() > bands[1].rate() ||
49 (bands[0].rate() == bands[1].rate() &&
50 bands[0].burst() >= bands[1].burst())) {
51 cir = bands[1].rate();
52 cburst = bands[1].burst();
53 pir = bands[0].rate();
54 pburst = bands[0].burst();
55 } else {
56 cir = bands[0].rate();
57 cburst = bands[0].burst();
58 pir = bands[1].rate();
59 pburst = bands[1].burst();
60 }
61 return P4RuntimeOuterClass.MeterConfig.newBuilder()
62 .setCir(cir)
63 .setCburst(cburst)
64 .setPir(pir)
65 .setPburst(pburst)
66 .build();
67 }
68
69 @Override
70 protected P4RuntimeOuterClass.MeterEntry encode(
71 PiMeterCellConfig piEntity, Object ignored, PiPipeconf pipeconf,
72 P4InfoBrowser browser)
73 throws P4InfoBrowser.NotFoundException, CodecException {
74 final int meterId = browser.meters().getByName(
75 piEntity.cellId().meterId().id()).getPreamble().getId();
Wailok Shum96642092021-08-06 16:23:36 +080076 P4RuntimeOuterClass.MeterEntry.Builder builder =
77 P4RuntimeOuterClass.MeterEntry.newBuilder()
Carmelo Cascone4c289b72019-01-22 15:30:45 -080078 .setMeterId(meterId)
79 .setIndex(P4RuntimeOuterClass.Index.newBuilder()
Wailok Shum96642092021-08-06 16:23:36 +080080 .setIndex(piEntity.cellId().index()).build());
81 // We keep the config field unset if it is reset scenario
82 P4RuntimeOuterClass.MeterConfig meterConfig = getP4Config(piEntity);
83 if (meterConfig != null) {
84 builder = builder.setConfig(meterConfig);
85 }
86 return builder.build();
Carmelo Cascone4c289b72019-01-22 15:30:45 -080087 }
88
89 @Override
90 protected P4RuntimeOuterClass.MeterEntry encodeKey(
91 PiMeterCellHandle handle, Object metadata, PiPipeconf pipeconf,
92 P4InfoBrowser browser)
93 throws P4InfoBrowser.NotFoundException {
94 return keyMsgBuilder(handle.cellId(), browser).build();
95 }
96
97 @Override
98 protected P4RuntimeOuterClass.MeterEntry encodeKey(
99 PiMeterCellConfig piEntity, Object metadata, PiPipeconf pipeconf,
100 P4InfoBrowser browser)
101 throws P4InfoBrowser.NotFoundException {
102 return keyMsgBuilder(piEntity.cellId(), browser).build();
103 }
104
105 private P4RuntimeOuterClass.MeterEntry.Builder keyMsgBuilder(
106 PiMeterCellId cellId, P4InfoBrowser browser)
107 throws P4InfoBrowser.NotFoundException {
108 final int meterId = browser.meters().getByName(
109 cellId.meterId().id()).getPreamble().getId();
110 return P4RuntimeOuterClass.MeterEntry.newBuilder()
111 .setMeterId(meterId)
112 .setIndex(P4RuntimeOuterClass.Index.newBuilder()
113 .setIndex(cellId.index()).build());
114 }
115
116 @Override
117 protected PiMeterCellConfig decode(
118 P4RuntimeOuterClass.MeterEntry message, Object ignored,
119 PiPipeconf pipeconf, P4InfoBrowser browser)
120 throws P4InfoBrowser.NotFoundException {
121 final String meterName = browser.meters()
122 .getById(message.getMeterId())
123 .getPreamble()
124 .getName();
125 return PiMeterCellConfig.builder()
126 .withMeterCellId(PiMeterCellId.ofIndirect(
127 PiMeterId.of(meterName), message.getIndex().getIndex()))
128 .withMeterBand(new PiMeterBand(message.getConfig().getCir(),
129 message.getConfig().getCburst()))
130 .withMeterBand(new PiMeterBand(message.getConfig().getPir(),
131 message.getConfig().getPburst()))
132 .build();
133 }
134}