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;
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
17 import org.junit.BeforeClass;
18 import org.junit.Test;
20 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
21 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntry;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntryBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntryBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthSrc;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthType;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MatchField;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.v10.grouping.MatchV10Builder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
57 * Unit test for {@link MatchConvertorImpl}.
59 public class MatchConvertorImplTest {
60 private static final BigInteger DPID = BigInteger.TEN;
61 private static final Long IN_PORT = Long.valueOf(6);
62 private static final String URI_IN_PORT =
63 "openflow:" + DPID + ":" + IN_PORT;
64 private static final MacAddress MAC_SRC =
65 MacAddress.getDefaultInstance("00:11:22:33:44:55");
66 private static final MacAddress MAC_DST =
67 MacAddress.getDefaultInstance("fa:fb:fc:fd:fe:ff");
68 private static final int ETHTYPE_IPV4 = 0x800;
69 private static final short VLAN_PCP = 7;
70 private static final Ipv4Address IPV4_SRC =
71 Ipv4Address.getDefaultInstance("192.168.10.254");
72 private static final Ipv4Address IPV4_DST =
73 Ipv4Address.getDefaultInstance("10.1.2.3");
75 private static final int DL_VLAN_NONE = 0xffff;
78 public static void setUp() {
79 OpenflowPortsUtil.init();
83 * Test method for {@link MatchConvertorImpl#fromOFMatchToSALMatch(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match, BigInteger, OpenflowVersion)}.
86 public void testFromOFMatchToSALMatch() {
87 List<MatchEntries> entries = createDefaultMatchEntries();
90 // Match packet with VLAN tag regardless of its value.
93 // Match untagged frame.
96 // Match packet with VLAN tag and VID equals the specified value.
100 for (int vid: vids) {
101 List<MatchEntries> matchEntries =
102 new ArrayList<MatchEntries>(entries);
103 matchEntries.add(toOfVlanVid(vid));
104 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match ofMatch =
105 createOFMatch(matchEntries);
107 MatchBuilder builder = MatchConvertorImpl.
108 fromOFMatchToSALMatch(ofMatch, DPID, OpenflowVersion.OF13);
109 checkDefault(builder);
110 VlanMatch vlanMatch = builder.getVlanMatch();
111 int expectedVid = (vid < 0) ? 0 : vid;
112 Boolean expectedCfi = Boolean.valueOf(vid != 0);
113 assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
114 getValue().intValue());
115 assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
116 assertEquals(null, vlanMatch.getVlanPcp());
121 * Test method for {@link MatchConvertorImpl#fromOFMatchV10ToSALMatch(MatchV10, BigInteger, OpenflowVersion)}.
124 public void testFromOFMatchV10ToSALMatch() {
126 // Match untagged frame.
129 // Match packet with VLAN tag and VID equals the specified value.
133 0, 1, 20, 40, 62, 63,
136 FlowWildcardsV10Builder wcBuilder = new FlowWildcardsV10Builder();
137 for (int vid: vids) {
138 for (short dscp: dscps) {
139 short tos = (short)(dscp << 2);
140 MatchV10Builder builder = new MatchV10Builder();
141 builder.setDlSrc(MAC_SRC).setDlDst(MAC_DST).setDlVlan(vid).
142 setDlVlanPcp(VLAN_PCP).setDlType(ETHTYPE_IPV4).
143 setInPort(IN_PORT.intValue()).
144 setNwSrc(IPV4_SRC).setNwDst(IPV4_DST).setNwTos(tos);
145 wcBuilder.setAll(false).setNwProto(true).setTpSrc(true).
147 if (vid == DL_VLAN_NONE) {
148 wcBuilder.setDlVlanPcp(true);
151 FlowWildcardsV10 wc = wcBuilder.build();
152 MatchV10 ofMatch = builder.setWildcards(wc).build();
153 Match match = MatchConvertorImpl.fromOFMatchV10ToSALMatch(
154 ofMatch, DPID, OpenflowVersion.OF10);
155 checkDefaultV10(match, wc, vid);
157 IpMatch ipMatch = match.getIpMatch();
158 assertEquals(null, ipMatch.getIpProtocol());
159 assertEquals(dscp, ipMatch.getIpDscp().getValue().shortValue());
160 assertEquals(null, ipMatch.getIpEcn());
162 // Set all wildcard bits.
163 wc = wcBuilder.setAll(true).build();
164 ofMatch = builder.setWildcards(wc).build();
165 match = MatchConvertorImpl.fromOFMatchV10ToSALMatch(
166 ofMatch, DPID, OpenflowVersion.OF10);
167 checkDefaultV10(match, wc, vid);
168 assertEquals(null, match.getIpMatch());
173 private void checkDefault(MatchBuilder builder) {
174 EthernetMatch ethMatch = builder.getEthernetMatch();
175 assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
176 assertEquals(null, ethMatch.getEthernetSource().getMask());
177 assertEquals(MAC_DST, ethMatch.getEthernetDestination().getAddress());
178 assertEquals(null, ethMatch.getEthernetDestination().getMask());
179 assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
180 getValue().intValue());
182 NodeConnectorId inPort = builder.getInPort();
183 assertEquals(URI_IN_PORT, inPort.getValue());
186 private org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match createOFMatch(List<MatchEntries> entries) {
187 org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder builder =
188 new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder();
189 return builder.setType(OxmMatchType.class).setMatchEntries(entries).
193 private List<MatchEntries> createDefaultMatchEntries() {
194 List<MatchEntries> entries = new ArrayList<MatchEntries>();
195 entries.add(toOfPort(InPort.class, IN_PORT));
196 entries.add(MatchConvertorImpl.toOfMacAddress(
197 EthSrc.class, MAC_SRC, null));
198 entries.add(MatchConvertorImpl.toOfMacAddress(
199 EthDst.class, MAC_DST, null));
200 entries.add(toOfEthernetType(ETHTYPE_IPV4));
204 private MatchEntries toOfEthernetType(int ethType) {
205 MatchEntriesBuilder builder = new MatchEntriesBuilder();
206 builder.setOxmClass(OpenflowBasicClass.class);
207 builder.setHasMask(false);
208 builder.setOxmMatchField(EthType.class);
209 EthTypeMatchEntryBuilder ethTypeBuilder =
210 new EthTypeMatchEntryBuilder();
211 ethTypeBuilder.setEthType(new EtherType(ethType));
212 builder.addAugmentation(EthTypeMatchEntry.class,
213 ethTypeBuilder.build());
214 return builder.build();
217 private MatchEntries toOfPort(Class<? extends MatchField> field,
219 MatchEntriesBuilder builder = new MatchEntriesBuilder();
220 builder.setOxmClass(OpenflowBasicClass.class);
221 builder.setHasMask(false);
222 builder.setOxmMatchField(field);
223 PortNumberMatchEntryBuilder portBuilder =
224 new PortNumberMatchEntryBuilder();
225 portBuilder.setPortNumber(new PortNumber(portNumber));
226 builder.addAugmentation(PortNumberMatchEntry.class,
227 portBuilder.build());
228 return builder.build();
231 private MatchEntries toOfVlanVid(int vid) {
232 MatchEntriesBuilder builder = new MatchEntriesBuilder();
234 Integer vidValue = Integer.valueOf(vid);
236 builder.setOxmClass(OpenflowBasicClass.class);
237 builder.setOxmMatchField(VlanVid.class);
238 VlanVidMatchEntryBuilder vidBuilder = new VlanVidMatchEntryBuilder();
240 // Match untagged frame.
242 } else if (vid < 0) {
243 // Match packet with VLAN tag regardless of its value.
244 mask = new byte[]{0x10, 0x00};
245 vidValue = Integer.valueOf(0);
248 vidBuilder.setCfiBit(cfi);
249 vidBuilder.setVlanVid(vidValue);
250 builder.addAugmentation(VlanVidMatchEntry.class, vidBuilder.build());
251 boolean hasMask = mask != null;
253 addMaskAugmentation(builder, mask);
255 builder.setHasMask(hasMask);
256 return builder.build();
259 private void addMaskAugmentation(MatchEntriesBuilder builder, byte[] mask) {
260 MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
261 maskBuilder.setMask(mask);
262 builder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
265 private void checkDefaultV10(Match match, FlowWildcardsV10 wc, int vid) {
266 EthernetMatch ethMatch = match.getEthernetMatch();
267 if (wc.isDLSRC().booleanValue()) {
268 if (ethMatch != null) {
269 assertEquals(null, ethMatch.getEthernetSource());
272 assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
275 if (wc.isDLDST().booleanValue()) {
276 if (ethMatch != null) {
277 assertEquals(null, ethMatch.getEthernetDestination());
280 assertEquals(MAC_DST,
281 ethMatch.getEthernetDestination().getAddress());
284 if (wc.isDLTYPE().booleanValue()) {
285 if (ethMatch != null) {
286 assertEquals(null, ethMatch.getEthernetType());
288 assertEquals(null, match.getLayer3Match());
290 assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
291 getValue().intValue());
293 Ipv4Match ipv4Match = (Ipv4Match)match.getLayer3Match();
294 assertEquals(IPV4_SRC.getValue()+"/32",
295 ipv4Match.getIpv4Source().getValue());
296 assertEquals(IPV4_DST.getValue()+"/32",
297 ipv4Match.getIpv4Destination().getValue());
300 VlanMatch vlanMatch = match.getVlanMatch();
301 if (wc.isDLVLAN().booleanValue()) {
302 assertEquals(null, vlanMatch);
306 if (vid == DL_VLAN_NONE) {
308 expectedCfi = Boolean.FALSE;
311 expectedCfi = Boolean.TRUE;
313 assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
314 getValue().intValue());
315 assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
317 if (wc.isDLVLANPCP().booleanValue()) {
318 assertEquals(null, vlanMatch.getVlanPcp());
320 assertEquals(VLAN_PCP,
321 vlanMatch.getVlanPcp().getValue().shortValue());