BUG 4132 - backport to lithium
authorJosh <jhershbe@redhat.com>
Wed, 13 Jan 2016 13:46:28 +0000 (15:46 +0200)
committerJosh <jhershbe@redhat.com>
Sat, 16 Jan 2016 15:59:21 +0000 (17:59 +0200)
Fix in master:
https://git.opendaylight.org/gerrit/#/c/32324/
(this is a mod to the commit msg in an attempt
to trigger a build)

Change-Id: I5e2253d08acc24345a27ac3752795d40994e486a
Signed-off-by: Josh <jhershbe@redhat.com>
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/ConfigActivator.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/Service.java
openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IcmpEchoResponderService.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/ConfigActivator.java
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IcmpEchoProvider.java [new file with mode: 0644]
openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/impl/NeutronL3Adapter.java
utils/mdsal-openflow/src/main/java/org/opendaylight/ovsdb/utils/mdsal/openflow/ActionUtils.java

index 3e2115bbc6c141c1c65b563bcb9bdd003799a06b..203b9309753a930616fa72b4dfa0b04442b3a861 100644 (file)
@@ -1,3 +1,11 @@
+/*
+ * Copyright (c) 2015, 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
 package org.opendaylight.ovsdb.openstack.netvirt.providers;
 
 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
@@ -8,6 +16,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.ConfigurationService;
 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EgressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IcmpEchoProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.L2ForwardingProvider;
@@ -28,6 +37,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.ArpResponderService;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.ClassifierService;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.EgressAclService;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.IcmpEchoResponderService;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.InboundNatService;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.IngressAclService;
 import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services.L2ForwardingService;
@@ -128,6 +138,9 @@ public class ConfigActivator implements BundleActivator {
                 gatewayMacResolverService, Service.GATEWAY_RESOLVER);
         getNotificationProviderService().registerNotificationListener(gatewayMacResolverService);
 
+        IcmpEchoResponderService icmpEchoResponderService = new IcmpEchoResponderService();
+        registerService(context, IcmpEchoProvider.class.getName(),
+                                            icmpEchoResponderService, Service.ICMP_ECHO);
 
         pipelineOrchestrator.setDependencies(context, null);
         outboundNatService.setDependencies(context, null);
@@ -143,6 +156,7 @@ public class ConfigActivator implements BundleActivator {
         classifierService.setDependencies(context, null);
         of13Provider.setDependencies(context, null);
         gatewayMacResolverService.setDependencies(context, null);
+        icmpEchoResponderService.setDependencies(context, null);
 
         @SuppressWarnings("unchecked")
         ServiceTracker NetworkingProviderManagerTracker = new ServiceTracker(context,
index c401a3b23d9fbdfbabadc48008077b9a5e75f69a..4fce9f15678e5b22c6da95058a089ead263c41dd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014 - 2016 Red Hat, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -16,6 +16,7 @@ public enum Service {
     GATEWAY_RESOLVER((short) 0, "External Network Gateway Resolver"),
     DIRECTOR ((short) 10, "Director"),
     ARP_RESPONDER ((short) 20, "Distributed ARP Responder"),
+    ICMP_ECHO ((short) 20, "Distributed ICMP Echo Responder"),
     INBOUND_NAT ((short) 30, "DNAT for inbound floating-ip traffic"),
     EGRESS_ACL ((short) 40, "Egress Acces-control"),
     LOAD_BALANCER ((short) 50, "Distributed LBaaS"),
diff --git a/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IcmpEchoResponderService.java b/openstack/net-virt-providers/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/providers/openflow13/services/IcmpEchoResponderService.java
new file mode 100644 (file)
index 0000000..431fa6e
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.services;
+
+import com.google.common.collect.Lists;
+import org.opendaylight.ovsdb.openstack.netvirt.api.*;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.OF13Provider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
+import org.opendaylight.ovsdb.utils.mdsal.openflow.MatchUtils;
+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.action.types.rev131112.action.list.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.address.Ipv4Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.math.BigInteger;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.util.List;
+
+/**
+ * @author Josh Hershberg (jhershbe@redhat.com)
+ */
+public class IcmpEchoResponderService extends AbstractServiceInstance implements IcmpEchoProvider, ConfigInterface {
+    private static final Logger LOG = LoggerFactory.getLogger(IcmpEchoResponderService.class);
+
+    public IcmpEchoResponderService() {
+        super(Service.ICMP_ECHO);
+    }
+
+    public IcmpEchoResponderService(Service service) {
+        super(service);
+    }
+
+    @Override
+    public Status programIcmpEchoEntry(Long dpid, String segmentationId, String macAddressStr, InetAddress ipAddress, Action action) {
+        String nodeName = Constants.OPENFLOW_NODE_PREFIX + dpid;
+        MacAddress macAddress = new MacAddress(macAddressStr);
+
+        MatchBuilder matchBuilder = new MatchBuilder();
+        NodeBuilder nodeBuilder = OF13Provider.createNodeBuilder(nodeName);
+
+        // Instructions List Stores Individual Instructions
+        InstructionsBuilder isb = new InstructionsBuilder();
+        List<Instruction> instructions = Lists.newArrayList();
+        InstructionBuilder ib = new InstructionBuilder();
+        ApplyActionsBuilder aab = new ApplyActionsBuilder();
+        ActionBuilder ab = new ActionBuilder();
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action> actionList = Lists.newArrayList();
+
+        if (segmentationId != null) {
+            final Long inPort = MatchUtils.parseExplicitOFPort(segmentationId);
+            if (inPort != null) {
+                MatchUtils.createInPortMatch(matchBuilder, dpid, inPort);
+            } else {
+                MatchUtils.createTunnelIDMatch(matchBuilder, new BigInteger(segmentationId));
+            }
+        }
+
+        if (ipAddress instanceof Inet6Address) {
+            // WORKAROUND: For now ipv6 is not supported
+            // TODO: implement ipv6 case
+            LOG.debug("ipv6 address case is not implemented yet. dpid {} segmentationId {} macAddressStr, ipAddress {} action {}",
+                    dpid, segmentationId, macAddressStr, ipAddress, action);
+            return new Status(StatusCode.NOTIMPLEMENTED);
+        }
+
+        // Match ICMP echo requests, type=8, code=0
+        MatchUtils.createICMPv4Match(matchBuilder, (short)8, (short)0);
+        MatchUtils.createDstL3IPv4Match(matchBuilder, MatchUtils.iPv4PrefixFromIPv4Address(ipAddress.getHostAddress()));
+
+        // Move Eth Src to Eth Dst
+        ab.setAction(ActionUtils.nxMoveEthSrcToEthDstAction());
+        ab.setOrder(0);
+        ab.setKey(new ActionKey(0));
+        actionList.add(ab.build());
+
+        // Set Eth Src
+        ab.setAction(ActionUtils.setDlSrcAction(new MacAddress(macAddress)));
+        ab.setOrder(1);
+        ab.setKey(new ActionKey(1));
+        actionList.add(ab.build());
+
+        // Move Ip Src to Ip Dst
+        ab.setAction(ActionUtils.nxMoveIpSrcToIpDstAction());
+        ab.setOrder(2);
+        ab.setKey(new ActionKey(2));
+        actionList.add(ab.build());
+
+        // Set Ip Src
+        ab.setAction(ActionUtils.setNwSrcAction(new Ipv4Builder().setIpv4Address(
+                                    MatchUtils.iPv4PrefixFromIPv4Address(ipAddress.getHostAddress())).build()));
+        ab.setOrder(3);
+        ab.setKey(new ActionKey(3));
+        actionList.add(ab.build());
+
+        // Set the ICMP type to 0 (echo reply)
+        ab.setAction(ActionUtils.setIcmpTypeAction((byte)0));
+        ab.setOrder(4);
+        ab.setKey(new ActionKey(4));
+        actionList.add(ab.build());
+
+        // Output of InPort
+        ab.setAction(ActionUtils.outputAction(new NodeConnectorId(nodeName + ":INPORT")));
+        ab.setOrder(5);
+        ab.setKey(new ActionKey(5));
+        actionList.add(ab.build());
+
+        // Create Apply Actions Instruction
+        aab.setAction(actionList);
+        ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+        ib.setOrder(0);
+        ib.setKey(new InstructionKey(0));
+        instructions.add(ib.build());
+
+        FlowBuilder flowBuilder = new FlowBuilder();
+        String flowId = "IcmpEchoResponder_" + segmentationId + "_" + ipAddress.getHostAddress();
+
+        flowBuilder.setId(new FlowId(flowId));
+        FlowKey key = new FlowKey(new FlowId(flowId));
+        flowBuilder.setBarrier(true);
+        flowBuilder.setTableId(this.getTable());
+        flowBuilder.setKey(key);
+        flowBuilder.setPriority(1024);
+        flowBuilder.setFlowName(flowId);
+        flowBuilder.setHardTimeout(0);
+        flowBuilder.setIdleTimeout(0);
+
+        flowBuilder.setMatch(matchBuilder.build());
+        flowBuilder.setInstructions(isb.setInstruction(instructions).build());
+
+        if (action.equals(Action.ADD)) {
+            writeFlow(flowBuilder, nodeBuilder);
+        } else {
+            removeFlow(flowBuilder, nodeBuilder);
+        }
+
+        // ToDo: WriteFlow/RemoveFlow should return something we can use to check success
+        return new Status(StatusCode.SUCCESS);
+    }
+
+    @Override
+    public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+        super.setDependencies(bundleContext.getServiceReference(IcmpEchoProvider.class.getName()), this);
+    }
+
+    @Override
+    public void setDependencies(Object impl) {}
+}
index e54241ccbe0c944bed4f54ba18626b54f24b5e6e..557e6224f6bf423d57ae437852de4983eaad4832 100644 (file)
@@ -36,6 +36,7 @@ public class ConfigActivator implements BundleActivator {
     private ServiceTracker gatewayMacResolverProviderTracker;
     private ServiceTracker ingressAclProviderTracker;
     private ServiceTracker egressAclProviderTracker;
+    private ServiceTracker icmpEchoProviderTracker;
 
     public ConfigActivator(ProviderContext providerContext) {
         this.providerContext = providerContext;
@@ -468,6 +469,22 @@ public class ConfigActivator implements BundleActivator {
         egressAclProviderTracker.open();
         this.egressAclProviderTracker = egressAclProviderTracker;
 
+        @SuppressWarnings("unchecked")
+        ServiceTracker icmpEchoResponderServiceTracker = new ServiceTracker(context,
+                IcmpEchoProvider.class, null) {
+            @Override
+            public Object addingService(ServiceReference reference) {
+                LOG.info("addingService IcmpEchoProvider");
+                IcmpEchoProvider service = (IcmpEchoProvider) context.getService(reference);
+                if(service != null) {
+                    neutronL3Adapter.setDependencies(service);
+                }
+                return service;
+            }
+        };
+        icmpEchoResponderServiceTracker.open();
+        this.icmpEchoProviderTracker = icmpEchoResponderServiceTracker;
+
     }
 
 
diff --git a/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IcmpEchoProvider.java b/openstack/net-virt/src/main/java/org/opendaylight/ovsdb/openstack/netvirt/api/IcmpEchoProvider.java
new file mode 100644 (file)
index 0000000..4e429bf
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016 Red Hat, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.ovsdb.openstack.netvirt.api;
+
+import java.net.InetAddress;
+
+/**
+ * @author Josh Hershberg (jhershbe@redhat.com)
+ */
+public interface IcmpEchoProvider {
+
+    Status programIcmpEchoEntry(Long dpid, String segmentationId,
+                                 String macAddress, InetAddress ipAddress, Action action);
+}
index 8f26c2ac420b6d9a2406e9a16120d83a23da5cfc..fe49b19f5968738088002f106d4810b6b178903e 100644 (file)
@@ -1,5 +1,5 @@
  /*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014, 2016 Red Hat, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -34,6 +34,7 @@ import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
 import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolver;
 import org.opendaylight.ovsdb.openstack.netvirt.api.GatewayMacResolverListener;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IcmpEchoProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.InboundNatProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.L3ForwardingProvider;
 import org.opendaylight.ovsdb.openstack.netvirt.api.NodeCacheManager;
@@ -88,6 +89,7 @@ public class NeutronL3Adapter extends AbstractHandler implements GatewayMacResol
     private volatile RoutingProvider routingProvider;
     private volatile GatewayMacResolver gatewayMacResolver;
     private volatile SecurityServicesManager securityServicesManager;
+    private volatile IcmpEchoProvider icmpEchoProvider;
 
     private class FloatIpData {
         private final Long dpid;          // br-int of node where floating ip is associated with tenant port
@@ -849,6 +851,7 @@ public class NeutronL3Adapter extends AbstractHandler implements GatewayMacResol
                             actionForNode);
                 }
                 programStaticArpStage1(dpid, destinationSegmentationId, macAddress, ipStr, actionForNode);
+                programIcmpEcho(dpid, destinationSegmentationId, macAddress, ipStr, actionForNode);
             }
 
             // Compute action to be programmed. In the case of rewrite exclusions, we must never program rules
@@ -1025,6 +1028,41 @@ public class NeutronL3Adapter extends AbstractHandler implements GatewayMacResol
         return status;
     }
 
+    private boolean programIcmpEcho(Long dpid, String segOrOfPort,
+                                           String macAddress, String ipStr,
+                                           Action action) {
+        if (action == Action.DELETE ) {
+            LOGGER.trace("Deleting Flow : programIcmpEcho dpid {} segOrOfPort {} mac {} ip {} action {}",
+                    dpid, segOrOfPort, macAddress, ipStr, action);
+        }
+        if (action == Action.ADD) {
+            LOGGER.trace("Adding Flow : programIcmpEcho dpid {} segOrOfPort {} mac {} ip {} action {}",
+                    dpid, segOrOfPort, macAddress, ipStr, action);
+        }
+
+        Status status = new Status(StatusCode.UNSUPPORTED);
+        if (icmpEchoProvider != null){
+            try {
+                InetAddress inetAddress = InetAddress.getByName(ipStr);
+                status = icmpEchoProvider.programIcmpEchoEntry(dpid, segOrOfPort,
+                                                macAddress, inetAddress, action);
+            } catch (UnknownHostException e) {
+                status = new Status(StatusCode.BADREQUEST);
+            }
+        }
+
+        if (status.isSuccess()) {
+            LOGGER.debug("programIcmpEcho {} for mac:{} addr:{} dpid:{} segOrOfPort:{} action:{}",
+                    icmpEchoProvider == null ? "skipped" : "programmed",
+                    macAddress, ipStr, dpid, segOrOfPort, action);
+        } else {
+            LOGGER.error("programIcmpEcho failed for mac:{} addr:{} dpid:{} segOrOfPort:{} action:{} status:{}",
+                    macAddress, ipStr, dpid, segOrOfPort, action, status);
+        }
+
+        return status.isSuccess();
+    }
+
     private boolean programStaticArpStage1(Long dpid, String segOrOfPort,
                                            String macAddress, String ipStr,
                                            Action action) {
@@ -1442,6 +1480,7 @@ public class NeutronL3Adapter extends AbstractHandler implements GatewayMacResol
                 (GatewayMacResolver) ServiceHelper.getGlobalInstance(GatewayMacResolver.class, this);
         securityServicesManager =
                 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+
         initL3AdapterMembers();
     }
 
@@ -1465,6 +1504,8 @@ public class NeutronL3Adapter extends AbstractHandler implements GatewayMacResol
             l3ForwardingProvider = (L3ForwardingProvider)impl;
         }else if (impl instanceof GatewayMacResolver) {
             gatewayMacResolver = (GatewayMacResolver)impl;
+        }else if (impl instanceof IcmpEchoProvider) {
+            icmpEchoProvider = (IcmpEchoProvider)impl;
         }
     }
 }
index 7f30c1cd6445d42569a6a0dc70e84cc0b4651ea5..26570b895fd818e0ac88dfa8f8323e75ab790cf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2014 Red Hat, Inc.
+ * Copyright (C) 2014, 2016 Red Hat, Inc.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
@@ -34,6 +34,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.acti
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.action.set.nw.src.action._case.SetNwSrcActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.address.Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Icmpv4MatchBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.TunnelBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
@@ -46,6 +47,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpSpaCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfArpTpaCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfEthDstCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstOfIpDstCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegLoadNodesNodeGroupBucketsBucketActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.group.buckets.bucket.action.action.NxActionRegMoveNodesNodeGroupBucketsBucketActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionOutputRegNodesNodeTableFlowApplyActionsCaseBuilder;
@@ -64,6 +66,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcNxRegCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfArpSpaCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfEthSrcCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.src.choice.grouping.src.choice.SrcOfIpSrcCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxHashFields;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.OfjNxMpAlgorithm;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionMultipathNodesNodeTableFlowApplyActionsCaseBuilder;
@@ -234,6 +237,14 @@ public final class ActionUtils {
         return nxLoadArpSpaAction(BigInteger.valueOf(ipl));
     }
 
+    public static Action setIcmpTypeAction(byte value) {
+        SetFieldBuilder setFieldBuilder = new SetFieldBuilder();
+        setFieldBuilder.setIcmpv4Match(new Icmpv4MatchBuilder().setIcmpv4Type((short)value).build());
+        return new SetFieldCaseBuilder()
+                .setSetField(setFieldBuilder.build())
+                .build();
+    }
+
     public static Action nxMoveRegAction(SrcChoice srcChoice,
                                          DstChoice dstChoice,
                                          int endOffset,
@@ -297,6 +308,12 @@ public final class ActionUtils {
                                    .setOfArpTpa(Boolean.TRUE).build());
     }
 
+    public static Action nxMoveIpSrcToIpDstAction() {
+        return nxMoveRegAction(new SrcOfIpSrcCaseBuilder().setOfIpSrc(Boolean.TRUE).build(),
+                               new DstOfIpDstCaseBuilder().setOfIpDst(Boolean.TRUE).build());
+    }
+
+
     public static Action nxOutputRegAction(SrcChoice srcChoice) {
         NxOutputReg r = new NxOutputRegBuilder()
             .setSrc(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.output.reg.grouping.nx.output.reg.SrcBuilder()