Lines Matching refs:fl
60 #define for_each_fl_rcu(hash, fl) \ argument
61 for (fl = rcu_dereference_bh(fl_ht[(hash)]); \
62 fl != NULL; \
63 fl = rcu_dereference_bh(fl->next))
64 #define for_each_fl_continue_rcu(fl) \ argument
65 for (fl = rcu_dereference_bh(fl->next); \
66 fl != NULL; \
67 fl = rcu_dereference_bh(fl->next))
76 struct ip6_flowlabel *fl; in __fl_lookup() local
78 for_each_fl_rcu(FL_HASH(label), fl) { in __fl_lookup()
79 if (fl->label == label && net_eq(fl->fl_net, net)) in __fl_lookup()
80 return fl; in __fl_lookup()
87 struct ip6_flowlabel *fl; in fl_lookup() local
90 fl = __fl_lookup(net, label); in fl_lookup()
91 if (fl && !atomic_inc_not_zero(&fl->users)) in fl_lookup()
92 fl = NULL; in fl_lookup()
94 return fl; in fl_lookup()
97 static bool fl_shared_exclusive(struct ip6_flowlabel *fl) in fl_shared_exclusive() argument
99 return fl->share == IPV6_FL_S_EXCL || in fl_shared_exclusive()
100 fl->share == IPV6_FL_S_PROCESS || in fl_shared_exclusive()
101 fl->share == IPV6_FL_S_USER; in fl_shared_exclusive()
106 struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu); in fl_free_rcu() local
108 if (fl->share == IPV6_FL_S_PROCESS) in fl_free_rcu()
109 put_pid(fl->owner.pid); in fl_free_rcu()
110 kfree(fl->opt); in fl_free_rcu()
111 kfree(fl); in fl_free_rcu()
115 static void fl_free(struct ip6_flowlabel *fl) in fl_free() argument
117 if (!fl) in fl_free()
120 if (fl_shared_exclusive(fl) || fl->opt) in fl_free()
123 call_rcu(&fl->rcu, fl_free_rcu); in fl_free()
126 static void fl_release(struct ip6_flowlabel *fl) in fl_release() argument
130 fl->lastuse = jiffies; in fl_release()
131 if (atomic_dec_and_test(&fl->users)) { in fl_release()
132 unsigned long ttd = fl->lastuse + fl->linger; in fl_release()
133 if (time_after(ttd, fl->expires)) in fl_release()
134 fl->expires = ttd; in fl_release()
135 ttd = fl->expires; in fl_release()
136 if (fl->opt && fl->share == IPV6_FL_S_EXCL) { in fl_release()
137 struct ipv6_txoptions *opt = fl->opt; in fl_release()
138 fl->opt = NULL; in fl_release()
157 struct ip6_flowlabel *fl; in ip6_fl_gc() local
161 while ((fl = rcu_dereference_protected(*flp, in ip6_fl_gc()
163 if (atomic_read(&fl->users) == 0) { in ip6_fl_gc()
164 unsigned long ttd = fl->lastuse + fl->linger; in ip6_fl_gc()
165 if (time_after(ttd, fl->expires)) in ip6_fl_gc()
166 fl->expires = ttd; in ip6_fl_gc()
167 ttd = fl->expires; in ip6_fl_gc()
169 *flp = fl->next; in ip6_fl_gc()
170 fl_free(fl); in ip6_fl_gc()
177 flp = &fl->next; in ip6_fl_gc()
194 struct ip6_flowlabel *fl; in ip6_fl_purge() local
198 while ((fl = rcu_dereference_protected(*flp, in ip6_fl_purge()
200 if (net_eq(fl->fl_net, net) && in ip6_fl_purge()
201 atomic_read(&fl->users) == 0) { in ip6_fl_purge()
202 *flp = fl->next; in ip6_fl_purge()
203 fl_free(fl); in ip6_fl_purge()
207 flp = &fl->next; in ip6_fl_purge()
214 struct ip6_flowlabel *fl, __be32 label) in fl_intern()
218 fl->label = label & IPV6_FLOWLABEL_MASK; in fl_intern()
223 fl->label = htonl(prandom_u32())&IPV6_FLOWLABEL_MASK; in fl_intern()
224 if (fl->label) { in fl_intern()
225 lfl = __fl_lookup(net, fl->label); in fl_intern()
239 lfl = __fl_lookup(net, fl->label); in fl_intern()
247 fl->lastuse = jiffies; in fl_intern()
248 fl->next = fl_ht[FL_HASH(fl->label)]; in fl_intern()
249 rcu_assign_pointer(fl_ht[FL_HASH(fl->label)], fl); in fl_intern()
268 struct ip6_flowlabel *fl = sfl->fl; in __fl6_sock_lookup() local
270 if (fl->label == label && atomic_inc_not_zero(&fl->users)) { in __fl6_sock_lookup()
271 fl->lastuse = jiffies; in __fl6_sock_lookup()
273 return fl; in __fl6_sock_lookup()
295 fl_release(sfl->fl); in fl6_free_socklist()
313 struct ip6_flowlabel *fl, in fl6_merge_options() argument
316 struct ipv6_txoptions *fl_opt = fl->opt; in fl6_merge_options()
350 static int fl6_renew(struct ip6_flowlabel *fl, unsigned long linger, unsigned long expires) in fl6_renew() argument
360 fl->lastuse = jiffies; in fl6_renew()
361 if (time_before(fl->linger, linger)) in fl6_renew()
362 fl->linger = linger; in fl6_renew()
363 if (time_before(expires, fl->linger)) in fl6_renew()
364 expires = fl->linger; in fl6_renew()
365 if (time_before(fl->expires, fl->lastuse + expires)) in fl6_renew()
366 fl->expires = fl->lastuse + expires; in fl6_renew()
376 struct ip6_flowlabel *fl = NULL; in fl_create() local
387 fl = kzalloc(sizeof(*fl), GFP_KERNEL); in fl_create()
388 if (!fl) in fl_create()
397 fl->opt = kmalloc(sizeof(*fl->opt) + olen, GFP_KERNEL); in fl_create()
398 if (!fl->opt) in fl_create()
401 memset(fl->opt, 0, sizeof(*fl->opt)); in fl_create()
402 fl->opt->tot_len = sizeof(*fl->opt) + olen; in fl_create()
404 if (copy_from_sockptr_offset(fl->opt + 1, optval, in fl_create()
409 msg.msg_control = (void *)(fl->opt+1); in fl_create()
412 ipc6.opt = fl->opt; in fl_create()
417 if (fl->opt->opt_flen) in fl_create()
419 if (fl->opt->opt_nflen == 0) { in fl_create()
420 kfree(fl->opt); in fl_create()
421 fl->opt = NULL; in fl_create()
425 fl->fl_net = net; in fl_create()
426 fl->expires = jiffies; in fl_create()
427 err = fl6_renew(fl, freq->flr_linger, freq->flr_expires); in fl_create()
430 fl->share = freq->flr_share; in fl_create()
437 fl->dst = freq->flr_dst; in fl_create()
438 atomic_set(&fl->users, 1); in fl_create()
439 switch (fl->share) { in fl_create()
444 fl->owner.pid = get_task_pid(current, PIDTYPE_PID); in fl_create()
447 fl->owner.uid = current_euid(); in fl_create()
453 if (fl_shared_exclusive(fl) || fl->opt) in fl_create()
455 return fl; in fl_create()
458 if (fl) { in fl_create()
459 kfree(fl->opt); in fl_create()
460 kfree(fl); in fl_create()
491 struct ip6_flowlabel *fl) in fl_link() argument
494 sfl->fl = fl; in fl_link()
519 if (sfl->fl->label == (np->flow_label & IPV6_FLOWLABEL_MASK)) { in ipv6_flowlabel_opt_get()
521 freq->flr_label = sfl->fl->label; in ipv6_flowlabel_opt_get()
522 freq->flr_dst = sfl->fl->dst; in ipv6_flowlabel_opt_get()
523 freq->flr_share = sfl->fl->share; in ipv6_flowlabel_opt_get()
524 freq->flr_expires = (sfl->fl->expires - jiffies) / HZ; in ipv6_flowlabel_opt_get()
525 freq->flr_linger = sfl->fl->linger / HZ; in ipv6_flowlabel_opt_get()
560 if (sfl->fl->label == freq->flr_label) in ipv6_flowlabel_put()
570 fl_release(sfl->fl); in ipv6_flowlabel_put()
584 if (sfl->fl->label == freq->flr_label) { in ipv6_flowlabel_renew()
585 err = fl6_renew(sfl->fl, freq->flr_linger, in ipv6_flowlabel_renew()
595 struct ip6_flowlabel *fl = fl_lookup(net, freq->flr_label); in ipv6_flowlabel_renew() local
597 if (fl) { in ipv6_flowlabel_renew()
598 err = fl6_renew(fl, freq->flr_linger, in ipv6_flowlabel_renew()
600 fl_release(fl); in ipv6_flowlabel_renew()
611 struct ip6_flowlabel *fl, *fl1 = NULL; in ipv6_flowlabel_get() local
634 fl = fl_create(net, sk, freq, optval, optlen, &err); in ipv6_flowlabel_get()
635 if (!fl) in ipv6_flowlabel_get()
644 if (sfl->fl->label == freq->flr_label) { in ipv6_flowlabel_get()
649 fl1 = sfl->fl; in ipv6_flowlabel_get()
666 fl1->share != fl->share || in ipv6_flowlabel_get()
668 (fl1->owner.pid != fl->owner.pid)) || in ipv6_flowlabel_get()
670 !uid_eq(fl1->owner.uid, fl->owner.uid))) in ipv6_flowlabel_get()
676 if (fl->linger > fl1->linger) in ipv6_flowlabel_get()
677 fl1->linger = fl->linger; in ipv6_flowlabel_get()
678 if ((long)(fl->expires - fl1->expires) > 0) in ipv6_flowlabel_get()
679 fl1->expires = fl->expires; in ipv6_flowlabel_get()
681 fl_free(fl); in ipv6_flowlabel_get()
701 fl1 = fl_intern(net, fl, freq->flr_label); in ipv6_flowlabel_get()
708 if (copy_to_sockptr_offset(optval, offset, &fl->label, in ipv6_flowlabel_get()
709 sizeof(fl->label))) { in ipv6_flowlabel_get()
714 fl_link(np, sfl1, fl); in ipv6_flowlabel_get()
717 fl_free(fl); in ipv6_flowlabel_get()
755 struct ip6_flowlabel *fl = NULL; in ip6fl_get_first() local
760 for_each_fl_rcu(state->bucket, fl) { in ip6fl_get_first()
761 if (net_eq(fl->fl_net, net)) in ip6fl_get_first()
765 fl = NULL; in ip6fl_get_first()
767 return fl; in ip6fl_get_first()
770 static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flowlabel *fl) in ip6fl_get_next() argument
775 for_each_fl_continue_rcu(fl) { in ip6fl_get_next()
776 if (net_eq(fl->fl_net, net)) in ip6fl_get_next()
782 for_each_fl_rcu(state->bucket, fl) { in ip6fl_get_next()
783 if (net_eq(fl->fl_net, net)) in ip6fl_get_next()
788 fl = NULL; in ip6fl_get_next()
791 return fl; in ip6fl_get_next()
796 struct ip6_flowlabel *fl = ip6fl_get_first(seq); in ip6fl_get_idx() local
797 if (fl) in ip6fl_get_idx()
798 while (pos && (fl = ip6fl_get_next(seq, fl)) != NULL) in ip6fl_get_idx()
800 return pos ? NULL : fl; in ip6fl_get_idx()
816 struct ip6_flowlabel *fl; in ip6fl_seq_next() local
819 fl = ip6fl_get_first(seq); in ip6fl_seq_next()
821 fl = ip6fl_get_next(seq, v); in ip6fl_seq_next()
823 return fl; in ip6fl_seq_next()
838 struct ip6_flowlabel *fl = v; in ip6fl_seq_show() local
841 (unsigned int)ntohl(fl->label), in ip6fl_seq_show()
842 fl->share, in ip6fl_seq_show()
843 ((fl->share == IPV6_FL_S_PROCESS) ? in ip6fl_seq_show()
844 pid_nr_ns(fl->owner.pid, state->pid_ns) : in ip6fl_seq_show()
845 ((fl->share == IPV6_FL_S_USER) ? in ip6fl_seq_show()
846 from_kuid_munged(seq_user_ns(seq), fl->owner.uid) : in ip6fl_seq_show()
848 atomic_read(&fl->users), in ip6fl_seq_show()
849 fl->linger/HZ, in ip6fl_seq_show()
850 (long)(fl->expires - jiffies)/HZ, in ip6fl_seq_show()
851 &fl->dst, in ip6fl_seq_show()
852 fl->opt ? fl->opt->opt_nflen : 0); in ip6fl_seq_show()