HiHuo
首页
博客
手册
工具
关于
首页
博客
手册
工具
关于
  • 网络架构师学习手册

    • 网络架构师学习教程
    • 基础篇

      • 第1章 网络模型与数据流转
      • 第2章 以太网与二层通信
      • 第3章 IP路由与三层转发
      • 第4章 TCP与可靠传输
      • 第5章 应用层协议
    • Linux网络栈

      • 第6章 数据包接收路径
      • 第7章 多核网络优化
      • 第8章 Netfilter与防火墙
      • 第9章 流量控制与QoS
    • 虚拟网络

      • 第10章 Network Namespace基础
      • 第11章 Bridge与互联
      • 第12章 VXLAN与Overlay网络
      • 第13章 OVS与SDN
    • Kubernetes网络

      • 第14章 CNI模型与实现
      • 第15章 kube-proxy与Service实现
      • 第16章 CoreDNS与服务发现
      • 第17章 NetworkPolicy与安全隔离
      • 第18章 Calico网络深度解析
      • 第19章 Cilium与eBPF网络
    • 网络架构

      • 第20章 网络设备与拓扑设计
      • 第21章 网络容量规划与计算
      • 第22章 负载均衡架构设计
      • 第23章 高可用网络架构
      • 第24章 网络安全架构
    • 性能调优

      • 第25章 系统级网络调优
      • 第26章 故障排查方法论
      • 第27章 生产环境案例分析
    • 前沿技术

      • 第28章 eBPF深度实践
      • 第29章 ServiceMesh与边车代理
      • 第30章 网络技术趋势与未来展望
    • 附录

      • 附录A:命令速查手册
      • 附录B:排错决策树
      • 附录C:学习资源
      • 附录D:技能图谱

第2章 以太网与二层通信

学习目标

  • 理解以太网帧结构和MAC地址机制
  • 掌握ARP协议的工作原理
  • 了解VLAN和生成树协议
  • 能够配置和排查二层网络问题

🔬 原理

以太网帧结构

标准以太网帧格式:

[目的MAC(6)] [源MAC(6)] [类型(2)] [数据(46-1500)] [CRC(4)]

字段详解:

  • 目的MAC:6字节,目标设备的物理地址
  • 源MAC:6字节,发送设备的物理地址
  • 类型:2字节,上层协议类型(0x0800=IP,0x0806=ARP)
  • 数据:46-1500字节,有效载荷
  • CRC:4字节,循环冗余校验

最小/最大帧长度:

  • 最小:64字节(6+6+2+46+4)
  • 最大:1518字节(6+6+2+1500+4)
  • 原因:确保冲突检测机制正常工作

MAC地址机制

MAC地址格式:

格式:XX:XX:XX:XX:XX:XX(十六进制)
示例:00:1B:44:11:3A:B7

地址类型:

  • 单播:第一个字节最低位为0
  • 多播:第一个字节最低位为1
  • 广播:全1地址(FF:FF:FF:FF:FF:FF)

地址分配:

  • 前3字节:OUI(组织唯一标识符)
  • 后3字节:厂商分配

ARP协议

ARP(Address Resolution Protocol):IP地址到MAC地址的映射

工作过程:

  1. ARP请求:广播"谁是192.168.1.1?告诉我你的MAC"
  2. ARP应答:单播"我是192.168.1.1,MAC是xx:xx:xx"
  3. 缓存更新:将映射关系存入ARP表

ARP表结构:

IP地址        MAC地址            接口
192.168.1.1   00:1b:44:11:3a:b7  eth0
192.168.1.2   00:1b:44:11:3a:b8  eth0

VLAN技术

VLAN(Virtual LAN):虚拟局域网,通过Tag隔离二层广播域

VLAN Tag格式:

[目的MAC(6)] [源MAC(6)] [VLAN Tag(4)] [类型(2)] [数据] [CRC(4)]

VLAN Tag字段:

  • TPID:2字节,固定值0x8100
  • PCP:3位,优先级
  • DEI:1位,丢弃指示
  • VID:12位,VLAN ID(1-4094)

VLAN类型:

  • Access端口:只属于一个VLAN
  • Trunk端口:属于多个VLAN,带Tag传输

生成树协议(STP)

STP目的:防止二层环路,确保网络拓扑无环

工作原理:

  1. 选举根桥(最小BID)
  2. 每个非根桥选择根端口
  3. 每个网段选择指定端口
  4. 阻塞其他端口

️ 实现

Linux Bridge实现

Bridge数据结构:

struct net_bridge {
    struct list_head port_list;    // 端口列表
    struct hlist_head hash[BR_HASH_SIZE]; // FDB哈希表
    struct net_device *dev;        // Bridge设备
    // ... 更多字段
};

