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
8 package org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.match;
10 import java.util.Collection;
11 import java.util.Iterator;
12 import java.util.List;
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.common.IpConversionUtil;
16 import org.opendaylight.openflowplugin.openflow.md.core.sal.convertor.data.VersionConvertorData;
17 import org.opendaylight.openflowplugin.openflow.md.util.ActionUtil;
18 import org.opendaylight.openflowplugin.openflow.md.util.InventoryDataServiceUtil;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
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.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.field._case.SetField;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.Match;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4Match;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4Match;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatch;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatch;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.FlowWildcardsV10;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.v10.grouping.MatchV10Builder;
37 import org.opendaylight.yangtools.yang.common.Uint16;
38 import org.opendaylight.yangtools.yang.common.Uint8;
41 * The type Match converter v 10.
43 public class MatchV10Convertor extends Convertor<Match, MatchV10, VersionConvertorData> {
45 private static final List<Class<?>> TYPES = List.of(
47 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match.class,
48 org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.mod.removed.Match.class,
49 org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.received.Match.class,
50 org.opendaylight.yang.gen.v1.urn.opendaylight.packet.service.rev130709.packet.in.message.Match.class,
51 org.opendaylight.yang.gen.v1.urn.opendaylight.table.types.rev131026.table.feature.prop.type.table.feature
52 .prop.type.Match.class,
58 private static final MacAddress ZERO_MAC = new MacAddress("00:00:00:00:00:00");
63 private static final Ipv4Address ZERO_IPV4 = new Ipv4Address("0.0.0.0");
65 private static final Uint8 DEFAULT_PREFIX = Uint8.valueOf(32);
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, final UdpMatch udpMatch) {
74 final var port = udpMatch.getUdpDestinationPort();
76 matchBuilder.setTpDst(port.getValue());
82 private static boolean convertL4UdpSrcMatch(final MatchV10Builder matchBuilder, final UdpMatch udpMatch) {
83 final var port = udpMatch.getUdpSourcePort();
85 matchBuilder.setTpSrc(port.getValue());
91 private static boolean convertL4TpDstMatch(final MatchV10Builder matchBuilder, final TcpMatch tcpMatch) {
92 final var port = tcpMatch.getTcpDestinationPort();
94 matchBuilder.setTpDst(tcpMatch.getTcpDestinationPort().getValue());
100 private static boolean convertL4TpSrcMatch(final MatchV10Builder matchBuilder, final TcpMatch tcpMatch) {
101 final var port = tcpMatch.getTcpSourcePort();
103 matchBuilder.setTpSrc(port.getValue());
109 private static boolean convertNwTos(final MatchV10Builder matchBuilder, final IpMatch ipMatch) {
110 final var ipDscp = ipMatch.getIpDscp();
111 if (ipDscp != null) {
112 matchBuilder.setNwTos(ActionUtil.dscpToTos(ipDscp.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, final Ipv4Match ipv4) {
134 final Ipv4Prefix destination = ipv4.getIpv4Destination();
135 if (destination != null) {
136 // TODO: consider using IetfInetUtil
137 Iterator<String> addressParts = IpConversionUtil.PREFIX_SPLITTER.split(destination.getValue()).iterator();
138 matchBuilder.setNwDst(new Ipv4Address(addressParts.next()));
139 matchBuilder.setNwDstMask(buildPrefix(addressParts));
144 * Method splits the IP address and its mask and set their respective values in MatchV10Builder instance.
145 * Wildcard value of the IP mask will be determined by Openflow java encoding library.
147 * @param matchBuilder match builder
148 * @param ipv4 ip v4 match
150 private static void convertL3Ipv4SrcMatch(final MatchV10Builder matchBuilder, final Ipv4Match ipv4) {
151 final Ipv4Prefix source = ipv4.getIpv4Source();
152 if (source != null) {
153 // TODO: consider IetfInetUtil
154 Iterator<String> addressParts = IpConversionUtil.PREFIX_SPLITTER.split(source.getValue()).iterator();
155 matchBuilder.setNwSrc(new Ipv4Address(addressParts.next()));
156 matchBuilder.setNwSrcMask(buildPrefix(addressParts));
160 private static Uint8 buildPrefix(final Iterator<String> addressParts) {
161 return addressParts.hasNext() ? Uint8.valueOf(addressParts.next()) : DEFAULT_PREFIX;
164 private static boolean convertDlVlanPcp(final MatchV10Builder matchBuilder, final VlanMatch vlanMatch) {
165 final var vlanPcp = vlanMatch.getVlanPcp();
166 if (vlanPcp != null) {
167 matchBuilder.setDlVlanPcp(vlanPcp.getValue());
173 private static boolean convertDlVlan(final MatchV10Builder matchBuilder, final VlanMatch vlanMatch) {
174 final var id = vlanMatch.getVlanId();
176 final Uint16 vlanId = id.getVlanId().getValue();
177 matchBuilder.setDlVlan(Uint16.ZERO.equals(vlanId) ? OFP_VLAN_NONE : vlanId);
183 private static boolean convertEthernetDlType(final MatchV10Builder matchBuilder,
184 final EthernetMatch ethernetMatch) {
185 final var ethType = ethernetMatch.getEthernetType();
186 if (ethType != null) {
187 matchBuilder.setDlType(Uint16.valueOf(ethType.getType().getValue().intValue()));
193 private static boolean convertEthernetDlSrc(final MatchV10Builder matchBuilder,
194 final EthernetMatch ethernetMatch) {
195 final var ethSource = ethernetMatch.getEthernetSource();
196 if (ethSource != null) {
197 matchBuilder.setDlSrc(ethSource.getAddress());
203 private static boolean convertEthernetDlDst(final MatchV10Builder matchBuilder,
204 final EthernetMatch ethernetMatch) {
205 if (ethernetMatch.getEthernetDestination() != null) {
206 matchBuilder.setDlDst(ethernetMatch.getEthernetDestination().getAddress());
212 private static boolean convertInPortMatch(final MatchV10Builder matchBuilder, final NodeConnectorId inPort) {
213 if (inPort != null) {
214 matchBuilder.setInPort(Uint16.valueOf(
215 InventoryDataServiceUtil.portNumberfromNodeConnectorId(OpenflowVersion.OF10, inPort).intValue()));
222 * Create default empty match v10
223 * Use this method, if result from converter is empty.
225 public static MatchV10 defaultResult() {
226 return new MatchV10Builder().build();
230 public Collection<Class<?>> getTypes() {
235 public MatchV10 convert(final Match source, final VersionConvertorData data) {
236 MatchV10Builder matchBuilder = new MatchV10Builder()
237 .setInPort(Uint16.ZERO)
240 .setDlType(Uint16.ZERO)
241 .setDlVlan(OFP_VLAN_NONE)
242 .setDlVlanPcp(Uint8.ZERO)
244 .setNwDstMask(Uint8.ZERO)
246 .setNwSrcMask(Uint8.ZERO)
247 .setNwProto(Uint8.ZERO)
248 .setNwTos(Uint8.ZERO)
249 .setTpSrc(Uint16.ZERO)
250 .setTpDst(Uint16.ZERO);
252 boolean dlDst = true;
253 boolean dlSsc = true;
254 boolean dlType = true;
255 boolean dlVlan = true;
256 boolean dlVlanPcp = true;
257 boolean ipPort = true;
258 boolean nwProto = true;
259 boolean nwTos = true;
260 boolean tpDst = true;
261 boolean tpSrc = true;
263 if (source != null) {
264 EthernetMatch ethernetMatch = source.getEthernetMatch();
265 if (ethernetMatch != null) {
266 dlDst = convertEthernetDlDst(matchBuilder, ethernetMatch);
267 dlSsc = convertEthernetDlSrc(matchBuilder, ethernetMatch);
268 dlType = convertEthernetDlType(matchBuilder, ethernetMatch);
270 VlanMatch vlanMatch = source.getVlanMatch();
271 if (vlanMatch != null) {
272 dlVlan = convertDlVlan(matchBuilder, vlanMatch);
273 dlVlanPcp = convertDlVlanPcp(matchBuilder, vlanMatch);
275 NodeConnectorId inPort = source.getInPort();
276 if (inPort != null) {
277 ipPort = convertInPortMatch(matchBuilder, inPort);
279 Layer3Match l3Match = source.getLayer3Match();
280 if (l3Match != null) {
281 if (l3Match instanceof Ipv4Match) {
282 Ipv4Match ipv4 = (Ipv4Match) l3Match;
283 convertL3Ipv4SrcMatch(matchBuilder, ipv4);
284 convertL3Ipv4DstMatch(matchBuilder, ipv4);
287 IpMatch ipMatch = source.getIpMatch();
288 if (ipMatch != null) {
289 nwProto = convertNwProto(matchBuilder, ipMatch);
290 nwTos = convertNwTos(matchBuilder, ipMatch);
292 Layer4Match layer4Match = source.getLayer4Match();
293 if (layer4Match != null) {
294 if (layer4Match instanceof TcpMatch) {
295 TcpMatch tcpMatch = (TcpMatch) layer4Match;
296 tpSrc = convertL4TpSrcMatch(matchBuilder, tcpMatch);
297 tpDst = convertL4TpDstMatch(matchBuilder, tcpMatch);
298 } else if (layer4Match instanceof UdpMatch) {
299 UdpMatch udpMatch = (UdpMatch) layer4Match;
300 tpSrc = convertL4UdpSrcMatch(matchBuilder, udpMatch);
301 tpDst = convertL4UdpDstMatch(matchBuilder, udpMatch);
304 Icmpv4Match icmpv4Match = source.getIcmpv4Match();
305 if (icmpv4Match != null) {
306 Uint8 type = icmpv4Match.getIcmpv4Type();
308 matchBuilder.setTpSrc(Uint16.valueOf(type));
311 Uint8 code = icmpv4Match.getIcmpv4Code();
313 matchBuilder.setTpDst(Uint16.valueOf(code));
321 .setWildcards(new FlowWildcardsV10(
322 dlDst, dlSsc, dlType, dlVlan, dlVlanPcp, ipPort, nwProto, nwTos, tpDst, tpSrc))