aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/neighbour.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/neighbour.c')
-rw-r--r--net/core/neighbour.c68
1 files changed, 17 insertions, 51 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index e587e6819698..bff37908bd55 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -15,6 +15,7 @@
15 * Harald Welte Add neighbour cache statistics like rtstat 15 * Harald Welte Add neighbour cache statistics like rtstat
16 */ 16 */
17 17
18#include <linux/slab.h>
18#include <linux/types.h> 19#include <linux/types.h>
19#include <linux/kernel.h> 20#include <linux/kernel.h>
20#include <linux/module.h> 21#include <linux/module.h>
@@ -771,6 +772,8 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
771} 772}
772 773
773static void neigh_invalidate(struct neighbour *neigh) 774static void neigh_invalidate(struct neighbour *neigh)
775 __releases(neigh->lock)
776 __acquires(neigh->lock)
774{ 777{
775 struct sk_buff *skb; 778 struct sk_buff *skb;
776 779
@@ -2092,7 +2095,7 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
2092 if (h > s_h) 2095 if (h > s_h)
2093 s_idx = 0; 2096 s_idx = 0;
2094 for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) { 2097 for (n = tbl->hash_buckets[h], idx = 0; n; n = n->next) {
2095 if (dev_net(n->dev) != net) 2098 if (!net_eq(dev_net(n->dev), net))
2096 continue; 2099 continue;
2097 if (idx < s_idx) 2100 if (idx < s_idx)
2098 goto next; 2101 goto next;
@@ -2417,8 +2420,7 @@ EXPORT_SYMBOL(neigh_seq_stop);
2417 2420
2418static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos) 2421static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos)
2419{ 2422{
2420 struct proc_dir_entry *pde = seq->private; 2423 struct neigh_table *tbl = seq->private;
2421 struct neigh_table *tbl = pde->data;
2422 int cpu; 2424 int cpu;
2423 2425
2424 if (*pos == 0) 2426 if (*pos == 0)
@@ -2435,8 +2437,7 @@ static void *neigh_stat_seq_start(struct seq_file *seq, loff_t *pos)
2435 2437
2436static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos) 2438static void *neigh_stat_seq_next(struct seq_file *seq, void *v, loff_t *pos)
2437{ 2439{
2438 struct proc_dir_entry *pde = seq->private; 2440 struct neigh_table *tbl = seq->private;
2439 struct neigh_table *tbl = pde->data;
2440 int cpu; 2441 int cpu;
2441 2442
2442 for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) { 2443 for (cpu = *pos; cpu < nr_cpu_ids; ++cpu) {
@@ -2455,8 +2456,7 @@ static void neigh_stat_seq_stop(struct seq_file *seq, void *v)
2455 2456
2456static int neigh_stat_seq_show(struct seq_file *seq, void *v) 2457static int neigh_stat_seq_show(struct seq_file *seq, void *v)
2457{ 2458{
2458 struct proc_dir_entry *pde = seq->private; 2459 struct neigh_table *tbl = seq->private;
2459 struct neigh_table *tbl = pde->data;
2460 struct neigh_statistics *st = v; 2460 struct neigh_statistics *st = v;
2461 2461
2462 if (v == SEQ_START_TOKEN) { 2462 if (v == SEQ_START_TOKEN) {
@@ -2501,7 +2501,7 @@ static int neigh_stat_seq_open(struct inode *inode, struct file *file)
2501 2501
2502 if (!ret) { 2502 if (!ret) {
2503 struct seq_file *sf = file->private_data; 2503 struct seq_file *sf = file->private_data;
2504 sf->private = PDE(inode); 2504 sf->private = PDE(inode)->data;
2505 } 2505 }
2506 return ret; 2506 return ret;
2507}; 2507};
@@ -2559,28 +2559,27 @@ EXPORT_SYMBOL(neigh_app_ns);
2559 2559
2560#ifdef CONFIG_SYSCTL 2560#ifdef CONFIG_SYSCTL
2561 2561
2562#define NEIGH_VARS_MAX 19
2563
2562static struct neigh_sysctl_table { 2564static struct neigh_sysctl_table {
2563 struct ctl_table_header *sysctl_header; 2565 struct ctl_table_header *sysctl_header;
2564 struct ctl_table neigh_vars[__NET_NEIGH_MAX]; 2566 struct ctl_table neigh_vars[NEIGH_VARS_MAX];
2565 char *dev_name; 2567 char *dev_name;
2566} neigh_sysctl_template __read_mostly = { 2568} neigh_sysctl_template __read_mostly = {
2567 .neigh_vars = { 2569 .neigh_vars = {
2568 { 2570 {
2569 .ctl_name = NET_NEIGH_MCAST_SOLICIT,
2570 .procname = "mcast_solicit", 2571 .procname = "mcast_solicit",
2571 .maxlen = sizeof(int), 2572 .maxlen = sizeof(int),
2572 .mode = 0644, 2573 .mode = 0644,
2573 .proc_handler = proc_dointvec, 2574 .proc_handler = proc_dointvec,
2574 }, 2575 },
2575 { 2576 {
2576 .ctl_name = NET_NEIGH_UCAST_SOLICIT,
2577 .procname = "ucast_solicit", 2577 .procname = "ucast_solicit",
2578 .maxlen = sizeof(int), 2578 .maxlen = sizeof(int),
2579 .mode = 0644, 2579 .mode = 0644,
2580 .proc_handler = proc_dointvec, 2580 .proc_handler = proc_dointvec,
2581 }, 2581 },
2582 { 2582 {
2583 .ctl_name = NET_NEIGH_APP_SOLICIT,
2584 .procname = "app_solicit", 2583 .procname = "app_solicit",
2585 .maxlen = sizeof(int), 2584 .maxlen = sizeof(int),
2586 .mode = 0644, 2585 .mode = 0644,
@@ -2593,38 +2592,30 @@ static struct neigh_sysctl_table {
2593 .proc_handler = proc_dointvec_userhz_jiffies, 2592 .proc_handler = proc_dointvec_userhz_jiffies,
2594 }, 2593 },
2595 { 2594 {
2596 .ctl_name = NET_NEIGH_REACHABLE_TIME,
2597 .procname = "base_reachable_time", 2595 .procname = "base_reachable_time",
2598 .maxlen = sizeof(int), 2596 .maxlen = sizeof(int),
2599 .mode = 0644, 2597 .mode = 0644,
2600 .proc_handler = proc_dointvec_jiffies, 2598 .proc_handler = proc_dointvec_jiffies,
2601 .strategy = sysctl_jiffies,
2602 }, 2599 },
2603 { 2600 {
2604 .ctl_name = NET_NEIGH_DELAY_PROBE_TIME,
2605 .procname = "delay_first_probe_time", 2601 .procname = "delay_first_probe_time",
2606 .maxlen = sizeof(int), 2602 .maxlen = sizeof(int),
2607 .mode = 0644, 2603 .mode = 0644,
2608 .proc_handler = proc_dointvec_jiffies, 2604 .proc_handler = proc_dointvec_jiffies,
2609 .strategy = sysctl_jiffies,
2610 }, 2605 },
2611 { 2606 {
2612 .ctl_name = NET_NEIGH_GC_STALE_TIME,
2613 .procname = "gc_stale_time", 2607 .procname = "gc_stale_time",
2614 .maxlen = sizeof(int), 2608 .maxlen = sizeof(int),
2615 .mode = 0644, 2609 .mode = 0644,
2616 .proc_handler = proc_dointvec_jiffies, 2610 .proc_handler = proc_dointvec_jiffies,
2617 .strategy = sysctl_jiffies,
2618 }, 2611 },
2619 { 2612 {
2620 .ctl_name = NET_NEIGH_UNRES_QLEN,
2621 .procname = "unres_qlen", 2613 .procname = "unres_qlen",
2622 .maxlen = sizeof(int), 2614 .maxlen = sizeof(int),
2623 .mode = 0644, 2615 .mode = 0644,
2624 .proc_handler = proc_dointvec, 2616 .proc_handler = proc_dointvec,
2625 }, 2617 },
2626 { 2618 {
2627 .ctl_name = NET_NEIGH_PROXY_QLEN,
2628 .procname = "proxy_qlen", 2619 .procname = "proxy_qlen",
2629 .maxlen = sizeof(int), 2620 .maxlen = sizeof(int),
2630 .mode = 0644, 2621 .mode = 0644,
@@ -2649,45 +2640,36 @@ static struct neigh_sysctl_table {
2649 .proc_handler = proc_dointvec_userhz_jiffies, 2640 .proc_handler = proc_dointvec_userhz_jiffies,
2650 }, 2641 },
2651 { 2642 {
2652 .ctl_name = NET_NEIGH_RETRANS_TIME_MS,
2653 .procname = "retrans_time_ms", 2643 .procname = "retrans_time_ms",
2654 .maxlen = sizeof(int), 2644 .maxlen = sizeof(int),
2655 .mode = 0644, 2645 .mode = 0644,
2656 .proc_handler = proc_dointvec_ms_jiffies, 2646 .proc_handler = proc_dointvec_ms_jiffies,
2657 .strategy = sysctl_ms_jiffies,
2658 }, 2647 },
2659 { 2648 {
2660 .ctl_name = NET_NEIGH_REACHABLE_TIME_MS,
2661 .procname = "base_reachable_time_ms", 2649 .procname = "base_reachable_time_ms",
2662 .maxlen = sizeof(int), 2650 .maxlen = sizeof(int),
2663 .mode = 0644, 2651 .mode = 0644,
2664 .proc_handler = proc_dointvec_ms_jiffies, 2652 .proc_handler = proc_dointvec_ms_jiffies,
2665 .strategy = sysctl_ms_jiffies,
2666 }, 2653 },
2667 { 2654 {
2668 .ctl_name = NET_NEIGH_GC_INTERVAL,
2669 .procname = "gc_interval", 2655 .procname = "gc_interval",
2670 .maxlen = sizeof(int), 2656 .maxlen = sizeof(int),
2671 .mode = 0644, 2657 .mode = 0644,
2672 .proc_handler = proc_dointvec_jiffies, 2658 .proc_handler = proc_dointvec_jiffies,
2673 .strategy = sysctl_jiffies,
2674 }, 2659 },
2675 { 2660 {
2676 .ctl_name = NET_NEIGH_GC_THRESH1,
2677 .procname = "gc_thresh1", 2661 .procname = "gc_thresh1",
2678 .maxlen = sizeof(int), 2662 .maxlen = sizeof(int),
2679 .mode = 0644, 2663 .mode = 0644,
2680 .proc_handler = proc_dointvec, 2664 .proc_handler = proc_dointvec,
2681 }, 2665 },
2682 { 2666 {
2683 .ctl_name = NET_NEIGH_GC_THRESH2,
2684 .procname = "gc_thresh2", 2667 .procname = "gc_thresh2",
2685 .maxlen = sizeof(int), 2668 .maxlen = sizeof(int),
2686 .mode = 0644, 2669 .mode = 0644,
2687 .proc_handler = proc_dointvec, 2670 .proc_handler = proc_dointvec,
2688 }, 2671 },
2689 { 2672 {
2690 .ctl_name = NET_NEIGH_GC_THRESH3,
2691 .procname = "gc_thresh3", 2673 .procname = "gc_thresh3",
2692 .maxlen = sizeof(int), 2674 .maxlen = sizeof(int),
2693 .mode = 0644, 2675 .mode = 0644,
@@ -2698,8 +2680,7 @@ static struct neigh_sysctl_table {
2698}; 2680};
2699 2681
2700int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, 2682int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2701 int p_id, int pdev_id, char *p_name, 2683 char *p_name, proc_handler *handler)
2702 proc_handler *handler, ctl_handler *strategy)
2703{ 2684{
2704 struct neigh_sysctl_table *t; 2685 struct neigh_sysctl_table *t;
2705 const char *dev_name_source = NULL; 2686 const char *dev_name_source = NULL;
@@ -2710,10 +2691,10 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2710#define NEIGH_CTL_PATH_DEV 3 2691#define NEIGH_CTL_PATH_DEV 3
2711 2692
2712 struct ctl_path neigh_path[] = { 2693 struct ctl_path neigh_path[] = {
2713 { .procname = "net", .ctl_name = CTL_NET, }, 2694 { .procname = "net", },
2714 { .procname = "proto", .ctl_name = 0, }, 2695 { .procname = "proto", },
2715 { .procname = "neigh", .ctl_name = 0, }, 2696 { .procname = "neigh", },
2716 { .procname = "default", .ctl_name = NET_PROTO_CONF_DEFAULT, }, 2697 { .procname = "default", },
2717 { }, 2698 { },
2718 }; 2699 };
2719 2700
@@ -2738,7 +2719,6 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2738 2719
2739 if (dev) { 2720 if (dev) {
2740 dev_name_source = dev->name; 2721 dev_name_source = dev->name;
2741 neigh_path[NEIGH_CTL_PATH_DEV].ctl_name = dev->ifindex;
2742 /* Terminate the table early */ 2722 /* Terminate the table early */
2743 memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); 2723 memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14]));
2744 } else { 2724 } else {
@@ -2750,31 +2730,19 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2750 } 2730 }
2751 2731
2752 2732
2753 if (handler || strategy) { 2733 if (handler) {
2754 /* RetransTime */ 2734 /* RetransTime */
2755 t->neigh_vars[3].proc_handler = handler; 2735 t->neigh_vars[3].proc_handler = handler;
2756 t->neigh_vars[3].strategy = strategy;
2757 t->neigh_vars[3].extra1 = dev; 2736 t->neigh_vars[3].extra1 = dev;
2758 if (!strategy)
2759 t->neigh_vars[3].ctl_name = CTL_UNNUMBERED;
2760 /* ReachableTime */ 2737 /* ReachableTime */
2761 t->neigh_vars[4].proc_handler = handler; 2738 t->neigh_vars[4].proc_handler = handler;
2762 t->neigh_vars[4].strategy = strategy;
2763 t->neigh_vars[4].extra1 = dev; 2739 t->neigh_vars[4].extra1 = dev;
2764 if (!strategy)
2765 t->neigh_vars[4].ctl_name = CTL_UNNUMBERED;
2766 /* RetransTime (in milliseconds)*/ 2740 /* RetransTime (in milliseconds)*/
2767 t->neigh_vars[12].proc_handler = handler; 2741 t->neigh_vars[12].proc_handler = handler;
2768 t->neigh_vars[12].strategy = strategy;
2769 t->neigh_vars[12].extra1 = dev; 2742 t->neigh_vars[12].extra1 = dev;
2770 if (!strategy)
2771 t->neigh_vars[12].ctl_name = CTL_UNNUMBERED;
2772 /* ReachableTime (in milliseconds) */ 2743 /* ReachableTime (in milliseconds) */
2773 t->neigh_vars[13].proc_handler = handler; 2744 t->neigh_vars[13].proc_handler = handler;
2774 t->neigh_vars[13].strategy = strategy;
2775 t->neigh_vars[13].extra1 = dev; 2745 t->neigh_vars[13].extra1 = dev;
2776 if (!strategy)
2777 t->neigh_vars[13].ctl_name = CTL_UNNUMBERED;
2778 } 2746 }
2779 2747
2780 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL); 2748 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL);
@@ -2782,9 +2750,7 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2782 goto free; 2750 goto free;
2783 2751
2784 neigh_path[NEIGH_CTL_PATH_DEV].procname = t->dev_name; 2752 neigh_path[NEIGH_CTL_PATH_DEV].procname = t->dev_name;
2785 neigh_path[NEIGH_CTL_PATH_NEIGH].ctl_name = pdev_id;
2786 neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name; 2753 neigh_path[NEIGH_CTL_PATH_PROTO].procname = p_name;
2787 neigh_path[NEIGH_CTL_PATH_PROTO].ctl_name = p_id;
2788 2754
2789 t->sysctl_header = 2755 t->sysctl_header =
2790 register_net_sysctl_table(neigh_parms_net(p), neigh_path, t->neigh_vars); 2756 register_net_sysctl_table(neigh_parms_net(p), neigh_path, t->neigh_vars);