+ -
当前位置:首页 → 问答吧 → 桥设备处理数据包时的一个疑问?

桥设备处理数据包时的一个疑问?

时间:2010-08-07

来源:互联网

本帖最后由 cuTlh 于 2010-08-07 19:15 编辑

在netif_receive_skb交给桥设备后,handle_bridge为什么还要调用deliver_skb去deliver给上层?
  1. static inline struct sk_buff *handle_bridge(struct sk_buff *skb,
  2.                                             struct packet_type **pt_prev, int *ret,
  3.                                             struct net_device *orig_dev)
  4. {
  5.         struct net_bridge_port *port;

  6.         if (skb->pkt_type == PACKET_LOOPBACK ||
  7.             (port = rcu_dereference(skb->dev->br_port)) == NULL)
  8.                 return skb;

  9.         if (*pt_prev) {
  10.                 *ret = deliver_skb(skb, *pt_prev, orig_dev);
  11.                 *pt_prev = NULL;
  12.         }

  13.         return br_handle_frame_hook(port, skb);
  14. }
复制代码
看Kendo的一篇文章说是“pt_prev用于在共享SKB的时候提高效率”,抱歉原文找不到了 http://blog.csdn.net/zhaodm/archive/2006/12/25/1460041.aspx

但是这个skb既被上层协议处理函数使用,又被桥的处理函数(br_handle_frame)使用,不会有问题吗? 并且也没看懂怎么提高效率了?

作者: cuTlh   发布时间: 2010-08-07

这里pt_prev是在之前的  
list_for_each_entry_rcu(ptype, &ptype_all, list) {
        if (!ptype->dev || ptype->dev == skb->dev) {
            if (pt_prev)
                ret = deliver_skb(skb, pt_prev, orig_dev);
            pt_prev = ptype;
        }
    }

作者: linuxxtz   发布时间: 2010-08-07

遍历ptype_all中找到的ptype,而ptype_all是可以接受所有包的,如PACKET截包。
   if (*pt_prev) {
                 *ret = deliver_skb(skb, *pt_prev, orig_dev);
                 *pt_prev = NULL;
         }
这里是如果有这种情况需处理,就会把包上交给这种协议。

作者: linuxxtz   发布时间: 2010-08-07

回复 linuxxtz


    噢,是的,您说的对!在br_handle_frame处理的时候会检查这个数据包是不是共享的,如果是的话就会clone数据buffer,然后再由桥模块进行处理。
  1. skb = skb_share_check(skb, GFP_ATOMIC);
  2.         if (!skb)
  3.                 return NULL;
复制代码
  同样,在macvlan_handle_frame_hook点也是这样做的。谢谢!

作者: cuTlh   发布时间: 2010-08-07

热门下载

更多