Ngsdn-Tutorial-Ⅳ

练习4-修改代码以启用IPv6路由

说明:本教程翻译自Next-Gen SDN TutorialExercise 4 - Modify code to enable IPv6 routing,自用学习Docker-P4-ONOS

在本练习中,系统将要求您将更改应用于P4代码以及ONOS应用,以为不同子网中的主机启用IPv6路由。

实际上,我们的结构控制平面(即ONOS应用程序)假定给定子网的主机都连接到相同的叶子,并且两个不同叶子的两个接口不能配置相同的IPv6子网。换句话说,仅对连接到同一叶的主机允许L2桥接。为了能够ping通连接到不同叶子的不同主机,我们需要在数据平面中支持IPv6路由。

本教程中使用的Mininet脚本topo.py定义了4个子网:

  • 2001:1:1::/64用3台主机连接到leaf1h1ah1b,和h1c
  • 2001:1:2::/641台主机连接到leaf1h2
  • 2001:2:3::/641台主机连接到leaf2h3
  • 2001:2:4::/641台主机连接到leaf2h4
topo.png

相同的IPv6前缀在netcfg.json文件中定义,并用于向交换机接口提供IPv6地址,即从主机角度来看的网关地址。我们的ONOS应用程序的目标是对交换机进行编程,使其表现得像传统的IPv6路由器。

不幸的是,我们提供给您的入门代码对IPv6路由的实现有误。您的任务是修复它。

为什么路由不起作用?

要找出原因,请使用Mininet CLI(make mn-cli)。ONOS和Mininet应该从上一个练习开始运行。如果不是这种情况,请返回练习3的步骤2。

让我们从ping通同一子网中的两个主机开始,例如h1ah1b

mininet> h1a ping h1b
PING 2001:1:1::b(2001:1:1::b) 56 data bytes
64 bytes from 2001:1:1::b: icmp_seq=1 ttl=64 time=1068 ms
64 bytes from 2001:1:1::b: icmp_seq=2 ttl=64 time=5.38 ms
64 bytes from 2001:1:1::b: icmp_seq=3 ttl=64 time=1.75 ms
...

对同一子网中的主机执行Ping操作。让我们尝试ping通不同子网中的主机,例如h2(IPv6地址为2001:1:2::1/64,位于2001:1:2::网络)和h1a2001:1:1::a/64,位于2001:1:1::网络):

mininet> h2 ping h1a
PING 2001:1:1::a(2001:1:1::a) 56 data bytes
From 2001:1:2::1 icmp_seq=1 Destination unreachable: Address unreachable
From 2001:1:2::1 icmp_seq=2 Destination unreachable: Address unreachable
From 2001:1:2::1 icmp_seq=3 Destination unreachable: Address unreachable
...

Ping不起作用。要找出原因并调试问题,让我们暂时让ping运行。

检查流规则和组

首先要做的是检查leaf1(两个主机都连接在哪里)具有所有必需的流规则和组,以在h2h1a之间路由数据包。我们应该在中看到相关条目routing_v6_table

打开ONOS CLI(make onos-cli)并转储以下条目routing_v6_table

onos> flows -s any device:leaf1 | grep routing_v6_table

验证是否存在以下条目:

ADDED, bytes=0, packets=0, table=IngressPipeImpl.routing_v6_table, priority=10, selector=[hdr.ipv6.dst_addr=0x2001000100010000000000000000000a/128], treatment=[immediate=[GROUP:0x1a]]
...
ADDED, bytes=0, packets=0, table=IngressPipeImpl.routing_v6_table, priority=10, selector=[hdr.ipv6.dst_addr=0x20010001000200000000000000000001/128], treatment=[immediate=[GROUP:0x20]]

需要使用这些条目来路由具有目标IPv6地址h2(第一个条目)和h1a(第二个条目之一)的数据包。两个条目都有字节和数据包计数器,其值为0,这是可疑的,因为routing_v6_tableP4程序中将其定义为具有计数器,并且ONOS定期读取这些计数器。似乎没有数据包与这些条目匹配。可能是什么问题呢?

在h2的接口上dump数据包

虽然之间的中国平安h2h1a运行,让我们用tcpdump来dump发送和接收的所有数据包h2

在新的终端窗口上,键入以下命令:

util/mn-cmd h2 tcpdump -i h2-eth0 -n

mn-cmd实用程序可用于在Mininet主机的网络名称空间内运行任意命令。在这里,我们使用它在h2上启动tcpdump,指定将数据包转储出接口h2-eth0h2中的唯一接口)。-n用于避免在数据包地址上进行DNS查找。

