2 * Copyright (c) 2014 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.controller.sal.compatibility;
10 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.CRUDP;
11 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.ETHERNET_ARP;
12 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.TCP;
13 import static org.opendaylight.controller.sal.compatibility.ProtocolConstants.UDP;
14 import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
15 import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
16 import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
18 import java.net.Inet4Address;
19 import java.net.Inet6Address;
20 import java.net.InetAddress;
22 import org.opendaylight.controller.sal.core.NodeConnector;
23 import org.opendaylight.controller.sal.match.Match;
24 import org.opendaylight.controller.sal.match.MatchField;
25 import org.opendaylight.controller.sal.match.MatchType;
26 import org.opendaylight.controller.sal.utils.NetUtils;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
28 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
30 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
31 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv6Builder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpSourceHardwareAddressBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.arp.match.fields.ArpTargetHardwareAddressBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetDestinationBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetSourceBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.ethernet.match.fields.EthernetTypeBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatch;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.EthernetMatchBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatch;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.IpMatchBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer4Match;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatch;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.VlanMatchBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.ArpMatchBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.SctpMatchBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.TcpMatchBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._4.match.UdpMatchBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.vlan.match.fields.VlanIdBuilder;
62 import com.google.common.net.InetAddresses;
65 * MD-SAL to AD-SAL conversions collection
67 public final class FromSalConversionsUtils {
69 /** http://en.wikipedia.org/wiki/IPv4#Packet_structure (end of octet number 1, bit 14.+15.) */
70 public static final int ENC_FIELD_BIT_SIZE = 2;
72 private FromSalConversionsUtils() {
73 throw new IllegalAccessError("forcing no instance for factory");
76 @SuppressWarnings("unused")
77 private static Address addressFromAction(InetAddress inetAddress) {
78 String strInetAddresss = InetAddresses.toAddrString(inetAddress);
79 if (inetAddress instanceof Inet4Address) {
80 Ipv4Builder ipv4Builder = new Ipv4Builder();
81 ipv4Builder.setIpv4Address(new Ipv4Prefix(strInetAddresss));
82 return ipv4Builder.build();
83 } else if (inetAddress instanceof Inet6Address) {
84 Ipv6Builder ipv6Builder = new Ipv6Builder();
85 ipv6Builder.setIpv6Address(new Ipv6Prefix(strInetAddresss));
86 return ipv6Builder.build();
91 public static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match toMatch(
93 if (sourceMatch != null) {
94 MatchBuilder targetBuilder = new MatchBuilder();
96 targetBuilder.setEthernetMatch(ethernetMatch(sourceMatch));
97 targetBuilder.setIpMatch(ipMatch(sourceMatch));
98 targetBuilder.setVlanMatch(vlanMatch(sourceMatch));
99 targetBuilder.setLayer3Match(layer3Match(sourceMatch));
100 targetBuilder.setLayer4Match(layer4Match(sourceMatch));
101 targetBuilder.setInPort(inPortMatch(sourceMatch));
103 return targetBuilder.build();
109 private static NodeConnectorId inPortMatch(Match sourceMatch) {
110 MatchField inPort = sourceMatch.getField(MatchType.IN_PORT);
111 if(inPort != null && inPort.getValue() != null && (inPort.getValue() instanceof NodeConnector)) {
112 NodeConnector port = (NodeConnector)inPort.getValue();
113 return (NodeConnectorId)MDFlowMapping.toUri(port);
118 private static Layer4Match layer4Match(final Match sourceMatch) {
119 MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO);
120 Short nwProtocolSource = null;
121 if (nwProto != null && nwProto.getValue() != null) {
122 nwProtocolSource = (short) ((byte) nwProto.getValue());
123 switch (nwProtocolSource) {
125 return Layer4MatchAsTcp(sourceMatch);
127 return Layer4MatchAsUdp(sourceMatch);
129 return Layer4MatchAsSctp(sourceMatch);
135 private static Layer4Match Layer4MatchAsSctp(final Match sourceMatch) {
136 SctpMatchBuilder sctpMatchBuilder = new SctpMatchBuilder();
138 Integer sourcePort = transportPort(sourceMatch, MatchType.TP_SRC);
139 Integer destinationPort = transportPort(sourceMatch,
142 if (sourcePort != null) {
143 sctpMatchBuilder.setSctpSourcePort(new PortNumber(sourcePort));
145 if (destinationPort != null) {
146 sctpMatchBuilder.setSctpDestinationPort(new PortNumber(
149 if(sourcePort != null || destinationPort != null) {
150 return sctpMatchBuilder.build();
155 private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) {
156 UdpMatchBuilder udpMatchBuilder = new UdpMatchBuilder();
158 Integer sourcePort = transportPort(sourceMatch, MatchType.TP_SRC);
159 Integer destinationPort = transportPort(sourceMatch,
162 if (sourcePort != null) {
163 udpMatchBuilder.setUdpSourcePort(new PortNumber(sourcePort));
166 if (destinationPort != null) {
167 udpMatchBuilder.setUdpDestinationPort(new PortNumber(
170 if(sourcePort != null || destinationPort != null) {
171 return udpMatchBuilder.build();
176 private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) {
177 TcpMatchBuilder tcpMatchBuilder = new TcpMatchBuilder();
179 Integer sourcePort = transportPort(sourceMatch, MatchType.TP_SRC);
180 Integer destinationPort = transportPort(sourceMatch,
183 if (sourcePort != null) {
184 tcpMatchBuilder.setTcpSourcePort(new PortNumber(sourcePort));
186 if (destinationPort != null) {
187 tcpMatchBuilder.setTcpDestinationPort(new PortNumber(
190 if(sourcePort != null || destinationPort != null) {
191 return tcpMatchBuilder.build();
196 private static Integer transportPort(final Match sourceMatch,
197 final MatchType matchType) {
198 MatchField transportPort = sourceMatch.getField(matchType);
199 if (transportPort != null && transportPort.getValue() != null
200 && transportPort.getValue().getClass().equals(Short.class)) {
201 return new Integer(NetUtils.getUnsignedShort((short) transportPort
207 private static VlanMatch vlanMatch(final Match sourceMatch) {
208 VlanMatchBuilder vlanMatchBuild = new VlanMatchBuilder();
210 MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
211 if (vlan != null && vlan.getValue() != null) {
212 VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
213 short vid = (short)vlan.getValue();
214 boolean present = (vid != MatchType.DL_VLAN_NONE);
215 vlanIDBuilder.setVlanId(new VlanId((NetUtils
216 .getUnsignedShort(vid))));
217 vlanIDBuilder.setVlanIdPresent(present);
218 vlanMatchBuild.setVlanId(vlanIDBuilder.build());
221 MatchField vlanPriority = sourceMatch.getField(MatchType.DL_VLAN_PR);
222 if (vlanPriority != null && vlanPriority.getValue() != null) {
223 vlanMatchBuild.setVlanPcp(new VlanPcp((short) ((byte) vlanPriority
226 if((vlan != null && vlan.getValue() != null) || (vlanPriority != null && vlanPriority.getValue() != null)) {
227 return vlanMatchBuild.build();
232 private static IpMatch ipMatch(final Match sourceMatch) {
233 IpMatchBuilder targetIpMatchBuild = new IpMatchBuilder();
234 MatchField networkTos = sourceMatch.getField(MatchType.NW_TOS);
235 if (networkTos != null && networkTos.getValue() != null) {
236 Dscp dscp = new Dscp(
237 (short) (NetUtils.getUnsignedByte((Byte) networkTos
239 targetIpMatchBuild.setIpDscp(dscp);
242 MatchField protocol = sourceMatch.getField(MatchType.NW_PROTO);
243 if (protocol != null && protocol.getValue() != null) {
244 targetIpMatchBuild.setIpProtocol((short) ((byte) protocol
247 if((networkTos != null && networkTos.getValue() != null) || (protocol != null && protocol.getValue() != null)) {
248 return targetIpMatchBuild.build();
253 private static EthernetMatch ethernetMatch(final Match sourceMatch) {
254 final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder();
255 if(sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) {
256 EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
257 .setAddress(ethernetSourceAddress(sourceMatch));
258 targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
260 if(sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null) {
261 EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder()
262 .setAddress(ethernetDestAddress(sourceMatch));
263 targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
266 final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE);
267 if (dataLinkType != null && dataLinkType.getValue() != null) {
268 EtherType etherType = new EtherType(new Long(
269 NetUtils.getUnsignedShort((Short) dataLinkType.getValue())));
270 EthernetTypeBuilder ethType = new EthernetTypeBuilder()
272 targetEthMatchBuild.setEthernetType(ethType.build());
274 if((sourceMatch.getField(DL_SRC) != null && sourceMatch.getField(DL_SRC).getValue() != null) ||
275 (sourceMatch.getField(DL_DST) != null && sourceMatch.getField(DL_DST).getValue() != null)||
276 dataLinkType != null ) {
277 return targetEthMatchBuild.build();
282 private static MacAddress ethernetSourceAddress(final Match sourceMatch) {
283 final MatchField dataLinkSource = sourceMatch.getField(DL_SRC);
284 if (dataLinkSource != null && dataLinkSource.getValue() != null) {
285 return MDFlowMapping.toMacAddress((byte[])dataLinkSource.getValue());
291 private static Layer3Match layer3Match(final Match sourceMatch) {
292 InetAddress inetSourceAddress = null;
293 MatchField netSource = sourceMatch.getField(MatchType.NW_SRC);
294 if (netSource != null && netSource.getValue() != null) {
295 inetSourceAddress = (InetAddress) (netSource.getValue());
298 InetAddress inetDestAddress = null;
299 MatchField netDest = sourceMatch.getField(MatchType.NW_DST);
300 if (netDest != null && netDest.getValue() != null) {
301 inetDestAddress = (InetAddress) (netDest.getValue());
304 if ((inetSourceAddress instanceof Inet4Address)
305 || (inetDestAddress instanceof Inet4Address)) {
306 MatchField dataLinkType = sourceMatch.getField(DL_TYPE);
308 if (dataLinkType != null && dataLinkType.getValue() != null) {
309 dLType = (Short) (dataLinkType.getValue());
311 if (dLType != null && dLType.equals(ETHERNET_ARP)) {
312 return setLayer3MatchAsArp(sourceMatch,
313 (Inet4Address) inetSourceAddress,
314 (Inet4Address) inetDestAddress);
316 return setLayer3MatchAsIpv4((Inet4Address) inetSourceAddress,
317 (Inet4Address) inetDestAddress);
319 } else if ((inetSourceAddress instanceof Inet6Address)
320 || (inetDestAddress instanceof Inet6Address)) {
321 return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress,
322 (Inet6Address) inetDestAddress);
329 private static Layer3Match setLayer3MatchAsArp(final Match sourceMatch,
330 final Inet4Address inetSourceAddress,
331 final Inet4Address inetDestAddress) {
332 String inetSourceAddressStr = InetAddresses
333 .toAddrString(inetSourceAddress);
334 Ipv4Prefix ipv4SourcePrefix = new Ipv4Prefix(inetSourceAddressStr + "/32");
336 String inetDestAddressValue = InetAddresses
337 .toAddrString(inetDestAddress);
338 Ipv4Prefix ipv4DestPrefix = new Ipv4Prefix(inetDestAddressValue + "/32");
340 ArpMatchBuilder arpMatchBuilder = new ArpMatchBuilder();
342 arpMatchBuilder.setArpSourceTransportAddress(ipv4SourcePrefix);
343 arpMatchBuilder.setArpTargetTransportAddress(ipv4DestPrefix);
345 ArpSourceHardwareAddressBuilder arpSourceHardwareAddressBuilder = new ArpSourceHardwareAddressBuilder();
346 arpSourceHardwareAddressBuilder
347 .setAddress(ethernetSourceAddress(sourceMatch));
349 .setArpSourceHardwareAddress(arpSourceHardwareAddressBuilder
352 ArpTargetHardwareAddressBuilder arpTargetHardwareAddressBuilder = new ArpTargetHardwareAddressBuilder();
353 arpTargetHardwareAddressBuilder
354 .setAddress(ethernetDestAddress(sourceMatch));
356 .setArpTargetHardwareAddress(arpTargetHardwareAddressBuilder
359 return arpMatchBuilder.build();
363 private static MacAddress ethernetDestAddress(final Match sourceMatch) {
364 final MatchField dataLinkDest = sourceMatch.getField(DL_DST);
365 if (dataLinkDest != null && dataLinkDest.getValue() != null) {
366 return MDFlowMapping.toMacAddress((byte[]) dataLinkDest.getValue());
371 private static Layer3Match setLayer3MatchAsIpv4(
372 final Inet4Address inetSourceAddress,
373 final Inet4Address inetDestAddress) {
374 Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder();
375 if(inetSourceAddress != null) {
376 String inetSrcAddressString = InetAddresses
377 .toAddrString(inetSourceAddress);
378 layer4MatchBuild.setIpv4Source(new Ipv4Prefix(inetSrcAddressString + "/32"));
380 if(inetDestAddress != null) {
381 String inetDstAddressString = InetAddresses
382 .toAddrString(inetDestAddress);
384 .setIpv4Destination(new Ipv4Prefix(inetDstAddressString + "/32"));
386 return layer4MatchBuild.build();
390 private static Layer3Match setLayer3MatchAsIpv6(
391 final Inet6Address inetSourceAddress,
392 final Inet6Address inetDestAddress) {
393 Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder();
394 if(inetSourceAddress != null) {
395 String inetSrcAddressString = InetAddresses
396 .toAddrString(inetSourceAddress);
397 layer6MatchBuild.setIpv6Source(new Ipv6Prefix(inetSrcAddressString + "/128"));
399 if(inetDestAddress != null) {
400 String inetDstAddressString = InetAddresses
401 .toAddrString(inetDestAddress);
403 .setIpv6Destination(new Ipv6Prefix(inetDstAddressString + "/128"));
405 return layer6MatchBuild.build();
408 public static boolean flowEquals(Flow statsFlow, Flow storedFlow) {
409 if (statsFlow.getClass() != storedFlow.getClass()) {
412 if (statsFlow.getBufferId()== null) {
413 if (storedFlow.getBufferId() != null) {
416 } else if(!statsFlow.getBufferId().equals(storedFlow.getBufferId())) {
419 if (statsFlow.getContainerName()== null) {
420 if (storedFlow.getContainerName()!= null) {
423 } else if(!statsFlow.getContainerName().equals(storedFlow.getContainerName())) {
426 if (statsFlow.getCookie()== null) {
427 if (storedFlow.getCookie()!= null) {
430 } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
433 if (statsFlow.getMatch()== null) {
434 if (storedFlow.getMatch() != null) {
437 } else if(!statsFlow.getMatch().equals(storedFlow.getMatch())) {
440 if (statsFlow.getCookie()== null) {
441 if (storedFlow.getCookie()!= null) {
444 } else if(!statsFlow.getCookie().equals(storedFlow.getCookie())) {
447 if (statsFlow.getHardTimeout() == null) {
448 if (storedFlow.getHardTimeout() != null) {
451 } else if(!statsFlow.getHardTimeout().equals(storedFlow.getHardTimeout() )) {
454 if (statsFlow.getIdleTimeout()== null) {
455 if (storedFlow.getIdleTimeout() != null) {
458 } else if(!statsFlow.getIdleTimeout().equals(storedFlow.getIdleTimeout())) {
461 if (statsFlow.getPriority() == null) {
462 if (storedFlow.getPriority() != null) {
465 } else if(!statsFlow.getPriority().equals(storedFlow.getPriority())) {
468 if (statsFlow.getTableId() == null) {
469 if (storedFlow.getTableId() != null) {
472 } else if(!statsFlow.getTableId().equals(storedFlow.getTableId())) {
479 * @param nwDscp NW-DSCP
480 * @return shifted to NW-TOS (with empty ECN part)
482 public static int dscpToTos(int nwDscp) {
483 return (short) (nwDscp << ENC_FIELD_BIT_SIZE);