zoukankan      html  css  js  c++  java
  • 邻居子系统 之 邻居表的初始化neigh_table_init

    概述

    邻居子系统支持多种实现,例如ARP,ND等,这些实现需要在其初始化的时候,调用neigh_table_init将邻居表项添加到全局邻居子系统数组中,并对实例中的字段(如hash,定时器等)进行相关初始化;

    源码分析

    分析过程以ARP为例,引出邻居表的初始化,在arp_init初始化中,调用neigh_table_init来进行邻居表的初始化;其中NEIGH_ARP_TABLE为ARP在全局邻居表数组中的索引值,arp_table则是邻居表的一个实例,里面包含了部分字段的初始化;

     1 void __init arp_init(void)
     2 {
     3     neigh_table_init(NEIGH_ARP_TABLE, &arp_tbl);
     4 
     5     dev_add_pack(&arp_packet_type);
     6     arp_proc_init();
     7 #ifdef CONFIG_SYSCTL
     8     neigh_sysctl_register(NULL, &arp_tbl.parms, NULL);
     9 #endif
    10     register_netdevice_notifier(&arp_netdev_notifier);
    11 }

    索引值是一个枚举类型,从中可见现在已经实现的邻居表项有哪些,其中NEIGH_ARP_TABLE排在第一位;

    1 enum {
    2     NEIGH_ARP_TABLE = 0,
    3     NEIGH_ND_TABLE = 1,
    4     NEIGH_DN_TABLE = 2,
    5     NEIGH_NR_TABLES,
    6     NEIGH_LINK_TABLE = NEIGH_NR_TABLES /* Pseudo table for neigh_xmit */
    7 };

    下面为ARP表项实例;

     1 struct neigh_table arp_tbl = {
     2     .family        = AF_INET,
     3     .key_len    = 4,
     4     .protocol    = cpu_to_be16(ETH_P_IP),
     5     .hash        = arp_hash,
     6     .key_eq        = arp_key_eq,
     7     .constructor    = arp_constructor,
     8     .proxy_redo    = parp_redo,
     9     .id        = "arp_cache",
    10     .parms        = {
    11         .tbl            = &arp_tbl,
    12         .reachable_time        = 30 * HZ,
    13         .data    = {
    14             [NEIGH_VAR_MCAST_PROBES] = 3,
    15             [NEIGH_VAR_UCAST_PROBES] = 3,
    16             [NEIGH_VAR_RETRANS_TIME] = 1 * HZ,
    17             [NEIGH_VAR_BASE_REACHABLE_TIME] = 30 * HZ,
    18             [NEIGH_VAR_DELAY_PROBE_TIME] = 5 * HZ,
    19             [NEIGH_VAR_GC_STALETIME] = 60 * HZ,
    20             [NEIGH_VAR_QUEUE_LEN_BYTES] = 64 * 1024,
    21             [NEIGH_VAR_PROXY_QLEN] = 64,
    22             [NEIGH_VAR_ANYCAST_DELAY] = 1 * HZ,
    23             [NEIGH_VAR_PROXY_DELAY]    = (8 * HZ) / 10,
    24             [NEIGH_VAR_LOCKTIME] = 1 * HZ,
    25         },
    26     },
    27     .gc_interval    = 30 * HZ,
    28     .gc_thresh1    = 128,
    29     .gc_thresh2    = 512,
    30     .gc_thresh3    = 1024,
    31 };

    每个邻居表实例都需要通过调用neigh_table_init进行初始化,并将其加入到全局邻居表数组中;函数首先对邻居表项中的参数进行初始化,其中包括了初始化邻居项hash和代理项hash,初始化垃圾回收GC任务和代理处理定时器任务,以及一些其他必要字段,最后将该邻居表项实例加入到全局数组neigh_tables中;

     1 void neigh_table_init(int index, struct neigh_table *tbl)
     2 {
     3     unsigned long now = jiffies;
     4     unsigned long phsize;
     5 
     6     /* 初始化参数列表 */
     7     INIT_LIST_HEAD(&tbl->parms_list);
     8     /* 将参数添加到参数列表 */
     9     list_add(&tbl->parms.list, &tbl->parms_list);
    10     /* 设置net */
    11     write_pnet(&tbl->parms.net, &init_net);
    12     /* 设置引用计数 */
    13     atomic_set(&tbl->parms.refcnt, 1);
    14     /* 设置可达状态的超时时间 */
    15     tbl->parms.reachable_time =
    16               neigh_rand_reach_time(NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME));
    17     /* 统计信息 */
    18     tbl->stats = alloc_percpu(struct neigh_statistics);
    19     if (!tbl->stats)
    20         panic("cannot create neighbour cache statistics");
    21 
    22     /* 初始化proc */
    23 #ifdef CONFIG_PROC_FS
    24     if (!proc_create_data(tbl->id, 0, init_net.proc_net_stat,
    25                   &neigh_stat_seq_fops, tbl))
    26         panic("cannot create neighbour proc dir entry");
    27 #endif
    28 
    29     /* 初始化邻居项hash */
    30     RCU_INIT_POINTER(tbl->nht, neigh_hash_alloc(3));
    31 
    32     /* 初始化代理项hash */
    33     phsize = (PNEIGH_HASHMASK + 1) * sizeof(struct pneigh_entry *);
    34     tbl->phash_buckets = kzalloc(phsize, GFP_KERNEL);
    35 
    36     if (!tbl->nht || !tbl->phash_buckets)
    37         panic("cannot allocate neighbour cache hashes");
    38 
    39     /* 邻居项的结构大小 */
    40     if (!tbl->entry_size)
    41         tbl->entry_size = ALIGN(offsetof(struct neighbour, primary_key) +
    42                     tbl->key_len, NEIGH_PRIV_ALIGN);
    43     else
    44         WARN_ON(tbl->entry_size % NEIGH_PRIV_ALIGN);
    45 
    46     rwlock_init(&tbl->lock);
    47     /* gc任务初始化 */
    48     INIT_DEFERRABLE_WORK(&tbl->gc_work, neigh_periodic_work);
    49     queue_delayed_work(system_power_efficient_wq, &tbl->gc_work,
    50             tbl->parms.reachable_time);
    51 
    52     /* 代理定时器处理初始化 */
    53     setup_timer(&tbl->proxy_timer, neigh_proxy_process, (unsigned long)tbl);
    54     skb_queue_head_init_class(&tbl->proxy_queue,
    55             &neigh_table_proxy_queue_class);
    56 
    57     /* 初始化最近一次gc的时间 */
    58     tbl->last_flush = now;
    59     /* 初始化最近一次可达状态reachable_time的更新时间 */
    60     tbl->last_rand    = now + tbl->parms.reachable_time * 20;
    61 
    62     /* 加入全局邻居项数组 */
    63     neigh_tables[index] = tbl;
    64 }
  • 相关阅读:
    mysql高可用研究(二) 主从+MHA+Atlas
    zabbix实现mysql数据库的监控(一)
    Redis数据类型
    zabbix实现mysql数据库的监控(二)
    zabbix实现mysql数据库的监控(三)
    9.SpringMVC注解式开发-处理器的请求映射规则的定义
    8.SpringMVC注解式开发-HelloWorld
    7.SpringMVC 配置式开发-ModelAndView和视图解析器
    6.SpringMVC 配置式开发-处理器
    5.SpringMVC 配置式开发-处理器适配器
  • 原文地址:https://www.cnblogs.com/wanpengcoder/p/11755380.html
Copyright © 2011-2022 走看看