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