summaryrefslogtreecommitdiffstats
path: root/net/can/proc.c
diff options
context:
space:
mode:
authorMario Kicherer <dev@kicherer.org>2017-02-21 06:19:47 -0500
committerMarc Kleine-Budde <mkl@pengutronix.de>2017-04-04 11:35:58 -0400
commit8e8cda6d737d356054c9eeef642aec0e8ae7e6bc (patch)
treebdc78138b5beca98f398c86ad65c526bbea2ebf8 /net/can/proc.c
parentdabf54dd1c6369160f8d4c793a8613dfb4e7848a (diff)
can: initial support for network namespaces
This patch adds initial support for network namespaces. The changes only enable support in the CAN raw, proc and af_can code. GW and BCM still have their checks that ensure that they are used only from the main namespace. The patch boils down to moving the global structures, i.e. the global filter list and their /proc stats, into a per-namespace structure and passing around the corresponding "struct net" in a lot of different places. Changes since v1: - rebased on current HEAD (2bfe01e) - fixed overlong line Signed-off-by: Mario Kicherer <dev@kicherer.org> Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
Diffstat (limited to 'net/can/proc.c')
-rw-r--r--net/can/proc.c144
1 files changed, 70 insertions, 74 deletions
diff --git a/net/can/proc.c b/net/can/proc.c
index 85ef7bb0f176..9a8d54d57b22 100644
--- a/net/can/proc.c
+++ b/net/can/proc.c
@@ -62,17 +62,6 @@
62#define CAN_PROC_RCVLIST_EFF "rcvlist_eff" 62#define CAN_PROC_RCVLIST_EFF "rcvlist_eff"
63#define CAN_PROC_RCVLIST_ERR "rcvlist_err" 63#define CAN_PROC_RCVLIST_ERR "rcvlist_err"
64 64
65static struct proc_dir_entry *can_dir;
66static struct proc_dir_entry *pde_version;
67static struct proc_dir_entry *pde_stats;
68static struct proc_dir_entry *pde_reset_stats;
69static struct proc_dir_entry *pde_rcvlist_all;
70static struct proc_dir_entry *pde_rcvlist_fil;
71static struct proc_dir_entry *pde_rcvlist_inv;
72static struct proc_dir_entry *pde_rcvlist_sff;
73static struct proc_dir_entry *pde_rcvlist_eff;
74static struct proc_dir_entry *pde_rcvlist_err;
75
76static int user_reset; 65static int user_reset;
77 66
78static const char rx_list_name[][8] = { 67static const char rx_list_name[][8] = {
@@ -351,20 +340,21 @@ static inline void can_rcvlist_proc_show_one(struct seq_file *m, int idx,
351static int can_rcvlist_proc_show(struct seq_file *m, void *v) 340static int can_rcvlist_proc_show(struct seq_file *m, void *v)
352{ 341{
353 /* double cast to prevent GCC warning */ 342 /* double cast to prevent GCC warning */
354 int idx = (int)(long)m->private; 343 int idx = (int)(long)PDE_DATA(m->file->f_inode);
355 struct net_device *dev; 344 struct net_device *dev;
356 struct dev_rcv_lists *d; 345 struct dev_rcv_lists *d;
346 struct net *net = m->private;
357 347
358 seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]); 348 seq_printf(m, "\nreceive list '%s':\n", rx_list_name[idx]);
359 349
360 rcu_read_lock(); 350 rcu_read_lock();
361 351
362 /* receive list for 'all' CAN devices (dev == NULL) */ 352 /* receive list for 'all' CAN devices (dev == NULL) */
363 d = &can_rx_alldev_list; 353 d = net->can.can_rx_alldev_list;
364 can_rcvlist_proc_show_one(m, idx, NULL, d); 354 can_rcvlist_proc_show_one(m, idx, NULL, d);
365 355
366 /* receive list for registered CAN devices */ 356 /* receive list for registered CAN devices */
367 for_each_netdev_rcu(&init_net, dev) { 357 for_each_netdev_rcu(net, dev) {
368 if (dev->type == ARPHRD_CAN && dev->ml_priv) 358 if (dev->type == ARPHRD_CAN && dev->ml_priv)
369 can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv); 359 can_rcvlist_proc_show_one(m, idx, dev, dev->ml_priv);
370 } 360 }
@@ -377,7 +367,7 @@ static int can_rcvlist_proc_show(struct seq_file *m, void *v)
377 367
378static int can_rcvlist_proc_open(struct inode *inode, struct file *file) 368static int can_rcvlist_proc_open(struct inode *inode, struct file *file)
379{ 369{
380 return single_open(file, can_rcvlist_proc_show, PDE_DATA(inode)); 370 return single_open_net(inode, file, can_rcvlist_proc_show);
381} 371}
382 372
383static const struct file_operations can_rcvlist_proc_fops = { 373static const struct file_operations can_rcvlist_proc_fops = {
@@ -417,6 +407,7 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
417{ 407{
418 struct net_device *dev; 408 struct net_device *dev;
419 struct dev_rcv_lists *d; 409 struct dev_rcv_lists *d;
410 struct net *net = m->private;
420 411
421 /* RX_SFF */ 412 /* RX_SFF */
422 seq_puts(m, "\nreceive list 'rx_sff':\n"); 413 seq_puts(m, "\nreceive list 'rx_sff':\n");
@@ -424,11 +415,11 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
424 rcu_read_lock(); 415 rcu_read_lock();
425 416
426 /* sff receive list for 'all' CAN devices (dev == NULL) */ 417 /* sff receive list for 'all' CAN devices (dev == NULL) */
427 d = &can_rx_alldev_list; 418 d = net->can.can_rx_alldev_list;
428 can_rcvlist_proc_show_array(m, NULL, d->rx_sff, ARRAY_SIZE(d->rx_sff)); 419 can_rcvlist_proc_show_array(m, NULL, d->rx_sff, ARRAY_SIZE(d->rx_sff));
429 420
430 /* sff receive list for registered CAN devices */ 421 /* sff receive list for registered CAN devices */
431 for_each_netdev_rcu(&init_net, dev) { 422 for_each_netdev_rcu(net, dev) {
432 if (dev->type == ARPHRD_CAN && dev->ml_priv) { 423 if (dev->type == ARPHRD_CAN && dev->ml_priv) {
433 d = dev->ml_priv; 424 d = dev->ml_priv;
434 can_rcvlist_proc_show_array(m, dev, d->rx_sff, 425 can_rcvlist_proc_show_array(m, dev, d->rx_sff,
@@ -444,7 +435,7 @@ static int can_rcvlist_sff_proc_show(struct seq_file *m, void *v)
444 435
445static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file) 436static int can_rcvlist_sff_proc_open(struct inode *inode, struct file *file)
446{ 437{
447 return single_open(file, can_rcvlist_sff_proc_show, NULL); 438 return single_open_net(inode, file, can_rcvlist_sff_proc_show);
448} 439}
449 440
450static const struct file_operations can_rcvlist_sff_proc_fops = { 441static const struct file_operations can_rcvlist_sff_proc_fops = {
@@ -460,6 +451,7 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
460{ 451{
461 struct net_device *dev; 452 struct net_device *dev;
462 struct dev_rcv_lists *d; 453 struct dev_rcv_lists *d;
454 struct net *net = m->private;
463 455
464 /* RX_EFF */ 456 /* RX_EFF */
465 seq_puts(m, "\nreceive list 'rx_eff':\n"); 457 seq_puts(m, "\nreceive list 'rx_eff':\n");
@@ -467,11 +459,11 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
467 rcu_read_lock(); 459 rcu_read_lock();
468 460
469 /* eff receive list for 'all' CAN devices (dev == NULL) */ 461 /* eff receive list for 'all' CAN devices (dev == NULL) */
470 d = &can_rx_alldev_list; 462 d = net->can.can_rx_alldev_list;
471 can_rcvlist_proc_show_array(m, NULL, d->rx_eff, ARRAY_SIZE(d->rx_eff)); 463 can_rcvlist_proc_show_array(m, NULL, d->rx_eff, ARRAY_SIZE(d->rx_eff));
472 464
473 /* eff receive list for registered CAN devices */ 465 /* eff receive list for registered CAN devices */
474 for_each_netdev_rcu(&init_net, dev) { 466 for_each_netdev_rcu(net, dev) {
475 if (dev->type == ARPHRD_CAN && dev->ml_priv) { 467 if (dev->type == ARPHRD_CAN && dev->ml_priv) {
476 d = dev->ml_priv; 468 d = dev->ml_priv;
477 can_rcvlist_proc_show_array(m, dev, d->rx_eff, 469 can_rcvlist_proc_show_array(m, dev, d->rx_eff,
@@ -487,7 +479,7 @@ static int can_rcvlist_eff_proc_show(struct seq_file *m, void *v)
487 479
488static int can_rcvlist_eff_proc_open(struct inode *inode, struct file *file) 480static int can_rcvlist_eff_proc_open(struct inode *inode, struct file *file)
489{ 481{
490 return single_open(file, can_rcvlist_eff_proc_show, NULL); 482 return single_open_net(inode, file, can_rcvlist_eff_proc_show);
491} 483}
492 484
493static const struct file_operations can_rcvlist_eff_proc_fops = { 485static const struct file_operations can_rcvlist_eff_proc_fops = {
@@ -499,81 +491,85 @@ static const struct file_operations can_rcvlist_eff_proc_fops = {
499}; 491};
500 492
501/* 493/*
502 * proc utility functions
503 */
504
505static void can_remove_proc_readentry(const char *name)
506{
507 if (can_dir)
508 remove_proc_entry(name, can_dir);
509}
510
511/*
512 * can_init_proc - create main CAN proc directory and procfs entries 494 * can_init_proc - create main CAN proc directory and procfs entries
513 */ 495 */
514void can_init_proc(void) 496void can_init_proc(struct net *net)
515{ 497{
516 /* create /proc/net/can directory */ 498 /* create /proc/net/can directory */
517 can_dir = proc_mkdir("can", init_net.proc_net); 499 net->can.proc_dir = proc_net_mkdir(net, "can", net->proc_net);
518 500
519 if (!can_dir) { 501 if (!net->can.proc_dir) {
520 pr_info("can: failed to create /proc/net/can.\n"); 502 printk(KERN_INFO "can: failed to create /proc/net/can . "
503 "CONFIG_PROC_FS missing?\n");
521 return; 504 return;
522 } 505 }
523 506
524 /* own procfs entries from the AF_CAN core */ 507 /* own procfs entries from the AF_CAN core */
525 pde_version = proc_create(CAN_PROC_VERSION, 0644, can_dir, 508 net->can.pde_version = proc_create(CAN_PROC_VERSION, 0644,
526 &can_version_proc_fops); 509 net->can.proc_dir,
527 pde_stats = proc_create(CAN_PROC_STATS, 0644, can_dir, 510 &can_version_proc_fops);
528 &can_stats_proc_fops); 511 net->can.pde_stats = proc_create(CAN_PROC_STATS, 0644,
529 pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644, can_dir, 512 net->can.proc_dir,
530 &can_reset_stats_proc_fops); 513 &can_stats_proc_fops);
531 pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644, can_dir, 514 net->can.pde_reset_stats = proc_create(CAN_PROC_RESET_STATS, 0644,
532 &can_rcvlist_proc_fops, (void *)RX_ERR); 515 net->can.proc_dir,
533 pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644, can_dir, 516 &can_reset_stats_proc_fops);
534 &can_rcvlist_proc_fops, (void *)RX_ALL); 517 net->can.pde_rcvlist_err = proc_create_data(CAN_PROC_RCVLIST_ERR, 0644,
535 pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644, can_dir, 518 net->can.proc_dir,
536 &can_rcvlist_proc_fops, (void *)RX_FIL); 519 &can_rcvlist_proc_fops,
537 pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644, can_dir, 520 (void *)RX_ERR);
538 &can_rcvlist_proc_fops, (void *)RX_INV); 521 net->can.pde_rcvlist_all = proc_create_data(CAN_PROC_RCVLIST_ALL, 0644,
539 pde_rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644, can_dir, 522 net->can.proc_dir,
540 &can_rcvlist_eff_proc_fops); 523 &can_rcvlist_proc_fops,
541 pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644, can_dir, 524 (void *)RX_ALL);
542 &can_rcvlist_sff_proc_fops); 525 net->can.pde_rcvlist_fil = proc_create_data(CAN_PROC_RCVLIST_FIL, 0644,
526 net->can.proc_dir,
527 &can_rcvlist_proc_fops,
528 (void *)RX_FIL);
529 net->can.pde_rcvlist_inv = proc_create_data(CAN_PROC_RCVLIST_INV, 0644,
530 net->can.proc_dir,
531 &can_rcvlist_proc_fops,
532 (void *)RX_INV);
533 net->can.pde_rcvlist_eff = proc_create(CAN_PROC_RCVLIST_EFF, 0644,
534 net->can.proc_dir,
535 &can_rcvlist_eff_proc_fops);
536 net->can.pde_rcvlist_sff = proc_create(CAN_PROC_RCVLIST_SFF, 0644,
537 net->can.proc_dir,
538 &can_rcvlist_sff_proc_fops);
543} 539}
544 540
545/* 541/*
546 * can_remove_proc - remove procfs entries and main CAN proc directory 542 * can_remove_proc - remove procfs entries and main CAN proc directory
547 */ 543 */
548void can_remove_proc(void) 544void can_remove_proc(struct net *net)
549{ 545{
550 if (pde_version) 546 if (net->can.pde_version)
551 can_remove_proc_readentry(CAN_PROC_VERSION); 547 remove_proc_entry(CAN_PROC_VERSION, net->can.proc_dir);
552 548
553 if (pde_stats) 549 if (net->can.pde_stats)
554 can_remove_proc_readentry(CAN_PROC_STATS); 550 remove_proc_entry(CAN_PROC_STATS, net->can.proc_dir);
555 551
556 if (pde_reset_stats) 552 if (net->can.pde_reset_stats)
557 can_remove_proc_readentry(CAN_PROC_RESET_STATS); 553 remove_proc_entry(CAN_PROC_RESET_STATS, net->can.proc_dir);
558 554
559 if (pde_rcvlist_err) 555 if (net->can.pde_rcvlist_err)
560 can_remove_proc_readentry(CAN_PROC_RCVLIST_ERR); 556 remove_proc_entry(CAN_PROC_RCVLIST_ERR, net->can.proc_dir);
561 557
562 if (pde_rcvlist_all) 558 if (net->can.pde_rcvlist_all)
563 can_remove_proc_readentry(CAN_PROC_RCVLIST_ALL); 559 remove_proc_entry(CAN_PROC_RCVLIST_ALL, net->can.proc_dir);
564 560
565 if (pde_rcvlist_fil) 561 if (net->can.pde_rcvlist_fil)
566 can_remove_proc_readentry(CAN_PROC_RCVLIST_FIL); 562 remove_proc_entry(CAN_PROC_RCVLIST_FIL, net->can.proc_dir);
567 563
568 if (pde_rcvlist_inv) 564 if (net->can.pde_rcvlist_inv)
569 can_remove_proc_readentry(CAN_PROC_RCVLIST_INV); 565 remove_proc_entry(CAN_PROC_RCVLIST_INV, net->can.proc_dir);
570 566
571 if (pde_rcvlist_eff) 567 if (net->can.pde_rcvlist_eff)
572 can_remove_proc_readentry(CAN_PROC_RCVLIST_EFF); 568 remove_proc_entry(CAN_PROC_RCVLIST_EFF, net->can.proc_dir);
573 569
574 if (pde_rcvlist_sff) 570 if (net->can.pde_rcvlist_sff)
575 can_remove_proc_readentry(CAN_PROC_RCVLIST_SFF); 571 remove_proc_entry(CAN_PROC_RCVLIST_SFF, net->can.proc_dir);
576 572
577 if (can_dir) 573 if (net->can.proc_dir)
578 remove_proc_entry("can", init_net.proc_net); 574 remove_proc_entry("can", net->proc_net);
579} 575}