标签:linux route policy routing fib 负载均衡
上篇我们讲到了,如何匹配策略,得到一个路由表,其实在 rib_rule 里,存的是该策略所使用的路由表的索引,这里顺便解释一下 FIB (Forward Infomation Base), 即转发信息数据库,即相当于路由表。子网掩码长度相同的路由项,由 fn_zone 表示,并进行散列。想想现在进行到哪里了,确定了路由表,然后开始从子网掩码最长的子网匹配,确定目标主机与哪个子网匹配,所以根据目标主机的 IP 与此时的掩码长度可以得到与它匹配的子网。看代码:
static int fn_hash_lookup(struct fib_table *tb, const struct flowi *flp, struct fib_result *res) { int err; struct fn_zone *fz; struct fn_hash *t = (struct fn_hash*)tb->tb_data; read_lock(&fib_hash_lock); for (fz = t->fn_zone_list; fz; fz = fz->fz_next) { struct hlist_head *head; struct hlist_node *node; struct fib_node *f; __be32 k = fz_key(flp->fl4_dst, fz); head = &fz->fz_hash[fn_hash(k, fz)]; hlist_for_each_entry(f, node, head, fn_hash) { if (f->fn_key != k) continue; err = fib_semantic_match(&f->fn_alias, flp, res, f->fn_key, fz->fz_mask, fz->fz_order); if (err <= 0) goto out; } } err = 1; out: read_unlock(&fib_hash_lock); return err; }
int fib_semantic_match(struct list_head *head, const struct flowi *flp, struct fib_result *res, __be32 zone, __be32 mask, int prefixlen) { struct fib_alias *fa; int nh_sel = 0; list_for_each_entry_rcu(fa, head, fa_list) { int err; if (fa->fa_tos && fa->fa_tos != flp->fl4_tos) continue; if (fa->fa_scope < flp->fl4_scope) continue; fa->fa_state |= FA_S_ACCESSED; err = fib_props[fa->fa_type].error; if (err == 0) { struct fib_info *fi = fa->fa_info; if (fi->fib_flags & RTNH_F_DEAD) continue; switch (fa->fa_type) { case RTN_UNICAST: case RTN_LOCAL: case RTN_BROADCAST: case RTN_ANYCAST: case RTN_MULTICAST: for_nexthops(fi) { if (nh->nh_flags&RTNH_F_DEAD) continue; if (!flp->oif || flp->oif == nh->nh_oif) break; } #ifdef CONFIG_IP_ROUTE_MULTIPATH if (nhsel < fi->fib_nhs) { nh_sel = nhsel; goto out_fill_res; } #else if (nhsel < 1) { goto out_fill_res; } #endif endfor_nexthops(fi); continue; default: printk(KERN_WARNING "fib_semantic_match bad type %#x\n", fa->fa_type); return -EINVAL; } } return err; } return 1; out_fill_res: res->prefixlen = prefixlen; res->nh_sel = nh_sel; res->type = fa->fa_type; res->scope = fa->fa_scope; res->fi = fa->fa_info; atomic_inc(&res->fi->fib_clntref); return 0; }
u32 tos = RT_FL_TOS(oldflp); struct flowi fl = { .nl_u = { .ip4_u = { .daddr = oldflp->fl4_dst, .saddr = oldflp->fl4_src, .tos = tos & IPTOS_RT_MASK, .scope = ((tos & RTO_ONLINK) ? RT_SCOPE_LINK : RT_SCOPE_UNIVERSE), } }, .mark = oldflp->mark, .iif = net->loopback_dev->ifindex, .oif = oldflp->oif };
标签:linux route policy routing fib 负载均衡
原文地址:http://blog.csdn.net/henzox/article/details/43566787