二层交换机原型设计与实现(三)

一、概述

二层交换机的主要功能就是在端口之间搬移分组,当然是要根据正确的目标地址来搬移,涉及到以太网帧格式的解析、源和目的MAC地址的提取,MAC表的设计、查找和老化等等一系列的系统功能实现。我们开始设计交换机并不考虑那么多,从简单入手,轻装上阵,你也许会走得更好。

二、基于端口号的交换与验证

上一篇文章我们学会了打印分组的基本信息和将分组发送到指定端口输出。今天我们就可以来实现一个简单的交换功能,完成两台主机之间的正常通信了。

1)端口交换

顾名思义,就是只识别判断端口号就将分组进行交换转发,先实现一个基于端口的交换功能。固定逻辑只能实现固定的两个端口交换,我们可以将要交换的两个端口从程序启动时作为参数输入,这样就可以在启动命令时按需要指定要交换的两个端口参数了。

增加两个端口变量的全局定义,并在main函数的参数输入中获取输入的值,如:

/*端口交换要使用的两个全局端口号变量*/
int port1 = 0,port2 = 0;
/*main函数中添加如下代码*/
else if(argc == 5)
{
  debug = atoi(argv[1]);
  mid = atoi(argv[2]);  
  port1 = atoi(argv[3]);  
  port2 = atoi(argv[4]);
}
/*callback函数中添加如下代码*/
if(pkt->um.inport == port1)
  pkt->um.outport = port2;
else
  pkt->um.outport = port1;

2)验证

编译代码并执行生成文件命令,观察打印消息。

root@HNXS:/home/hnxs/l2switch# make
gcc -o ul2switch main_ul2switch.c -lua -lreg -lpthread
root@HNXS:/home/hnxs/l2switch# ./ul2switch 1 130 0 2
fastU->REG Version:20180827,OpenBox HW Version:2020210329
fastU->Register UA to FAST Kernel! Wait Reply......
fastU->UA->pid:2132,mid:130,Register OK!
fastU->libua version:20180827
fastU->fast_ua_recv......
inport:2,dstmid:130,len:92,dmac:FF:FF:FF:FF:FF:FF,smac:B8:27:EB:C1:D1:39
pkt_send_normal->0xb5500470,outport:0,len:92
inport:0,dstmid:130,len:92,dmac:B8:27:EB:C1:D1:39,smac:B8:27:EB:D8:83:20
pkt_send_normal->0xb5500470,outport:2,len:92
inport:2,dstmid:130,len:130,dmac:B8:27:EB:D8:83:20,smac:B8:27:EB:C1:D1:39
pkt_send_normal->0xb5500470,outport:0,len:130
inport:2,dstmid:130,len:130,dmac:B8:27:EB:D8:83:20,smac:B8:27:EB:C1:D1:39
pkt_send_normal->0xb5500470,outport:0,len:130

同时,在一个测试主机上ping另一台测试主机的IP,发现已经ping通了。

64 bytes from 192.168.2.117: icmp_seq=10 ttl=64 time=2.02 ms
64 bytes from 192.168.2.117: icmp_seq=11 ttl=64 time=0.742 ms
64 bytes from 192.168.2.117: icmp_seq=12 ttl=64 time=0.597 ms

3)思考

从上述交换打印分析,前两个报文应该是ARP分组,32字节metadata加60字节以太帧数据。第1个是广播请求,第2个是单播应答。第3和第4个报文就是第1组ping的交互数据了,标准ping的98字节(130-32=98)。

先不往大了说,至少我们前面添加了几行代码就实现了我们的一个最基本的原型交换了,如果要换端口测试,只需要在启动命令时更改相应的端口号参数就行了。那交换机端口多了,用户多了之后呢?我们岂不是要不断回来的启动程序和设置端口来保证他们通信呢?这是不是跟解放前的电话接线员工作有点类似?接线员接到电话后,先要询问打电话的人要打给谁,然后再把线给连过去。当然,原来的电话通信与分组交换还是有些较大区别,只是类比一下,不扩展细说。

三、基于MAC地址交换与验证

在分组交换的头部携带有该分组要去往的目的地址,我们管他叫目的MAC地址。在以太网网络中,任意一个通信终端都必须具备一个唯一的MAC地址,用作通信内容标识。在基于端口交换的基础上,我们也可以很容易的实现一个基于MAC地址的简单交换功能。至于为什么选目的MAC作为交换判断参数,大家细想肯定能明白。

1)MAC交换

根据以太网帧格式定义,从分组头部位置提取目的MAC作为判断参数,实现一个基于MAC地址的交换功能。既然要根据目的MAC地址来做转发,我们需要知道哪一个MAC地址的主机连接在交换机的哪一个端口上面,假设我们已经获取了这些信息如下:

