可参考程序examples/p4-topo-test.cc
主要包括ns4文件路径信息,运行时参数设置信息,初始化下发流表API接口等
P4GlobalVar::g_homePath="/home/kphf1995cm/";
P4GlobalVar::g_ns3RootName = "ns-allinone-3.26/";
P4GlobalVar::g_ns3SrcName = "ns-3.26/";
P4GlobalVar::g_nfDir = P4GlobalVar::g_homePath + P4GlobalVar::g_ns3RootName + P4GlobalVar::g_ns3SrcName + "src/ns4/test/";
P4GlobalVar::g_topoDir = P4GlobalVar::g_homePath + P4GlobalVar::g_ns3RootName + P4GlobalVar::g_ns3SrcName + "src/ns4/topo/";
P4GlobalVar::g_nsType = NS4;
P4GlobalVar::g_runtimeCliTime=10;
SwitchApi::InitApiMap();
P4GlobalVar::InitNfStrUintMap();
这里可以继承P4TopologyReader,实现其中的Read函数,自定义其它的topo格式
我们这里使用的是已编写的CsmaTopologyReader
std::string topoFormat("CsmaTopo");
std::string topoPath = P4GlobalVar::g_topoDir + "csmaTopo.txt";
便于在运行时调节参数
CommandLine cmd;
cmd.AddValue("format", "Format to use for data input [Orbis|Inet|Rocketfuel|CsmaTopo].",
topoFormat);
cmd.AddValue("model", "Select p4 model[0] or traditional bridge model[1]", P4GlobalVar::g_nsType);
cmd.AddValue("podnum", "Numbers of built tree topo levels", podNum);
cmd.AddValue("build","Build flow table entries by program[1] or not[0]",toBuild);
cmd.AddValue("application","Application type OnoffSink[0] UdpClientServer[1]",application);
cmd.Parse(argc, argv);
这里可编写程序构建需要的网络拓扑或者直接省略手动定义网络拓扑
我们这边采用已编写的fattree拓扑构建程序
构建好的网络拓扑会保存在topo目录下
FattreeTopoHelper treeTopo(podNum,topoPath);
treeTopo.Write();
P4TopologyReaderHelper p4TopoHelp;
p4TopoHelp.SetFileName(topoInput);
p4TopoHelp.SetFileType(topoFormat);
Ptr<P4TopologyReader> topoReader = p4TopoHelp.GetTopologyReader();
if (topoReader != 0)
{
topoReader->Read();
}
if (topoReader->LinksSize() == 0)
{
NS_LOG_ERROR("Problems reading the topology file. Failing.");
return -1;
}
这里是根据所读取的网络拓扑来初始化网络链路信息
这里是通过程序自动构建每个交换机所需要的流表项,主要是使得数据包能够从源主机到达目的主机
所构建的流表项保存在flowtable目录中
也可以手动编写每个交换机所需要的流表项
if(toBuild==1&&P4GlobalVar::g_nsType==NS4)
{
NS_LOG_LOGIC("BuildFlowtableHelper");
//BuildFlowtableHelper flowtableHelper("fattree",podNum);
BuildFlowtableHelper flowtableHelper;
flowtableHelper.Build(linkSwitchIndex,linkSwitchPort,hostIpv4,switchPortInfo);
flowtableHelper.Write(P4GlobalVar::g_flowTableDir);
flowtableHelper.Show();
}
这里会构建P4交换机,并将P4交换机的每个端口与一个网络设备相连
在构建P4交换机同时,会提前下发该交换机的流表项
新创建的P4交换机会被添加到P4控制器中,以便于管理
if (P4GlobalVar::g_nsType == NS4)
{
P4GlobalVar::g_populateFlowTableWay = LOCAL_CALL;
std::string flowTableName;
P4Helper bridge;
for (unsigned int i = 0; i < switchNum; i++)
{
flowTableName = UintToString(i);
//P4GlobalVar::g_networkFunc = SIMPLE_ROUTER;
P4GlobalVar::g_networkFunc = P4GlobalVar::g_nfStrUintMap[switchNetFunc[i]];
P4GlobalVar::SetP4MatchTypeJsonPath();
P4GlobalVar::g_flowTablePath = P4GlobalVar::g_flowTableDir + flowTableName;
bridge.Install(csmaSwitch.Get(i),switchNodes[i].switchDevices);// do what?
}
}
这里可给主机或交换机安装一些应用程序,例如OnoffSink或UdpEchoClient等,也可实现自定义的应用
设置启动、关闭应用程序的时间
这里的模拟过程是基于ns3的离散事件处理的