⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dn_fib.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
link_it:	if ((ofi = dn_fib_find_info(fi)) != NULL) {		fi->fib_dead = 1;		dn_fib_free_info(fi);		ofi->fib_treeref++;		return ofi;	}	fi->fib_treeref++;	atomic_inc(&fi->fib_clntref);	write_lock(&dn_fib_info_lock);	fi->fib_next = dn_fib_info_list;	fi->fib_prev = NULL;	if (dn_fib_info_list)		dn_fib_info_list->fib_prev = fi;	dn_fib_info_list = fi;	dn_fib_info_cnt++;	write_unlock(&dn_fib_info_lock);	return fi;err_inval:	err = -EINVAL;failure:	*errp = err;	if (fi) {		fi->fib_dead = 1;		dn_fib_free_info(fi);	}	return NULL;}void dn_fib_select_multipath(const struct dn_fib_key *key, struct dn_fib_res *res){	struct dn_fib_info *fi = res->fi;	int w;	if (fi->fib_power <= 0) {		int power = 0;		change_nexthops(fi) {			if (!(nh->nh_flags&RTNH_F_DEAD)) {				power += nh->nh_weight;				nh->nh_power = nh->nh_weight;			}		} endfor_nexthops(fi);		fi->fib_power = power;	}	w = jiffies % fi->fib_power;	change_nexthops(fi) {		if (!(nh->nh_flags&RTNH_F_DEAD) && nh->nh_power) {			if ((w -= nh->nh_power) <= 0) {				nh->nh_power--;				fi->fib_power--;				res->nh_sel = nhsel;				return;			}		}	} endfor_nexthops(fi);	printk(KERN_DEBUG "DECnet: BUG! dn_fib_select_multipath\n");}/* * Punt to user via netlink for example, but for now * we just drop it. */int dn_fib_rt_message(struct sk_buff *skb){	kfree_skb(skb);	return 0;}#ifdef CONFIG_RTNETLINKstatic int dn_fib_check_attr(struct rtmsg *r, struct rtattr **rta){	int i;	for(i = 1; i <= RTA_MAX; i++) {		struct rtattr *attr = rta[i-1];		if (attr) {			if (RTA_PAYLOAD(attr) < 4 && RTA_PAYLOAD(attr) != 2)				return -EINVAL;			if (i != RTA_MULTIPATH && i != RTA_METRICS)				rta[i-1] = (struct rtattr *)RTA_DATA(attr);		}	}	return 0;}int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg){	struct dn_fib_table *tb;	struct rtattr **rta = arg;	struct rtmsg *r = NLMSG_DATA(nlh);	if (dn_fib_check_attr(r, rta))		return -EINVAL;	tb = dn_fib_get_table(r->rtm_table, 0);	if (tb)		return tb->delete(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb));	return -ESRCH;}int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg){	struct dn_fib_table *tb;	struct rtattr **rta = arg;	struct rtmsg *r = NLMSG_DATA(nlh);	if (dn_fib_check_attr(r, rta))		return -EINVAL;	tb = dn_fib_get_table(r->rtm_table, 1);	if (tb) 		return tb->insert(tb, r, (struct dn_kern_rta *)rta, nlh, &NETLINK_CB(skb));	return -ENOBUFS;}int dn_fib_dump(struct sk_buff *skb, struct netlink_callback *cb){	int t;	int s_t;	struct dn_fib_table *tb;	if (NLMSG_PAYLOAD(cb->nlh, 0) >= sizeof(struct rtmsg) &&		((struct rtmsg *)NLMSG_DATA(cb->nlh))->rtm_flags&RTM_F_CLONED)			return dn_cache_dump(skb, cb);	s_t = cb->args[0];	if (s_t == 0)		s_t = cb->args[0] = DN_MIN_TABLE;	for(t = s_t; t < DN_NUM_TABLES; t++) {		if (t < s_t)			continue;		if (t > s_t)			memset(&cb->args[1], 0, sizeof(cb->args)-sizeof(int));		tb = dn_fib_get_table(t, 0);		if (tb == NULL)			continue;		if (tb->dump(tb, skb, cb) < 0)			break;	}	cb->args[0] = t;	return skb->len;}#endif /* CONFIG_RTNETLINK */int dn_fib_sync_down(dn_address local, struct net_device *dev, int force){        int ret = 0;        int scope = RT_SCOPE_NOWHERE;        if (force)                scope = -1;        for_fib_info() {                /*                  * This makes no sense for DECnet.... we will almost                 * certainly have more than one local address the same                 * over all our interfaces. It needs thinking about                 * some more.                 */                if (local && fi->fib_prefsrc == local) {                        fi->fib_flags |= RTNH_F_DEAD;                        ret++;                } else if (dev && fi->fib_nhs) {                        int dead = 0;                        change_nexthops(fi) {                                if (nh->nh_flags&RTNH_F_DEAD)                                        dead++;                                else if (nh->nh_dev == dev &&                                                nh->nh_scope != scope) {                                        nh->nh_flags |= RTNH_F_DEAD;                                        fi->fib_power -= nh->nh_power;                                        nh->nh_power = 0;                                        dead++;                                }                        } endfor_nexthops(fi)                        if (dead == fi->fib_nhs) {                                fi->fib_flags |= RTNH_F_DEAD;                                ret++;                        }                }        } endfor_fib_info();        return ret;}int dn_fib_sync_up(struct net_device *dev){        int ret = 0;        if (!(dev->flags&IFF_UP))                return 0;        for_fib_info() {                int alive = 0;                change_nexthops(fi) {                        if (!(nh->nh_flags&RTNH_F_DEAD)) {                                alive++;                                continue;                        }                        if (nh->nh_dev == NULL || !(nh->nh_dev->flags&IFF_UP))                                continue;                        if (nh->nh_dev != dev || dev->dn_ptr == NULL)                                continue;                        alive++;                        nh->nh_power = 0;                        nh->nh_flags &= ~RTNH_F_DEAD;                } endfor_nexthops(fi);                if (alive == fi->fib_nhs) {                        fi->fib_flags &= ~RTNH_F_DEAD;                        ret++;                }        } endfor_fib_info();        return ret;}void dn_fib_flush(void){        int flushed = 0;        struct dn_fib_table *tb;        int id;        for(id = DN_NUM_TABLES; id > 0; id--) {                if ((tb = dn_fib_get_table(id, 0)) == NULL)                        continue;                flushed += tb->flush(tb);        }        if (flushed)                dn_rt_cache_flush(-1);}int dn_fib_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg){	if (!capable(CAP_NET_ADMIN))		return -EPERM;	switch(cmd) {		case SIOCADDRT:		case SIOCDELRT:			return 0;	}	return -EINVAL;}#ifdef CONFIG_PROC_FSstatic int decnet_rt_get_info(char *buffer, char **start, off_t offset, int length){        int first = offset / 128;        char *ptr = buffer;        int count = (length + 127) / 128;        int len;        int i;        struct dn_fib_table *tb;        *start = buffer + (offset % 128);        if (--first < 0) {                sprintf(buffer, "%-127s\n", "Iface\tDest\tGW  \tFlags\tRefCnt\tUse\tMetric\tMask\t\tMTU\tWindow\tIRTT");                --count;                ptr += 128;                first = 0;        }        for(i = DN_MIN_TABLE; (i <= DN_NUM_TABLES) && (count > 0); i++) {                if ((tb = dn_fib_get_table(i, 0)) != NULL) {                        int n = tb->get_info(tb, ptr, first, count);                        count -= n;                        ptr += n * 128;                }        }        len = ptr - *start;        if (len >= length)                return length;        if (len >= 0)                return len;        return 0;}#endif /* CONFIG_PROC_FS */void __exit dn_fib_cleanup(void){#ifdef CONFIG_PROC_FS	proc_net_remove("decnet_route");#endif	dn_fib_table_cleanup();	dn_fib_rules_cleanup();}void __init dn_fib_init(void){#ifdef CONFIG_PROC_FS	proc_net_create("decnet_route", 0, decnet_rt_get_info);#endif	dn_fib_table_init();	dn_fib_rules_init();}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -