65622c485fd79c082459c0c9699f476d674cd4ea
[openflowplugin.git] / openflowplugin / src / test / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / MatchConvertorImplV13Test.java
1 /*\r
2  * Copyright (c) 2014 Pantheon Technologies s.r.o. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 \r
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;\r
10 \r
11 import java.math.BigInteger;\r
12 import java.util.ArrayList;\r
13 import java.util.List;\r
14 \r
15 import org.junit.Assert;\r
16 import org.junit.Before;\r
17 import org.junit.Test;\r
18 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;\r
19 import org.opendaylight.openflowplugin.openflow.md.util.OpenflowPortsUtil;\r
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;\r
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;\r
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Address;\r
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6FlowLabel;\r
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatch;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6Match;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatch;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntry;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.BosMatchEntryBuilder;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DscpMatchEntry;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.DscpMatchEntryBuilder;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntry;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EcnMatchEntryBuilder;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntry;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.EthTypeMatchEntryBuilder;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4CodeMatchEntry;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4CodeMatchEntryBuilder;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4TypeMatchEntry;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv4TypeMatchEntryBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6CodeMatchEntry;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6CodeMatchEntryBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6TypeMatchEntry;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Icmpv6TypeMatchEntryBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntry;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv4AddressMatchEntryBuilder;\r
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntry;\r
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6AddressMatchEntryBuilder;\r
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntry;\r
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.Ipv6FlabelMatchEntryBuilder;\r
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntry;\r
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.IsidMatchEntryBuilder;\r
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntry;\r
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MacAddressMatchEntryBuilder;\r
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntry;\r
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MaskMatchEntryBuilder;\r
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntry;\r
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MetadataMatchEntryBuilder;\r
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsLabelMatchEntry;\r
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.MplsLabelMatchEntryBuilder;\r
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OpCodeMatchEntry;\r
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.OpCodeMatchEntryBuilder;\r
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntry;\r
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortMatchEntryBuilder;\r
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntry;\r
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PortNumberMatchEntryBuilder;\r
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ProtocolNumberMatchEntry;\r
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.ProtocolNumberMatchEntryBuilder;\r
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntry;\r
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.PseudoFieldMatchEntryBuilder;\r
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcMatchEntry;\r
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.TcMatchEntryBuilder;\r
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpMatchEntry;\r
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanPcpMatchEntryBuilder;\r
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntry;\r
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev131002.VlanVidMatchEntryBuilder;\r
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.EtherType;\r
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.Ipv6ExthdrFlags;\r
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.PortNumber;\r
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpOp;\r
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpSha;\r
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpSpa;\r
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpTha;\r
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.ArpTpa;\r
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthDst;\r
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthSrc;\r
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.EthType;\r
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv4Code;\r
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv4Type;\r
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv6Code;\r
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Icmpv6Type;\r
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPhyPort;\r
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.InPort;\r
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpDscp;\r
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpEcn;\r
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.IpProto;\r
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Dst;\r
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv4Src;\r
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Dst;\r
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Exthdr;\r
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Flabel;\r
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdSll;\r
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTarget;\r
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6NdTll;\r
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Ipv6Src;\r
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.Metadata;\r
109 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsBos;\r
110 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsLabel;\r
111 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.MplsTc;\r
112 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OpenflowBasicClass;\r
113 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.OxmMatchType;\r
114 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.PbbIsid;\r
115 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpDst;\r
116 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.SctpSrc;\r
117 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpDst;\r
118 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TcpSrc;\r
119 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.TunnelId;\r
120 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpDst;\r
121 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.UdpSrc;\r
122 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanPcp;\r
123 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.VlanVid;\r
124 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.Match;\r
125 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.match.grouping.MatchBuilder;\r
126 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntries;\r
127 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev130731.oxm.fields.grouping.MatchEntriesBuilder;\r
128 \r
129 /**\r
130  * @author michal.polkorab\r
131  *\r
132  */\r
133 public class MatchConvertorImplV13Test {\r
134 \r
135     /**\r
136      * Initializes OpenflowPortsUtil\r
137      */\r
138     @Before\r
139     public void startUp() {\r
140         OpenflowPortsUtil.init();\r
141     }\r
142 \r
143     /**\r
144      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
145      */\r
146     @Test(expected=NullPointerException.class)\r
147     public void testEmptyMatch() {\r
148         MatchBuilder builder = new MatchBuilder();\r
149         Match match = builder.build();\r
150 \r
151         MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF10);\r
152     }\r
153 \r
154     /**\r
155      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
156      */\r
157     @Test\r
158     public void testEmptyMatchEntries() {\r
159         MatchBuilder builder = new MatchBuilder();\r
160         builder.setType(OxmMatchType.class);\r
161         List<MatchEntries> entries = new ArrayList<>();\r
162         builder.setMatchEntries(entries);\r
163         Match match = builder.build();\r
164 \r
165         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
166         .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF10);\r
167         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build();\r
168 \r
169         Assert.assertEquals("Wrong match entries", null, builtMatch.getEthernetMatch());\r
170         Assert.assertEquals("Wrong match entries", null, builtMatch.getIcmpv4Match());\r
171         Assert.assertEquals("Wrong match entries", null, builtMatch.getIcmpv6Match());\r
172         Assert.assertEquals("Wrong match entries", null, builtMatch.getInPhyPort());\r
173         Assert.assertEquals("Wrong match entries", null, builtMatch.getInPort());\r
174         Assert.assertEquals("Wrong match entries", null, builtMatch.getIpMatch());\r
175         Assert.assertEquals("Wrong match entries", null, builtMatch.getLayer3Match());\r
176         Assert.assertEquals("Wrong match entries", null, builtMatch.getLayer4Match());\r
177         Assert.assertEquals("Wrong match entries", null, builtMatch.getMetadata());\r
178         Assert.assertEquals("Wrong match entries", null, builtMatch.getProtocolMatchFields());\r
179         Assert.assertEquals("Wrong match entries", null, builtMatch.getVlanMatch());\r
180         Assert.assertEquals("Wrong match entries", null, builtMatch.getTunnel());\r
181     }\r
182 \r
183     /**\r
184      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
185      */\r
186     @Test\r
187     public void testWithMatchEntriesNoMasks() {\r
188         MatchBuilder builder = new MatchBuilder();\r
189         builder.setType(OxmMatchType.class);\r
190         List<MatchEntries> entries = new ArrayList<>();\r
191         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
192         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
193         entriesBuilder.setOxmMatchField(InPort.class);\r
194         entriesBuilder.setHasMask(false);\r
195         PortNumberMatchEntryBuilder portNumberBuilder = new PortNumberMatchEntryBuilder();\r
196         portNumberBuilder.setPortNumber(new PortNumber(1L));\r
197         entriesBuilder.addAugmentation(PortNumberMatchEntry.class, portNumberBuilder.build());\r
198         entries.add(entriesBuilder.build());\r
199         entriesBuilder = new MatchEntriesBuilder();\r
200         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
201         entriesBuilder.setOxmMatchField(InPhyPort.class);\r
202         entriesBuilder.setHasMask(false);\r
203         portNumberBuilder = new PortNumberMatchEntryBuilder();\r
204         portNumberBuilder.setPortNumber(new PortNumber(2L));\r
205         entriesBuilder.addAugmentation(PortNumberMatchEntry.class, portNumberBuilder.build());\r
206         entries.add(entriesBuilder.build());\r
207         entriesBuilder = new MatchEntriesBuilder();\r
208         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
209         entriesBuilder.setOxmMatchField(Metadata.class);\r
210         entriesBuilder.setHasMask(false);\r
211         MetadataMatchEntryBuilder metadataBuilder = new MetadataMatchEntryBuilder();\r
212         metadataBuilder.setMetadata(new byte[]{0, 1, 2, 3, 4, 5, 6, 7});\r
213         entriesBuilder.addAugmentation(MetadataMatchEntry.class, metadataBuilder.build());\r
214         entries.add(entriesBuilder.build());\r
215         entriesBuilder = new MatchEntriesBuilder();\r
216         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
217         entriesBuilder.setOxmMatchField(EthDst.class);\r
218         entriesBuilder.setHasMask(false);\r
219         MacAddressMatchEntryBuilder macAddressBuilder = new MacAddressMatchEntryBuilder();\r
220         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:01"));\r
221         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
222         entries.add(entriesBuilder.build());\r
223         entriesBuilder = new MatchEntriesBuilder();\r
224         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
225         entriesBuilder.setOxmMatchField(EthSrc.class);\r
226         entriesBuilder.setHasMask(false);\r
227         macAddressBuilder = new MacAddressMatchEntryBuilder();\r
228         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:02"));\r
229         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
230         entries.add(entriesBuilder.build());\r
231         entriesBuilder = new MatchEntriesBuilder();\r
232         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
233         entriesBuilder.setOxmMatchField(EthType.class);\r
234         entriesBuilder.setHasMask(false);\r
235         EthTypeMatchEntryBuilder ethTypeBuilder = new EthTypeMatchEntryBuilder();\r
236         ethTypeBuilder.setEthType(new EtherType(3));\r
237         entriesBuilder.addAugmentation(EthTypeMatchEntry.class, ethTypeBuilder.build());\r
238         entries.add(entriesBuilder.build());\r
239         entriesBuilder = new MatchEntriesBuilder();\r
240         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
241         entriesBuilder.setOxmMatchField(VlanVid.class);\r
242         entriesBuilder.setHasMask(false);\r
243         VlanVidMatchEntryBuilder vlanVidBuilder = new VlanVidMatchEntryBuilder();\r
244         vlanVidBuilder.setVlanVid(4);\r
245         vlanVidBuilder.setCfiBit(true);\r
246         entriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanVidBuilder.build());\r
247         entries.add(entriesBuilder.build());\r
248         entriesBuilder = new MatchEntriesBuilder();\r
249         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
250         entriesBuilder.setOxmMatchField(VlanPcp.class);\r
251         entriesBuilder.setHasMask(false);\r
252         VlanPcpMatchEntryBuilder pcpBuilder = new VlanPcpMatchEntryBuilder();\r
253         pcpBuilder.setVlanPcp((short) 5);\r
254         entriesBuilder.addAugmentation(VlanPcpMatchEntry.class, pcpBuilder.build());\r
255         entries.add(entriesBuilder.build());\r
256         entriesBuilder = new MatchEntriesBuilder();\r
257         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
258         entriesBuilder.setOxmMatchField(IpDscp.class);\r
259         entriesBuilder.setHasMask(false);\r
260         DscpMatchEntryBuilder dscpBuilder = new DscpMatchEntryBuilder();\r
261         dscpBuilder.setDscp(new Dscp((short) 6));\r
262         entriesBuilder.addAugmentation(DscpMatchEntry.class, dscpBuilder.build());\r
263         entries.add(entriesBuilder.build());\r
264         entriesBuilder = new MatchEntriesBuilder();\r
265         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
266         entriesBuilder.setOxmMatchField(IpEcn.class);\r
267         entriesBuilder.setHasMask(false);\r
268         EcnMatchEntryBuilder ecnBuilder = new EcnMatchEntryBuilder();\r
269         ecnBuilder.setEcn((short) 7);\r
270         entriesBuilder.addAugmentation(EcnMatchEntry.class, ecnBuilder.build());\r
271         entries.add(entriesBuilder.build());\r
272         entriesBuilder = new MatchEntriesBuilder();\r
273         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
274         entriesBuilder.setOxmMatchField(IpProto.class);\r
275         entriesBuilder.setHasMask(false);\r
276         ProtocolNumberMatchEntryBuilder protoBuilder =  new ProtocolNumberMatchEntryBuilder();\r
277         protoBuilder.setProtocolNumber((short) 8);\r
278         entriesBuilder.addAugmentation(ProtocolNumberMatchEntry.class, protoBuilder.build());\r
279         entries.add(entriesBuilder.build());\r
280         entriesBuilder = new MatchEntriesBuilder();\r
281         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
282         entriesBuilder.setOxmMatchField(Ipv4Src.class);\r
283         entriesBuilder.setHasMask(false);\r
284         Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
285         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.1"));\r
286         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
287         entries.add(entriesBuilder.build());\r
288         entriesBuilder = new MatchEntriesBuilder();\r
289         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
290         entriesBuilder.setOxmMatchField(Ipv4Dst.class);\r
291         entriesBuilder.setHasMask(false);\r
292         ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
293         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.2"));\r
294         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
295         entries.add(entriesBuilder.build());\r
296         entriesBuilder = new MatchEntriesBuilder();\r
297         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
298         entriesBuilder.setOxmMatchField(TcpSrc.class);\r
299         entriesBuilder.setHasMask(false);\r
300         PortMatchEntryBuilder portBuilder = new PortMatchEntryBuilder();\r
301         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf\r
302                 .inet.types.rev100924.PortNumber(9));\r
303         entriesBuilder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
304         entries.add(entriesBuilder.build());\r
305         entriesBuilder = new MatchEntriesBuilder();\r
306         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
307         entriesBuilder.setOxmMatchField(TcpDst.class);\r
308         entriesBuilder.setHasMask(false);\r
309         portBuilder = new PortMatchEntryBuilder();\r
310         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf\r
311                 .inet.types.rev100924.PortNumber(10));\r
312         entriesBuilder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
313         entries.add(entriesBuilder.build());\r
314         entriesBuilder = new MatchEntriesBuilder();\r
315         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
316         entriesBuilder.setOxmMatchField(Icmpv4Type.class);\r
317         entriesBuilder.setHasMask(false);\r
318         Icmpv4TypeMatchEntryBuilder icmpv4TypeBuilder = new Icmpv4TypeMatchEntryBuilder();\r
319         icmpv4TypeBuilder.setIcmpv4Type((short) 15);\r
320         entriesBuilder.addAugmentation(Icmpv4TypeMatchEntry.class, icmpv4TypeBuilder.build());\r
321         entries.add(entriesBuilder.build());\r
322         entriesBuilder = new MatchEntriesBuilder();\r
323         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
324         entriesBuilder.setOxmMatchField(Icmpv4Code.class);\r
325         entriesBuilder.setHasMask(false);\r
326         Icmpv4CodeMatchEntryBuilder icmpv4CodeBuilder = new Icmpv4CodeMatchEntryBuilder();\r
327         icmpv4CodeBuilder.setIcmpv4Code((short) 16);\r
328         entriesBuilder.addAugmentation(Icmpv4CodeMatchEntry.class, icmpv4CodeBuilder.build());\r
329         entries.add(entriesBuilder.build());\r
330         entriesBuilder = new MatchEntriesBuilder();\r
331         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
332         entriesBuilder.setOxmMatchField(Icmpv6Type.class);\r
333         entriesBuilder.setHasMask(false);\r
334         Icmpv6TypeMatchEntryBuilder icmpv6TypeBuilder = new Icmpv6TypeMatchEntryBuilder();\r
335         icmpv6TypeBuilder.setIcmpv6Type((short) 19);\r
336         entriesBuilder.addAugmentation(Icmpv6TypeMatchEntry.class, icmpv6TypeBuilder.build());\r
337         entries.add(entriesBuilder.build());\r
338         entriesBuilder = new MatchEntriesBuilder();\r
339         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
340         entriesBuilder.setOxmMatchField(Icmpv6Code.class);\r
341         entriesBuilder.setHasMask(false);\r
342         Icmpv6CodeMatchEntryBuilder icmpv6CodeBuilder = new Icmpv6CodeMatchEntryBuilder();\r
343         icmpv6CodeBuilder.setIcmpv6Code((short) 20);\r
344         entriesBuilder.addAugmentation(Icmpv6CodeMatchEntry.class, icmpv6CodeBuilder.build());\r
345         entries.add(entriesBuilder.build());\r
346         entriesBuilder = new MatchEntriesBuilder();\r
347         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
348         entriesBuilder.setOxmMatchField(MplsLabel.class);\r
349         entriesBuilder.setHasMask(false);\r
350         MplsLabelMatchEntryBuilder mplsLabelBuilder = new MplsLabelMatchEntryBuilder();\r
351         mplsLabelBuilder.setMplsLabel(21L);\r
352         entriesBuilder.addAugmentation(MplsLabelMatchEntry.class, mplsLabelBuilder.build());\r
353         entries.add(entriesBuilder.build());\r
354         entriesBuilder = new MatchEntriesBuilder();\r
355         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
356         entriesBuilder.setOxmMatchField(MplsTc.class);\r
357         entriesBuilder.setHasMask(false);\r
358         TcMatchEntryBuilder tcBuilder = new TcMatchEntryBuilder();\r
359         tcBuilder.setTc((short) 22);\r
360         entriesBuilder.addAugmentation(TcMatchEntry.class, tcBuilder.build());\r
361         entries.add(entriesBuilder.build());\r
362         entriesBuilder = new MatchEntriesBuilder();\r
363         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
364         entriesBuilder.setOxmMatchField(MplsBos.class);\r
365         entriesBuilder.setHasMask(false);\r
366         BosMatchEntryBuilder bosBuilder = new BosMatchEntryBuilder();\r
367         bosBuilder.setBos(true);\r
368         entriesBuilder.addAugmentation(BosMatchEntry.class, bosBuilder.build());\r
369         entries.add(entriesBuilder.build());\r
370         entriesBuilder = new MatchEntriesBuilder();\r
371         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
372         entriesBuilder.setOxmMatchField(PbbIsid.class);\r
373         entriesBuilder.setHasMask(false);\r
374         IsidMatchEntryBuilder isidBuilder = new IsidMatchEntryBuilder();\r
375         isidBuilder.setIsid(23L);\r
376         entriesBuilder.addAugmentation(IsidMatchEntry.class, isidBuilder.build());\r
377         entries.add(entriesBuilder.build());\r
378         entriesBuilder = new MatchEntriesBuilder();\r
379         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
380         entriesBuilder.setOxmMatchField(TunnelId.class);\r
381         entriesBuilder.setHasMask(false);\r
382         metadataBuilder = new MetadataMatchEntryBuilder();\r
383         metadataBuilder.setMetadata(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});\r
384         entriesBuilder.addAugmentation(MetadataMatchEntry.class, metadataBuilder.build());\r
385         entries.add(entriesBuilder.build());\r
386         builder.setMatchEntries(entries);\r
387         Match match = builder.build();\r
388 \r
389         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
390         .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF10);\r
391         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build();\r
392 \r
393         Assert.assertEquals("Wrong in port", "openflow:42:1", builtMatch.getInPort().getValue());\r
394         Assert.assertEquals("Wrong in phy port", "openflow:42:2", builtMatch.getInPhyPort().getValue());\r
395         Assert.assertEquals("Wrong metadata", new BigInteger(1, new byte[]{0, 1, 2, 3, 4, 5, 6, 7}), builtMatch.getMetadata().getMetadata());\r
396         Assert.assertEquals("Wrong eth dst", new MacAddress("00:00:00:00:00:01"), builtMatch.getEthernetMatch().getEthernetDestination().getAddress());\r
397         Assert.assertEquals("Wrong eth src", new MacAddress("00:00:00:00:00:02"), builtMatch.getEthernetMatch().getEthernetSource().getAddress());\r
398         Assert.assertEquals("Wrong eth type", 3, builtMatch.getEthernetMatch().getEthernetType().getType().getValue().intValue());\r
399         Assert.assertEquals("Wrong vlan id", 4, builtMatch.getVlanMatch().getVlanId().getVlanId().getValue().intValue());\r
400         // TODO - finish implementation by setting the vlanIdPresent flag\r
401 //        Assert.assertEquals("Wrong vlan id entries", true, builtMatch.getVlanMatch().getVlanId().isVlanIdPresent());\r
402         Assert.assertEquals("Wrong vlan pcp", 5, builtMatch.getVlanMatch().getVlanPcp().getValue().intValue());\r
403         Assert.assertEquals("Wrong ip dscp", 6, builtMatch.getIpMatch().getIpDscp().getValue().intValue());\r
404         Assert.assertEquals("Wrong ip ecn", 7, builtMatch.getIpMatch().getIpEcn().intValue());\r
405         Assert.assertEquals("Wrong ip proto", null, builtMatch.getIpMatch().getIpProto());\r
406         Assert.assertEquals("Wrong ip protocol", 8, builtMatch.getIpMatch().getIpProtocol().intValue());\r
407         TcpMatch tcpMatch = (TcpMatch) builtMatch.getLayer4Match();\r
408         Assert.assertEquals("Wrong tcp src port", 9, tcpMatch.getTcpSourcePort().getValue().intValue());\r
409         Assert.assertEquals("Wrong tcp dst port", 10, tcpMatch.getTcpDestinationPort().getValue().intValue());\r
410         Assert.assertEquals("Wrong icmpv4 type", 15, builtMatch.getIcmpv4Match().getIcmpv4Type().intValue());\r
411         Assert.assertEquals("Wrong icmpv4 code", 16, builtMatch.getIcmpv4Match().getIcmpv4Code().intValue());\r
412         Assert.assertEquals("Wrong icmpv6 type", 19, builtMatch.getIcmpv6Match().getIcmpv6Type().intValue());\r
413         Assert.assertEquals("Wrong icmpv6 code", 20, builtMatch.getIcmpv6Match().getIcmpv6Code().intValue());\r
414         Ipv4Match ipv4Match = (Ipv4Match) builtMatch.getLayer3Match();\r
415         Assert.assertEquals("Wrong ipv4 src address", "10.0.0.1/32", ipv4Match.getIpv4Source().getValue());\r
416         Assert.assertEquals("Wrong ipv4 dst address", "10.0.0.2/32", ipv4Match.getIpv4Destination().getValue());\r
417         Assert.assertEquals("Wrong mpls label", 21, builtMatch.getProtocolMatchFields().getMplsLabel().intValue());\r
418         Assert.assertEquals("Wrong mpls bos", 1, builtMatch.getProtocolMatchFields().getMplsBos().intValue());\r
419         Assert.assertEquals("Wrong mpls tc", 22, builtMatch.getProtocolMatchFields().getMplsTc().intValue());\r
420         Assert.assertEquals("Wrong pbb isid", 23, builtMatch.getProtocolMatchFields().getPbb().getPbbIsid().intValue());\r
421         Assert.assertEquals("Wrong tunnel id", new BigInteger(1, new byte[]{1, 2, 3, 4, 5, 6, 7, 8}),\r
422                 builtMatch.getTunnel().getTunnelId());\r
423     }\r
424 \r
425     /**\r
426      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
427      */\r
428     @Test\r
429     public void testWithMatchEntriesWithMasks() {\r
430         MatchBuilder builder = new MatchBuilder();\r
431         builder.setType(OxmMatchType.class);\r
432         List<MatchEntries> entries = new ArrayList<>();\r
433         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
434         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
435         entriesBuilder.setOxmMatchField(Metadata.class);\r
436         entriesBuilder.setHasMask(true);\r
437         MetadataMatchEntryBuilder metadataBuilder = new MetadataMatchEntryBuilder();\r
438         metadataBuilder.setMetadata(new byte[]{0, 1, 2, 3, 4, 5, 6, 7});\r
439         entriesBuilder.addAugmentation(MetadataMatchEntry.class, metadataBuilder.build());\r
440         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();\r
441         maskBuilder.setMask(new byte[]{0, 0, 0, 0, 0, 0, 0, 1});\r
442         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
443         entries.add(entriesBuilder.build());\r
444         entriesBuilder = new MatchEntriesBuilder();\r
445         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
446         entriesBuilder.setOxmMatchField(EthDst.class);\r
447         entriesBuilder.setHasMask(true);\r
448         MacAddressMatchEntryBuilder macAddressBuilder = new MacAddressMatchEntryBuilder();\r
449         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:01"));\r
450         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
451         maskBuilder = new MaskMatchEntryBuilder();\r
452         maskBuilder.setMask(new byte[]{0, 0, 0, 0, 0, 2});\r
453         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
454         entries.add(entriesBuilder.build());\r
455         entriesBuilder = new MatchEntriesBuilder();\r
456         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
457         entriesBuilder.setOxmMatchField(EthSrc.class);\r
458         entriesBuilder.setHasMask(true);\r
459         macAddressBuilder = new MacAddressMatchEntryBuilder();\r
460         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:02"));\r
461         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
462         maskBuilder = new MaskMatchEntryBuilder();\r
463         maskBuilder.setMask(new byte[]{0, 0, 0, 0, 0, 3});\r
464         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
465         entries.add(entriesBuilder.build());\r
466         entriesBuilder = new MatchEntriesBuilder();\r
467         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
468         entriesBuilder.setOxmMatchField(VlanVid.class);\r
469         entriesBuilder.setHasMask(true);\r
470         VlanVidMatchEntryBuilder vlanVidBuilder = new VlanVidMatchEntryBuilder();\r
471         vlanVidBuilder.setVlanVid(4);\r
472         vlanVidBuilder.setCfiBit(true);\r
473         entriesBuilder.addAugmentation(VlanVidMatchEntry.class, vlanVidBuilder.build());\r
474         maskBuilder = new MaskMatchEntryBuilder();\r
475         maskBuilder.setMask(new byte[]{0, 4});\r
476         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
477         entries.add(entriesBuilder.build());\r
478         entriesBuilder = new MatchEntriesBuilder();\r
479         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
480         entriesBuilder.setOxmMatchField(Ipv4Src.class);\r
481         entriesBuilder.setHasMask(true);\r
482         Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
483         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.1"));\r
484         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
485         maskBuilder = new MaskMatchEntryBuilder();\r
486         maskBuilder.setMask(new byte[]{(byte) 255, (byte) 255, (byte) 255, 0});\r
487         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
488         entries.add(entriesBuilder.build());\r
489         entriesBuilder = new MatchEntriesBuilder();\r
490         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
491         entriesBuilder.setOxmMatchField(Ipv4Dst.class);\r
492         entriesBuilder.setHasMask(true);\r
493         ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
494         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.2"));\r
495         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
496         maskBuilder = new MaskMatchEntryBuilder();\r
497         maskBuilder.setMask(new byte[]{(byte) 255, (byte) 255, (byte) 240, 0});\r
498         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
499         entries.add(entriesBuilder.build());\r
500         // FIXME - PbbIsid should check for mask length of 3 instead of 2\r
501 //        entriesBuilder = new MatchEntriesBuilder();\r
502 //        entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
503 //        entriesBuilder.setOxmMatchField(PbbIsid.class);\r
504 //        entriesBuilder.setHasMask(true);\r
505 //        IsidMatchEntryBuilder isidBuilder = new IsidMatchEntryBuilder();\r
506 //        isidBuilder.setIsid(23L);\r
507 //        entriesBuilder.addAugmentation(IsidMatchEntry.class, isidBuilder.build());\r
508 //        maskBuilder = new MaskMatchEntryBuilder();\r
509 //        maskBuilder.setMask(new byte[]{0, 0, 7});\r
510 //        entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
511 //        entries.add(entriesBuilder.build());\r
512         entriesBuilder = new MatchEntriesBuilder();\r
513         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
514         entriesBuilder.setOxmMatchField(TunnelId.class);\r
515         entriesBuilder.setHasMask(true);\r
516         metadataBuilder = new MetadataMatchEntryBuilder();\r
517         metadataBuilder.setMetadata(new byte[]{1, 2, 3, 4, 5, 6, 7, 8});\r
518         entriesBuilder.addAugmentation(MetadataMatchEntry.class, metadataBuilder.build());\r
519         maskBuilder = new MaskMatchEntryBuilder();\r
520         maskBuilder.setMask(new byte[]{0, 0, 0, 0, 0, 0, 0, 8});\r
521         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
522         entries.add(entriesBuilder.build());\r
523         builder.setMatchEntries(entries);\r
524         Match match = builder.build();\r
525 \r
526         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
527         .MatchBuilder salMatch = MatchConvertorImpl.fromOFMatchToSALMatch(match, new BigInteger("42"), OpenflowVersion.OF10);\r
528         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatch.build();\r
529 \r
530         Assert.assertEquals("Wrong metadata", new BigInteger(1, new byte[]{0, 1, 2, 3, 4, 5, 6, 7}), builtMatch.getMetadata().getMetadata());\r
531         Assert.assertEquals("Wrong metadata mask", new BigInteger(1, new byte[]{0, 0, 0, 0, 0, 0, 0, 1}),\r
532                 builtMatch.getMetadata().getMetadataMask());\r
533         Assert.assertEquals("Wrong eth dst", new MacAddress("00:00:00:00:00:01"), builtMatch.getEthernetMatch().getEthernetDestination().getAddress());\r
534 //        Assert.assertEquals("Wrong eth dst mask", new MacAddress("00:00:00:00:00:01"), builtMatch.getEthernetMatch().getEthernetDestination().getMask());\r
535         Assert.assertEquals("Wrong eth src", new MacAddress("00:00:00:00:00:02"), builtMatch.getEthernetMatch().getEthernetSource().getAddress());\r
536 //        Assert.assertEquals("Wrong eth src mask", new MacAddress("00:00:00:00:00:03"), builtMatch.getEthernetMatch().getEthernetSource().getMask());\r
537         Assert.assertEquals("Wrong vlan id", 4, builtMatch.getVlanMatch().getVlanId().getVlanId().getValue().intValue());\r
538         // TODO - finish implementation by setting the vlanIdPresent flag\r
539 //        Assert.assertEquals("Wrong vlan id entries", true, builtMatch.getVlanMatch().getVlanId().isVlanIdPresent());\r
540         Ipv4Match ipv4Match = (Ipv4Match) builtMatch.getLayer3Match();\r
541         Assert.assertEquals("Wrong ipv4 src address", "10.0.0.1/24", ipv4Match.getIpv4Source().getValue());\r
542         Assert.assertEquals("Wrong ipv4 dst address", "10.0.0.2/20", ipv4Match.getIpv4Destination().getValue());\r
543 //        Assert.assertEquals("Wrong pbb isid", 23, builtMatch.getProtocolMatchFields().getPbb().getPbbIsid().intValue());\r
544         Assert.assertEquals("Wrong tunnel id", new BigInteger(1, new byte[]{1, 2, 3, 4, 5, 6, 7, 8}),\r
545                 builtMatch.getTunnel().getTunnelId());\r
546     }\r
547 \r
548     /**\r
549      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
550      */\r
551     @Test\r
552     public void testLayer4MatchUdp() {\r
553         MatchBuilder builder = new MatchBuilder();\r
554         builder.setType(OxmMatchType.class);\r
555         List<MatchEntries> entries = new ArrayList<>();\r
556         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
557         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
558         entriesBuilder.setOxmMatchField(UdpSrc.class);\r
559         entriesBuilder.setHasMask(false);\r
560         PortMatchEntryBuilder portBuilder = new PortMatchEntryBuilder();\r
561         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf\r
562                 .inet.types.rev100924.PortNumber(11));\r
563         entriesBuilder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
564         entries.add(entriesBuilder.build());\r
565         entriesBuilder = new MatchEntriesBuilder();\r
566         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
567         entriesBuilder.setOxmMatchField(UdpDst.class);\r
568         entriesBuilder.setHasMask(false);\r
569         portBuilder = new PortMatchEntryBuilder();\r
570         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf\r
571                 .inet.types.rev100924.PortNumber(12));\r
572         entriesBuilder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
573         entries.add(entriesBuilder.build());\r
574         builder.setMatchEntries(entries);\r
575         \r
576         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
577         .MatchBuilder builtMatch = MatchConvertorImpl.fromOFMatchToSALMatch(builder.build(), new BigInteger("42"), OpenflowVersion.OF13);\r
578         \r
579         UdpMatch udpMatch = (UdpMatch) builtMatch.getLayer4Match();\r
580         Assert.assertEquals("Wrong udp src port", 11, udpMatch.getUdpSourcePort().getValue().intValue());\r
581         Assert.assertEquals("Wrong udp dst port", 12, udpMatch.getUdpDestinationPort().getValue().intValue());\r
582     }\r
583 \r
584     /**\r
585      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
586      */\r
587     @Test\r
588     public void testLayer4MatchSctp() {\r
589         MatchBuilder builder = new MatchBuilder();\r
590         builder.setType(OxmMatchType.class);\r
591         List<MatchEntries> entries = new ArrayList<>();\r
592         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
593         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
594         entriesBuilder.setOxmMatchField(SctpSrc.class);\r
595         entriesBuilder.setHasMask(false);\r
596         PortMatchEntryBuilder portBuilder = new PortMatchEntryBuilder();\r
597         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf\r
598                 .inet.types.rev100924.PortNumber(13));\r
599         entriesBuilder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
600         entries.add(entriesBuilder.build());\r
601         entriesBuilder = new MatchEntriesBuilder();\r
602         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
603         entriesBuilder.setOxmMatchField(SctpDst.class);\r
604         entriesBuilder.setHasMask(false);\r
605         portBuilder = new PortMatchEntryBuilder();\r
606         portBuilder.setPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf\r
607                 .inet.types.rev100924.PortNumber(14));\r
608         entriesBuilder.addAugmentation(PortMatchEntry.class, portBuilder.build());\r
609         entries.add(entriesBuilder.build());\r
610         entries.add(entriesBuilder.build());\r
611         builder.setMatchEntries(entries);\r
612         \r
613         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
614         .MatchBuilder salMatchBuilder = MatchConvertorImpl.fromOFMatchToSALMatch(builder.build(), new BigInteger("42"), OpenflowVersion.OF13);\r
615         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatchBuilder.build();\r
616         \r
617         SctpMatch udpMatch = (SctpMatch) builtMatch.getLayer4Match();\r
618         Assert.assertEquals("Wrong sctp src port", 13, udpMatch.getSctpSourcePort().getValue().intValue());\r
619         Assert.assertEquals("Wrong sctp dst port", 14, udpMatch.getSctpDestinationPort().getValue().intValue());\r
620     }\r
621 \r
622     /**\r
623      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
624      */\r
625     @Test\r
626     public void testLayer3MatchIpv6() {\r
627         MatchBuilder builder = new MatchBuilder();\r
628         builder.setType(OxmMatchType.class);\r
629         List<MatchEntries> entries = new ArrayList<>();\r
630         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
631         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
632         entriesBuilder.setOxmMatchField(Ipv6Src.class);\r
633         entriesBuilder.setHasMask(false);\r
634         Ipv6AddressMatchEntryBuilder ipv6AddressBuilder = new Ipv6AddressMatchEntryBuilder();\r
635         ipv6AddressBuilder.setIpv6Address(new Ipv6Address("0000:0001:0002:0003:0004:0005:0006:0007"));\r
636         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());\r
637         entries.add(entriesBuilder.build());\r
638         entriesBuilder = new MatchEntriesBuilder();\r
639         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
640         entriesBuilder.setOxmMatchField(Ipv6Dst.class);\r
641         entriesBuilder.setHasMask(false);\r
642         ipv6AddressBuilder = new Ipv6AddressMatchEntryBuilder();\r
643         ipv6AddressBuilder.setIpv6Address(new Ipv6Address("0001:0002:0003:0004:0005:0006:0007:0008"));\r
644         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());\r
645         entries.add(entriesBuilder.build());\r
646         entriesBuilder = new MatchEntriesBuilder();\r
647         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
648         entriesBuilder.setOxmMatchField(Ipv6Flabel.class);\r
649         entriesBuilder.setHasMask(false);\r
650         Ipv6FlabelMatchEntryBuilder ipv6FlabelBuilder = new Ipv6FlabelMatchEntryBuilder();\r
651         ipv6FlabelBuilder.setIpv6Flabel(new Ipv6FlowLabel(18L));\r
652         entriesBuilder.addAugmentation(Ipv6FlabelMatchEntry.class, ipv6FlabelBuilder.build());\r
653         entries.add(entriesBuilder.build());\r
654         entriesBuilder = new MatchEntriesBuilder();\r
655         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
656         entriesBuilder.setOxmMatchField(Ipv6NdTarget.class);\r
657         entriesBuilder.setHasMask(false);\r
658         ipv6AddressBuilder = new Ipv6AddressMatchEntryBuilder();\r
659         ipv6AddressBuilder.setIpv6Address(new Ipv6Address("0002:0003:0004:0005:0006:0007:0008:0009"));\r
660         entriesBuilder.addAugmentation(Ipv6AddressMatchEntry.class, ipv6AddressBuilder.build());\r
661         entries.add(entriesBuilder.build());\r
662         entriesBuilder = new MatchEntriesBuilder();\r
663         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
664         entriesBuilder.setOxmMatchField(Ipv6NdSll.class);\r
665         entriesBuilder.setHasMask(false);\r
666         MacAddressMatchEntryBuilder macAddressBuilder = new MacAddressMatchEntryBuilder();\r
667         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:05"));\r
668         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
669         entries.add(entriesBuilder.build());\r
670         entriesBuilder = new MatchEntriesBuilder();\r
671         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
672         entriesBuilder.setOxmMatchField(Ipv6NdTll.class);\r
673         entriesBuilder.setHasMask(false);\r
674         macAddressBuilder = new MacAddressMatchEntryBuilder();\r
675         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:06"));\r
676         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
677         entries.add(entriesBuilder.build());\r
678         entriesBuilder = new MatchEntriesBuilder();\r
679         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
680         entriesBuilder.setOxmMatchField(Ipv6Exthdr.class);\r
681         entriesBuilder.setHasMask(false);\r
682         PseudoFieldMatchEntryBuilder pseudoBuilder = new PseudoFieldMatchEntryBuilder();\r
683         pseudoBuilder.setPseudoField(new Ipv6ExthdrFlags(true, false, true, false, true, false, true, false, true));\r
684         entriesBuilder.addAugmentation(PseudoFieldMatchEntry.class, pseudoBuilder.build());\r
685         builder.setMatchEntries(entries);\r
686         entries.add(entriesBuilder.build());\r
687 \r
688         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
689         .MatchBuilder salMatchBuilder = MatchConvertorImpl.fromOFMatchToSALMatch(builder.build(), new BigInteger("42"), OpenflowVersion.OF13);\r
690         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatchBuilder.build();\r
691         \r
692         Ipv6Match ipv6Match = (Ipv6Match) builtMatch.getLayer3Match();\r
693         Assert.assertEquals("Wrong ipv6 src address", "0000:0001:0002:0003:0004:0005:0006:0007",\r
694                 ipv6Match.getIpv6Source().getValue());\r
695         Assert.assertEquals("Wrong ipv6 dst address", "0001:0002:0003:0004:0005:0006:0007:0008",\r
696                 ipv6Match.getIpv6Destination().getValue());\r
697         Assert.assertEquals("Wrong ipv6 nd target", "0002:0003:0004:0005:0006:0007:0008:0009",\r
698                 ipv6Match.getIpv6NdTarget().getValue());\r
699         Assert.assertEquals("Wrong ipv6 flabel", 18, ipv6Match.getIpv6Label().getIpv6Flabel().getValue().intValue());\r
700         Assert.assertEquals("Wrong ipv6 nd sll", new MacAddress("00:00:00:00:00:05"), ipv6Match.getIpv6NdSll());\r
701         Assert.assertEquals("Wrong ipv6 nd tll", new MacAddress("00:00:00:00:00:06"), ipv6Match.getIpv6NdTll());\r
702         Assert.assertEquals("Wrong ipv6 ext header", 358, ipv6Match.getIpv6ExtHeader().getIpv6Exthdr().intValue());\r
703     }\r
704 \r
705     /**\r
706      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
707      */\r
708     @Test\r
709     public void testLayer3MatchIpv6ExtHeader2() {\r
710         MatchBuilder builder = new MatchBuilder();\r
711         builder.setType(OxmMatchType.class);\r
712         List<MatchEntries> entries = new ArrayList<>();\r
713         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
714         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
715         entriesBuilder.setOxmMatchField(Ipv6Exthdr.class);\r
716         entriesBuilder.setHasMask(true);\r
717         PseudoFieldMatchEntryBuilder pseudoBuilder = new PseudoFieldMatchEntryBuilder();\r
718         pseudoBuilder.setPseudoField(new Ipv6ExthdrFlags(false, true, false, true, false, true, false, true, false));\r
719         entriesBuilder.addAugmentation(PseudoFieldMatchEntry.class, pseudoBuilder.build());\r
720         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();\r
721         maskBuilder.setMask(new byte[]{1, 2});\r
722         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
723         entries.add(entriesBuilder.build());\r
724         builder.setMatchEntries(entries);\r
725 \r
726         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
727         .MatchBuilder salMatchBuilder = MatchConvertorImpl.fromOFMatchToSALMatch(builder.build(), new BigInteger("42"), OpenflowVersion.OF13);\r
728         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatchBuilder.build();\r
729         \r
730         Ipv6Match ipv6Match = (Ipv6Match) builtMatch.getLayer3Match();\r
731         Assert.assertEquals("Wrong ipv6 ext header", 153, ipv6Match.getIpv6ExtHeader().getIpv6Exthdr().intValue());\r
732         Assert.assertEquals("Wrong ipv6 ext header mask", 258, ipv6Match.getIpv6ExtHeader().getIpv6ExthdrMask().intValue());\r
733     }\r
734 \r
735     /**\r
736      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
737      */\r
738     @Test\r
739     public void testLayer3MatchArp() {\r
740         MatchBuilder builder = new MatchBuilder();\r
741         builder.setType(OxmMatchType.class);\r
742         List<MatchEntries> entries = new ArrayList<>();\r
743         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
744         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
745         entriesBuilder.setOxmMatchField(ArpOp.class);\r
746         entriesBuilder.setHasMask(false);\r
747         OpCodeMatchEntryBuilder opCodeBuilder = new OpCodeMatchEntryBuilder();\r
748         opCodeBuilder.setOpCode(17);\r
749         entriesBuilder.addAugmentation(OpCodeMatchEntry.class, opCodeBuilder.build());\r
750         entries.add(entriesBuilder.build());\r
751         entriesBuilder = new MatchEntriesBuilder();\r
752         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
753         entriesBuilder.setOxmMatchField(ArpSpa.class);\r
754         entriesBuilder.setHasMask(false);\r
755         Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
756         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.3"));\r
757         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
758         entries.add(entriesBuilder.build());\r
759         entriesBuilder = new MatchEntriesBuilder();\r
760         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
761         entriesBuilder.setOxmMatchField(ArpTpa.class);\r
762         entriesBuilder.setHasMask(false);\r
763         ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
764         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.4"));\r
765         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
766         entries.add(entriesBuilder.build());\r
767         entriesBuilder = new MatchEntriesBuilder();\r
768         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
769         entriesBuilder.setOxmMatchField(ArpSha.class);\r
770         entriesBuilder.setHasMask(false);\r
771         MacAddressMatchEntryBuilder macAddressBuilder = new MacAddressMatchEntryBuilder();\r
772         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:03"));\r
773         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
774         entries.add(entriesBuilder.build());\r
775         entriesBuilder = new MatchEntriesBuilder();\r
776         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
777         entriesBuilder.setOxmMatchField(ArpTha.class);\r
778         entriesBuilder.setHasMask(false);\r
779         macAddressBuilder = new MacAddressMatchEntryBuilder();\r
780         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:04"));\r
781         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
782         entries.add(entriesBuilder.build());\r
783         builder.setMatchEntries(entries);\r
784         \r
785         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
786         .MatchBuilder salMatchBuilder = MatchConvertorImpl.fromOFMatchToSALMatch(builder.build(), new BigInteger("42"), OpenflowVersion.OF13);\r
787         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatchBuilder.build();\r
788         \r
789         ArpMatch arpMatch = (ArpMatch) builtMatch.getLayer3Match();\r
790         Assert.assertEquals("Wrong arp op", 17, arpMatch.getArpOp().intValue());\r
791         Assert.assertEquals("Wrong arp spa", "10.0.0.3/32", arpMatch.getArpSourceTransportAddress().getValue());\r
792         Assert.assertEquals("Wrong arp tpa", "10.0.0.4/32", arpMatch.getArpTargetTransportAddress().getValue());\r
793         Assert.assertEquals("Wrong arp sha", "00:00:00:00:00:03", arpMatch.getArpSourceHardwareAddress().getAddress().getValue());\r
794         Assert.assertEquals("Wrong arp tha", "00:00:00:00:00:04", arpMatch.getArpTargetHardwareAddress().getAddress().getValue());\r
795     }\r
796 \r
797     /**\r
798      * Test {@link MatchConvertorImpl#fromOFMatchToSALMatch(Match, BigInteger, OpenflowVersion)}\r
799      */\r
800     @Test\r
801     public void testLayer3MatchArpWithMasks() {\r
802         MatchBuilder builder = new MatchBuilder();\r
803         builder.setType(OxmMatchType.class);\r
804         List<MatchEntries> entries = new ArrayList<>();\r
805         MatchEntriesBuilder entriesBuilder = new MatchEntriesBuilder();\r
806         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
807         entriesBuilder.setOxmMatchField(ArpSpa.class);\r
808         entriesBuilder.setHasMask(true);\r
809         Ipv4AddressMatchEntryBuilder ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
810         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.3"));\r
811         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
812         MaskMatchEntryBuilder maskBuilder = new MaskMatchEntryBuilder();\r
813         maskBuilder.setMask(new byte[]{(byte) 255, (byte) 255, (byte) 255, 0});\r
814         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
815         entries.add(entriesBuilder.build());\r
816         entriesBuilder = new MatchEntriesBuilder();\r
817         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
818         entriesBuilder.setOxmMatchField(ArpTpa.class);\r
819         entriesBuilder.setHasMask(true);\r
820         ipv4AddressBuilder = new Ipv4AddressMatchEntryBuilder();\r
821         ipv4AddressBuilder.setIpv4Address(new Ipv4Address("10.0.0.4"));\r
822         entriesBuilder.addAugmentation(Ipv4AddressMatchEntry.class, ipv4AddressBuilder.build());\r
823         maskBuilder = new MaskMatchEntryBuilder();\r
824         maskBuilder.setMask(new byte[]{(byte) 255, (byte) 128, 0, 0});\r
825         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
826         entries.add(entriesBuilder.build());\r
827         entriesBuilder = new MatchEntriesBuilder();\r
828         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
829         entriesBuilder.setOxmMatchField(ArpSha.class);\r
830         entriesBuilder.setHasMask(true);\r
831         MacAddressMatchEntryBuilder macAddressBuilder = new MacAddressMatchEntryBuilder();\r
832         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:03"));\r
833         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
834         maskBuilder = new MaskMatchEntryBuilder();\r
835         maskBuilder.setMask(new byte[]{0, 0, 1, 0, 4, 0});\r
836         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
837         entries.add(entriesBuilder.build());\r
838         entriesBuilder = new MatchEntriesBuilder();\r
839         entriesBuilder.setOxmClass(OpenflowBasicClass.class);\r
840         entriesBuilder.setOxmMatchField(ArpTha.class);\r
841         entriesBuilder.setHasMask(true);\r
842         macAddressBuilder = new MacAddressMatchEntryBuilder();\r
843         macAddressBuilder.setMacAddress(new MacAddress("00:00:00:00:00:04"));\r
844         entriesBuilder.addAugmentation(MacAddressMatchEntry.class, macAddressBuilder.build());\r
845         maskBuilder = new MaskMatchEntryBuilder();\r
846         maskBuilder.setMask(new byte[]{1, 1, 1, 2, 2, 2});\r
847         entriesBuilder.addAugmentation(MaskMatchEntry.class, maskBuilder.build());\r
848         entries.add(entriesBuilder.build());\r
849         builder.setMatchEntries(entries);\r
850         \r
851         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow\r
852         .MatchBuilder salMatchBuilder = MatchConvertorImpl.fromOFMatchToSALMatch(builder.build(), new BigInteger("42"), OpenflowVersion.OF13);\r
853         org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match builtMatch = salMatchBuilder.build();\r
854         \r
855         ArpMatch arpMatch = (ArpMatch) builtMatch.getLayer3Match();\r
856         // FIXME - fix mask computation\r
857 //        Assert.assertEquals("Wrong arp spa", "10.0.0.3/8", arpMatch.getArpSourceTransportAddress().getValue());\r
858 //        Assert.assertEquals("Wrong arp tpa", "10.0.0.4/9", arpMatch.getArpTargetTransportAddress().getValue());\r
859         Assert.assertEquals("Wrong arp sha", "00:00:00:00:00:03", arpMatch.getArpSourceHardwareAddress().getAddress().getValue());\r
860         Assert.assertEquals("Wrong arp sha mask", "00:00:01:00:04:00", arpMatch.getArpSourceHardwareAddress().getMask().getValue());\r
861         Assert.assertEquals("Wrong arp tha", "00:00:00:00:00:04", arpMatch.getArpTargetHardwareAddress().getAddress().getValue());\r
862         Assert.assertEquals("Wrong arp tha mask", "01:01:01:02:02:02", arpMatch.getArpTargetHardwareAddress().getMask().getValue());\r
863     }\r
864 }