路由1【转载: route 源码分析之路由表初始化 】
1 开始学习Linux路由。管他对不对先从此函数开始: 2 3 void __init ip_fib_init(void) 4 { 5 /*注册与路由相关的rtnetlink 消息以及他的处理函数,主要处理路由添加删除*/ 6 rtnl_register(PF_INET, RTM_NEWROUTE, inet_rtm_newroute, NULL); 7 rtnl_register(PF_INET, RTM_DELROUTE, inet_rtm_delroute, NULL); 8 rtnl_register(PF_INET, RTM_GETROUTE, NULL, inet_dump_fib); 9 10 /*注册协议栈子系统,也就是路由系统。 重点--fib_net_ops*/ 11 register_pernet_subsys(&fib_net_ops); 12 13 /*register a network notifier block,主要是设备状态改变*/ 14 register_netdevice_notifier(&fib_netdev_notifier); 15 /*修改设备的配置--IP地址*/ 16 register_inetaddr_notifier(&fib_inetaddr_notifier); 17 18 /*为 fib_alias 和 fib_node 分配缓存*/ 19 fib_hash_init(); 20 } 21 22 蓝色的字体的部分还在ip_rt_init函数中注册过。针对一个消息注册了两个不同的处理函数,注册函数原型: 23 void rtnl_register(int protocol, int msgtype, 24 rtnl_doit_func doit, rtnl_dumpit_func dumpit) 25 26 忽略子系统这个东东,看一下fib_net_ops这个玩意: 27 定义: 28 struct pernet_operations { 29 struct list_head list; 30 int (*init)(struct net *net); 31 void (*exit)(struct net *net); 32 }; 33 初始化: 34 static struct pernet_operations fib_net_ops = { 35 .init = fib_net_init, 36 .exit = fib_net_exit, 37 }; 38 39 看来是函数指针,不用说这两个函数就是初始化和注销路由子系统的。Go on... 40 static int __net_init fib_net_init(struct net *net) 41 { 42 int error; 43 44 error = ip_fib_net_init(net); 45 if (error < 0) 46 goto out; 47 /*创建内核的netlink sock?, 暂时跳过*/ 48 error = nl_fib_lookup_init(net); 49 if (error < 0) 50 goto out_nlfl; 51 52 /*创建初始化proc文件系统, 跳过*/ 53 error = fib_proc_init(net); 54 if (error < 0) 55 goto out_proc; 56 out: 57 return error; 58 59 out_proc: 60 nl_fib_lookup_exit(net); 61 out_nlfl: 62 ip_fib_net_exit(net); 63 goto out; 64 } 65 66 没处下手,一个挨着一个看吧。不过多出来个net。看一下定义吧: 67 struct net { 68 atomic_t count; /* To decided when the network 69 * namespace should be freed. 70 */ 71 #ifdef NETNS_REFCNT_DEBUG 72 atomic_t use_count; /* To track references we 73 * destroy on demand 74 */ 75 #endif 76 struct list_head list; /* list of network namespaces */ 77 struct work_struct work; /* work struct for freeing */ 78 79 struct proc_dir_entry *proc_net; 80 struct proc_dir_entry *proc_net_stat; 81 82 #ifdef CONFIG_SYSCTL 83 struct ctl_table_set sysctls; 84 #endif 85 86 struct net_device *loopback_dev; /* The loopback */ 87 88 struct list_head dev_base_head; 89 struct hlist_head *dev_name_head; 90 struct hlist_head *dev_index_head; 91 92 /* core fib_rules */ 93 struct list_head rules_ops; 94 spinlock_t rules_mod_lock; 95 96 struct sock *rtnl; /* rtnetlink socket */ 97 98 struct netns_core core; 99 struct netns_mib mib; 100 struct netns_packet packet; 101 struct netns_unix unx; 102 struct netns_ipv4 ipv4; 103 #if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE) 104 struct netns_ipv6 ipv6; 105 #endif 106 #if defined(CONFIG_IP_DCCP) || defined(CONFIG_IP_DCCP_MODULE) 107 struct netns_dccp dccp; 108 #endif 109 #ifdef CONFIG_NETFILTER 110 struct netns_xt xt; 111 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE) 112 struct netns_ct ct; 113 #endif 114 #endif 115 #ifdef CONFIG_XFRM 116 struct netns_xfrm xfrm; 117 #endif 118 struct net_generic *gen; 119 }; 120 121 感觉很多东西都包在其中,是个大家伙。与路由关系密切。尤其是struct netns_ipv4 ipv4;。继续。 122 static int __net_init ip_fib_net_init(struct net *net) 123 { 124 int err; 125 unsigned int i; 126 127 /*终于出现表了256大小的hash表,其实每个hash表对应256个路由表*/ 128 net->ipv4.fib_table_hash = kzalloc( 129 sizeof(struct hlist_head)*FIB_TABLE_HASHSZ, GFP_KERNEL); 130 if (net->ipv4.fib_table_hash == NULL) 131 return -ENOMEM; 132 133 /*初始化每个hash表的冲突链*/ 134 for (i = 0; i < FIB_TABLE_HASHSZ; i++) 135 INIT_HLIST_HEAD(&net->ipv4.fib_table_hash[i]); 136 137 /*有了256个表,就得提一提Linux的查找路由表的规则, 也就是策略路由ip rule add/del ...*/ 138 err = fib4_rules_init(net); 139 if (err < 0) 140 goto fail; 141 return 0; 142 143 fail: 144 kfree(net->ipv4.fib_table_hash); 145 return err; 146 } 147 148 /*有两个同名函数,我选择支持策略路由的这个函数*/ 149 int __net_init fib4_rules_init(struct net *net) 150 { 151 int err; 152 struct fib_rules_ops *ops; 153 154 /*给ops分配空间,并以fib4_rules_ops_template初始化ops*/ 155 ops = kmemdup(&fib4_rules_ops_template, sizeof(*ops), GFP_KERNEL); 156 if (ops == NULL) 157 return -ENOMEM; 158 INIT_LIST_HEAD(&ops->rules_list); 159 ops->fro_net = net; 160 161 /*把协议族不同的路由表规则链起来, 上一句的赋值ops->fro_net = net 泄漏了他要把这些个玩意 链到哪里 struct list_head rules_ops;*/ 162 fib_rules_register(ops); 163 164 /*创建三个最基本的路由表local,main,default的规则表*/ 165 err = fib_default_rules_init(ops); 166 if (err < 0) 167 goto fail; 168 net->ipv4.rules_ops = ops; 169 return 0; 170 171 fail: 172 /* also cleans all rules already added */ 173 fib_rules_unregister(ops); 174 kfree(ops); 175 return err; 176 } 177 178 看一下 179 struct fib_rules_ops 180 { 181 int family; 182 struct list_head list; 183 int rule_size; 184 int addr_size; 185 int unresolved_rules; 186 int nr_goto_rules; 187 188 int (*action)(struct fib_rule *, 189 struct flowi *, int, 190 struct fib_lookup_arg *); 191 int (*match)(struct fib_rule *, 192 struct flowi *, int); 193 int (*configure)(struct fib_rule *, 194 struct sk_buff *, 195 struct nlmsghdr *, 196 struct fib_rule_hdr *, 197 struct nlattr **); 198 int (*compare)(struct fib_rule *, 199 struct fib_rule_hdr *, 200 struct nlattr **); 201 int (*fill)(struct fib_rule *, struct sk_buff *, 202 struct nlmsghdr *, 203 struct fib_rule_hdr *); 204 u32 (*default_pref)(struct fib_rules_ops *ops); 205 size_t (*nlmsg_payload)(struct fib_rule *); 206 207 /* Called after modifications to the rules set, must flush 208 * the route cache if one exists. */ 209 void (*flush_cache)(struct fib_rules_ops *ops); 210 211 int nlgroup; 212 const struct nla_policy *policy; 213 /*针对各个路由表的规则链表*/ 214 struct list_head rules_list; 215 struct module *owner; 216 /*net 和 ops之间的关系*/ 217 struct net *fro_net; 218 }; 219 220 看一下模板的初始值: 221 static struct fib_rules_ops fib4_rules_ops_template = { 222 .family = AF_INET, 223 .rule_size = sizeof(struct fib4_rule), 224 .addr_size = sizeof(u32), 225 .action = fib4_rule_action, 226 .match = fib4_rule_match, 227 .configure = fib4_rule_configure, 228 .compare = fib4_rule_compare, 229 .fill = fib4_rule_fill, 230 .default_pref = fib4_rule_default_pref, 231 .nlmsg_payload = fib4_rule_nlmsg_payload, 232 .flush_cache = fib4_rule_flush_cache, 233 .nlgroup = RTNLGRP_IPV4_RULE, 234 .policy = fib4_rule_policy, 235 .owner = THIS_MODULE, 236 }; 237 238 static int fib_default_rules_init(struct fib_rules_ops *ops) 239 { 240 int err; 241 242 /*规则表都链入ops的rules_list,用路由表的id把表和规则联系起来*/ 243 err = fib_default_rule_add(ops, 0, RT_TABLE_LOCAL, FIB_RULE_PERMANENT); 244 if (err < 0) 245 return err; 246 err = fib_default_rule_add(ops, 0x7FFE, RT_TABLE_MAIN, 0); 247 if (err < 0) 248 return err; 249 err = fib_default_rule_add(ops, 0x7FFF, RT_TABLE_DEFAULT, 0); 250 if (err < 0) 251 return err; 252 return 0; 253 } 254 255 没找见路由表在哪初始化!!!