netifd调试总结(OpenWrt 22.03)

目录

1.调试

1.1 gdb调试

​编辑1.2 D打印

1.3 syslog打印

1.4 命令行获取IP

2 初始化过程分析(BPI-R64)

2.1 创建CPU口和mdio驱动初始化

2.1.1 创建CPU口

2.1.2 mdio驱动初始化

2.1.3 注册CPU口

2.2 创建用户口(mdio设备初始化)

2.3 生成/etc/config/network

3 支持的device类型

3.1 802.1q

3.2 MAC VLAN

4 监听内核接口状态的变化


1.调试

1.1 gdb调试

如下所示,修改配置(问题:有些东西打印不出来,比如ifname,提示 ifname = <error reading variable>)


1.2 D打印

在/etc/init.d/network中增加如下内容就能使用“logread -e netifd”看到D打印的内容,“-d 15"表示打开以下所有模块的打印,如果”-d 1",那就只打印DEBUG_SYSTEM:

enum {
    DEBUG_SYSTEM    = 0,
    DEBUG_DEVICE    = 1,
    DEBUG_INTERFACE    = 2,
    DEBUG_WIRELESS    = 3,
};


 


注意:D打印的内容是"daemon.err netifd[10824]"开头的,而netifd使用的syslog级别为L_CRIT,L_WARNING,L_NOTICE,L_INFO,L_DEBUG,感觉是特意避开err级别,避免跟D混淆。

1.3 syslog打印

如果将上面的启动参数修改为“procd_set_param command /sbin/netifd -l 5 -d 15”,则代码及对应的打印内容如下所示:

DPRINTF("connected as %08x\n", ubus_ctx->local_id);
netifd_log_message(L_DEBUG, "connected as %08x\n", ubus_ctx->local_id);
netifd_log_message(L_INFO, "connected as %08x\n", ubus_ctx->local_id);
netifd_log_message(L_NOTICE, "connected as %08x\n", ubus_ctx->local_id);
netifd_log_message(L_WARNING, "connected as %08x\n", ubus_ctx->local_id);
netifd_log_message(L_CRIT, "connected as %08x\n", ubus_ctx->local_id);


 

daemon.err netifd[17096]: netifd_ubus_init(1364): connected as 0d6fc15a
daemon.debug netifd: connected as 0d6fc15a
daemon.info netifd: connected as 0d6fc15a
daemon.notice netifd: connected as 0d6fc15a
daemon.warn netifd: connected as 0d6fc15a
daemon.crit netifd: connected as 0d6fc15a


 


1.4 命令行获取IP

ifstatus WAN1 | jsonfilter -e '@["ipv4-address"][0].address'


 


2 初始化过程分析(BPI-R64)

2.1 创建CPU口和mdio驱动初始化

kernel_init->kernel_init_freeable->do_basic_setup->do_initcalls->do_one_initcall
  ->mtk_driver_init(mtk_eth_soc.c中通过module_platform_driver注册)
    ->platform_driver_register->__platform_driver_register->driver_register->bus_add_driver->driver_attach->bus_for_each_dev
      ->__driver_attach->device_driver_attach->driver_probe_device->really_probe
        ->platform_drv_probe(paltform.c中通过__platform_driver_register注册)->mtk_probe


 


2.1.1 创建CPU口
  • 创建CPU口
mtk_probe->mtk_add_mac->alloc_etherdev->alloc_etherdev_mq->alloc_etherdev_mqs->alloc_netdev_mqs(此时接口名称为'eth%d')
  • 将netdev与DTS关联起来
mtk_probe->mtk_add_mac(其中eth->netdev[id]->dev.of_node = np;关联起来,在设备初始化时match)

2.1.2 mdio驱动初始化
mtk_probe->mtk_mdio_init(读DTS)->of_mdiobus_register->of_mdiobus_register_device->mdio_device_register->device_add
            ->bus_probe_device->device_initial_probe->__device_attach->bus_for_each_drv->__device_attach_driver
              ->driver_probe_device->really_probe->mdio_probe(mdio.h中通过mdio_module_init注册)
                ->mt7530_probe(drivers\net\dsa\mt7530.c中通过mdio_module_driver(mt7530_mdio_driver)注册)
                  ->dsa_register_switch->dsa_switch_probe->dsa_switch_parse_of->dsa_switch_parse_ports_of->dsa_port_parse_of
                    ->of_find_net_device_by_node(DTS中port@6调用,因为此时接口没有注册,所以class_find_device返回NULL,进而dsa_port_parse_of返回-EPROBE_DEFER,驱动初始化完成)

2.1.3 注册CPU口

注册时,会自动给CPU口命名为命名为eth0和eth1

mtk_probe->register_netdev->register_netdevice->dev_get_valid_name->dev_alloc_name_ns->__dev_alloc_name



2.2 创建用户口(mdio设备初始化)

