当前位置: 首页 > news >正文

LWIP协议栈实现ARP协议

1) 核心数据结构与状态机(对应图片:etharp_entry 与 etharp_q_entry)

  • 代码:struct etharp_entry
    • 字段说明:
      • q:挂载的等待发送的 pbuf(或队列,取决于 ARP_QUEUEING)
      • ipaddr / ethaddr / netif:映射关系与所属接口
      • ctime:条目年龄(以秒计;由 etharp_tmr 每秒自增)
      • state:ETHARP_STATE_(EMPTY、PENDING、STABLE、REREQUESTING_、STATIC)
  • 行为:
    • PENDING:已发送 ARP 请求,等待应答。可以挂载 1 个或多个待发包(取决 ARP_QUEUEING)。
    • STABLE:已解析到 MAC,可直接发送;ctime 达到 ARP_MAXAGE 则过期。
      在这里插入图片描述在这里插入图片描述
      上图是arp_entry结构体和etharp_q_entry结构体。
      在这里插入图片描述
      下图是每个arp结构的state状态机。在这里插入图片描述

2) 条目查找与回收策略(对应代码:etharp_find_entry)

  • 功能:一次扫描实现查找/选择回收项/创建新项的逻辑(提高效率,避免多遍扫描)。
  • 回收优先级(若无空槽并且允许回收 ETHARP_FLAG_TRY_HARD):
    1. 最久的 stable(不含 static)
    2. 最久的 pending(无队列)
    3. 最久的 pending(有队列)
  • 图片提示: ARP_QUEUEING 宏和默认值(通常关闭),说明队列功能默认不开启以节省内存与复杂度。
  • 修改建议:若设备需要短时间内缓存多个待发包(例如启动爆发流量),开启 ARP_QUEUEING 并适当设置 ARP_QUEUE_LEN;但要增加 MEMP_ARP_QUEUE 池。

在这里插入图片描述

3) 更新缓存(对应代码:etharp_update_arp_entry,etharp_input)

  • etharp_input 收到 ARP 包(request/reply)时:
    • 先通过 etharp_update_arp_entry 更新/插入缓存(若为请求且目标为本机,会触发 reply)。
    • 对于 reply:只是更新条目(并会把挂起队列的数据发出)。
  • 若条目由 PENDING -> STABLE:会弹出队列,调用 ethernet_output 发送并 pbuf_free。
  • 图片(Wireshark trace)说明:当内核重试 TCP 但 ARP 未解析时会出现大量重传;抓包显示 ARP 请求/应答后 TCP 连接恢复,说明 ARP 解析是许多上层超时/重传的根源。
  • 在这里插入图片描述

4) 发包路径与决策(对应代码:etharp_output / etharp_query / etharp_output_to_arp_index)

  • 发送单播 IP 包:

    • 先检查广播/多播,直接选择目标 MAC。
    • 否则在 ARP 表查找稳定条目(快速 path);若找到,直接 etharp_output_to_arp_index -> ethernet_output。
    • 若没找到,调用 etharp_query:创建/标记 pending、发送 ARP request,并把 pbuf 挂到表项(或复制/引用,见下)。
  • 关于 pbuf 挂载策略(关键点):

    • 如果 q 的 pbuf 类型会被上层修改(PBUF_NEEDS_COPY),则必须复制为 PBUF_RAM(pbuf_clone),保证队列中的数据不被上层改写。
    • 默认行为(无队列)会只保存一份 pbuf(覆盖旧的)。
  • 在这里插入图片描述

5) 请求/重发/老化策略(对应代码常量与 etharp_tmr)

  • ARP_MAXPENDING(默认 5 秒)控制 pending 条目失效时间。若未收到回复,ethtarp_tmr 会在到期后释放条目。
  • ARP_MAXAGE(默认通常 5 分钟),在接近过期时会做 re-request:
    • ARP_AGE_REREQUEST_USED_UNICAST = ARP_MAXAGE - 30(15/30s 的差异用于广播/单播策略,见源码)
  • etharp_tmr 实现:每秒自增 ctime,达到阈值会 etharp_request(对于 pending)或 etharp_free_entry(过期)。
    在这里插入图片描述

在这里插入图片描述

6) ARP 请求构造与发送(etharp_request / etharp_raw)

  • etharp_raw 负责构造 ARP 报文(填 arp header、sender/target 地址)并调用 ethernet_output 发送(PBUF_LINK + PBUF_RAM)。
  • 如果使用 AUTOIP(link-local),对特殊源 IP 必须用广播发送(RFC 要求)。
  • 图片(ARP 帧格式图)对照:头部字段顺序、各字段长度(hw type、proto type、hwlen、protolen、opcode、sender hw/ip、target hw/ip)。
    在这里插入图片描述

