NAT Action added in Nicira Extension 70/49770/16
authorAswin Suryanarayanan <asuryana@redhat.com>
Fri, 23 Dec 2016 08:50:25 +0000 (14:20 +0530)
committerAnil Vishnoi <vishnoianil@gmail.com>
Fri, 10 Feb 2017 08:50:20 +0000 (08:50 +0000)
Nat action is added as a port of conntrack action, it is an optional
action field.

Change-Id: Iec97d9d859e0e2060abc3a31ceb929c1b1e43b4a
Signed-off-by: Aswin Suryanarayanan <asuryana@redhat.com>
extension/openflowjava-extension-nicira/src/main/java/org/opendaylight/openflowjava/nx/codec/action/ConntrackCodec.java
extension/openflowjava-extension-nicira/src/main/yang/nicira-action.yang
extension/openflowjava-extension-nicira/src/test/java/org/opendaylight/openflowjava/nx/codec/action/ConntrackCodecTest.java
extension/openflowplugin-extension-nicira/src/main/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertor.java
extension/openflowplugin-extension-nicira/src/main/yang/openflowplugin-extension-nicira-action.yang
extension/openflowplugin-extension-nicira/src/test/java/org/opendaylight/openflowplugin/extension/vendor/nicira/convertor/action/ConntrackConvertorTest.java

index ca615eff2a3c9c670bfa130442ed9d9decd589c5..a3b624141ac995254c8e07d00fbf2a0c35871acd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Hewlett-Packard Enterprise and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 Hewlett-Packard Enterprise 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,
@@ -9,24 +9,46 @@
 package org.opendaylight.openflowjava.nx.codec.action;
 
 import io.netty.buffer.ByteBuf;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
 import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
 import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrack;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrackBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.NxActionConntrackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNatBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.net.InetAddresses;
+
 /**
  * @author Aswin Suryanarayanan.
  */
 
 public class ConntrackCodec extends AbstractActionCodec {
-    public static final int LENGTH = 24;
+    private static final Logger LOG = LoggerFactory.getLogger( ConntrackCodec.class);
+    public static final int CT_LENGTH = 24;
+    public static final int NX_NAT_LENGTH = 16;
+    public static final int SHORT_LENGTH = 2;
+    public static final int INT_LENGTH = 4;
+
     public static final byte NXAST_CONNTRACK_SUBTYPE = 35;
+    public static final byte NXAST_NAT_SUBTYPE = 36;
     public static final NiciraActionSerializerKey SERIALIZER_KEY =
             new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionConntrack.class);
     public static final NiciraActionDeserializerKey DESERIALIZER_KEY =
@@ -34,14 +56,85 @@ public class ConntrackCodec extends AbstractActionCodec {
 
     @Override
     public void serialize(final Action input, final ByteBuf outBuffer) {
-        ActionConntrack action = ((ActionConntrack) input.getActionChoice());
-        serializeHeader(LENGTH, NXAST_CONNTRACK_SUBTYPE, outBuffer);
+        LOG.trace("serialize :conntrack");
+        ActionConntrack action = (ActionConntrack) input.getActionChoice();
+        int length = getActionLength(action);
+        int pad = length % 8;
+        serializeHeader(length + pad + CT_LENGTH, NXAST_CONNTRACK_SUBTYPE, outBuffer);
 
         outBuffer.writeShort(action.getNxActionConntrack().getFlags().shortValue());
         outBuffer.writeInt(action.getNxActionConntrack().getZoneSrc().intValue());
         outBuffer.writeShort(action.getNxActionConntrack().getConntrackZone().shortValue());
         outBuffer.writeByte(action.getNxActionConntrack().getRecircTable().byteValue());
         outBuffer.writeZero(5);
+        serializeCtAction(outBuffer,action, length);
+    }
+
+    private int getActionLength(final ActionConntrack action) {
+        int length = 0;
+        List<CtActions> ctActionsList = action.getNxActionConntrack().getCtActions();
+        if (ctActionsList == null) {
+            return length;
+        }
+        for (CtActions ctActions : ctActionsList) {
+            if (ctActions.getOfpactActions() instanceof NxActionNatCase) {
+                length += NX_NAT_LENGTH;
+                NxActionNatCase nxActionNatCase = (NxActionNatCase)ctActions.getOfpactActions();
+                NxActionNat natAction = nxActionNatCase.getNxActionNat();
+                short rangePresent = natAction.getRangePresent().shortValue();
+                if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue())) {
+                    length += INT_LENGTH;
+                }
+                if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MAX.getIntValue())) {
+                    length += INT_LENGTH;
+                }
+                if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMIN.getIntValue())) {
+                    length += SHORT_LENGTH;
+                }
+                if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMAX.getIntValue())) {
+                    length += SHORT_LENGTH;
+                }
+            }
+        }
+        LOG.trace("ActionLength :conntrack: length {}",length);
+        return length;
+    }
+
+    private void serializeCtAction(final ByteBuf outBuffer, final ActionConntrack action, final int length) {
+        List<CtActions> ctActionsList = action.getNxActionConntrack().getCtActions();
+        if (ctActionsList != null) {
+            for (CtActions ctActions : ctActionsList) {
+                if (ctActions.getOfpactActions() instanceof NxActionNatCase){
+                    NxActionNatCase nxActionNatCase = (NxActionNatCase)ctActions.getOfpactActions();
+                    NxActionNat natAction = nxActionNatCase.getNxActionNat();
+                    int pad = length % 8;
+                    serializeHeader(length + pad, NXAST_NAT_SUBTYPE, outBuffer);
+                    outBuffer.writeZero(2);
+                    outBuffer.writeShort(natAction.getFlags().shortValue());
+                    short rangePresent = natAction.getRangePresent().shortValue();
+                    outBuffer.writeShort(rangePresent);
+                    if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue())) {
+                        if (null != natAction.getIpAddressMin()) {
+                            outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(natAction
+                                    .getIpAddressMin().getIpv4Address()));
+                        }
+                    }
+                    if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MAX.getIntValue())) {
+                        if (null != natAction.getIpAddressMax()) {
+                            outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(natAction
+                                    .getIpAddressMax().getIpv4Address()));
+                        }
+                    }
+                    if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMIN.getIntValue())) {
+                        outBuffer.writeShort(natAction.getPortMin());
+                    }
+                    if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMAX.getIntValue())) {
+                        outBuffer.writeShort(natAction.getPortMax());
+                    }
+                    outBuffer.writeZero(pad);
+                }
+            }
+        }
     }
 
     @Override
