import org.opendaylight.openflowjava.nx.api.NiciraExtensionCodecRegistrator;
import org.opendaylight.openflowjava.nx.api.NiciraUtil;
import org.opendaylight.openflowjava.nx.codec.action.ActionDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralDeserializer;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer;
new ConcurrentHashMap<>();
private final List<SwitchConnectionProvider> providers;
+ private final ActionDeserializer of10ActionDeserializer;
+ private final ActionDeserializer of13ActionDeserializer;
public NiciraExtensionCodecRegistratorImpl(List<SwitchConnectionProvider> providers) {
this.providers = providers;
- ActionDeserializer of10ActionDeserializer = new ActionDeserializer(EncodeConstants.OF10_VERSION_ID);
- ActionDeserializer of13ActionDeserializer = new ActionDeserializer(EncodeConstants.OF13_VERSION_ID);
+ of10ActionDeserializer = new ActionDeserializer(EncodeConstants.OF10_VERSION_ID);
+ of13ActionDeserializer = new ActionDeserializer(EncodeConstants.OF13_VERSION_ID);
registerActionDeserializer(ActionDeserializer.OF10_DESERIALIZER_KEY, of10ActionDeserializer);
registerActionDeserializer(ActionDeserializer.OF13_DESERIALIZER_KEY, of13ActionDeserializer);
}
*/
@Override
public void registerActionDeserializer(NiciraActionDeserializerKey key, OFDeserializer<Action> deserializer) {
+ if (deserializer instanceof DeserializerRegistryInjector) {
+ DeserializerRegistryInjector registryInjectable = (DeserializerRegistryInjector) deserializer;
+ if (key.getVersion() == EncodeConstants.OF10_VERSION_ID) {
+ registryInjectable.injectDeserializerRegistry(of10ActionDeserializer.getDeserializerRegistry());
+ }
+ if (key.getVersion() == EncodeConstants.OF13_VERSION_ID) {
+ registryInjectable.injectDeserializerRegistry(of13ActionDeserializer.getDeserializerRegistry());
+ }
+ }
ACTION_DESERIALIZERS.put(key, deserializer);
}
import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
import org.opendaylight.openflowjava.nx.codec.action.PopNshCodec;
import org.opendaylight.openflowjava.nx.codec.action.PushNshCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoad2Codec;
import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
registrator.registerActionDeserializer(RegLoadCodec.DESERIALIZER_KEY, NiciraActionCodecs.REG_LOAD_CODEC);
registrator.registerActionSerializer(RegLoadCodec.SERIALIZER_KEY, NiciraActionCodecs.REG_LOAD_CODEC);
+ registrator.registerActionDeserializer(RegLoad2Codec.DESERIALIZER_KEY, NiciraActionCodecs.REG_LOAD2_CODEC);
+ registrator.registerActionSerializer(RegLoad2Codec.SERIALIZER_KEY, NiciraActionCodecs.REG_LOAD2_CODEC);
registrator.registerActionDeserializer(RegMoveCodec.DESERIALIZER_KEY, NiciraActionCodecs.REG_MOVE_CODEC);
registrator.registerActionSerializer(RegMoveCodec.SERIALIZER_KEY, NiciraActionCodecs.REG_MOVE_CODEC);
registrator.registerActionDeserializer(OutputRegCodec.DESERIALIZER_KEY, NiciraActionCodecs.OUTPUT_REG_CODEC);
public void close() throws Exception {
registrator.unregisterActionDeserializer(RegLoadCodec.DESERIALIZER_KEY);
registrator.unregisterActionSerializer(RegLoadCodec.SERIALIZER_KEY);
+ registrator.unregisterActionDeserializer(RegLoad2Codec.DESERIALIZER_KEY);
+ registrator.unregisterActionSerializer(RegLoad2Codec.SERIALIZER_KEY);
registrator.unregisterActionDeserializer(RegMoveCodec.DESERIALIZER_KEY);
registrator.unregisterActionSerializer(RegMoveCodec.SERIALIZER_KEY);
registrator.unregisterActionDeserializer(OutputRegCodec.DESERIALIZER_KEY);
return new ExperimenterId(NiciraConstants.NX_VENDOR_ID);
}
+ private static int getPaddingRemainder(int nonPaddedSize) {
+ int paddingRemainder = EncodeConstants.PADDING - (nonPaddedSize % EncodeConstants.PADDING);
+ return paddingRemainder % EncodeConstants.PADDING;
+ }
+
+ protected static final void skipPadding(ByteBuf message, int startIndex) {
+ int nonPaddedSize = message.readerIndex() - startIndex;
+ message.skipBytes(getPaddingRemainder(nonPaddedSize));
+ }
+
+ protected static final void writePaddingAndSetLength(ByteBuf outBuffer, int startIndex) {
+ int nonPaddedSize = outBuffer.writerIndex() - startIndex;
+ outBuffer.writeZero(getPaddingRemainder(nonPaddedSize));
+ outBuffer.setShort(startIndex + EncodeConstants.SIZE_OF_SHORT_IN_BYTES, outBuffer.writerIndex() - startIndex);
+ }
}
import org.opendaylight.openflowjava.nx.NiciraExtensionCodecRegistratorImpl;
import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
import org.opendaylight.openflowjava.nx.api.NiciraConstants;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
import org.opendaylight.openflowjava.protocol.api.keys.ExperimenterActionDeserializerKey;
import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-public class ActionDeserializer implements OFDeserializer<Action> {
+public class ActionDeserializer implements OFDeserializer<Action>, DeserializerRegistryInjector {
private static final Logger LOG = LoggerFactory.getLogger(ActionDeserializer.class);
EncodeConstants.OF10_VERSION_ID, NiciraConstants.NX_VENDOR_ID);
private final short version;
+ private DeserializerRegistry deserializerRegistry;
/**
* Constructor.
return actionDeserializer.deserialize(message);
}
+ @Override
+ public void injectDeserializerRegistry(DeserializerRegistry registry) {
+ this.deserializerRegistry = registry;
+ }
+
+ public DeserializerRegistry getDeserializerRegistry() {
+ return deserializerRegistry;
+ }
}
public interface NiciraActionCodecs {
RegMoveCodec REG_MOVE_CODEC = new RegMoveCodec();
RegLoadCodec REG_LOAD_CODEC = new RegLoadCodec();
+ RegLoad2Codec REG_LOAD2_CODEC = new RegLoad2Codec();
OutputRegCodec OUTPUT_REG_CODEC = new OutputRegCodec();
ResubmitCodec RESUBMIT_CODEC = new ResubmitCodec();
MultipathCodec MULTIPATH_CODEC = new MultipathCodec();
--- /dev/null
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH. 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.openflowjava.nx.codec.action;
+
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
+import io.netty.buffer.ByteBuf;
+import java.util.Collections;
+import java.util.Objects;
+import org.opendaylight.openflowjava.nx.api.NiciraActionDeserializerKey;
+import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistryInjector;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
+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.oxm.rev150225.ExperimenterClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2Builder;
+
+public class RegLoad2Codec
+ extends AbstractActionCodec
+ implements SerializerRegistryInjector, DeserializerRegistryInjector {
+
+ public static final byte SUBTYPE = 33; // NXAST_REG_LOAD2
+ public static final NiciraActionSerializerKey SERIALIZER_KEY = new NiciraActionSerializerKey(
+ EncodeConstants.OF13_VERSION_ID, ActionRegLoad2.class);
+ public static final NiciraActionDeserializerKey DESERIALIZER_KEY = new NiciraActionDeserializerKey(
+ EncodeConstants.OF13_VERSION_ID, SUBTYPE);
+ private SerializerRegistry serializerRegistry;
+ private DeserializerRegistry deserializerRegistry;
+
+ @Override
+ @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
+ public Action deserialize(ByteBuf message) {
+ Objects.requireNonNull(deserializerRegistry);
+
+ final int startIndex = message.readerIndex();
+ ActionBuilder actionBuilder = deserializeHeader(message);
+
+ int oxmClass = message.getUnsignedShort(message.readerIndex());
+ int oxmField = message.getUnsignedByte(message.readerIndex() + EncodeConstants.SIZE_OF_SHORT_IN_BYTES) >>> 1;
+ MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(
+ EncodeConstants.OF13_VERSION_ID,
+ oxmClass,
+ oxmField);
+ if (oxmClass == EncodeConstants.EXPERIMENTER_VALUE) {
+ long expId = message.getUnsignedInt(message.readerIndex()
+ + EncodeConstants.SIZE_OF_SHORT_IN_BYTES
+ + EncodeConstants.SIZE_OF_BYTE_IN_BYTES * 2);
+ key.setExperimenterId(expId);
+ }
+ OFDeserializer<MatchEntry> matchDeserializer = deserializerRegistry.getDeserializer(key);
+ MatchEntry matchEntry = matchDeserializer.deserialize(message);
+
+ skipPadding(message, startIndex);
+
+ NxActionRegLoad2 nxActionRegLoad2 = new NxActionRegLoad2Builder()
+ .setMatchEntry(Collections.singletonList(matchEntry))
+ .build();
+ ActionRegLoad2 actionRegLoad2 = new ActionRegLoad2Builder().setNxActionRegLoad2(nxActionRegLoad2).build();
+ return actionBuilder.setActionChoice(actionRegLoad2).build();
+ }
+
+ @Override
+ @SuppressFBWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR") // FB doesn't recognize Objects.requireNonNull
+ public void serialize(Action input, ByteBuf outBuffer) {
+ Objects.requireNonNull(serializerRegistry);
+
+ final int startIndex = outBuffer.writerIndex();
+ serializeHeader(EncodeConstants.EMPTY_LENGTH, SUBTYPE, outBuffer);
+
+ ActionRegLoad2 actionRegLoad2 = (ActionRegLoad2) input.getActionChoice();
+ NxActionRegLoad2 nxActionRegLoad2 = actionRegLoad2.getNxActionRegLoad2();
+ MatchEntry matchEntry = nxActionRegLoad2.getMatchEntry().get(0);
+ MatchEntrySerializerKey<?, ?> key = new MatchEntrySerializerKey<>(
+ EncodeConstants.OF13_VERSION_ID,
+ matchEntry.getOxmClass(),
+ matchEntry.getOxmMatchField());
+ if (matchEntry.getOxmClass().equals(ExperimenterClass.class)) {
+ ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
+ key.setExperimenterId(experimenterIdCase.getExperimenter().getExperimenter().getValue());
+ }
+ OFSerializer<MatchEntry> serializer = serializerRegistry.getSerializer(key);
+ serializer.serialize(matchEntry, outBuffer);
+
+ writePaddingAndSetLength(outBuffer, startIndex);
+ }
+
+ @Override
+ public void injectSerializerRegistry(SerializerRegistry registry) {
+ this.serializerRegistry = registry;
+ }
+
+ @Override
+ public void injectDeserializerRegistry(DeserializerRegistry registry) {
+ this.deserializerRegistry = registry;
+ }
+}
namespace "urn:opendaylight:openflowjava:nx:action";
prefix "nicira-action";
+ import openflow-extensible-match { prefix oxm;}
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";}
identity nxm-nx-reg-load {
base ofaction:experimenter-action-sub-type;
}
+ identity nxm-nx-reg-load2 {
+ base ofaction:experimenter-action-sub-type;
+ }
identity nxm-nx-reg-move {
base ofaction:experimenter-action-sub-type;
}
}
}
}
+
+ grouping ofj-nx-action-reg-load2-grouping {
+ container nx-action-reg-load2 {
+ uses oxm:match-entries-grouping;
+ }
+ }
+
grouping ofj-nx-action-reg-move-grouping {
container nx-action-reg-move {
leaf n_bits {
case action-reg-load {
uses ofj-nx-action-reg-load-grouping;
}
+ case action-reg-load2 {
+ uses ofj-nx-action-reg-load2-grouping;
+ }
case action-reg-move {
uses ofj-nx-action-reg-move-grouping;
}
import org.opendaylight.openflowjava.nx.api.NiciraActionSerializerKey;
import org.opendaylight.openflowjava.nx.api.NiciraUtil;
import org.opendaylight.openflowjava.nx.codec.action.ActionDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistryInjector;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFGeneralSerializer;
import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
@Mock
OFSerializer<Action> actionSerializer;
- @Mock
+ @Mock(extraInterfaces = DeserializerRegistryInjector.class)
OFDeserializer<Action> actionDeserializer;
@Mock
OFSerializer<MatchEntry> matchSerializer;
assertTrue(niciraExtensionCodecRegistrator.isEmptyActionDeserializers());
niciraExtensionCodecRegistrator.registerActionDeserializer(actionDeserializerKey, actionDeserializer);
assertFalse(niciraExtensionCodecRegistrator.isEmptyActionDeserializers());
+ Mockito.verify((DeserializerRegistryInjector) actionDeserializer)
+ .injectDeserializerRegistry(Matchers.any());
}
@Test
import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
import org.opendaylight.openflowjava.nx.codec.action.PopNshCodec;
import org.opendaylight.openflowjava.nx.codec.action.PushNshCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoad2Codec;
import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPopNsh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPushNsh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegMove;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionResubmit;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxArpSha;
Mockito.verify(registrator).registerActionSerializer(
Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad.class)),
Matchers.any(RegLoadCodec.class));
+ Mockito.verify(registrator).registerActionDeserializer(
+ Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 33)),
+ Matchers.any(RegLoad2Codec.class));
+ Mockito.verify(registrator).registerActionSerializer(
+ Matchers.eq(new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad2.class)),
+ Matchers.any(RegLoad2Codec.class));
Mockito.verify(registrator).registerActionDeserializer(
Matchers.eq(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 6)),
Matchers.any(RegMoveCodec.class));
.unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 7));
Mockito.verify(registrator).unregisterActionSerializer(
new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad.class));
+ Mockito.verify(registrator)
+ .unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 33));
+ Mockito.verify(registrator).unregisterActionSerializer(
+ new NiciraActionSerializerKey(EncodeConstants.OF13_VERSION_ID, ActionRegLoad2.class));
Mockito.verify(registrator)
.unregisterActionDeserializer(new NiciraActionDeserializerKey(EncodeConstants.OF13_VERSION_ID, 6));
Mockito.verify(registrator).unregisterActionSerializer(
--- /dev/null
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH. 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.openflowjava.nx.codec.action;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertSame;
+import static org.mockito.Matchers.any;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.when;
+
+import io.netty.buffer.ByteBuf;
+import io.netty.buffer.UnpooledByteBufAllocator;
+import java.util.Collections;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.runners.MockitoJUnitRunner;
+import org.opendaylight.openflowjava.nx.api.NiciraConstants;
+import org.opendaylight.openflowjava.protocol.api.extensibility.DeserializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFDeserializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.OFSerializer;
+import org.opendaylight.openflowjava.protocol.api.extensibility.SerializerRegistry;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntryDeserializerKey;
+import org.opendaylight.openflowjava.protocol.api.keys.MatchEntrySerializerKey;
+import org.opendaylight.openflowjava.protocol.api.util.EncodeConstants;
+import org.opendaylight.openflowjava.util.ByteBufUtils;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.experimenter.id._case.ExperimenterBuilder;
+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.openflow.oxm.rev150225.ExperimenterClass;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.MatchField;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntryBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2Builder;
+
+@RunWith(MockitoJUnitRunner.class)
+public class RegLoad2CodecTest {
+
+ private RegLoad2Codec regLoad2Codec;
+
+ @Mock
+ private SerializerRegistry serializerRegistry;
+ @Mock
+ private DeserializerRegistry deserializerRegistry;
+ @Mock
+ private OFSerializer<MatchEntry> ofSerializer;
+ @Mock
+ private OFDeserializer<MatchEntry> ofDeserializer;
+
+ @Before
+ public void setup() {
+ regLoad2Codec = new RegLoad2Codec();
+ regLoad2Codec.injectSerializerRegistry(serializerRegistry);
+ regLoad2Codec.injectDeserializerRegistry(deserializerRegistry);
+ }
+
+ @Test
+ public void deserialize() {
+ final ByteBuf byteBuf = ByteBufUtils.hexStringToByteBuf(
+ "FF FF 00 14 00 00 23 20 00 21" // REG_LOAD2 header
+ + " FF FF 02 00 00 5A D6 50" // OXM field
+ + " 00 00 00 00 00 00"); // padding
+ MatchEntryDeserializerKey key = new MatchEntryDeserializerKey(
+ EncodeConstants.OF13_VERSION_ID,
+ EncodeConstants.EXPERIMENTER_VALUE,
+ 1);
+ key.setExperimenterId(NiciraConstants.NX_NSH_VENDOR_ID);
+ final MatchEntry matchEntry = new MatchEntryBuilder().build();
+ when(deserializerRegistry.getDeserializer(key)).thenReturn(ofDeserializer);
+ when(ofDeserializer.deserialize(byteBuf)).thenAnswer(invocationOnMock -> {
+ invocationOnMock.getArgumentAt(0, ByteBuf.class).skipBytes(8);
+ return matchEntry;
+ });
+
+ Action action = regLoad2Codec.deserialize(byteBuf);
+
+ assertEquals(0, byteBuf.readableBytes());
+ assertSame(((ActionRegLoad2) action.getActionChoice()).getNxActionRegLoad2().getMatchEntry().get(0),
+ matchEntry);
+ }
+
+ @Test
+ public void serialize() {
+ final ByteBuf out = UnpooledByteBufAllocator.DEFAULT.buffer();
+ final Action action = createAction();
+ MatchEntrySerializerKey<?, ?> key = new MatchEntrySerializerKey<>(
+ EncodeConstants.OF13_VERSION_ID,
+ ExperimenterClass.class,
+ OxmMatchFieldClass.class);
+ key.setExperimenterId(NiciraConstants.NX_NSH_VENDOR_ID);
+ when(serializerRegistry.getSerializer(key)).thenReturn(ofSerializer);
+ doNothing().when(ofSerializer).serialize(any(), any());
+
+ regLoad2Codec.serialize(action, out);
+
+ assertEquals(EncodeConstants.EXPERIMENTER_VALUE, out.readUnsignedShort());
+ assertEquals(16, out.readUnsignedShort());
+ assertEquals(NiciraConstants.NX_VENDOR_ID.longValue(), out.readUnsignedInt());
+ assertEquals(RegLoad2Codec.SUBTYPE, out.readUnsignedShort());
+ }
+
+ private Action createAction() {
+ ExperimenterBuilder experimenterBuilder = new ExperimenterBuilder();
+ experimenterBuilder.setExperimenter(new ExperimenterId(NiciraConstants.NX_NSH_VENDOR_ID));
+ ExperimenterIdCaseBuilder expCaseBuilder = new ExperimenterIdCaseBuilder();
+ expCaseBuilder.setExperimenter(experimenterBuilder.build());
+ MatchEntryBuilder matchEntryBuilder = new MatchEntryBuilder();
+ matchEntryBuilder.setOxmMatchField(OxmMatchFieldClass.class);
+ matchEntryBuilder.setOxmClass(ExperimenterClass.class);
+ matchEntryBuilder.setMatchEntryValue(expCaseBuilder.build());
+ NxActionRegLoad2 nxActionRegLoad2 = new NxActionRegLoad2Builder()
+ .setMatchEntry(Collections.singletonList(matchEntryBuilder.build()))
+ .build();
+ ActionRegLoad2 actionRegLoad2 = new ActionRegLoad2Builder().setNxActionRegLoad2(nxActionRegLoad2).build();
+ return new ActionBuilder().setActionChoice(actionRegLoad2).build();
+ }
+
+ private interface OxmMatchFieldClass extends MatchField {
+ // only for testing purposes
+ }
+}
\ No newline at end of file
<artifactId>slf4j-log4j12</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>pl.pragmatists</groupId>
+ <artifactId>JUnitParams</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
import org.opendaylight.openflowjava.nx.codec.action.OutputRegCodec;
import org.opendaylight.openflowjava.nx.codec.action.PopNshCodec;
import org.opendaylight.openflowjava.nx.codec.action.PushNshCodec;
+import org.opendaylight.openflowjava.nx.codec.action.RegLoad2Codec;
import org.opendaylight.openflowjava.nx.codec.action.RegLoadCodec;
import org.opendaylight.openflowjava.nx.codec.action.RegMoveCodec;
import org.opendaylight.openflowjava.nx.codec.action.ResubmitCodec;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.OutputRegConvertor;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.PopNshConvertor;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.PushNshConvertor;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegLoad2Convertor;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegLoadConvertor;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegLoadConvertorProxy;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.RegMoveConvertor;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.action.ResubmitConvertor;
import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.ArpOpConvertor;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPopNsh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionPushNsh;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegMove;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionResubmit;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.add.flow.input.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionConntrackRpcAddFlowApplyActionsCase;
private static final EthDstConvertor ETH_DST_CONVERTOR = new EthDstConvertor();
private static final EthSrcConvertor ETH_SRC_CONVERTOR = new EthSrcConvertor();
private static final RegLoadConvertor REG_LOAD_CONVERTOR = new RegLoadConvertor();
+ private static final RegLoad2Convertor REG_LOAD2_CONVERTOR = new RegLoad2Convertor();
+ private static final RegLoadConvertorProxy REG_LOAD_CONVERTOR_PROXY = new RegLoadConvertorProxy();
private static final RegMoveConvertor REG_MOVE_CONVERTOR = new RegMoveConvertor();
private static final OutputRegConvertor OUTPUT_REG_CONVERTOR = new OutputRegConvertor();
private static final EthTypeConvertor ETH_TYPE_CONVERTOR = new EthTypeConvertor();
this.extensionConverterRegistrator = Preconditions.checkNotNull(provider.getExtensionConverterRegistrator());
registrations = new HashSet<>();
// src=dataStore/config
- registerAction13(NxActionRegLoadNodesNodeTableFlowApplyActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadNodesNodeTableFlowApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveNodesNodeTableFlowApplyActionsCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionOutputRegNodesNodeTableFlowApplyActionsCase.class, OUTPUT_REG_CONVERTOR);
registerAction13(NxActionResubmitNodesNodeTableFlowApplyActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(NxActionDecapNodesNodeTableFlowApplyActionsCase.class, DECAP_CONVERTOR);
registerAction13(NxActionDecNshTtlNodesNodeTableFlowApplyActionsCase.class, DEC_NSH_TTL_CONVERTOR);
- registerAction13(NxActionRegLoadNodesNodeTableFlowWriteActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadNodesNodeTableFlowWriteActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveNodesNodeTableFlowWriteActionsCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionOutputRegNodesNodeTableFlowWriteActionsCase.class, OUTPUT_REG_CONVERTOR);
registerAction13(NxActionResubmitNodesNodeTableFlowWriteActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(NxActionDecapNodesNodeTableFlowWriteActionsCase.class, DECAP_CONVERTOR);
registerAction13(NxActionDecNshTtlNodesNodeTableFlowWriteActionsCase.class, DEC_NSH_TTL_CONVERTOR);
- registerAction13(NxActionRegLoadNodesNodeGroupBucketsBucketActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadNodesNodeGroupBucketsBucketActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveNodesNodeGroupBucketsBucketActionsCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionOutputRegNodesNodeGroupBucketsBucketActionsCase.class, OUTPUT_REG_CONVERTOR);
registerAction13(NxActionResubmitNodesNodeGroupBucketsBucketActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(NxActionDecNshTtlNodesNodeGroupBucketsBucketActionsCase.class, DEC_NSH_TTL_CONVERTOR);
// src=rpc-addFlow
- registerAction13(NxActionRegLoadRpcAddFlowApplyActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadRpcAddFlowApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveRpcAddFlowApplyActionsCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionOutputRegRpcAddFlowApplyActionsCase.class, OUTPUT_REG_CONVERTOR);
registerAction13(NxActionResubmitRpcAddFlowApplyActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(NxActionDecapRpcAddFlowApplyActionsCase.class, DECAP_CONVERTOR);
registerAction13(NxActionDecNshTtlRpcAddFlowApplyActionsCase.class, DEC_NSH_TTL_CONVERTOR);
- registerAction13(NxActionRegLoadRpcAddFlowWriteActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadRpcAddFlowWriteActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveRpcAddFlowWriteActionsCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionOutputRegRpcAddFlowWriteActionsCase.class, OUTPUT_REG_CONVERTOR);
registerAction13(NxActionResubmitRpcAddFlowWriteActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(NxActionDecapRpcAddFlowWriteActionsCase.class, DECAP_CONVERTOR);
registerAction13(NxActionDecNshTtlRpcAddFlowWriteActionsCase.class, DEC_NSH_TTL_CONVERTOR);
- registerAction13(NxActionRegLoadRpcAddGroupCase.class, REG_LOAD_CONVERTOR);
- registerAction13(NxActionRegLoadRpcRemoveGroupCase.class, REG_LOAD_CONVERTOR);
- registerAction13(NxActionRegLoadRpcUpdateGroupOriginalCase.class, REG_LOAD_CONVERTOR);
- registerAction13(NxActionRegLoadRpcUpdateGroupUpdatedCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadRpcAddGroupCase.class, REG_LOAD_CONVERTOR_PROXY);
+ registerAction13(NxActionRegLoadRpcRemoveGroupCase.class, REG_LOAD_CONVERTOR_PROXY);
+ registerAction13(NxActionRegLoadRpcUpdateGroupOriginalCase.class, REG_LOAD_CONVERTOR_PROXY);
+ registerAction13(NxActionRegLoadRpcUpdateGroupUpdatedCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveRpcAddGroupCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionRegMoveRpcRemoveGroupCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionRegMoveRpcUpdateGroupOriginalCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionDecNshTtlRpcUpdateGroupOriginalCase.class, DEC_NSH_TTL_CONVERTOR);
registerAction13(NxActionDecNshTtlRpcUpdateGroupUpdatedCase.class, DEC_NSH_TTL_CONVERTOR);
- registerAction13(NxActionRegLoadRpcTransmitPacketCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadRpcTransmitPacketCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionResubmitRpcTransmitPacketCase.class, RESUBMIT_CONVERTOR);
- registerAction13(NxActionRegLoadRpcUpdateFlowOriginalApplyActionsCase.class, REG_LOAD_CONVERTOR);
- registerAction13(NxActionRegLoadRpcUpdateFlowUpdatedApplyActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadRpcUpdateFlowOriginalApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
+ registerAction13(NxActionRegLoadRpcUpdateFlowUpdatedApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionResubmitRpcUpdateFlowUpdatedApplyActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(NxActionRegMoveRpcUpdateFlowUpdatedApplyActionsCase.class, REG_MOVE_CONVERTOR);
- registerAction13(NxActionRegLoadRpcRemoveFlowApplyActionsCase.class, REG_LOAD_CONVERTOR);
+ registerAction13(NxActionRegLoadRpcRemoveFlowApplyActionsCase.class, REG_LOAD_CONVERTOR_PROXY);
registerAction13(NxActionRegMoveRpcRemoveFlowApplyActionsCase.class, REG_MOVE_CONVERTOR);
registerAction13(NxActionResubmitRpcRemoveFlowApplyActionsCase.class, RESUBMIT_CONVERTOR);
registerAction13(ActionRegLoad.class, REG_LOAD_CONVERTOR);
+ registerAction13(ActionRegLoad2.class, REG_LOAD2_CONVERTOR);
registerAction13(ActionRegMove.class, REG_MOVE_CONVERTOR);
registerAction13(ActionOutputReg.class, OUTPUT_REG_CONVERTOR);
registerAction13(ActionResubmit.class, RESUBMIT_CONVERTOR);
registrations.add(extensionConverterRegistrator.registerActionConvertor(
NiciraUtil.createOfJavaKeyFrom(RegLoadCodec.SERIALIZER_KEY), REG_LOAD_CONVERTOR));
+ registrations.add(extensionConverterRegistrator.registerActionConvertor(
+ NiciraUtil.createOfJavaKeyFrom(RegLoad2Codec.SERIALIZER_KEY), REG_LOAD2_CONVERTOR));
registrations.add(extensionConverterRegistrator.registerActionConvertor(
NiciraUtil.createOfJavaKeyFrom(RegMoveCodec.SERIALIZER_KEY), REG_MOVE_CONVERTOR));
registrations.add(extensionConverterRegistrator.registerActionConvertor(
--- /dev/null
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH. 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.openflowplugin.extension.vendor.nicira.convertor.action;
+
+import com.google.common.base.Preconditions;
+import java.math.BigInteger;
+import java.util.Collections;
+import javax.annotation.Nullable;
+import org.opendaylight.openflowjava.nx.codec.match.NiciraMatchCodecs;
+import org.opendaylight.openflowplugin.extension.api.ConvertorActionFromOFJava;
+import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.CodecPreconditionException;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.NshFlagsConvertor;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.NshTtlConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.OfjAugNxExpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.ofj.nxm.nx.match.nsh.flags.grouping.NshFlagsValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.ofj.nxm.nx.match.nsh.ttl.grouping.NshTtlValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.NxExpMatchEntryValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.nx.exp.match.entry.value.NshFlagsCaseValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.nx.exp.match.entry.value.NshTtlCaseValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionRegLoadGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshTtlCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshTtlCaseBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoadBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.Dst;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.DstBuilder;
+
+/**
+ * Convert between RegLoad SAL action and RegLoad2 nicira action.
+ */
+public class RegLoad2Convertor implements
+ 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(Action input,
+ ActionPath path) {
+ NxActionRegLoad2 actionRegLoad2 = ((ActionRegLoad2) input.getActionChoice()).getNxActionRegLoad2();
+ MatchEntry matchEntry = actionRegLoad2.getMatchEntry().get(0);
+ NxRegLoad nxRegLoad = resolveRegLoad(matchEntry);
+ return RegLoadConvertor.resolveAction(nxRegLoad, path);
+ }
+
+ @Override
+ public Action convert(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionCase) {
+ Preconditions.checkArgument(actionCase instanceof NxActionRegLoadGrouping);
+
+ NxActionRegLoadGrouping nxAction = (NxActionRegLoadGrouping) actionCase;
+ MatchEntry matchEntry = resolveMatchEntry(nxAction.getNxRegLoad());
+ NxActionRegLoad2 nxActionRegLoad2 = new NxActionRegLoad2Builder()
+ .setMatchEntry(Collections.singletonList(matchEntry))
+ .build();
+ ActionRegLoad2 actionRegLoad2 = new ActionRegLoad2Builder().setNxActionRegLoad2(nxActionRegLoad2).build();
+ return ActionUtil.createAction(actionRegLoad2);
+ }
+
+ private static MatchEntry resolveMatchEntry(NxRegLoad nxRegLoad) {
+ Dst dst = nxRegLoad.getDst();
+ BigInteger value = nxRegLoad.getValue();
+ int start = dst.getStart();
+ int end = dst.getEnd();
+ BigInteger[] valueMask = resolveValueMask(value, start, end);
+ value = valueMask[0];
+ BigInteger mask = valueMask[1];
+ DstChoice dstChoice = dst.getDstChoice();
+ return resolveMatchEntry(dstChoice, value, mask);
+ }
+
+ private static MatchEntry resolveMatchEntry(DstChoice dstChoice, BigInteger value, BigInteger mask) {
+ if (dstChoice instanceof DstNxNshFlagsCase) {
+ return NshFlagsConvertor.buildMatchEntry(value.shortValue(), mask.shortValue());
+ }
+ if (dstChoice instanceof DstNxNshTtlCase) {
+ return NshTtlConvertor.buildMatchEntry(value.shortValue(), mask.shortValue());
+ }
+
+ throw new CodecPreconditionException("Missing implementation of a case in dst-choice? " + dstChoice.getClass());
+ }
+
+ private static NxRegLoad resolveRegLoad(MatchEntry matchEntry) {
+ ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
+ OfjAugNxExpMatch ofjAugNxExpMatch = experimenterIdCase.augmentation(OfjAugNxExpMatch.class);
+ NxExpMatchEntryValue nxExpMatchEntryValue = ofjAugNxExpMatch.getNxExpMatchEntryValue();
+ DstBuilder dstBuilder = new DstBuilder();
+ return resolveRegLoad(nxExpMatchEntryValue, dstBuilder);
+ }
+
+ private static NxRegLoad resolveRegLoad(NxExpMatchEntryValue value, DstBuilder dstBuilder) {
+ if (value instanceof NshFlagsCaseValue) {
+ int valueLength = NiciraMatchCodecs.NSH_FLAGS_CODEC.getValueLength();
+ dstBuilder.setDstChoice(new DstNxNshFlagsCaseBuilder().setNxNshFlags(true).build());
+ NshFlagsValues nshFlagsValues = ((NshFlagsCaseValue) value).getNshFlagsValues();
+ return resolveRegLoad(nshFlagsValues.getNshFlags(), nshFlagsValues.getMask(), valueLength, dstBuilder);
+ }
+ if (value instanceof NshTtlCaseValue) {
+ int valueLength = NiciraMatchCodecs.NSH_TTL_CODEC.getValueLength();
+ dstBuilder.setDstChoice(new DstNxNshTtlCaseBuilder().setNxNshTtl(true).build());
+ NshTtlValues nshTtlValues = ((NshTtlCaseValue) value).getNshTtlValues();
+ return resolveRegLoad(nshTtlValues.getNshTtl(), nshTtlValues.getMask(), valueLength, dstBuilder);
+ }
+
+ throw new CodecPreconditionException("Missing codec for " + value.getImplementedInterface());
+ }
+
+ private static NxRegLoad resolveRegLoad(Short value, Short mask, int valueLength, DstBuilder dstBuilder) {
+ return resolveRegLoad(
+ BigInteger.valueOf(value),
+ mask == null ? null : BigInteger.valueOf(mask),
+ valueLength,
+ dstBuilder);
+ }
+
+ private static NxRegLoad resolveRegLoad(BigInteger value,
+ @Nullable BigInteger mask,
+ int length,
+ DstBuilder dstBuilder) {
+ final int start;
+ final int end;
+ if (mask == null) {
+ start = 0;
+ end = length * 8;
+ } else {
+ start = mask.getLowestSetBit();
+ end = start + mask.shiftRight(start).not().getLowestSetBit();
+ value = value.and(mask).shiftRight(start);
+
+ if (value.bitLength() > end - start) {
+ // We cannot map a REG_LOAD2 to a single REG_LOAD if the mask
+ // has multiple 1-bit segments (i.e. 0xFF00FF)
+ throw new IllegalArgumentException("Value does not fit in the first 1-bit segment of the mask");
+ }
+ }
+
+ dstBuilder.setStart(start);
+ dstBuilder.setEnd(end - 1);
+ NxRegLoadBuilder nxRegLoadBuilder = new NxRegLoadBuilder();
+ nxRegLoadBuilder.setDst(dstBuilder.build());
+ nxRegLoadBuilder.setValue(value);
+ return nxRegLoadBuilder.build();
+ }
+
+ private static BigInteger[] resolveValueMask(BigInteger value, int start, int end) {
+ int bits = end - start + 1;
+ if (value.bitLength() > bits) {
+ throw new IllegalArgumentException("Value does not fit the bit range");
+ }
+
+ BigInteger mask = BigInteger.ONE.shiftLeft(bits).subtract(BigInteger.ONE).shiftLeft(start);
+ value = value.shiftLeft(start);
+
+ return new BigInteger[] {value, mask};
+ }
+
+}
return rightShifted & mask;
}
- private static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action resolveAction(
+ static org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action resolveAction(
final NxRegLoad value, final ActionPath path) {
switch (path) {
case INVENTORY_FLOWNODE_TABLE_WRITE_ACTIONS:
--- /dev/null
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH. 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.openflowplugin.extension.vendor.nicira.convertor.action;
+
+import com.google.common.base.Preconditions;
+import com.google.common.collect.ImmutableSet;
+import java.util.Set;
+import org.opendaylight.openflowplugin.extension.api.ConvertorActionToOFJava;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.NxActionRegLoadGrouping;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.DstChoice;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshTtlCase;
+import org.opendaylight.yangtools.yang.binding.DataContainer;
+
+/**
+ * RegLoad SAL actions are converted to RegLoad2 action for experimenter
+ * fields, or to RegLoad action otherwise.
+ */
+public class RegLoadConvertorProxy implements
+ ConvertorActionToOFJava<org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action,
+ Action> {
+
+ private static final RegLoadConvertor REG_LOAD_CONVERTOR = new RegLoadConvertor();
+ private static final RegLoad2Convertor REG_LOAD2_CONVERTOR = new RegLoad2Convertor();
+
+ private static final Set<Class<? extends DataContainer>> REG_LOAD2_CONVERTEES =
+ new ImmutableSet.Builder<Class<? extends DataContainer>>()
+ .add(DstNxNshFlagsCase.class)
+ .add(DstNxNshTtlCase.class)
+ .build();
+
+ @Override
+ public Action convert(
+ org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionCase) {
+ Preconditions.checkArgument(actionCase instanceof NxActionRegLoadGrouping);
+ DstChoice dstChoice = ((NxActionRegLoadGrouping) actionCase).getNxRegLoad().getDst().getDstChoice();
+ if (REG_LOAD2_CONVERTEES.contains(dstChoice.getImplementedInterface())) {
+ return REG_LOAD2_CONVERTOR.convert(actionCase);
+ } else {
+ return REG_LOAD_CONVERTOR.convert(actionCase);
+ }
+ }
+}
type empty;
}
}
+ grouping nxm-nx-nsh-flags-grouping {
+ leaf nx-nsh-flags {
+ type empty;
+ }
+ }
grouping nxm-nx-nsh-mdtype-grouping {
leaf nx-nsh-mdtype {
type empty;
type empty;
}
}
+ grouping nxm-nx-nsh-ttl-grouping {
+ leaf nx-nsh-ttl {
+ type empty;
+ }
+ }
grouping nxm-nx-tun-gpe-np-grouping {
leaf nx-tun-gpe-np {
type empty;
case dst-nx-encap-eth-dst-case {
uses nxm-nx-encap-eth-dst-grouping;
}
+ case dst-nx-nsh-flags-case {
+ uses nxm-nx-nsh-flags-grouping;
+ }
case dst-nx-nsh-mdtype-case {
uses nxm-nx-nsh-mdtype-grouping;
}
case dst-nx-nsh-np-case {
uses nxm-nx-nsh-np-grouping;
}
+ case dst-nx-nsh-ttl-case {
+ uses nxm-nx-nsh-ttl-grouping;
+ }
case dst-nx-tun-gpe-np-case {
uses nxm-nx-tun-gpe-np-grouping;
}
case src-nx-encap-eth-dst-case {
uses nxm-nx-encap-eth-dst-grouping;
}
+ case src-nx-nsh-flags-case {
+ uses nxm-nx-nsh-flags-grouping;
+ }
case src-nx-nsh-mdtype-case {
uses nxm-nx-nsh-mdtype-grouping;
}
case src-nx-nsh-np-case {
uses nxm-nx-nsh-np-grouping;
}
+ case src-nx-nsh-ttl-case {
+ uses nxm-nx-nsh-ttl-grouping;
+ }
case src-nx-tun-gpe-np-case {
uses nxm-nx-tun-gpe-np-grouping;
}
--- /dev/null
+/*
+ * Copyright (c) 2018 SUSE LINUX GmbH. 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.openflowplugin.extension.vendor.nicira.convertor.action;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Collections;
+import junitparams.JUnitParamsRunner;
+import junitparams.Parameters;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+import org.opendaylight.openflowplugin.extension.api.path.ActionPath;
+import org.opendaylight.openflowplugin.extension.vendor.nicira.convertor.match.NshFlagsConvertor;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.augments.rev150225.oxm.container.match.entry.value.ExperimenterIdCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.common.action.rev150203.actions.grouping.Action;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflow.oxm.rev150225.match.entries.grouping.MatchEntry;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.action.container.action.choice.ActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.action.rev140421.ofj.nx.action.reg.load2.grouping.NxActionRegLoad2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.OfjAugNxExpMatch;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.ofj.nxm.nx.match.nsh.flags.grouping.NshFlagsValues;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.oxm.container.match.entry.value.experimenter.id._case.nx.exp.match.entry.value.NshFlagsCaseValue;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxNshFlagsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flows.statistics.update.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.get.flow.statistics.output.flow.and.statistics.map.list.instructions.instruction.instruction.write.actions._case.write.actions.action.action.NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.group.desc.stats.updated.group.desc.stats.buckets.bucket.action.action.NxActionRegLoadNotifGroupDescStatsUpdatedCase;
+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.NxActionRegLoadNodesNodeTableFlowApplyActionsCase;
+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.NxActionRegLoadNodesNodeTableFlowWriteActionsCase;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.NxRegLoad;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.reg.load.grouping.nx.reg.load.Dst;
+
+@RunWith(JUnitParamsRunner.class)
+public class RegLoad2ConvertorTest {
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ public static Iterable<Object[]> commonData() {
+ return Arrays.asList(new Object[][] {
+ {0, 0, 0x01, 0x01, 0x01, null},
+ {0, 7, 0xFF, 0xFF, 0xFF, null},
+ {0, 3, 0x0F, 0x0F, 0x0F, null},
+ {4, 7, 0x0F, 0xF0, 0xF0, null},
+ {3, 5, 0x05, 0x28, 0x38, null}
+ });
+ }
+
+ public static Iterable<Object[]> salToOpenflowData() {
+ return Arrays.asList(new Object[][] {
+ // specified values do not fit in the bit range
+ {1, 5, 0xFF, null, null, IllegalArgumentException.class},
+ {3, 5, 0x08, null, null, IllegalArgumentException.class}
+ });
+ }
+
+ public static Iterable<Object[]> openflowToSalData() {
+ return Arrays.asList(new Object[][] {
+ // multiple 1-bit segment in mask
+ {null, null, null, 0x05, 0x05, IllegalArgumentException.class},
+ {null, null, null, 0x28, 0x28, IllegalArgumentException.class},
+ // no mask
+ {0, 7, 0x01, 0x01, null, null}
+ });
+ }
+
+ @Test
+ @Parameters(method = "commonData, salToOpenflowData")
+ public void testConvertSalToOf(Integer rangeStart,
+ Integer rangeEnd,
+ Integer rangeValue,
+ Integer value,
+ Integer mask,
+ Class<? extends Exception> expectedException) {
+
+ if (expectedException != null) {
+ thrown.expect(expectedException);
+ }
+
+ Dst dst = mock(Dst.class);
+ when(dst.getStart()).thenReturn(rangeStart);
+ when(dst.getEnd()).thenReturn(rangeEnd);
+ NxRegLoad nxRegLoad = mock(NxRegLoad.class);
+ when(nxRegLoad.getValue()).thenReturn(BigInteger.valueOf(rangeValue));
+ when(nxRegLoad.getDst()).thenReturn(dst);
+ when(nxRegLoad.getDst().getDstChoice()).thenReturn(mock(DstNxNshFlagsCase.class));
+ NxActionRegLoadNodesNodeTableFlowApplyActionsCase actionsCase =
+ mock(NxActionRegLoadNodesNodeTableFlowApplyActionsCase.class);
+ when(actionsCase.getNxRegLoad()).thenReturn(nxRegLoad);
+
+ RegLoad2Convertor regLoad2Convertor = new RegLoad2Convertor();
+ ActionRegLoad2 actionRegLoad = (ActionRegLoad2) regLoad2Convertor.convert(actionsCase).getActionChoice();
+
+ MatchEntry matchEntry = actionRegLoad.getNxActionRegLoad2().getMatchEntry().get(0);
+ ExperimenterIdCase experimenterIdCase = (ExperimenterIdCase) matchEntry.getMatchEntryValue();
+ OfjAugNxExpMatch ofjAugNxExpMatch = experimenterIdCase.augmentation(OfjAugNxExpMatch.class);
+ NshFlagsCaseValue nshFlagsCaseValue = (NshFlagsCaseValue) ofjAugNxExpMatch.getNxExpMatchEntryValue();
+ NshFlagsValues nshFlagsValues = nshFlagsCaseValue.getNshFlagsValues();
+
+ assertEquals(value.intValue(), nshFlagsValues.getNshFlags().intValue());
+ assertEquals(mask.intValue(), nshFlagsValues.getMask().intValue());
+ }
+
+ @Test
+ @Parameters(method = "commonData, openflowToSalData")
+ public void testConvertOfToSal(Integer rangeStart,
+ Integer rangeEnd,
+ Integer rangeValue,
+ Integer value,
+ Integer mask,
+ Class<? extends Exception> expectedException) {
+
+ if (expectedException != null) {
+ thrown.expect(expectedException);
+ }
+
+ NxActionRegLoad2 nxActionRegLoad2 = mock(NxActionRegLoad2.class);
+ when(nxActionRegLoad2.getMatchEntry()).thenReturn(Collections.singletonList(
+ NshFlagsConvertor.buildMatchEntry(value.shortValue(), mask == null ? null : mask.shortValue())));
+ ActionRegLoad2 actionRegLoad2 = mock(ActionRegLoad2.class);
+ when(actionRegLoad2.getNxActionRegLoad2()).thenReturn(nxActionRegLoad2);
+ Action action = mock(Action.class);
+ when(action.getActionChoice()).thenReturn(actionRegLoad2);
+
+ RegLoad2Convertor regLoad2Convertor = new RegLoad2Convertor();
+
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult
+ = regLoad2Convertor.convert(action, ActionPath.INVENTORY_FLOWNODE_TABLE_WRITE_ACTIONS);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult1
+ = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_UPDATE_APPLY_ACTIONS);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult2
+ = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_UPDATE_WRITE_ACTIONS);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult3
+ = regLoad2Convertor.convert(action, ActionPath.GROUP_DESC_STATS_UPDATED_BUCKET_ACTION);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult4
+ = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_RPC_APPLY_ACTIONS);
+ final org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionResult5
+ = regLoad2Convertor.convert(action, ActionPath.FLOWS_STATISTICS_RPC_WRITE_ACTIONS);
+
+ assertEquals(rangeStart,
+ ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getStart());
+ assertEquals(rangeEnd,
+ ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getDst().getEnd());
+ assertEquals(BigInteger.valueOf(rangeValue),
+ ((NxActionRegLoadNodesNodeTableFlowWriteActionsCase) actionResult).getNxRegLoad().getValue());
+
+ assertEquals(rangeStart,
+ ((NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase) actionResult1).getNxRegLoad().getDst()
+ .getStart());
+ assertEquals(rangeEnd,
+ ((NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase) actionResult1).getNxRegLoad().getDst()
+ .getEnd());
+ assertEquals(BigInteger.valueOf(rangeValue),
+ ((NxActionRegLoadNotifFlowsStatisticsUpdateApplyActionsCase) actionResult1).getNxRegLoad().getValue());
+
+ assertEquals(rangeStart,
+ ((NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegLoad().getDst()
+ .getStart());
+ assertEquals(rangeEnd,
+ ((NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegLoad().getDst()
+ .getEnd());
+ assertEquals(BigInteger.valueOf(rangeValue),
+ ((NxActionRegLoadNotifFlowsStatisticsUpdateWriteActionsCase) actionResult2).getNxRegLoad().getValue());
+
+ assertEquals(rangeStart,
+ ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getDst().getStart());
+ assertEquals(rangeEnd,
+ ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getDst().getEnd());
+ assertEquals(BigInteger.valueOf(rangeValue),
+ ((NxActionRegLoadNotifGroupDescStatsUpdatedCase) actionResult3).getNxRegLoad().getValue());
+
+ assertEquals(rangeStart,
+ ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst()
+ .getStart());
+ assertEquals(rangeEnd,
+ ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getDst()
+ .getEnd());
+ assertEquals(BigInteger.valueOf(rangeValue),
+ ((NxActionRegLoadNotifDirectStatisticsUpdateApplyActionsCase) actionResult4).getNxRegLoad().getValue());
+
+ assertEquals(rangeStart,
+ ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst()
+ .getStart());
+ assertEquals(rangeEnd,
+ ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getDst()
+ .getEnd());
+ assertEquals(BigInteger.valueOf(rangeValue),
+ ((NxActionRegLoadNotifDirectStatisticsUpdateWriteActionsCase) actionResult5).getNxRegLoad().getValue());
+ }
+}
\ No newline at end of file
<artifactId>argparse4j</artifactId>
<version>0.7.0</version>
</dependency>
+ <dependency>
+ <groupId>pl.pragmatists</groupId>
+ <artifactId>JUnitParams</artifactId>
+ <version>1.0.3</version>
+ </dependency>
</dependencies>
</dependencyManagement>