屏幕上应该显示路由不起作用的原因。

...
21:05:13.653869 IP6 2001:1:2::1 > ff02::1:ff00:ff: ICMP6, neighbor solicitation, who has 2001:1:2::ff, length 32
21:05:14.678054 IP6 2001:1:2::1 > ff02::1:ff00:ff: ICMP6, neighbor solicitation, who has 2001:1:2::ff, length 32
21:05:15.701769 IP6 2001:1:2::1 > ff02::1:ff00:ff: ICMP6, neighbor solicitation, who has 2001:1:2::ff, length 32
...

2001:1:2::ffh2中配置的IPv6网关。为了对h1a进行ping操作,在这种情况下,h2需要将数据包发送到其网关2001:1:2::ff,但它无法获得相应网关的MAC地址。

如果你看一下netcfg.json文件,你会发现,2001:1:2::ff关联到leaf16端口的IPv6地址。

之前我们说过,我们的结构应该像传统的IPv6路由器一样工作,因此它应该能够回复连接的主机发送的邻居请求(NS)数据包,并生成带有交换机MAC地址(myStationMac)的邻居广告(NA) 。不幸的是,对于交换机接口IPv6地址的NDP处理的实现是不完整的。您将需要修改P4程序以及ONOS应用才能使其正常运行。

为交换机接口IPv6地址实现NDP处理

我们已经提供了处理由连接到同一子网的主机交换的NDP NS和NA的方法(请参阅参考资料l2_ternary_table)。对于主机,Linux网络堆栈负责生成NDP NA答复。但是对于我们架构中的交换机,实在没有能用的Linux网络堆栈。

有多种解决此问题的方法:

  • 我们可以为主机配置静态NDP条目,而无需交换机回复NDP NS数据包;
  • 我们可以通过输入包拦截NDP NS,在ONOS中生成相应的NDP NA答复,然后通过输出包将其发送回去。还可以
  • 我们可以指示交换机使用P4生成NDP NA答复。也就是说,我们可以编写P4代码来处理对NDP请求的答复,而无需控制平面的任何干预。

我们选择实现最后一个选项,以显示一个有趣的P4用例。

这个想法很简单,NDP NA数据包具有与NDP NS数据包相同的标头结构。它们都是具有不同报头字段值的ICMPv6数据包,例如不同的ICMPv6类型,不同的以太网地址等。知道NDP NS请求中找到的给定IPv6目标地址的MAC地址的交换机可以将同一数据包转换为NDP NA通过修改其某些字段来回复。

练习步骤

在下面,您将被要求:

  1. 修改P4程序以启用交换机内NDP NA生成;
  2. 运行PTF测试,以确保您的更改能够按预期进行,并避免出现退化;
  3. 修改ONOS应用程序以控制P4程序的NDP生成功能;
  4. 在Mininet上测试连接性。

1.修改P4程序

p4src/main.p4的入口管道实现中,我们已经提供了一个名为ndp_ns_to_na的将NDP NS数据包转换为NDP NA数据包的动作。您的任务是实现使用此类操作的表。

该表应定义netcfg.json中提供接口的IPv6地址和myStationMac与每个交换机关联的接口IPv6地址(也在netcfg.json中定义)之间的映射。当收到一个NDP NS数据包,要求解析此类IPv6地址之一时,ndp_ns_to_na应使用给定的myStationMac作为参数调用该操作。ONOS应用程序将负责根据netcfg.json的内容在此表中插入条目。

  1. 开放p4src/main.p4;
  2. 寻找入口管道(control IngressPipeImpl)的实现;
  3. 在要求的地方修改代码(查找TODO EXERCISE 4);
  4. 使用该make p4-build命令编译修改后的P4程序。在继续操作之前,请确保解决所有编译器错误。

2.运行PTF测试

在继续之前,让我们通过运行一些PTF测试来确保P4更改能够按预期进行。我们提供了一个用于NDP生成的测试用例,以及其他一些基本功能(例如,包输入/输出,桥接,路由等)的测试用例。运行PTF测试将为您的更改按预期工作提供一定的保证,而不会破坏其他部分。
在运行测试之前,您需要对测试用例实现进行一些简单的更改。

打开文件ptf/tests/ndp.py并在需要的地方进行修改(查找TODO EXERCISE 4)。该测试文件仅定义一个执行以下操作的测试用例:

  1. 在刚创建的表中插入一个条目;
  2. 向交换机发送NDP NS报文;
  3. 验证交换机是否发回正确填充的NDP NA。