@@ -55,9 +148,42 @@ public class ConntrackCodec extends AbstractActionCodec {
         nxActionConntrackBuilder.setConntrackZone(message.readUnsignedShort());
         nxActionConntrackBuilder.setRecircTable(message.readUnsignedByte());
         message.skipBytes(5);
+        dserializeCtAction(message,nxActionConntrackBuilder);
         actionConntrackBuilder.setNxActionConntrack(nxActionConntrackBuilder.build());
         actionBuilder.setActionChoice(actionConntrackBuilder.build());
 
         return actionBuilder.build();
     }
+
+    private void dserializeCtAction(final ByteBuf message, final NxActionConntrackBuilder nxActionConntrackBuilder) {
+        deserializeHeader(message);
+
+        NxActionNatBuilder nxActionNatBuilder = new NxActionNatBuilder();
+        message.skipBytes(2);
+        nxActionNatBuilder.setFlags(message.readUnsignedShort());
+
+        int rangePresent = message.readUnsignedShort();
+        nxActionNatBuilder.setRangePresent(rangePresent);
+        if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue())) {
+            InetAddress address = InetAddresses.fromInteger((int)message.readUnsignedInt());
+            nxActionNatBuilder.setIpAddressMin(new IpAddress(address.getHostAddress().toCharArray()));
+        }
+        if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MAX.getIntValue())) {
+            InetAddress address = InetAddresses.fromInteger((int)message.readUnsignedInt());
+            nxActionNatBuilder.setIpAddressMax(new IpAddress(address.getHostAddress().toCharArray()));
+        }
+        if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMIN.getIntValue())) {
+            nxActionNatBuilder.setPortMin(message.readUnsignedShort());
+        }
+        if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMAX.getIntValue())) {
+            nxActionNatBuilder.setPortMax(message.readUnsignedShort());
+        }
+        NxActionNatCaseBuilder caseBuilder = new NxActionNatCaseBuilder();
+        caseBuilder.setNxActionNat(nxActionNatBuilder.build());
+        CtActionsBuilder ctActionsBuilder = new CtActionsBuilder();
+        ctActionsBuilder.setOfpactActions(caseBuilder.build());
+        List<CtActions> ctActionsList = new ArrayList<>();
+        ctActionsList.add(ctActionsBuilder.build());
+        nxActionConntrackBuilder.setCtActions(ctActionsList);
+    }
 }
index 8194f8bca8095a59593b5881b819e3b466966cba..7479f5af11e765e84586410cbc25dbf302cf778b 100644 (file)
@@ -7,6 +7,7 @@ module nicira-action {
     import openflow-action {prefix ofaction; revision-date "2015-02-03";}
     import openflow-types {prefix oft;}
     import yang-ext {prefix ext; revision-date "2013-07-09";}
+    import ietf-inet-types { prefix "inet"; revision-date "2013-07-15"; }
 
     description
         "Nicira openflow extensions of action.";
@@ -163,6 +164,60 @@ module nicira-action {
         }
     }
 
