V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
lolcat
V2EX  ›  Linux

tcp/ip 协议栈中,子网掩码是存哪的?

  •  
  •   lolcat · 2021-07-07 12:40:12 +08:00 · 3412 次点击
    这是一个创建于 1017 天前的主题,其中的信息可能已经有所发展或是发生改变。
    网络数据报文里好像没有保存子网掩码的部分。假设有如下场景:

    路由器,A 口网段:192.168.128.0/24,B 口网段:192.168.128.0/23,如果有人给 192.168.128.0/24 网段的某个机器发了个数据报,路由器怎么知道是转发给 A 口还是 B 口?
    第 1 条附言  ·  2021-07-07 15:41:12 +08:00
    看了下大家的回复,帖子里可能没说明白。

    我的问题是:
    路由器配置静态路由表,把 192.168.128.0/24 的流量全部转发到 A 口,把 192.168.128.0/23 的流量全部转发到 B 口,如果有人给 192.168.128.7 这台主机发送数据,因为数据报中没有关于子网掩码的数据,路由器怎么知道把这个数据包转发到哪个口?

    看了大家回复,
    1. 有人说路由器的静态路由表不允许这么配置。
    2. 有人说根据最长匹配原则,192.168.128.7 这个地址可以匹配 A 口 192.168.128.0/24 这个网段的 24 位,而只能匹配 B 口 192.168.128.0/23 这个网段的 23 位,根据最长匹配规则应该会把这个数据包转发到 A 口。

    到底哪个答案是正确的呢?

    我之前从没配置过路由器,路由器配置界面长啥样的我记得和 linux 的终端差不多,但是谢希仁那本《计算机网络》我感觉我学的真的还算可以的啊,@raaaaaar 15 楼回复,我不记得那本书里哪里介绍了关于此知识的内容啊。 @Tianao 12 楼的回复的后半段我没看懂,请问那些知识是不是思科认证才能接触到的啊?
    34 条回复    2021-07-14 18:32:51 +08:00
    ThirdFlame
        1
    ThirdFlame  
       2021-07-07 12:44:51 +08:00
    路由器是根据路由表转发的。
    路由表 路由条目根据生成方法可以分为 直连路由、静态路由、动态路由
    路由器根据 A 口、B 口配置的 IP 地址 /掩码 自动生成相应的直连路由。
    coolzjy
        2
    coolzjy  
       2021-07-07 12:45:01 +08:00
    报文不需要子网掩码,IP 即唯一标识一个网络节点。子网掩码是用来划分网络的,只需要在网络节点上配置就好了。
    lolcat
        3
    lolcat  
    OP
       2021-07-07 12:50:28 +08:00
    @ThirdFlame 请问在我说的上述场景中,静态路由表已经写好了,192.168.128.0/24 网段的报文就转发给 A 口,192.168.128.0/23 网段的报文就转发给 B 口,那么路由器收到一个目标地址是 192.168.128.7 的报文,他该转发给那个口呢?
    lolcat
        4
    lolcat  
    OP
       2021-07-07 12:50:34 +08:00
    @coolzjy 请问在我说的上述场景中,静态路由表已经写好了,192.168.128.0/24 网段的报文就转发给 A 口,192.168.128.0/23 网段的报文就转发给 B 口,那么路由器收到一个目标地址是 192.168.128.7 的报文,他该转发给那个口呢?
    mmtromsb456
        5
    mmtromsb456  
       2021-07-07 12:59:27 +08:00 via iPhone   ❤️ 4
    路由表遵守最长前缀匹配,所以 A 接口与 B 接口交集部分走 A 接口,剩余部分走 B 接口
    lolcat
        6
    lolcat  
    OP
       2021-07-07 13:30:30 +08:00
    @mmtromsb456 还是没看懂,请问在上述的例子中,A 接口和 B 接口在不同网段,怎么可能有交集呢?如果静态路由表已经写好了,192.168.128.0/24 网段的报文就转发给 A 口,192.168.128.0/23 网段的报文就转发给 B 口,那么路由器收到一个目标地址是 192.168.128.7 的报文,他该转发给那个口呢?
    v2mm
        7
    v2mm  
       2021-07-07 13:31:50 +08:00
    192.168.128.7 取前 24bit == 192.168.128.0 走 A 口

    但是比如 192.168.129.7,则
    192.168.129.7 取前 24bit == 192.168.129.0 不走 A 口
    192.168.129.7 取前 23bit == 192.168.128.0 走 B 口
    qbqbqbqb
        8
    qbqbqbqb  
       2021-07-07 13:43:53 +08:00
    @lolcat 系统不会也无法知道你现实中的网段配置,一切按照路由表和规则来。如果路由表写成这样,按照路由表匹配规则(最长前缀),这个报文必然是走 A 口。如果实际上这台机器在 B 网段,那这个包就丢了。
    Tianao
        9
    Tianao  
       2021-07-07 13:45:07 +08:00 via iPhone
    「路由器,A 口网段:192.168.128.0/24,B 口网段:192.168.128.0/23 」

    路由器的以太网接口等广播型三层接口(还包括但不限于 dot1q 子接口、vlan 虚接口)不允许这么配,会提示网段冲突。

    如果是 loopback 口、地址借用等情况确实配上了,此时适用最长匹配原则。
    qbqbqbqb
        10
    qbqbqbqb  
       2021-07-07 13:56:31 +08:00
    “子网掩码”和“默认网关”你可以理解成一种简化的静态路由表配置,系统根据这两个参数将其展开成完整的静态路由表(即设置“IP/子网掩码”网段走接口直连路由,"0.0.0.0/0"走“默认网关”),是不会出现在具体的报文里的(当然 DHCP 这种除外)。

    比如说 192.168.128.7/24 和 192.168.128.7/23,这就是一个 IP 地址,只能代表一台主机(绝对不能将其理解为两个网段中的两个不同主机,这是一种常见的误解,如果在相互连接的网络中这样配置两台主机的话会导致 IP 冲突),只是说配置前者的话系统会认为它的网段有最多 254 台主机这么大,配置后者的话系统会认为它的网段有最多 510 台主机那么大。
    xiaooloong
        11
    xiaooloong  
       2021-07-07 13:57:52 +08:00
    掩码只做本地演算用,传输的数据中不体现。
    Tianao
        12
    Tianao  
       2021-07-07 14:02:55 +08:00 via iPhone
    @lolcat 看了楼主楼上的回复,看来楼主根本没有这样用过路由器,也不理解网段、网络、子网、超网、网络地址、网络号、主机地址、最长匹配的概念和实际意义,建议楼主先去学习下这些基础知识,再来纠结这些以自己的水平在现实应用场景中根本不可能遇到的场景(最典型的 IP 以太网路由器在简单的局域网环境下不可能(不被允许)这样配置,如果遇到串行、帧中继等非广播型网络、loopback 口做路由通告或身份 ID 等有条件出现这样的配置场景的情况,这个问题自然就不会成为问题了)。

    总而言之,楼主现在的基础知识决定了这样纠结这个问题没有意义,只会成为“思而不学则殆”的典型。
    cpstar
        13
    cpstar  
       2021-07-07 14:26:17 +08:00
    A 口 B 口冲突了吧
    按道理,掩码只负责子网判定,跟 IP 无关,所以按照 LZ 描述,A 口 B 口可以同时设置 192.168.128.5,那显然这是不允许的。
    msaionyc
        14
    msaionyc  
       2021-07-07 14:30:18 +08:00
    @lolcat A 和 B 为什么没交集?
    raaaaaar
        15
    raaaaaar  
       2021-07-07 14:31:34 +08:00
    建议看下《计算机网络》,谢的那本,网络那章,写得很清楚
    dier
        16
    dier  
       2021-07-07 15:24:29 +08:00
    在路由器上如果你先配置了条件中 A 口的网段,B 口的网段就配置不成功,所以你这个问题不存在
    lolcat
        17
    lolcat  
    OP
       2021-07-07 15:43:43 +08:00
    @raaaaaar 谢的那本书我不记得讲了这方面的知识啊
    CRVV
        18
    CRVV  
       2021-07-07 16:45:48 +08:00
    路由表当然可以这么配置
    ip route add 192.168.128.0/24 dev eth0
    ip route add 192.168.128.0/23 dev eth1
    这么配置完,走 eth0

    如果是给 interface 这么设置,Linux 上也可以配置出来,但这是很奇怪的配置,没人这么用。
    网络里面通常认为一个 IP 地址对应唯一一台机器,如果设置成这样
    eth0 192.168.128.1/24
    eth1 192.168.128.2/23
    那么 192.168.128.3 同时属于这两个网络,那么当然会认为这是一台机器而不是两个子网里的两台机器,这个数据包要怎么发给这一台机器是无所谓的事情,总能到。

    子网掩码不是一个网络的属性,也不是一个地址的属性。它本身唯一的作用就是表示一组连续的 IP 地址,然后这一组 IP 地址叫做一个子网。
    比如 ip route add 192.168.1.0/24 via 10.2.3.4 一次设置了 256 个 IP 地址的路由,不用一个一个加路由。
    给 interface 设置的子网掩码是告诉电脑哪些 IP 地址和本机是直连的,这些直连的 IP 可以直接走数据链路层通信( ARP 协议),不用经过路由器。和本机直连的 IP 地址也不一定是连续的,你可以在一个 interface 上设置多个 IP 地址和子网掩码。和设置路由一样,一次设置一组,不用一个一个加,仅些而已。

    这种事情找几台机器,至少要有一台带两个网卡的,连起来玩一下就知道了。
    Tianao
        19
    Tianao  
       2021-07-07 16:57:25 +08:00   ❤️ 4
    回复楼主附言 1
    「看了大家回复,
    1. 有人说路由器的静态路由表不允许这么配置。
    2. 有人说根据最长匹配原则,192.168.128.7 这个地址可以匹配 A 口 192.168.128.0/24 这个网段的 24 位,而只能匹配 B 口 192.168.128.0/23 这个网段的 23 位,根据最长匹配规则应该会把这个数据包转发到 A 口。

    到底哪个答案是正确的呢?」

    首先,192.168.128.0/24 192.168.128.0/23 是两个网络地址而不是主机地址,因此不能配置到普通接口上。如果 A B 两个口都是工作在三层模式的以太网接口,那么路由器不允许配置为两个接口分别配置 192.168.128.1/24 192.168.128.1/23 这样两个地址,在配置好一个之后,再配置另一个时会被拒绝并报错。

    其次,假设两个地址配置成功后,路由器会自动生成去往这两个网络的直连路由。

    然后,现代路由器路由器在实际执行路由转发时的直接参照是 FIB (转发信息表)而不是路由表(路由表不一定包含物理出接口,也没有下一跳的目的 MAC 地址),而 FIB 是根据全局路由表(有时候被称为系统路由表或者优选路由表)及其他表项生成的。

    再然后,全局路由表是通过参照各协议路由表经路由优选后得出的。路由优选的一个原则是路由协议的管理距离优,比如,直连路由的管理距离优于手工静态路由,也就是说对于去往同一目的网络(即网络地址和掩码均完全相同)的路由,直连路由永远会在优选中胜出(除非手动干预路由协议的管理距离),也就是说,在楼主假想的这种情况下,手工配置的静态路由永远不会「成为活跃路由生效而参与 FIB 的构建进而影响最终路由选路和转发执行」。

    最后,路由器在针对特定目的主机地址( 192.168.128.7 )在存储 FIB 的 TCAM (三元内容可寻址寄存器)中执行硬件查表时,才会用到并遵循最长匹配原则,此时路由器为目的主机地址 192.168.128.7 匹配到了具有最长匹配位数的 192.168.128.0/24 表项,并从此直连路由出接口送出。全程和静态路由没有半毛钱关系。

    而且,以上的前提是,这两个重叠的接口地址可以被配置上去并生效。
    Tianao
        20
    Tianao  
       2021-07-07 17:09:22 +08:00
    再明确回复一下楼主附言 1 的「 1. 有人说路由器的静态路由表不允许这么配置。」

    不是静态路由不允许这么配,是接口地址不允许这么配。静态路由可以这么配,但是配了也不会生效(成为在优选中胜出的活跃路由并被显示在全局路由表)。
    www5070504
        21
    www5070504  
       2021-07-07 17:27:13 +08:00
    楼上牛鼻
    rrfeng
        22
    rrfeng  
       2021-07-07 17:35:03 +08:00 via Android
    报文只有地址
    报文转发节点才需要掩码

    这牛角尖钻的清新脱俗。。。。
    idealhs
        23
    idealhs  
       2021-07-07 17:59:40 +08:00
    牛逼的,楼上学习了,回去复习下计算机网络
    CRVV
        24
    CRVV  
       2021-07-07 18:03:11 +08:00
    @Tianao

    你要不要自己找台 Linux 试试,不报错

    ip addr add 192.168.1.1/24 dev eth0
    ip addr add 192.168.1.1/24 dev eth1
    libook
        25
    libook  
       2021-07-07 18:03:55 +08:00
    如果路由器两个口可以设置重合的网段,是不是我也可以设置一模一样的网段,比如 A 口和 B 口都设置 192.168.128.0/23,那么这样的话,即便数据包会携带子网掩码路由器也是一样无法判断究竟应该转发给谁。

    子网掩码一般都是设备自己知道,用于推算网络基本情况的,这个要么是走 DHCP,要么是静态配置,而不是在每个数据包发送过程中夹带的。

    而路由器自己维护路由表,所以有自主权决定数据包怎么转发(而不是终端来告诉路由器应该发给 A 口还是 B 口,这样就变成了终端在越殂代疱了),通常的情况是路由器同时接入两个不重合的网段,根据发送者的 IP 和接收者的 IP 来看落在哪个 IP 段里,就走转发到哪个线路。所以如果两个网段是重合的,那么就得看路由器是什么策略,这个如果没有统一的标准的话就可能是不同路由器、不同配置会有不同结果。
    Tianao
        26
    Tianao  
       2021-07-07 18:10:29 +08:00 via iPhone
    @CRVV #24 Linux 缺省情况下不能在 eth0 和 eth1 之间路由 IP 分组,不符合我上述的限制条件。
    Nerv
        27
    Nerv  
       2021-07-07 23:38:54 +08:00 via Android
    楼主的问题:
    **数据报没有关于子网掩码的数据**

    回答:单个 ip 地址子网掩码是 255.255.255.255 ,也就是 /32 。
    Nerv
        28
    Nerv  
       2021-07-07 23:50:18 +08:00 via Android
    @libook
    同一个路由器的两个端口无法配置相同的网段。
    https://networkengineering.stackexchange.com/a/33165
    xuanbg
        29
    xuanbg  
       2021-07-08 08:16:03 +08:00
    首先,你的网络设置就有问题。A 口网段:192.168.128.0/24,B 口网段:192.168.128.0/23,路由器允许这样配置吗?如果允许,那么对于 192.168.128.0/24 的地址,一定是往 A 口转发的。因为这样符合最小匹配原则。
    libook
        30
    libook  
       2021-07-08 10:35:22 +08:00
    @Nerv #28 这个就是我想说明的,我举了个例子来证伪路由器同时接入两个重合 IP 段的情况。
    但拒绝设置重合网段这是个“加法”功能,厂商不做的话就不会有这种机制,所以我留了个口子,保不齐有厂商没做这个判断,然后用户确实可以配置两个重合的网段,那么就看具体什么算法,有可能始终走物理顺序第一的口,也可能因为路由表顺序的优化走最后走过的口,也可能发生了缓冲区错误停止运行。
    qbqbqbqb
        31
    qbqbqbqb  
       2021-07-14 17:51:42 +08:00
    @Tianao 但是楼主提到的两个网络掩码分别是 24 和 23,不属于“去往同一目的网络(即网络地址和掩码均完全相同)的路由”,因而如果没有其它冲突的话两者都会被选为活动路由写入全局路由表,最终还是走最长匹配原则。
    qbqbqbqb
        32
    qbqbqbqb  
       2021-07-14 18:12:40 +08:00
    @Nerv 电脑可以。例如双网卡同时接入一个 LAN 中,两个接口通过 DHCP 获取同一网段的两个不同地址。这种配置完全合法,不会导致网络故障。而且对于 NAS 用户使用 SMB3 多通道传输几乎必须这么配置。
    Tianao
        33
    Tianao  
       2021-07-14 18:24:16 +08:00 via iPhone
    @qbqbqbqb #31 我说的“去往同一目的网络(即网络地址和掩码均完全相同)的路由”是在路由优选部分,同样是 /24 的直连路由会把同样是 /24 的手工静态路由 override 掉,最终被选为活动路由写入全局路由表的是 /23 /24 两条直连路由(和手工配置的静态路由的目的网络是一致的,但是不是手工静态路由哦,因为同样前缀的 /23 和 /24 的两条静态路由在路由优选中都败给了同样前缀的直连路由);最长匹配是发生在 FIB 查表时的,和路由优选是先后顺序关系(不冲突),“最终还是走最长匹配原则”这种说法很奇怪,因为最终肯定要在 FIB 查表时按前缀长度降序匹配,最后肯定都是遵循最长匹配原则的(不是说有了路由优选就不看最长匹配了,最长匹配是在路由优选之后、在路由优选的结果——全局路由表、FIB 的基础上)。先理解现代 IP 路由交换架构哦。
    Nerv
        34
    Nerv  
       2021-07-14 18:32:51 +08:00
    @qbqbqbqb 你都说了不是路由器,和同网段矛盾的是转发工作。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   5198 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 51ms · UTC 08:04 · PVG 16:04 · LAX 01:04 · JFK 04:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.