Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/net/ipv6/ip6_flowlabel.c
48906 views
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/*
3
* ip6_flowlabel.c IPv6 flowlabel manager.
4
*
5
* Authors: Alexey Kuznetsov, <[email protected]>
6
*/
7
8
#include <linux/capability.h>
9
#include <linux/errno.h>
10
#include <linux/types.h>
11
#include <linux/socket.h>
12
#include <linux/net.h>
13
#include <linux/netdevice.h>
14
#include <linux/in6.h>
15
#include <linux/proc_fs.h>
16
#include <linux/seq_file.h>
17
#include <linux/slab.h>
18
#include <linux/export.h>
19
#include <linux/pid_namespace.h>
20
#include <linux/jump_label_ratelimit.h>
21
22
#include <net/net_namespace.h>
23
#include <net/sock.h>
24
25
#include <net/ipv6.h>
26
#include <net/rawv6.h>
27
#include <net/transp_v6.h>
28
29
#include <linux/uaccess.h>
30
31
#define FL_MIN_LINGER 6 /* Minimal linger. It is set to 6sec specified
32
in old IPv6 RFC. Well, it was reasonable value.
33
*/
34
#define FL_MAX_LINGER 150 /* Maximal linger timeout */
35
36
/* FL hash table */
37
38
#define FL_MAX_PER_SOCK 32
39
#define FL_MAX_SIZE 4096
40
#define FL_HASH_MASK 255
41
#define FL_HASH(l) (ntohl(l)&FL_HASH_MASK)
42
43
static atomic_t fl_size = ATOMIC_INIT(0);
44
static struct ip6_flowlabel __rcu *fl_ht[FL_HASH_MASK+1];
45
46
static void ip6_fl_gc(struct timer_list *unused);
47
static DEFINE_TIMER(ip6_fl_gc_timer, ip6_fl_gc);
48
49
/* FL hash table lock: it protects only of GC */
50
51
static DEFINE_SPINLOCK(ip6_fl_lock);
52
53
/* Big socket sock */
54
55
static DEFINE_SPINLOCK(ip6_sk_fl_lock);
56
57
DEFINE_STATIC_KEY_DEFERRED_FALSE(ipv6_flowlabel_exclusive, HZ);
58
EXPORT_SYMBOL(ipv6_flowlabel_exclusive);
59
60
#define for_each_fl_rcu(hash, fl) \
61
for (fl = rcu_dereference(fl_ht[(hash)]); \
62
fl != NULL; \
63
fl = rcu_dereference(fl->next))
64
#define for_each_fl_continue_rcu(fl) \
65
for (fl = rcu_dereference(fl->next); \
66
fl != NULL; \
67
fl = rcu_dereference(fl->next))
68
69
#define for_each_sk_fl_rcu(sk, sfl) \
70
for (sfl = rcu_dereference(inet_sk(sk)->ipv6_fl_list); \
71
sfl != NULL; \
72
sfl = rcu_dereference(sfl->next))
73
74
static inline struct ip6_flowlabel *__fl_lookup(struct net *net, __be32 label)
75
{
76
struct ip6_flowlabel *fl;
77
78
for_each_fl_rcu(FL_HASH(label), fl) {
79
if (fl->label == label && net_eq(fl->fl_net, net))
80
return fl;
81
}
82
return NULL;
83
}
84
85
static struct ip6_flowlabel *fl_lookup(struct net *net, __be32 label)
86
{
87
struct ip6_flowlabel *fl;
88
89
rcu_read_lock();
90
fl = __fl_lookup(net, label);
91
if (fl && !atomic_inc_not_zero(&fl->users))
92
fl = NULL;
93
rcu_read_unlock();
94
return fl;
95
}
96
97
static bool fl_shared_exclusive(struct ip6_flowlabel *fl)
98
{
99
return fl->share == IPV6_FL_S_EXCL ||
100
fl->share == IPV6_FL_S_PROCESS ||
101
fl->share == IPV6_FL_S_USER;
102
}
103
104
static void fl_free_rcu(struct rcu_head *head)
105
{
106
struct ip6_flowlabel *fl = container_of(head, struct ip6_flowlabel, rcu);
107
108
if (fl->share == IPV6_FL_S_PROCESS)
109
put_pid(fl->owner.pid);
110
kfree(fl->opt);
111
kfree(fl);
112
}
113
114
115
static void fl_free(struct ip6_flowlabel *fl)
116
{
117
if (!fl)
118
return;
119
120
if (fl_shared_exclusive(fl) || fl->opt)
121
static_branch_slow_dec_deferred(&ipv6_flowlabel_exclusive);
122
123
call_rcu(&fl->rcu, fl_free_rcu);
124
}
125
126
static void fl_release(struct ip6_flowlabel *fl)
127
{
128
spin_lock_bh(&ip6_fl_lock);
129
130
fl->lastuse = jiffies;
131
if (atomic_dec_and_test(&fl->users)) {
132
unsigned long ttd = fl->lastuse + fl->linger;
133
if (time_after(ttd, fl->expires))
134
fl->expires = ttd;
135
ttd = fl->expires;
136
if (fl->opt && fl->share == IPV6_FL_S_EXCL) {
137
struct ipv6_txoptions *opt = fl->opt;
138
fl->opt = NULL;
139
kfree(opt);
140
}
141
if (!timer_pending(&ip6_fl_gc_timer) ||
142
time_after(ip6_fl_gc_timer.expires, ttd))
143
mod_timer(&ip6_fl_gc_timer, ttd);
144
}
145
spin_unlock_bh(&ip6_fl_lock);
146
}
147
148
static void ip6_fl_gc(struct timer_list *unused)
149
{
150
int i;
151
unsigned long now = jiffies;
152
unsigned long sched = 0;
153
154
spin_lock(&ip6_fl_lock);
155
156
for (i = 0; i <= FL_HASH_MASK; i++) {
157
struct ip6_flowlabel *fl;
158
struct ip6_flowlabel __rcu **flp;
159
160
flp = &fl_ht[i];
161
while ((fl = rcu_dereference_protected(*flp,
162
lockdep_is_held(&ip6_fl_lock))) != NULL) {
163
if (atomic_read(&fl->users) == 0) {
164
unsigned long ttd = fl->lastuse + fl->linger;
165
if (time_after(ttd, fl->expires))
166
fl->expires = ttd;
167
ttd = fl->expires;
168
if (time_after_eq(now, ttd)) {
169
*flp = fl->next;
170
fl_free(fl);
171
atomic_dec(&fl_size);
172
continue;
173
}
174
if (!sched || time_before(ttd, sched))
175
sched = ttd;
176
}
177
flp = &fl->next;
178
}
179
}
180
if (!sched && atomic_read(&fl_size))
181
sched = now + FL_MAX_LINGER;
182
if (sched) {
183
mod_timer(&ip6_fl_gc_timer, sched);
184
}
185
spin_unlock(&ip6_fl_lock);
186
}
187
188
static void __net_exit ip6_fl_purge(struct net *net)
189
{
190
int i;
191
192
spin_lock_bh(&ip6_fl_lock);
193
for (i = 0; i <= FL_HASH_MASK; i++) {
194
struct ip6_flowlabel *fl;
195
struct ip6_flowlabel __rcu **flp;
196
197
flp = &fl_ht[i];
198
while ((fl = rcu_dereference_protected(*flp,
199
lockdep_is_held(&ip6_fl_lock))) != NULL) {
200
if (net_eq(fl->fl_net, net) &&
201
atomic_read(&fl->users) == 0) {
202
*flp = fl->next;
203
fl_free(fl);
204
atomic_dec(&fl_size);
205
continue;
206
}
207
flp = &fl->next;
208
}
209
}
210
spin_unlock_bh(&ip6_fl_lock);
211
}
212
213
static struct ip6_flowlabel *fl_intern(struct net *net,
214
struct ip6_flowlabel *fl, __be32 label)
215
{
216
struct ip6_flowlabel *lfl;
217
218
fl->label = label & IPV6_FLOWLABEL_MASK;
219
220
rcu_read_lock();
221
spin_lock_bh(&ip6_fl_lock);
222
if (label == 0) {
223
for (;;) {
224
fl->label = htonl(get_random_u32())&IPV6_FLOWLABEL_MASK;
225
if (fl->label) {
226
lfl = __fl_lookup(net, fl->label);
227
if (!lfl)
228
break;
229
}
230
}
231
} else {
232
/*
233
* we dropper the ip6_fl_lock, so this entry could reappear
234
* and we need to recheck with it.
235
*
236
* OTOH no need to search the active socket first, like it is
237
* done in ipv6_flowlabel_opt - sock is locked, so new entry
238
* with the same label can only appear on another sock
239
*/
240
lfl = __fl_lookup(net, fl->label);
241
if (lfl) {
242
atomic_inc(&lfl->users);
243
spin_unlock_bh(&ip6_fl_lock);
244
rcu_read_unlock();
245
return lfl;
246
}
247
}
248
249
fl->lastuse = jiffies;
250
fl->next = fl_ht[FL_HASH(fl->label)];
251
rcu_assign_pointer(fl_ht[FL_HASH(fl->label)], fl);
252
atomic_inc(&fl_size);
253
spin_unlock_bh(&ip6_fl_lock);
254
rcu_read_unlock();
255
return NULL;
256
}
257
258
259
260
/* Socket flowlabel lists */
261
262
struct ip6_flowlabel *__fl6_sock_lookup(struct sock *sk, __be32 label)
263
{
264
struct ipv6_fl_socklist *sfl;
265
266
label &= IPV6_FLOWLABEL_MASK;
267
268
rcu_read_lock();
269
for_each_sk_fl_rcu(sk, sfl) {
270
struct ip6_flowlabel *fl = sfl->fl;
271
272
if (fl->label == label && atomic_inc_not_zero(&fl->users)) {
273
fl->lastuse = jiffies;
274
rcu_read_unlock();
275
return fl;
276
}
277
}
278
rcu_read_unlock();
279
return NULL;
280
}
281
EXPORT_SYMBOL_GPL(__fl6_sock_lookup);
282
283
void fl6_free_socklist(struct sock *sk)
284
{
285
struct inet_sock *inet = inet_sk(sk);
286
struct ipv6_fl_socklist *sfl;
287
288
if (!rcu_access_pointer(inet->ipv6_fl_list))
289
return;
290
291
spin_lock_bh(&ip6_sk_fl_lock);
292
while ((sfl = rcu_dereference_protected(inet->ipv6_fl_list,
293
lockdep_is_held(&ip6_sk_fl_lock))) != NULL) {
294
inet->ipv6_fl_list = sfl->next;
295
spin_unlock_bh(&ip6_sk_fl_lock);
296
297
fl_release(sfl->fl);
298
kfree_rcu(sfl, rcu);
299
300
spin_lock_bh(&ip6_sk_fl_lock);
301
}
302
spin_unlock_bh(&ip6_sk_fl_lock);
303
}
304
305
/* Service routines */
306
307
308
/*
309
It is the only difficult place. flowlabel enforces equal headers
310
before and including routing header, however user may supply options
311
following rthdr.
312
*/
313
314
struct ipv6_txoptions *fl6_merge_options(struct ipv6_txoptions *opt_space,
315
struct ip6_flowlabel *fl,
316
struct ipv6_txoptions *fopt)
317
{
318
struct ipv6_txoptions *fl_opt = fl->opt;
319
320
if (!fopt || fopt->opt_flen == 0)
321
return fl_opt;
322
323
if (fl_opt) {
324
opt_space->hopopt = fl_opt->hopopt;
325
opt_space->dst0opt = fl_opt->dst0opt;
326
opt_space->srcrt = fl_opt->srcrt;
327
opt_space->opt_nflen = fl_opt->opt_nflen;
328
} else {
329
if (fopt->opt_nflen == 0)
330
return fopt;
331
opt_space->hopopt = NULL;
332
opt_space->dst0opt = NULL;
333
opt_space->srcrt = NULL;
334
opt_space->opt_nflen = 0;
335
}
336
opt_space->dst1opt = fopt->dst1opt;
337
opt_space->opt_flen = fopt->opt_flen;
338
opt_space->tot_len = fopt->tot_len;
339
return opt_space;
340
}
341
EXPORT_SYMBOL_GPL(fl6_merge_options);
342
343
static unsigned long check_linger(unsigned long ttl)
344
{
345
if (ttl < FL_MIN_LINGER)
346
return FL_MIN_LINGER*HZ;
347
if (ttl > FL_MAX_LINGER && !capable(CAP_NET_ADMIN))
348
return 0;
349
return ttl*HZ;
350
}
351
352
static int fl6_renew(struct ip6_flowlabel *fl, unsigned long linger, unsigned long expires)
353
{
354
linger = check_linger(linger);
355
if (!linger)
356
return -EPERM;
357
expires = check_linger(expires);
358
if (!expires)
359
return -EPERM;
360
361
spin_lock_bh(&ip6_fl_lock);
362
fl->lastuse = jiffies;
363
if (time_before(fl->linger, linger))
364
fl->linger = linger;
365
if (time_before(expires, fl->linger))
366
expires = fl->linger;
367
if (time_before(fl->expires, fl->lastuse + expires))
368
fl->expires = fl->lastuse + expires;
369
spin_unlock_bh(&ip6_fl_lock);
370
371
return 0;
372
}
373
374
static struct ip6_flowlabel *
375
fl_create(struct net *net, struct sock *sk, struct in6_flowlabel_req *freq,
376
sockptr_t optval, int optlen, int *err_p)
377
{
378
struct ip6_flowlabel *fl = NULL;
379
int olen;
380
int addr_type;
381
int err;
382
383
olen = optlen - CMSG_ALIGN(sizeof(*freq));
384
err = -EINVAL;
385
if (olen > 64 * 1024)
386
goto done;
387
388
err = -ENOMEM;
389
fl = kzalloc(sizeof(*fl), GFP_KERNEL);
390
if (!fl)
391
goto done;
392
393
if (olen > 0) {
394
struct msghdr msg;
395
struct flowi6 flowi6;
396
struct ipcm6_cookie ipc6;
397
398
err = -ENOMEM;
399
fl->opt = kmalloc(sizeof(*fl->opt) + olen, GFP_KERNEL);
400
if (!fl->opt)
401
goto done;
402
403
memset(fl->opt, 0, sizeof(*fl->opt));
404
fl->opt->tot_len = sizeof(*fl->opt) + olen;
405
err = -EFAULT;
406
if (copy_from_sockptr_offset(fl->opt + 1, optval,
407
CMSG_ALIGN(sizeof(*freq)), olen))
408
goto done;
409
410
msg.msg_controllen = olen;
411
msg.msg_control = (void *)(fl->opt+1);
412
memset(&flowi6, 0, sizeof(flowi6));
413
414
ipc6.opt = fl->opt;
415
err = ip6_datagram_send_ctl(net, sk, &msg, &flowi6, &ipc6);
416
if (err)
417
goto done;
418
err = -EINVAL;
419
if (fl->opt->opt_flen)
420
goto done;
421
if (fl->opt->opt_nflen == 0) {
422
kfree(fl->opt);
423
fl->opt = NULL;
424
}
425
}
426
427
fl->fl_net = net;
428
fl->expires = jiffies;
429
err = fl6_renew(fl, freq->flr_linger, freq->flr_expires);
430
if (err)
431
goto done;
432
fl->share = freq->flr_share;
433
addr_type = ipv6_addr_type(&freq->flr_dst);
434
if ((addr_type & IPV6_ADDR_MAPPED) ||
435
addr_type == IPV6_ADDR_ANY) {
436
err = -EINVAL;
437
goto done;
438
}
439
fl->dst = freq->flr_dst;
440
atomic_set(&fl->users, 1);
441
switch (fl->share) {
442
case IPV6_FL_S_EXCL:
443
case IPV6_FL_S_ANY:
444
break;
445
case IPV6_FL_S_PROCESS:
446
fl->owner.pid = get_task_pid(current, PIDTYPE_PID);
447
break;
448
case IPV6_FL_S_USER:
449
fl->owner.uid = current_euid();
450
break;
451
default:
452
err = -EINVAL;
453
goto done;
454
}
455
if (fl_shared_exclusive(fl) || fl->opt) {
456
WRITE_ONCE(sock_net(sk)->ipv6.flowlabel_has_excl, 1);
457
static_branch_deferred_inc(&ipv6_flowlabel_exclusive);
458
}
459
return fl;
460
461
done:
462
if (fl) {
463
kfree(fl->opt);
464
kfree(fl);
465
}
466
*err_p = err;
467
return NULL;
468
}
469
470
static int mem_check(struct sock *sk)
471
{
472
int room = FL_MAX_SIZE - atomic_read(&fl_size);
473
struct ipv6_fl_socklist *sfl;
474
int count = 0;
475
476
if (room > FL_MAX_SIZE - FL_MAX_PER_SOCK)
477
return 0;
478
479
rcu_read_lock();
480
for_each_sk_fl_rcu(sk, sfl)
481
count++;
482
rcu_read_unlock();
483
484
if (room <= 0 ||
485
((count >= FL_MAX_PER_SOCK ||
486
(count > 0 && room < FL_MAX_SIZE/2) || room < FL_MAX_SIZE/4) &&
487
!capable(CAP_NET_ADMIN)))
488
return -ENOBUFS;
489
490
return 0;
491
}
492
493
static inline void fl_link(struct sock *sk, struct ipv6_fl_socklist *sfl,
494
struct ip6_flowlabel *fl)
495
{
496
struct inet_sock *inet = inet_sk(sk);
497
498
spin_lock_bh(&ip6_sk_fl_lock);
499
sfl->fl = fl;
500
sfl->next = inet->ipv6_fl_list;
501
rcu_assign_pointer(inet->ipv6_fl_list, sfl);
502
spin_unlock_bh(&ip6_sk_fl_lock);
503
}
504
505
int ipv6_flowlabel_opt_get(struct sock *sk, struct in6_flowlabel_req *freq,
506
int flags)
507
{
508
struct ipv6_pinfo *np = inet6_sk(sk);
509
struct ipv6_fl_socklist *sfl;
510
511
if (flags & IPV6_FL_F_REMOTE) {
512
freq->flr_label = np->rcv_flowinfo & IPV6_FLOWLABEL_MASK;
513
return 0;
514
}
515
516
if (inet6_test_bit(REPFLOW, sk)) {
517
freq->flr_label = np->flow_label;
518
return 0;
519
}
520
521
rcu_read_lock();
522
523
for_each_sk_fl_rcu(sk, sfl) {
524
if (sfl->fl->label == (np->flow_label & IPV6_FLOWLABEL_MASK)) {
525
spin_lock_bh(&ip6_fl_lock);
526
freq->flr_label = sfl->fl->label;
527
freq->flr_dst = sfl->fl->dst;
528
freq->flr_share = sfl->fl->share;
529
freq->flr_expires = (sfl->fl->expires - jiffies) / HZ;
530
freq->flr_linger = sfl->fl->linger / HZ;
531
532
spin_unlock_bh(&ip6_fl_lock);
533
rcu_read_unlock();
534
return 0;
535
}
536
}
537
rcu_read_unlock();
538
539
return -ENOENT;
540
}
541
542
#define socklist_dereference(__sflp) \
543
rcu_dereference_protected(__sflp, lockdep_is_held(&ip6_sk_fl_lock))
544
545
static int ipv6_flowlabel_put(struct sock *sk, struct in6_flowlabel_req *freq)
546
{
547
struct ipv6_pinfo *np = inet6_sk(sk);
548
struct ipv6_fl_socklist __rcu **sflp;
549
struct ipv6_fl_socklist *sfl;
550
551
if (freq->flr_flags & IPV6_FL_F_REFLECT) {
552
if (sk->sk_protocol != IPPROTO_TCP)
553
return -ENOPROTOOPT;
554
if (!inet6_test_bit(REPFLOW, sk))
555
return -ESRCH;
556
np->flow_label = 0;
557
inet6_clear_bit(REPFLOW, sk);
558
return 0;
559
}
560
561
spin_lock_bh(&ip6_sk_fl_lock);
562
for (sflp = &inet_sk(sk)->ipv6_fl_list;
563
(sfl = socklist_dereference(*sflp)) != NULL;
564
sflp = &sfl->next) {
565
if (sfl->fl->label == freq->flr_label)
566
goto found;
567
}
568
spin_unlock_bh(&ip6_sk_fl_lock);
569
return -ESRCH;
570
found:
571
if (freq->flr_label == (np->flow_label & IPV6_FLOWLABEL_MASK))
572
np->flow_label &= ~IPV6_FLOWLABEL_MASK;
573
*sflp = sfl->next;
574
spin_unlock_bh(&ip6_sk_fl_lock);
575
fl_release(sfl->fl);
576
kfree_rcu(sfl, rcu);
577
return 0;
578
}
579
580
static int ipv6_flowlabel_renew(struct sock *sk, struct in6_flowlabel_req *freq)
581
{
582
struct net *net = sock_net(sk);
583
struct ipv6_fl_socklist *sfl;
584
int err;
585
586
rcu_read_lock();
587
for_each_sk_fl_rcu(sk, sfl) {
588
if (sfl->fl->label == freq->flr_label) {
589
err = fl6_renew(sfl->fl, freq->flr_linger,
590
freq->flr_expires);
591
rcu_read_unlock();
592
return err;
593
}
594
}
595
rcu_read_unlock();
596
597
if (freq->flr_share == IPV6_FL_S_NONE &&
598
ns_capable(net->user_ns, CAP_NET_ADMIN)) {
599
struct ip6_flowlabel *fl = fl_lookup(net, freq->flr_label);
600
601
if (fl) {
602
err = fl6_renew(fl, freq->flr_linger,
603
freq->flr_expires);
604
fl_release(fl);
605
return err;
606
}
607
}
608
return -ESRCH;
609
}
610
611
static int ipv6_flowlabel_get(struct sock *sk, struct in6_flowlabel_req *freq,
612
sockptr_t optval, int optlen)
613
{
614
struct ipv6_fl_socklist *sfl, *sfl1 = NULL;
615
struct ip6_flowlabel *fl, *fl1 = NULL;
616
struct net *net = sock_net(sk);
617
int err;
618
619
if (freq->flr_flags & IPV6_FL_F_REFLECT) {
620
if (net->ipv6.sysctl.flowlabel_consistency) {
621
net_info_ratelimited("Can not set IPV6_FL_F_REFLECT if flowlabel_consistency sysctl is enable\n");
622
return -EPERM;
623
}
624
625
if (sk->sk_protocol != IPPROTO_TCP)
626
return -ENOPROTOOPT;
627
inet6_set_bit(REPFLOW, sk);
628
return 0;
629
}
630
631
if (freq->flr_label & ~IPV6_FLOWLABEL_MASK)
632
return -EINVAL;
633
if (net->ipv6.sysctl.flowlabel_state_ranges &&
634
(freq->flr_label & IPV6_FLOWLABEL_STATELESS_FLAG))
635
return -ERANGE;
636
637
fl = fl_create(net, sk, freq, optval, optlen, &err);
638
if (!fl)
639
return err;
640
641
sfl1 = kmalloc(sizeof(*sfl1), GFP_KERNEL);
642
643
if (freq->flr_label) {
644
err = -EEXIST;
645
rcu_read_lock();
646
for_each_sk_fl_rcu(sk, sfl) {
647
if (sfl->fl->label == freq->flr_label) {
648
if (freq->flr_flags & IPV6_FL_F_EXCL) {
649
rcu_read_unlock();
650
goto done;
651
}
652
fl1 = sfl->fl;
653
if (!atomic_inc_not_zero(&fl1->users))
654
fl1 = NULL;
655
break;
656
}
657
}
658
rcu_read_unlock();
659
660
if (!fl1)
661
fl1 = fl_lookup(net, freq->flr_label);
662
if (fl1) {
663
recheck:
664
err = -EEXIST;
665
if (freq->flr_flags&IPV6_FL_F_EXCL)
666
goto release;
667
err = -EPERM;
668
if (fl1->share == IPV6_FL_S_EXCL ||
669
fl1->share != fl->share ||
670
((fl1->share == IPV6_FL_S_PROCESS) &&
671
(fl1->owner.pid != fl->owner.pid)) ||
672
((fl1->share == IPV6_FL_S_USER) &&
673
!uid_eq(fl1->owner.uid, fl->owner.uid)))
674
goto release;
675
676
err = -ENOMEM;
677
if (!sfl1)
678
goto release;
679
if (fl->linger > fl1->linger)
680
fl1->linger = fl->linger;
681
if ((long)(fl->expires - fl1->expires) > 0)
682
fl1->expires = fl->expires;
683
fl_link(sk, sfl1, fl1);
684
fl_free(fl);
685
return 0;
686
687
release:
688
fl_release(fl1);
689
goto done;
690
}
691
}
692
err = -ENOENT;
693
if (!(freq->flr_flags & IPV6_FL_F_CREATE))
694
goto done;
695
696
err = -ENOMEM;
697
if (!sfl1)
698
goto done;
699
700
err = mem_check(sk);
701
if (err != 0)
702
goto done;
703
704
fl1 = fl_intern(net, fl, freq->flr_label);
705
if (fl1)
706
goto recheck;
707
708
if (!freq->flr_label) {
709
size_t offset = offsetof(struct in6_flowlabel_req, flr_label);
710
711
if (copy_to_sockptr_offset(optval, offset, &fl->label,
712
sizeof(fl->label))) {
713
/* Intentionally ignore fault. */
714
}
715
}
716
717
fl_link(sk, sfl1, fl);
718
return 0;
719
done:
720
fl_free(fl);
721
kfree(sfl1);
722
return err;
723
}
724
725
int ipv6_flowlabel_opt(struct sock *sk, sockptr_t optval, int optlen)
726
{
727
struct in6_flowlabel_req freq;
728
729
if (optlen < sizeof(freq))
730
return -EINVAL;
731
if (copy_from_sockptr(&freq, optval, sizeof(freq)))
732
return -EFAULT;
733
734
switch (freq.flr_action) {
735
case IPV6_FL_A_PUT:
736
return ipv6_flowlabel_put(sk, &freq);
737
case IPV6_FL_A_RENEW:
738
return ipv6_flowlabel_renew(sk, &freq);
739
case IPV6_FL_A_GET:
740
return ipv6_flowlabel_get(sk, &freq, optval, optlen);
741
default:
742
return -EINVAL;
743
}
744
}
745
746
#ifdef CONFIG_PROC_FS
747
748
struct ip6fl_iter_state {
749
struct seq_net_private p;
750
struct pid_namespace *pid_ns;
751
int bucket;
752
};
753
754
#define ip6fl_seq_private(seq) ((struct ip6fl_iter_state *)(seq)->private)
755
756
static struct ip6_flowlabel *ip6fl_get_first(struct seq_file *seq)
757
{
758
struct ip6_flowlabel *fl = NULL;
759
struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
760
struct net *net = seq_file_net(seq);
761
762
for (state->bucket = 0; state->bucket <= FL_HASH_MASK; ++state->bucket) {
763
for_each_fl_rcu(state->bucket, fl) {
764
if (net_eq(fl->fl_net, net))
765
goto out;
766
}
767
}
768
fl = NULL;
769
out:
770
return fl;
771
}
772
773
static struct ip6_flowlabel *ip6fl_get_next(struct seq_file *seq, struct ip6_flowlabel *fl)
774
{
775
struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
776
struct net *net = seq_file_net(seq);
777
778
for_each_fl_continue_rcu(fl) {
779
if (net_eq(fl->fl_net, net))
780
goto out;
781
}
782
783
try_again:
784
if (++state->bucket <= FL_HASH_MASK) {
785
for_each_fl_rcu(state->bucket, fl) {
786
if (net_eq(fl->fl_net, net))
787
goto out;
788
}
789
goto try_again;
790
}
791
fl = NULL;
792
793
out:
794
return fl;
795
}
796
797
static struct ip6_flowlabel *ip6fl_get_idx(struct seq_file *seq, loff_t pos)
798
{
799
struct ip6_flowlabel *fl = ip6fl_get_first(seq);
800
if (fl)
801
while (pos && (fl = ip6fl_get_next(seq, fl)) != NULL)
802
--pos;
803
return pos ? NULL : fl;
804
}
805
806
static void *ip6fl_seq_start(struct seq_file *seq, loff_t *pos)
807
__acquires(RCU)
808
{
809
struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
810
811
state->pid_ns = proc_pid_ns(file_inode(seq->file)->i_sb);
812
813
rcu_read_lock();
814
return *pos ? ip6fl_get_idx(seq, *pos - 1) : SEQ_START_TOKEN;
815
}
816
817
static void *ip6fl_seq_next(struct seq_file *seq, void *v, loff_t *pos)
818
{
819
struct ip6_flowlabel *fl;
820
821
if (v == SEQ_START_TOKEN)
822
fl = ip6fl_get_first(seq);
823
else
824
fl = ip6fl_get_next(seq, v);
825
++*pos;
826
return fl;
827
}
828
829
static void ip6fl_seq_stop(struct seq_file *seq, void *v)
830
__releases(RCU)
831
{
832
rcu_read_unlock();
833
}
834
835
static int ip6fl_seq_show(struct seq_file *seq, void *v)
836
{
837
struct ip6fl_iter_state *state = ip6fl_seq_private(seq);
838
if (v == SEQ_START_TOKEN) {
839
seq_puts(seq, "Label S Owner Users Linger Expires Dst Opt\n");
840
} else {
841
struct ip6_flowlabel *fl = v;
842
seq_printf(seq,
843
"%05X %-1d %-6d %-6d %-6ld %-8ld %pi6 %-4d\n",
844
(unsigned int)ntohl(fl->label),
845
fl->share,
846
((fl->share == IPV6_FL_S_PROCESS) ?
847
pid_nr_ns(fl->owner.pid, state->pid_ns) :
848
((fl->share == IPV6_FL_S_USER) ?
849
from_kuid_munged(seq_user_ns(seq), fl->owner.uid) :
850
0)),
851
atomic_read(&fl->users),
852
fl->linger/HZ,
853
(long)(fl->expires - jiffies)/HZ,
854
&fl->dst,
855
fl->opt ? fl->opt->opt_nflen : 0);
856
}
857
return 0;
858
}
859
860
static const struct seq_operations ip6fl_seq_ops = {
861
.start = ip6fl_seq_start,
862
.next = ip6fl_seq_next,
863
.stop = ip6fl_seq_stop,
864
.show = ip6fl_seq_show,
865
};
866
867
static int __net_init ip6_flowlabel_proc_init(struct net *net)
868
{
869
if (!proc_create_net("ip6_flowlabel", 0444, net->proc_net,
870
&ip6fl_seq_ops, sizeof(struct ip6fl_iter_state)))
871
return -ENOMEM;
872
return 0;
873
}
874
875
static void __net_exit ip6_flowlabel_proc_fini(struct net *net)
876
{
877
remove_proc_entry("ip6_flowlabel", net->proc_net);
878
}
879
#else
880
static inline int ip6_flowlabel_proc_init(struct net *net)
881
{
882
return 0;
883
}
884
static inline void ip6_flowlabel_proc_fini(struct net *net)
885
{
886
}
887
#endif
888
889
static void __net_exit ip6_flowlabel_net_exit(struct net *net)
890
{
891
ip6_fl_purge(net);
892
ip6_flowlabel_proc_fini(net);
893
}
894
895
static struct pernet_operations ip6_flowlabel_net_ops = {
896
.init = ip6_flowlabel_proc_init,
897
.exit = ip6_flowlabel_net_exit,
898
};
899
900
int ip6_flowlabel_init(void)
901
{
902
return register_pernet_subsys(&ip6_flowlabel_net_ops);
903
}
904
905
void ip6_flowlabel_cleanup(void)
906
{
907
static_key_deferred_flush(&ipv6_flowlabel_exclusive);
908
timer_delete(&ip6_fl_gc_timer);
909
unregister_pernet_subsys(&ip6_flowlabel_net_ops);
910
}
911
912