您将需要通过填写刚刚创建的表的名称来修改测试用例。

要仅运行NDP测试用例:

make p4-test TEST=ndp

为确保新更改不会破坏其他功能,应使用以下命令运行所有测试:

make p4-test

如果所有测试成功,那么恭喜!您可以转到下一步。除此以外...

如何调试失败的测试?

运行PTF测试时,会产生多个文件,可用于发现错误:

  • ptf/bmv2.log:具有跟踪级别的BMv2日志(显示匹配的表以及每个数据包的其他信息)
  • ptf/ptf.pcap:包含测试期间发送和接收的所有数据包的PCAP文件(您可能需要安装Wireshark以便更直观地查看)
  • ptf/ptf.log:所有包操作(发送和接收)的PTF日志

3.修改ONOS应用

应用程序启动程序代码已经提供了一个组件,该组件负责控制P4程序中的NDP生成功能。该组件通过侦听设备事件来工作。当ONOS连接到新交换机时,它将查看网络配置(netcfg.json)以获取所有接口IPv6地址myStationMac,然后使用,该信息填充您刚刚创建的表。

在使用此组件之前,您需要进行一些修改才能使其与P4程序一起使用。例如,您需要提供刚创建的P4表的名称。

  1. 打开文件:app/src/main/java/org/onosproject/ngsdn/tutorial/NdpReplyComponent.java

  2. 根据需要修改(查找TODO EXERCISE 4

  3. 使用命令构建ONOS应用(包括pipeconf)make app-build

4.生成并重新加载应用

在ONOS运行时,使用以下命令重新加载您的应用程序:

$ make app-reload

第一次后重新加载应用

在构建应用程序时,修改后的P4编译器输出(bmv2.jsonp4info.txt)将与Java类一起打包在一起。如果同一应用程序的另一个实例正在运行,该命令make app-reload将首先停用正在运行的实例并加载新实例。

要将更改应用于应用实现,请随意使用任意make app-build app-reload多次。该应用程序已包含在每次重新加载时从ONOS清除任何表条目和其他转发状态的逻辑。

验证ONOS日志

重新加载应用程序后,您应该看到消息,表明已设置了新的管道配置并NdpReplyComponent已将其激活:

INFO  [PiPipeconfManager] Unregistered pipeconf: org.onosproject.ngsdn-tutorial (fingerprint=...)
INFO  [PipeconfLoader] Found 1 outdated drivers for pipeconf 'org.onosproject.ngsdn-tutorial', removing...
INFO  [PiPipeconfManager] New pipeconf registered: org.onosproject.ngsdn-tutorial (fingerprint=...)
INFO  [PipelineConfigClientImpl] Setting pipeline config for device:leaf1 to org.onosproject.ngsdn-tutorial...
...
INFO  [MainComponent] Waiting to remove flows and groups from previous execution of org.onosproject.ngsdn-tutorial..
...
INFO  [MainComponent] Started
INFO  [NdpReplyComponent] Started
...
INFO  [NdpReplyComponent] *** NDP REPLY - Starting Initial set up for device:leaf1...
INFO  [NdpReplyComponent] Adding rules to device:leaf1 to generate NDP NA for 4 IPv6 interfaces...
INFO  [NdpReplyComponent] *** NDP REPLY - Starting Initial set up for device:spine1...
INFO  [NdpReplyComponent] device:spine1 does not have any IPv6 interface configured
INFO  [NdpReplyComponent] *** NDP REPLY - Starting Initial set up for device:spine2...
INFO  [NdpReplyComponent] device:spine2 does not have any IPv6 interface configured
INFO  [NdpReplyComponent] *** NDP REPLY - Starting Initial set up for device:leaf2...
INFO  [NdpReplyComponent] Adding rules to device:leaf2 to generate NDP NA for 2 IPv6 interfaces...
...

了解ONOS错误日志

在Mininet中尝试解决方案之前,值得查看一下ONOS日志中可能的错误。重新加载应用程序时可能会看到两种主要类型的错误:

  1. 写入错误,例如删除不存在的实体或插入已经存在的实体:

    WARN  [WriteResponseImpl] Unable to DELETE PRE entry on device...: NOT_FOUND Multicast group does not exist ...
    WARN  [WriteResponseImpl] Unable to INSERT table entry on device...: ALREADY_EXIST Match entry exists, use MODIFY if you wish to change action ...
    

    这些通常是暂时性错误,您不必担心它们。它们描述了ONOS内部设备状态的暂时不一致,应通过定期对帐机制尽快恢复这种状态。ONOS核心会定期轮询设备状态,以确保其内部表示准确无误,同时将任何未决的修改写入设备,以解决这些错误。

    否则,如果您看到它们定期出现(每3-4秒一次),则表示对帐过程不起作用,并且其他地方出了问题。尝试重新加载应用程序(make app-reload);如果仍不能解决警告,请与教员联系。

  2. 转换错误,表示ONOS无法将应用程序生成的流规则(或组)转换为与P4Info兼容的表示形式。例如:

    WARN  [P4RuntimeFlowRuleProgrammable] Unable to translate flow rule for pipeconf 'org.onosproject.ngsdn-tutorial':...
    

    请仔细阅读错误消息并根据需要对应用进行更改。可能是您使用的表,匹配字段或操作名称不存在于P4Info中。检查您的P4Info文件,修改并重新加载应用程序(make app-build app-reload)。

5.在Mininet上测试IPv6路由

验证ping

如果您在运行h2h1a之间留下了ping命令,请检查该终端窗口是否可以正常工作!

为了验证ping也适用于连接到不同叶子的主机,让我们依次使用以下命令在h2h3之间开始新的ping:

mininet> h2 ping h3
mininet> h3 ping h2
PING 2001:1:2::1(2001:1:2::1) 56 data bytes
64 bytes from 2001:1:2::1: icmp_seq=2 ttl=61 time=2.39 ms
64 bytes from 2001:1:2::1: icmp_seq=3 ttl=61 time=2.29 ms
64 bytes from 2001:1:2::1: icmp_seq=4 ttl=61 time=2.71 ms
...

h3h2之间执行ping操作有效。

注意:我们需要先从h2开始ping,然后再从h3开始ping,以便ONOS在转发ping数据包之前发现两个主机的位置。这是因为当前的实现要求主机生成ONDP会发现的NDP NS数据包。为了避免必须手动生成NDP NS消息,可能的解决方案是:

  • 在Mininet中配置IPv6主机,以定期自动生成另一种NDP消息,称为路由器请求(RS)。

  • 在ACL表中插入流规则,将NDP RS数据包克隆到CPU。这将需要匹配NDP NA和NS以外的ICMPv6代码的其他值。

  • 修改hostprovider内置的应用程序实现,以从NDP RS消息中了解主机位置(当前仅使用NDP NA和NS)。

验证基于P4的NDP NA生成

要验证交换机基于P4的NDP NA生成是否正常工作,可以检查h2或的邻居表h3,它应该显示类似以下内容:

mininet> h2 ip -6 n
2001:2:3::ff dev h2-eth0 lladdr 00:aa:00:00:00:02 router REACHABLE

2001:2:3::ff在规定的IPv6网关地址netcfg.jsontopo.py,和00:aa:00:00:00:02myStationMac用于定义leaf2netcfg.json

6.使用ONOS Web UI可视化ECMP

为了验证ECMP是否正常工作,让我们开始从h2h3使用iperf的多个并行流量。在Mininet命令提示符下,键入:

mininet> h2 iperf -c h3 -u -V -P5 -b1M -t600 -i1

此命令将在h2上启动一个iperf客户端,通过IPv6(-V)将UDP数据包(-u)发送到h3(-c)。为此,我们生成5个不同的流(-P5),每个流的上限为1Mbit/s(-b1M),运行10分钟(-t600),并每1秒报告一次统计信息(-i1)。

由于我们正在生成UDP流量,因此无需在上启动iperf服务器h3

要可视化流量,请从教程VM(例如Firefox)中打开浏览器到http://127.0.0.1:8181/onos/ui。询问时,请使用用户名onos和密码rocks。在显示ONOS拓扑视图的同一页面上:

  • H键盘上的显示主机;
  • 按下L以显示设备标签;
  • 多次按A,直到看到端口/链接统计信息,以包/秒(pps)或位/秒为单位。

ECMP应该能按预期工作,因此您应该看到流量转发到两个通道,如下面的屏幕截图所示:

routing-ecmp.png

恭喜你!

您已经完成了这个练习!现在,您的结构可以在任何主机之间转发IPv6流量。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,826评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,968评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,234评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,562评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,611评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,482评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,271评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,166评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,608评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,814评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,926评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,644评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,249评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,866评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,991评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,063评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,871评论 2 354