Linuxのポーリング処理のコードを読んでみよう 〜netif_receive_skb編〜

Linuxのポーリング処理のコードを読んでみよう 〜ポーリング編〜 - かーねる・う゛いえむにっきの続き。

e1000_clean()が呼んでいたnetif_receive_skb()の中の処理を見ていく。

 2960 int netif_receive_skb(struct sk_buff *skb)
 2961 {
 2962         if (netdev_tstamp_prequeue)
 2963                 net_timestamp_check(skb);
 2964 
 2965         if (skb_defer_rx_timestamp(skb))
 2966                 return NET_RX_SUCCESS;
 2967 
 2968 #ifdef CONFIG_RPS
 2969         {
 2970                 struct rps_dev_flow voidflow, *rflow = &voidflow;
 2971                 int cpu, ret;
 2972 
 2973                 rcu_read_lock();
 2974 
 2975                 cpu = get_rps_cpu(skb->dev, skb, &rflow);
 2976 
 2977                 if (cpu >= 0) {
 2978                         ret = enqueue_to_backlog(skb, cpu, &rflow->last_qtail);
 2979                         rcu_read_unlock();
 2980                 } else {
 2981                         rcu_read_unlock();
 2982                         ret = __netif_receive_skb(skb);
 2983                 }
 2984 
 2985                 return ret;
 2986         }
 2987 #else
 2988         return __netif_receive_skb(skb);
 2989 #endif
 2990 }
 2991 EXPORT_SYMBOL(netif_receive_skb);

なにやら#ifdef CONFIG_RPSとあるが、これはこの記事で書いたRPSのコードである。
RPSが有効な場合は、get_rps_cpu()でキュー先のCPUを決め、cpuidが0でなければ enqueue_to_backlog()でキューイングを行う。
cpuidが0なら今ポーリングを行っているCPUであるはずだから、__netif_receive_skb()を呼び出してこの場でパケット処理を行う。
(としか読めないのだが、cpu == 0が必ずポーリングを実行しているCPUという仮定はどっから来てるんだろう…)
RPSが無効なら、常に__netif_receive_skb()を呼び出しこの場でパケット処理を行う。

で、こちらが__netif_receive_skb()のコード。

 2817 static int __netif_receive_skb(struct sk_buff *skb)
 2818 {
 2819         struct packet_type *ptype, *pt_prev;
 2820         rx_handler_func_t *rx_handler;
 2821         struct net_device *orig_dev;
 2822         struct net_device *master;
 2823         struct net_device *null_or_orig;
 2824         struct net_device *orig_or_bond;
 2825         int ret = NET_RX_DROP;
 2826         __be16 type;
 2827 
 2828         if (!netdev_tstamp_prequeue)
 2829                 net_timestamp_check(skb);
 2830 
 2831         if (vlan_tx_tag_present(skb) && vlan_hwaccel_do_receive(skb))
 2832                 return NET_RX_SUCCESS;
 2833 
 2834         /* if we've gotten here through NAPI, check netpoll */
 2835         if (netpoll_receive_skb(skb))
 2836                 return NET_RX_DROP;
 2837 
 2838         if (!skb->skb_iif)
 2839                 skb->skb_iif = skb->dev->ifindex;
 2840 
 2841         /*
 2842          * bonding note: skbs received on inactive slaves should only
 2843          * be delivered to pkt handlers that are exact matches.  Also
 2844          * the deliver_no_wcard flag will be set.  If packet handlers
 2845          * are sensitive to duplicate packets these skbs will need to
 2846          * be dropped at the handler.  The vlan accel path may have
 2847          * already set the deliver_no_wcard flag.
 2848          */
 2849         null_or_orig = NULL;
 2850         orig_dev = skb->dev;
 2851         master = ACCESS_ONCE(orig_dev->master);
 2852         if (skb->deliver_no_wcard)
 2853                 null_or_orig = orig_dev;
 2854         else if (master) {
 2855                 if (skb_bond_should_drop(skb, master)) {
 2856                         skb->deliver_no_wcard = 1;
 2857                         null_or_orig = orig_dev; /* deliver only exact match */
 2858                 } else
 2859                         skb->dev = master;
 2860         }
 2861 
 2862         __this_cpu_inc(softnet_data.processed);
 2863         skb_reset_network_header(skb);
 2864         skb_reset_transport_header(skb);
 2865         skb->mac_len = skb->network_header - skb->mac_header;
 2866 
 2867         pt_prev = NULL;
 2868 
 2869         rcu_read_lock();
 2870 
 2871 #ifdef CONFIG_NET_CLS_ACT
 2872         if (skb->tc_verd & TC_NCLS) {
 2873                 skb->tc_verd = CLR_TC_NCLS(skb->tc_verd);
 2874                 goto ncls;
 2875         }
 2876 #endif
 2877 
 2878         list_for_each_entry_rcu(ptype, &ptype_all, list) {
 2879                 if (ptype->dev == null_or_orig || ptype->dev == skb->dev ||
 2880                     ptype->dev == orig_dev) {
 2881                         if (pt_prev)
 2882                                 ret = deliver_skb(skb, pt_prev, orig_dev);
 2883                         pt_prev = ptype;
 2884                 }
 2885         }
 2886 
 2887 #ifdef CONFIG_NET_CLS_ACT
 2888         skb = handle_ing(skb, &pt_prev, &ret, orig_dev);
 2889         if (!skb)
 2890                 goto out;
 2891 ncls:
 2892 #endif
 2893 
 2894         /* Handle special case of bridge or macvlan */
 2895         rx_handler = rcu_dereference(skb->dev->rx_handler);
 2896         if (rx_handler) {
 2897                 if (pt_prev) {
 2898                         ret = deliver_skb(skb, pt_prev, orig_dev);
 2899                         pt_prev = NULL;
 2900                 }
 2901                 skb = rx_handler(skb);
 2902                 if (!skb)
 2903                         goto out;
 2904         }
 2905 
 2906         /*
 2907          * Make sure frames received on VLAN interfaces stacked on
 2908          * bonding interfaces still make their way to any base bonding
 2909          * device that may have registered for a specific ptype.  The
 2910          * handler may have to adjust skb->dev and orig_dev.
 2911          */
 2912         orig_or_bond = orig_dev;
 2913         if ((skb->dev->priv_flags & IFF_802_1Q_VLAN) &&
 2914             (vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING)) {
 2915                 orig_or_bond = vlan_dev_real_dev(skb->dev);
 2916         }
 2917 
 2918         type = skb->protocol;
 2919         list_for_each_entry_rcu(ptype,
 2920                         &ptype_base[ntohs(type) & PTYPE_HASH_MASK], list) {
 2921                 if (ptype->type == type && (ptype->dev == null_or_orig ||
 2922                      ptype->dev == skb->dev || ptype->dev == orig_dev ||
 2923                      ptype->dev == orig_or_bond)) {
 2924                         if (pt_prev)
 2925                                 ret = deliver_skb(skb, pt_prev, orig_dev);
 2926                         pt_prev = ptype;
 2927                 }
 2928         }
 2929 
 2930         if (pt_prev) {
 2931                 ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
 2932         } else {
 2933                 kfree_skb(skb);
 2934                 /* Jamal, now you will not able to escape explaining
 2935                  * me how you were going to use this. :-)
 2936                  */
 2937                 ret = NET_RX_DROP;
 2938         }
 2939 
 2940 out:
 2941         rcu_read_unlock();
 2942         return ret;
 2943 }

