Skip to content

Commit 2f68a33

Browse files
Merge pull request #93 from cisco-system-traffic-generator/ipv6ns
add vlan and srcIp option for ipv6 ns
2 parents f8e7df9 + 2d90c01 commit 2f68a33

File tree

2 files changed

+74
-14
lines changed

2 files changed

+74
-14
lines changed

src/main/java/com/cisco/trex/stateless/IPv6NeighborDiscoveryService.java

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,26 @@
1010
import com.cisco.trex.stateless.model.StreamRxStats;
1111
import com.cisco.trex.stateless.model.StreamVM;
1212
import com.cisco.trex.stateless.model.TRexClientResult;
13+
import com.cisco.trex.stateless.model.port.PortVlan;
14+
import com.google.common.collect.Lists;
1315
import com.google.common.net.InetAddresses;
1416
import java.net.Inet6Address;
1517
import java.net.UnknownHostException;
18+
import java.util.AbstractMap;
1619
import java.util.ArrayList;
1720
import java.util.Arrays;
1821
import java.util.Collections;
1922
import java.util.HashMap;
23+
import java.util.LinkedList;
2024
import java.util.List;
2125
import java.util.Map;
2226
import java.util.Optional;
27+
import java.util.Queue;
2328
import java.util.function.Predicate;
2429
import java.util.stream.Collectors;
2530
import java.util.stream.Stream;
2631
import org.apache.commons.lang3.StringUtils;
32+
import org.pcap4j.packet.Dot1qVlanTagPacket;
2733
import org.pcap4j.packet.EthernetPacket;
2834
import org.pcap4j.packet.IcmpV6CommonPacket;
2935
import org.pcap4j.packet.IcmpV6CommonPacket.IpV6NeighborDiscoveryOption;
@@ -48,6 +54,8 @@
4854

4955
public class IPv6NeighborDiscoveryService {
5056

57+
private static final EtherType QInQ =
58+
new EtherType((short) 0x88a8, "802.1Q Provider Bridge (Q-in-Q)");
5159
private TRexClient tRexClient;
5260

5361
public IPv6NeighborDiscoveryService(TRexClient tRexClient) {
@@ -67,6 +75,7 @@ public Map<String, Ipv6Node> scan(int portIdx, int timeDuration, String dstIP, S
6775
}
6876

6977
String srcMac = portStatus.getAttr().getLayerConiguration().getL2Configuration().getSrc();
78+
PortVlan vlan = portStatus.getAttr().getVlan();
7079

7180
Packet pingPkt =
7281
buildICMPV6EchoReq(
@@ -91,8 +100,10 @@ public Map<String, Ipv6Node> scan(int portIdx, int timeDuration, String dstIP, S
91100
String nodeIp = ipV6Packet.getHeader().getSrcAddr().toString().substring(1);
92101
String nodeMac = getLinkLayerAddress(ipV6Packet);
93102

94-
nsNaStreams.add(buildStream(buildICMPV6NSPkt(srcMac, nodeMac, nodeIp, srcIP)));
95-
nsNaStreams.add(buildStream(buildICMPV6NAPkt(srcMac, nodeMac, nodeIp, srcIP)));
103+
nsNaStreams.add(
104+
buildStream(buildICMPV6NSPkt(vlan, srcMac, nodeMac, nodeIp, srcIP)));
105+
nsNaStreams.add(
106+
buildStream(buildICMPV6NAPkt(vlan, srcMac, nodeMac, nodeIp, srcIP)));
96107
});
97108
}
98109

@@ -183,15 +194,16 @@ public EthernetPacket sendNeighborSolicitation(int portIdx, int timeout, String
183194
throw new ServiceModeRequiredException();
184195
}
185196
String srcMac = portStatus.getAttr().getLayerConiguration().getL2Configuration().getSrc();
186-
return sendNeighborSolicitation(portIdx, timeout, srcMac, dstIp);
197+
PortVlan vlan = portStatus.getAttr().getVlan();
198+
return sendNeighborSolicitation(vlan, portIdx, timeout, srcMac, null, dstIp);
187199
}
188200

