网络子系统11_arp子系统初始化
// 1.邻居: // 网络中的邻居指连接到同一个LAN中,且至少有一个接口有相同的ip子网配置 // 2.邻居协议的作用: // 通过l3地址获取主机的l2地址 // 3.通过l3获取l2地址办法: // 3.1 点到点连接,此时不需要l2地址 // 3.2 特殊的l3地址,通过简单的规则获取l2的映射 // 3.3 多播地址通过简单的转换规则转换为l2地址 // 3.4 ip中使用arp协议完成映射 // arp协议的初始化 // 向内核邻居子系统注册arp地址解析协议。 // 调用路径:inet_init->arp_init // 函数主要任务: // 1. 注册arp协议 // 2. 初始化proc中相应的项 // 3. 向netdev_chain注册监听块 1.1 void __init arp_init(void) { //向通用邻居子系统注册arp协议 neigh_table_init(&arp_tbl); //注册一个l3协议 dev_add_pack(&arp_packet_type); //初始化proc文件系统中的对应项 arp_proc_init(); ... //系那个netdev_chain注册监听者 register_netdevice_notifier(&arp_netdev_notifier); } // arp协议表 // 参考 深入理解linux网络技术内幕 2.1 struct neigh_table arp_tbl = { .family = AF_INET,//协议所属的地址族 .entry_size = sizeof(struct neighbour) + 4,//多预留4个字节 .key_len = 4,//hash函数使用的key的长度,ip地址长度 .hash = arp_hash,//hash函数 .constructor = arp_constructor,//初始化struct neighbour的回调函数 .proxy_redo = parp_redo,//代理相关 .id = "arp_cache",//分配struct neighbour SLAB时,用于指定名字 .parms = { //默认提供一个调整邻居协议的控制块 .tbl = &arp_tbl, .base_reachable_time = 30 * HZ,//默认可到达性时间间隔基值 .retrans_time = 1 * HZ,//当一台主机在retrans_time时间间隔内没有收到solicitation请求的应答时,就会发出一个新的solicitation请求 .gc_staletime = 60 * HZ,//一个邻居项在gc_staletime时间还没有被用到,并且没有程序引用它,则它会被删除 .reachable_time = 30 * HZ,//由rand(0, base_reachable_time) + base_reachable_time/2计算 .delay_probe_time = 5 * HZ,//NUD_DELAY->NUD_PROBE的时间间隔 .queue_len = 3,//arp_queue队列中能容纳的元素最大数目 .ucast_probes = 3,//为证实一个地址的可到达性,能发送的单播solicitation数目量 .mcast_probes = 3,//为解析一个邻居地址,可以发出的多播solicitation请求数 .anycast_delay = 1 * HZ,//暂不使用 .proxy_delay = (8 * HZ) / 10,//代理相关 .proxy_qlen = 64, .locktime = 1 * HZ,//相邻两次对一个neighbour项字段更新时,必须经历的时间间隔 }, .gc_interval = 30 * HZ,//控制gc_timer定时器的超时时间 .gc_thresh1 = 128,//三个不同级别的内存状态 .gc_thresh2 = 512, .gc_thresh3 = 1024, }; // arp子系统对网络设备事件的监听控制块 2.1 static struct notifier_block arp_netdev_notifier = { .notifier_call = arp_netdev_event, }; // 网络设备事件的处理函数 // arp协议只处理到达此邻居项的接口设备地址改变消息。 2.2 static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr) { struct net_device *dev = ptr; //设备的硬件地址已改变 switch (event) { case NETDEV_CHANGEADDR: //通用例程 neigh_changeaddr(&arp_tbl, dev); //刷新路由缓存 rt_cache_flush(0); break; default: break; } return NOTIFY_DONE; }
最后更新:2017-04-03 15:21:56