mt7628-openwrt-3.10.14问题:
拔下网线后,ifconfig仍看到ip,ip未释放;
拔下网线,更换另一个路由器网线,ip也不重新获取。
原因:
以太网驱动监测到网线插拔时,没有成功发送信号到udhcpc进程,以释放ip+得新获取ip
解决方法:
第一步:
查看以太网驱动:build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/linux-ramips_mt7628/linux-3.10.14/drivers/net/raeth/raether.c中void kill_sig_workq(struct work_struct *work)函数,此函数用来向应用层发送信号更新ip。
void kill_sig_workq(struct work_struct *work)
{
struct file *fp;
char pid[8]={0};
struct task_struct *p = NULL;
//read udhcpc pid from file, and send signal USR2,USR1 to get a new IP
fp = filp_open("/var/run/udhcpc.pid", O_RDONLY, 0);
if (IS_ERR(fp))
return;
if (fp->f_op && fp->f_op->read) {
if (fp->f_op->read(fp, pid, 8, &fp->f_pos) > 0) {
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
p = pid_task(find_get_pid(simple_strtoul(pid, NULL, 10)), PIDTYPE_PID);
#else
p = find_task_by_pid(simple_strtoul(pid, NULL, 10));
#endif
if (NULL != p) {
printk("csx----send sig ok\r\n");
send_sig(SIGUSR2, p, 0);
send_sig(SIGUSR1, p, 0);
}
}
}
filp_close(fp, NULL);
}
以代码中可以得知发送信号的目标进程是udhcpc,进程号存于"/var/run/udhcpc.pid"。
而实际设备中仅有"/var/run/udhcpc-eth0.1.pid"
经常查找得知此文件的创建始于:package/network/config/netifd/files/lib/netifd/proto/dhcp.sh
修改dhcp.sh,将"/var/run/udhcpc-$ifname.pid"改为“/var/run/udhcpc.pid”
proto_dhcp_setup() {
local config="$1"
local iface="$2"
local ipaddr hostname clientid vendorid broadcast reqopts iface6rd sendopts delegate zone6rd zone
json_get_vars ipaddr hostname clientid vendorid broadcast reqopts iface6rd sendopts delegate zone6rd zone
local opt dhcpopts
for opt in $reqopts; do
append dhcpopts "-O $opt"
done
for opt in $sendopts; do
append dhcpopts "-x $opt"
done
[ "$broadcast" = 1 ] && broadcast="-B" || broadcast=
[ -n "$clientid" ] && clientid="-x 0x3d:${clientid//:/}" || clientid="-C"
[ -n "$iface6rd" ] && proto_export "IFACE6RD=$iface6rd"
[ "$iface6rd" != 0 -a -f /lib/netifd/proto/6rd.sh ] && append dhcpopts "-O 212"
[ -n "$zone6rd" ] && proto_export "ZONE6RD=$zone6rd"
[ -n "$zone" ] && proto_export "ZONE=$zone"
[ "$delegate" = "0" ] && proto_export "IFACE6RD_DELEGATE=0"
proto_export "INTERFACE=$config"
proto_run_command "$config" udhcpc \
-p /var/run/udhcpc.pid \
-s /lib/netifd/dhcp.script \
-f -t 0 -i "$iface" \
${ipaddr:+-r $ipaddr} \
${hostname:+-H $hostname} \
${vendorid:+-V $vendorid} \
$clientid $broadcast $dhcpopts
}
第二步(如果第一步未成功,继续第二步):
经过第一步的操作,发现信号仍未发出,继续查看以太网驱动raether.c
发现schedule_work(&ei_local->kill_sig_wq)未执行。我这里使用的单网口方案,wan口P0对应
(RALINK_ETH_SW_BASE+0x80)寄存器的第25位,于是将
#ifdef (CONFIG_WAN_AT_P0)
改为:
#if defined (CONFIG_WAN_AT_P0) || defined (CONFIG_ETH_ONE_PORT_ONLY)
测试发现插入网线时有信号,拔出网线时却没有。
于是直接将link down到link up的相关判断注释掉。使其无论插拔网线,均可发送信号到udhcp
if (reg_int_val & PORT_ST_CHG) {
printk("csx----->RT305x_ESW: Link Status Changed\n");
stat_curr = *((volatile u32 *)(RALINK_ETH_SW_BASE+0x80));
//#ifdef (CONFIG_WAN_AT_P0)
//#if defined (CONFIG_WAN_AT_P0) || defined (CONFIG_ETH_ONE_PORT_ONLY)
//link down --> link up : send signal to user application
//link up --> link down : ignore
// if ((stat & (1<<25)) || !(stat_curr & (1<<25)))
//#else
// if ((stat & (1<<29)) || !(stat_curr & (1<<29)))
//#endif
// goto out;
schedule_work(&ei_local->kill_sig_wq);
//out:
stat = stat_curr;
}