zoukankan      html  css  js  c++  java
  • 邻居子系统 之 输出

    概述

    neigh_hh_output-缓存输出,直接拷贝二层头部,然后输出;

    neigh_connected_output-快速输出,用于连接状态的输出;需要重新构建二层头部,然后输出;

    neigh_resolve_output-慢速输出,用于非连接状态的输出;需要对邻居项状态进行检查,然后重新构造二层头部,最后输出;

    neigh_direct_output-直接输出,用于没有二层头部时的输出;

    源码分析
     1 /* 拷贝缓存的二层头部,输出 */
     2 static inline int neigh_hh_output(const struct hh_cache *hh, struct sk_buff *skb)
     3 {
     4     unsigned int seq;
     5     unsigned int hh_len;
     6 
     7     /* 拷贝二层头到skb */
     8     do {
     9         seq = read_seqbegin(&hh->hh_lock);
    10         hh_len = hh->hh_len;
    11         /* 二层头部<DATA_MOD,直接使用该长度拷贝 */
    12         if (likely(hh_len <= HH_DATA_MOD)) {
    13             /* this is inlined by gcc */
    14             memcpy(skb->data - HH_DATA_MOD, hh->hh_data, HH_DATA_MOD);
    15         } 
    16         /* >=DATA_MOD,对齐头部,拷贝 */
    17         else {
    18             unsigned int hh_alen = HH_DATA_ALIGN(hh_len);
    19 
    20             memcpy(skb->data - hh_alen, hh->hh_data, hh_alen);
    21         }
    22     } while (read_seqretry(&hh->hh_lock, seq));
    23 
    24     skb_push(skb, hh_len);
    25 
    26     /* 发送 */
    27     return dev_queue_xmit(skb);
    28 }
     1 /* CONNECTED状态的发送函数,没有neigh_hh_output快,这个需要重建二层头 */
     2 int neigh_connected_output(struct neighbour *neigh, struct sk_buff *skb)
     3 {
     4     struct net_device *dev = neigh->dev;
     5     unsigned int seq;
     6     int err;
     7 
     8     /* 拷贝二层头 */
     9     do {
    10         __skb_pull(skb, skb_network_offset(skb));
    11         seq = read_seqbegin(&neigh->ha_lock);
    12         err = dev_hard_header(skb, dev, ntohs(skb->protocol),
    13                       neigh->ha, NULL, skb->len);
    14     } while (read_seqretry(&neigh->ha_lock, seq));
    15 
    16     /* 发送数据包 */
    17     if (err >= 0)
    18         err = dev_queue_xmit(skb);
    19     else {
    20         err = -EINVAL;
    21         kfree_skb(skb);
    22     }
    23     return err;
    24 }
     1 /* 非CONNECTED状态的慢速发送 */
     2 int neigh_resolve_output(struct neighbour *neigh, struct sk_buff *skb)
     3 {
     4     int rc = 0;
     5 
     6     /* 检测邻居项状态有效性 */
     7     if (!neigh_event_send(neigh, skb)) {
     8         int err;
     9         struct net_device *dev = neigh->dev;
    10         unsigned int seq;
    11 
    12         /* 有二层头缓存函数,则缓存之 */
    13         if (dev->header_ops->cache && !neigh->hh.hh_len)
    14             neigh_hh_init(neigh);
    15 
    16         /* 填充二层头 */
    17         do {
    18             __skb_pull(skb, skb_network_offset(skb));
    19             seq = read_seqbegin(&neigh->ha_lock);
    20             err = dev_hard_header(skb, dev, ntohs(skb->protocol),
    21                           neigh->ha, NULL, skb->len);
    22         } while (read_seqretry(&neigh->ha_lock, seq));
    23 
    24         /* 数据包发送 */
    25         if (err >= 0)
    26             rc = dev_queue_xmit(skb);
    27         else
    28             goto out_kfree_skb;
    29     }
    30 out:
    31     return rc;
    32 out_kfree_skb:
    33     rc = -EINVAL;
    34     kfree_skb(skb);
    35     goto out;
    36 }
    1 int neigh_direct_output(struct neighbour *neigh, struct sk_buff *skb)
    2 {
    3     return dev_queue_xmit(skb);
    4 }
  • 相关阅读:
    UVALive 5983 MAGRID DP
    2015暑假训练(UVALive 5983
    poj 1426 Find The Multiple (BFS)
    poj 3126 Prime Path (BFS)
    poj 2251 Dungeon Master 3维bfs(水水)
    poj 3278 catch that cow BFS(基础水)
    poj3083 Children of the Candy Corn BFS&&DFS
    BZOJ1878: [SDOI2009]HH的项链 (离线查询+树状数组)
    洛谷P3178 [HAOI2015]树上操作(dfs序+线段树)
    洛谷P3065 [USACO12DEC]第一!First!(Trie树+拓扑排序)
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11755409.html
Copyright © 2011-2022 走看看