Bump upstreams
[openflowplugin.git] / openflowplugin / src / main / java / org / opendaylight / openflowplugin / openflow / md / core / sal / convertor / match / MatchV10ResponseConvertor.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 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;
9
10 import java.util.Collection;
11 import java.util.Collections;
12 import java.util.Set;
13 import org.opendaylight.openflowplugin.api.openflow.md.util.OpenflowVersion;
14 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.common.Convertor;
15 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionDatapathIdConvertorData;
16 import org.opendaylight.openflowplugin.openflow.md.util.ActionUtil;
17 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
18 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Dscp;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
34 import org.opendaylight.yangtools.yang.common.Uint16;
35 import org.opendaylight.yangtools.yang.common.Uint32;
36 import org.opendaylight.yangtools.yang.common.Uint64;
37 import org.opendaylight.yangtools.yang.common.Uint8;
38
39 /**
40  * Converts Openflow 1.0 specific flow match to MD-SAL format flow match.
41  *
42  * <p>
43  * Example usage:
44  * <pre>
45  * {@code
46  * VersionDatapathIdConvertorData data = new VersionDatapathIdConvertorData(version);
47  * data.setDatapathId(datapathId);
48  * Optional<MatchBuilder> salMatch = convertorManager.convert(ofMatchV10, data);
49  * }
50  * </pre>
51  */
52 public class MatchV10ResponseConvertor extends Convertor<MatchV10, MatchBuilder, VersionDatapathIdConvertorData> {
53     private static final short PROTO_TCP = 6;
54     private static final short PROTO_UDP = 17;
55     private static final short PROTO_ICMPV4 = 1;
56     private static final String NO_IP = "0.0.0.0/0";
57     private static final Set<Class<?>> TYPES = Collections.singleton(MatchV10.class);
58
59     @Override
60     public Collection<Class<?>> getTypes() {
61         return TYPES;
62     }
63
64     @Override
65     public MatchBuilder convert(final MatchV10 source, final VersionDatapathIdConvertorData datapathIdConvertorData) {
66         MatchBuilder matchBuilder = new MatchBuilder();
67         EthernetMatchBuilder ethMatchBuilder = new EthernetMatchBuilder();
68         VlanMatchBuilder vlanMatchBuilder = new VlanMatchBuilder();
69         Ipv4MatchBuilder ipv4MatchBuilder = new Ipv4MatchBuilder();
70         IpMatchBuilder ipMatchBuilder = new IpMatchBuilder();
71         OpenflowVersion ofVersion = OpenflowVersion.get(datapathIdConvertorData.getVersion());
72         Uint64 datapathid = datapathIdConvertorData.getDatapathId();
73
74         if (!source.getWildcards().getINPORT() && source.getInPort() != null) {
75             matchBuilder.setInPort(InventoryDataServiceUtil.nodeConnectorIdfromDatapathPortNo(datapathid,
76                     Uint32.valueOf(source.getInPort()), ofVersion));
77         }
78
79         if (!source.getWildcards().getDLSRC() && source.getDlSrc() != null) {
80             EthernetSourceBuilder ethSrcBuilder = new EthernetSourceBuilder();
81             ethSrcBuilder.setAddress(source.getDlSrc());
82             ethMatchBuilder.setEthernetSource(ethSrcBuilder.build());
83             matchBuilder.setEthernetMatch(ethMatchBuilder.build());
84         }
85         if (!source.getWildcards().getDLDST() && source.getDlDst() != null) {
86             EthernetDestinationBuilder ethDstBuilder = new EthernetDestinationBuilder();
87             ethDstBuilder.setAddress(source.getDlDst());
88             ethMatchBuilder.setEthernetDestination(ethDstBuilder.build());
89             matchBuilder.setEthernetMatch(ethMatchBuilder.build());
90         }
91         if (!source.getWildcards().getDLTYPE() && source.getDlType() != null) {
92             EthernetTypeBuilder ethTypeBuilder = new EthernetTypeBuilder();
93             ethTypeBuilder.setType(new org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType(
94                     Uint32.valueOf(source.getDlType())));
95             ethMatchBuilder.setEthernetType(ethTypeBuilder.build());
96             matchBuilder.setEthernetMatch(ethMatchBuilder.build());
97         }
98         if (!source.getWildcards().getDLVLAN() && source.getDlVlan() != null) {
99             Uint16 vlanId = source.getDlVlan();
100             if (vlanId.toJava() == 0xffff) {
101                 vlanId = Uint16.ZERO;
102             }
103
104             vlanMatchBuilder.setVlanId(new VlanIdBuilder()
105                 .setVlanId(new org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId(vlanId))
106                 .setVlanIdPresent(!Uint16.ZERO.equals(vlanId))
107                 .build());
108             matchBuilder.setVlanMatch(vlanMatchBuilder.build());
109         }
110         if (!source.getWildcards().getDLVLANPCP() && source.getDlVlanPcp() != null) {
111             vlanMatchBuilder.setVlanPcp(new org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp(
112                     source.getDlVlanPcp()));
113             matchBuilder.setVlanMatch(vlanMatchBuilder.build());
114         }
115         if (!source.getWildcards().getDLTYPE() && source.getNwSrc() != null) {
116             final Ipv4Prefix prefix;
117             if (source.getNwSrcMask() != null) {
118                 prefix = IetfInetUtil.ipv4PrefixFor(source.getNwSrc(), source.getNwSrcMask().toJava());
119             } else {
120                 //Openflow Spec : 1.3.2
121                 //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
122                 // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
123                 // statistics response.
124                 prefix = IetfInetUtil.ipv4PrefixFor(source.getNwSrc());
125             }
126             if (!NO_IP.equals(prefix.getValue())) {
127                 ipv4MatchBuilder.setIpv4Source(prefix);
128                 matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
129             }
130         }
131         if (!source.getWildcards().getDLTYPE() && source.getNwDst() != null) {
132             final Ipv4Prefix prefix;
133             if (source.getNwDstMask() != null) {
134                 prefix = IetfInetUtil.ipv4PrefixFor(source.getNwDst(), source.getNwDstMask().toJava());
135             } else {
136                 //Openflow Spec : 1.3.2
137                 //An all-one-bits oxm_mask is equivalent to specifying 0 for oxm_hasmask and omitting oxm_mask.
138                 // So when user specify 32 as a mast, switch omit that mast and we get null as a mask in flow
139                 // statistics response.
140                 prefix = IetfInetUtil.ipv4PrefixFor(source.getNwDst());
141             }
142             if (!NO_IP.equals(prefix.getValue())) {
143                 ipv4MatchBuilder.setIpv4Destination(prefix);
144                 matchBuilder.setLayer3Match(ipv4MatchBuilder.build());
145             }
146         }
147         if (!source.getWildcards().getNWPROTO() && source.getNwProto() != null) {
148             Uint8 nwProto = source.getNwProto();
149             ipMatchBuilder.setIpProtocol(nwProto);
150             matchBuilder.setIpMatch(ipMatchBuilder.build());
151
152             int proto = nwProto.intValue();
153             if (proto == PROTO_TCP) {
154                 TcpMatchBuilder tcpMatchBuilder = new TcpMatchBuilder();
155                 boolean hasTcp = false;
156                 if (!source.getWildcards().getTPSRC() && source.getTpSrc() != null) {
157                     tcpMatchBuilder.setTcpSourcePort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
158                             .inet.types.rev130715.PortNumber(source.getTpSrc()));
159                     hasTcp = true;
160                 }
161                 if (!source.getWildcards().getTPDST() && source.getTpDst() != null) {
162                     tcpMatchBuilder.setTcpDestinationPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
163                             .ietf.inet.types.rev130715.PortNumber(source.getTpDst()));
164                     hasTcp = true;
165                 }
166
167                 if (hasTcp) {
168                     matchBuilder.setLayer4Match(tcpMatchBuilder.build());
169                 }
170             } else if (proto == PROTO_UDP) {
171                 UdpMatchBuilder udpMatchBuilder = new UdpMatchBuilder();
172                 boolean hasUdp = false;
173                 if (!source.getWildcards().getTPSRC() && source.getTpSrc() != null) {
174                     udpMatchBuilder.setUdpSourcePort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf
175                             .inet.types.rev130715.PortNumber(source.getTpSrc()));
176                     hasUdp = true;
177                 }
178                 if (!source.getWildcards().getTPDST() && source.getTpDst() != null) {
179                     udpMatchBuilder.setUdpDestinationPort(new org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang
180                             .ietf.inet.types.rev130715.PortNumber(source.getTpDst()));
181                     hasUdp = true;
182                 }
183
184                 if (hasUdp) {
185                     matchBuilder.setLayer4Match(udpMatchBuilder.build());
186                 }
187             } else if (proto == PROTO_ICMPV4) {
188                 Icmpv4MatchBuilder icmpv4MatchBuilder = new Icmpv4MatchBuilder();
189                 boolean hasIcmpv4 = false;
190                 if (!source.getWildcards().getTPSRC()) {
191                     Uint16 type = source.getTpSrc();
192                     if (type != null) {
193                         icmpv4MatchBuilder.setIcmpv4Type(type.toUint8());
194                         hasIcmpv4 = true;
195                     }
196                 }
197                 if (!source.getWildcards().getTPDST()) {
198                     Uint16 code = source.getTpDst();
199                     if (code != null) {
200                         icmpv4MatchBuilder.setIcmpv4Code(code.toUint8());
201                         hasIcmpv4 = true;
202                     }
203                 }
204
205                 if (hasIcmpv4) {
206                     matchBuilder.setIcmpv4Match(icmpv4MatchBuilder.build());
207                 }
208             }
209         }
210         if (!source.getWildcards().getNWTOS() && source.getNwTos() != null) {
211             ipMatchBuilder.setIpDscp(new Dscp(ActionUtil.tosToDscp(source.getNwTos())));
212             matchBuilder.setIpMatch(ipMatchBuilder.build());
213         }
214
215         return matchBuilder;
216     }
217 }