主机MAC地址:B8:27:EB:D8:83:20,交换机端口:0
主机MAC地址:B8:27:EB:C1:D1:39,交换机端口:2

替换原来端口交换的逻辑代码,替换代码如下:

/*新增两个MAC的内存格式定义,与S4平台(ARM)相关哦*/
u64 mac1 = 0x2083D8EB27B8,mac2 = 0x39D1C1EB27B8;
/*注释原来端口转发逻辑,添加MAC转发逻辑*/
if(!ether_addr_equal(pkt->data,(u8 *)&mac1))
  pkt->um.outport = 0;
else if(!ether_addr_equal(pkt->data,(u8 *)&mac2))
  pkt->um.outport = 2;

ether_addr_equal函数是判断两个MAC地址是否相等,详情参阅代码。

两个MAC地址的定义准确来说要根据MAC的顺序方式表示后再做网络序转换,为简化逻辑和方便验证,直接定义成了小端平台下反序方式,这样正好跟网络序的MAC地址对比相等。关于平台数据的大小端的问题或主机序与网络序问题,请网上搜索学习。

2)验证

编译代码并执行生成文件命令,观察打印消息。

root@HNXS:/home/hnxs/l2switch# make
gcc -o ul2switch main_ul2switch.c -lua -lreg -lpthread
root@HNXS:/home/hnxs/l2switch# ./ul2switch
fastU->REG Version:20180827,OpenBox HW Version:2020210329
fastU->Register UA to FAST Kernel! Wait Reply......
fastU->UA->pid:2255,mid:129,Register OK!
fastU->libua version:20180827
fastU->fast_ua_recv......
inport:0,dstmid:129,len:92,dmac:FF:FF:FF:FF:FF:FF,smac:B8:27:EB:D8:83:20
pkt_send_normal->0xb5400470,outport:0,len:92
inport:0,dstmid:129,len:92,dmac:FF:FF:FF:FF:FF:FF,smac:B8:27:EB:D8:83:20
pkt_send_normal->0xb5400470,outport:0,len:92
inport:0,dstmid:129,len:92,dmac:FF:FF:FF:FF:FF:FF,smac:B8:27:EB:D8:83:20
pkt_send_normal->0xb5400470,outport:0,len:92

同时,在2端口测试主机上ping另一台测试主机的IP,发现ping不通哦。这是因为我们现在的逻辑没有考虑ARP广播MAC地址的处理逻辑,导致其无法正常转发。本节暂不处理广播的泛洪转发功能,后续文章中与组播一起讨论。

那如何让两边主机不发ARP广播直接发ping的分组呢?了解网络通信原理的人都知道,这个广播是在ping之前发出的MAC地址学习分组,如果没有学习到对端的MAC地址,则ping的分组无法完成二层协议的封装,无法从协议栈发出。使用如下命令分别在两台主机上进行对端IP与对端MAC的静态绑定设置,ping的分组便能正常发出了。

/*192.168.2.115主机执行*/
#arp –s 192.168.2.117 b8:27:eb:d8:83:20
/*192.168.2.117主机执行*/
#arp –s 192.168.2.115 b8:27:eb:c1:d1:39

现在,在任意一台主机上执行ping均能可以看到ping通了。

3)思考

我们现在终于可以根据主机的MAC地址来进行分组交换转发了,但这只是两台主机的固定交换转发,如果机器MAC多了怎么办?如果机器连接交换机的端口变了怎么办?我们需要有一张记录表,能够记录哪个MAC地址在哪个端口就好了,通过每个分组的目的MAC来查找其对应的输出端口,这样就很容易实现分组交换了。

四、总结与下一步

1)交换过程的核心数据字段

从上述实验可以看出,目前交换里面用到的就两个字段,一个是端口号,另一个是MAC地址。那目的MAC地址与输出端口号从哪获得?其实就是从分组头的源MAC地址和输入端口转换变成目的MAC和输出端口。故在交换过程中,其核心数据就2个:端口号和MAC地址。

2)MAC转发表设计与验证

MAC转发表就是我们前面提到的记录表,这张表记录了一个MAC地址与其对应端口号的绑定关系,这一关系要从输入分组数据中提取而来,由分组的输入端口与源MAC地址组成这一绑定关系,在查表中便可通过目的MAC来获取其正确的输出端口了。下一篇文章我们聊一下MAC转发表的设计。

 

欢迎您和学生们加入FAST开源项目群沟通与探讨,一起体验不一样的系统设计过程。请先加微信号15116127200后邀请入群。

图片
关注FAST开源公众号

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值