Skip to content

Commit e3851c2

Browse files
committed
[fix] custom header processing works
1 parent 9918ff0 commit e3851c2

11 files changed

Lines changed: 2265 additions & 115 deletions

examples/p4-basic-test-p2p.cc

Lines changed: 53 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
#include "ns3/core-module.h"
22
#include "ns3/network-module.h"
33
#include "ns3/applications-module.h"
4-
#include "ns3/point-to-point-helper.h"
4+
#include "ns3/p4-p2p-helper.h"
55
#include "ns3/internet-module.h"
66
#include "ns3/bridge-helper.h"
77
#include "ns3/p4-helper.h"
88
#include "ns3/global.h"
99

10+
#include "ns3/custom-header.h"
11+
#include "ns3/custom-p2p-net-device.h"
1012
#include "ns3/format-utils.h"
1113
#include "ns3/p4-topology-reader-helper.h"
1214

@@ -68,12 +70,19 @@ struct HostNodeC_t
6870
int
6971
main (int argc, char *argv[])
7072
{
73+
74+
// ============================ parameters ============================
75+
76+
ns3::PacketMetadata::Enable (); // 开启数据包元数据追踪
77+
7178
LogComponentEnable ("P4BasicTestP2P", LOG_LEVEL_INFO);
79+
LogComponentEnable ("CustomP2PNetDevice", LOG_LEVEL_DEBUG);
80+
LogComponentEnable ("BridgeP4NetDevice", LOG_LEVEL_DEBUG);
7281

7382
// ============================ parameters ============================
7483

7584
// Simulation parameters
76-
uint16_t pktSize = 512; //in Bytes. 1458 to prevent fragments, default 512
85+
uint16_t pktSize = 1000; //in Bytes. 1458 to prevent fragments, default 512
7786

7887
// h1 -> h2 with 2.0Mbps
7988
std::string appDataRate[] = {"2.0Mbps"};
@@ -102,7 +111,7 @@ main (int argc, char *argv[])
102111
// ============================ topo -> network ============================
103112

104113
// loading from topo file --> gene topo(linking the nodes)
105-
std::string topoInput = P4GlobalVar::PathConfig::NfDir + "test_simple/topo.txt";
114+
std::string topoInput = P4GlobalVar::PathConfig::NfDir + "custom_header/topo.txt";
106115
std::string topoFormat ("P2PTopo");
107116

108117
P4TopologyReaderHelper p4TopoHelp;
@@ -129,8 +138,10 @@ main (int argc, char *argv[])
129138
// CsmaHelper csma;
130139
// csma.SetChannelAttribute ("DataRate", StringValue ("10Mbps")); //@todo
131140
// csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (0.01)));
132-
PointToPointHelper p2p;
133-
p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
141+
// PointToPointHelper p2p;
142+
// p2p.SetDeviceAttribute ("DataRate", StringValue ("10Mbps"));
143+
P4PointToPointHelper p4p2phelper;
144+
p4p2phelper.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (0.01)));
134145

135146
// ============================ init network link info ============================
136147
P4TopologyReader::ConstLinksIterator_t iter;
@@ -143,11 +154,11 @@ main (int argc, char *argv[])
143154
// Here the dataRate is in point-to-point-net-device, not in channel
144155
// if (iter->GetAttributeFailSafe ("DataRate", dataRate))
145156
// p2p.SetChannelAttribute ("DataRate", StringValue (dataRate));
146-
if (iter->GetAttributeFailSafe ("Delay", delay))
147-
p2p.SetChannelAttribute ("Delay", StringValue (delay));
157+
// if (iter->GetAttributeFailSafe ("Delay", delay))
158+
// p4p2phelper.SetChannelAttribute ("Delay", StringValue (delay));
148159

