# export KARAF_ETC # Karaf etc folder
# export KARAF_OPTS # Additional available Karaf options
# export KARAF_DEBUG # Enable debug mode
-if [ "x$JAVA_MAX_PERM_MEM" == "x" ]; then
+if [ "x$JAVA_MAX_PERM_MEM" = "x" ]; then
export JAVA_MAX_PERM_MEM="512m"
fi
-if [ "x$JAVA_MAX_MEM" == "x" ]; then
+if [ "x$JAVA_MAX_MEM" = "x" ]; then
export JAVA_MAX_MEM="2048m"
fi
#Hosttracker hostsdb key scheme setting
hosttracker.keyscheme=IP
+# LISP Flow Mapping configuration
+# Map-Register messages overwrite existing RLOC sets in EID-to-RLOC mappings
+lisp.mappingOverwrite = true
+# Enable the Solicit-Map-Request (SMR) mechanism
+lisp.smr = false
+
import com.google.common.net.InetAddresses;
-public class FromSalConversionsUtils {
+/**
+ * MD-SAL to AD-SAL conversions collection
+ */
+public final class FromSalConversionsUtils {
- private FromSalConversionsUtils() {
+ /** http://en.wikipedia.org/wiki/IPv4#Packet_structure (end of octet number 1, bit 14.+15.) */
+ public static final int ENC_FIELD_BIT_SIZE = 2;
+ private FromSalConversionsUtils() {
+ throw new IllegalAccessError("forcing no instance for factory");
}
@SuppressWarnings("unused")
return true;
}
+ /**
+ * @param nwDscp NW-DSCP
+ * @return shifted to NW-TOS (with empty ECN part)
+ */
+ public static int dscpToTos(int nwDscp) {
+ return (short) (nwDscp << ENC_FIELD_BIT_SIZE);
+ }
}
private static SetNwTosActionCase _toAction(final SetNwTos sourceAction) {
return new SetNwTosActionCaseBuilder()
- .setSetNwTosAction(new SetNwTosActionBuilder().setTos(sourceAction.getNwTos()).build())
+ .setSetNwTosAction(new SetNwTosActionBuilder().setTos(FromSalConversionsUtils.dscpToTos(sourceAction.getNwTos())).build())
.build();
}
private static final Logger LOG = LoggerFactory.getLogger(ToSalConversionsUtils.class);
private ToSalConversionsUtils() {
-
+ throw new IllegalAccessError("forcing no instance for factory");
}
public static Flow toFlow(org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.Flow source, Node node) {
} else if (sourceAction instanceof SetNwTosActionCase) {
Integer tos = ((SetNwTosActionCase) sourceAction).getSetNwTosAction().getTos();
if (tos != null) {
- targetAction.add(new SetNwTos(tos));
+ targetAction.add(new SetNwTos(ToSalConversionsUtils.tosToNwDscp(tos)));
}
} else if (sourceAction instanceof SetTpDstActionCase) {
PortNumber port = ((SetTpDstActionCase) sourceAction).getSetTpDstAction().getPort();
return mac;
}
+
+ /**
+ * @param nwTos NW-TOS
+ * @return shifted to NW-DSCP
+ */
+ public static int tosToNwDscp(int nwTos) {
+ return (short) (nwTos >>> FromSalConversionsUtils.ENC_FIELD_BIT_SIZE);
+ }
}
--- /dev/null
+/**
+ * Copyright (c) 2014 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils;
+
+/**
+ * test of {@link FromSalConversionsUtils}
+ */
+public class FromSalConversionsUtilsTest {
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.FromSalConversionsUtils#dscpToTos(int)}.
+ */
+ @Test
+ public void testDscpToTos() {
+ Assert.assertEquals(0, FromSalConversionsUtils.dscpToTos(0));
+ Assert.assertEquals(4, FromSalConversionsUtils.dscpToTos(1));
+ Assert.assertEquals(252, FromSalConversionsUtils.dscpToTos(63));
+ Assert.assertEquals(256, FromSalConversionsUtils.dscpToTos(64));
+ Assert.assertEquals(-4, FromSalConversionsUtils.dscpToTos(-1));
+ }
+
+}
}
assertTrue("Ipv4 address wasn't found.", ipv4AddressFound);
} else if (innerAction instanceof SetNwTosActionCase) {
- assertEquals("Wrong TOS in SetNwTosAction.", (Integer) 63, ((SetNwTosActionCase) innerAction).getSetNwTosAction().getTos());
+ assertEquals("Wrong TOS in SetNwTosAction.", (Integer) 252, ((SetNwTosActionCase) innerAction).getSetNwTosAction().getTos());
} else if (innerAction instanceof SetNwDstActionCase) {
Address address = ((SetNwDstActionCase) innerAction).getSetNwDstAction().getAddress();
boolean ipv4AddressFound = false;
private void prepareActionSetNwTos(SetNwTosActionCaseBuilder wrapper) {
SetNwTosActionBuilder setNwTosActionBuilder = new SetNwTosActionBuilder();
- setNwTosActionBuilder.setTos(63);
+ setNwTosActionBuilder.setTos(252);
wrapper.setSetNwTosAction(setNwTosActionBuilder.build());
}
--- /dev/null
+/**
+ * Copyright (c) 2014 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.sal.compatibility.test;
+
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils;
+
+/**
+ * test of {@link ToSalConversionsUtils}
+ */
+public class ToSalConversionsUtilsTest {
+
+ /**
+ * Test method for {@link org.opendaylight.controller.sal.compatibility.ToSalConversionsUtils#tosToNwDscp(int)}.
+ */
+ @Test
+ public void testTosToNwDscp() {
+ Assert.assertEquals(0, ToSalConversionsUtils.tosToNwDscp(0));
+ Assert.assertEquals(0, ToSalConversionsUtils.tosToNwDscp(1));
+ Assert.assertEquals(1, ToSalConversionsUtils.tosToNwDscp(4));
+ Assert.assertEquals(63, ToSalConversionsUtils.tosToNwDscp(252));
+ Assert.assertEquals(63, ToSalConversionsUtils.tosToNwDscp(253));
+ Assert.assertEquals(-1, ToSalConversionsUtils.tosToNwDscp(-1));
+ }
+}
import akka.actor.ActorRef;
import akka.actor.Props;
import akka.testkit.JavaTestKit;
+import akka.util.Timeout;
+import com.google.protobuf.ByteString;
import junit.framework.Assert;
import org.junit.Test;
import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl;
import org.opendaylight.controller.cluster.raft.RaftActorContext;
import org.opendaylight.controller.cluster.raft.RaftState;
import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry;
+import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot;
import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout;
import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
+import org.opendaylight.controller.cluster.raft.messages.InstallSnapshot;
+import org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply;
import org.opendaylight.controller.cluster.raft.messages.RequestVote;
import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
-
+import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
+import scala.concurrent.Await;
+import scala.concurrent.Future;
+import scala.concurrent.duration.Duration;
+import scala.concurrent.duration.FiniteDuration;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import static akka.pattern.Patterns.ask;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
public class FollowerTest extends AbstractRaftActorBehaviorTest {
return new Follower(actorContext);
}
- @Override protected RaftActorContext createActorContext() {
- return new MockRaftActorContext("test", getSystem(), followerActor);
+ @Override protected RaftActorContext createActorContext() {
+ return createActorContext(followerActor);
+ }
+
+ protected RaftActorContext createActorContext(ActorRef actorRef){
+ return new MockRaftActorContext("test", getSystem(), actorRef);
}
@Test
createActorContext();
context.setLastApplied(100);
- setLastLogEntry((MockRaftActorContext) context, 1, 100, new MockRaftActorContext.MockPayload(""));
+ setLastLogEntry((MockRaftActorContext) context, 1, 100,
+ new MockRaftActorContext.MockPayload(""));
((MockRaftActorContext) context).getReplicatedLog().setSnapshotIndex(99);
List<ReplicatedLogEntry> entries =
Arrays.asList(
- (ReplicatedLogEntry) new MockRaftActorContext.MockReplicatedLogEntry(2, 101,
- new MockRaftActorContext.MockPayload("foo"))
+ (ReplicatedLogEntry) new MockRaftActorContext.MockReplicatedLogEntry(2, 101,
+ new MockRaftActorContext.MockPayload("foo"))
);
// The new commitIndex is 101
}};
}
+
+ /**
+ * This test verifies that when InstallSnapshot is received by
+ * the follower its applied correctly.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testHandleInstallSnapshot() throws Exception {
+ JavaTestKit javaTestKit = new JavaTestKit(getSystem()) {{
+
+ ActorRef leaderActor = getSystem().actorOf(Props.create(
+ MessageCollectorActor.class));
+
+ MockRaftActorContext context = (MockRaftActorContext)
+ createActorContext(getRef());
+
+ Follower follower = (Follower)createBehavior(context);
+
+ HashMap<String, String> followerSnapshot = new HashMap<>();
+ followerSnapshot.put("1", "A");
+ followerSnapshot.put("2", "B");
+ followerSnapshot.put("3", "C");
+
+ ByteString bsSnapshot = toByteString(followerSnapshot);
+ ByteString chunkData = ByteString.EMPTY;
+ int offset = 0;
+ int snapshotLength = bsSnapshot.size();
+ int i = 1;
+
+ do {
+ chunkData = getNextChunk(bsSnapshot, offset);
+ final InstallSnapshot installSnapshot =
+ new InstallSnapshot(1, "leader-1", i, 1,
+ chunkData, i, 3);
+ follower.handleMessage(leaderActor, installSnapshot);
+ offset = offset + 50;
+ i++;
+ } while ((offset+50) < snapshotLength);
+
+ final InstallSnapshot installSnapshot3 = new InstallSnapshot(1, "leader-1", 3, 1, chunkData, 3, 3);
+ follower.handleMessage(leaderActor, installSnapshot3);
+
+ String[] matches = new ReceiveWhile<String>(String.class, duration("2 seconds")) {
+ @Override
+ protected String match(Object o) throws Exception {
+ if (o instanceof ApplySnapshot) {
+ ApplySnapshot as = (ApplySnapshot)o;
+ if (as.getSnapshot().getLastIndex() != installSnapshot3.getLastIncludedIndex()) {
+ return "applySnapshot-lastIndex-mismatch";
+ }
+ if (as.getSnapshot().getLastAppliedTerm() != installSnapshot3.getLastIncludedTerm()) {
+ return "applySnapshot-lastAppliedTerm-mismatch";
+ }
+ if (as.getSnapshot().getLastAppliedIndex() != installSnapshot3.getLastIncludedIndex()) {
+ return "applySnapshot-lastAppliedIndex-mismatch";
+ }
+ if (as.getSnapshot().getLastTerm() != installSnapshot3.getLastIncludedTerm()) {
+ return "applySnapshot-lastTerm-mismatch";
+ }
+ return "applySnapshot";
+ }
+
+ return "ignoreCase";
+ }
+ }.get();
+
+ String applySnapshotMatch = "";
+ for (String reply: matches) {
+ if (reply.startsWith("applySnapshot")) {
+ applySnapshotMatch = reply;
+ }
+ }
+
+ assertEquals("applySnapshot", applySnapshotMatch);
+
+ Object messages = executeLocalOperation(leaderActor, "get-all-messages");
+
+ assertNotNull(messages);
+ assertTrue(messages instanceof List);
+ List<Object> listMessages = (List<Object>) messages;
+
+ int installSnapshotReplyReceivedCount = 0;
+ for (Object message: listMessages) {
+ if (message instanceof InstallSnapshotReply) {
+ ++installSnapshotReplyReceivedCount;
+ }
+ }
+
+ assertEquals(3, installSnapshotReplyReceivedCount);
+
+ }};
+ }
+
+ public Object executeLocalOperation(ActorRef actor, Object message) throws Exception {
+ FiniteDuration operationDuration = Duration.create(5, TimeUnit.SECONDS);
+ Timeout operationTimeout = new Timeout(operationDuration);
+ Future<Object> future = ask(actor, message, operationTimeout);
+
+ try {
+ return Await.result(future, operationDuration);
+ } catch (Exception e) {
+ throw e;
+ }
+ }
+
+ public ByteString getNextChunk (ByteString bs, int offset){
+ int snapshotLength = bs.size();
+ int start = offset;
+ int size = 50;
+ if (50 > snapshotLength) {
+ size = snapshotLength;
+ } else {
+ if ((start + 50) > snapshotLength) {
+ size = snapshotLength - start;
+ }
+ }
+ return bs.substring(start, start + size);
+ }
+
+ private ByteString toByteString(Map<String, String> state) {
+ ByteArrayOutputStream b = null;
+ ObjectOutputStream o = null;
+ try {
+ try {
+ b = new ByteArrayOutputStream();
+ o = new ObjectOutputStream(b);
+ o.writeObject(state);
+ byte[] snapshotBytes = b.toByteArray();
+ return ByteString.copyFrom(snapshotBytes);
+ } finally {
+ if (o != null) {
+ o.flush();
+ o.close();
+ }
+ if (b != null) {
+ b.close();
+ }
+ }
+ } catch (IOException e) {
+ org.junit.Assert.fail("IOException in converting Hashmap to Bytestring:" + e);
+ }
+ return null;
+ }
}
--- /dev/null
+/*
+ * Copyright (c) 2013 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,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.raft.utils;
+
+import akka.actor.UntypedActor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+
+public class MessageCollectorActor extends UntypedActor {
+ private List<Object> messages = new ArrayList<>();
+
+ @Override public void onReceive(Object message) throws Exception {
+ if(message instanceof String){
+ if("get-all-messages".equals(message)){
+ getSender().tell(messages, getSelf());
+ }
+ } else {
+ messages.add(message);
+ }
+ }
+}
this.executor = Preconditions.checkNotNull(executor);
}
+ private static ThreadExecutorStatsMXBeanImpl createInternal(final Executor executor,
+ final String mBeanName, final String mBeanType, final String mBeanCategory) {
+ if (executor instanceof ThreadPoolExecutor) {
+ final ThreadExecutorStatsMXBeanImpl ret = new ThreadExecutorStatsMXBeanImpl(
+ (ThreadPoolExecutor) executor, mBeanName, mBeanType, mBeanCategory);
+ return ret;
+ }
+
+ LOG.info("Executor {} is not supported", executor);
+ return null;
+ }
+
/**
- * Create a new bean for the statistics, which is already registered.
+ * Creates a new bean if the backing executor is a ThreadPoolExecutor and registers it.
*
- * @param executor
- * @param mBeanName
- * @param mBeanType
- * @param mBeanCategory
- * @return
+ * @param executor the backing {@link Executor}
+ * @param mBeanName Used as the <code>name</code> property in the bean's ObjectName.
+ * @param mBeanType Used as the <code>type</code> property in the bean's ObjectName.
+ * @param mBeanCategory Used as the <code>Category</code> property in the bean's ObjectName.
+ * @return a registered ThreadExecutorStatsMXBeanImpl instance if the backing executor
+ * is a ThreadPoolExecutor, otherwise null.
*/
public static ThreadExecutorStatsMXBeanImpl create(final Executor executor, final String mBeanName,
final String mBeanType, @Nullable final String mBeanCategory) {
- if (executor instanceof ThreadPoolExecutor) {
- final ThreadExecutorStatsMXBeanImpl ret = new ThreadExecutorStatsMXBeanImpl((ThreadPoolExecutor) executor, mBeanName, mBeanType, mBeanCategory);
+ ThreadExecutorStatsMXBeanImpl ret = createInternal(executor, mBeanName, mBeanType, mBeanCategory);
+ if(ret != null) {
ret.registerMBean();
- return ret;
}
- LOG.info("Executor {} is not supported", executor);
- return null;
+ return ret;
+ }
+
+ /**
+ * Creates a new bean if the backing executor is a ThreadPoolExecutor.
+ *
+ * @param executor the backing {@link Executor}
+ * @return a ThreadExecutorStatsMXBeanImpl instance if the backing executor
+ * is a ThreadPoolExecutor, otherwise null.
+ */
+ public static ThreadExecutorStatsMXBeanImpl create(final Executor executor) {
+ return createInternal(executor, "", "", null);
}
@Override
}
public void setDataStoreExecutor(ExecutorService dsExecutor) {
- this.dataStoreExecutorStatsBean = ThreadExecutorStatsMXBeanImpl.create(dsExecutor,
- "notification-executor", getMBeanType(), getMBeanCategory());
+ this.dataStoreExecutorStatsBean = ThreadExecutorStatsMXBeanImpl.create(dsExecutor);
}
public void setNotificationManager(QueuedNotificationManager<?, ?> manager) {
this.notificationManagerStatsBean = new QueuedNotificationManagerMXBeanImpl(manager,
"notification-manager", getMBeanType(), getMBeanCategory());
- this.notificationExecutorStatsBean = ThreadExecutorStatsMXBeanImpl.create(manager.getExecutor(),
- "data-store-executor", getMBeanType(), getMBeanCategory());
+ this.notificationExecutorStatsBean = ThreadExecutorStatsMXBeanImpl.create(manager.getExecutor());
}
@Override
@Override
public ThreadExecutorStats getDataStoreExecutorStats() {
- return dataStoreExecutorStatsBean.toThreadExecutorStats();
+ return dataStoreExecutorStatsBean == null ? null :
+ dataStoreExecutorStatsBean.toThreadExecutorStats();
}
@Override
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-2014 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,
end += rawPayload.length;
}
int checksumStartByte = start + getfieldOffset(CHECKSUM) / NetUtils.NumBitsInAByte;
+ int even = end & ~1;
- for (int i = start; i <= (end - 1); i = i + 2) {
+ for (int i = start; i < even; i = i + 2) {
// Skip, if the current bytes are checkSum bytes
if (i == checksumStartByte) {
continue;
wordData = ((data[i] << 8) & 0xFF00) + (data[i + 1] & 0xFF);
sum = sum + wordData;
}
- carry = (sum >> 16) & 0xFF;
+ if (even < end) {
+ // Add the last octet with zero padding.
+ wordData = (data[even] << 8) & 0xFF00;
+ sum = sum + wordData;
+ }
+
+ carry = sum >>> 16;
finalSum = (sum & 0xFFFF) + carry;
return (short) ~((short) finalSum & 0xFFFF);
}
*/
public void setHeaderField(String headerField, byte[] readValue) {
if (headerField.equals(PROTOCOL)) {
- payloadClass = protocolClassMap.get(readValue[0]);
+ // Don't set payloadClass if framgment offset is not zero.
+ byte[] fragoff = hdrFieldsMap.get(FRAGOFFSET);
+ if (fragoff == null || BitBufferHelper.getShort(fragoff) == 0) {
+ payloadClass = protocolClassMap.get(readValue[0]);
+ }
+ } else if (headerField.equals(FRAGOFFSET)) {
+ if (readValue != null && BitBufferHelper.getShort(readValue) != 0) {
+ // Clear payloadClass because protocol header is not present
+ // in this packet.
+ payloadClass = null;
+ }
} else if (headerField.equals(OPTIONS) &&
(readValue == null || readValue.length == 0)) {
hdrFieldsMap.remove(headerField);
/*
- * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2013-2014 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,
package org.opendaylight.controller.sal.packet;
+import java.util.Arrays;
+
import junit.framework.Assert;
import org.junit.Test;
(byte) 0x2b, (byte) 0x2c, (byte) 0x2d, (byte) 0x2e,
(byte) 0x2f, (byte) 0x30, (byte) 0x31, (byte) 0x32,
(byte) 0x33, (byte) 0x34, (byte) 0x35, (byte) 0x36, (byte) 0x37 };
+ serializeTest(icmpRawPayload, (short)0xe553);
+
+ serializeTest(null, (short)0xb108);
+ serializeTest(new byte[0], (short)0xb108);
+
+ byte[] odd = {
+ (byte)0xba, (byte)0xd4, (byte)0xc7, (byte)0x53,
+ (byte)0xf8, (byte)0x59, (byte)0x68, (byte)0x77,
+ (byte)0xfd, (byte)0x27, (byte)0xe0, (byte)0x5b,
+ (byte)0xd0, (byte)0x2e, (byte)0x28, (byte)0x41,
+ (byte)0xa3, (byte)0x48, (byte)0x5d, (byte)0x2e,
+ (byte)0x7d, (byte)0x5b, (byte)0xd3, (byte)0x60,
+ (byte)0xb3, (byte)0x88, (byte)0x8d, (byte)0x0f,
+ (byte)0x1d, (byte)0x87, (byte)0x51, (byte)0x0f,
+ (byte)0x6a, (byte)0xff, (byte)0xf7, (byte)0xd4,
+ (byte)0x40, (byte)0x35, (byte)0x4e, (byte)0x01,
+ (byte)0x36,
+ };
+ serializeTest(odd, (short)0xd0ad);
+
+ // Large payload that causes 16-bit checksum overflow more than
+ // 255 times.
+ byte[] largeEven = new byte[1024];
+ Arrays.fill(largeEven, (byte)0xff);
+ serializeTest(largeEven, (short)0xb108);
+
+ byte[] largeOdd = new byte[1021];
+ Arrays.fill(largeOdd, (byte)0xff);
+ serializeTest(largeOdd, (short)0xb207);
+ }
- short checksum = (short)0xe553;
-
- // Create ICMP object
+ private void serializeTest(byte[] payload, short checksum)
+ throws PacketException {
ICMP icmp = new ICMP();
- icmp.setType((byte)8);
- icmp.setCode((byte)0);
- icmp.setIdentifier((short) 0x46f5);
- icmp.setSequenceNumber((short) 2);
- icmp.setRawPayload(icmpRawPayload);
- //icmp.setChecksum(checksum);
+ icmp.setType((byte)8).setCode((byte)0).
+ setIdentifier((short)0x46f5).setSequenceNumber((short)2);
+ int payloadSize = 0;
+ if (payload != null) {
+ icmp.setRawPayload(payload);
+ payloadSize = payload.length;
+ }
// Serialize
- byte[] stream = icmp.serialize();
- Assert.assertTrue(stream.length == 64);
+ byte[] data = icmp.serialize();
+ Assert.assertEquals(payloadSize + 8, data.length);
// Deserialize
ICMP icmpDes = new ICMP();
- icmpDes.deserialize(stream, 0, stream.length);
+ icmpDes.deserialize(data, 0, data.length);
Assert.assertFalse(icmpDes.isCorrupted());
- Assert.assertTrue(icmpDes.getChecksum() == checksum);
- Assert.assertTrue(icmp.equals(icmpDes));
+ Assert.assertEquals(checksum, icmpDes.getChecksum());
+ Assert.assertEquals(icmp, icmpDes);
}
}
import java.net.UnknownHostException;
import java.util.Arrays;
-import junit.framework.Assert;
-
+import org.junit.Assert;
import org.junit.Test;
+
import org.opendaylight.controller.sal.match.Match;
import org.opendaylight.controller.sal.match.MatchType;
import org.opendaylight.controller.sal.utils.EtherTypes;
Assert.assertEquals(protocol, (byte) match.getField(MatchType.NW_PROTO).getValue());
Assert.assertEquals(tos, (byte) match.getField(MatchType.NW_TOS).getValue());
}
+
+ @Test
+ public void testFragment() throws Exception {
+ byte[] payload1 = new byte[0];
+ byte[] payload2 = {
+ (byte)0x61, (byte)0xd1, (byte)0x3d, (byte)0x51,
+ (byte)0x1b, (byte)0x75, (byte)0xa7, (byte)0x83,
+ };
+ byte[] payload3 = {
+ (byte)0xe7, (byte)0x0f, (byte)0x2d, (byte)0x7e,
+ (byte)0x15, (byte)0xba, (byte)0xe7, (byte)0x6d,
+ (byte)0xb5, (byte)0xc5, (byte)0xb5, (byte)0x37,
+ (byte)0x59, (byte)0xbc, (byte)0x91, (byte)0x43,
+ (byte)0xb5, (byte)0xb7, (byte)0xe4, (byte)0x28,
+ (byte)0xec, (byte)0x62, (byte)0x6b, (byte)0x6a,
+ (byte)0xd1, (byte)0xcb, (byte)0x79, (byte)0x1e,
+ (byte)0xfc, (byte)0x82, (byte)0xf5, (byte)0xb4,
+ };
+
+ // Ensure that the payload is not deserialized if the fragment offset
+ // is not zero.
+ byte proto = IPProtocols.TCP.byteValue();
+ fragmentTest(payload1, proto, (short)0xf250);
+ fragmentTest(payload2, proto, (short)0xf248);
+ fragmentTest(payload3, proto, (short)0xf230);
+
+ proto = IPProtocols.UDP.byteValue();
+ fragmentTest(payload1, proto, (short)0xf245);
+ fragmentTest(payload2, proto, (short)0xf23d);
+ fragmentTest(payload3, proto, (short)0xf225);
+
+ proto = IPProtocols.ICMP.byteValue();
+ fragmentTest(payload1, proto, (short)0xf255);
+ fragmentTest(payload2, proto, (short)0xf24d);
+ fragmentTest(payload3, proto, (short)0xf235);
+
+ // Ensure that the protocol header in the first fragment is
+ // deserialized.
+ proto = IPProtocols.TCP.byteValue();
+ TCP tcp = new TCP();
+ tcp.setSourcePort((short)1234).setDestinationPort((short)32000).
+ setSequenceNumber((int)0xd541f5f8).setAckNumber((int)0x58da787d).
+ setDataOffset((byte)5).setReserved((byte)0).
+ setHeaderLenFlags((short)0x18).setWindowSize((short)0x40e8).
+ setUrgentPointer((short)0x15f7).setChecksum((short)0x0d4e);
+ firstFragmentTest(tcp, payload1, proto, (short)0xdfe6);
+ tcp.setChecksum((short)0xab2a);
+ firstFragmentTest(tcp, payload2, proto, (short)0xdfde);
+ tcp.setChecksum((short)0x1c75);
+ firstFragmentTest(tcp, payload3, proto, (short)0xdfc6);
+
+ proto = IPProtocols.UDP.byteValue();
+ UDP udp = new UDP();
+ udp.setSourcePort((short)53).setDestinationPort((short)45383).
+ setLength((short)(payload1.length + 8)).setChecksum((short)0);
+ firstFragmentTest(udp, payload1, proto, (short)0xdfe7);
+ udp.setLength((short)(payload2.length + 8));
+ firstFragmentTest(udp, payload2, proto, (short)0xdfdf);
+ udp.setLength((short)(payload3.length + 8));
+ firstFragmentTest(udp, payload3, proto, (short)0xdfc7);
+
+ proto = IPProtocols.ICMP.byteValue();
+ ICMP icmp = new ICMP();
+ icmp.setType((byte)8).setCode((byte)0).setIdentifier((short)0x3d1e).
+ setSequenceNumber((short)1);
+ firstFragmentTest(icmp, payload1, proto, (short)0xdff7);
+ firstFragmentTest(icmp, payload2, proto, (short)0xdfef);
+ firstFragmentTest(icmp, payload3, proto, (short)0xdfd7);
+ }
+
+ private void fragmentTest(byte[] payload, byte proto, short checksum)
+ throws Exception {
+ // Construct a fragmented raw IPv4 packet.
+ int ipv4Len = 20;
+ byte[] rawIp = new byte[ipv4Len + payload.length];
+
+ byte ipVersion = 4;
+ byte dscp = 35;
+ byte ecn = 2;
+ byte tos = (byte)((dscp << 2) | ecn);
+ short totalLen = (short)rawIp.length;
+ short id = 22143;
+ short offset = 0xb9;
+ byte ttl = 64;
+ byte[] srcIp = {(byte)0x0a, (byte)0x00, (byte)0x00, (byte)0x01};
+ byte[] dstIp = {(byte)0xc0, (byte)0xa9, (byte)0x66, (byte)0x23};
+
+ rawIp[0] = (byte)((ipVersion << 4) | (ipv4Len >> 2));
+ rawIp[1] = tos;
+ rawIp[2] = (byte)(totalLen >>> Byte.SIZE);
+ rawIp[3] = (byte)totalLen;
+ rawIp[4] = (byte)(id >>> Byte.SIZE);
+ rawIp[5] = (byte)id;
+ rawIp[6] = (byte)(offset >>> Byte.SIZE);
+ rawIp[7] = (byte)offset;
+ rawIp[8] = ttl;
+ rawIp[9] = proto;
+ rawIp[10] = (byte)(checksum >>> Byte.SIZE);
+ rawIp[11] = (byte)checksum;
+ System.arraycopy(srcIp, 0, rawIp, 12, srcIp.length);
+ System.arraycopy(dstIp, 0, rawIp, 16, srcIp.length);
+ System.arraycopy(payload, 0, rawIp, ipv4Len, payload.length);
+
+ // Deserialize.
+ IPv4 ipv4 = new IPv4();
+ ipv4.deserialize(rawIp, 0, rawIp.length * Byte.SIZE);
+
+ Assert.assertEquals(ipVersion, ipv4.getVersion());
+ Assert.assertEquals(ipv4Len, ipv4.getHeaderLen());
+ Assert.assertEquals(dscp, ipv4.getDiffServ());
+ Assert.assertEquals(ecn, ipv4.getECN());
+ Assert.assertEquals(totalLen, ipv4.getTotalLength());
+ Assert.assertEquals(id, ipv4.getIdentification());
+ Assert.assertEquals((byte)0, ipv4.getFlags());
+ Assert.assertEquals(offset, ipv4.getFragmentOffset());
+ Assert.assertEquals(ttl, ipv4.getTtl());
+ Assert.assertEquals(proto, ipv4.getProtocol());
+ Assert.assertEquals(checksum, ipv4.getChecksum());
+ Assert.assertEquals(NetUtils.byteArray4ToInt(srcIp),
+ ipv4.getSourceAddress());
+ Assert.assertEquals(NetUtils.byteArray4ToInt(dstIp),
+ ipv4.getDestinationAddress());
+ Assert.assertFalse(ipv4.isCorrupted());
+
+ // payloadClass should not be set if fragment offset is not zero.
+ Assert.assertEquals(null, ipv4.getPayload());
+ Assert.assertArrayEquals(payload, ipv4.getRawPayload());
+ }
+
+ private void firstFragmentTest(Packet payload, byte[] rawPayload,
+ byte proto, short checksum)
+ throws Exception {
+ // Construct a raw IPv4 packet with MF flag.
+ int ipv4Len = 20;
+ payload.setRawPayload(rawPayload);
+ byte[] payloadBytes = payload.serialize();
+ byte[] rawIp = new byte[ipv4Len + payloadBytes.length];
+
+ byte ipVersion = 4;
+ byte dscp = 13;
+ byte ecn = 1;
+ byte tos = (byte)((dscp << 2) | ecn);
+ short totalLen = (short)rawIp.length;
+ short id = 19834;
+ byte flags = 0x1;
+ short offset = 0;
+ short off = (short)(((short)flags << 13) | offset);
+ byte ttl = 64;
+ byte[] srcIp = {(byte)0xac, (byte)0x23, (byte)0x5b, (byte)0xfd};
+ byte[] dstIp = {(byte)0xc0, (byte)0xa8, (byte)0x64, (byte)0x71};
+
+ rawIp[0] = (byte)((ipVersion << 4) | (ipv4Len >> 2));
+ rawIp[1] = tos;
+ rawIp[2] = (byte)(totalLen >>> Byte.SIZE);
+ rawIp[3] = (byte)totalLen;
+ rawIp[4] = (byte)(id >>> Byte.SIZE);
+ rawIp[5] = (byte)id;
+ rawIp[6] = (byte)(off >>> Byte.SIZE);
+ rawIp[7] = (byte)off;
+ rawIp[8] = ttl;
+ rawIp[9] = proto;
+ rawIp[10] = (byte)(checksum >>> Byte.SIZE);
+ rawIp[11] = (byte)checksum;
+ System.arraycopy(srcIp, 0, rawIp, 12, srcIp.length);
+ System.arraycopy(dstIp, 0, rawIp, 16, srcIp.length);
+ System.arraycopy(payloadBytes, 0, rawIp, ipv4Len, payloadBytes.length);
+
+ // Deserialize.
+ IPv4 ipv4 = new IPv4();
+ ipv4.deserialize(rawIp, 0, rawIp.length * Byte.SIZE);
+
+ Assert.assertEquals(ipVersion, ipv4.getVersion());
+ Assert.assertEquals(ipv4Len, ipv4.getHeaderLen());
+ Assert.assertEquals(dscp, ipv4.getDiffServ());
+ Assert.assertEquals(ecn, ipv4.getECN());
+ Assert.assertEquals(totalLen, ipv4.getTotalLength());
+ Assert.assertEquals(id, ipv4.getIdentification());
+ Assert.assertEquals(flags, ipv4.getFlags());
+ Assert.assertEquals(offset, ipv4.getFragmentOffset());
+ Assert.assertEquals(ttl, ipv4.getTtl());
+ Assert.assertEquals(proto, ipv4.getProtocol());
+ Assert.assertEquals(checksum, ipv4.getChecksum());
+ Assert.assertEquals(NetUtils.byteArray4ToInt(srcIp),
+ ipv4.getSourceAddress());
+ Assert.assertEquals(NetUtils.byteArray4ToInt(dstIp),
+ ipv4.getDestinationAddress());
+ Assert.assertFalse(ipv4.isCorrupted());
+
+ // Protocol header in the first fragment should be deserialized.
+ Assert.assertEquals(null, ipv4.getRawPayload());
+
+ Packet desPayload = ipv4.getPayload();
+ Assert.assertEquals(payload, desPayload);
+ Assert.assertFalse(desPayload.isCorrupted());
+ Assert.assertArrayEquals(rawPayload, desPayload.getRawPayload());
+ }
}