linux 路由表 fib,linux内核 路由fib表之创建

2.2.2 路由创建

当通过netlink,操作类型为RTM_NEWROUTE时,调用inet_rtm_newroute函数添加路由。

功能:

a)、将用户空间配置内容传过来

b)、路由表的创建

c)、路由表项的添加

流程:

cd8aeb3ffceb45e51f122f22b61ae3b9.png

代码:

static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)

//其中nlh为配置路由的参数,有目的地址、掩码长度、路由表table_id、网关地址等。

{

struct net *net = sock_net(skb->sk);

struct fib_config cfg;

struct fib_table *tb;

int err;

err = rtm_to_fib_config(net, skb, nlh, &cfg); //将netlink传递的消息nlh赋值给fib_config cfg

if (err < 0)

goto errout;

tb = fib_new_table(net, cfg.fc_table); //根据给定路由表ID,获取路由表

if (tb == NULL) {

err = -ENOBUFS;

goto errout;

}

err = tb->tb_insert(tb, &cfg); //获取路由表后,通过insert创建路由表项并添到该路由表

errout:

return err;

}

2.2.2.1 接收用户空间消息

rtm_to_fib_config(net, skb, nlh, &cfg)用于将nlh内容,传递到cfg中。

static int rtm_to_fib_config(struct net *net, struct sk_buff *skb,

struct nlmsghdr *nlh, struct fib_config *cfg)

{

struct nlattr *attr;

int err, remaining;

struct rtmsg *rtm;

err=nlmsg_validate(nlh, sizeof(*rtm), RTA_MAX, rtm_ipv4_policy);

if (err < 0)

goto errout;

memset(cfg, 0, sizeof(*cfg));

//跳过nlh的硬件头部,让rtm指向nlh的内容,即将nlh赋值给rtm

rtm= nlmsg_data(nlh);

//将rtm的内容,赋值给cfg

cfg->fc_dst_len = rtm->rtm_dst_len; //掩码长度

cfg->fc_tos = rtm->rtm_tos; //好像是默认为0

cfg->fc_table = rtm->rtm_table; //路由表id: connected为0;kernel route为255 //如果id为0,kernel会将id设为254

cfg->fc_protocol = rtm->rtm_protocol; //协议类型:connected和kernel route都为11

cfg->fc_scope = rtm->rtm_scope; //范围:connected为253;kernel route为254

cfg->fc_type = rtm->rtm_type; //类型:connected为1;kernel route为2

cfg->fc_flags = rtm->rtm_flags; //connected和kernel route都为1024

cfg->fc_nlflags = nlh->nlmsg_flags;

cfg->fc_nlinfo.pid = NETLINK_CB(skb).pid;

cfg->fc_nlinfo.nlh = nlh;

cfg->fc_nlinfo.nl_net = net;

if (cfg->fc_type > RTN_MAX) {

err = -EINVAL;

goto errout;

}

nlmsg_for_each_attr(attr, nlh, sizeof(struct rtmsg), remaining) {

switch (nla_type(attr)) {

case RTA_DST:

cfg->fc_dst = nla_get_be32(attr);

break;

case RTA_OIF:

cfg->fc_oif = nla_get_u32(attr);

break;

case RTA_GATEWAY:

cfg->fc_gw =nla_get_be32(attr);

break;

case RTA_PRIORITY:

cfg->fc_priority = nla_get_u32(attr);

break;

case RTA_PREFSRC:

cfg->fc_prefsrc = nla_get_be32(attr);

break;

case RTA_METRICS:

cfg->fc_mx = nla_data(attr);

cfg->fc_mx_len = nla_len(attr);

break;

case RTA_MULTIPATH:

cfg->fc_mp = nla_data(attr);

cfg->fc_mp_len = nla_len(attr);

break;

case RTA_FLOW:

cfg->fc_flow = nla_get_u32(attr);

break;

case RTA_TABLE:

cfg->fc_table = nla_get_u32(attr);

break;

}

}

return 0;<


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部