43a46c4121ae661de341f7979376169cee88fae9
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / MatchConvertorV10Impl.java
1 /**
2  * Copyright (c) 2013, 2015 Cisco Systems, Inc. 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 java.math.BigInteger;
12 import java.util.Iterator;
13
14 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.IpConversionUtil;
15 import org.opendaylight.openflowplugin.openflow.md.util.ActionUtil;
16 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
17 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4Match;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
34
35 /**
36  *
37  */
38 public class MatchConvertorV10Impl implements MatchConvertor<MatchV10> {
39
40     /** default MAC */
41     public static final MacAddress zeroMac = new MacAddress("00:00:00:00:00:00");
42     /** default IPv4 */
43     public static final Ipv4Address zeroIPv4 = new Ipv4Address("0.0.0.0");
44
45     /*
46      * The value 0xffff (OFP_VLAN_NONE) is used to indicate
47      * that no VLAN ID is set for OF Flow.
48      */
49     private static final Integer OFP_VLAN_NONE = 0xffff;
50
51     /**
52      * Method builds openflow 1.0 specific match (MatchV10) from MD-SAL match.
53      * @param match MD-SAL match
54      * @return OF-API match
55      * @author avishnoi@in.ibm.com
56      */
57     @Override
58     public MatchV10 convert(final Match match,final BigInteger datapathid) {
59         MatchV10Builder matchBuilder = new MatchV10Builder();
60         boolean _dLDST = true;
61         boolean _dLSRC = true;
62         boolean _dLTYPE = true;
63         boolean _dLVLAN = true;
64         boolean _dLVLANPCP = true;
65         boolean _iNPORT = true;
66         boolean _nWPROTO = true;
67         boolean _nWTOS = true;
68         boolean _tPDST = true;
69         boolean _tPSRC = true;
70
71         matchBuilder.setInPort(0);
72         matchBuilder.setDlDst(zeroMac);
73         matchBuilder.setDlSrc(zeroMac);
74         matchBuilder.setDlType(0);
75         matchBuilder.setDlVlan(OFP_VLAN_NONE);
76         matchBuilder.setDlVlanPcp((short) 0);
77         matchBuilder.setNwDst(zeroIPv4);
78         matchBuilder.setNwDstMask((short) 0);
79         matchBuilder.setNwSrc(zeroIPv4);
80         matchBuilder.setNwSrcMask((short) 0);
81         matchBuilder.setNwProto((short) 0);
82         matchBuilder.setNwTos((short) 0);
83         matchBuilder.setTpSrc(0);
84         matchBuilder.setTpDst(0);
85
86         if (match != null) {
87             EthernetMatch ethernetMatch = match.getEthernetMatch();
88             if(ethernetMatch!= null){
89                 _dLDST = convertEthernetDlDst(matchBuilder, ethernetMatch);
90                 _dLSRC = convertEthernetDlSrc(matchBuilder, ethernetMatch);
91                 _dLTYPE = convertEthernetDlType(matchBuilder, ethernetMatch);
92             }
93             VlanMatch vlanMatch = match.getVlanMatch();
94             if(vlanMatch!= null){
95                 _dLVLAN = convertDlVlan(matchBuilder, vlanMatch);
96                 _dLVLANPCP = convertDlVlanPcp(matchBuilder, vlanMatch);
97             }
98             NodeConnectorId inPort = match.getInPort();
99             if(inPort!=null){
100                 _iNPORT = convertInPortMatch(matchBuilder, inPort);
101             }
102             Layer3Match l3Match = match.getLayer3Match();
103             if(l3Match != null){
104                 if(l3Match instanceof Ipv4Match){
105                     Ipv4Match ipv4 = (Ipv4Match)l3Match;
106                     convertL3Ipv4SrcMatch(matchBuilder, ipv4);
107                     convertL3Ipv4DstMatch(matchBuilder, ipv4);
108                 }
109             }
110             IpMatch ipMatch = match.getIpMatch();
111             if(ipMatch!=null){
112                 _nWPROTO = convertNwProto(matchBuilder, ipMatch);
113                 _nWTOS = convertNwTos(matchBuilder, ipMatch);
114             }
115             Layer4Match layer4Match = match.getLayer4Match();
116             if (layer4Match != null) {
117                 if (layer4Match instanceof TcpMatch) {
118                     TcpMatch tcpMatch = (TcpMatch) layer4Match;
119                     _tPSRC = convertL4TpSrcMatch(matchBuilder, tcpMatch);
120                     _tPDST = convertL4TpDstMatch(matchBuilder, tcpMatch);
121                 } else if (layer4Match instanceof UdpMatch) {
122                     UdpMatch udpMatch = (UdpMatch) layer4Match;
123                     _tPSRC = convertL4UdpSrcMatch(matchBuilder, udpMatch);
124                     _tPDST = convertL4UdpDstMatch(matchBuilder, udpMatch);
125                 }
126             } else {
127                 Icmpv4Match icmpv4Match = match.getIcmpv4Match();
128                 if (icmpv4Match != null) {
129                     Short type = icmpv4Match.getIcmpv4Type();
130                     if (type != null) {
131                         matchBuilder.setTpSrc(type.intValue());
132                         _tPSRC = false;
133                     }
134                     Short code = icmpv4Match.getIcmpv4Code();
135                     if (code != null) {
136                         matchBuilder.setTpDst(code.intValue());
137                         _tPDST = false;
138                     }
139                 }
140             }
141         }
142
143         FlowWildcardsV10 wildCards = new FlowWildcardsV10(
144                 _dLDST, _dLSRC, _dLTYPE, _dLVLAN,
145                 _dLVLANPCP, _iNPORT, _nWPROTO, _nWTOS, _tPDST, _tPSRC);
146         matchBuilder.setWildcards(wildCards);
147
148         return matchBuilder.build();
149     }
150
151     /**
152      * @param matchBuilder
153      * @param udpMatch
154      * @return is wildCard
155      */
156     private static boolean convertL4UdpDstMatch(final MatchV10Builder matchBuilder,
157             final UdpMatch udpMatch) {
158         if (udpMatch.getUdpDestinationPort() != null) {
159             matchBuilder.setTpDst(udpMatch.getUdpDestinationPort().getValue());
160             return false;
161         }
162         return true;
163     }
164
165     /**
166      * @param matchBuilder
167      * @param udpMatch
168      * @return is wildCard
169      */
170     private static boolean convertL4UdpSrcMatch(final MatchV10Builder matchBuilder,
171             final UdpMatch udpMatch) {
172         if (udpMatch.getUdpSourcePort() != null) {
173             matchBuilder.setTpSrc(udpMatch.getUdpSourcePort().getValue());
174             return false;
175         }
176         return true;
177     }
178
179     /**
180      * @param matchBuilder
181      * @param tcpMatch
182      * @return is wildCard
183      */
184     private static boolean convertL4TpDstMatch(final MatchV10Builder matchBuilder,
185             final TcpMatch tcpMatch) {
186         if (tcpMatch.getTcpDestinationPort() != null) {
187             matchBuilder.setTpDst(tcpMatch.getTcpDestinationPort().getValue());
188             return false;
189         }
190         return true;
191     }
192
193     /**
194      * @param matchBuilder
195      * @param tcpMatch
196      * @return is wildCard
197      */
198     private static boolean convertL4TpSrcMatch(final MatchV10Builder matchBuilder,
199             final TcpMatch tcpMatch) {
200         if (tcpMatch.getTcpSourcePort() != null) {
201             matchBuilder.setTpSrc(tcpMatch.getTcpSourcePort().getValue());
202             return false;
203         }
204         return true;
205     }
206
207     /**
208      * @param matchBuilder
209      * @param ipMatch
210      * @return is wildCard
211      */
212     private static boolean convertNwTos(final MatchV10Builder matchBuilder,
213             final IpMatch ipMatch) {
214         if (ipMatch.getIpDscp() != null) {
215             matchBuilder.setNwTos(ActionUtil.dscpToTos(ipMatch.getIpDscp().getValue()));
216             return false;
217         }
218         return true;
219     }
220
221     /**
222      * @param matchBuilder
223      * @param ipMatch
224      * @return is wildCard
225      */
226     private static boolean convertNwProto(final MatchV10Builder matchBuilder, final IpMatch ipMatch) {
227         if (ipMatch.getIpProtocol() != null) {
228             matchBuilder.setNwProto(ipMatch.getIpProtocol());
229             return false;
230         }
231         return true;
232     }
233
234     /**
235      * Method splits the IP address and its mask and set their respective values in MatchV10Builder instance.
236      * Wildcard value of the IP mask will be determined by Openflow java encoding library.
237      * @param matchBuilder
238      * @param ipv4
239      */
240     private static void convertL3Ipv4DstMatch(final MatchV10Builder matchBuilder,
241             final Ipv4Match ipv4) {
242         if(ipv4.getIpv4Destination()!=null){
243             Iterator<String> addressParts = IpConversionUtil.PREFIX_SPLITTER.split(ipv4.getIpv4Destination().getValue()).iterator();
244             Ipv4Address ipv4Address = new Ipv4Address(addressParts.next());
245             Integer prefix = buildPrefix(addressParts);
246             matchBuilder.setNwDst(ipv4Address);
247             matchBuilder.setNwDstMask(prefix.shortValue());
248         }
249     }
250
251     /**
252      * Method splits the IP address and its mask and set their respective values in MatchV10Builder instance.
253      * Wildcard value of the IP mask will be determined by Openflow java encoding library.
254      * @param matchBuilder
255      * @param ipv4
256      */
257     private static void convertL3Ipv4SrcMatch(final MatchV10Builder matchBuilder,
258             final Ipv4Match ipv4) {
259         if(ipv4.getIpv4Source()!=null){
260             Iterator<String> addressParts = IpConversionUtil.PREFIX_SPLITTER.split(ipv4.getIpv4Source().getValue()).iterator();
261             Ipv4Address ipv4Address = new Ipv4Address(addressParts.next());
262             int prefix = buildPrefix(addressParts);
263
264             matchBuilder.setNwSrc(ipv4Address);
265             matchBuilder.setNwSrcMask((short) prefix);
266         }
267     }
268
269     /**
270      * @param addressParts
271      * @return
272      */
273     private static int buildPrefix(final Iterator<String> addressParts) {
274         int prefix = 32;
275         if (addressParts.hasNext()) {
276             prefix = Integer.parseInt(addressParts.next());
277         }
278         return prefix;
279     }
280
281     /**
282      * @param matchBuilder
283      * @param vlanMatch
284      * @return
285      */
286     private static boolean convertDlVlanPcp(final MatchV10Builder matchBuilder,
287             final VlanMatch vlanMatch) {
288         if (vlanMatch.getVlanPcp() != null) {
289             matchBuilder.setDlVlanPcp(vlanMatch.getVlanPcp().getValue());
290             return false;
291         }
292         return true;
293     }
294
295     /**
296      * @param matchBuilder
297      * @param vlanMatch
298      * @return
299      */
300     private static boolean convertDlVlan(final MatchV10Builder matchBuilder, final VlanMatch vlanMatch) {
301         if (vlanMatch.getVlanId() != null) {
302             int vlanId = vlanMatch.getVlanId().getVlanId().getValue();
303             matchBuilder.setDlVlan((vlanId == 0 ? OFP_VLAN_NONE : vlanId));
304             return false;
305         }
306         return true;
307     }
308
309     /**
310      * @param matchBuilder
311      * @param ethernetMatch
312      * @return is wildCard
313      */
314     private static boolean convertEthernetDlType(final MatchV10Builder matchBuilder,
315             final EthernetMatch ethernetMatch) {
316         if (ethernetMatch.getEthernetType() != null) {
317             matchBuilder.setDlType(ethernetMatch.getEthernetType().getType().getValue().intValue());
318             return false;
319         }
320         return true;
321     }
322
323     /**
324      * @param matchBuilder
325      * @param ethernetMatch
326      * @return is wildCard
327      */
328     private static boolean convertEthernetDlSrc(final MatchV10Builder matchBuilder,
329             final EthernetMatch ethernetMatch) {
330         if (ethernetMatch.getEthernetSource() != null) {
331             matchBuilder.setDlSrc(ethernetMatch.getEthernetSource().getAddress());
332             return false;
333         }
334         return true;
335     }
336
337     /**
338      * @param matchBuilder
339      * @param ethernetMatch
340      * @return is wildCard
341      */
342     private static boolean convertEthernetDlDst(final MatchV10Builder matchBuilder,
343             final EthernetMatch ethernetMatch) {
344         if (ethernetMatch.getEthernetDestination() != null) {
345             matchBuilder.setDlDst(ethernetMatch.getEthernetDestination().getAddress());
346             return false;
347         }
348         return true;
349     }
350
351     /**
352      * @param matchBuilder
353      * @param inPort
354      */
355     private static boolean convertInPortMatch(final MatchV10Builder matchBuilder, final NodeConnectorId inPort) {
356         if (inPort != null) {
357             matchBuilder.setInPort(InventoryDataServiceUtil.portNumberfromNodeConnectorId(OpenflowVersion.OF10, inPort).intValue());
358             return false;
359         }
360         return true;
361     }
362
363 }