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