7) queue 与内存(ARP 队列与 pbuf 类型)

  • 如果挂载队列,必须考虑内存池(MEMP_ARP_QUEUE)与 pbuf 池(PBUF_RAM 当需要复制时)。
  • PBUF_NEEDS_COPY 宏会检测 pbuf 类型是否安全入队(PBUF_REF/PBUF_ROM 等不可直接入队)。
  • 若内存不足(无法为队列分配 memp 或无法复制 pbuf),会丢弃并返回 ERR_MEM,并统计 ETHARP memerr(见代码调用 ETHARP_STATS_INC)。

8) 性能与问题排查建议

  • 常见问题:ARP 导致上层 TCP 超时/重传(见 Wireshark),最终原因往往是:
    • ARP 请求未发出(驱动问题 / ethernet_output 未调用)
    • ARP 请求发送但未到达对端(VLAN/交换机/子网配置错误)
    • 驱动或 DMA 未把 RX 帧传递给 lwIP(ethernetif_input 未上送 pbuf)
    • ARP 表条目被过快回收(ARP_MAXAGE 设置过小)
  • 排查清单:
    • 抓包看是否存在 ARP 请求/应答(Wireshark)。若有应答但内核仍在重传,说明内核未把应答更新到表(检查 etharp_input 是否被调用及 netif 关联)。
    • 开启 LWIP_DEBUG/ETHARP_DEBUG 与统计(etharp.xmit / eth arp.recv / eth arp.memerr)观察。
    • 检查 MEMP_ARP_QUEUE 与 PBUF_POOL 是否不足(pbuf_alloc 失败会导致丢包)。
  • 优化建议:
    • 在高并发或 burst 场景启用 ARP_QUEUEING 与合理 ARP_QUEUE_LEN,并增大 MEMP_ARP_QUEUE 数量。
    • 若系统多接口 / 路由复杂,配置 ETHARP_TABLE_MATCH_NETIF 与 LWIP_HOOK_ETHARP_GET_GW 来控制回路与网关选择。
    • 对延迟敏感的应用可以适度增大 ARP_MAXAGE,或对关键目标预填 ARP(etharp_add_static_entry)。
      正常arp表如下。
      在这里插入图片描述
http://www.lryc.cn/news/625991.html

相关文章:

  • Python脚本每天爬取微博热搜-终版
  • Spring Cloud 微服务架构:Eureka 与 ZooKeeper 服务发现原理与实战指南 NO.1
  • Stream API-怎么理解流
  • Day13_【DataFrame数据组合merge连接】【案例】
  • Redis(11)如何通过命令行操作Redis?
  • 反向代理实现服务器联网
  • 人工神经网络MATLAB工具箱指南
  • Selenium自动化测试入门:cookie处理
  • electron进程间通信- 渲染进程与主进程双向通信
  • 如何用给各种IDE配置R语言环境
  • UGUI源码剖析(10):总结——基于源码分析的UGUI设计原则与性能优化策略
  • Ubuntu 和麒麟系统创建新用户 webapp、配置密码、赋予 sudo 权限并禁用 root 的 SSH 登录的详细
  • Python os 模块与路径操作:从基础到实战应用
  • 《AI 与人类创造力:是替代者还是 “超级协作者”?》​
  • 读《精益数据分析》:营收(Revenue)—— 设计可持续盈利模式
  • RabbitMQ:SpringAMQP 入门案例
  • Day22 顺序表与链表的实现及应用(含字典功能与操作对比)
  • 计算机大数据毕业设计推荐:基于Spark的气候疾病传播可视化分析系统【Hadoop、python、spark】
  • QT示例 基于Subdiv2D的Voronoi图实现鼠标点击屏幕碎裂掉落特效
  • jmetergrafanainfluxdb搭建压测监控平台
  • C# NX二次开发:操作按钮控件Button和标签控件Label详解
  • CentOS上安装Docker的完整流程
  • 可以一键生成PPT的AI PPT工具(最新整理)
  • AiPPT怎么样?好用吗?
  • Lecture 12: Concurrency 5
  • 大数据毕业设计选题推荐:护肤品店铺运营数据可视化分析系统详解
  • 106、【OS】【Nuttx】【周边】文档构建渲染:安装 Sphinx 扩展(下)
  • OptiTrack光学跟踪系统,提高机器人活动精度
  • 电影购票+票房预测系统 - 后端项目介绍(附源码)
  • Qt密码生成器项目开发教程 - 安全可靠的随机密码生成工具