Bug 2126: Fixed bugs in MatchConvertorImpl.OfMatchToSALMatchConvertor().
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / MatchConvertorImplTest.java
1 /*
2  * Copyright (c) 2014 NEC Corporation and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;
10
11 import static org.junit.Assert.assertEquals;
12
13 import java.math.BigInteger;
14 import java.util.ArrayList;
15 import java.util.List;
16
17 import org.junit.BeforeClass;
18 import org.junit.Test;
19
20 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
21 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;
22
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntry;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntryBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntryBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthSrc;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthType;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MatchField;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;
48
49 /**
50  * Unit test for {@link MatchConvertorImpl}.
51  */
52 public class MatchConvertorImplTest {
53     private static final BigInteger  DPID = BigInteger.TEN;
54     private static final Long  IN_PORT = Long.valueOf(6);
55     private static final String  URI_IN_PORT =
56         "openflow:" + DPID + ":" + IN_PORT;
57     private static final MacAddress MAC_SRC =
58         MacAddress.getDefaultInstance("00:11:22:33:44:55");
59     private static final MacAddress MAC_DST =
60         MacAddress.getDefaultInstance("fa:fb:fc:fd:fe:ff");
61     private static final int  ETHTYPE_IPV4 = 0x800;
62
63     @BeforeClass
64     public static void setUp() {
65         OpenflowPortsUtil.init();
66     }
67
68     /**
69      * Test method for {@link MatchConvertorImpl#fromOFMatchToSALMatch(org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match, BigInteger, OpenflowVersion)}.
70      */
71     @Test
72     public void testFromOFMatchToSALMatch() {
73         List<MatchEntries> entries = createDefaultMatchEntries();
74
75         int[] vids = {
76             // Match packet with VLAN tag regardless of its value.
77             -1,
78
79             // Match untagged frame.
80             0,
81
82             // Match packet with VLAN tag and VID equals the specified value.
83             1, 20, 4095,
84         };
85
86         for (int vid: vids) {
87             List<MatchEntries> matchEntries =
88                 new ArrayList<MatchEntries>(entries);
89             matchEntries.add(toOfVlanVid(vid));
90             org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match ofMatch =
91                 createOFMatch(matchEntries);
92
93             MatchBuilder builder = MatchConvertorImpl.
94                 fromOFMatchToSALMatch(ofMatch, DPID, OpenflowVersion.OF13);
95             checkDefault(builder);
96             VlanMatch vlanMatch = builder.getVlanMatch();
97             int expectedVid = (vid < 0) ? 0 : vid;
98             Boolean expectedCfi = Boolean.valueOf(vid != 0);
99             assertEquals(expectedVid, vlanMatch.getVlanId().getVlanId().
100                          getValue().intValue());
101             assertEquals(expectedCfi, vlanMatch.getVlanId().isVlanIdPresent());
102             assertEquals(null, vlanMatch.getVlanPcp());
103         }
104     }
105
106     private void checkDefault(MatchBuilder builder) {
107         EthernetMatch ethMatch = builder.getEthernetMatch();
108         assertEquals(MAC_SRC, ethMatch.getEthernetSource().getAddress());
109         assertEquals(null, ethMatch.getEthernetSource().getMask());
110         assertEquals(MAC_DST, ethMatch.getEthernetDestination().getAddress());
111         assertEquals(null, ethMatch.getEthernetDestination().getMask());
112         assertEquals(ETHTYPE_IPV4, ethMatch.getEthernetType().getType().
113                      getValue().intValue());
114
115         NodeConnectorId inPort = builder.getInPort();
116         assertEquals(URI_IN_PORT, inPort.getValue());
117     }
118
119     private org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match createOFMatch(List<MatchEntries> entries) {
120         org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder builder =
121             new org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder();
122         return builder.setType(OxmMatchType.class).setMatchEntries(entries).
123             build();
124     }
125
126     private List<MatchEntries> createDefaultMatchEntries() {
127         List<MatchEntries> entries = new ArrayList<MatchEntries>();
128         entries.add(toOfPort(InPort.class, IN_PORT));
129         entries.add(MatchConvertorImpl.toOfMacAddress(
130                         EthSrc.class, MAC_SRC, null));
131         entries.add(MatchConvertorImpl.toOfMacAddress(
132                         EthDst.class, MAC_DST, null));
133         entries.add(toOfEthernetType(ETHTYPE_IPV4));
134         return entries;
135     }
136
137     private MatchEntries toOfEthernetType(int ethType) {
138         MatchEntriesBuilder builder = new MatchEntriesBuilder();
139         builder.setOxmClass(OpenflowBasicClass.class);
140         builder.setHasMask(false);
141         builder.setOxmMatchField(EthType.class);
142         EthTypeMatchEntryBuilder ethTypeBuilder =
143             new EthTypeMatchEntryBuilder();
144         ethTypeBuilder.setEthType(new EtherType(ethType));
145         builder.addAugmentation(EthTypeMatchEntry.class,
146                                 ethTypeBuilder.build());
147         return builder.build();
148     }
149
150     private MatchEntries toOfPort(Class<? extends MatchField> field,
151                                   Long portNumber) {
152         MatchEntriesBuilder builder = new MatchEntriesBuilder();
153         builder.setOxmClass(OpenflowBasicClass.class);
154         builder.setHasMask(false);
155         builder.setOxmMatchField(field);
156         PortNumberMatchEntryBuilder portBuilder =
157             new PortNumberMatchEntryBuilder();
158         portBuilder.setPortNumber(new PortNumber(portNumber));
159         builder.addAugmentation(PortNumberMatchEntry.class,
160                                             portBuilder.build());
161         return builder.build();
162     }
163
164     private MatchEntries toOfVlanVid(int vid) {
165         MatchEntriesBuilder builder = new MatchEntriesBuilder();
166         boolean cfi = true;
167         Integer vidValue = Integer.valueOf(vid);
168         byte[] mask = null;
169         builder.setOxmClass(OpenflowBasicClass.class);
170         builder.setOxmMatchField(VlanVid.class);
171         VlanVidMatchEntryBuilder vidBuilder = new VlanVidMatchEntryBuilder();
172         if (vid == 0) {
173             // Match untagged frame.
174             cfi = false;
175         } else if (vid < 0) {
176             // Match packet with VLAN tag regardless of its value.
177             mask = new byte[]{0x10, 0x00};
178             vidValue = Integer.valueOf(0);
179         }
180
181         vidBuilder.setCfiBit(cfi);
182         vidBuilder.setVlanVid(vidValue);
183         builder.addAugmentation(VlanVidMatchEntry.class, vidBuilder.build());
184         boolean hasMask = mask != null;
185         if (hasMask) {
186             addMaskAugmentation(builder, mask);
187         }
188         builder.setHasMask(hasMask);
189         return builder.build();
190     }
191
192     private void addMaskAugmentation(MatchEntriesBuilder builder, byte[] mask) {
193         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();
194         maskBuilder.setMask(mask);
195         builder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());
196     }
197 }