189201
public EthernetPacket sendNeighborSolicitation(
190-
int portIdx, int timeout, String srcMac, String dstIp) {
202+
PortVlan vlan, int portIdx, int timeout, String srcMac, String srcIp, String dstIp) {
191203
long endTs = System.currentTimeMillis() + timeout * 1000;
192204

193205
Packet icmpv6NSPkt =
194-
buildICMPV6NSPkt(srcMac, multicastMacFromIPv6(dstIp).toString(), dstIp, null);
206+
buildICMPV6NSPkt(vlan, srcMac, multicastMacFromIPv6(dstIp).toString(), dstIp, srcIp);
195207

196208
tRexClient.startStreamsIntermediate(portIdx, Arrays.asList(buildStream(icmpv6NSPkt)));
197209

@@ -239,14 +251,45 @@ public EthernetPacket sendNeighborSolicitation(
239251
return na;
240252
}
241253

254+
private static AbstractMap.SimpleEntry<EtherType, Packet.Builder> buildVlan(
255+
IpV6Packet.Builder ipv6Builder, PortVlan vlan) {
256+
Queue<Integer> vlanTags = new LinkedList<>(Lists.reverse(vlan.getTags()));
257+
Packet.Builder resultPayloadBuilder = ipv6Builder;
258+
EtherType resultEtherType = EtherType.IPV6;
259+
260+
if (vlanTags.peek() != null) {
261+
Dot1qVlanTagPacket.Builder vlanInsideBuilder = new Dot1qVlanTagPacket.Builder();
262+
vlanInsideBuilder
263+
.type(EtherType.IPV6)
264+
.vid(vlanTags.poll().shortValue())
265+
.payloadBuilder(ipv6Builder);
266+
267+
resultPayloadBuilder = vlanInsideBuilder;
268+
resultEtherType = EtherType.DOT1Q_VLAN_TAGGED_FRAMES;
269+
270+
if (vlanTags.peek() != null) {
271+
Dot1qVlanTagPacket.Builder vlanOutsideBuilder = new Dot1qVlanTagPacket.Builder();
272+
vlanOutsideBuilder
273+
.type(EtherType.DOT1Q_VLAN_TAGGED_FRAMES)
274+
.vid(vlanTags.poll().shortValue())
275+
.payloadBuilder(vlanInsideBuilder);
276+
resultPayloadBuilder = vlanOutsideBuilder;
277+
resultEtherType = QInQ;
278+
}
279+
}
280+
281+
return new AbstractMap.SimpleEntry<>(resultEtherType, resultPayloadBuilder);
282+
}
283+
242284
private Map<String, EthernetPacket> sendNSandIcmpV6Req(
243285
int portIdx, int timeDuration, String srcMac, String dstIp) {
244286
long endTs = System.currentTimeMillis() + timeDuration * 1000;
245287
TRexClientResult<PortStatus> portStatusResult = tRexClient.getPortStatus(portIdx);
288+
PortVlan vlan = portStatusResult.get().getAttr().getVlan();
246289

247290
Packet pingPkt = buildICMPV6EchoReq(null, srcMac, null, dstIp);
248291
Packet icmpv6NSPkt =
249-
buildICMPV6NSPkt(srcMac, multicastMacFromIPv6(dstIp).toString(), dstIp, null);
292+
buildICMPV6NSPkt(vlan, srcMac, multicastMacFromIPv6(dstIp).toString(), dstIp, null);
250293

251294
List<com.cisco.trex.stateless.model.Stream> stlStreams =
252295
Stream.of(buildStream(pingPkt), buildStream(icmpv6NSPkt)).collect(Collectors.toList());
@@ -317,7 +360,8 @@ private com.cisco.trex.stateless.model.Stream buildStream(Packet pkt) {
317360
null);
318361
}
319362

320-
private Packet buildICMPV6NSPkt(String srcMac, String dstMac, String dstIp, String srcIp) {
363+
private Packet buildICMPV6NSPkt(
364+
PortVlan vlan, String srcMac, String dstMac, String dstIp, String srcIp) {
321365
EthernetPacket.Builder ethBuilder = new EthernetPacket.Builder();
322366
try {
323367

@@ -356,12 +400,19 @@ private Packet buildICMPV6NSPkt(String srcMac, String dstMac, String dstIp, Stri
356400
.payloadBuilder(icmpCommonPktBuilder)
357401
.correctLengthAtBuild(true);
358402

403+
AbstractMap.SimpleEntry<EtherType, Packet.Builder> payload =
404+
new AbstractMap.SimpleEntry<>(EtherType.IPV6, ipV6Builder);
405+
if (!vlan.getTags().isEmpty()) {
406+
payload = buildVlan(ipV6Builder, vlan);
407+
}
408+
359409
ethBuilder
360-
.type(EtherType.IPV6)
361410
.srcAddr(MacAddress.getByName(srcMac))
362411
.dstAddr(MacAddress.getByName(dstMac))
363-
.payloadBuilder(ipV6Builder)
412+
.type(payload.getKey())
413+
.payloadBuilder(payload.getValue())
364414
.paddingAtBuild(true);
415+
365416
} catch (UnknownHostException ignored) {
366417
// Do nothing
367418
}
@@ -396,7 +447,8 @@ private static String getLinkLayerAddress(IpV6Packet pkt) {
396447
return ByteArrays.toHexString(linkLayerAddress, ":");
397448
}
398449

399-
private Packet buildICMPV6NAPkt(String srcMac, String dstMac, String dstIp, String srcIP) {
450+
private Packet buildICMPV6NAPkt(
451+
PortVlan vlan, String srcMac, String dstMac, String dstIp, String srcIP) {
400452
final String specifiedSrcIP = srcIP != null ? srcIP : generateIPv6AddrFromMAC(srcMac);
401453

402454
EthernetPacket.Builder ethBuilder = new EthernetPacket.Builder();
@@ -438,12 +490,19 @@ private Packet buildICMPV6NAPkt(String srcMac, String dstMac, String dstIp, Stri
438490
.payloadBuilder(icmpCommonPktBuilder)
439491
.correctLengthAtBuild(true);
440492

493+
AbstractMap.SimpleEntry<EtherType, Packet.Builder> payload =
494+
new AbstractMap.SimpleEntry<>(EtherType.IPV6, ipV6Builder);
495+
if (!vlan.getTags().isEmpty()) {
496+
payload = buildVlan(ipV6Builder, vlan);
497+
}
498+
441499
ethBuilder
442-
.type(EtherType.IPV6)
443500
.srcAddr(MacAddress.getByName(srcMac))
444501
.dstAddr(MacAddress.getByName("33:33:00:00:00:01"))
445-
.payloadBuilder(ipV6Builder)
502+
.type(payload.getKey())
503+
.payloadBuilder(payload.getValue())
446504
.paddingAtBuild(true);
505+
447506
} catch (UnknownHostException ignored) {
448507
// Do nothing
449508
}

src/main/java/com/cisco/trex/stateless/TRexClient.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -612,13 +612,14 @@ public String resolveIpv6(int portIndex, String dstIp) throws ServiceModeRequire
612612
return null;
613613
}
614614

615-
public String resolveIpv6(int portIndex, String srcMac, String dstIp) {
615+
public String resolveIpv6(
616+
PortVlan vlan, int portIndex, String srcMac, String srcIp, String dstIp) {
616617
removeRxQueue(portIndex);
617618
setRxQueue(portIndex, 1000);
618619

619620
EthernetPacket naPacket =
620621
new IPv6NeighborDiscoveryService(this)
621-
.sendNeighborSolicitation(portIndex, 5, srcMac, dstIp);
622+
.sendNeighborSolicitation(vlan, portIndex, 5, srcMac, srcIp, dstIp);
622623
if (naPacket != null) {
623624
return naPacket.getHeader().getSrcAddr().toString();
624625
}

0 commit comments

Comments
 (0)