ARP - 内核设计与实现
参考资料:
http://www.saminiir.com/lets-code-tcp-ip-stack-1-ethernet-arp/
rfc 826
ARP 分成三个部分:
* 输出模块
* 输入模块
* 高速缓存管理程序: 轮循表项,删除已经过期的表项。
设计原则:
* 单一的ARP高速缓存
* 全局替换策略
* 高速缓存中的超时与删除
* 分组多队列的形式等待与发送
* 互斥访问
数据结构 neighbor include/net/neighbour.h
struct neighbour { struct neighbour __rcu *next; // 邻居表散列表中下一个 struct neigh_table *tbl; // 邻居表 struct neigh_parms *parms; // 邻居对象 unsigned long confirmed; // 确认时间 unsigned long updated; // rwlock_t lock; refcount_t refcnt; // 引用计数器 neigh_hold() 会增1,neigh_release()减1, 当为0时,neigh_release会调用neigh_destroy()释放 struct sk_buff_head arp_queue; unsigned int arp_queue_len_bytes; struct timer_list timer; // 时间定时器 unsigned long used; // atomic_t probes; __u8 flags; __u8 nud_state; // 邻居NUD状态 __u8 type; __u8 dead; // 活动状态时设置 seqlock_t ha_lock; // 对邻居硬件地址进行保护 unsigned char ha[ALIGN(MAX_ADDR_LEN, sizeof(unsigned long))]; // 邻居mac地址 struct hh_cache hh; // L2报头的硬件报头缓存 int (*output)(struct neighbour *, struct sk_buff *); // 一个指向传输方法 neigh_resolv_output() neigh_direct_output() const struct neigh_ops *ops; struct rcu_head rcu; struct net_device *dev; u8 primary_key[0]; // 邻居IP地址 } __randomize_layout;
数据结构ARP表 neigh_table include/net/neighbour.h
struct neigh_table { int family; // 协议 AF_INET 或者 AF_INET6 int entry_size; // neigh_alloc() 分配邻居条目,分配的空间tbl->entry_size + dev->neigh_priv_len int key_len; // 查找键长度 __be16 protocol; __u32 (*hash)(const void *pkey, const struct net_device *dev, __u32 *hash_rnd); bool (*key_eq)(const struct neighbour *, const void *pkey); int (*constructor)(struct neighbour *); int (*pconstructor)(struct pneigh_entry *); void (*pdestructor)(struct pneigh_entry *); void (*proxy_redo)(struct sk_buff *skb); char *id; // arp 表的名称 struct neigh_parms parms; struct list_head parms_list; int gc_interval; int gc_thresh1; int gc_thresh2; int gc_thresh3; unsigned long last_flush; // 最近一次运行方法neigh_forced_gc 时间 struct delayed_work gc_work; struct timer_list proxy_timer; struct sk_buff_head proxy_queue; atomic_t entries; rwlock_t lock; unsigned long last_rand; struct neigh_statistics __percpu *stats; struct neigh_hash_table __rcu *nht; // 邻居散列表 struct pneigh_entry **phash_buckets; };
ARP表初始化
void neigh_table_init(int index, struct neigh_table *tbl);
创建与释放邻居
struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey, struct net_device *dev, bool want_ref);
static inline struct neighbour *neigh_create(struct neigh_table *tbl, const void *pkey, struct net_device *dev) { return __neigh_create(tbl, pkey, dev, true); }
用户空间与邻接子系统交互
iproute2/ip neigh 模块
删除arp表项中的项
int arpdelete(const char *, const char *);
搜索ARP表 int arpsearch(FILE *, char *, in_addr_t addr, void (*action)(FILE *, char *, struct sockaddr_dl *sdl, struct sockaddr_inarp *sin, struct rt_msghdr *rtm));
打印entry void print_entry(FILE *, char *, struct sockaddr_dl *sdl, struct sockaddr_inarp *sin, struct rt_msghdr *rtm);
// 配置arp表项 void conf_arp_entry(FILE *, char *, struct sockaddr_dl *, struct sockaddr_inarp *, struct rt_msghdr *);
获取 邻居地址
int getinetaddr(const char *, struct in_addr *);
发送arp消息 int rtmsg_arp(int, int, int, int);

浙公网安备 33010602011771号