一、概述

二层交换机的主要功能就是在端口之间搬移分组,当然是要根据正确的目标地址来搬移,涉及到以太网帧格式的解析、源和目的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;
elsepkt->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. 二层交换机原型设计与实现(二)

    一.概述 FAST架构的UA编程非常简单,有其固定的套路,核心部分两块,一是在main函数中把环境初始化好,注册UA的回调函数和配置硬件默认规则:二是在回调函数中专心处理分组数据,实现完整业务功能. ...

  2. 二层交换机原型设计与实现(一)

    一.概述 交换机是我们网络领域应用最为广泛的网络互联设备,其主要功能是完成各端口之间分组的交换功能.交换机仅做分组交换,不对分组进行任何数据修改.交换机的端口没有IP与MAC的属性.端口数据IO一般为 ...

  3. 构建之法--原型设计(第三次作业)

    这个作业属于哪个课程 https://edu.cnblogs.com/campus/xnsy/2019autumnsystemanalysisanddesign 这个作业要求 https://www. ...

  4. 原型设计(第三次作业)

    这个作业属于哪个课程 <课程的链接> 这个作业要求在哪里 <作业要求的链接> 这个作业的目标 熟悉各项原型工具,使用一种工具进行原型设计 培养原型设计思维,为之后的团队项目提前 ...

  5. 原型设计应当掌握的四个设计思维:初始、常态、边界、错误

    原型设计应当掌握的四个设计思维包括:初始.常态.边界.错误.这四种方法,产品经理在设计中可能有的人都经常在这样做,但是少有人总结提炼出简单八个字所深谙的设计思路. 初始 初始,简单理解就是,你要展示给 ...

  6. 四行代码定乾坤:硬件二层交换机设计与实现

    一.概述 "我OpenBox又回来了!" 沉寂了16个月,终于又提笔开始写<硬件二层交换设计与实现>.从软件设计到硬件设计需要这么长时间吗?答案是肯定的,不仅需要,而且 ...

  7. 《AlwaysRun团队》第三次作业:团队项目的原型设计

    <AlwaysRun团队>第三次作业:团队项目的原型设计 项目 内容 这个作业属于哪个课程 [任课教师博客主页链接](https://home.cnblogs.com/u/nwnu-dai ...

  8. 软工实践第三次作业-原型设计

    写在最最前面 界面我自己看的挺顺眼的,就当他美观吧哈哈哈哈(尴尬) 写在前面 本次作业 结对成员:031602441 张子纯,031602408 何守成 队友博客:队友博客 原型设计工具:墨刀 原型: ...

  9. 第三次作业-介绍一款原型设计工具

    课程:软件工程综合实践专题  学号:1759214 介绍一款原型设计工具:Mockplus http://www.mockplus.cn 如今是一个快节奏的社会,每一天都会有无数的软件发布,每一款软件 ...

最新文章

  1. 【机器学习】基于自适应变异粒子群算法的非线性函数寻优
  2. 无线网络未来十年十大产业趋势
  3. 说说大型高并发高负载网站的系统架构(更新)
  4. 关于iOS的社会化分享方案总结
  5. 主成分分析法_“主成分分析法”——线上讨论会等你加入
  6. SkinMagic使用后按钮加自定义图标或菜单GetMneu返回NULL的解决方法
  7. GitLab 自动触发 Jenkins 构建
  8. python自然语言处理评论_python自然语言处理——学习笔记:Chapter3纠错
  9. postgres 错误duplicate key value violates unique constraint 解决方案
  10. html5中的一些标签学习总结
  11. 操作系统中的处理机调度调度_操作系统中的流程分类和调度
  12. Centos7安装完成找不到 ifconfig 网路设置命令
  13. 内存管理 kmalloc
  14. Redis主从,哨兵架构简单搭建
  15. ubuntu使用双模机械师K7机械键盘遇到的问题
  16. android 6g 有必要吗,Android手机6GB内存有必要吗?实测出真知
  17. Error:Module “./antd/es/badge/style“ does not exist in container. while loading “./antd/es/badge/sty
  18. 科创板、香港主板、纳斯达克三地部门上市条件和要求
  19. 【秋招面经】金山前端题目总结
  20. Xshell连接虚拟机失败,解决办法!

热门文章

  1. 求解:3090使用pcie3.0 x8与x16性能
  2. js 的 forEach()函数
  3. 认知决定着架构师能力的上线——架构认知的三个层次
  4. ProBuilder操作一览表
  5. centos7 双机设备实现
  6. SpringBoot使用通配符加载配置文件
  7. mysql between详解_MySQL中BETWEEN子句的用法实例详解
  8. 前端Js实现模糊查询
  9. 程序员不得不知道的技术面试资料大全
  10. Charm安装、使用