2 * Copyright (c) 2015, 2017 Hewlett-Packard Enterprise and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.openflowjava.nx.codec.action;
11 import io.netty.buffer.ByteBuf;
13 import java.net.InetAddress;
14 import java.util.ArrayList;
15 import java.util.List;
17 import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
18 import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
19 import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IetfInetUtil;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.ActionBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.NxActionNatRangePresent;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrack;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionConntrackBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.NxActionConntrackBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActions;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.conntrack.grouping.nx.action.conntrack.CtActionsBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCase;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.NxActionNatCaseBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNat;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofpact.actions.ofpact.actions.nx.action.nat._case.NxActionNatBuilder;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.common.net.InetAddresses;
40 * @author Aswin Suryanarayanan.
43 public class ConntrackCodec extends AbstractActionCodec {
44 private static final Logger LOG = LoggerFactory.getLogger( ConntrackCodec.class);
45 public static final int CT_LENGTH = 24;
46 public static final int NX_NAT_LENGTH = 16;
47 public static final int SHORT_LENGTH = 2;
48 public static final int INT_LENGTH = 4;
50 public static final byte NXAST_CONNTRACK_SUBTYPE = 35;
51 public static final byte NXAST_NAT_SUBTYPE = 36;
52 public static final NiciraActionSerializerKey SERIALIZER_KEY =
53 new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionConntrack.class);
54 public static final NiciraActionDeserializerKey DESERIALIZER_KEY =
55 new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, NXAST_CONNTRACK_SUBTYPE);
58 public void serialize(final Action input, final ByteBuf outBuffer) {
59 LOG.trace("serialize :conntrack");
60 ActionConntrack action = (ActionConntrack) input.getActionChoice();
61 int length = getActionLength(action);
63 serializeHeader(length + pad + CT_LENGTH, NXAST_CONNTRACK_SUBTYPE, outBuffer);
65 outBuffer.writeShort(action.getNxActionConntrack().getFlags().shortValue());
66 outBuffer.writeInt(action.getNxActionConntrack().getZoneSrc().intValue());
67 outBuffer.writeShort(action.getNxActionConntrack().getConntrackZone().shortValue());
68 outBuffer.writeByte(action.getNxActionConntrack().getRecircTable().byteValue());
69 outBuffer.writeZero(5);
70 serializeCtAction(outBuffer,action, length);
73 private int getActionLength(final ActionConntrack action) {
75 List<CtActions> ctActionsList = action.getNxActionConntrack().getCtActions();
76 if (ctActionsList == null) {
79 for (CtActions ctActions : ctActionsList) {
80 if (ctActions.getOfpactActions() instanceof NxActionNatCase) {
81 length += NX_NAT_LENGTH;
82 NxActionNatCase nxActionNatCase = (NxActionNatCase)ctActions.getOfpactActions();
83 NxActionNat natAction = nxActionNatCase.getNxActionNat();
84 short rangePresent = natAction.getRangePresent().shortValue();
85 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue())) {
88 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MAX.getIntValue())) {
91 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMIN.getIntValue())) {
92 length += SHORT_LENGTH;
94 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMAX.getIntValue())) {
95 length += SHORT_LENGTH;
99 LOG.trace("ActionLength :conntrack: length {}",length);
103 private void serializeCtAction(final ByteBuf outBuffer, final ActionConntrack action, final int length) {
104 List<CtActions> ctActionsList = action.getNxActionConntrack().getCtActions();
105 if (ctActionsList != null) {
106 for (CtActions ctActions : ctActionsList) {
107 if (ctActions.getOfpactActions() instanceof NxActionNatCase){
108 NxActionNatCase nxActionNatCase = (NxActionNatCase)ctActions.getOfpactActions();
109 NxActionNat natAction = nxActionNatCase.getNxActionNat();
110 int pad = length % 8;
111 serializeHeader(length + pad, NXAST_NAT_SUBTYPE, outBuffer);
112 outBuffer.writeZero(2);
113 outBuffer.writeShort(natAction.getFlags().shortValue());
114 short rangePresent = natAction.getRangePresent().shortValue();
115 outBuffer.writeShort(rangePresent);
116 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue())) {
117 if (null != natAction.getIpAddressMin()) {
118 outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(natAction
119 .getIpAddressMin().getIpv4Address()));
122 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MAX.getIntValue())) {
123 if (null != natAction.getIpAddressMax()) {
124 outBuffer.writeBytes(IetfInetUtil.INSTANCE.ipv4AddressBytes(natAction
125 .getIpAddressMax().getIpv4Address()));
128 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMIN.getIntValue())) {
129 outBuffer.writeShort(natAction.getPortMin());
131 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMAX.getIntValue())) {
132 outBuffer.writeShort(natAction.getPortMax());
134 outBuffer.writeZero(pad);
141 public Action deserialize(final ByteBuf message) {
142 ActionBuilder actionBuilder = deserializeHeader(message);
143 ActionConntrackBuilder actionConntrackBuilder = new ActionConntrackBuilder();
145 NxActionConntrackBuilder nxActionConntrackBuilder = new NxActionConntrackBuilder();
146 nxActionConntrackBuilder.setFlags(message.readUnsignedShort());
147 nxActionConntrackBuilder.setZoneSrc(message.readUnsignedInt());
148 nxActionConntrackBuilder.setConntrackZone(message.readUnsignedShort());
149 nxActionConntrackBuilder.setRecircTable(message.readUnsignedByte());
150 message.skipBytes(5);
151 dserializeCtAction(message,nxActionConntrackBuilder);
152 actionConntrackBuilder.setNxActionConntrack(nxActionConntrackBuilder.build());
153 actionBuilder.setActionChoice(actionConntrackBuilder.build());
155 return actionBuilder.build();
158 private void dserializeCtAction(final ByteBuf message, final NxActionConntrackBuilder nxActionConntrackBuilder) {
159 deserializeHeader(message);
161 NxActionNatBuilder nxActionNatBuilder = new NxActionNatBuilder();
162 message.skipBytes(2);
163 nxActionNatBuilder.setFlags(message.readUnsignedShort());
165 int rangePresent = message.readUnsignedShort();
166 nxActionNatBuilder.setRangePresent(rangePresent);
167 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MIN.getIntValue())) {
168 InetAddress address = InetAddresses.fromInteger((int)message.readUnsignedInt());
169 nxActionNatBuilder.setIpAddressMin(new IpAddress(address.getHostAddress().toCharArray()));
171 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEIPV4MAX.getIntValue())) {
172 InetAddress address = InetAddresses.fromInteger((int)message.readUnsignedInt());
173 nxActionNatBuilder.setIpAddressMax(new IpAddress(address.getHostAddress().toCharArray()));
175 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMIN.getIntValue())) {
176 nxActionNatBuilder.setPortMin(message.readUnsignedShort());
178 if (0 != (rangePresent & NxActionNatRangePresent.NXNATRANGEPROTOMAX.getIntValue())) {
179 nxActionNatBuilder.setPortMax(message.readUnsignedShort());
181 NxActionNatCaseBuilder caseBuilder = new NxActionNatCaseBuilder();
182 caseBuilder.setNxActionNat(nxActionNatBuilder.build());
183 CtActionsBuilder ctActionsBuilder = new CtActionsBuilder();
184 ctActionsBuilder.setOfpactActions(caseBuilder.build());
185 List<CtActions> ctActionsList = new ArrayList<>();
186 ctActionsList.add(ctActionsBuilder.build());
187 nxActionConntrackBuilder.setCtActions(ctActionsList);