分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 网页技术

netif_receive_skb->__netif_receive_skb_core

发布时间:2023-09-06 01:13责任编辑:赖小花关键词:暂无标签

在设备驱动收包之后,会通过netif_receive_skb将收取的包,按照注册的协议回调,传递到上层进行处理;

 ?1 /* 将skb传递到上层 */ ?2 static int __netif_receive_skb_core(struct sk_buff *skb, bool pfmemalloc) ?3 { ?4 ????struct packet_type *ptype, *pt_prev; ?5 ????rx_handler_func_t *rx_handler; ?6 ????struct net_device *orig_dev; ?7 ????bool deliver_exact = false; ?8 ????int ret = NET_RX_DROP; ?9 ????__be16 type; 10 ?11 ????/* 记录收包时间,netdev_tstamp_prequeue为0,表示可能有包延迟 */ 12 ????net_timestamp_check(!netdev_tstamp_prequeue, skb); 13 ?14 ????trace_netif_receive_skb(skb); 15 ?16 ????/* 记录收包设备 */ 17 ????orig_dev = skb->dev; 18 ?19 ????/* 重置各层头部 */ 20 ????skb_reset_network_header(skb); 21 ????if (!skb_transport_header_was_set(skb)) 22 ????????skb_reset_transport_header(skb); 23 ????skb_reset_mac_len(skb); 24 ?25 ????/* ?26 ????????留下一个节点,最后一次向上层传递时, 27 ????????不需要在inc引用,回调中会free 28 ????????这样相当于少调用了一次free 29 ????*/ 30 ????pt_prev = NULL; 31 ?32 another_round: 33 ?34 ????/* 接收设备索引号 */ 35 ????skb->skb_iif = skb->dev->ifindex; 36 ?37 ????/* 处理包数统计 */ 38 ????__this_cpu_inc(softnet_data.processed); 39 ?40 ????/* vlan包,则去掉vlan头 */ 41 ????if (skb->protocol == cpu_to_be16(ETH_P_8021Q) || 42 ????????skb->protocol == cpu_to_be16(ETH_P_8021AD)) { 43 ?44 ????????/* 45 ????????????这里改了三层协议,protocol指向ip等 46 ????????????another_round不会再走这里 47 ????????*/ 48 ????????skb = skb_vlan_untag(skb); 49 ????????if (unlikely(!skb)) 50 ????????????goto out; 51 ????} 52 ?53 ????/* 不对数据包进行分类 */ 54 ????if (skb_skip_tc_classify(skb)) 55 ????????goto skip_classify; 56 ?57 ????/* prmemalloc */ 58 ????if (pfmemalloc) 59 ????????goto skip_taps; 60 ?61 ?62 ????/* 下面两个是未(指定)设备的所有协议传递的上层传递 */ 63 ?64 ?65 ????/* 如抓包程序未指定设备 */ ????66 ????/* 进行未指定设备的全局链表对应协议的skb上层传递 */ 67 ????list_for_each_entry_rcu(ptype, &ptype_all, list) { 68 ????????if (pt_prev) 69 ????????????ret = deliver_skb(skb, pt_prev, orig_dev); 70 ????????pt_prev = ptype; 71 ????} 72 ?73 ????/* 如抓包程序指定了设备 */ 74 ????/* 进行指定设备的协议链表的skb上层传递 */ 75 ????list_for_each_entry_rcu(ptype, &skb->dev->ptype_all, list) { 76 ????????if (pt_prev) 77 ????????????ret = deliver_skb(skb, pt_prev, orig_dev); 78 ????????pt_prev = ptype; 79 ????} 80 ?81 skip_taps: 82 #ifdef CONFIG_NET_INGRESS 83 ????if (static_key_false(&ingress_needed)) { 84 ????????skb = sch_handle_ingress(skb, &pt_prev, &ret, orig_dev); 85 ????????if (!skb) 86 ????????????goto out; 87 ?88 ????????if (nf_ingress(skb, &pt_prev, &ret, orig_dev) < 0) 89 ????????????goto out; 90 ????} 91 #endif 92 ????skb_reset_tc(skb); 93 skip_classify: 94 ?95 ????/* 不支持使用pfmemalloc */ 96 ????if (pfmemalloc && !skb_pfmemalloc_protocol(skb)) 97 ????????goto drop; 98 ?99 ????/* 如果是vlan包 */100 ????if (skb_vlan_tag_present(skb)) {101 ????????/* 处理prev */102 ????????if (pt_prev) {103 ????????????ret = deliver_skb(skb, pt_prev, orig_dev);104 ????????????pt_prev = NULL;105 ????????}106 107 ????????/* 根据实际的vlan设备调整信息,再走一遍 */108 ????????if (vlan_do_receive(&skb))109 ????????????goto another_round;110 ????????else if (unlikely(!skb))111 ????????????goto out;112 ????}113 114 ????/* 如果有注册handler,那么调用,比如网桥模块 */115 ????rx_handler = rcu_dereference(skb->dev->rx_handler);116 ????if (rx_handler) {117 ????????if (pt_prev) {118 ????????????ret = deliver_skb(skb, pt_prev, orig_dev);119 ????????????pt_prev = NULL;120 ????????}121 ????????switch (rx_handler(&skb)) {122 ????????????/* 已处理,无需进一步处理 */123 ????????case RX_HANDLER_CONSUMED:124 ????????????ret = NET_RX_SUCCESS;125 ????????????goto out;126 ????????????/* 修改了skb->dev,在处理一次 */127 ????????case RX_HANDLER_ANOTHER:128 ????????????goto another_round;129 ????????????/* 精确传递到ptype->dev == skb->dev */130 ????????case RX_HANDLER_EXACT:131 ????????????deliver_exact = true;132 ????????????/* 正常传递即可 */133 ????????case RX_HANDLER_PASS:134 ????????????break;135 ????????default:136 ????????????BUG();137 ????????}138 ????}139 140 ????/* 还有vlan标记,说明找不到vlanid对应的设备 */141 ????if (unlikely(skb_vlan_tag_present(skb))) {142 ????????/* 存在vlanid,则判定是到其他设备的包 */143 ????????if (skb_vlan_tag_get_id(skb))144 ????????????skb->pkt_type = PACKET_OTHERHOST;145 ????????/* Note: we might in the future use prio bits146 ?????????* and set skb->priority like in vlan_do_receive()147 ?????????* For the time being, just ignore Priority Code Point148 ?????????*/149 ????????skb->vlan_tci = 0;150 ????}151 152 ????/* 设置三层协议,下面提交都是按照三层协议提交的 */153 ????type = skb->protocol;154 155 ????/* deliver only exact match when indicated */156 ????/* 未设置精确发送,则向未指定设备的指定协议全局发送一份 */157 ????if (likely(!deliver_exact)) {158 ????????deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type,159 ???????????????????????&ptype_base[ntohs(type) &160 ???????????????????????????PTYPE_HASH_MASK]);161 ????}162 163 ????/* 指定设备的,向原设备上层传递 ?*/164 ????deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type,165 ???????????????????&orig_dev->ptype_specific);166 167 ????/* ?当前设备与原设备不同,向当前设备传递 */168 ????if (unlikely(skb->dev != orig_dev)) {169 ????????deliver_ptype_list_skb(skb, &pt_prev, orig_dev, type,170 ???????????????????????&skb->dev->ptype_specific);171 ????}172 173 ????if (pt_prev) {174 ????????if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC)))175 ????????????goto drop;176 ????????else177 ????????????/*178 ????????????????使用pt_prev这里就不需要deliver_skb来inc应用数了179 ????????????????func执行内部会free,减少了一次skb_free180 ????????????*/181 ????????????/* 传递到上层*/182 ????????????ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);183 ????} else {184 drop:185 ????????if (!deliver_exact)186 ????????????atomic_long_inc(&skb->dev->rx_dropped);187 ????????else188 ????????????atomic_long_inc(&skb->dev->rx_nohandler);189 ????????kfree_skb(skb);190 ????????/* Jamal, now you will not able to escape explaining191 ?????????* me how you were going to use this. :-)192 ?????????*/193 ????????ret = NET_RX_DROP;194 ????}195 196 out:197 ????return ret;198 }

netif_receive_skb->__netif_receive_skb_core

原文地址:http://www.cnblogs.com/wanpengcoder/p/7577088.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved