注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

TCP/IP驱动十三 ——内核中的路由3  

2013-09-11 21:01:07|  分类: TCPIP驱动 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

TCP/IP驱动十三  ——内核中的路由3

在路由中有很多的细节,需要你知道路由的方式,这个东西跟编程没有关系,是需要懂得路由的知识,才可以和代码更好的结合。在下面的代码讲述过程中,会穿插一些这方面的知识,以利于大家的理解。

static int fib_get_nhs(struct fib_info *fi, struct rtnexthop *rtnh,

                          int remaining, struct fib_config *cfg)

{

         change_nexthops(fi) {

                   int attrlen;

 

                   if (!rtnh_ok(rtnh, remaining))

                            return -EINVAL;

 

                   nh->nh_flags = (cfg->fc_flags & ~0xFF) | rtnh->rtnh_flags;

                   nh->nh_oif = rtnh->rtnh_ifindex;

                   nh->nh_weight = rtnh->rtnh_hops + 1;

 

                   attrlen = rtnh_attrlen(rtnh);

                   if (attrlen > 0) {

                            struct nlattr *nla, *attrs = rtnh_attrs(rtnh);

 

                            nla = nla_find(attrs, attrlen, RTA_GATEWAY);

                            nh->nh_gw = nla ? nla_get_be32(nla) : 0;

#ifdef CONFIG_NET_CLS_ROUTE

                            nla = nla_find(attrs, attrlen, RTA_FLOW);

                            nh->nh_tclassid = nla ? nla_get_u32(nla) : 0;

#endif

                   }

 

                   rtnh = rtnh_next(rtnh, &remaining);

         } endfor_nexthops(fi);

 

         return 0;

}

上面用到了下面的两个函数:

static inline struct nlattr *rtnh_attrs(const struct rtnexthop *rtnh)

{

         return (struct nlattr *) ((char *) rtnh + NLA_ALIGN(sizeof(*rtnh)));

}

 

static inline int rtnh_attrlen(const struct rtnexthop *rtnh)

{

         return rtnh->rtnh_len - NLA_ALIGN(sizeof(*rtnh));

}

看上面代码的红色部分,这个很简单,但是却挺重要,在内核中经常利用这种指针的方式来分配连续的不同的数据空间。然后通过计算不同的结构体占用的空间大小来取得实际的数量。这里需要说明的是,通过attrlen可以得到renexthop这个跳转结构后的nlattr数量大小,并通过后面的代码来得到其相应的信息并存储到fib_nh这个结体中,在上一节也谈到过类似问题,这里重新提的重点是renexthop这个结构体后面的属性结构体nlattr是可以有多个 的。

struct fib_info *fib_create_info(struct fib_config *cfg)

{

….以下从796行开始

         if (cfg->fc_scope > RT_SCOPE_HOST)

                   goto err_inval;

 

         if (cfg->fc_scope == RT_SCOPE_HOST) {

                   struct fib_nh *nh = fi->fib_nh;

 

                   /* Local address is added. */

//1、本地路由只需要一跳,即使开启多路由下一跳也只为1

//2、本地路由是不需要指定网关的。

                   if (nhs != 1 || nh->nh_gw)

                            goto err_inval;

                   nh->nh_scope = RT_SCOPE_NOWHERE;

                   nh->nh_dev = dev_get_by_index(net, fi->fib_nh->nh_oif);

                   err = -ENODEV;

                   if (nh->nh_dev == NULL)

                            goto failure;

         } else {

                   change_nexthops(fi) {

                            if ((err = fib_check_nh(cfg, fi, nh)) != 0)

                                     goto failure;

                   } endfor_nexthops(fi)

         }

…….

}

在这个函数中同样变红的代码部分,是内核中的一个枚举体:

/* rtm_scope

 

   Really it is not scope, but sort of distance to the destination.

   NOWHERE are reserved for not existing destinations, HOST is our

   local addresses, LINK are destinations, located on directly attached

   link and UNIVERSE is everywhere in the Universe.

 

   Intermediate values are also possible f.e. interior routes

   could be assigned a value between UNIVERSE and LINK.

*/

 

enum rt_scope_t

{

         RT_SCOPE_UNIVERSE=0, 非直连,需要下一个网关

/* User defined values  */

         RT_SCOPE_SITE=200,本地封闭的一个内部路由

         RT_SCOPE_LINK=253,  路由为本地网络

         RT_SCOPE_HOST=254, 路由为本机接口(回环网),由fib_add_ifaddr自动添加

         RT_SCOPE_NOWHERE=255  不可到达

};

大家应该一看就明白了,这个是一个跳转范围的东西(其实是一个跳转范围的类型更合适)。在上面的代码中,大家如果不明白这几个值的意义,就比较麻烦了。在路由过程中,如果不可到达那就不用再向下走了,都到达不了,还有啥意义可言,这就是上面fib_create_info代码第一行的意义。同样如果是本机了,那么也就不用再找了,所以直接在路由跳转信息结构fib_nh中设置其SCOPE为不可到达。不要没事浪费宝贵的CPU的时间和精力。

这样就可以比较轻松的解决的路由的问题。

时间紧张啊,太紧张了,得挤一挤。

  评论这张
 
阅读(825)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017