blob: 385262958c22761d707de7205161811ebb1f172d [file] [log] [blame]
Yi Tsengfa4a1c72017-11-03 10:22:38 -07001/*
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
Carmelo Cascone356ab8b2019-09-25 01:02:53 -070017package org.onosproject.pipelines.fabric.impl.behaviour;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070018
19import com.google.common.collect.ImmutableList;
20import org.junit.Before;
21import org.junit.Test;
22import org.onlab.packet.MacAddress;
Yi Tseng1b154bd2017-11-20 17:48:19 -080023import org.onlab.packet.MplsLabel;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070024import org.onlab.packet.VlanId;
25import org.onlab.util.ImmutableByteSequence;
Carmelo Cascone2388cc12021-05-26 19:30:30 +020026import org.onosproject.net.DeviceId;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070027import org.onosproject.net.PortNumber;
28import org.onosproject.net.flow.DefaultTrafficTreatment;
29import org.onosproject.net.flow.TrafficTreatment;
Carmelo Cascone2388cc12021-05-26 19:30:30 +020030import org.onosproject.net.packet.DefaultOutboundPacket;
31import org.onosproject.net.packet.OutboundPacket;
32import org.onosproject.net.pi.model.PiPacketOperationType;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070033import org.onosproject.net.pi.runtime.PiAction;
34import org.onosproject.net.pi.runtime.PiActionParam;
Carmelo Cascone2388cc12021-05-26 19:30:30 +020035import org.onosproject.net.pi.runtime.PiPacketMetadata;
36import org.onosproject.net.pi.runtime.PiPacketOperation;
Carmelo Cascone2102bfb2020-12-04 16:54:24 -080037import org.onosproject.pipelines.fabric.FabricConstants;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070038
Carmelo Cascone2388cc12021-05-26 19:30:30 +020039import java.nio.ByteBuffer;
40import java.util.Collection;
41
Daniele Morof51d0c12019-07-30 10:43:10 -070042import static org.easymock.EasyMock.createNiceMock;
43import static org.easymock.EasyMock.expect;
44import static org.easymock.EasyMock.replay;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070045import static org.junit.Assert.assertEquals;
46
47/**
48 * Test for fabric interpreter.
49 */
50public class FabricInterpreterTest {
51 private static final VlanId VLAN_100 = VlanId.vlanId("100");
52 private static final PortNumber PORT_1 = PortNumber.portNumber(1);
53 private static final MacAddress SRC_MAC = MacAddress.valueOf("00:00:00:00:00:01");
54 private static final MacAddress DST_MAC = MacAddress.valueOf("00:00:00:00:00:02");
Yi Tseng1b154bd2017-11-20 17:48:19 -080055 private static final MplsLabel MPLS_10 = MplsLabel.mplsLabel(10);
Carmelo Cascone2388cc12021-05-26 19:30:30 +020056 private static final DeviceId DEVICE_ID = DeviceId.deviceId("device:1");
57 private static final int PORT_BITWIDTH = 9;
Yi Tsengfa4a1c72017-11-03 10:22:38 -070058
59 private FabricInterpreter interpreter;
60
Daniele Morof51d0c12019-07-30 10:43:10 -070061 FabricCapabilities allCapabilities;
62
Yi Tsengfa4a1c72017-11-03 10:22:38 -070063 @Before
64 public void setup() {
Daniele Morof51d0c12019-07-30 10:43:10 -070065 allCapabilities = createNiceMock(FabricCapabilities.class);
66 expect(allCapabilities.hasHashedTable()).andReturn(true).anyTimes();
67 expect(allCapabilities.supportDoubleVlanTerm()).andReturn(true).anyTimes();
68 replay(allCapabilities);
69 interpreter = new FabricInterpreter(allCapabilities);
Yi Tsengfa4a1c72017-11-03 10:22:38 -070070 }
71
Yi Tsengfa4a1c72017-11-03 10:22:38 -070072 /* Forwarding control block */
73
74 /**
Carmelo Casconeb5324e72018-11-25 02:26:32 -080075 * Map empty treatment for routing v4 table.
Yi Tsengdf3eec52018-02-15 14:56:02 -080076 */
77 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -080078 public void testRoutingV4TreatmentEmpty() throws Exception {
Yi Tsengdf3eec52018-02-15 14:56:02 -080079 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
Carmelo Casconeb5324e72018-11-25 02:26:32 -080080 PiAction mappedAction = interpreter.mapTreatment(
81 treatment, FabricConstants.FABRIC_INGRESS_FORWARDING_ROUTING_V4);
Charles Chancf696e52018-08-16 16:25:13 -070082 PiAction expectedAction = PiAction.builder()
Charles Chancd03f072018-08-31 17:46:37 -070083 .withId(FabricConstants.FABRIC_INGRESS_FORWARDING_NOP_ROUTING_V4)
Charles Chancf696e52018-08-16 16:25:13 -070084 .build();
85 assertEquals(expectedAction, mappedAction);
Carmelo Casconeb5324e72018-11-25 02:26:32 -080086 }
Charles Chancf696e52018-08-16 16:25:13 -070087
Carmelo Casconeb5324e72018-11-25 02:26:32 -080088 /**
Wailok Shum4f51bde2021-06-11 22:48:41 +080089 * Map empty treatment to NOP for ACL table.
Carmelo Casconeb5324e72018-11-25 02:26:32 -080090 */
91 @Test
92 public void testAclTreatmentEmpty() throws Exception {
93 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
94 PiAction mappedAction = interpreter.mapTreatment(
95 treatment, FabricConstants.FABRIC_INGRESS_ACL_ACL);
96 PiAction expectedAction = PiAction.builder()
97 .withId(FabricConstants.FABRIC_INGRESS_ACL_NOP_ACL)
Charles Chancf696e52018-08-16 16:25:13 -070098 .build();
99 assertEquals(expectedAction, mappedAction);
Yi Tsengdf3eec52018-02-15 14:56:02 -0800100 }
101
Wailok Shum4f51bde2021-06-11 22:48:41 +0800102 /**
103 * Map wipeDeferred treatment to DROP for ACL table.
104 */
105 @Test
106 public void testAclTreatmentWipeDeferred() throws Exception {
107 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
108 .wipeDeferred()
109 .build();
110 PiAction mappedAction = interpreter.mapTreatment(
111 treatment, FabricConstants.FABRIC_INGRESS_ACL_ACL);
112 PiAction expectedAction = PiAction.builder()
113 .withId(FabricConstants.FABRIC_INGRESS_ACL_DROP)
114 .build();
115 assertEquals(expectedAction, mappedAction);
116 }
117
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700118 /* Next control block */
119
120 /**
121 * Map treatment to output action.
122 */
123 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800124 public void testNextTreatmentSimpleOutput() throws Exception {
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700125 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
126 .setOutput(PORT_1)
127 .build();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800128 PiAction mappedAction = interpreter.mapTreatment(
129 treatment, FabricConstants.FABRIC_INGRESS_NEXT_SIMPLE);
130 PiActionParam param = new PiActionParam(FabricConstants.PORT_NUM, PORT_1.toLong());
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700131 PiAction expectedAction = PiAction.builder()
Yi Tseng47eac892018-07-11 02:17:04 +0800132 .withId(FabricConstants.FABRIC_INGRESS_NEXT_OUTPUT_SIMPLE)
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700133 .withParameter(param)
134 .build();
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700135 assertEquals(expectedAction, mappedAction);
136 }
137
138 /**
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800139 * Map treatment for hashed table to routing v4 action.
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700140 */
141 @Test
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800142 public void testNextTreatmentHashedRoutingV4() throws Exception {
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700143 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
144 .setEthSrc(SRC_MAC)
145 .setEthDst(DST_MAC)
146 .setOutput(PORT_1)
147 .build();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800148 PiAction mappedAction = interpreter.mapTreatment(
149 treatment, FabricConstants.FABRIC_INGRESS_NEXT_HASHED);
150 PiActionParam ethSrcParam = new PiActionParam(FabricConstants.SMAC, SRC_MAC.toBytes());
151 PiActionParam ethDstParam = new PiActionParam(FabricConstants.DMAC, DST_MAC.toBytes());
152 PiActionParam portParam = new PiActionParam(FabricConstants.PORT_NUM, PORT_1.toLong());
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700153 PiAction expectedAction = PiAction.builder()
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800154 .withId(FabricConstants.FABRIC_INGRESS_NEXT_ROUTING_HASHED)
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700155 .withParameters(ImmutableList.of(ethSrcParam, ethDstParam, portParam))
156 .build();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800157 assertEquals(expectedAction, mappedAction);
158 }
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700159
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800160 /**
Wailok Shumfb7e7872021-06-18 17:30:08 +0800161 * Map treatment to set_vlan_output action.
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800162 */
163 @Test
Wailok Shumfb7e7872021-06-18 17:30:08 +0800164 public void testNextVlanTreatment() throws Exception {
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800165 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Wailok Shumfb7e7872021-06-18 17:30:08 +0800166 .setVlanId(VLAN_100)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800167 .build();
168 PiAction mappedAction = interpreter.mapTreatment(
Wailok Shumfb7e7872021-06-18 17:30:08 +0800169 treatment, FabricConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_VLAN);
170 PiActionParam vlanParam = new PiActionParam(
171 FabricConstants.VLAN_ID, VLAN_100.toShort());
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800172 PiAction expectedAction = PiAction.builder()
Wailok Shumfb7e7872021-06-18 17:30:08 +0800173 .withId(FabricConstants.FABRIC_INGRESS_PRE_NEXT_SET_VLAN)
174 .withParameter(vlanParam)
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800175 .build();
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700176 assertEquals(expectedAction, mappedAction);
177 }
178
179 /**
Wailok Shumfb7e7872021-06-18 17:30:08 +0800180 * Map treatment to set_mpls action.
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700181 */
182 @Test
Wailok Shumfb7e7872021-06-18 17:30:08 +0800183 public void testNextMplsTreatment() throws Exception {
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700184 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
Wailok Shumfb7e7872021-06-18 17:30:08 +0800185 .setMpls(MPLS_10)
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700186 .build();
Carmelo Casconeb5324e72018-11-25 02:26:32 -0800187 PiAction mappedAction = interpreter.mapTreatment(
Wailok Shumfb7e7872021-06-18 17:30:08 +0800188 treatment, FabricConstants.FABRIC_INGRESS_PRE_NEXT_NEXT_MPLS);
189 PiActionParam mplsParam = new PiActionParam(
190 FabricConstants.LABEL, MPLS_10.toInt());
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700191 PiAction expectedAction = PiAction.builder()
Wailok Shumfb7e7872021-06-18 17:30:08 +0800192 .withId(FabricConstants.FABRIC_INGRESS_PRE_NEXT_SET_MPLS_LABEL)
193 .withParameter(mplsParam)
Yi Tseng1b154bd2017-11-20 17:48:19 -0800194 .build();
195 assertEquals(expectedAction, mappedAction);
196 }
Carmelo Cascone2388cc12021-05-26 19:30:30 +0200197
198 @Test
199 public void testMapOutboundPacketWithoutForwarding()
200 throws Exception {
201 PortNumber outputPort = PortNumber.portNumber(1);
202 TrafficTreatment outputTreatment = DefaultTrafficTreatment.builder()
203 .setOutput(outputPort)
204 .build();
205 ByteBuffer data = ByteBuffer.allocate(64);
206 OutboundPacket outPkt = new DefaultOutboundPacket(DEVICE_ID, outputTreatment, data);
207 Collection<PiPacketOperation> result = interpreter.mapOutboundPacket(outPkt);
208 assertEquals(result.size(), 1);
209
210 ImmutableList.Builder<PiPacketMetadata> builder = ImmutableList.builder();
211 builder.add(PiPacketMetadata.builder()
212 .withId(FabricConstants.EGRESS_PORT)
213 .withValue(ImmutableByteSequence.copyFrom(outputPort.toLong())
214 .fit(PORT_BITWIDTH))
215 .build());
Carmelo Cascone2388cc12021-05-26 19:30:30 +0200216
217 PiPacketOperation expectedPktOp = PiPacketOperation.builder()
218 .withType(PiPacketOperationType.PACKET_OUT)
219 .withData(ImmutableByteSequence.copyFrom(data))
220 .withMetadatas(builder.build())
221 .build();
222
223 assertEquals(expectedPktOp, result.iterator().next());
224 }
225
226 @Test
227 public void testMapOutboundPacketWithForwarding()
228 throws Exception {
229 PortNumber outputPort = PortNumber.TABLE;
230 TrafficTreatment outputTreatment = DefaultTrafficTreatment.builder()
231 .setOutput(outputPort)
232 .build();
233 ByteBuffer data = ByteBuffer.allocate(64);
234 OutboundPacket outPkt = new DefaultOutboundPacket(DEVICE_ID, outputTreatment, data);
235 Collection<PiPacketOperation> result = interpreter.mapOutboundPacket(outPkt);
236 assertEquals(result.size(), 1);
237
238 ImmutableList.Builder<PiPacketMetadata> builder = ImmutableList.builder();
239 builder.add(PiPacketMetadata.builder()
Carmelo Cascone2388cc12021-05-26 19:30:30 +0200240 .withId(FabricConstants.DO_FORWARDING)
241 .withValue(ImmutableByteSequence.copyFrom(1)
242 .fit(1))
243 .build());
244
245 PiPacketOperation expectedPktOp = PiPacketOperation.builder()
246 .withType(PiPacketOperationType.PACKET_OUT)
247 .withData(ImmutableByteSequence.copyFrom(data))
248 .withMetadatas(builder.build())
249 .build();
250
251 assertEquals(expectedPktOp, result.iterator().next());
252 }
Yi Tsengfa4a1c72017-11-03 10:22:38 -0700253}