免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1856 | 回复: 2
打印 上一主题 下一主题

关于发送数据包时网络设备注销的问题,高手请进 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2010-05-17 09:58 |只看该作者 |倒序浏览
在IP曾往下发送数据包时,对应的网络设备被注销了,那么可能会导致kernel panic.但是我在内核代码中并没有看到对应的保护代码。

__inline__ int ip_finish_output(struct sk_buff *skb)
{
         struct net_device *dev = skb->dst->dev;

         skb->dev = dev;  // 这里设置了dev,且假设没有netfilter的规则
         skb->protocol = htons(ETH_P_IP);

         return NF_HOOK(PF_INET, NF_IP_POST_ROUTING, skb, NULL, dev,
                       ip_finish_output2);
}


static inline int ip_finish_output2(struct sk_buff *skb)
{
         struct dst_entry *dst = skb->dst;
         struct hh_cache *hh = dst->hh;

#ifdef CONFIG_NETFILTER_DEBUG
         nf_debug_ip_finish_output2(skb);
#endif /*CONFIG_NETFILTER_DEBUG*/

         if (hh) {
                 int hh_alen;

                 read_lock_bh(&hh->hh_lock);
                 hh_alen = HH_DATA_ALIGN(hh->hh_len);
                 memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
                 read_unlock_bh(&hh->hh_lock);
                 skb_push(skb, hh->hh_len);
                 return hh->hh_output(skb); //这里是发送函数,实际指向dev_queue_xmit.
         } else if (dst->neighbour)
                 return dst->neighbour->output(skb);

         if (net_ratelimit())
                 printk(KERN_DEBUG "ip_finish_output2: No header cache and no neighbour!\n");
         kfree_skb(skb);
         return -EINVAL;
}

int dev_queue_xmit(struct sk_buff *skb)
{
...
        if (skb->ip_summed == CHECKSUM_HW &&
            (!(dev->features&(NETIF_F_HW_CSUM|NETIF_F_NO_CSUM)) &&
              (!(dev->features&NETIF_F_IP_CSUM) ||
               skb->protocol != htons(ETH_P_IP)))) {
                if ((skb = skb_checksum_help(skb)) == NULL)
                         return -ENOMEM;
        } // 假设在检查之后,网络设备被删除了

         spin_lock_bh(&dev->queue_lock);
         q = dev->qdisc;
         if (q->enqueue) {    //这里可能发生kernel panic
                 int ret = q->enqueue(skb, q);

                 qdisc_run(dev);

                 spin_unlock_bh(&dev->queue_lock);
                 return ret == NET_XMIT_BYPASS ? NET_XMIT_SUCCESS : ret;
         }

...

}

期待高手回答。

另外问个比较基础的问题: 在local_bh_disable(); 后,是不是软中断和硬中断都被屏蔽了?因为系统调用而产生的软中断是不是也被屏蔽了。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
2 [报告]
发表于 2010-05-17 10:33 |只看该作者
         spin_lock_bh(&dev->queue_lock);
         q = dev->qdisc;
         if (q->enqueue) {    //这里可能发生kernel panic
                 int ret = q->enqueue(skb, q);

LZ认为红色的一行代码是做什么用的?

论坛徽章:
0
3 [报告]
发表于 2010-05-17 10:39 |只看该作者
LZ认为红色的一行代码是做什么用的?
Godbach 发表于 2010-05-17 10:33

这个知道啊。使用spin_lock锁住dev,但是我的内核是单核的。应该只会local_bh_disable(),只有代码运行到spin_lock后才安全,我个人的看法。但是问题是如果是在检查check_sum后就立刻执行了系统调用的软中断,然后网络设备被删除了,这样不就出问题了吗?或者是dev_queue_xmit这个函数是不可中断的?

不知道我理解的对不对?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP