Linux 网络层实现

netif_receive_skb(skb)
{
  如果开启了netpoll,直接netpoll_rx()然后返回;??????????????
  如果使用了bond功能,就把skb->dev设置成设备组中的主设备,skb->realdev还是原来的设备;
  入帧计数;
  初始化每层协议的raw指针,后续访问都用raw指针;
  如果开启了流量控制,且流量控制裁决为TC_NCLS,则goto ncls;
  对于所有协议(IP/IPv6/...)类型packet_type,如果协议匹配本skb的dev,则调用deliver_skb(skb,pt_prev)-->pt_prev中的钩子(如ip_rcv());
  如果开启了流量控制,调用deliver_skb()-->pt_prev中的钩子(此处不知道是哪个函数);?????????
  ncls:
  转移数据包;??????
  如果开启了网桥,则调用handle_bridge()-->deliver_sbk(),然后goto out;
  将包分发给L3层协议;
  返回;
}


ip_rcv(skb,dev,pt)  //pt:struct packet_type,包处理协议
{
  检查包的目的地址,如果与本机不符则丢弃;
  检查sk_buff是否被内核其他部分用了,如果被用了,则会建立一份skb的copy;
  检查skb->data包长度是否够,不够的话得从frags里面复制一份过来;
  对IP报头做一些健康性(头长度、头+选项长度、校验和)检查,对不合格的包进行丢弃处理;
  判断是否有L2填充,如果有,重置skb->ip_summed;
  return NF_HOOK(NF_IP_PRE_ROUTING,ip_rcv_finish); //如果nf_hooks中定义了相应的防火墙函数(elem->hook()),且数据包通过防火墙过滤,则调用ip_rcv_finish()进行路由;
}


ip_rcv_finish(skb)
{
  如果skb->dest==NULL,则进行路由查找,找不到的话还要把包给丢了;
  如果开启了CONFIG_NET_CLS_ROUTE,更新QoS的统计数据;
  如果IP头中有选项,调用ip_options_compile()对选项逐个进行分析;??????????
  return dst_input(skb);实际上调用skb->dst->input() //如果是本地IP包,则input=ip_local_deliver();如果是转发,则input=ip_forward()
}


ip_local_deliver(skb)
{
  如果需要重组,则调用ip_defrag();内部查找所有分片,如果找到,则调用ip_frag_reasm()进行重组,否则返回0
  return NF_HOOK(NF_IP_LOCAL_IN,ip_local_deliver_finish());
}


ip_local_deliver_finish(skb)
{
  skb->data += skb->nh.iph->ihl*4;等于忽略ip头;
  根据协议号查找传输层struct sock *raw_sk;找到则调用raw_v4_input()向L4分发原始数据包;
  如果传输层需要检查IPSec则进行检查,如果检查失败,就释放包并退出;
  根据协议号查找struct net_protocol *ipprot->handler(skb); //对于tcp,就是tcp_v4_rcv()
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值