Lines Matching refs:fi

47 #define for_fib_info() { struct dn_fib_info *fi;\
48 for(fi = dn_fib_info_list; fi; fi = fi->fib_next)
51 #define for_nexthops(fi) { int nhsel; const struct dn_fib_nh *nh;\ argument
52 for(nhsel = 0, nh = (fi)->fib_nh; nhsel < (fi)->fib_nhs; nh++, nhsel++)
54 #define change_nexthops(fi) { int nhsel; struct dn_fib_nh *nh;\ argument
55 for(nhsel = 0, nh = (struct dn_fib_nh *)((fi)->fib_nh); nhsel < (fi)->fib_nhs; nh++, nhsel++)
57 #define endfor_nexthops(fi) } argument
85 void dn_fib_free_info(struct dn_fib_info *fi) in dn_fib_free_info() argument
87 if (fi->fib_dead == 0) { in dn_fib_free_info()
92 change_nexthops(fi) { in dn_fib_free_info()
96 } endfor_nexthops(fi); in dn_fib_free_info()
97 kfree(fi); in dn_fib_free_info()
100 void dn_fib_release_info(struct dn_fib_info *fi) in dn_fib_release_info() argument
103 if (fi && --fi->fib_treeref == 0) { in dn_fib_release_info()
104 if (fi->fib_next) in dn_fib_release_info()
105 fi->fib_next->fib_prev = fi->fib_prev; in dn_fib_release_info()
106 if (fi->fib_prev) in dn_fib_release_info()
107 fi->fib_prev->fib_next = fi->fib_next; in dn_fib_release_info()
108 if (fi == dn_fib_info_list) in dn_fib_release_info()
109 dn_fib_info_list = fi->fib_next; in dn_fib_release_info()
110 fi->fib_dead = 1; in dn_fib_release_info()
111 dn_fib_info_put(fi); in dn_fib_release_info()
116 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
120 for_nexthops(fi) { in dn_fib_nh_comp()
128 } endfor_nexthops(fi); in dn_fib_nh_comp()
135 if (fi->fib_nhs != nfi->fib_nhs) in dn_fib_find_info()
137 if (nfi->fib_protocol == fi->fib_protocol && in dn_fib_find_info()
138 nfi->fib_prefsrc == fi->fib_prefsrc && in dn_fib_find_info()
139 nfi->fib_priority == fi->fib_priority && in dn_fib_find_info()
140 memcmp(nfi->fib_metrics, fi->fib_metrics, sizeof(fi->fib_metrics)) == 0 && in dn_fib_find_info()
141 ((nfi->fib_flags^fi->fib_flags)&~RTNH_F_DEAD) == 0 && in dn_fib_find_info()
142 (nfi->fib_nhs == 0 || dn_fib_nh_comp(fi, nfi) == 0)) in dn_fib_find_info()
143 return fi; in dn_fib_find_info()
163 static int dn_fib_get_nhs(struct dn_fib_info *fi, const struct nlattr *attr, in dn_fib_get_nhs() argument
169 change_nexthops(fi) { in dn_fib_get_nhs()
185 } endfor_nexthops(fi); in dn_fib_get_nhs()
191 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
267 struct dn_fib_info *fi = NULL; in dn_fib_create_info() local
281 fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct dn_fib_nh), GFP_KERNEL); in dn_fib_create_info()
283 if (fi == NULL) in dn_fib_create_info()
286 fi->fib_protocol = r->rtm_protocol; in dn_fib_create_info()
287 fi->fib_nhs = nhs; in dn_fib_create_info()
288 fi->fib_flags = r->rtm_flags; in dn_fib_create_info()
291 fi->fib_priority = nla_get_u32(attrs[RTA_PRIORITY]); in dn_fib_create_info()
305 fi->fib_metrics[type-1] = nla_get_u32(attr); in dn_fib_create_info()
311 fi->fib_prefsrc = nla_get_le16(attrs[RTA_PREFSRC]); in dn_fib_create_info()
314 if ((err = dn_fib_get_nhs(fi, attrs[RTA_MULTIPATH], r)) != 0) in dn_fib_create_info()
318 fi->fib_nh->nh_oif != nla_get_u32(attrs[RTA_OIF])) in dn_fib_create_info()
322 fi->fib_nh->nh_gw != nla_get_le16(attrs[RTA_GATEWAY])) in dn_fib_create_info()
325 struct dn_fib_nh *nh = fi->fib_nh; in dn_fib_create_info()
341 fi->fib_nh->nh_gw = nla_get_le16(attrs[RTA_GATEWAY]); in dn_fib_create_info()
356 struct dn_fib_nh *nh = fi->fib_nh; in dn_fib_create_info()
362 nh->nh_dev = dev_get_by_index(&init_net, fi->fib_nh->nh_oif); in dn_fib_create_info()
367 change_nexthops(fi) { in dn_fib_create_info()
368 if ((err = dn_fib_check_nh(r, fi, nh)) != 0) in dn_fib_create_info()
370 } endfor_nexthops(fi) in dn_fib_create_info()
373 if (fi->fib_prefsrc) { in dn_fib_create_info()
375 fi->fib_prefsrc != nla_get_le16(attrs[RTA_DST])) in dn_fib_create_info()
376 if (dnet_addr_type(fi->fib_prefsrc) != RTN_LOCAL) in dn_fib_create_info()
381 if ((ofi = dn_fib_find_info(fi)) != NULL) { in dn_fib_create_info()
382 fi->fib_dead = 1; in dn_fib_create_info()
383 dn_fib_free_info(fi); in dn_fib_create_info()
388 fi->fib_treeref++; in dn_fib_create_info()
389 atomic_inc(&fi->fib_clntref); in dn_fib_create_info()
391 fi->fib_next = dn_fib_info_list; in dn_fib_create_info()
392 fi->fib_prev = NULL; in dn_fib_create_info()
394 dn_fib_info_list->fib_prev = fi; in dn_fib_create_info()
395 dn_fib_info_list = fi; in dn_fib_create_info()
397 return fi; in dn_fib_create_info()
404 if (fi) { in dn_fib_create_info()
405 fi->fib_dead = 1; in dn_fib_create_info()
406 dn_fib_free_info(fi); in dn_fib_create_info()
412 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
417 if (fi->fib_flags & RTNH_F_DEAD) in dn_fib_semantic_match()
420 res->fi = fi; in dn_fib_semantic_match()
425 atomic_inc(&fi->fib_clntref); in dn_fib_semantic_match()
429 for_nexthops(fi) { in dn_fib_semantic_match()
436 if (nhsel < fi->fib_nhs) { in dn_fib_semantic_match()
438 atomic_inc(&fi->fib_clntref); in dn_fib_semantic_match()
441 endfor_nexthops(fi); in dn_fib_semantic_match()
442 res->fi = NULL; in dn_fib_semantic_match()
447 res->fi = NULL; in dn_fib_semantic_match()
456 struct dn_fib_info *fi = res->fi; in dn_fib_select_multipath() local
460 if (fi->fib_power <= 0) { in dn_fib_select_multipath()
462 change_nexthops(fi) { in dn_fib_select_multipath()
467 } endfor_nexthops(fi); in dn_fib_select_multipath()
468 fi->fib_power = power; in dn_fib_select_multipath()
476 w = jiffies % fi->fib_power; in dn_fib_select_multipath()
478 change_nexthops(fi) { in dn_fib_select_multipath()
482 fi->fib_power--; in dn_fib_select_multipath()
488 } endfor_nexthops(fi); in dn_fib_select_multipath()
704 if (local && fi->fib_prefsrc == local) { in dn_fib_sync_down()
705 fi->fib_flags |= RTNH_F_DEAD; in dn_fib_sync_down()
707 } else if (dev && fi->fib_nhs) { in dn_fib_sync_down()
710 change_nexthops(fi) { in dn_fib_sync_down()
717 fi->fib_power -= nh->nh_power; in dn_fib_sync_down()
722 } endfor_nexthops(fi) in dn_fib_sync_down()
723 if (dead == fi->fib_nhs) { in dn_fib_sync_down()
724 fi->fib_flags |= RTNH_F_DEAD; in dn_fib_sync_down()
743 change_nexthops(fi) { in dn_fib_sync_up()
757 } endfor_nexthops(fi); in dn_fib_sync_up()
760 fi->fib_flags &= ~RTNH_F_DEAD; in dn_fib_sync_up()