免费注册 查看新帖 |

Chinaunix

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

[网络子系统] Linux内核协议栈怎么把报文交到对应的dev [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-12-28 13:46 |只看该作者 |倒序浏览
在有lan的时候Linux协议栈中怎么找到对应的net_device(比如eth1.10)呢?在netif_receive_skb中看到可以找到对应的协议类型但是不知道怎么找到对应的dev,比如eth1有eth1.10、eth1.15。怎么发到对应的dev上去?

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
2 [报告]
发表于 2013-12-28 21:18 |只看该作者
@Godbach

                           

论坛徽章:
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
3 [报告]
发表于 2014-01-06 15:10 |只看该作者
回复 1# jasonsungblog

查路由啊。


   

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
4 [报告]
发表于 2014-01-06 15:27 |只看该作者
Godbach 发表于 2014-01-06 15:10
回复 1# jasonsungblog

查路由啊。


请教下 如下代码中的FIXME部分:

  1.         对一个RX来的skb,其skb->dev代表着:该skb从哪个dev接受到的。
  2.         对一个TX的skb来说,其skb->dev代表着:该skb将从哪个dev发送出去。

  3.         那么,skb->dev是什么时候赋值的呢? rx的路径很好理解,nic driver再
  4.         netdev_alloc_skb时,就已经把相应的net_device指针赋值给skb->dev了。

  5.         tx呢? 以udp为例:

  6.         udp_sendmsg
  7.                 flowi4_init_output
  8.                 ip_route_output_flow
  9.                 ..
  10.                 ip_make_skb
  11.                 udp_send_skb
  12.                         ip_send_skb
  13.                                 ip_local_out
  14.                                         __ip_local_out

  15.         从ip_send_skb到__ip_local_out,不曾对skb->dev做修改,而__ip_local_out
  16.         中已经直接实用skb_dst(skb)->dev作为包的输出设备了。
  17.         这说明,skb->dev的赋值,是在调用ip_send_skb之前,就已经完成了。


  18.         udp_sendmsg

  19.                 /* FIXME: sk->sk_bound_dev_if是什么? 依照我的理解,是在
  20.                  *           udp_prot的connect方法,也就是ip4_datagram_connect
  21.                  *           中,设置的:
  22.                  *                   ip4_datagram_connect
  23.                  *                           ip_route_connect
  24.                  */
  25.                 ipc.oif = sk->sk_bound_dev_if
  26.                 flowi4_init_output(fl4, ipc.oif, sk->sk_mark, tos,
  27.                                    RT_SCOPE_UNIVERSE, sk->sk_protocol,
  28.                                    inet_sk_flowi_flags(sk)|FLOWI_FLAG_CAN_SLEEP,
  29.                                    faddr, saddr, dport, inet->inet_sport);
  30.                         /* NOTE: 这里给flowi4_oif赋值了 */
  31.                         fl4->flowi4_oif = ipc.oif

  32.                 ip_route_output_flow
  33.                         __ip_route_output_key
  34.                                 struct net_device *dev_out = NULL;
  35.                                 ..
  36.                                 /* NOTE: 如果fl4的flowi4_oif不是0,那么,这里就从
  37.                                  *         if idex寻找dev_out了 -- 而上面的
  38.                                  *         flowi4_init_output中,已经给flowi4_oif
  39.                                  *         赋值过了。
  40.                                  */
  41.                                 if (fl4->flowi4_oif)
  42.                                         dev_out = dev_get_by_index_rcu(net,
  43.                                                         fl4->flowi4_oif);

  44.                                 make_route:(label)
  45.                                         __mkroute_output
  46.                                                 rt_dst_alloc(dev_out, ...)
  47.                                                         dst_alloc
  48.                                                                 dst->dev = dev;
复制代码

论坛徽章:
16
CU十二周年纪念徽章
日期:2013-10-24 15:41:3415-16赛季CBA联赛之广东
日期:2015-12-23 21:21:55青铜圣斗士
日期:2015-12-05 10:35:30黄金圣斗士
日期:2015-11-26 20:42:16神斗士
日期:2015-11-19 12:47:50每日论坛发贴之星
日期:2015-11-18 06:20:00程序设计版块每日发帖之星
日期:2015-11-18 06:20:002015亚冠之城南
日期:2015-11-10 19:10:492015亚冠之萨济拖拉机
日期:2015-10-28 18:47:282015亚冠之柏太阳神
日期:2015-08-30 17:21:492015亚冠之山东鲁能
日期:2015-07-07 18:48:39摩羯座
日期:2014-08-29 23:01:42
5 [报告]
发表于 2014-01-07 10:47 |只看该作者
在vlan.c中的函数vlan-skb-rcv会根据vlan-id去修正skb的dev指向的

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
6 [报告]
发表于 2014-01-07 11:20 |只看该作者
回复 4# 帅绝人寰
  /* FIXME: sk->sk_bound_dev_if是什么? 依照我的理解,是在
                 *           udp_prot的connect方法,也就是ip4_datagram_connect
                 *           中,设置的:
                 *                   ip4_datagram_connect
                 *                           ip_route_connect
                 */


这个一般是通过SO_BINDTODEVICE选项设置的。默认情况下是0,不指定出口设备,由路由时候决定
   

论坛徽章:
2
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:53:17
7 [报告]
发表于 2014-01-07 12:11 |只看该作者
瀚海书香 发表于 2014-01-07 11:20
回复 4# 帅绝人寰


以UDP为例,假如不曾setsockopt,那么第一个packet应该是象你说的, 走路由; 第二个呢? 是还走路由?

论坛徽章:
6
金牛座
日期:2013-10-08 10:19:10技术图书徽章
日期:2013-10-14 16:24:09CU十二周年纪念徽章
日期:2013-10-24 15:41:34狮子座
日期:2013-11-24 19:26:19未羊
日期:2014-01-23 15:50:002015年亚洲杯之阿联酋
日期:2015-05-09 14:36:15
8 [报告]
发表于 2014-01-07 14:09 |只看该作者
回复 7# 帅绝人寰
以UDP为例,假如不曾setsockopt,那么第一个packet应该是象你说的, 走路由; 第二个呢? 是还走路由?


刚才通过systemtap跟踪了一下,每次调用udp_sendmsg的时候,sk->sk_bound_dev_if都是0。

systemtap代码如下:
  1. %{
  2. #include <linux/skbuff.h>
  3. #include <linux/socket.h>
  4. #include <net/sock.h>
  5. %}
  6. function print_sk:long(addr:long)
  7. %{
  8.         struct sock *sk = (struct sock*)THIS->addr;
  9.         printk(KERN_ALERT "sk->sk_bound_dev_if=%d\n", sk->sk_bound_dev_if);
  10. %}
  11. probe kernel.function("udp_sendmsg")
  12. {
  13.         print_sk($sk);
  14. }
复制代码
用户态核心代码如下:
  1. while (count > 0) {
  2.                 q = quota;
  3.                 while (q > 0) {
  4.                         n = sendto(sockfd, sendline, packetsize, 0,
  5.                                         servaddr, serlen);
  6.                         if ( n == -1) {
  7.                                 printf("sendto error=%d, err=%s\n", errno, strerror(errno));
  8.                                 exit(-1);
  9.                         }
  10.                         ++(info.packet);
  11.                         info.bytes += n;
  12.                         --q;
  13.                 }
  14.                 printf("Send UDP total packets=%llu total bytes=%llu \n",
  15.                                 info.packet, info.bytes);
  16.                 --count;
  17.                 usleep(interval * 1000);
  18.         }
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP