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 5ac07d31fbc9..27d3fefeaa13 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]);
@@ -2638,117 +2655,158 @@ EXPORT_SYMBOL(neigh_app_ns);
2638 2655
2639#ifdef CONFIG_SYSCTL 2656#ifdef CONFIG_SYSCTL
2640 2657
2641#define NEIGH_VARS_MAX 19 2658static int proc_unres_qlen(ctl_table *ctl, int write, void __user *buffer,
2659 size_t *lenp, loff_t *ppos)
2660{
2661 int size, ret;
2662 ctl_table tmp = *ctl;
2663
2664 tmp.data = &size;
2665 size = DIV_ROUND_UP(*(int *)ctl->data, SKB_TRUESIZE(ETH_FRAME_LEN));
2666 ret = proc_dointvec(&tmp, write, buffer, lenp, ppos);
2667 if (write && !ret)
2668 *(int *)ctl->data = size * SKB_TRUESIZE(ETH_FRAME_LEN);
2669 return ret;
2670}
2671
2672enum {
2673 NEIGH_VAR_MCAST_PROBE,
2674 NEIGH_VAR_UCAST_PROBE,
2675 NEIGH_VAR_APP_PROBE,
2676 NEIGH_VAR_RETRANS_TIME,
2677 NEIGH_VAR_BASE_REACHABLE_TIME,
2678 NEIGH_VAR_DELAY_PROBE_TIME,
2679 NEIGH_VAR_GC_STALETIME,
2680 NEIGH_VAR_QUEUE_LEN,
2681 NEIGH_VAR_QUEUE_LEN_BYTES,
2682 NEIGH_VAR_PROXY_QLEN,
2683 NEIGH_VAR_ANYCAST_DELAY,
2684 NEIGH_VAR_PROXY_DELAY,
2685 NEIGH_VAR_LOCKTIME,
2686 NEIGH_VAR_RETRANS_TIME_MS,
2687 NEIGH_VAR_BASE_REACHABLE_TIME_MS,
2688 NEIGH_VAR_GC_INTERVAL,
2689 NEIGH_VAR_GC_THRESH1,
2690 NEIGH_VAR_GC_THRESH2,
2691 NEIGH_VAR_GC_THRESH3,
2692 NEIGH_VAR_MAX
2693};
2642 2694
2643static struct neigh_sysctl_table { 2695static struct neigh_sysctl_table {
2644 struct ctl_table_header *sysctl_header; 2696 struct ctl_table_header *sysctl_header;
2645 struct ctl_table neigh_vars[NEIGH_VARS_MAX]; 2697 struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1];
2646 char *dev_name; 2698 char *dev_name;
2647} neigh_sysctl_template __read_mostly = { 2699} neigh_sysctl_template __read_mostly = {
2648 .neigh_vars = { 2700 .neigh_vars = {
2649 { 2701 [NEIGH_VAR_MCAST_PROBE] = {
2650 .procname = "mcast_solicit", 2702 .procname = "mcast_solicit",
2651 .maxlen = sizeof(int), 2703 .maxlen = sizeof(int),
2652 .mode = 0644, 2704 .mode = 0644,
2653 .proc_handler = proc_dointvec, 2705 .proc_handler = proc_dointvec,
2654 }, 2706 },
2655 { 2707 [NEIGH_VAR_UCAST_PROBE] = {
2656 .procname = "ucast_solicit", 2708 .procname = "ucast_solicit",
2657 .maxlen = sizeof(int), 2709 .maxlen = sizeof(int),
2658 .mode = 0644, 2710 .mode = 0644,
2659 .proc_handler = proc_dointvec, 2711 .proc_handler = proc_dointvec,
2660 }, 2712 },
2661 { 2713 [NEIGH_VAR_APP_PROBE] = {
2662 .procname = "app_solicit", 2714 .procname = "app_solicit",
2663 .maxlen = sizeof(int), 2715 .maxlen = sizeof(int),
2664 .mode = 0644, 2716 .mode = 0644,
2665 .proc_handler = proc_dointvec, 2717 .proc_handler = proc_dointvec,
2666 }, 2718 },
2667 { 2719 [NEIGH_VAR_RETRANS_TIME] = {
2668 .procname = "retrans_time", 2720 .procname = "retrans_time",
2669 .maxlen = sizeof(int), 2721 .maxlen = sizeof(int),
2670 .mode = 0644, 2722 .mode = 0644,
2671 .proc_handler = proc_dointvec_userhz_jiffies, 2723 .proc_handler = proc_dointvec_userhz_jiffies,
2672 }, 2724 },
2673 { 2725 [NEIGH_VAR_BASE_REACHABLE_TIME] = {
2674 .procname = "base_reachable_time", 2726 .procname = "base_reachable_time",
2675 .maxlen = sizeof(int), 2727 .maxlen = sizeof(int),
2676 .mode = 0644, 2728 .mode = 0644,
2677 .proc_handler = proc_dointvec_jiffies, 2729 .proc_handler = proc_dointvec_jiffies,
2678 }, 2730 },
2679 { 2731 [NEIGH_VAR_DELAY_PROBE_TIME] = {
2680 .procname = "delay_first_probe_time", 2732 .procname = "delay_first_probe_time",
2681 .maxlen = sizeof(int), 2733 .maxlen = sizeof(int),
2682 .mode = 0644, 2734 .mode = 0644,
2683 .proc_handler = proc_dointvec_jiffies, 2735 .proc_handler = proc_dointvec_jiffies,
2684 }, 2736 },
2685 { 2737 [NEIGH_VAR_GC_STALETIME] = {
2686 .procname = "gc_stale_time", 2738 .procname = "gc_stale_time",
2687 .maxlen = sizeof(int), 2739 .maxlen = sizeof(int),
2688 .mode = 0644, 2740 .mode = 0644,
2689 .proc_handler = proc_dointvec_jiffies, 2741 .proc_handler = proc_dointvec_jiffies,
2690 }, 2742 },
2691 { 2743 [NEIGH_VAR_QUEUE_LEN] = {
2692 .procname = "unres_qlen", 2744 .procname = "unres_qlen",
2693 .maxlen = sizeof(int), 2745 .maxlen = sizeof(int),
2694 .mode = 0644, 2746 .mode = 0644,
2747 .proc_handler = proc_unres_qlen,
2748 },
2749 [NEIGH_VAR_QUEUE_LEN_BYTES] = {
2750 .procname = "unres_qlen_bytes",
2751 .maxlen = sizeof(int),
2752 .mode = 0644,
2695 .proc_handler = proc_dointvec, 2753 .proc_handler = proc_dointvec,
2696 }, 2754 },
2697 { 2755 [NEIGH_VAR_PROXY_QLEN] = {
2698 .procname = "proxy_qlen", 2756 .procname = "proxy_qlen",
2699 .maxlen = sizeof(int), 2757 .maxlen = sizeof(int),
2700 .mode = 0644, 2758 .mode = 0644,
2701 .proc_handler = proc_dointvec, 2759 .proc_handler = proc_dointvec,
2702 }, 2760 },
2703 { 2761 [NEIGH_VAR_ANYCAST_DELAY] = {
2704 .procname = "anycast_delay", 2762 .procname = "anycast_delay",
2705 .maxlen = sizeof(int), 2763 .maxlen = sizeof(int),
2706 .mode = 0644, 2764 .mode = 0644,
2707 .proc_handler = proc_dointvec_userhz_jiffies, 2765 .proc_handler = proc_dointvec_userhz_jiffies,
2708 }, 2766 },
2709 { 2767 [NEIGH_VAR_PROXY_DELAY] = {
2710 .procname = "proxy_delay", 2768 .procname = "proxy_delay",
2711 .maxlen = sizeof(int), 2769 .maxlen = sizeof(int),
2712 .mode = 0644, 2770 .mode = 0644,
2713 .proc_handler = proc_dointvec_userhz_jiffies, 2771 .proc_handler = proc_dointvec_userhz_jiffies,
2714 }, 2772 },
2715 { 2773 [NEIGH_VAR_LOCKTIME] = {
2716 .procname = "locktime", 2774 .procname = "locktime",
2717 .maxlen = sizeof(int), 2775 .maxlen = sizeof(int),
2718 .mode = 0644, 2776 .mode = 0644,
2719 .proc_handler = proc_dointvec_userhz_jiffies, 2777 .proc_handler = proc_dointvec_userhz_jiffies,
2720 }, 2778 },
2721 { 2779 [NEIGH_VAR_RETRANS_TIME_MS] = {
2722 .procname = "retrans_time_ms", 2780 .procname = "retrans_time_ms",
2723 .maxlen = sizeof(int), 2781 .maxlen = sizeof(int),
2724 .mode = 0644, 2782 .mode = 0644,
2725 .proc_handler = proc_dointvec_ms_jiffies, 2783 .proc_handler = proc_dointvec_ms_jiffies,
2726 }, 2784 },
2727 { 2785 [NEIGH_VAR_BASE_REACHABLE_TIME_MS] = {
2728 .procname = "base_reachable_time_ms", 2786 .procname = "base_reachable_time_ms",
2729 .maxlen = sizeof(int), 2787 .maxlen = sizeof(int),
2730 .mode = 0644, 2788 .mode = 0644,
2731 .proc_handler = proc_dointvec_ms_jiffies, 2789 .proc_handler = proc_dointvec_ms_jiffies,
2732 }, 2790 },
2733 { 2791 [NEIGH_VAR_GC_INTERVAL] = {
2734 .procname = "gc_interval", 2792 .procname = "gc_interval",
2735 .maxlen = sizeof(int), 2793 .maxlen = sizeof(int),
2736 .mode = 0644, 2794 .mode = 0644,
2737 .proc_handler = proc_dointvec_jiffies, 2795 .proc_handler = proc_dointvec_jiffies,
2738 }, 2796 },
2739 { 2797 [NEIGH_VAR_GC_THRESH1] = {
2740 .procname = "gc_thresh1", 2798 .procname = "gc_thresh1",
2741 .maxlen = sizeof(int), 2799 .maxlen = sizeof(int),
2742 .mode = 0644, 2800 .mode = 0644,
2743 .proc_handler = proc_dointvec, 2801 .proc_handler = proc_dointvec,
2744 }, 2802 },
2745 { 2803 [NEIGH_VAR_GC_THRESH2] = {
2746 .procname = "gc_thresh2", 2804 .procname = "gc_thresh2",
2747 .maxlen = sizeof(int), 2805 .maxlen = sizeof(int),
2748 .mode = 0644, 2806 .mode = 0644,
2749 .proc_handler = proc_dointvec, 2807 .proc_handler = proc_dointvec,
2750 }, 2808 },
2751 { 2809 [NEIGH_VAR_GC_THRESH3] = {
2752 .procname = "gc_thresh3", 2810 .procname = "gc_thresh3",
2753 .maxlen = sizeof(int), 2811 .maxlen = sizeof(int),
2754 .mode = 0644, 2812 .mode = 0644,
@@ -2781,47 +2839,49 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p,
2781 if (!t) 2839 if (!t)
2782 goto err; 2840 goto err;
2783 2841
2784 t->neigh_vars[0].data = &p->mcast_probes; 2842 t->neigh_vars[NEIGH_VAR_MCAST_PROBE].data = &p->mcast_probes;
2785 t->neigh_vars[1].data = &p->ucast_probes; 2843 t->neigh_vars[NEIGH_VAR_UCAST_PROBE].data = &p->ucast_probes;
2786 t->neigh_vars[2].data = &p->app_probes; 2844 t->neigh_vars[NEIGH_VAR_APP_PROBE].data = &p->app_probes;
2787 t->neigh_vars[3].data = &p->retrans_time; 2845 t->neigh_vars[NEIGH_VAR_RETRANS_TIME].data = &p->retrans_time;
2788 t->neigh_vars[4].data = &p->base_reachable_time; 2846 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].data = &p->base_reachable_time;
2789 t->neigh_vars[5].data = &p->delay_probe_time; 2847 t->neigh_vars[NEIGH_VAR_DELAY_PROBE_TIME].data = &p->delay_probe_time;
2790 t->neigh_vars[6].data = &p->gc_staletime; 2848 t->neigh_vars[NEIGH_VAR_GC_STALETIME].data = &p->gc_staletime;
2791 t->neigh_vars[7].data = &p->queue_len; 2849 t->neigh_vars[NEIGH_VAR_QUEUE_LEN].data = &p->queue_len_bytes;
2792 t->neigh_vars[8].data = &p->proxy_qlen; 2850 t->neigh_vars[NEIGH_VAR_QUEUE_LEN_BYTES].data = &p->queue_len_bytes;
2793 t->neigh_vars[9].data = &p->anycast_delay; 2851 t->neigh_vars[NEIGH_VAR_PROXY_QLEN].data = &p->proxy_qlen;
2794 t->neigh_vars[10].data = &p->proxy_delay; 2852 t->neigh_vars[NEIGH_VAR_ANYCAST_DELAY].data = &p->anycast_delay;
2795 t->neigh_vars[11].data = &p->locktime; 2853 t->neigh_vars[NEIGH_VAR_PROXY_DELAY].data = &p->proxy_delay;
2796 t->neigh_vars[12].data = &p->retrans_time; 2854 t->neigh_vars[NEIGH_VAR_LOCKTIME].data = &p->locktime;
2797 t->neigh_vars[13].data = &p->base_reachable_time; 2855 t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].data = &p->retrans_time;
2856 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].data = &p->base_reachable_time;
2798 2857
2799 if (dev) { 2858 if (dev) {
2800 dev_name_source = dev->name; 2859 dev_name_source = dev->name;
2801 /* Terminate the table early */ 2860 /* Terminate the table early */
2802 memset(&t->neigh_vars[14], 0, sizeof(t->neigh_vars[14])); 2861 memset(&t->neigh_vars[NEIGH_VAR_GC_INTERVAL], 0,
2862 sizeof(t->neigh_vars[NEIGH_VAR_GC_INTERVAL]));
2803 } else { 2863 } else {
2804 dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname; 2864 dev_name_source = neigh_path[NEIGH_CTL_PATH_DEV].procname;
2805 t->neigh_vars[14].data = (int *)(p + 1); 2865 t->neigh_vars[NEIGH_VAR_GC_INTERVAL].data = (int *)(p + 1);
2806 t->neigh_vars[15].data = (int *)(p + 1) + 1; 2866 t->neigh_vars[NEIGH_VAR_GC_THRESH1].data = (int *)(p + 1) + 1;
2807 t->neigh_vars[16].data = (int *)(p + 1) + 2; 2867 t->neigh_vars[NEIGH_VAR_GC_THRESH2].data = (int *)(p + 1) + 2;
2808 t->neigh_vars[17].data = (int *)(p + 1) + 3; 2868 t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = (int *)(p + 1) + 3;
2809 } 2869 }
2810 2870
2811 2871
2812 if (handler) { 2872 if (handler) {
2813 /* RetransTime */ 2873 /* RetransTime */
2814 t->neigh_vars[3].proc_handler = handler; 2874 t->neigh_vars[NEIGH_VAR_RETRANS_TIME].proc_handler = handler;
2815 t->neigh_vars[3].extra1 = dev; 2875 t->neigh_vars[NEIGH_VAR_RETRANS_TIME].extra1 = dev;
2816 /* ReachableTime */ 2876 /* ReachableTime */
2817 t->neigh_vars[4].proc_handler = handler; 2877 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = handler;
2818 t->neigh_vars[4].extra1 = dev; 2878 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].extra1 = dev;
2819 /* RetransTime (in milliseconds)*/ 2879 /* RetransTime (in milliseconds)*/
2820 t->neigh_vars[12].proc_handler = handler; 2880 t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler;
2821 t->neigh_vars[12].extra1 = dev; 2881 t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].extra1 = dev;
2822 /* ReachableTime (in milliseconds) */ 2882 /* ReachableTime (in milliseconds) */
2823 t->neigh_vars[13].proc_handler = handler; 2883 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler;
2824 t->neigh_vars[13].extra1 = dev; 2884 t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].extra1 = dev;
2825 } 2885 }
2826 2886
2827 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL); 2887 t->dev_name = kstrdup(dev_name_source, GFP_KERNEL);