2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;
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;
43 * The type Match converter v 10.
45 public class MatchV10Convertor extends Convertor<Match, MatchV10, VersionConvertorData> {
47 private static final List<Class<?>> TYPES = Arrays.asList(
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,
60 private static final MacAddress ZERO_MAC = new MacAddress("00:00:00:00:00:00");
65 private static final Ipv4Address ZERO_IPV4 = new Ipv4Address("0.0.0.0");
68 * The value 0xffff (OFP_VLAN_NONE) is used to indicate
69 * that no VLAN ID is set for OF Flow.
71 private static final Uint16 OFP_VLAN_NONE = Uint16.MAX_VALUE;
73 private static boolean convertL4UdpDstMatch(final MatchV10Builder matchBuilder,
74 final UdpMatch udpMatch) {
75 if (udpMatch.getUdpDestinationPort() != null) {
76 matchBuilder.setTpDst(udpMatch.getUdpDestinationPort().getValue());
82 private static boolean convertL4UdpSrcMatch(final MatchV10Builder matchBuilder,
83 final UdpMatch udpMatch) {
84 if (udpMatch.getUdpSourcePort() != null) {
85 matchBuilder.setTpSrc(udpMatch.getUdpSourcePort().getValue());
91 private static boolean convertL4TpDstMatch(final MatchV10Builder matchBuilder,
92 final TcpMatch tcpMatch) {
93 if (tcpMatch.getTcpDestinationPort() != null) {
94 matchBuilder.setTpDst(tcpMatch.getTcpDestinationPort().getValue());
100 private static boolean convertL4TpSrcMatch(final MatchV10Builder matchBuilder,
101 final TcpMatch tcpMatch) {
102 if (tcpMatch.getTcpSourcePort() != null) {
103 matchBuilder.setTpSrc(tcpMatch.getTcpSourcePort().getValue());
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()));
118 private static boolean convertNwProto(final MatchV10Builder matchBuilder, final IpMatch ipMatch) {
119 if (ipMatch.getIpProtocol() != null) {
120 matchBuilder.setNwProto(ipMatch.getIpProtocol());
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.
130 * @param matchBuilder match builder
131 * @param ipv4 ip v4 match
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());
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.
149 * @param matchBuilder match builder
150 * @param ipv4 ip v4 match
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);
160 matchBuilder.setNwSrc(ipv4Address);
161 matchBuilder.setNwSrcMask((short) prefix);
165 private static int buildPrefix(final Iterator<String> addressParts) {
167 if (addressParts.hasNext()) {
168 prefix = Integer.parseInt(addressParts.next());
173 private static boolean convertDlVlanPcp(final MatchV10Builder matchBuilder,
174 final VlanMatch vlanMatch) {
175 if (vlanMatch.getVlanPcp() != null) {
176 matchBuilder.setDlVlanPcp(vlanMatch.getVlanPcp().getValue());
182 private static boolean convertDlVlan(final MatchV10Builder matchBuilder, final VlanMatch vlanMatch) {
183 final VlanId id = vlanMatch.getVlanId();
185 final Uint16 vlanId = id.getVlanId().getValue();
186 matchBuilder.setDlVlan(vlanId.toJava() == 0 ? OFP_VLAN_NONE : vlanId);
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());
201 private static boolean convertEthernetDlSrc(final MatchV10Builder matchBuilder,
202 final EthernetMatch ethernetMatch) {
203 if (ethernetMatch.getEthernetSource() != null) {
204 matchBuilder.setDlSrc(ethernetMatch.getEthernetSource().getAddress());
210 private static boolean convertEthernetDlDst(final MatchV10Builder matchBuilder,
211 final EthernetMatch ethernetMatch) {
212 if (ethernetMatch.getEthernetDestination() != null) {
213 matchBuilder.setDlDst(ethernetMatch.getEthernetDestination().getAddress());
219 private static boolean convertInPortMatch(final MatchV10Builder matchBuilder, final NodeConnectorId inPort) {
220 if (inPort != null) {
221 matchBuilder.setInPort(InventoryDataServiceUtil.portNumberfromNodeConnectorId(OpenflowVersion.OF10,
229 * Create default empty match v10
230 * Use this method, if result from converter is empty.
232 public static MatchV10 defaultResult() {
233 return new MatchV10Builder().build();
237 public Collection<Class<?>> getTypes() {
242 public MatchV10 convert(final Match source, final VersionConvertorData data) {
243 MatchV10Builder matchBuilder = new MatchV10Builder()
244 .setInPort(Uint16.ZERO)
247 .setDlType(Uint16.ZERO)
248 .setDlVlan(OFP_VLAN_NONE)
249 .setDlVlanPcp(Uint8.ZERO)
251 .setNwDstMask(Uint8.ZERO)
253 .setNwSrcMask(Uint8.ZERO)
254 .setNwProto(Uint8.ZERO)
255 .setNwTos(Uint8.ZERO)
256 .setTpSrc(Uint16.ZERO)
257 .setTpDst(Uint16.ZERO);
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;
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);
277 VlanMatch vlanMatch = source.getVlanMatch();
278 if (vlanMatch != null) {
279 dlVlan = convertDlVlan(matchBuilder, vlanMatch);
280 dlVlanPcp = convertDlVlanPcp(matchBuilder, vlanMatch);
282 NodeConnectorId inPort = source.getInPort();
283 if (inPort != null) {
284 ipPort = convertInPortMatch(matchBuilder, inPort);
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);
294 IpMatch ipMatch = source.getIpMatch();
295 if (ipMatch != null) {
296 nwProto = convertNwProto(matchBuilder, ipMatch);
297 nwTos = convertNwTos(matchBuilder, ipMatch);
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);
311 Icmpv4Match icmpv4Match = source.getIcmpv4Match();
312 if (icmpv4Match != null) {
313 Uint8 type = icmpv4Match.getIcmpv4Type();
315 matchBuilder.setTpSrc(Uint16.valueOf(type));
318 Uint8 code = icmpv4Match.getIcmpv4Code();
320 matchBuilder.setTpDst(Uint16.valueOf(code));
327 FlowWildcardsV10 wildCards = new FlowWildcardsV10(
328 dlDst, dlSsc, dlType, dlVlan,
329 dlVlanPcp, ipPort, nwProto, nwTos, tpDst, tpSrc);
330 matchBuilder.setWildcards(wildCards);
332 return matchBuilder.build();