获取接口名称
deferred_probe_work_func(具体何时调用不清楚)->bus_probe_device->device_initial_probe->__device_attach->bus_for_each_drv
  ->__device_attach_driver->driver_probe_device->really_probe->mdio_probe(mdio.h中通过mdio_module_init注册)
   ->mt7530_probe(drivers\net\dsa\mt7530.c中通过mdio_module_driver(mt7530_mdio_driver)注册)
     ->dsa_register_switch->dsa_switch_probe
         其中->dsa_switch_parse_of->dsa_switch_parse_ports_of->dsa_port_parse_of->dsa_port_parse_user(从DTS中读取接口名称)
         另外->dsa_tree_setup->dsa_tree_setup_switches->dsa_port_setup->dsa_slave_create(创建lan1~lan4及wan口。)


2.3 生成/etc/config/network

config_generate根据target\linux\mediatek\mt7622\base-files\etc\board.d\02_network生成/etc/config/network,具体实现的参考链接如下:OpenWrt file/bin/config_generate network初始化分析

3 支持的device类型

LuCI类型UCI类型对应结构体使用场景
Network deviceN/A simple_device_type对应真实物理端口,好像不创建也不影响功能。。。
Bridge devicebridgebridge_device_type基于桥设备创建桥接口,比如br-lan
VLAN(802.1q)8021qvlan8021q_device_type基于802.1q设备创建接口,比如创建802.1q的路由连接
VLAN(802.1ad)8021advlan8021ad_device_type基于802.1ad设备创建接口,比如创建802.1ad的路由连接
MAC VLANmacvlanmacvlan_device_type
Virtual Ethernetvethveth_device_type

所有类型都通过device_type_add来添加。

3.1 802.1q

  • 创建带VLAN的device

  • 创建interface,这样在WAN侧抓到的报文就是带VLAN 100的

  • 对应的UCI配置如下:
config device
        option type '8021q'
        option ifname 'wan'
        option vid '100'
        option name 'wan.100'

config interface 'WAN'
        option proto 'dhcp'
        option device 'wan.100'



3.2 MAC VLAN

  • 创建带MAC VLAN的device,wanmac1也用同样方法创建

  • 创建interface,WAN1使用相同方法创建

  • 对应的UCI配置如下:
config device
        option type 'macvlan'
        option ifname 'wan'
        option mode 'bridge'
        option name 'wanmac0'

config device
        option type 'macvlan'
        option ifname 'wan'
        option mode 'bridge'
        option name 'wanmac1'

config interface 'WAN0'
        option proto 'dhcp'
        option device 'wanmac0'config interface 'WAN1'
        option proto 'dhcp'
        option device 'wanmac1'

  • 两个MAC VLAN桥模式的WAN连接通信

执行如下命令,参考链接:https://unix.stackexchange.com/questions/398671/communication-problem-between-macvlan-interfaces-when-sockets-are-bound-to-devic

device0=`ifstatus WAN0 | jsonfilter -e '@["device"]'`
device1=`ifstatus WAN1 | jsonfilter -e '@["device"]'`
ip0=`ifstatus WAN0 | jsonfilter -e '@["ipv4-address"][0].address'`
ip1=`ifstatus WAN1 | jsonfilter -e '@["ipv4-address"][0].address'`

ip route del default
ip route del `ip route|grep "$device0"` 
ip route del `ip route|grep "$device1"` 
ip rule del pref 0
ip rule add pref 200 to "$ip1" lookup 100
ip rule add pref 200 to "$ip0" lookup 101
ip route add default dev "$device0" table 100
ip route add default dev "$device1" table 101
ip rule add pref 1000 lookup local
ip rule add pref 100 to "$ip0" iif "$device0" lookup local
ip rule add pref 100 to "$ip1" iif "$device1" lookup local

ping -I $device0 $ip1 #此时能ping通


 


4 监听内核接口状态的变化

  • 1、system_init中调用create_event_socket创建监听netlink的socket
  • 2、当接口link up或者link down时,在内核中调用netif_carrier_on,最终会走到netdev_state_change,再通过rtmsg_ifinfo发出netlink消息。
  • 3、在system_init中注册的cb_rtnl_event监听到消息之后,做相应的处理。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenWrt 22.03.5是OpenWrt操作系统的一个版本。根据引用\[1\],OpenWrt 22.03.0版本的亮点包括基于nftables的Firewall4防火墙。这意味着在22.03.5版本中,你可以使用Firewall4防火墙来保护你的网络。 根据引用\[2\],编译完成后,你可以将OpenWrt 22.03.5版本烧写到设备上,并查看系统的现象。在引用中提供的示例输出中,可以看到BusyBox版本为v1.36.1,内置的shell为ash。此外,还提供了Linux内核版本为5.15.112的信息。 根据引用\[3\],如果你想使OpenWrt系统支持qmi协议以便支持移远5G模块通讯,你可以通过LuCI界面进行配置。具体的配置步骤可以参考引用中提供的指南。 综上所述,OpenWrt 22.03.5是一个支持基于nftables的Firewall4防火墙的版本,你可以通过编译和烧写来安装它,并且可以通过配置来使其支持qmi协议以便支持移远5G模块通讯。 #### 引用[.reference_title] - *1* [OpenWrt-v22.03 通过安装 ZeroTier 插件实现异地组网](https://blog.csdn.net/m0_60027682/article/details/127024674)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [OK1043-openwrt系统移植](https://blog.csdn.net/last_sun/article/details/131227124)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值