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