import org.opendaylight.controller.sal.action.Flood;
import org.opendaylight.controller.sal.action.Output;
import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.core.Config;
import org.opendaylight.controller.sal.core.ContainerFlow;
import org.opendaylight.controller.sal.core.IContainer;
import org.opendaylight.controller.sal.core.IContainerListener;
IConfigurationContainerAware,
IInventoryListener,
IObjectReader,
- ICacheUpdateAware,
+ ICacheUpdateAware<Object,Object>,
CommandProvider,
IFlowProgrammerListener {
private static final String NODEDOWN = "Node is Down";
retrieveCaches();
}
- @SuppressWarnings("deprecation")
private void allocateCaches() {
if (this.clusterContainerService == null) {
log.warn("Un-initialized clusterContainerService, can't create cache");
}
}
- @SuppressWarnings({ "unchecked", "deprecation" })
+ @SuppressWarnings({ "unchecked" })
private void retrieveCaches() {
ConcurrentMap<?, ?> map;
@Override
public void notifyNodeConnector(NodeConnector nodeConnector, UpdateType type, Map<String, Property> propMap) {
+ boolean updateStaticFlowCluster = false;
+
+ switch (type) {
+ case ADDED:
+ break;
+ case CHANGED:
+ Config config = (propMap == null) ? null : (Config) propMap.get(Config.ConfigPropName);
+ if (config != null) {
+ switch (config.getValue()) {
+ case Config.ADMIN_DOWN:
+ log.trace("Port {} is administratively down: uninstalling interested flows", nodeConnector);
+ updateStaticFlowCluster = removeFlowsOnNodeConnectorDown(nodeConnector);
+ break;
+ case Config.ADMIN_UP:
+ log.trace("Port {} is administratively up: installing interested flows", nodeConnector);
+ updateStaticFlowCluster = installFlowsOnNodeConnectorUp(nodeConnector);
+ break;
+ case Config.ADMIN_UNDEF:
+ break;
+ default:
+ }
+ }
+ break;
+ case REMOVED:
+ // This is the case where a switch port is removed from the SDN agent space
+ log.trace("Port {} was removed from our control: uninstalling interested flows", nodeConnector);
+ updateStaticFlowCluster = removeFlowsOnNodeConnectorDown(nodeConnector);
+ break;
+ default:
+
+ }
+
+ if (updateStaticFlowCluster) {
+ refreshClusterStaticFlowsStatus(nodeConnector.getNode());
+ }
+ }
+
+ /*
+ * It goes through the static flows configuration, it identifies the ones
+ * which have the specified node connector as input or output port and
+ * install them on the network node if they are marked to be installed in
+ * hardware and their status shows they were not installed yet
+ */
+ private boolean installFlowsOnNodeConnectorUp(NodeConnector nodeConnector) {
+ boolean updated = false;
+ List<FlowConfig> flowConfigForNode = getStaticFlows(nodeConnector.getNode());
+ for (FlowConfig flowConfig : flowConfigForNode) {
+ if (doesFlowContainNodeConnector(flowConfig.getFlow(), nodeConnector)) {
+ if (flowConfig.installInHw() && !flowConfig.getStatus().equals(SUCCESS)) {
+ Status status = this.installFlowEntry(flowConfig.getFlowEntry());
+ if (!status.isSuccess()) {
+ flowConfig.setStatus(status.getDescription());
+ } else {
+ flowConfig.setStatus(SUCCESS);
+ }
+ updated = true;
+ }
+ }
+ }
+ return updated;
+ }
+ /*
+ * Remove from the network node all the flows which have the specified node
+ * connector as input or output port. If any of the flow entry is a static
+ * flow, it updates the correspondent configuration.
+ */
+ private boolean removeFlowsOnNodeConnectorDown(NodeConnector nodeConnector) {
+ boolean updated = false;
+ List<FlowEntryInstall> nodeFlowEntries = nodeFlows.get(nodeConnector.getNode());
+ if (nodeFlowEntries == null) {
+ return updated;
+ }
+ for (FlowEntryInstall fei : new ArrayList<FlowEntryInstall>(nodeFlowEntries)) {
+ if (doesFlowContainNodeConnector(fei.getInstall().getFlow(), nodeConnector)) {
+ Status status = this.removeEntryInternal(fei, true);
+ if (!status.isSuccess()) {
+ continue;
+ }
+ /*
+ * If the flow entry is a static flow, then update its
+ * configuration
+ */
+ if (fei.getGroupName().equals(FlowConfig.STATICFLOWGROUP)) {
+ FlowConfig flowConfig = getStaticFlow(fei.getFlowName(), fei.getNode());
+ if (flowConfig != null) {
+ flowConfig.setStatus(PORTREMOVED);
+ updated = true;
+ }
+ }
+ }
+ }
+ return updated;
}
private FlowConfig getDerivedFlowConfig(FlowConfig original, String configName, Short port) {
switch (t) {
case REMOVED:
-
- List<FlowEntryInstall> nodeFlowEntries = nodeFlows.get(nc.getNode());
- if (nodeFlowEntries == null) {
- return;
- }
- for (FlowEntryInstall fei : new ArrayList<FlowEntryInstall>(nodeFlowEntries)) {
- if (doesFlowContainNodeConnector(fei.getInstall().getFlow(), nc)) {
- Status status = this.removeEntryInternal(fei, true);
- if (!status.isSuccess()) {
- continue;
- }
- /*
- * If the flow entry is a static flow, then update its
- * configuration
- */
- if (fei.getGroupName().equals(FlowConfig.STATICFLOWGROUP)) {
- FlowConfig flowConfig = getStaticFlow(fei.getFlowName(), fei.getNode());
- if (flowConfig != null) {
- flowConfig.setStatus(PORTREMOVED);
- updateStaticFlowCluster = true;
- }
- }
- }
- }
- if (updateStaticFlowCluster) {
- refreshClusterStaticFlowsStatus(nc.getNode());
- }
+ log.trace("Port {} was removed from container: uninstalling interested flows", nc);
+ updateStaticFlowCluster = removeFlowsOnNodeConnectorDown(nc);
break;
case ADDED:
- List<FlowConfig> flowConfigForNode = getStaticFlows(nc.getNode());
- for (FlowConfig flowConfig : flowConfigForNode) {
- if (doesFlowContainNodeConnector(flowConfig.getFlow(), nc)) {
- if (flowConfig.installInHw()) {
- Status status = this.installFlowEntry(flowConfig.getFlowEntry());
- if (!status.isSuccess()) {
- flowConfig.setStatus(status.getDescription());
- } else {
- flowConfig.setStatus(SUCCESS);
- }
- updateStaticFlowCluster = true;
- }
- }
- }
- if (updateStaticFlowCluster) {
- refreshClusterStaticFlowsStatus(nc.getNode());
- }
+ log.trace("Port {} was added to container: reinstall interested flows", nc);
+ updateStaticFlowCluster = installFlowsOnNodeConnectorUp(nc);
+
break;
case CHANGED:
break;
default:
}
+
+ if (updateStaticFlowCluster) {
+ refreshClusterStaticFlowsStatus(nc.getNode());
+ }
}
@Override
--- /dev/null
+package org.opendaylight.controller.sal.compability;
+
+import static org.opendaylight.controller.sal.match.MatchType.DL_DST;
+import static org.opendaylight.controller.sal.match.MatchType.DL_SRC;
+import static org.opendaylight.controller.sal.match.MatchType.DL_TYPE;
+
+import java.math.BigInteger;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.opendaylight.controller.sal.action.Controller;
+import org.opendaylight.controller.sal.action.Drop;
+import org.opendaylight.controller.sal.action.Flood;
+import org.opendaylight.controller.sal.action.FloodAll;
+import org.opendaylight.controller.sal.action.HwPath;
+import org.opendaylight.controller.sal.action.Loopback;
+import org.opendaylight.controller.sal.action.Output;
+import org.opendaylight.controller.sal.action.PopVlan;
+import org.opendaylight.controller.sal.action.PushVlan;
+import org.opendaylight.controller.sal.action.SetDlDst;
+import org.opendaylight.controller.sal.action.SetDlSrc;
+import org.opendaylight.controller.sal.action.SetDlType;
+import org.opendaylight.controller.sal.action.SetNextHop;
+import org.opendaylight.controller.sal.action.SetNwDst;
+import org.opendaylight.controller.sal.action.SetNwSrc;
+import org.opendaylight.controller.sal.action.SetNwTos;
+import org.opendaylight.controller.sal.action.SetTpDst;
+import org.opendaylight.controller.sal.action.SetTpSrc;
+import org.opendaylight.controller.sal.action.SetVlanCfi;
+import org.opendaylight.controller.sal.action.SetVlanId;
+import org.opendaylight.controller.sal.action.SetVlanPcp;
+import org.opendaylight.controller.sal.action.SwPath;
+import org.opendaylight.controller.sal.core.NodeConnector;
+import org.opendaylight.controller.sal.flowprogrammer.Flow;
+import org.opendaylight.controller.sal.match.Match;
+import org.opendaylight.controller.sal.match.MatchField;
+import org.opendaylight.controller.sal.match.MatchType;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Dscp;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.PortNumber;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Uri;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev100924.MacAddress;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAdded;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.service.rev130819.FlowAddedBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.ControllerActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.action.OutputActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.EtherType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanPcp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.arp.match.fields.ArpSourceHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.arp.match.fields.ArpTargetHardwareAddressBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetDestinationBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetSourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.ethernet.match.fields.EthernetTypeBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.EthernetMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.EthernetMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.IpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.IpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.Layer3Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.Layer4Match;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.VlanMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.VlanMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.ArpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.Ipv4MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._3.match.Ipv6MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.SctpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.TcpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.match.layer._4.match.UdpMatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev130819.vlan.match.fields.VlanIdBuilder;
+
+public class FromSalConversionsUtils {
+
+ // source: http://en.wikipedia.org/wiki/Ethertype
+ private static final Short ETHERNET_ARP = new Short((short) 0x0806);
+
+ // source: http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
+ private static final short TCP = (short) 0x06;
+ private static final short UDP = (short) 0x11;
+ private static final short SCTP = (short) 0x84;
+
+ private FromSalConversionsUtils() {
+
+ }
+
+ public static FlowAdded flowFrom(Flow sourceFlow) {
+ if (sourceFlow != null) {
+ final FlowAddedBuilder targetFlow = new FlowAddedBuilder();
+
+ targetFlow.setHardTimeout(new Integer(sourceFlow.getHardTimeout()));
+ targetFlow.setIdleTimeout(new Integer(sourceFlow.getIdleTimeout()));
+ targetFlow.setPriority(new Integer(sourceFlow.getPriority()));
+ targetFlow.setCookie(new BigInteger(String.valueOf(sourceFlow.getId())));
+
+ List<org.opendaylight.controller.sal.action.Action> sourceActions = sourceFlow.getActions();
+ List<Action> targetActions = new ArrayList<>();
+ for (org.opendaylight.controller.sal.action.Action sourceAction : sourceActions) {
+ targetActions.add(actionFrom(sourceAction));
+ }
+ targetFlow.setAction(targetActions);
+
+ targetFlow.setMatch(matchFrom(sourceFlow.getMatch()));
+
+ return targetFlow.build();
+ }
+ return null;
+ }
+
+ private static Action actionFrom(org.opendaylight.controller.sal.action.Action sourceAction) {
+
+ ActionBuilder targetActionBuilder = new ActionBuilder();
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.action.Action targetAction = null;
+
+ if (sourceAction instanceof Controller) {
+ targetAction = new ControllerActionBuilder().build();
+ } else if (sourceAction instanceof Drop) {
+ // TODO: define maping
+ } else if (sourceAction instanceof Flood) {
+ // TODO: define maping
+ } else if (sourceAction instanceof FloodAll) {
+ // TODO: define maping
+ } else if (sourceAction instanceof HwPath) {
+ // TODO: define maping
+ } else if (sourceAction instanceof Loopback) {
+ // TODO: define maping
+ } else if (sourceAction instanceof Output) {
+ NodeConnector nodeConnector = ((Output) sourceAction).getPort();
+
+ OutputActionBuilder outputActionBuilder = new OutputActionBuilder();
+ outputActionBuilder.setOutputNodeConnector(nodeConnectorToUri(nodeConnector));
+ targetAction = outputActionBuilder.build();
+
+ } else if (sourceAction instanceof PopVlan) {
+ // TODO: define maping
+ } else if (sourceAction instanceof PushVlan) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetDlDst) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetDlSrc) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetDlType) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetNextHop) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetNwDst) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetNwSrc) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetNwTos) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetTpDst) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetTpSrc) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetVlanCfi) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetVlanId) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SetVlanPcp) {
+ // TODO: define maping
+ } else if (sourceAction instanceof SwPath) {
+ // TODO: define maping
+ }
+
+ targetActionBuilder.setAction(targetAction);
+
+ return targetActionBuilder.build();
+ }
+
+ private static List<Uri> nodeConnectorToUri(NodeConnector nodeConnector) {
+ // TODO Define mapping
+ return null;
+ }
+
+ private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.Match matchFrom(
+ Match sourceMatch) {
+ if (sourceMatch != null) {
+ org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.MatchBuilder targetBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev130819.flow.MatchBuilder();
+
+ targetBuilder.setEthernetMatch(ethernetMatchFrom(sourceMatch));
+ targetBuilder.setIpMatch(ipMatchFrom(sourceMatch));
+ targetBuilder.setVlanMatch(vlanMatchFrom(sourceMatch));
+ targetBuilder.setLayer3Match(layer3Match(sourceMatch));
+ targetBuilder.setLayer4Match(layer4Match(sourceMatch));
+
+ return targetBuilder.build();
+ }
+ return null;
+
+ }
+
+ private static Layer4Match layer4Match(final Match sourceMatch) {
+ MatchField nwProto = sourceMatch.getField(MatchType.NW_PROTO);
+ Short nwProtocolSource = null;
+ if (nwProto != null && nwProto.getValue() != null) {
+ nwProtocolSource = (Short) (nwProto.getValue());
+ }
+
+ switch (nwProtocolSource) {
+ case TCP:
+ return Layer4MatchAsTcp(sourceMatch);
+ case UDP:
+ return Layer4MatchAsUdp(sourceMatch);
+ case SCTP:
+ return Layer4MatchAsSctp(sourceMatch);
+ }
+ return null;
+ }
+
+ private static Layer4Match Layer4MatchAsSctp(final Match sourceMatch) {
+ SctpMatchBuilder sctpMatchBuilder = new SctpMatchBuilder();
+
+ Integer sourcePort = transportPortFrom(sourceMatch, MatchType.TP_SRC);
+ Integer destinationPort = transportPortFrom(sourceMatch, MatchType.TP_DST);
+
+ if (sourcePort != null) {
+ sctpMatchBuilder.setSctpSourcePort(new PortNumber(sourcePort));
+ }
+ if (destinationPort != null) {
+ sctpMatchBuilder.setSctpDestinationPort(new PortNumber(destinationPort));
+ }
+
+ return sctpMatchBuilder.build();
+ }
+
+ private static Layer4Match Layer4MatchAsUdp(final Match sourceMatch) {
+ UdpMatchBuilder udpMatchBuilder = new UdpMatchBuilder();
+
+ Integer sourcePort = transportPortFrom(sourceMatch, MatchType.TP_SRC);
+ Integer destinationPort = transportPortFrom(sourceMatch, MatchType.TP_DST);
+
+ if (sourcePort != null) {
+ udpMatchBuilder.setUdpSourcePort(new PortNumber(sourcePort));
+ }
+
+ if (destinationPort != null) {
+ udpMatchBuilder.setUdpDestinationPort(new PortNumber(destinationPort));
+ }
+
+ return udpMatchBuilder.build();
+ }
+
+ private static Layer4Match Layer4MatchAsTcp(final Match sourceMatch) {
+ TcpMatchBuilder tcpMatchBuilder = new TcpMatchBuilder();
+
+ Integer sourcePort = transportPortFrom(sourceMatch, MatchType.TP_SRC);
+ Integer destinationPort = transportPortFrom(sourceMatch, MatchType.TP_DST);
+
+ if (sourcePort != null) {
+ tcpMatchBuilder.setTcpSourcePort(new PortNumber(sourcePort));
+ }
+ if (destinationPort != null) {
+ tcpMatchBuilder.setTcpDestinationPort(new PortNumber(destinationPort));
+ }
+
+ return tcpMatchBuilder.build();
+ }
+
+ private static Integer transportPortFrom(final Match sourceMatch, final MatchType matchType) {
+ MatchField transportPort = sourceMatch.getField(matchType);
+ if (transportPort != null && transportPort.getValue() != null) {
+ return (Integer) (transportPort.getValue());
+ }
+ return null;
+ }
+
+ private static VlanMatch vlanMatchFrom(final Match sourceMatch) {
+ VlanMatchBuilder vlanMatchBuild = new VlanMatchBuilder();
+
+ MatchField vlan = sourceMatch.getField(MatchType.DL_VLAN);
+ if (vlan != null && vlan.getValue() != null) {
+ VlanIdBuilder vlanIDBuilder = new VlanIdBuilder();
+ vlanIDBuilder.setVlanId(new VlanId((Integer) (vlan.getValue())));
+ vlanMatchBuild.setVlanId(vlanIDBuilder.build());
+ }
+
+ MatchField vlanPriority = sourceMatch.getField(MatchType.DL_VLAN_PR);
+ if (vlanPriority != null && vlanPriority.getValue() != null) {
+ vlanMatchBuild.setVlanPcp(new VlanPcp((Short) (vlanPriority.getValue())));
+ }
+
+ return vlanMatchBuild.build();
+ }
+
+ private static IpMatch ipMatchFrom(final Match sourceMatch) {
+ IpMatchBuilder targetIpMatchBuild = new IpMatchBuilder();
+ MatchField networkTos = sourceMatch.getField(MatchType.NW_TOS);
+ if (networkTos != null && networkTos.getValue() != null) {
+ Dscp dscp = new Dscp((Short) (networkTos.getValue()));
+ targetIpMatchBuild.setIpDscp(dscp);
+ }
+
+ MatchField protocol = sourceMatch.getField(MatchType.NW_PROTO);
+ if (protocol != null && protocol.getValue() != null) {
+ targetIpMatchBuild.setIpProtocol((Short) (protocol.getValue()));
+ }
+
+ return targetIpMatchBuild.build();
+
+ }
+
+ private static EthernetMatch ethernetMatchFrom(final Match sourceMatch) {
+ final EthernetMatchBuilder targetEthMatchBuild = new EthernetMatchBuilder();
+
+ EthernetSourceBuilder ethSourBuild = new EthernetSourceBuilder()
+ .setAddress(ethernetSourceAddressFrom(sourceMatch));
+ targetEthMatchBuild.setEthernetSource(ethSourBuild.build());
+
+ final MatchField dataLinkDest = sourceMatch.getField(DL_DST);
+ if (dataLinkDest != null && dataLinkDest.getValue() != null) {
+ final MacAddress macDestAddress;
+ macDestAddress = new MacAddress((String) (dataLinkDest.getValue()));
+ EthernetDestinationBuilder ethDestBuild = new EthernetDestinationBuilder().setAddress(macDestAddress);
+ targetEthMatchBuild.setEthernetDestination(ethDestBuild.build());
+ }
+
+ final MatchField dataLinkType = sourceMatch.getField(MatchType.DL_TYPE);
+ if (dataLinkType != null && dataLinkType.getValue() != null) {
+ EtherType etherType = new EtherType((Long) (dataLinkType.getValue()));
+ EthernetTypeBuilder ethType = new EthernetTypeBuilder().setType(etherType);
+ targetEthMatchBuild.setEthernetType(ethType.build());
+ }
+ return targetEthMatchBuild.build();
+ }
+
+ private static MacAddress ethernetSourceAddressFrom(final Match sourceMatch) {
+ final MatchField dataLinkSource = sourceMatch.getField(DL_SRC);
+ if (dataLinkSource != null && dataLinkSource.getValue() != null) {
+ return new MacAddress(new MacAddress((String) (dataLinkSource.getValue())));
+ }
+ return null;
+
+ }
+
+ private static Layer3Match layer3Match(final Match sourceMatch) {
+ InetAddress inetSourceAddress = null;
+ MatchField netSource = sourceMatch.getField(MatchType.NW_SRC);
+ if (netSource != null && netSource.getValue() != null) {
+ inetSourceAddress = (InetAddress) (netSource.getValue());
+ }
+
+ InetAddress inetDestAddress = null;
+ MatchField netDest = sourceMatch.getField(MatchType.NW_DST);
+ if (netSource != null && netSource.getValue() != null) {
+ inetDestAddress = (InetAddress) (netDest.getValue());
+ }
+
+ if ((inetSourceAddress instanceof Inet4Address) && (inetDestAddress instanceof Inet4Address)) {
+ MatchField dataLinkType = sourceMatch.getField(DL_TYPE);
+ Short dLType = null;
+ if (dataLinkType != null && dataLinkType.getValue() != null) {
+ dLType = (Short) (dataLinkType.getValue());
+ }
+ if (dLType.equals(ETHERNET_ARP)) {
+ return setLayer3MatchAsArp(sourceMatch, (Inet4Address) inetSourceAddress,
+ (Inet4Address) inetDestAddress);
+ } else {
+ return setLayer3MatchAsIpv4((Inet4Address) inetSourceAddress, (Inet4Address) inetDestAddress);
+ }
+ } else if ((inetSourceAddress instanceof Inet6Address) && (inetDestAddress instanceof Inet6Address)) {
+ return setLayer3MatchAsIpv6((Inet6Address) inetSourceAddress, (Inet6Address) inetDestAddress);
+ }
+
+ return null;
+
+ }
+
+ private static Layer3Match setLayer3MatchAsArp(final Match sourceMatch, final Inet4Address inetSourceAddress,
+ final Inet4Address inetDestAddress) {
+ byte[] inetSourceAddressValue = inetSourceAddress.getAddress();
+ Ipv4Prefix ipv4SourcePrefix = new Ipv4Prefix(Arrays.toString(inetSourceAddressValue));
+
+ byte[] inetDestAddressValue = inetDestAddress.getAddress();
+ Ipv4Prefix ipv4DestPrefix = new Ipv4Prefix(Arrays.toString(inetDestAddressValue));
+
+ ArpMatchBuilder arpMatchBuilder = new ArpMatchBuilder();
+
+ arpMatchBuilder.setArpSourceTransportAddress(ipv4SourcePrefix);
+ arpMatchBuilder.setArpSourceTransportAddress(ipv4DestPrefix);
+
+ ArpSourceHardwareAddressBuilder arpSourceHardwareAddressBuilder = new ArpSourceHardwareAddressBuilder();
+ arpSourceHardwareAddressBuilder.setAddress(ethernetSourceAddressFrom(sourceMatch));
+ arpMatchBuilder.setArpSourceHardwareAddress(arpSourceHardwareAddressBuilder.build());
+
+ ArpTargetHardwareAddressBuilder arpTargetHardwareAddressBuilder = new ArpTargetHardwareAddressBuilder();
+ arpTargetHardwareAddressBuilder.setAddress(ethernetDestAddressFrom(sourceMatch));
+ arpMatchBuilder.setArpTargetHardwareAddress(arpTargetHardwareAddressBuilder.build());
+
+ return arpMatchBuilder.build();
+
+ }
+
+ private static MacAddress ethernetDestAddressFrom(final Match sourceMatch) {
+ final MatchField dataLinkDest = sourceMatch.getField(DL_DST);
+ if (dataLinkDest != null && dataLinkDest.getValue() != null) {
+ return new MacAddress((String) (dataLinkDest.getValue()));
+ }
+ return null;
+ }
+
+ private static Layer3Match setLayer3MatchAsIpv4(final Inet4Address inetSourceAddress,
+ final Inet4Address inetDestAddress) {
+ byte[] inetAddressValue = inetSourceAddress.getAddress();
+
+ Ipv4MatchBuilder layer4MatchBuild = new Ipv4MatchBuilder();
+ layer4MatchBuild.setIpv4Source(new Ipv4Prefix(Arrays.toString(inetAddressValue)));
+ return layer4MatchBuild.build();
+
+ }
+
+ private static Layer3Match setLayer3MatchAsIpv6(final Inet6Address inetSourceAddress,
+ final Inet6Address inetDestAddress) {
+ byte[] inetAddressValue = inetSourceAddress.getAddress();
+ Ipv6MatchBuilder layer6MatchBuild = new Ipv6MatchBuilder();
+
+ layer6MatchBuild.setIpv6Source(new Ipv6Prefix(Arrays.toString(inetAddressValue)));
+ return layer6MatchBuild.build();
+ }
+
+}