149160
NetDeviceContainer link =
150-
p2p.Install (NodeContainer (iter->GetFromNode (), iter->GetToNode ()));
161+
p4p2phelper.Install (NodeContainer (iter->GetFromNode (), iter->GetToNode ()));
151162
fromIndex = iter->GetFromIndex ();
152163
toIndex = iter->GetToIndex ();
153164
if (iter->GetFromType () == 's' && iter->GetToType () == 's')
@@ -279,22 +290,50 @@ main (int argc, char *argv[])
279290
NS_LOG_INFO ("Node " << i << ": IP = " << ipHex << ", MAC = " << macHex);
280291
}
281292

293+
// ============================ add custom header for the p4 switch ============================
294+
295+
CustomHeader myTunnelHeader;
296+
myTunnelHeader.SetLayer (HeaderLayer::LAYER_3); // Network Layer
297+
myTunnelHeader.SetOperator (ADD_BEFORE); // add before the ipv4 header
298+
299+
myTunnelHeader.SetField ("proto_id", 0x0800); // Example: IPv4 protocol
300+
myTunnelHeader.SetField ("dst_id", 0x1); // Example: Destination ID
301+
302+
// Set for the NetDevice
303+
for (unsigned int i = 0; i < hostNum; i++)
304+
{
305+
Ptr<NetDevice> device = hostNodes[i].hostDevice.Get (0);
306+
if (device->GetObject<CustomP2PNetDevice> ())
307+
{
308+
NS_LOG_DEBUG (
309+
"Host " << i << " NetDevice is CustomP2PNetDevice, Setting for the Tunnel Header!");
310+
Ptr<CustomP2PNetDevice> customDevice = DynamicCast<CustomP2PNetDevice> (device);
311+
customDevice->SetWithCustomHeader (true);
312+
customDevice->SetCustomHeader (myTunnelHeader);
313+
}
314+
}
315+
316+
// ============================ add application to the hosts ============================
317+
282318
// Bridge or P4 switch configuration
283319
if (P4GlobalVar::g_nsType == P4Simulator)
284320
{
285321
NS_LOG_INFO ("*** P4Simulator mode");
322+
286323
P4GlobalVar::g_populateFlowTableWay = NS3PIFOTM; //LOCAL_CALL RUNTIME_CLI NS3PIFOTM
287324
P4GlobalVar::g_networkFunc = P4ModuleType::BASIC;
288325
P4GlobalVar::SetP4MatchTypeJsonPath ();
326+
P4GlobalVar::g_p4JsonPath =
327+
P4GlobalVar::PathConfig::NfDir + "custom_header/custom_header.json";
289328

290329
P4Helper p4Bridge;
291330
for (unsigned int i = 0; i < switchNum; i++)
292331
{
293-
P4GlobalVar::g_flowTablePath = P4GlobalVar::PathConfig::NfDir + "test_simple/flowtable_" +
294-
std::to_string (i) + ".txt";
332+
P4GlobalVar::g_flowTablePath = P4GlobalVar::PathConfig::NfDir +
333+
"custom_header/flowtable_" + std::to_string (i) + ".txt";
295334
P4GlobalVar::g_viewFlowTablePath = P4GlobalVar::g_flowTablePath;
296335
NS_LOG_INFO ("*** Installing P4 bridge [ "
297-
<< i << " ]device with configuration: " << std::endl
336+
<< i << " ] device with configuration: " << std::endl
298337
<< "P4JsonPath = " << P4GlobalVar::g_p4JsonPath << ", " << std::endl
299338
<< "FlowTablePath = " << P4GlobalVar::g_flowTablePath << ", " << std::endl
300339
<< "ViewFlowTablePath = " << P4GlobalVar::g_viewFlowTablePath);
@@ -314,7 +353,7 @@ main (int argc, char *argv[])
314353
// == First == send link h0 -----> h1
315354
unsigned int serverI = 1;
316355
unsigned int clientI = 0;
317-
uint16_t servPort = 9093; // setting for port
356+
uint16_t servPort = 12000; // setting for port
318357

319358
Ptr<Node> node = terminals.Get (serverI);
320359
Ptr<Ipv4> ipv4_adder = node->GetObject<Ipv4> ();
@@ -333,14 +372,14 @@ main (int argc, char *argv[])
333372
onOff1.SetAttribute ("DataRate", StringValue (appDataRate[0]));
334373
onOff1.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
335374
onOff1.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
336-
onOff1.SetAttribute ("MaxBytes", UintegerValue (2000));
375+
onOff1.SetAttribute ("MaxBytes", UintegerValue (1000));
337376

338377
ApplicationContainer app1 = onOff1.Install (terminals.Get (clientI));
339378
app1.Start (Seconds (client_start_time));
340379
app1.Stop (Seconds (client_stop_time));
341380

342381
// Enable pcap tracing
343-
p2p.EnablePcapAll ("p4-basic-test-p2p");
382+
p4p2phelper.EnablePcapAll ("p4-basic-test-p2p");
344383

345384
// Run simulation
346385
NS_LOG_INFO ("Running simulation...");

helper/global.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ class P4GlobalVar : public Object
6363
static std::string g_flowTablePath;
6464
static std::string g_viewFlowTablePath;
6565
static std::string g_p4JsonPath;
66-
static constexpr uint64_t g_p4Protocol = 0x12; // 改成 uint16_t 并使用 constexpr
66+
static constexpr uint64_t g_p4Protocol = 0x12;
6767

6868
// Here if dst_port of the udp/tcp header in [g_portRangeMin, g_portRangeMax],
6969
// the packet will add the custom header.

model/bridge-p4-net-device.cc

Lines changed: 111 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -150,69 +150,84 @@ BridgeP4NetDevice::ReceiveFromDevice (Ptr<NetDevice> incomingPort, Ptr<const Pac
150150
Ptr<ns3::Packet> ns3Packet ((ns3::Packet *) PeekPointer (packet));
151151

152152
// check if ethernet packet
153+
// EthernetHeader eeh_1;
154+
// if (ns3Packet->PeekHeader (eeh_1))
155+
// {
156+
// NS_LOG_DEBUG ("Ethernet packet");
157+
// // log the ethernet header information
158+
// Mac48Address src_mac = eeh_1.GetSource ();
159+
// Mac48Address dst_mac = eeh_1.GetDestination ();
160+
// uint16_t protocol_eth = eeh_1.GetLengthType ();
161+
// NS_LOG_DEBUG ("* Ethernet header: Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
162+
// << ", Protocol: " << protocol_eth);
163+
// }
164+
165+
// // check if ipv4 packet
166+
// Ipv4Header ip_hd;
167+
// if (ns3Packet->PeekHeader (ip_hd))
168+
// {
169+
// NS_LOG_DEBUG ("IPv4 packet");
170+
// // log the ipv4 header information
171+
// Ipv4Address src_ip = ip_hd.GetSource ();
172+
// Ipv4Address dst_ip = ip_hd.GetDestination ();
173+
// uint8_t protocol_ip = ip_hd.GetProtocol ();
174+
// uint8_t ttl_ip = ip_hd.GetTtl ();
175+
// uint16_t id_ip = ip_hd.GetIdentification ();
176+
// uint16_t len_ip = ip_hd.GetPayloadSize ();
177+
// uint16_t frag_ip = ip_hd.GetFragmentOffset ();
178+
// NS_LOG_DEBUG ("** Ipv4 header: Source IP: "
179+
// << src_ip << ", Destination IP: " << dst_ip
180+
// << ", Protocol: " << static_cast<uint32_t> (protocol_ip)
181+
// << ", TTL: " << static_cast<uint32_t> (ttl_ip) << ", ID: " << id_ip
182+
// << ", Length: " << len_ip << ", Fragment Offset: " << frag_ip);
183+
// // std::cout << "** Ipv4 header: Source IP: " << src_ip << ", Destination IP: " << dst_ip
184+
// // << ", Protocol: " << static_cast<uint32_t> (protocol_ip)
185+
// // << ", TTL: " << static_cast<uint32_t> (ttl_ip) << ", ID: " << id_ip
186+
// // << ", Length: " << len_ip << ", Fragment Offset: " << frag_ip << std::endl;
187+
// }
188+
189+
// // check if arp packet
190+
// ArpHeader arp_hd;
191+
// if (ns3Packet->PeekHeader (arp_hd))
192+
// {
193+
// NS_LOG_DEBUG ("ARP packet");
194+
// // log the arp header information
195+
// Address src_mac = arp_hd.GetSourceHardwareAddress ();
196+
// Address dst_mac = arp_hd.GetDestinationHardwareAddress ();
197+
// Ipv4Address src_ip = arp_hd.GetSourceIpv4Address ();
198+
// Ipv4Address dst_ip = arp_hd.GetDestinationIpv4Address ();
199+
// NS_LOG_DEBUG ("** Arp header: Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
200+
// << ", Source IP: " << src_ip
201+
// << ", Destination IP: " << dst_ip);
202+
// // std::cout << "** Arp header: Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
203+
// // << ", Source IP: " << src_ip << ", Destination IP: " << dst_ip << std::endl;
204+
// }
205+
206+
std::cout << "ns3::BridgeP4NetDevice::ReceiveFromDevice" << std::endl;
207+
ns3Packet->Print (std::cout);
208+
std::cout << " " << std::endl;
209+
210+
// Add ethernet header for the packet, this is because the csma-net-device for each port will remove the
211+
// ethernet header, so we add another ethernet header, avoid modifications to existing mods.
153212
EthernetHeader eeh_1;
154213
if (ns3Packet->PeekHeader (eeh_1))
155214
{
156215
NS_LOG_DEBUG ("Ethernet packet");
157-
// log the ethernet header information
158-
Mac48Address src_mac = eeh_1.GetSource ();
159-
Mac48Address dst_mac = eeh_1.GetDestination ();
160-
uint16_t protocol_eth = eeh_1.GetLengthType ();
161-
NS_LOG_DEBUG ("* Ethernet header: Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
162-
<< ", Protocol: " << protocol_eth);
163-
}
164-
165-
// check if ipv4 packet
166-
Ipv4Header ip_hd;
167-
if (ns3Packet->PeekHeader (ip_hd))
168-
{
169-
NS_LOG_DEBUG ("IPv4 packet");
170-
// log the ipv4 header information
171-
Ipv4Address src_ip = ip_hd.GetSource ();
172-
Ipv4Address dst_ip = ip_hd.GetDestination ();
173-
uint8_t protocol_ip = ip_hd.GetProtocol ();
174-
uint8_t ttl_ip = ip_hd.GetTtl ();
175-
uint16_t id_ip = ip_hd.GetIdentification ();
176-
uint16_t len_ip = ip_hd.GetPayloadSize ();
177-
uint16_t frag_ip = ip_hd.GetFragmentOffset ();
178-
NS_LOG_DEBUG ("** Ipv4 header: Source IP: "
179-
<< src_ip << ", Destination IP: " << dst_ip
180-
<< ", Protocol: " << static_cast<uint32_t> (protocol_ip)
181-
<< ", TTL: " << static_cast<uint32_t> (ttl_ip) << ", ID: " << id_ip
182-
<< ", Length: " << len_ip << ", Fragment Offset: " << frag_ip);
183-
// std::cout << "** Ipv4 header: Source IP: " << src_ip << ", Destination IP: " << dst_ip
184-
// << ", Protocol: " << static_cast<uint32_t> (protocol_ip)
185-
// << ", TTL: " << static_cast<uint32_t> (ttl_ip) << ", ID: " << id_ip
186-
// << ", Length: " << len_ip << ", Fragment Offset: " << frag_ip << std::endl;
216+
ns3Packet->RemoveHeader (eeh_1);
187217
}
188-
189-
// check if arp packet
190-
ArpHeader arp_hd;
191-
if (ns3Packet->PeekHeader (arp_hd))
192-
{
193-
NS_LOG_DEBUG ("ARP packet");
194-
// log the arp header information
195-
Address src_mac = arp_hd.GetSourceHardwareAddress ();
196-
Address dst_mac = arp_hd.GetDestinationHardwareAddress ();
197-
Ipv4Address src_ip = arp_hd.GetSourceIpv4Address ();
198-
Ipv4Address dst_ip = arp_hd.GetDestinationIpv4Address ();
199-
NS_LOG_DEBUG ("** Arp header: Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
200-
<< ", Source IP: " << src_ip
201-
<< ", Destination IP: " << dst_ip);
202-
// std::cout << "** Arp header: Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
203-
// << ", Source IP: " << src_ip << ", Destination IP: " << dst_ip << std::endl;
204-
}
205-
206-
// Add ethernet header for the packet, this is because the csma-net-device for each port will remove the
207-
// ethernet header, so we add another ethernet header, avoid modifications to existing mods.
208218
eeh_1.SetDestination (dst48);
209219
eeh_1.SetSource (src48);
210-
eeh_1.SetLengthType (protocol);
220+
// eeh_1.SetLengthType (protocol); // Keep the protocol number
211221
std::cout << "* Modified Ethernet header: Source MAC: " << eeh_1.GetSource ()
212222
<< ", Destination MAC: " << eeh_1.GetDestination ()
213223
<< ", Protocol: " << eeh_1.GetLengthType () << std::endl;
214224
ns3Packet->AddHeader (eeh_1);
215225

226+
std::cout << "ns3::BridgeP4NetDevice::ReceiveFromDevice After changing header with MAC address"
227+
<< std::endl;
228+
ns3Packet->Print (std::cout);
229+
std::cout << " " << std::endl;
230+
216231
m_p4Switch->ReceivePacket (ns3Packet, inPort, protocol, dst);
217232
}
218233

@@ -435,6 +450,10 @@ BridgeP4NetDevice::SendNs3Packet (Ptr<Packet> packetOut, int outPort, uint16_t p
435450
NS_LOG_DEBUG ("Sending ns3 packet to port " << outPort);
436451
if (packetOut)
437452
{
453+
std::cout << "Bridge send out with packet lenghttttttth " << packetOut->GetSize ()
454+
<< std::endl;
455+
packetOut->Print (std::cout);
456+
std::cout << " " << std::endl;
438457

439458
EthernetHeader eeh_1;
440459
if (packetOut->PeekHeader (eeh_1))
@@ -444,48 +463,52 @@ BridgeP4NetDevice::SendNs3Packet (Ptr<Packet> packetOut, int outPort, uint16_t p
444463
Mac48Address src_mac = eeh_1.GetSource ();
445464
Mac48Address dst_mac = eeh_1.GetDestination ();
446465
uint16_t protocol_eth = eeh_1.GetLengthType ();
466+
protocol = protocol_eth;
447467
NS_LOG_DEBUG ("Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
448468
<< ", Protocol: " << protocol_eth);
449-
// std::cout << "<= Ethernet header: Source MAC: " << src_mac
450-
// << ", Destination MAC: " << dst_mac << ", Protocol: " << protocol_eth
451-
// << std::endl;
469+
std::cout << "SEND:: <= Ethernet header: Source MAC: " << src_mac
470+
<< ", Destination MAC: " << dst_mac << ", Protocol: " << protocol_eth
471+
<< std::endl;
452472
}
453473

454474
EthernetHeader eeh;
455-
packetOut->RemoveHeader (eeh);
456-
457-
Ipv4Header ip_hd;
458-
if (packetOut->PeekHeader (ip_hd))
459-
{
460-
NS_LOG_DEBUG ("IPv4 packet");
461-
// log the ipv4 header information
462-
Ipv4Address src_ip = ip_hd.GetSource ();
463-
Ipv4Address dst_ip = ip_hd.GetDestination ();
464-
uint8_t protocol_ip = ip_hd.GetProtocol ();
465-
uint8_t ttl_ip = ip_hd.GetTtl ();
466-
uint16_t id_ip = ip_hd.GetIdentification ();
467-
uint16_t len_ip = ip_hd.GetPayloadSize ();
468-
uint16_t frag_ip = ip_hd.GetFragmentOffset ();
469-
NS_LOG_DEBUG ("Source IP: " << src_ip << ", Destination IP: " << dst_ip
470-
<< ", Protocol: " << static_cast<uint32_t> (protocol_ip)
471-
<< ", TTL: " << static_cast<uint32_t> (ttl_ip)
472-
<< ", ID: " << id_ip << ", Length: " << len_ip
473-
<< ", Fragment Offset: " << frag_ip);
474-
}
475-
476-
ArpHeader arp_hd;
477-
if (packetOut->PeekHeader (arp_hd))
478-
{
479-
NS_LOG_DEBUG ("ARP packet");
480-
// log the arp header information
481-
Address src_mac = arp_hd.GetSourceHardwareAddress ();
482-
Address dst_mac = arp_hd.GetDestinationHardwareAddress ();
483-
Ipv4Address src_ip = arp_hd.GetSourceIpv4Address ();
484-
Ipv4Address dst_ip = arp_hd.GetDestinationIpv4Address ();
485-
NS_LOG_DEBUG ("Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
486-
<< ", Source IP: " << src_ip
487-
<< ", Destination IP: " << dst_ip);
488-
}
475+
packetOut->RemoveHeader (eeh); // keep the ethernet header
476+
477+
// packetOut->Print (std::cout);
478+
// std::cout << " " << std::endl;
479+
480+
// Ipv4Header ip_hd;
481+
// if (packetOut->PeekHeader (ip_hd))
482+
// {
483+
// NS_LOG_DEBUG ("IPv4 packet");
484+
// // log the ipv4 header information
485+
// Ipv4Address src_ip = ip_hd.GetSource ();
486+
// Ipv4Address dst_ip = ip_hd.GetDestination ();
487+
// uint8_t protocol_ip = ip_hd.GetProtocol ();
488+
// uint8_t ttl_ip = ip_hd.GetTtl ();
489+
// uint16_t id_ip = ip_hd.GetIdentification ();
490+
// uint16_t len_ip = ip_hd.GetPayloadSize ();
491+
// uint16_t frag_ip = ip_hd.GetFragmentOffset ();
492+
// NS_LOG_DEBUG ("Source IP: " << src_ip << ", Destination IP: " << dst_ip
493+
// << ", Protocol: " << static_cast<uint32_t> (protocol_ip)
494+
// << ", TTL: " << static_cast<uint32_t> (ttl_ip)
495+
// << ", ID: " << id_ip << ", Length: " << len_ip
496+
// << ", Fragment Offset: " << frag_ip);
497+
// }
498+
499+
// ArpHeader arp_hd;
500+
// if (packetOut->PeekHeader (arp_hd))
501+
// {
502+
// NS_LOG_DEBUG ("ARP packet");
503+
// // log the arp header information
504+
// Address src_mac = arp_hd.GetSourceHardwareAddress ();
505+
// Address dst_mac = arp_hd.GetDestinationHardwareAddress ();
506+
// Ipv4Address src_ip = arp_hd.GetSourceIpv4Address ();
507+
// Ipv4Address dst_ip = arp_hd.GetDestinationIpv4Address ();
508+
// NS_LOG_DEBUG ("Source MAC: " << src_mac << ", Destination MAC: " << dst_mac
509+
// << ", Source IP: " << src_ip
510+
// << ", Destination IP: " << dst_ip);
511+
// }
489512

490513
if (outPort != 511)
491514
{

0 commit comments

Comments
 (0)