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.c162
1 files changed, 111 insertions, 51 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 039d51e6c284..2684794458ca 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -238,6 +238,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
238 it to safe state. 238 it to safe state.
239 */ 239 */
240 skb_queue_purge(&n->arp_queue); 240 skb_queue_purge(&n->arp_queue);
241 n->arp_queue_len_bytes = 0;
241 n->output = neigh_blackhole; 242 n->output = neigh_blackhole;
242 if (n->nud_state & NUD_VALID) 243 if (n->nud_state & NUD_VALID)
243 n->nud_state = NUD_NOARP; 244 n->nud_state = NUD_NOARP;
@@ -702,6 +703,7 @@ void neigh_destroy(struct neighbour *neigh)
702 printk(KERN_WARNING "Impossible event.\n"); 703 printk(KERN_WARNING "Impossible event.\n");
703 704
704 skb_queue_purge(&neigh->arp_queue); 705 skb_queue_purge(&neigh->arp_queue);
706 neigh->arp_queue_len_bytes = 0;
705 707
706 dev_put(neigh->dev); 708 dev_put(neigh->dev);
707 neigh_parms_put(neigh->parms); 709 neigh_parms_put(neigh->parms);
@@ -842,6 +844,7 @@ static void neigh_invalidate(struct neighbour *neigh)
842 write_lock(&neigh->lock); 844 write_lock(&neigh->lock);
843 } 845 }
844 skb_queue_purge(&neigh->arp_queue); 846 skb_queue_purge(&neigh->arp_queue);
847 neigh->arp_queue_len_bytes = 0;
845} 848}
846 849
847static void neigh_probe(struct neighbour *neigh) 850static void neigh_probe(struct neighbour *neigh)
@@ -980,15 +983,20 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb)
980 983
981 if (neigh->nud_state == NUD_INCOMPLETE) { 984 if (neigh->nud_state == NUD_INCOMPLETE) {
982 if (skb) { 985 if (skb) {
983 if (skb_queue_len(&neigh->arp_queue) >= 986 while (neigh->arp_queue_len_bytes + skb->truesize >
984 neigh->parms->queue_len) { 987 neigh->parms->queue_len_bytes) {
985 struct sk_buff *buff; 988 struct sk_buff *buff;
989
986 buff = __skb_dequeue(&neigh->arp_queue); 990 buff = __skb_dequeue(&neigh->arp_queue);
991 if (!buff)
992 break;
993 neigh->arp_queue_len_bytes -= buff->truesize;
987 kfree_skb(buff); 994 kfree_skb(buff);
988 NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards); 995 NEIGH_CACHE_STAT_INC(neigh->tbl, unres_discards);
989 } 996 }
990 skb_dst_force(skb); 997 skb_dst_force(skb);
991 __skb_queue_tail(&neigh->arp_queue, skb); 998 __skb_queue_tail(&neigh->arp_queue, skb);
999 neigh->arp_queue_len_bytes += skb->truesize;
992 } 1000 }
993 rc = 1; 1001 rc = 1;
994 } 1002 }
@@ -1175,6 +1183,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
1175 write_lock_bh(&neigh->lock); 1183 write_lock_bh(&neigh->lock);
1176 } 1184 }
1177 skb_queue_purge(&neigh->arp_queue); 1185 skb_queue_purge(&neigh->arp_queue);
1186 neigh->arp_queue_len_bytes = 0;
1178 } 1187 }
1179out: 1188out:
1180 if (update_isrouter) { 1189 if (update_isrouter) {
@@ -1747,7 +1756,11 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms)
1747 NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex); 1756 NLA_PUT_U32(skb, NDTPA_IFINDEX, parms->dev->ifindex);
1748 1757
1749 NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)); 1758 NLA_PUT_U32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt));
1750 NLA_PUT_U32(skb, NDTPA_QUEUE_LEN, parms->queue_len); 1759 NLA_PUT_U32(skb, NDTPA_QUEUE_LENBYTES, parms->queue_len_bytes);
1760 /* approximative value for deprecated QUEUE_LEN (in packets) */
1761 NLA_PUT_U32(skb, NDTPA_QUEUE_LEN,
1762 DIV_ROUND_UP(parms->queue_len_bytes,
1763 SKB_TRUESIZE(ETH_FRAME_LEN)));
1751 NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen); 1764 NLA_PUT_U32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen);
1752 NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes); 1765 NLA_PUT_U32(skb, NDTPA_APP_PROBES, parms->app_probes);
1753 NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes); 1766 NLA_PUT_U32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes);
@@ -1974,7 +1987,11 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1974 1987
1975 switch (i) { 1988 switch (i) {
1976 case NDTPA_QUEUE_LEN: 1989 case NDTPA_QUEUE_LEN:
1977 p->queue_len = nla_get_u32(tbp[i]); 1990 p->queue_len_bytes = nla_get_u32(tbp[i]) *
1991 SKB_TRUESIZE(ETH_FRAME_LEN);
1992 break;
1993 case NDTPA_QUEUE_LENBYTES:
1994 p->queue_len_bytes = nla_get_u32(tbp[i]);
1978 break; 1995 break;
1979 case NDTPA_PROXY_QLEN: 1996 case NDTPA_PROXY_QLEN:
1980 p->proxy_qlen = nla_get_u32(tbp[i]); 1997 p->proxy_qlen = nla_get_u32(tbp[i]);
@@ -2635,117 +2652,158 @@ EXPORT_SYMBOL(neigh_app_ns);
2635 2652
2636#ifdef CONFIG_SYSCTL 2653#ifdef CONFIG_SYSCTL
2637 2654
2638#define NEIGH_VARS_MAX 19 2655static int proc_unres_qlen(ctl_table *ctl, int write, void __user *buffer,
2656 size_t *lenp, loff_t *ppos)
2657{
2658 int size, ret;
2659 ctl_table tmp = *ctl;
2660
2661 tmp.data = &size;
2662 size = DIV_ROUND_UP(*(int *)ctl->data, SKB_TRUESIZE(ETH_FRAME_LEN));
2663 ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);
2664 if (write && !ret)
2665 *(int *)ctl->data = size * SKB_TRUESIZE(ETH_FRAME_LEN);
2666 return ret;
2667}
2668
2669enum {
2670 NEIGH_VAR_MCAST_PROBE,
2671 NEIGH_VAR_UCAST_PROBE,
2672 NEIGH_VAR_APP_PROBE,
2673 NEIGH_VAR_RETRANS_TIME,
2674 NEIGH_VAR_BASE_REACHABLE_TIME,
2675 NEIGH_VAR_DELAY_PROBE_TIME,
2676 NEIGH_VAR_GC_STALETIME,
2677 NEIGH_VAR_QUEUE_LEN,
2678 NEIGH_VAR_QUEUE_LEN_BYTES,
2679 NEIGH_VAR_PROXY_QLEN,
2680 NEIGH_VAR_ANYCAST_DELAY,
2681 NEIGH_VAR_PROXY_DELAY,
2682 NEIGH_VAR_LOCKTIME,
2683 NEIGH_VAR_RETRANS_TIME_MS,
2684 NEIGH_VAR_BASE_REACHABLE_TIME_MS,
2685 NEIGH_VAR_GC_INTERVAL,
2686 NEIGH_VAR_GC_THRESH1,
2687 NEIGH_VAR_GC_THRESH2,
2688 NEIGH_VAR_GC_THRESH3,
2689 NEIGH_VAR_MAX
2690};
2639 2691
2640static struct neigh_sysctl_table { 2692static struct neigh_sysctl_table {
2641 struct ctl_table_header *sysctl_header; 2693 struct ctl_table_header *sysctl_header;
2642 struct ctl_table neigh_vars[NEIGH_VARS_MAX]; 2694 struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1];
2643 char *dev_name; 2695 char *dev_name;
2644} neigh_sysctl_template __read_mostly = { 2696} neigh_sysctl_template __read_mostly = {
2645 .neigh_vars = { 2697 .neigh_vars = {
2646 { 2698 [NEIGH_VAR_MCAST_PROBE] = {
2647 .procname = "mcast_solicit", 2699 .procname = "mcast_solicit",
2648 .maxlen = sizeof(int), 2700 .maxlen = sizeof(int),
2649 .mode = 0644, 2701 .mode = 0644,
2650 .proc_handler = proc_dointvec, 2702 .proc_handler = proc_dointvec,
2651 }, 2703 },
2652 { 2704 [NEIGH_VAR_UCAST_PROBE] = {
2653 .procname = "ucast_solicit", 2705 .procname = "ucast_solicit",
2654 .maxlen = sizeof(int), 2706 .maxlen = sizeof(int),
2655 .mode = 0644, 2707 .mode = 0644,
2656 .proc_handler = proc_dointvec, 2708 .proc_handler = proc_dointvec,
2657 }, 2709 },
2658 { 2710 [NEIGH_VAR_APP_PROBE] = {
2659 .procname = "app_solicit", 2711 .procname = "app_solicit",
2660 .maxlen = sizeof(int), 2712 .maxlen = sizeof(int),
2661 .mode = 0644, 2713 .mode = 0644,
2662 .proc_handler = proc_dointvec, 2714 .proc_handler = proc_dointvec,
2663 }, 2715 },
2664 { 2716 [NEIGH_VAR_RETRANS_TIME] = {
2665 .procname = "retrans_time", 2717 .procname = "retrans_time",
2666 .maxlen = sizeof(int), 2718 .maxlen = sizeof(int),
2667 .mode = 0644, 2719 .mode = 0644,
2668 .proc_handler = proc_dointvec_userhz_jiffies, 2720 .proc_handler = proc_dointvec_userhz_jiffies,
2669 }, 2721 },
2670 { 2722 [NEIGH_VAR_BASE_REACHABLE_TIME] = {
2671 .procname = "base_reachable_time", 2723 .procname = "base_reachable_time",
2672 .maxlen = sizeof(int), 2724 .maxlen = sizeof(int),
2673 .mode = 0644, 2725 .mode = 0644,
2674 .proc_handler = proc_dointvec_jiffies, 2726 .proc_handler = proc_dointvec_jiffies,
2675 }, 2727 },
2676 { 2728 [NEIGH_VAR_DELAY_PROBE_TIME] = {
2677 .procname = "delay_first_probe_time", 2729 .procname = "delay_first_probe_time",
2678 .maxlen = sizeof(int), 2730 .maxlen = sizeof(int),
2679 .mode = 0644, 2731 .mode = 0644,
2680 .proc_handler = proc_dointvec_jiffies, 2732 .proc_handler = proc_dointvec_jiffies,
2681 }, 2733 },
2682 { 2734 [NEIGH_VAR_GC_STALETIME] = {
2683 .procname = "gc_stale_time", 2735 .procname = "gc_stale_time",
2684 .maxlen = sizeof(int), 2736 .maxlen = sizeof(int),
2685 .mode = 0644, 2737 .mode = 0644,
2686 .proc_handler = proc_dointvec_jiffies, 2738 .proc_handler = proc_dointvec_jiffies,
2687 }, 2739 },
2688 { 2740 [NEIGH_VAR_QUEUE_LEN] = {
2689 .procname = "unres_qlen", 2741 .procname = "unres_qlen",
2690 .maxlen = sizeof(int), 2742 .maxlen = sizeof(int),
2691 .mode = 0644, 2743 .mode = 0644,
2744 .proc_handler = proc_unres_qlen,
2745 },
2746 [NEIGH_VAR_QUEUE_LEN_BYTES] = {
2747 .procname = "unres_qlen_bytes",
2748 .maxlen = sizeof(int),
2749 .mode = 0644,
2692 .proc_handler = proc_dointvec, 2750 .proc_handler = proc_dointvec,
2693 }, 2751 },
2694 { 2752 [NEIGH_VAR_PROXY_QLEN] = {
2695 .procname = "proxy_qlen", 2753 .procname = "proxy_qlen",
2696 .maxlen = sizeof(int), 2754 .maxlen = sizeof(int),
2697 .mode = 0644, 2755 .mode = 0644,
2698 .proc_handler = proc_dointvec, 2756 .proc_handler = proc_dointvec,
2699 }, 2757 },
2700 { 2758 [NEIGH_VAR_ANYCAST_DELAY] = {
2701 .procname = "anycast_delay", 2759 .procname = "anycast_delay",
2702 .maxlen = sizeof(int), 2760 .maxlen = sizeof(int),
2703 .mode = 0644, 2761 .mode = 0644,
2704 .proc_handler = proc_dointvec_userhz_jiffies, 2762 .proc_handler = proc_dointvec_userhz_jiffies,
2705 }, 2763 },
2706 { 2764 [NEIGH_VAR_PROXY_DELAY] = {
2707 .procname = "proxy_delay", 2765 .procname = "proxy_delay",
2708 .maxlen = sizeof(int), 2766 .maxlen = sizeof(int),
2709 .mode = 0644, 2767 .mode = 0644,
2710 .proc_handler = proc_dointvec_userhz_jiffies, 2768 .proc_handler = proc_dointvec_userhz_jiffies,
2711 }, 2769 },
2712 { 2770 [NEIGH_VAR_LOCKTIME] = {
2713 .procname = "locktime", 2771 .procname = "locktime",
2714 .maxlen = sizeof(int), 2772 .maxlen = sizeof(int),
2715 .mode = 0644, 2773 .mode = 0644,
2716 .proc_handler = proc_dointvec_userhz_jiffies, 2774 .proc_handler = proc_dointvec_userhz_jiffies,
2717 }, 2775 },
2718 { 2776 [NEIGH_VAR_RETRANS_TIME_MS] = {
2719 .procname = "retrans_time_ms", 2777 .procname = "retrans_time_ms",
2720 .maxlen = sizeof(int), 2778 .maxlen = sizeof(int),
2721 .mode = 0644, 2779 .mode = 0644,
2722 .proc_handler = proc_dointvec_ms_jiffies, 2780 .proc_handler = proc_dointvec_ms_jiffies,
2723 }, 2781 },
2724 { 2782 [NEIGH_VAR_BASE_REACHABLE_TIME_MS] = {
2725 .procname = "base_reachable_time_ms", 2783 .procname = "base_reachable_time_ms",
2726 .maxlen = sizeof(int), 2784 .maxlen = sizeof(int),
2727 .mode = 0644, 2785 .mode = 0644,
2728 .proc_handler = proc_dointvec_ms_jiffies, 2786 .proc_handler = proc_dointvec_ms_jiffies,
2729 }, 2787 },
2730 { 2788 [NEIGH_VAR_GC_INTERVAL] = {
2731 .procname = "gc_interval", 2789 .procname = "gc_interval",
2732 .maxlen = sizeof(int), 2790 .maxlen = sizeof(int),
2733 .mode = 0644, 2791 .mode = 0644,
2734 .proc_handler = proc_dointvec_jiffies, 2792 .proc_handler = proc_dointvec_jiffies,
2735 }, 2793 },
2736 { 2794 [NEIGH_VAR_GC_THRESH1] = {
2737 .procname = "gc_thresh1", 2795 .procname = "gc_thresh1",
2738 .maxlen = sizeof(int), 2796 .maxlen = sizeof(int),
2739 .mode = 0644, 2797 .mode = 0644,
2740 .proc_handler = proc_dointvec, 2798 .proc_handler = proc_dointvec,
2741 }, 2799 },
2742 { 2800 [NEIGH_VAR_GC_THRESH2] = {
2743 .procname = "gc_thresh2", 2801 .procname = "gc_thresh2",
2744 .maxlen = sizeof(int), 2802 .maxlen = sizeof(int),
2745 .mode = 0644, 2803 .mode = 0644,
2746 .proc_handler = proc_dointvec, 2804 .proc_handler = proc_dointvec,
2747 }, 2805 },
2748 { 2806 [NEIGH_VAR_GC_THRESH3] = {
2749 .procname = "gc_thresh3", 2807 .procname = "gc_thresh3",
2750 .maxlen = sizeof(int), 2808 .maxlen = sizeof(int),
2751 .mode = 0644, 2809 .mode = 0644,
@@ -2778,47 +2836,49 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2778 if (!t) 2836 if (!t)
2779 goto err; 2837 goto err;
2780 2838
2781 t->neigh_vars[0].data = &p->mcast_probes; 2839 t->neigh_vars[NEIGH_VAR_MCAST_PROBE].data = &p->mcast_probes;
2782 t->neigh_vars[1].data = &p->ucast_probes; 2840 t->neigh_vars[NEIGH_VAR_UCAST_PROBE].data = &p->ucast_probes;
2783 t->neigh_vars[2].data = &p->app_probes; 2841 t->neigh_vars[NEIGH_VAR_APP_PROBE].data = &p->app_probes;
2784 t->neigh_vars[3].data = &p->retrans_time; 2842 t->neigh_vars[NEIGH_VAR_RETRANS_TIME].data = &p->retrans_time;
2785 t->neigh_vars[4].data = &p->base_reachable_time; 2843 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].data = &p->base_reachable_time;
2786 t->neigh_vars[5].data = &p->delay_probe_time; 2844 t->neigh_vars[NEIGH_VAR_DELAY_PROBE_TIME].data = &p->delay_probe_time;
2787 t->neigh_vars[6].data = &p->gc_staletime; 2845 t->neigh_vars[NEIGH_VAR_GC_STALETIME].data = &p->gc_staletime;
2788 t->neigh_vars[7].data = &p->queue_len; 2846 t->neigh_vars[NEIGH_VAR_QUEUE_LEN].data = &p->queue_len_bytes;
2789 t->neigh_vars[8].data = &p->proxy_qlen; 2847 t->neigh_vars[NEIGH_VAR_QUEUE_LEN_BYTES].data = &p->queue_len_bytes;
2790 t->neigh_vars[9].data = &p->anycast_delay; 2848 t->neigh_vars[NEIGH_VAR_PROXY_QLEN].data = &p->proxy_qlen;
2791 t->neigh_vars[10].data = &p->proxy_delay; 2849 t->neigh_vars[NEIGH_VAR_ANYCAST_DELAY].data = &p->anycast_delay;
2792 t->neigh_vars[11].data = &p->locktime; 2850 t->neigh_vars[NEIGH_VAR_PROXY_DELAY].data = &p->proxy_delay;
2793 t->neigh_vars[12].data = &p->retrans_time; 2851 t->neigh_vars[NEIGH_VAR_LOCKTIME].data = &p->locktime;
2794 t->neigh_vars[13].data = &p->base_reachable_time; 2852 t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].data = &p->retrans_time;
2853 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].data = &p->base_reachable_time;
2795 2854
2796 if (dev) { 2855 if (dev) {
2797 dev_name_source = dev->name; 2856 dev_name_source = dev->name;
2798 /* Terminate the table early */ 2857 /* Terminate the table early */
2799 memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); 2858 memset(&t->neigh_vars[NEIGH_VAR_GC_INTERVAL], 0,
2859 sizeof(t->neigh_vars[NEIGH_VAR_GC_INTERVAL]));
2800 } else { 2860 } else {
2801 dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname; 2861 dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname;
2802 t->neigh_vars[14].data = (int *)(p + 1); 2862 t->neigh_vars[NEIGH_VAR_GC_INTERVAL].data = (int *)(p + 1);
2803 t->neigh_vars[15].data = (int *)(p + 1) + 1; 2863 t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = (int *)(p + 1) + 1;
2804 t->neigh_vars[16].data = (int *)(p + 1) + 2; 2864 t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = (int *)(p + 1) + 2;
2805 t->neigh_vars[17].data = (int *)(p + 1) + 3; 2865 t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = (int *)(p + 1) + 3;
2806 } 2866 }
2807 2867
2808 2868
2809 if (handler) { 2869 if (handler) {
2810 /* RetransTime */ 2870 /* RetransTime */
2811 t->neigh_vars[3].proc_handler = handler; 2871 t->neigh_vars[NEIGH_VAR_RETRANS_TIME].proc_handler = handler;
2812 t->neigh_vars[3].extra1 = dev; 2872 t->neigh_vars[NEIGH_VAR_RETRANS_TIME].extra1 = dev;
2813 /* ReachableTime */ 2873 /* ReachableTime */
2814 t->neigh_vars[4].proc_handler = handler; 2874 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = handler;
2815 t->neigh_vars[4].extra1 = dev; 2875 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].extra1 = dev;
2816 /* RetransTime (in milliseconds)*/ 2876 /* RetransTime (in milliseconds)*/
2817 t->neigh_vars[12].proc_handler = handler; 2877 t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler;
2818 t->neigh_vars[12].extra1 = dev; 2878 t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].extra1 = dev;
2819 /* ReachableTime (in milliseconds) */ 2879 /* ReachableTime (in milliseconds) */
2820 t->neigh_vars[13].proc_handler = handler; 2880 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler;
2821 t->neigh_vars[13].extra1 = dev; 2881 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].extra1 = dev;
2822 } 2882 }
2823 2883
2824 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL); 2884 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL);