aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/neighbour.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@openvz.org>2007-12-01 08:08:16 -0500
committerDavid S. Miller <davem@davemloft.net>2008-01-28 17:55:24 -0500
commitc3bac5a71b24f6ed892b250d4f7511cedc33d34c (patch)
tree449fac046faf749a6c24e5edc9c03c2441e853b3 /net/core/neighbour.c
parent3c607bbb472814f01b077af01ae326944ff6b8b3 (diff)
[NEIGH]: Use the ctl paths to create neighbours sysctls
The appropriate path is prepared right inside this function. It is prepared similar to how the ctl tables were. Since the path is modified, it is put on the stack, to avoid possible races with multiple calls to neigh_sysctl_register() : it is called by protocols and I didn't find any protection in this case. Did I overlooked the rtnl lock?. The stack growth of the neigh_sysctl_register() is 40 bytes. I believe this is OK, since this is not that much and this function is not called with the deep stack (device/protocols register). The device's name is stored on the template to free it later. This will help with the net namespaces, as each namespace should have its own set of these ctls. Besides, this saves ~350 bytes from the neigh template :) Signed-off-by: Pavel Emelyanov <xemul@openvz.org> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core/neighbour.c')
-rw-r--r--net/core/neighbour.c77
1 files changed, 27 insertions, 50 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 5dbe26f460d..4b6dd1e66f1 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2484,11 +2484,8 @@ void neigh_app_ns(struct neighbour *n)
2484 2484
2485static struct neigh_sysctl_table { 2485static struct neigh_sysctl_table {
2486 struct ctl_table_header *sysctl_header; 2486 struct ctl_table_header *sysctl_header;
2487 ctl_table neigh_vars[__NET_NEIGH_MAX]; 2487 struct ctl_table neigh_vars[__NET_NEIGH_MAX];
2488 ctl_table neigh_dev[2]; 2488 char *dev_name;
2489 ctl_table neigh_neigh_dir[2];
2490 ctl_table neigh_proto_dir[2];
2491 ctl_table neigh_root_dir[2];
2492} neigh_sysctl_template __read_mostly = { 2489} neigh_sysctl_template __read_mostly = {
2493 .neigh_vars = { 2490 .neigh_vars = {
2494 { 2491 {
@@ -2619,32 +2616,7 @@ static struct neigh_sysctl_table {
2619 .mode = 0644, 2616 .mode = 0644,
2620 .proc_handler = &proc_dointvec, 2617 .proc_handler = &proc_dointvec,
2621 }, 2618 },
2622 {} 2619 {},
2623 },
2624 .neigh_dev = {
2625 {
2626 .ctl_name = NET_PROTO_CONF_DEFAULT,
2627 .procname = "default",
2628 .mode = 0555,
2629 },
2630 },
2631 .neigh_neigh_dir = {
2632 {
2633 .procname = "neigh",
2634 .mode = 0555,
2635 },
2636 },
2637 .neigh_proto_dir = {
2638 {
2639 .mode = 0555,
2640 },
2641 },
2642 .neigh_root_dir = {
2643 {
2644 .ctl_name = CTL_NET,
2645 .procname = "net",
2646 .mode = 0555,
2647 },
2648 }, 2620 },
2649}; 2621};
2650 2622
@@ -2654,7 +2626,19 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2654{ 2626{
2655 struct neigh_sysctl_table *t; 2627 struct neigh_sysctl_table *t;
2656 const char *dev_name_source = NULL; 2628 const char *dev_name_source = NULL;
2657 char *dev_name = NULL; 2629
2630#define NEIGH_CTL_PATH_ROOT 0
2631#define NEIGH_CTL_PATH_PROTO 1
2632#define NEIGH_CTL_PATH_NEIGH 2
2633#define NEIGH_CTL_PATH_DEV 3
2634
2635 struct ctl_path neigh_path[] = {
2636 { .procname = "net", .ctl_name = CTL_NET, },
2637 { .procname = "proto", .ctl_name = 0, },
2638 { .procname = "neigh", .ctl_name = 0, },
2639 { .procname = "default", .ctl_name = NET_PROTO_CONF_DEFAULT, },
2640 { },
2641 };
2658 2642
2659 t = kmemdup(&neigh_sysctl_template, sizeof(*t), GFP_KERNEL); 2643 t = kmemdup(&neigh_sysctl_template, sizeof(*t), GFP_KERNEL);
2660 if (!t) 2644 if (!t)
@@ -2677,11 +2661,11 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2677 2661
2678 if (dev) { 2662 if (dev) {
2679 dev_name_source = dev->name; 2663 dev_name_source = dev->name;
2680 t->neigh_dev[0].ctl_name = dev->ifindex; 2664 neigh_path[NEIGH_CTL_PATH_DEV].ctl_name = dev->ifindex;
2681 /* Terminate the table early */ 2665 /* Terminate the table early */
2682 memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); 2666 memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14]));
2683 } else { 2667 } else {
2684 dev_name_source = t->neigh_dev[0].procname; 2668 dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname;
2685 t->neigh_vars[14].data = (int *)(p + 1); 2669 t->neigh_vars[14].data = (int *)(p + 1);
2686 t->neigh_vars[15].data = (int *)(p + 1) + 1; 2670 t->neigh_vars[15].data = (int *)(p + 1) + 1;
2687 t->neigh_vars[16].data = (int *)(p + 1) + 2; 2671 t->neigh_vars[16].data = (int *)(p + 1) + 2;
@@ -2716,23 +2700,16 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2716 t->neigh_vars[13].ctl_name = CTL_UNNUMBERED; 2700 t->neigh_vars[13].ctl_name = CTL_UNNUMBERED;
2717 } 2701 }
2718 2702
2719 dev_name = kstrdup(dev_name_source, GFP_KERNEL); 2703 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL);
2720 if (!dev_name) 2704 if (!t->dev_name)
2721 goto free; 2705 goto free;
2722 2706
2723 t->neigh_dev[0].procname = dev_name; 2707 neigh_path[NEIGH_CTL_PATH_DEV].procname = t->dev_name;
2724 2708 neigh_path[NEIGH_CTL_PATH_NEIGH].ctl_name = pdev_id;
2725 t->neigh_neigh_dir[0].ctl_name = pdev_id; 2709 neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name;
2726 2710 neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id;
2727 t->neigh_proto_dir[0].procname = p_name;
2728 t->neigh_proto_dir[0].ctl_name = p_id;
2729
2730 t->neigh_dev[0].child = t->neigh_vars;
2731 t->neigh_neigh_dir[0].child = t->neigh_dev;
2732 t->neigh_proto_dir[0].child = t->neigh_neigh_dir;
2733 t->neigh_root_dir[0].child = t->neigh_proto_dir;
2734 2711
2735 t->sysctl_header = register_sysctl_table(t->neigh_root_dir); 2712 t->sysctl_header = register_sysctl_paths(neigh_path, t->neigh_vars);
2736 if (!t->sysctl_header) 2713 if (!t->sysctl_header)
2737 goto free_procname; 2714 goto free_procname;
2738 2715
@@ -2740,7 +2717,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2740 return 0; 2717 return 0;
2741 2718
2742free_procname: 2719free_procname:
2743 kfree(dev_name); 2720 kfree(t->dev_name);
2744free: 2721free:
2745 kfree(t); 2722 kfree(t);
2746err: 2723err:
@@ -2753,7 +2730,7 @@ void neigh_sysctl_unregister(struct neigh_parms *p)
2753 struct neigh_sysctl_table *t = p->sysctl_table; 2730 struct neigh_sysctl_table *t = p->sysctl_table;
2754 p->sysctl_table = NULL; 2731 p->sysctl_table = NULL;
2755 unregister_sysctl_table(t->sysctl_header); 2732 unregister_sysctl_table(t->sysctl_header);
2756 kfree(t->neigh_dev[0].procname); 2733 kfree(t->dev_name);
2757 kfree(t); 2734 kfree(t);
2758 } 2735 }
2759} 2736}