struct net_bridge_port {
    struct net_bridge *br;         // 所属Bridge
    struct net_device *dev;        // 端口设备
    struct hlist_head hash[BR_HASH_SIZE]; // 端口FDB
    // ... 更多字段
};

FDB(Forwarding Database):

  • 学习MAC地址与端口的映射
  • 基于源MAC学习
  • 基于目标MAC转发

ARP实现

ARP表管理:

struct neigh_table arp_tbl = {
    .family = AF_INET,
    .key_len = 4,           // IP地址长度
    .hash = arp_hash,
    .constructor = arp_constructor,
    .pconstructor = arp_constructor,
    .pdestructor = arp_destructor,
    .proxy_redo = parp_redo,
    .id = "arp_cache",
    .parms = {
        .tbl = &arp_tbl,
        .reachable_time = 30 * HZ,
        .data = {
            [NEIGH_VAR_MCAST_PROBE] = 3,
            [NEIGH_VAR_UCAST_PROBE] = 3,
            [NEIGH_VAR_APP_PROBES] = 0,
            [NEIGH_VAR_RETRANS_TIME] = 1 * HZ,
            [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ,
            [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
            [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
            [NEIGH_VAR_QUEUE_LEN] = 3,
            [NEIGH_VAR_QUEUE_LEN_BYTES] = 64 * 1024,
            [NEIGH_VAR_PROXY_QLEN] = 64,
            [NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ,
            [NEIGH_VAR_PROXY_DELAY] = (8 * HZ) / 10,
            [NEIGH_VAR_LOCKTIME] = 1 * HZ,
        },
    },
    .gc_interval = 30 * HZ,
    .gc_thresh1 = 128,
    .gc_thresh2 = 512,
    .gc_thresh3 = 1024,
};

🛠️ 命令

基础二层命令

# 查看ARP表
ip neigh show

# 查看Bridge信息
bridge link

# 查看FDB
bridge fdb show

# 传统ARP命令
arp -an

VLAN配置

# 创建VLAN接口
sudo ip link add link eth0 name eth0.10 type vlan id 10

# 配置VLAN IP
sudo ip addr add 10.0.10.1/24 dev eth0.10

# 启动VLAN接口
sudo ip link set eth0.10 up

# 查看VLAN配置
ip -d link show eth0.10

Bridge配置

# 创建Bridge
sudo ip link add name br0 type bridge

# 启动Bridge
sudo ip link set br0 up

# 添加端口到Bridge
sudo ip link set eth1 master br0

# 配置Bridge IP
sudo ip addr add 192.168.1.1/24 dev br0

# 查看Bridge状态
bridge link show

代码

ARP学习程序

// arp_learning.c
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <netpacket/packet.h>
#include <net/ethernet.h>
#include <net/if.h>

struct arp_hdr {
    unsigned short ar_hrd;    // 硬件类型
    unsigned short ar_pro;    // 协议类型
    unsigned char  ar_hln;    // 硬件地址长度
    unsigned char  ar_pln;    // 协议地址长度
    unsigned short ar_op;     // 操作码
    unsigned char  ar_sha[6]; // 发送方硬件地址
    unsigned char  ar_sip[4]; // 发送方IP地址
    unsigned char  ar_tha[6]; // 目标硬件地址
    unsigned char  ar_tip[4]; // 目标IP地址
};

int main() {
    int sock = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ARP));
    if (sock < 0) {
        perror("socket");
        return 1;
    }
    
    char buffer[1024];
    while (1) {
        int len = recv(sock, buffer, sizeof(buffer), 0);
        if (len < 0) {
            perror("recv");
            continue;
        }
        
        struct arp_hdr *arp = (struct arp_hdr*)(buffer + 14);
        
        if (ntohs(arp->ar_op) == 1) { // ARP请求
            printf("ARP Request: Who has %d.%d.%d.%d? Tell %d.%d.%d.%d\n",
                   arp->ar_tip[0], arp->ar_tip[1], arp->ar_tip[2], arp->ar_tip[3],
                   arp->ar_sip[0], arp->ar_sip[1], arp->ar_sip[2], arp->ar_sip[3]);
        } else if (ntohs(arp->ar_op) == 2) { // ARP应答
            printf("ARP Reply: %d.%d.%d.%d is at %02x:%02x:%02x:%02x:%02x:%02x\n",
                   arp->ar_sip[0], arp->ar_sip[1], arp->ar_sip[2], arp->ar_sip[3],
                   arp->ar_sha[0], arp->ar_sha[1], arp->ar_sha[2],
                   arp->ar_sha[3], arp->ar_sha[4], arp->ar_sha[5]);
        }
    }
    
    close(sock);
    return 0;
}

编译运行:

gcc arp_learning.c -o arp_learning
sudo ./arp_learning

🧪 实验

实验1:ARP学习过程观察

目标:理解ARP协议的工作机制

步骤:

# 1. 清空ARP缓存
sudo ip neigh flush all

# 2. 查看ARP表(应该为空或很少)
ip neigh show

# 3. ping一个同网段IP
ping -c 1 192.168.1.1

# 4. 再次查看ARP表
ip neigh show

# 5. 抓包观察ARP过程
sudo tcpdump -i eth0 -nn arp

预期结果:

  • 看到ARP请求和应答
  • 理解广播和单播的区别
  • 观察ARP表的学习过程

实验2:VLAN配置与测试

目标:掌握VLAN的配置和隔离效果

步骤:

# 1. 创建VLAN 10
sudo ip link add link eth0 name eth0.10 type vlan id 10
sudo ip addr add 10.0.10.1/24 dev eth0.10
sudo ip link set eth0.10 up

# 2. 创建VLAN 20
sudo ip link add link eth0 name eth0.20 type vlan id 20
sudo ip addr add 10.0.20.1/24 dev eth0.20
sudo ip link set eth0.20 up

# 3. 查看VLAN配置
ip -d link show eth0.10
ip -d link show eth0.20

# 4. 测试VLAN隔离
ping -I eth0.10 10.0.20.1  # 应该失败
ping -I eth0.10 10.0.10.2  # 如果存在应该成功

预期结果:

  • 理解VLAN的隔离效果
  • 掌握VLAN Tag的作用
  • 学会VLAN配置方法

实验3:Bridge网络构建

目标:构建多容器Bridge网络

步骤:

# 1. 创建Bridge
sudo ip link add br0 type bridge
sudo ip link set br0 up
sudo ip addr add 10.0.0.1/24 dev br0

# 2. 创建3个namespace模拟容器
for i in 1 2 3; do
    sudo ip netns add ns$i
    sudo ip link add veth$i type veth peer name veth${i}-br
    sudo ip link set veth$i netns ns$i
    sudo ip link set veth${i}-br master br0
    sudo ip link set veth${i}-br up
    sudo ip netns exec ns$i ip link set veth$i up
    sudo ip netns exec ns$i ip addr add 10.0.0.1$i/24 dev veth$i
    sudo ip netns exec ns$i ip route add default via 10.0.0.1
done

# 3. 测试容器间通信
sudo ip netns exec ns1 ping -c 2 10.0.0.12
sudo ip netns exec ns1 ping -c 2 10.0.0.13

# 4. 查看Bridge学习的MAC
bridge fdb show br br0

# 5. 抓包观察ARP和ICMP
sudo tcpdump -i br0 -n

预期结果:

  • 理解Bridge的MAC学习机制
  • 掌握容器网络基础
  • 观察二层转发过程

实验4:容器访问外网(NAT)

目标:配置NAT让容器访问外网

步骤:

# 1. 开启IP转发
sudo sysctl -w net.ipv4.ip_forward=1

# 2. 添加SNAT规则
sudo iptables -t nat -A POSTROUTING -s 10.0.0.0/24 ! -o br0 -j MASQUERADE

# 3. 测试外网访问
sudo ip netns exec ns1 ping -c 2 8.8.8.8

# 4. 查看NAT规则
sudo iptables -t nat -vnL

预期结果:

  • 理解NAT的工作原理
  • 掌握容器外网访问配置
  • 学会iptables NAT规则

排错

常见问题排查

问题1:ARP表学习异常

# 检查ARP表
ip neigh show

# 手动添加ARP条目
sudo ip neigh add 192.168.1.100 lladdr 00:11:22:33:44:55 dev eth0

# 删除ARP条目
sudo ip neigh del 192.168.1.100 dev eth0

# 检查ARP统计
cat /proc/net/arp

问题2:VLAN配置问题

# 检查VLAN支持
cat /proc/net/vlan/config

# 检查VLAN接口状态
ip -d link show eth0.10

# 检查VLAN Tag
tcpdump -i eth0 -nn vlan

问题3:Bridge转发异常

# 检查Bridge状态
bridge link show

# 检查FDB
bridge fdb show

# 检查Bridge统计
cat /proc/net/bridge/bridge-nf-call-iptables

排错清单

  • [ ] 检查物理连接(网线、网卡状态)
  • [ ] 验证MAC地址配置(唯一性、格式)
  • [ ] 确认ARP表学习(超时、刷新)
  • [ ] 检查VLAN配置(ID、Tag、端口)
  • [ ] 验证Bridge状态(端口、FDB)
  • [ ] 测试二层连通性(ping、arping)
  • [ ] 查看系统日志(dmesg、/var/log/syslog)
Prev
第1章 网络模型与数据流转
Next
第3章 IP路由与三层转发