当系统中有多个网卡时,lwip会选择第一个网卡作为默认网卡,ping、tftp、iperf都会选择第一个网卡来进行,没有办法使用第二个网卡(一些命令可以通过-i选项选择网卡,有些命令则没有提供),此时需要修改lwip中发送数据时网卡选择的逻辑。
首先找到LWIP_HOOK_IP4_ROUTE_SRC宏,该宏的定义如下:
- #ifdef LWIP_HOOK_IP4_ROUTE_SRC
- struct netif *lwip_ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
- {
- struct netif *netif;
-
- /* iterate through netifs */
- for (netif = netif_list; netif != NULL; netif = netif->next)
- {
- /* is the netif up, does it have a link and a valid address? */
- if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif)))
- {
- /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
- if (src != NULL)
- {
- if (ip4_addr_cmp(src, netif_ip4_addr(netif)))
- {
- return netif;
- }
- }
- }
- }
- netif = netif_default;
- return netif;
- }
- #endif /* LWIP_HOOK_IP4_ROUTE_SRC */
可知,当上层有数据要发送时,lwip会查找已注册的网卡中适合的网卡,条件为:网卡已启动、网卡链接成功、已获取到ip,如果指定了源ip则在符合上述条件的网卡中找到和源ip地址一致的网卡,否则使用默认网卡。显然,当系统中有第二个网卡时,最终会找不到第二个网卡,最后仍使用默认网卡,需要修改成如下所示:
- #ifdef LWIP_HOOK_IP4_ROUTE_SRC
- struct netif *lwip_ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src)
- {
- struct netif *netif = RT_NULL, *netif_alt = RT_NULL;
-
- /* iterate through netifs */
- for (netif = netif_list; netif != NULL; netif = netif->next)
- {
- /* is the netif up, does it have a link and a valid address? */
- if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif)))
- {
- /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */
- if (src != NULL)
- {
- if (ip4_addr_cmp(src, netif_ip4_addr(netif)))
- {
- return netif;
- }
- else if((dest->addr & IN_CLASSA_HOST) == (netif->ip_addr.addr & IN_CLASSA_HOST))
- {
- netif_alt = netif;
- }
- }
- }
- }
-
- if(netif_alt)
- netif = netif_alt;
- else
- netif = netif_default;
-
- return netif;
- }
- #endif /* LWIP_HOOK_IP4_ROUTE_SRC */
来张代码对比图,可以清晰的看到修改的部分:
