Lines Matching refs:fi

49 #define for_fib_info() { struct dn_fib_info *fi;\
50 for(fi = dn_fib_info_list; fi; fi = fi->fib_next)
53 #define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\ argument
54 for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
56 #define change_nexthops(fi) { int nhsel; struct dn_fib_nh *nh;\ argument
57 for(nhsel = 0, nh = (struct dn_fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)
59 #define endfor_nexthops(fi) } argument
87 void dn_fib_free_info(struct dn_fib_info *fi) in dn_fib_free_info() argument
89 if (fi->fib_dead == 0) { in dn_fib_free_info()
94 change_nexthops(fi) { in dn_fib_free_info()
98 } endfor_nexthops(fi); in dn_fib_free_info()
99 kfree(fi); in dn_fib_free_info()
102 void dn_fib_release_info(struct dn_fib_info *fi) in dn_fib_release_info() argument
105 if (fi && --fi->fib_treeref == 0) { in dn_fib_release_info()
106 if (fi->fib_next) in dn_fib_release_info()
107 fi->fib_next->fib_prev = fi->fib_prev; in dn_fib_release_info()
108 if (fi->fib_prev) in dn_fib_release_info()
109 fi->fib_prev->fib_next = fi->fib_next; in dn_fib_release_info()
110 if (fi == dn_fib_info_list) in dn_fib_release_info()
111 dn_fib_info_list = fi->fib_next; in dn_fib_release_info()
112 fi->fib_dead = 1; in dn_fib_release_info()
113 dn_fib_info_put(fi); in dn_fib_release_info()
118 static inline int dn_fib_nh_comp(const struct dn_fib_info *fi, const struct dn_fib_info *ofi) in dn_fib_nh_comp() argument
122 for_nexthops(fi) { in dn_fib_nh_comp()
130 } endfor_nexthops(fi); in dn_fib_nh_comp()
137 if (fi->fib_nhs != nfi->fib_nhs) in dn_fib_find_info()
139 if (nfi->fib_protocol == fi->fib_protocol && in dn_fib_find_info()
140 nfi->fib_prefsrc == fi->fib_prefsrc && in dn_fib_find_info()
141 nfi->fib_priority == fi->fib_priority && in dn_fib_find_info()
142 memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 && in dn_fib_find_info()
143 ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && in dn_fib_find_info()
144 (nfi->fib_nhs == 0 || dn_fib_nh_comp(fi, nfi) == 0)) in dn_fib_find_info()
145 return fi; in dn_fib_find_info()
164 static int dn_fib_get_nhs(struct dn_fib_info *fi, const struct nlattr *attr, in dn_fib_get_nhs() argument
170 change_nexthops(fi) { in dn_fib_get_nhs()
189 } endfor_nexthops(fi); in dn_fib_get_nhs()
195 static int dn_fib_check_nh(const struct rtmsg *r, struct dn_fib_info *fi, struct dn_fib_nh *nh) in dn_fib_check_nh() argument
271 struct dn_fib_info *fi = NULL; in dn_fib_create_info() local
285 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL); in dn_fib_create_info()
287 if (fi == NULL) in dn_fib_create_info()
290 fi->fib_protocol = r->rtm_protocol; in dn_fib_create_info()
291 fi->fib_nhs = nhs; in dn_fib_create_info()
292 fi->fib_flags = r->rtm_flags; in dn_fib_create_info()
295 fi->fib_priority = nla_get_u32(attrs[RTA_PRIORITY]); in dn_fib_create_info()
309 fi->fib_metrics[type-1] = nla_get_u32(attr); in dn_fib_create_info()
315 fi->fib_prefsrc = nla_get_le16(attrs[RTA_PREFSRC]); in dn_fib_create_info()
318 if ((err = dn_fib_get_nhs(fi, attrs[RTA_MULTIPATH], r)) != 0) in dn_fib_create_info()
322 fi->fib_nh->nh_oif != nla_get_u32(attrs[RTA_OIF])) in dn_fib_create_info()
326 fi->fib_nh->nh_gw != nla_get_le16(attrs[RTA_GATEWAY])) in dn_fib_create_info()
329 struct dn_fib_nh *nh = fi->fib_nh; in dn_fib_create_info()
345 fi->fib_nh->nh_gw = nla_get_le16(attrs[RTA_GATEWAY]); in dn_fib_create_info()
360 struct dn_fib_nh *nh = fi->fib_nh; in dn_fib_create_info()
366 nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif); in dn_fib_create_info()
371 change_nexthops(fi) { in dn_fib_create_info()
372 if ((err = dn_fib_check_nh(r, fi, nh)) != 0) in dn_fib_create_info()
374 } endfor_nexthops(fi) in dn_fib_create_info()
377 if (fi->fib_prefsrc) { in dn_fib_create_info()
379 fi->fib_prefsrc != nla_get_le16(attrs[RTA_DST])) in dn_fib_create_info()
380 if (dnet_addr_type(fi->fib_prefsrc) != RTN_LOCAL) in dn_fib_create_info()
385 if ((ofi = dn_fib_find_info(fi)) != NULL) { in dn_fib_create_info()
386 fi->fib_dead = 1; in dn_fib_create_info()
387 dn_fib_free_info(fi); in dn_fib_create_info()
392 fi->fib_treeref++; in dn_fib_create_info()
393 refcount_set(&fi->fib_clntref, 1); in dn_fib_create_info()
395 fi->fib_next = dn_fib_info_list; in dn_fib_create_info()
396 fi->fib_prev = NULL; in dn_fib_create_info()
398 dn_fib_info_list->fib_prev = fi; in dn_fib_create_info()
399 dn_fib_info_list = fi; in dn_fib_create_info()
401 return fi; in dn_fib_create_info()
408 if (fi) { in dn_fib_create_info()
409 fi->fib_dead = 1; in dn_fib_create_info()
410 dn_fib_free_info(fi); in dn_fib_create_info()
416 int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn *fld, struct dn_fi… in dn_fib_semantic_match() argument
421 if (fi->fib_flags & RTNH_F_DEAD) in dn_fib_semantic_match()
424 res->fi = fi; in dn_fib_semantic_match()
429 refcount_inc(&fi->fib_clntref); in dn_fib_semantic_match()
433 for_nexthops(fi) { in dn_fib_semantic_match()
440 if (nhsel < fi->fib_nhs) { in dn_fib_semantic_match()
442 refcount_inc(&fi->fib_clntref); in dn_fib_semantic_match()
445 endfor_nexthops(fi); in dn_fib_semantic_match()
446 res->fi = NULL; in dn_fib_semantic_match()
451 res->fi = NULL; in dn_fib_semantic_match()
460 struct dn_fib_info *fi = res->fi; in dn_fib_select_multipath() local
464 if (fi->fib_power <= 0) { in dn_fib_select_multipath()
466 change_nexthops(fi) { in dn_fib_select_multipath()
471 } endfor_nexthops(fi); in dn_fib_select_multipath()
472 fi->fib_power = power; in dn_fib_select_multipath()
480 w = jiffies % fi->fib_power; in dn_fib_select_multipath()
482 change_nexthops(fi) { in dn_fib_select_multipath()
486 fi->fib_power--; in dn_fib_select_multipath()
492 } endfor_nexthops(fi); in dn_fib_select_multipath()
712 if (local && fi->fib_prefsrc == local) { in dn_fib_sync_down()
713 fi->fib_flags |= RTNH_F_DEAD; in dn_fib_sync_down()
715 } else if (dev && fi->fib_nhs) { in dn_fib_sync_down()
718 change_nexthops(fi) { in dn_fib_sync_down()
725 fi->fib_power -= nh->nh_power; in dn_fib_sync_down()
730 } endfor_nexthops(fi) in dn_fib_sync_down()
731 if (dead == fi->fib_nhs) { in dn_fib_sync_down()
732 fi->fib_flags |= RTNH_F_DEAD; in dn_fib_sync_down()
751 change_nexthops(fi) { in dn_fib_sync_up()
765 } endfor_nexthops(fi); in dn_fib_sync_up()
768 fi->fib_flags &= ~RTNH_F_DEAD; in dn_fib_sync_up()