コードがこんがらがっててわっかりにくいけど、多分2918行目でパケットのプロトコル番号を取得し、続く2919行目でptype_base[]から対応するハンドラを取り出し、deliver_skb()経由でpt_prev->func()を呼び出しているのだと推測される。

 2614 static inline int deliver_skb(struct sk_buff *skb,
 2615                               struct packet_type *pt_prev,
 2616                               struct net_device *orig_dev)
 2617 {
 2618         atomic_inc(&skb->users);
 2619         return pt_prev->func(skb, skb->dev, pt_prev, orig_dev);
 2620 }

では、このptype_base[]とpt_prev->funcとは何か、を調べてみる。

  374 /**
  375  *      dev_add_pack - add packet handler
  376  *      @pt: packet type declaration
  377  *
  378  *      Add a protocol handler to the networking stack. The passed &packet_type
  379  *      is linked into kernel lists and may not be freed until it has been
  380  *      removed from the kernel lists.
  381  *
  382  *      This call does not sleep therefore it can not
  383  *      guarantee all CPU's that are in middle of receiving packets
  384  *      will see the new packet type (until the next received packet).
  385  */
  386 
  387 void dev_add_pack(struct packet_type *pt)
  388 {
  389         int hash;
  390 
  391         spin_lock_bh(&ptype_lock);
  392         if (pt->type == htons(ETH_P_ALL))
  393                 list_add_rcu(&pt->list, &ptype_all);
  394         else {
  395                 hash = ntohs(pt->type) & PTYPE_HASH_MASK;
  396                 list_add_rcu(&pt->list, &ptype_base[hash]);
  397         }
  398         spin_unlock_bh(&ptype_lock);
  399 }
  400 EXPORT_SYMBOL(dev_add_pack);

ptype_base[]を触ってるコードを探してみるとdev_add_pack()が見つかる。
コメントを読むとadd packet handlerと書いてあって、パケットハンドラを登録する関数だという事がわかる。
ではコレを呼んでるコードはどこにあるんだろうとfxrで調べてみると、34個も表示されて、ああ、色んなプロトコルをサポートしているのだなぁと気づく。

まぁ、ここは素のIPv4じゃないすかね、って事でnet/ipv4/af_inet.cを見てみよう。

dev_add_pack()はinet_init()の最後の方で呼ばれている

 1720         dev_add_pack(&ip_packet_type);

引数にip_packet_typeを取っている。

 1606 static struct packet_type ip_packet_type __read_mostly = {
 1607         .type = cpu_to_be16(ETH_P_IP),
 1608         .func = ip_rcv,
 1609         .gso_send_check = inet_gso_send_check,
 1610         .gso_segment = inet_gso_segment,
 1611         .gro_receive = inet_gro_receive,
 1612         .gro_complete = inet_gro_complete,
 1613 };

これを見ると、ip_packet_type.funcはip_rcv()である事がわかる。
他の関数はGSOって言ってるのでオフロード関連のコードの筈。
typeは恐らく普通にプロトコル番号でしょう。

という事で、pt_prev->func()を呼ぶとip_rcv()が呼ばれる事が分かった。