+    typedef nx-action-nat-range-present {
+        type enumeration {
+            enum NX_NAT_RANGE_IPV4_MIN {
+                value 1;
+                description "IPV4 minimum value is present";
+            }
+            enum NX_NAT_RANGE_IPV4_MAX {
+                value 2;
+                description "IPV4 maximum value is present";
+            }
+            enum NX_NAT_RANGE_IPV6_MIN {
+                value 4;
+                description "IPV6 minimum value is present in range";
+            }
+            enum NX_NAT_RANGE_IPV6_MAX {
+                value 8;
+                description "IPV6 maximum value is present in range";
+            }
+            enum NX_NAT_RANGE_PROTO_MIN {
+                value 16;
+                description "Port minimum value is present in range";
+            }
+            enum NX_NAT_RANGE_PROTO_MAX {
+                value 32;
+                description "Port maximum value is present in range";
+            }
+        }
+    }
+
+    typedef nx-action-nat-flags {
+        type enumeration {
+            enum NX_NAT_F_SRC {
+                value 1;
+                description "Source nat is selected ,Mutually exclusive with NX_NAT_F_DST";
+            }
+            enum NX_NAT_F_DST {
+                value 2;
+                description "Destination nat is selected";
+            }
+            enum NX_NAT_F_PERSISTENT {
+                value 4;
+                description "Persistant flag is selected";
+            }
+            enum NX_NAT_F_PROTO_HASH {
+                value 8;
+                description "Hash mode is selected for port mapping, Mutually exclusive with PROTO_RANDOM ";
+            }
+            enum NX_NAT_F_PROTO_RANDOM {
+                value 16;
+                description "Port mapping will be randomized";
+            }
+        }
+    }
+
     grouping ofj-nx-action-multipath-grouping {
         container nx-action-multipath {
             leaf fields {
@@ -225,6 +280,39 @@ module nicira-action {
             leaf experimenter-id {
                 type oft:experimenter-id;
             }
+            list ct-actions{
+                uses ofpact-actions;
+            }
+        }
+    }
+
+    grouping ofpact-actions {
+        description
+           "Actions to be performed with conntrack.";
+        choice ofpact-actions {
+            case nx-action-nat-case {
+                container nx-action-nat {
+                    leaf flags {
+                        type uint16;
+                    }
+                    leaf range_present {
+                        type uint16;
+                    }
+                    leaf ip-address-min {
+                        type inet:ip-address;
+                    }
+                    leaf ip-address-max {
+                        type inet:ip-address;
+                    }
+                    leaf port-min {
+                        type uint16;
+                    }
+                    leaf port-max {
+                        type uint16;
+                    }
+                }
+            }
+
         }
     }
 
index 933772c87a1220eda96851d1dd18da21baa2cb84..6e8343d861c40ea7ac4f6c4cabba113186317378 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2016, 2017 Cisco Systems, 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,
@@ -10,17 +10,30 @@ package org.opendaylight.openflowjava.nx.codec.action;
 
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
+
+import java.util.ArrayList;
+import java.util.List;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.openflowjava.nx.api.NiciraConstants;
 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.types.rev130731.ExperimenterId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrack;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrackBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.NxActionConntrackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNatBuilder;
 
 public class ConntrackCodecTest {
 
@@ -29,8 +42,10 @@ public class ConntrackCodecTest {
     private ByteBuf buffer;
     private Action action;
 
-    private final int LENGTH = 24;
-    private final byte NXAST_CONNTRACK_SUBTYPE = 35;
+    private final int length = 24;
+    private final byte nxastConntrackSubtype = 35;
+    private final int nxNatLength = 32;
+    private final byte nxastNatSubtype = 36;
 
     @Before
     public void setUp() {
@@ -43,16 +58,28 @@ public class ConntrackCodecTest {
         action = createAction();
         conntrackCodec.serialize(action, buffer);
 
-        Assert.assertEquals(24, buffer.readableBytes());
+        Assert.assertEquals(56, buffer.readableBytes());
         Assert.assertEquals(EncodeConstants.EXPERIMENTER_VALUE, buffer.readUnsignedShort());
-        Assert.assertEquals(LENGTH, buffer.readUnsignedShort());
+        Assert.assertEquals(length + nxNatLength, buffer.readUnsignedShort());
         Assert.assertEquals(NiciraConstants.NX_VENDOR_ID.intValue(), buffer.readUnsignedInt());
-        Assert.assertEquals(NXAST_CONNTRACK_SUBTYPE, buffer.readUnsignedShort());
+        Assert.assertEquals(nxastConntrackSubtype, buffer.readUnsignedShort());
         Assert.assertEquals(1, buffer.readUnsignedShort());
         Assert.assertEquals(2, buffer.readUnsignedInt());
         Assert.assertEquals(3, buffer.readUnsignedShort());
         Assert.assertEquals(4, buffer.readByte());
         buffer.skipBytes(5);
+        Assert.assertEquals(EncodeConstants.EXPERIMENTER_VALUE, buffer.readUnsignedShort());
+        Assert.assertEquals(nxNatLength, buffer.readUnsignedShort());
+        Assert.assertEquals(NiciraConstants.NX_VENDOR_ID.intValue(), buffer.readUnsignedInt());
+        Assert.assertEquals(nxastNatSubtype, buffer.readUnsignedShort());
+        buffer.skipBytes(2);
+        Assert.assertEquals(5, buffer.readUnsignedShort());
+        Assert.assertEquals(0x3F, buffer.readUnsignedShort());
+        Assert.assertEquals(3232235520L, buffer.readUnsignedInt());
+        Assert.assertEquals(3232238080L, buffer.readUnsignedInt());
+        Assert.assertEquals(3000, buffer.readUnsignedShort());
+        Assert.assertEquals(4000, buffer.readUnsignedShort());
+        buffer.skipBytes(4);
     }
 
     @Test
@@ -60,27 +87,51 @@ public class ConntrackCodecTest {
         createBufer(buffer);
         action = conntrackCodec.deserialize(buffer);
 
-        ActionConntrack result = ((ActionConntrack) action.getActionChoice());
+        ActionConntrack result = (ActionConntrack) action.getActionChoice();
 
         Assert.assertEquals(1, result.getNxActionConntrack().getFlags().shortValue());
         Assert.assertEquals(2, result.getNxActionConntrack().getZoneSrc().intValue());
         Assert.assertEquals(3, result.getNxActionConntrack().getConntrackZone().shortValue());
         Assert.assertEquals(4, result.getNxActionConntrack().getRecircTable().byteValue());
-        Assert.assertEquals(0, buffer.readableBytes());
+        List<CtActions> ctActions = result.getNxActionConntrack().getCtActions();
+        NxActionNatCase nxActionNatCase = (NxActionNatCase) ctActions.get(0).getOfpactActions();
+        NxActionNat natAction = nxActionNatCase.getNxActionNat();
+        Assert.assertEquals(5, natAction.getFlags().shortValue());
+        Assert.assertEquals(0x3F, natAction.getRangePresent().intValue());
+        Assert.assertEquals("192.168.0.0", natAction.getIpAddressMin().getIpv4Address().getValue());
+        Assert.assertEquals("192.168.10.0", natAction.getIpAddressMax().getIpv4Address().getValue());
+        Assert.assertEquals(3000, natAction.getPortMin().shortValue());
+        Assert.assertEquals(4000, natAction.getPortMax().shortValue());
 
     }
 
     private Action createAction() {
-        ExperimenterId experimenterId = new ExperimenterId(NiciraConstants.NX_VENDOR_ID);
-        ActionBuilder actionBuilder = new ActionBuilder();
-        actionBuilder.setExperimenterId(experimenterId);
-        ActionConntrackBuilder actionConntrackBuilder = new ActionConntrackBuilder();
 
         NxActionConntrackBuilder nxActionConntrackBuilder = new NxActionConntrackBuilder();
         nxActionConntrackBuilder.setFlags(1);
         nxActionConntrackBuilder.setZoneSrc((long) 2);
         nxActionConntrackBuilder.setConntrackZone(3);
         nxActionConntrackBuilder.setRecircTable((short) 4);
+
+        NxActionNatBuilder nxActionNatBuilder = new NxActionNatBuilder();
+        nxActionNatBuilder.setFlags(5);
+        nxActionNatBuilder.setRangePresent(0x3F);
+        nxActionNatBuilder.setIpAddressMin(new IpAddress("192.168.0.0".toCharArray()));
+        nxActionNatBuilder.setIpAddressMax(new IpAddress("192.168.10.0".toCharArray()));
+        nxActionNatBuilder.setPortMin(3000);
+        nxActionNatBuilder.setPortMax(4000);
+        NxActionNatCaseBuilder nxActionNatCaseBuilder = new NxActionNatCaseBuilder();
+        nxActionNatCaseBuilder.setNxActionNat(nxActionNatBuilder.build());
+        CtActionsBuilder ctActionsBuilder = new CtActionsBuilder();
+        ctActionsBuilder.setOfpactActions(nxActionNatCaseBuilder.build());
+        List<CtActions> ctActionsList = new  ArrayList<>();
+        ctActionsList.add(ctActionsBuilder.build());
+        nxActionConntrackBuilder.setCtActions(ctActionsList);
+
+        ExperimenterId experimenterId = new ExperimenterId(NiciraConstants.NX_VENDOR_ID);
+        ActionBuilder actionBuilder = new ActionBuilder();
+        actionBuilder.setExperimenterId(experimenterId);
+        ActionConntrackBuilder actionConntrackBuilder = new ActionConntrackBuilder();
         actionConntrackBuilder.setNxActionConntrack(nxActionConntrackBuilder.build());
         actionBuilder.setActionChoice(actionConntrackBuilder.build());
 
@@ -89,9 +140,9 @@ public class ConntrackCodecTest {
 
     private void createBufer(ByteBuf message) {
         message.writeShort(EncodeConstants.EXPERIMENTER_VALUE);
-        message.writeShort(LENGTH);
+        message.writeShort(length + nxastNatSubtype);
         message.writeInt(NiciraConstants.NX_VENDOR_ID.intValue());
-        message.writeShort(NXAST_CONNTRACK_SUBTYPE);
+        message.writeShort(nxastConntrackSubtype);
         //FLAG = 1
         message.writeShort(1);
         //ZONE_SRC = 2
@@ -102,5 +153,22 @@ public class ConntrackCodecTest {
         message.writeByte(4);
         //ADDS 5 empty bytes
         message.writeZero(5);
+        message.writeShort(EncodeConstants.EXPERIMENTER_VALUE);
+        message.writeShort(nxNatLength);
+        message.writeInt(NiciraConstants.NX_VENDOR_ID.intValue());
+        message.writeShort(nxastNatSubtype);
+        message.writeZero(2);
+        //NAT FLAG
+        message.writeShort(5);
+        //RANGE PRESENT
+        message.writeShort(0x3F);
+        //IP ADDRESS MIN
+        message.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(new Ipv4Address("192.168.0.0")));
+        //IP ADDRESS MAX
+        message.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(new Ipv4Address("192.168.10.0")));
+        //PORT MIN
+        message.writeShort(3000);
+        //PORT MAX
+        message.writeShort(4000);
     }
 }
\ No newline at end of file
index 8ee4ebe2274d2c9c9172857be5f225515255ffe3..0aaa1da2c75b50723e3ea30236eedba51d386de9 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015 Hewlett-Packard Enterprise and others.  All rights reserved.
+ * Copyright (c) 2015, 2017 Hewlett-Packard Enterprise 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,
@@ -9,6 +9,10 @@
 package org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action;
 
 import com.google.common.base.Preconditions;
+
+import java.util.ArrayList;
+import java.util.List;
+
 import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
 import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
@@ -27,26 +31,68 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrack;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.nx.conntrack.CtActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.nx.conntrack.CtActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.OfpactActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.NxActionNatCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.NxActionNatCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNatBuilder;
 
 /**
  * @author Aswin Suryanarayanan.
  */
 
 public class ConntrackConvertor implements
-        ConvertorActionToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action, Action>,
+        ConvertorActionToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action
+        .Action, Action>,
         ConvertorActionFromOFJava<Action, ActionPath> {
 
     @Override
-    public org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action convert(final Action input, final ActionPath path) {
+    public org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action
+                          .Action convert(final Action input, final ActionPath path) {
         NxActionConntrack action = ((ActionConntrack) input.getActionChoice()).getNxActionConntrack();
         NxConntrackBuilder builder = new NxConntrackBuilder();
         builder.setFlags(action.getFlags());
         builder.setZoneSrc(action.getZoneSrc());
         builder.setRecircTable(action.getRecircTable());
         builder.setConntrackZone(action.getConntrackZone());
+        builder.setCtActions(getCtAction(action));
         return resolveAction(builder.build(), path);
     }
 
+    private List<CtActions> getCtAction(final NxActionConntrack action) {
+        if (action.getCtActions() == null) {
+            return null;
+        }
+        List<CtActions> ctActions = new ArrayList<CtActions>();
+        for (org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack
+                .grouping.nx.action.conntrack.CtActions ctAction : action.getCtActions()) {
+            org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions
+                .OfpactActions natAction = ctAction.getOfpactActions();
+            if (natAction instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421
+                    .ofpact.actions.ofpact.actions.NxActionNatCase) {
+                org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact
+                    .actions.nx.action.nat._case.NxActionNat nxActionNat = ((org.opendaylight.yang.gen.v1.urn
+                            .opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions
+                            .NxActionNatCase) natAction).getNxActionNat();
+                NxActionNatBuilder nxActionNatBuilder = new NxActionNatBuilder();
+                nxActionNatBuilder.setFlags(nxActionNat.getFlags());
+                nxActionNatBuilder.setRangePresent(nxActionNat.getRangePresent());
+                nxActionNatBuilder.setIpAddressMin(nxActionNat.getIpAddressMin());
+                nxActionNatBuilder.setIpAddressMax(nxActionNat.getIpAddressMax());
+                nxActionNatBuilder.setPortMin(nxActionNat.getPortMin());
+                nxActionNatBuilder.setPortMax(nxActionNat.getPortMax());
+                NxActionNatCaseBuilder caseBuilder = new NxActionNatCaseBuilder();
+                caseBuilder.setNxActionNat(nxActionNatBuilder.build());
+                CtActionsBuilder ctActionsBuilder = new CtActionsBuilder();
+                ctActionsBuilder.setOfpactActions(caseBuilder.build());
+                ctActions.add(ctActionsBuilder.build());
+            }
+        }
+        return ctActions;
+    }
+
     private static int resolveStart(final int ofsNBints) {
         return extractSub(ofsNBints, 10, 6);
     }
@@ -63,7 +109,8 @@ public class ConntrackConvertor implements
         return rightShifted & mask;
     }
 
-    private static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action resolveAction(final NxConntrack value, final ActionPath path) {
+    private static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action
+                        .Action resolveAction(final NxConntrack value, final ActionPath path) {
         switch (path) {
             case NODES_NODE_TABLE_FLOW_INSTRUCTIONS_INSTRUCTION_WRITEACTIONSCASE_WRITEACTIONS_ACTION_ACTION_EXTENSIONLIST_EXTENSION:
                 return new NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder().setNxConntrack(value).build();
@@ -83,7 +130,8 @@ public class ConntrackConvertor implements
     }
 
     @Override
-    public Action convert(final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action nxActionArg) {
+    public Action convert(final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action
+            .Action nxActionArg) {
         Preconditions.checkArgument(nxActionArg instanceof NxActionConntrackGrouping);
         NxActionConntrackGrouping nxAction = (NxActionConntrackGrouping) nxActionArg;
 
@@ -92,9 +140,47 @@ public class ConntrackConvertor implements
         nxActionConntrackBuilder.setZoneSrc(nxAction.getNxConntrack().getZoneSrc());
         nxActionConntrackBuilder.setRecircTable(nxAction.getNxConntrack().getRecircTable());
         nxActionConntrackBuilder.setConntrackZone(nxAction.getNxConntrack().getConntrackZone());
+        nxActionConntrackBuilder.setCtActions(getCtAction(nxAction.getNxConntrack()));
         ActionConntrackBuilder actionConntrackBuilder = new ActionConntrackBuilder();
         actionConntrackBuilder.setNxActionConntrack(nxActionConntrackBuilder.build());
         return ActionUtil.createAction(actionConntrackBuilder.build());
     }
 
-}
+    private List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack
+                                .grouping.nx.action.conntrack.CtActions> getCtAction(final NxConntrack action) {
+        if (action.getCtActions() == null) {
+            return null;
+        }
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack
+            .grouping.nx.action.conntrack.CtActions> ctActions = new ArrayList<org.opendaylight.yang.gen.v1.urn
+            .opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack
+            .CtActions>();
+        for ( CtActions ctAction : action.getCtActions()) {
+            OfpactActions natAction = ctAction.getOfpactActions();
+            if (natAction instanceof NxActionNatCase) {
+                NxActionNat nxActionNat = ((NxActionNatCase) natAction).getNxActionNat();
+                org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact
+                    .actions.nx.action.nat._case.NxActionNatBuilder nxActionNatBuilder = new org.opendaylight.yang.gen
+                    .v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat
+                    ._case.NxActionNatBuilder();
+                nxActionNatBuilder.setFlags(nxActionNat.getFlags());
+                nxActionNatBuilder.setRangePresent(nxActionNat.getRangePresent());
+                nxActionNatBuilder.setIpAddressMin(nxActionNat.getIpAddressMin());
+                nxActionNatBuilder.setIpAddressMax(nxActionNat.getIpAddressMax());
+                nxActionNatBuilder.setPortMin(nxActionNat.getPortMin());
+                nxActionNatBuilder.setPortMax(nxActionNat.getPortMax());
+                org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact
+                    .actions.NxActionNatCaseBuilder caseBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight
+                    .openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCaseBuilder();
+                caseBuilder.setNxActionNat(nxActionNatBuilder.build());
+                org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack
+                    .grouping.nx.action.conntrack.CtActionsBuilder ctActionsBuilder = new org.opendaylight.yang.gen.v1
+                    .urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action
+                    .conntrack.CtActionsBuilder();
+                ctActionsBuilder.setOfpactActions(caseBuilder.build());
+                ctActions.add(ctActionsBuilder.build());
+            }
+        }
+        return ctActions;
+    }
+}
\ No newline at end of file
index 4853a724d25d40780c46b06ff7223c4a0476f82c..7993262134cefd49921443e4ca050bde2ed52f0c 100644 (file)
@@ -17,6 +17,7 @@ module openflowplugin-extension-nicira-action {
     import openflow-action {prefix ofaction;revision-date "2015-02-03";}
     import nicira-action {prefix nicira-action;revision-date "2014-04-21";}
     import opendaylight-direct-statistics {prefix directstat;revision-date "2016-05-11";}
+    import ietf-inet-types { prefix "inet"; revision-date "2013-07-15"; }
 
     description
         "Nicira openflow action extensions.";
@@ -483,6 +484,38 @@ bits specified from the register.";
             leaf recirc-table {
                 type uint8;
             }
+            list ct-actions{
+                uses ofpact-actions;
+            }
+        }
+    }
+
+    grouping ofpact-actions {
+        description
+           "Actions to be performed with conntrack.";
+        choice ofpact-actions {
+            case nx-action-nat-case {
+                container nx-action-nat {
+                    leaf flags {
+                        type uint16;
+                    }
+                    leaf range_present {
+                        type uint16;
+                    }
+                    leaf ip-address-min {
+                        type inet:ip-address;
+                    }
+                    leaf ip-address-max {
+                        type inet:ip-address;
+                    }
+                    leaf port-min {
+                        type uint16;
+                    }
+                    leaf port-max {
+                        type uint16;
+                    }
+                }
+            }
         }
     }
 
index db0ce9774956e6170578154007b68ab5c26725d5..887ee0ea3561f043e896ca3f27ddccdc25874fce 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ * Copyright (c) 2016, 2017 Cisco Systems, 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,
@@ -8,10 +8,14 @@
 
 package org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action;
 
+import java.util.ArrayList;
+import java.util.List;
+
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrack;
@@ -25,6 +29,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.ni
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.NxConntrackBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.nx.conntrack.CtActions;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.conntrack.grouping.nx.conntrack.CtActionsBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.NxActionNatCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.NxActionNatCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNat;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNatBuilder;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -33,8 +43,6 @@ import org.slf4j.LoggerFactory;
  */
 public class ConntrackConvertorTest {
 
-    private static final Logger LOG = LoggerFactory.getLogger(ConntrackConvertorTest.class);
-
     private ConntrackConvertor conntrackConvertor;
 
     @Before
@@ -43,34 +51,88 @@ public class ConntrackConvertorTest {
     }
 
     @Test
-    public void testConvertToOFJava() throws Exception {
+    public void testConvertToOfJava() throws Exception {
 
+        final NxActionNatBuilder nxActionNatBuilder = new NxActionNatBuilder()
+                .setFlags(1)
+                .setRangePresent(2)
+                .setIpAddressMin(new IpAddress("192.168.0.0".toCharArray()))
+                .setIpAddressMin(new IpAddress("192.168.10.0".toCharArray()))
+                .setPortMin(3000)
+                .setPortMax(4000);
+        final CtActionsBuilder ctActionsBuilder = new CtActionsBuilder().setOfpactActions(new NxActionNatCaseBuilder()
+                .setNxActionNat(nxActionNatBuilder.build()).build());
+        List<CtActions> ctAction = new ArrayList<>();
+        ctAction.add(ctActionsBuilder.build());
         final NxConntrackBuilder nxConntrackBuilder = new NxConntrackBuilder()
                 .setConntrackZone(1)
                 .setFlags(1)
                 .setRecircTable((short) 1)
-                .setZoneSrc(1L);
+                .setZoneSrc(1L)
+                .setCtActions(ctAction);
 
         final NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder nxActionConntrackBuilder =
                 new NxActionConntrackNodesNodeTableFlowWriteActionsCaseBuilder()
                         .setNxConntrack(nxConntrackBuilder.build());
 
         final NxActionConntrackNodesNodeTableFlowWriteActionsCase actionsCase = nxActionConntrackBuilder.build();
-        final ActionConntrack actionConntrack = (ActionConntrack) conntrackConvertor.convert(actionsCase).getActionChoice();
+        final ActionConntrack actionConntrack = (ActionConntrack) conntrackConvertor.convert(actionsCase)
+                .getActionChoice();
 
-        Assert.assertEquals(actionsCase.getNxConntrack().getConntrackZone(), actionConntrack.getNxActionConntrack().getConntrackZone());
+        Assert.assertEquals(actionsCase.getNxConntrack().getConntrackZone(), actionConntrack.getNxActionConntrack()
+                .getConntrackZone());
         Assert.assertEquals(actionsCase.getNxConntrack().getFlags(), actionConntrack.getNxActionConntrack().getFlags());
-        Assert.assertEquals(actionsCase.getNxConntrack().getRecircTable(), actionConntrack.getNxActionConntrack().getRecircTable());
-        Assert.assertEquals(actionsCase.getNxConntrack().getZoneSrc(), actionConntrack.getNxActionConntrack().getZoneSrc());
+        Assert.assertEquals(actionsCase.getNxConntrack().getRecircTable(), actionConntrack.getNxActionConntrack()
+                .getRecircTable());
+        Assert.assertEquals(actionsCase.getNxConntrack().getZoneSrc(), actionConntrack.getNxActionConntrack()
+                .getZoneSrc());
+
+        NxActionNat natactionCase = ((NxActionNatCase) actionsCase.getNxConntrack().getCtActions().get(0)
+                .getOfpactActions()).getNxActionNat();
+        org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions
+            .nx.action.nat._case.NxActionNat nataction = ( (org.opendaylight
+                    .yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions
+                    .NxActionNatCase) actionConntrack.getNxActionConntrack().getCtActions().get(0).getOfpactActions())
+            .getNxActionNat();
+        Assert.assertEquals(natactionCase.getFlags(), nataction.getFlags());
+        Assert.assertEquals(natactionCase.getRangePresent(), nataction.getRangePresent());
+        Assert.assertEquals(natactionCase.getIpAddressMin().getIpv4Address().getValue(), nataction.getIpAddressMin()
+            .getIpv4Address().getValue());
+        Assert.assertEquals(natactionCase.getIpAddressMin().getIpv4Address().getValue(), nataction.getIpAddressMin()
+            .getIpv4Address().getValue());
+        Assert.assertEquals(natactionCase.getPortMin(), nataction.getPortMin());
+        Assert.assertEquals(natactionCase.getPortMax(), nataction.getPortMax());
+
     }
 
     @Test
-    public void testConvertFromOFJava() throws Exception {
+    public void testConvertFromOfJava() throws Exception {
+
+        org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions
+            .nx.action.nat._case.NxActionNatBuilder nxActionNatBuilder = new org.opendaylight.yang.gen.v1.urn
+            .opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case
+            .NxActionNatBuilder()
+            .setFlags(1)
+            .setRangePresent(2)
+            .setIpAddressMin(new IpAddress("192.168.0.0".toCharArray()))
+            .setIpAddressMax(new IpAddress("192.168.10.0".toCharArray()))
+            .setPortMin(3000)
+            .setPortMax(4000);
+        org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping
+            .nx.action.conntrack.CtActionsBuilder ctActionsBuilder = new org.opendaylight.yang.gen.v1.urn.opendaylight
+            .openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActionsBuilder()
+            .setOfpactActions(new org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact
+                    .actions.ofpact.actions.NxActionNatCaseBuilder().setNxActionNat(nxActionNatBuilder.build())
+                    .build());
+        List<org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack
+            .grouping.nx.action.conntrack.CtActions> ctActions = new ArrayList<>();
+        ctActions.add(ctActionsBuilder.build());
         final NxActionConntrackBuilder nxActionConntrackBuilder = new NxActionConntrackBuilder()
                 .setConntrackZone(1)
                 .setFlags(1)
                 .setRecircTable((short) 1)
-                .setZoneSrc(1L);
+                .setZoneSrc(1L)
+                .setCtActions(ctActions);
 
         final ActionConntrackBuilder actionConntrackBuilder = new ActionConntrackBuilder()
                 .setNxActionConntrack(nxActionConntrackBuilder.build());
@@ -93,34 +155,94 @@ public class ConntrackConvertorTest {
         final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action action5
                 = conntrackConvertor.convert(groupingAction, ActionPath.RPCFLOWSSTATISTICS_FLOWANDSTATISTICSMAPLIST_INSTRUCTIONS_INSTRUCTION_INSTRUCTION_APPLYACTIONSCASE_APPLYACTIONS_ACTION_ACTION);
 
-        Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getConntrackZone().longValue());
-        Assert.assertEquals(1L, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getZoneSrc().longValue());
-        Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getRecircTable().intValue());
-        Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack().getFlags().intValue());
-
-        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1).getNxConntrack().getConntrackZone().longValue());
-        Assert.assertEquals(1L, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1).getNxConntrack().getZoneSrc().longValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1).getNxConntrack().getRecircTable().intValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1).getNxConntrack().getFlags().intValue());
-
-        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2).getNxConntrack().getConntrackZone().longValue());
-        Assert.assertEquals(1L, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2).getNxConntrack().getZoneSrc().longValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2).getNxConntrack().getRecircTable().intValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2).getNxConntrack().getFlags().intValue());
-
-        Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getConntrackZone().longValue());
-        Assert.assertEquals(1L, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getZoneSrc().longValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getRecircTable().intValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack().getFlags().intValue());
-
-        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getConntrackZone().longValue());
-        Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getZoneSrc().longValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getRecircTable().intValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4).getNxConntrack().getFlags().intValue());
-
-        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getConntrackZone().longValue());
-        Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getZoneSrc().longValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getRecircTable().intValue());
-        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack().getFlags().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack()
+                .getConntrackZone().longValue());
+        Assert.assertEquals(1L, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack()
+                .getZoneSrc().longValue());
+        Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack()
+                .getRecircTable().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNodesNodeTableFlowWriteActionsCase) action).getNxConntrack()
+                .getFlags().intValue());
+
+        NxActionNat natActionCase = ((NxActionNatCase)((NxActionConntrackNodesNodeTableFlowWriteActionsCase)action)
+               .getNxConntrack().getCtActions().get(0).getOfpactActions()).getNxActionNat();
+        Assert.assertEquals(1, natActionCase.getFlags().shortValue());
+        Assert.assertEquals(2, natActionCase.getRangePresent().intValue());
+        Assert.assertEquals("192.168.0.0", natActionCase.getIpAddressMin().getIpv4Address().getValue());
+        Assert.assertEquals("192.168.10.0", natActionCase.getIpAddressMax().getIpv4Address().getValue());
+        Assert.assertEquals(3000, natActionCase.getPortMin().shortValue());
+        Assert.assertEquals(4000, natActionCase.getPortMax().shortValue());
+
+        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1)
+                .getNxConntrack().getConntrackZone().longValue());
+        Assert.assertEquals(1L, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1)
+                .getNxConntrack().getZoneSrc().longValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1)
+                .getNxConntrack().getRecircTable().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateWriteActionsCase) action1)
+                .getNxConntrack().getFlags().intValue());
+
+        NxActionNat natActionCase1 = ((NxActionNatCase)((NxActionConntrackNodesNodeTableFlowWriteActionsCase)action)
+                .getNxConntrack().getCtActions().get(0).getOfpactActions()).getNxActionNat();
+        Assert.assertEquals(1, natActionCase1.getFlags().shortValue());
+        Assert.assertEquals(2, natActionCase1.getRangePresent().intValue());
+        Assert.assertEquals("192.168.0.0", natActionCase1.getIpAddressMin().getIpv4Address().getValue());
+        Assert.assertEquals("192.168.10.0", natActionCase1.getIpAddressMax().getIpv4Address().getValue());
+        Assert.assertEquals(3000, natActionCase1.getPortMin().shortValue());
+        Assert.assertEquals(4000, natActionCase1.getPortMax().shortValue());
+
+        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2)
+                .getNxConntrack().getConntrackZone().longValue());
+        Assert.assertEquals(1L, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2)
+                .getNxConntrack().getZoneSrc().longValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2)
+                .getNxConntrack().getRecircTable().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifFlowsStatisticsUpdateApplyActionsCase) action2)
+                .getNxConntrack().getFlags().intValue());
+
+        NxActionNat natActionCase2 = ((NxActionNatCase)((NxActionConntrackNodesNodeTableFlowWriteActionsCase)action)
+                .getNxConntrack().getCtActions().get(0).getOfpactActions()).getNxActionNat();
+        Assert.assertEquals(1, natActionCase2.getFlags().shortValue());
+        Assert.assertEquals(2, natActionCase2.getRangePresent().intValue());
+        Assert.assertEquals("192.168.0.0", natActionCase2.getIpAddressMin().getIpv4Address().getValue());
+        Assert.assertEquals("192.168.10.0", natActionCase2.getIpAddressMax().getIpv4Address().getValue());
+        Assert.assertEquals(3000, natActionCase2.getPortMin().shortValue());
+        Assert.assertEquals(4000, natActionCase2.getPortMax().shortValue());
+
+        NxActionNat natActionCase3 = ((NxActionNatCase)((NxActionConntrackNodesNodeTableFlowWriteActionsCase)action)
+                .getNxConntrack().getCtActions().get(0).getOfpactActions()).getNxActionNat();
+        Assert.assertEquals(1, natActionCase3.getFlags().shortValue());
+        Assert.assertEquals(2, natActionCase3.getRangePresent().intValue());
+        Assert.assertEquals("192.168.0.0", natActionCase3.getIpAddressMin().getIpv4Address().getValue());
+        Assert.assertEquals("192.168.10.0", natActionCase3.getIpAddressMax().getIpv4Address().getValue());
+        Assert.assertEquals(3000, natActionCase3.getPortMin().shortValue());
+        Assert.assertEquals(4000, natActionCase3.getPortMax().shortValue());
+
+        Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack()
+                .getConntrackZone().longValue());
+        Assert.assertEquals(1L, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack()
+                .getZoneSrc().longValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack()
+                .getRecircTable().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifGroupDescStatsUpdatedCase) action3).getNxConntrack()
+                .getFlags().intValue());
+
+        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4)
+                .getNxConntrack().getConntrackZone().longValue());
+        Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4)
+                .getNxConntrack().getZoneSrc().longValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4)
+                .getNxConntrack().getRecircTable().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateWriteActionsCase) action4)
+                .getNxConntrack().getFlags().intValue());
+
+        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack()
+                .getConntrackZone().longValue());
+        Assert.assertEquals(1L, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5)
+                .getNxConntrack().getZoneSrc().longValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack()
+                .getRecircTable().intValue());
+        Assert.assertEquals(1, ((NxActionConntrackNotifDirectStatisticsUpdateApplyActionsCase) action5).getNxConntrack()
+                .getFlags().intValue());
     }
 }
\ No newline at end of file