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