2 * Copyright (c) 2014 NEC Corporation and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNotEquals;
13 import static org.junit.Assert.assertTrue;
15 import java.math.BigInteger;
16 import java.util.ArrayList;
17 import java.util.List;
18 import java.util.Optional;
19 import org.junit.BeforeClass;
20 import org.junit.Test;
21 import org.opendaylight.openflowplugin.api.OFConstants;
22 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.ConvertorManager;
23 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
24 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
25 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
26 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthDst;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthSrc;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.EthType;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.InPort;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OpenflowBasicClass;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.OxmMatchType;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.VlanVid;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthDstCaseBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthSrcCaseBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.EthTypeCaseBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.InPortCaseBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.VlanVidCaseBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.dst._case.EthDstBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.src._case.EthSrcBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.eth.type._case.EthTypeBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.in.port._case.InPortBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entry.value.grouping.match.entry.value.vlan.vid._case.VlanVidBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
61 * Unit test for {@link MatchConvertorImpl}.
63 public class MatchResponseConvertorTest {
64 private static final BigInteger DPID = BigInteger.TEN;
65 private static final Long IN_PORT = 6L;
66 private static final String URI_IN_PORT =
67 "openflow:" + DPID + ":" + IN_PORT;
68 private static final MacAddress MAC_SRC =
69 MacAddress.getDefaultInstance("00:11:22:33:44:55");
70 private static final MacAddress MAC_DST =
71 MacAddress.getDefaultInstance("fa:fb:fc:fd:fe:ff");
72 private static final int ETHTYPE_IPV4 = 0x800;
73 private static final short VLAN_PCP = 7;
74 private static final Ipv4Address IPV4_SRC =
75 Ipv4Address.getDefaultInstance("192.168.10.254");
76 private static final Ipv4Address IPV4_DST =
77 Ipv4Address.getDefaultInstance("10.1.2.3");
79 private static final int DL_VLAN_NONE = 0xffff;
82 public static void setUp() {
83 OpenflowPortsUtil.init();
87 * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchResponseConvertor#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchEntriesGrouping, org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData)} }.
90 public void testFromOFMatchToSALMatch() {
91 List<MatchEntry> entries = createDefaultMatchEntry();
94 // Match packet with VLAN tag regardless of its value.
97 // Match untagged frame.
100 // Match packet with VLAN tag and VID equals the specified value.
104 for (int vid : vids) {
105 List<MatchEntry> MatchEntry =
106 new ArrayList<MatchEntry>(entries);
107 MatchEntry.add(toOfVlanVid(vid));
108 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match ofMatch =
109 createOFMatch(MatchEntry);
111 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(OFConstants.OFP_VERSION_1_3);
112 data.setDatapathId(DPID);
113 final MatchBuilder builder = convert(ofMatch, data);
114 checkDefault(builder);
115 VlanMatch vlanMatch = builder.getVlanMatch();
116 int expectedVid = (vid < 0) ? 0 : vid;
117 Boolean expectedCfi = vid != 0;
118 assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
119 getValue().intValue());
120 assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
121 assertEquals(null, vlanMatch.getVlanPcp());
126 * Test method for {@link org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match.MatchV10ResponseConvertor#convert(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10, org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData)} }.
129 public void testFromOFMatchV10ToSALMatch() {
131 // Match untagged frame.
134 // Match packet with VLAN tag and VID equals the specified value.
138 0, 1, 20, 40, 62, 63,
141 FlowWildcardsV10Builder wcBuilder = new FlowWildcardsV10Builder();
142 for (int vid : vids) {
143 for (short dscp : dscps) {
144 short tos = (short) (dscp << 2);
145 MatchV10Builder builder = new MatchV10Builder();
146 builder.setDlSrc(MAC_SRC).setDlDst(MAC_DST).setDlVlan(vid).
147 setDlVlanPcp(VLAN_PCP).setDlType(ETHTYPE_IPV4).
148 setInPort(IN_PORT.intValue()).
149 setNwSrc(IPV4_SRC).setNwDst(IPV4_DST).setNwTos(tos);
150 wcBuilder.setAll(false).setNwProto(true).setTpSrc(true).
152 if (vid == DL_VLAN_NONE) {
153 wcBuilder.setDlVlanPcp(true);
156 FlowWildcardsV10 wc = wcBuilder.build();
157 MatchV10 ofMatch = builder.setWildcards(wc).build();
158 final VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(OFConstants.OFP_VERSION_1_0);
159 data.setDatapathId(DPID);
160 Match match = convert(ofMatch, data).build();
161 checkDefaultV10(match, wc, vid);
163 IpMatch ipMatch = match.getIpMatch();
164 assertEquals(null, ipMatch.getIpProtocol());
165 assertEquals(dscp, ipMatch.getIpDscp().getValue().shortValue());
166 assertEquals(null, ipMatch.getIpEcn());
168 // Set all wildcard bits.
169 wc = wcBuilder.setAll(true).build();
170 ofMatch = builder.setWildcards(wc).build();
171 match = convert(ofMatch, data).build();
172 checkDefaultV10(match, wc, vid);
173 assertEquals(null, match.getIpMatch());
178 private static void checkDefault(final MatchBuilder builder) {
179 EthernetMatch ethMatch = builder.getEthernetMatch();
180 assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
181 assertEquals(null, ethMatch.getEthernetSource().getMask());
182 assertEquals(MAC_DST, ethMatch.getEthernetDestination().getAddress());
183 assertEquals(null, ethMatch.getEthernetDestination().getMask());
184 assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
185 getValue().intValue());
187 NodeConnectorId inPort = builder.getInPort();
188 assertEquals(URI_IN_PORT, inPort.getValue());
191 private static org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match createOFMatch(final List<MatchEntry> entries) {
192 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder builder =
193 new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.MatchBuilder();
194 return builder.setType(OxmMatchType.class).setMatchEntry(entries).
198 private static List<MatchEntry> createDefaultMatchEntry() {
199 List<MatchEntry> entries = new ArrayList<>();
200 entries.add(toOfPort(InPort.class, IN_PORT));
202 MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
203 EthSrcCaseBuilder ethSrcCaseBuilder = new EthSrcCaseBuilder();
205 EthSrcBuilder ethSrcBuilder = new EthSrcBuilder();
206 ethSrcBuilder.setMacAddress(MAC_SRC);
207 ethSrcCaseBuilder.setEthSrc(ethSrcBuilder.build());
208 matchEntryBuilder.setMatchEntryValue(ethSrcCaseBuilder.build());
209 matchEntryBuilder.setOxmMatchField(EthSrc.class);
210 entries.add(matchEntryBuilder.build());
213 EthDstCaseBuilder ethDstCaseBuilder = new EthDstCaseBuilder();
214 EthDstBuilder ethDstBuilder = new EthDstBuilder();
215 ethDstBuilder.setMacAddress(MAC_DST);
216 ethDstCaseBuilder.setEthDst(ethDstBuilder.build());
217 matchEntryBuilder.setMatchEntryValue(ethDstCaseBuilder.build());
218 matchEntryBuilder.setOxmMatchField(EthDst.class);
219 entries.add(matchEntryBuilder.build());
221 entries.add(toOfEthernetType(ETHTYPE_IPV4));
225 private static MatchEntry toOfEthernetType(final int ethType) {
226 MatchEntryBuilder builder = new MatchEntryBuilder();
227 builder.setOxmClass(OpenflowBasicClass.class);
228 builder.setHasMask(false);
229 builder.setOxmMatchField(EthType.class);
230 EthTypeCaseBuilder ethTypeCaseBuilder = new EthTypeCaseBuilder();
231 EthTypeBuilder ethTypeBuilder = new EthTypeBuilder();
232 EtherType etherType = new EtherType(ethType);
233 ethTypeBuilder.setEthType(etherType);
234 ethTypeCaseBuilder.setEthType(ethTypeBuilder.build());
235 builder.setMatchEntryValue(ethTypeCaseBuilder.build());
236 return builder.build();
239 private static MatchEntry toOfPort(final Class<? extends MatchField> field,
240 final Long portNumber) {
241 MatchEntryBuilder builder = new MatchEntryBuilder();
242 builder.setOxmClass(OpenflowBasicClass.class);
243 builder.setHasMask(false);
244 builder.setOxmMatchField(field);
245 InPortCaseBuilder inPortCaseBuilder = new InPortCaseBuilder();
246 InPortBuilder portBuilder = new InPortBuilder();
247 portBuilder.setPortNumber(new PortNumber(portNumber));
248 inPortCaseBuilder.setInPort(portBuilder.build());
249 builder.setMatchEntryValue(inPortCaseBuilder.build());
250 return builder.build();
253 private static MatchEntry toOfVlanVid(final int vid) {
254 MatchEntryBuilder builder = new MatchEntryBuilder();
256 Integer vidValue = vid;
258 builder.setOxmClass(OpenflowBasicClass.class);
259 builder.setOxmMatchField(VlanVid.class);
260 VlanVidCaseBuilder vlanVidCaseBuilder = new VlanVidCaseBuilder();
262 // Match untagged frame.
264 } else if (vid < 0) {
265 // Match packet with VLAN tag regardless of its value.
266 mask = new byte[]{0x10, 0x00};
270 VlanVidBuilder vlanVidBuilder = new VlanVidBuilder();
271 vlanVidBuilder.setCfiBit(cfi);
272 vlanVidBuilder.setVlanVid(vidValue);
273 boolean hasMask = mask != null;
275 vlanVidBuilder.setMask(mask);
277 vlanVidCaseBuilder.setVlanVid(vlanVidBuilder.build());
278 builder.setHasMask(hasMask);
279 builder.setMatchEntryValue(vlanVidCaseBuilder.build());
280 return builder.build();
283 private static void checkDefaultV10(final Match match, final FlowWildcardsV10 wc, final int vid) {
284 EthernetMatch ethMatch = match.getEthernetMatch();
286 if (ethMatch != null) {
287 assertEquals(null, ethMatch.getEthernetSource());
290 assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
293 if (ethMatch != null) {
295 assertEquals(null, ethMatch.getEthernetDestination());
297 assertNotEquals(null, ethMatch.getEthernetDestination());
298 assertEquals(MAC_DST,
299 ethMatch.getEthernetDestination().getAddress());
304 if (ethMatch != null) {
305 assertEquals(null, ethMatch.getEthernetType());
307 assertEquals(null, match.getLayer3Match());
309 assert ethMatch != null;
310 assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
311 getValue().intValue());
313 Ipv4Match ipv4Match = (Ipv4Match) match.getLayer3Match();
314 assertEquals(IPV4_SRC.getValue() + "/32",
315 ipv4Match.getIpv4Source().getValue());
316 assertEquals(IPV4_DST.getValue() + "/32",
317 ipv4Match.getIpv4Destination().getValue());
320 VlanMatch vlanMatch = match.getVlanMatch();
322 assertEquals(null, vlanMatch);
326 if (vid == DL_VLAN_NONE) {
328 expectedCfi = Boolean.FALSE;
331 expectedCfi = Boolean.TRUE;
333 assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
334 getValue().intValue());
335 assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
337 if (wc.isDLVLANPCP()) {
338 assertEquals(null, vlanMatch.getVlanPcp());
340 assertEquals(VLAN_PCP,
341 vlanMatch.getVlanPcp().getValue().shortValue());
346 private MatchBuilder convert(MatchV10 match, VersionDatapathIdConvertorData data) {
347 final Optional<MatchBuilder> salMatchOptional = ConvertorManager.getInstance().convert(match, data);
349 return salMatchOptional.orElse(new MatchBuilder());
352 private MatchBuilder convert(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.grouping.Match match, VersionDatapathIdConvertorData data) {
353 final Optional<MatchBuilder> salMatchOptional = ConvertorManager.getInstance().convert(match, data);
355 return salMatchOptional.orElse(new MatchBuilder());