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