diff options
Diffstat (limited to 'net/core/neighbour.c')
-rw-r--r-- | net/core/neighbour.c | 483 |
1 files changed, 282 insertions, 201 deletions
diff --git a/net/core/neighbour.c b/net/core/neighbour.c index 932c6d7cf666..e16129019c66 100644 --- a/net/core/neighbour.c +++ b/net/core/neighbour.c | |||
@@ -38,6 +38,8 @@ | |||
38 | #include <linux/random.h> | 38 | #include <linux/random.h> |
39 | #include <linux/string.h> | 39 | #include <linux/string.h> |
40 | #include <linux/log2.h> | 40 | #include <linux/log2.h> |
41 | #include <linux/inetdevice.h> | ||
42 | #include <net/addrconf.h> | ||
41 | 43 | ||
42 | #define DEBUG | 44 | #define DEBUG |
43 | #define NEIGH_DEBUG 1 | 45 | #define NEIGH_DEBUG 1 |
@@ -115,7 +117,7 @@ static void neigh_cleanup_and_release(struct neighbour *neigh) | |||
115 | 117 | ||
116 | unsigned long neigh_rand_reach_time(unsigned long base) | 118 | unsigned long neigh_rand_reach_time(unsigned long base) |
117 | { | 119 | { |
118 | return base ? (net_random() % base) + (base >> 1) : 0; | 120 | return base ? (prandom_u32() % base) + (base >> 1) : 0; |
119 | } | 121 | } |
120 | EXPORT_SYMBOL(neigh_rand_reach_time); | 122 | EXPORT_SYMBOL(neigh_rand_reach_time); |
121 | 123 | ||
@@ -497,7 +499,7 @@ struct neighbour *__neigh_create(struct neigh_table *tbl, const void *pkey, | |||
497 | goto out_neigh_release; | 499 | goto out_neigh_release; |
498 | } | 500 | } |
499 | 501 | ||
500 | n->confirmed = jiffies - (n->parms->base_reachable_time << 1); | 502 | n->confirmed = jiffies - (NEIGH_VAR(n->parms, BASE_REACHABLE_TIME) << 1); |
501 | 503 | ||
502 | write_lock_bh(&tbl->lock); | 504 | write_lock_bh(&tbl->lock); |
503 | nht = rcu_dereference_protected(tbl->nht, | 505 | nht = rcu_dereference_protected(tbl->nht, |
@@ -764,9 +766,6 @@ static void neigh_periodic_work(struct work_struct *work) | |||
764 | nht = rcu_dereference_protected(tbl->nht, | 766 | nht = rcu_dereference_protected(tbl->nht, |
765 | lockdep_is_held(&tbl->lock)); | 767 | lockdep_is_held(&tbl->lock)); |
766 | 768 | ||
767 | if (atomic_read(&tbl->entries) < tbl->gc_thresh1) | ||
768 | goto out; | ||
769 | |||
770 | /* | 769 | /* |
771 | * periodically recompute ReachableTime from random function | 770 | * periodically recompute ReachableTime from random function |
772 | */ | 771 | */ |
@@ -776,9 +775,12 @@ static void neigh_periodic_work(struct work_struct *work) | |||
776 | tbl->last_rand = jiffies; | 775 | tbl->last_rand = jiffies; |
777 | for (p = &tbl->parms; p; p = p->next) | 776 | for (p = &tbl->parms; p; p = p->next) |
778 | p->reachable_time = | 777 | p->reachable_time = |
779 | neigh_rand_reach_time(p->base_reachable_time); | 778 | neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); |
780 | } | 779 | } |
781 | 780 | ||
781 | if (atomic_read(&tbl->entries) < tbl->gc_thresh1) | ||
782 | goto out; | ||
783 | |||
782 | for (i = 0 ; i < (1 << nht->hash_shift); i++) { | 784 | for (i = 0 ; i < (1 << nht->hash_shift); i++) { |
783 | np = &nht->hash_buckets[i]; | 785 | np = &nht->hash_buckets[i]; |
784 | 786 | ||
@@ -799,7 +801,7 @@ static void neigh_periodic_work(struct work_struct *work) | |||
799 | 801 | ||
800 | if (atomic_read(&n->refcnt) == 1 && | 802 | if (atomic_read(&n->refcnt) == 1 && |
801 | (state == NUD_FAILED || | 803 | (state == NUD_FAILED || |
802 | time_after(jiffies, n->used + n->parms->gc_staletime))) { | 804 | time_after(jiffies, n->used + NEIGH_VAR(n->parms, GC_STALETIME)))) { |
803 | *np = n->next; | 805 | *np = n->next; |
804 | n->dead = 1; | 806 | n->dead = 1; |
805 | write_unlock(&n->lock); | 807 | write_unlock(&n->lock); |
@@ -822,12 +824,12 @@ next_elt: | |||
822 | lockdep_is_held(&tbl->lock)); | 824 | lockdep_is_held(&tbl->lock)); |
823 | } | 825 | } |
824 | out: | 826 | out: |
825 | /* Cycle through all hash buckets every base_reachable_time/2 ticks. | 827 | /* Cycle through all hash buckets every BASE_REACHABLE_TIME/2 ticks. |
826 | * ARP entry timeouts range from 1/2 base_reachable_time to 3/2 | 828 | * ARP entry timeouts range from 1/2 BASE_REACHABLE_TIME to 3/2 |
827 | * base_reachable_time. | 829 | * BASE_REACHABLE_TIME. |
828 | */ | 830 | */ |
829 | schedule_delayed_work(&tbl->gc_work, | 831 | queue_delayed_work(system_power_efficient_wq, &tbl->gc_work, |
830 | tbl->parms.base_reachable_time >> 1); | 832 | NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME) >> 1); |
831 | write_unlock_bh(&tbl->lock); | 833 | write_unlock_bh(&tbl->lock); |
832 | } | 834 | } |
833 | 835 | ||
@@ -835,8 +837,9 @@ static __inline__ int neigh_max_probes(struct neighbour *n) | |||
835 | { | 837 | { |
836 | struct neigh_parms *p = n->parms; | 838 | struct neigh_parms *p = n->parms; |
837 | return (n->nud_state & NUD_PROBE) ? | 839 | return (n->nud_state & NUD_PROBE) ? |
838 | p->ucast_probes : | 840 | NEIGH_VAR(p, UCAST_PROBES) : |
839 | p->ucast_probes + p->app_probes + p->mcast_probes; | 841 | NEIGH_VAR(p, UCAST_PROBES) + NEIGH_VAR(p, APP_PROBES) + |
842 | NEIGH_VAR(p, MCAST_PROBES); | ||
840 | } | 843 | } |
841 | 844 | ||
842 | static void neigh_invalidate(struct neighbour *neigh) | 845 | static void neigh_invalidate(struct neighbour *neigh) |
@@ -901,12 +904,13 @@ static void neigh_timer_handler(unsigned long arg) | |||
901 | neigh_dbg(2, "neigh %p is still alive\n", neigh); | 904 | neigh_dbg(2, "neigh %p is still alive\n", neigh); |
902 | next = neigh->confirmed + neigh->parms->reachable_time; | 905 | next = neigh->confirmed + neigh->parms->reachable_time; |
903 | } else if (time_before_eq(now, | 906 | } else if (time_before_eq(now, |
904 | neigh->used + neigh->parms->delay_probe_time)) { | 907 | neigh->used + |
908 | NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { | ||
905 | neigh_dbg(2, "neigh %p is delayed\n", neigh); | 909 | neigh_dbg(2, "neigh %p is delayed\n", neigh); |
906 | neigh->nud_state = NUD_DELAY; | 910 | neigh->nud_state = NUD_DELAY; |
907 | neigh->updated = jiffies; | 911 | neigh->updated = jiffies; |
908 | neigh_suspect(neigh); | 912 | neigh_suspect(neigh); |
909 | next = now + neigh->parms->delay_probe_time; | 913 | next = now + NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME); |
910 | } else { | 914 | } else { |
911 | neigh_dbg(2, "neigh %p is suspected\n", neigh); | 915 | neigh_dbg(2, "neigh %p is suspected\n", neigh); |
912 | neigh->nud_state = NUD_STALE; | 916 | neigh->nud_state = NUD_STALE; |
@@ -916,7 +920,8 @@ static void neigh_timer_handler(unsigned long arg) | |||
916 | } | 920 | } |
917 | } else if (state & NUD_DELAY) { | 921 | } else if (state & NUD_DELAY) { |
918 | if (time_before_eq(now, | 922 | if (time_before_eq(now, |
919 | neigh->confirmed + neigh->parms->delay_probe_time)) { | 923 | neigh->confirmed + |
924 | NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME))) { | ||
920 | neigh_dbg(2, "neigh %p is now reachable\n", neigh); | 925 | neigh_dbg(2, "neigh %p is now reachable\n", neigh); |
921 | neigh->nud_state = NUD_REACHABLE; | 926 | neigh->nud_state = NUD_REACHABLE; |
922 | neigh->updated = jiffies; | 927 | neigh->updated = jiffies; |
@@ -928,11 +933,11 @@ static void neigh_timer_handler(unsigned long arg) | |||
928 | neigh->nud_state = NUD_PROBE; | 933 | neigh->nud_state = NUD_PROBE; |
929 | neigh->updated = jiffies; | 934 | neigh->updated = jiffies; |
930 | atomic_set(&neigh->probes, 0); | 935 | atomic_set(&neigh->probes, 0); |
931 | next = now + neigh->parms->retrans_time; | 936 | next = now + NEIGH_VAR(neigh->parms, RETRANS_TIME); |
932 | } | 937 | } |
933 | } else { | 938 | } else { |
934 | /* NUD_PROBE|NUD_INCOMPLETE */ | 939 | /* NUD_PROBE|NUD_INCOMPLETE */ |
935 | next = now + neigh->parms->retrans_time; | 940 | next = now + NEIGH_VAR(neigh->parms, RETRANS_TIME); |
936 | } | 941 | } |
937 | 942 | ||
938 | if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && | 943 | if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) && |
@@ -973,13 +978,16 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
973 | goto out_unlock_bh; | 978 | goto out_unlock_bh; |
974 | 979 | ||
975 | if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) { | 980 | if (!(neigh->nud_state & (NUD_STALE | NUD_INCOMPLETE))) { |
976 | if (neigh->parms->mcast_probes + neigh->parms->app_probes) { | 981 | if (NEIGH_VAR(neigh->parms, MCAST_PROBES) + |
982 | NEIGH_VAR(neigh->parms, APP_PROBES)) { | ||
977 | unsigned long next, now = jiffies; | 983 | unsigned long next, now = jiffies; |
978 | 984 | ||
979 | atomic_set(&neigh->probes, neigh->parms->ucast_probes); | 985 | atomic_set(&neigh->probes, |
986 | NEIGH_VAR(neigh->parms, UCAST_PROBES)); | ||
980 | neigh->nud_state = NUD_INCOMPLETE; | 987 | neigh->nud_state = NUD_INCOMPLETE; |
981 | neigh->updated = now; | 988 | neigh->updated = now; |
982 | next = now + max(neigh->parms->retrans_time, HZ/2); | 989 | next = now + max(NEIGH_VAR(neigh->parms, RETRANS_TIME), |
990 | HZ/2); | ||
983 | neigh_add_timer(neigh, next); | 991 | neigh_add_timer(neigh, next); |
984 | immediate_probe = true; | 992 | immediate_probe = true; |
985 | } else { | 993 | } else { |
@@ -994,14 +1002,14 @@ int __neigh_event_send(struct neighbour *neigh, struct sk_buff *skb) | |||
994 | neigh_dbg(2, "neigh %p is delayed\n", neigh); | 1002 | neigh_dbg(2, "neigh %p is delayed\n", neigh); |
995 | neigh->nud_state = NUD_DELAY; | 1003 | neigh->nud_state = NUD_DELAY; |
996 | neigh->updated = jiffies; | 1004 | neigh->updated = jiffies; |
997 | neigh_add_timer(neigh, | 1005 | neigh_add_timer(neigh, jiffies + |
998 | jiffies + neigh->parms->delay_probe_time); | 1006 | NEIGH_VAR(neigh->parms, DELAY_PROBE_TIME)); |
999 | } | 1007 | } |
1000 | 1008 | ||
1001 | if (neigh->nud_state == NUD_INCOMPLETE) { | 1009 | if (neigh->nud_state == NUD_INCOMPLETE) { |
1002 | if (skb) { | 1010 | if (skb) { |
1003 | while (neigh->arp_queue_len_bytes + skb->truesize > | 1011 | while (neigh->arp_queue_len_bytes + skb->truesize > |
1004 | neigh->parms->queue_len_bytes) { | 1012 | NEIGH_VAR(neigh->parms, QUEUE_LEN_BYTES)) { |
1005 | struct sk_buff *buff; | 1013 | struct sk_buff *buff; |
1006 | 1014 | ||
1007 | buff = __skb_dequeue(&neigh->arp_queue); | 1015 | buff = __skb_dequeue(&neigh->arp_queue); |
@@ -1171,7 +1179,7 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, | |||
1171 | neigh_update_hhs(neigh); | 1179 | neigh_update_hhs(neigh); |
1172 | if (!(new & NUD_CONNECTED)) | 1180 | if (!(new & NUD_CONNECTED)) |
1173 | neigh->confirmed = jiffies - | 1181 | neigh->confirmed = jiffies - |
1174 | (neigh->parms->base_reachable_time << 1); | 1182 | (NEIGH_VAR(neigh->parms, BASE_REACHABLE_TIME) << 1); |
1175 | notify = 1; | 1183 | notify = 1; |
1176 | } | 1184 | } |
1177 | if (new == old) | 1185 | if (new == old) |
@@ -1231,6 +1239,21 @@ out: | |||
1231 | } | 1239 | } |
1232 | EXPORT_SYMBOL(neigh_update); | 1240 | EXPORT_SYMBOL(neigh_update); |
1233 | 1241 | ||
1242 | /* Update the neigh to listen temporarily for probe responses, even if it is | ||
1243 | * in a NUD_FAILED state. The caller has to hold neigh->lock for writing. | ||
1244 | */ | ||
1245 | void __neigh_set_probe_once(struct neighbour *neigh) | ||
1246 | { | ||
1247 | neigh->updated = jiffies; | ||
1248 | if (!(neigh->nud_state & NUD_FAILED)) | ||
1249 | return; | ||
1250 | neigh->nud_state = NUD_PROBE; | ||
1251 | atomic_set(&neigh->probes, NEIGH_VAR(neigh->parms, UCAST_PROBES)); | ||
1252 | neigh_add_timer(neigh, | ||
1253 | jiffies + NEIGH_VAR(neigh->parms, RETRANS_TIME)); | ||
1254 | } | ||
1255 | EXPORT_SYMBOL(__neigh_set_probe_once); | ||
1256 | |||
1234 | struct neighbour *neigh_event_ns(struct neigh_table *tbl, | 1257 | struct neighbour *neigh_event_ns(struct neigh_table *tbl, |
1235 | u8 *lladdr, void *saddr, | 1258 | u8 *lladdr, void *saddr, |
1236 | struct net_device *dev) | 1259 | struct net_device *dev) |
@@ -1392,9 +1415,11 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p, | |||
1392 | struct sk_buff *skb) | 1415 | struct sk_buff *skb) |
1393 | { | 1416 | { |
1394 | unsigned long now = jiffies; | 1417 | unsigned long now = jiffies; |
1395 | unsigned long sched_next = now + (net_random() % p->proxy_delay); | ||
1396 | 1418 | ||
1397 | if (tbl->proxy_queue.qlen > p->proxy_qlen) { | 1419 | unsigned long sched_next = now + (prandom_u32() % |
1420 | NEIGH_VAR(p, PROXY_DELAY)); | ||
1421 | |||
1422 | if (tbl->proxy_queue.qlen > NEIGH_VAR(p, PROXY_QLEN)) { | ||
1398 | kfree_skb(skb); | 1423 | kfree_skb(skb); |
1399 | return; | 1424 | return; |
1400 | } | 1425 | } |
@@ -1441,7 +1466,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, | |||
1441 | p->tbl = tbl; | 1466 | p->tbl = tbl; |
1442 | atomic_set(&p->refcnt, 1); | 1467 | atomic_set(&p->refcnt, 1); |
1443 | p->reachable_time = | 1468 | p->reachable_time = |
1444 | neigh_rand_reach_time(p->base_reachable_time); | 1469 | neigh_rand_reach_time(NEIGH_VAR(p, BASE_REACHABLE_TIME)); |
1445 | dev_hold(dev); | 1470 | dev_hold(dev); |
1446 | p->dev = dev; | 1471 | p->dev = dev; |
1447 | write_pnet(&p->net, hold_net(net)); | 1472 | write_pnet(&p->net, hold_net(net)); |
@@ -1458,6 +1483,8 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev, | |||
1458 | p->next = tbl->parms.next; | 1483 | p->next = tbl->parms.next; |
1459 | tbl->parms.next = p; | 1484 | tbl->parms.next = p; |
1460 | write_unlock_bh(&tbl->lock); | 1485 | write_unlock_bh(&tbl->lock); |
1486 | |||
1487 | neigh_parms_data_state_cleanall(p); | ||
1461 | } | 1488 | } |
1462 | return p; | 1489 | return p; |
1463 | } | 1490 | } |
@@ -1510,7 +1537,7 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl) | |||
1510 | write_pnet(&tbl->parms.net, &init_net); | 1537 | write_pnet(&tbl->parms.net, &init_net); |
1511 | atomic_set(&tbl->parms.refcnt, 1); | 1538 | atomic_set(&tbl->parms.refcnt, 1); |
1512 | tbl->parms.reachable_time = | 1539 | tbl->parms.reachable_time = |
1513 | neigh_rand_reach_time(tbl->parms.base_reachable_time); | 1540 | neigh_rand_reach_time(NEIGH_VAR(&tbl->parms, BASE_REACHABLE_TIME)); |
1514 | 1541 | ||
1515 | tbl->stats = alloc_percpu(struct neigh_statistics); | 1542 | tbl->stats = alloc_percpu(struct neigh_statistics); |
1516 | if (!tbl->stats) | 1543 | if (!tbl->stats) |
@@ -1538,7 +1565,8 @@ static void neigh_table_init_no_netlink(struct neigh_table *tbl) | |||
1538 | 1565 | ||
1539 | rwlock_init(&tbl->lock); | 1566 | rwlock_init(&tbl->lock); |
1540 | INIT_DEFERRABLE_WORK(&tbl->gc_work, neigh_periodic_work); | 1567 | INIT_DEFERRABLE_WORK(&tbl->gc_work, neigh_periodic_work); |
1541 | schedule_delayed_work(&tbl->gc_work, tbl->parms.reachable_time); | 1568 | queue_delayed_work(system_power_efficient_wq, &tbl->gc_work, |
1569 | tbl->parms.reachable_time); | ||
1542 | setup_timer(&tbl->proxy_timer, neigh_proxy_process, (unsigned long)tbl); | 1570 | setup_timer(&tbl->proxy_timer, neigh_proxy_process, (unsigned long)tbl); |
1543 | skb_queue_head_init_class(&tbl->proxy_queue, | 1571 | skb_queue_head_init_class(&tbl->proxy_queue, |
1544 | &neigh_table_proxy_queue_class); | 1572 | &neigh_table_proxy_queue_class); |
@@ -1778,24 +1806,32 @@ static int neightbl_fill_parms(struct sk_buff *skb, struct neigh_parms *parms) | |||
1778 | if ((parms->dev && | 1806 | if ((parms->dev && |
1779 | nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) || | 1807 | nla_put_u32(skb, NDTPA_IFINDEX, parms->dev->ifindex)) || |
1780 | nla_put_u32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)) || | 1808 | nla_put_u32(skb, NDTPA_REFCNT, atomic_read(&parms->refcnt)) || |
1781 | nla_put_u32(skb, NDTPA_QUEUE_LENBYTES, parms->queue_len_bytes) || | 1809 | nla_put_u32(skb, NDTPA_QUEUE_LENBYTES, |
1810 | NEIGH_VAR(parms, QUEUE_LEN_BYTES)) || | ||
1782 | /* approximative value for deprecated QUEUE_LEN (in packets) */ | 1811 | /* approximative value for deprecated QUEUE_LEN (in packets) */ |
1783 | nla_put_u32(skb, NDTPA_QUEUE_LEN, | 1812 | nla_put_u32(skb, NDTPA_QUEUE_LEN, |
1784 | parms->queue_len_bytes / SKB_TRUESIZE(ETH_FRAME_LEN)) || | 1813 | NEIGH_VAR(parms, QUEUE_LEN_BYTES) / SKB_TRUESIZE(ETH_FRAME_LEN)) || |
1785 | nla_put_u32(skb, NDTPA_PROXY_QLEN, parms->proxy_qlen) || | 1814 | nla_put_u32(skb, NDTPA_PROXY_QLEN, NEIGH_VAR(parms, PROXY_QLEN)) || |
1786 | nla_put_u32(skb, NDTPA_APP_PROBES, parms->app_probes) || | 1815 | nla_put_u32(skb, NDTPA_APP_PROBES, NEIGH_VAR(parms, APP_PROBES)) || |
1787 | nla_put_u32(skb, NDTPA_UCAST_PROBES, parms->ucast_probes) || | 1816 | nla_put_u32(skb, NDTPA_UCAST_PROBES, |
1788 | nla_put_u32(skb, NDTPA_MCAST_PROBES, parms->mcast_probes) || | 1817 | NEIGH_VAR(parms, UCAST_PROBES)) || |
1818 | nla_put_u32(skb, NDTPA_MCAST_PROBES, | ||
1819 | NEIGH_VAR(parms, MCAST_PROBES)) || | ||
1789 | nla_put_msecs(skb, NDTPA_REACHABLE_TIME, parms->reachable_time) || | 1820 | nla_put_msecs(skb, NDTPA_REACHABLE_TIME, parms->reachable_time) || |
1790 | nla_put_msecs(skb, NDTPA_BASE_REACHABLE_TIME, | 1821 | nla_put_msecs(skb, NDTPA_BASE_REACHABLE_TIME, |
1791 | parms->base_reachable_time) || | 1822 | NEIGH_VAR(parms, BASE_REACHABLE_TIME)) || |
1792 | nla_put_msecs(skb, NDTPA_GC_STALETIME, parms->gc_staletime) || | 1823 | nla_put_msecs(skb, NDTPA_GC_STALETIME, |
1824 | NEIGH_VAR(parms, GC_STALETIME)) || | ||
1793 | nla_put_msecs(skb, NDTPA_DELAY_PROBE_TIME, | 1825 | nla_put_msecs(skb, NDTPA_DELAY_PROBE_TIME, |
1794 | parms->delay_probe_time) || | 1826 | NEIGH_VAR(parms, DELAY_PROBE_TIME)) || |
1795 | nla_put_msecs(skb, NDTPA_RETRANS_TIME, parms->retrans_time) || | 1827 | nla_put_msecs(skb, NDTPA_RETRANS_TIME, |
1796 | nla_put_msecs(skb, NDTPA_ANYCAST_DELAY, parms->anycast_delay) || | 1828 | NEIGH_VAR(parms, RETRANS_TIME)) || |
1797 | nla_put_msecs(skb, NDTPA_PROXY_DELAY, parms->proxy_delay) || | 1829 | nla_put_msecs(skb, NDTPA_ANYCAST_DELAY, |
1798 | nla_put_msecs(skb, NDTPA_LOCKTIME, parms->locktime)) | 1830 | NEIGH_VAR(parms, ANYCAST_DELAY)) || |
1831 | nla_put_msecs(skb, NDTPA_PROXY_DELAY, | ||
1832 | NEIGH_VAR(parms, PROXY_DELAY)) || | ||
1833 | nla_put_msecs(skb, NDTPA_LOCKTIME, | ||
1834 | NEIGH_VAR(parms, LOCKTIME))) | ||
1799 | goto nla_put_failure; | 1835 | goto nla_put_failure; |
1800 | return nla_nest_end(skb, nest); | 1836 | return nla_nest_end(skb, nest); |
1801 | 1837 | ||
@@ -2011,44 +2047,57 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2011 | 2047 | ||
2012 | switch (i) { | 2048 | switch (i) { |
2013 | case NDTPA_QUEUE_LEN: | 2049 | case NDTPA_QUEUE_LEN: |
2014 | p->queue_len_bytes = nla_get_u32(tbp[i]) * | 2050 | NEIGH_VAR_SET(p, QUEUE_LEN_BYTES, |
2015 | SKB_TRUESIZE(ETH_FRAME_LEN); | 2051 | nla_get_u32(tbp[i]) * |
2052 | SKB_TRUESIZE(ETH_FRAME_LEN)); | ||
2016 | break; | 2053 | break; |
2017 | case NDTPA_QUEUE_LENBYTES: | 2054 | case NDTPA_QUEUE_LENBYTES: |
2018 | p->queue_len_bytes = nla_get_u32(tbp[i]); | 2055 | NEIGH_VAR_SET(p, QUEUE_LEN_BYTES, |
2056 | nla_get_u32(tbp[i])); | ||
2019 | break; | 2057 | break; |
2020 | case NDTPA_PROXY_QLEN: | 2058 | case NDTPA_PROXY_QLEN: |
2021 | p->proxy_qlen = nla_get_u32(tbp[i]); | 2059 | NEIGH_VAR_SET(p, PROXY_QLEN, |
2060 | nla_get_u32(tbp[i])); | ||
2022 | break; | 2061 | break; |
2023 | case NDTPA_APP_PROBES: | 2062 | case NDTPA_APP_PROBES: |
2024 | p->app_probes = nla_get_u32(tbp[i]); | 2063 | NEIGH_VAR_SET(p, APP_PROBES, |
2064 | nla_get_u32(tbp[i])); | ||
2025 | break; | 2065 | break; |
2026 | case NDTPA_UCAST_PROBES: | 2066 | case NDTPA_UCAST_PROBES: |
2027 | p->ucast_probes = nla_get_u32(tbp[i]); | 2067 | NEIGH_VAR_SET(p, UCAST_PROBES, |
2068 | nla_get_u32(tbp[i])); | ||
2028 | break; | 2069 | break; |
2029 | case NDTPA_MCAST_PROBES: | 2070 | case NDTPA_MCAST_PROBES: |
2030 | p->mcast_probes = nla_get_u32(tbp[i]); | 2071 | NEIGH_VAR_SET(p, MCAST_PROBES, |
2072 | nla_get_u32(tbp[i])); | ||
2031 | break; | 2073 | break; |
2032 | case NDTPA_BASE_REACHABLE_TIME: | 2074 | case NDTPA_BASE_REACHABLE_TIME: |
2033 | p->base_reachable_time = nla_get_msecs(tbp[i]); | 2075 | NEIGH_VAR_SET(p, BASE_REACHABLE_TIME, |
2076 | nla_get_msecs(tbp[i])); | ||
2034 | break; | 2077 | break; |
2035 | case NDTPA_GC_STALETIME: | 2078 | case NDTPA_GC_STALETIME: |
2036 | p->gc_staletime = nla_get_msecs(tbp[i]); | 2079 | NEIGH_VAR_SET(p, GC_STALETIME, |
2080 | nla_get_msecs(tbp[i])); | ||
2037 | break; | 2081 | break; |
2038 | case NDTPA_DELAY_PROBE_TIME: | 2082 | case NDTPA_DELAY_PROBE_TIME: |
2039 | p->delay_probe_time = nla_get_msecs(tbp[i]); | 2083 | NEIGH_VAR_SET(p, DELAY_PROBE_TIME, |
2084 | nla_get_msecs(tbp[i])); | ||
2040 | break; | 2085 | break; |
2041 | case NDTPA_RETRANS_TIME: | 2086 | case NDTPA_RETRANS_TIME: |
2042 | p->retrans_time = nla_get_msecs(tbp[i]); | 2087 | NEIGH_VAR_SET(p, RETRANS_TIME, |
2088 | nla_get_msecs(tbp[i])); | ||
2043 | break; | 2089 | break; |
2044 | case NDTPA_ANYCAST_DELAY: | 2090 | case NDTPA_ANYCAST_DELAY: |
2045 | p->anycast_delay = nla_get_msecs(tbp[i]); | 2091 | NEIGH_VAR_SET(p, ANYCAST_DELAY, |
2092 | nla_get_msecs(tbp[i])); | ||
2046 | break; | 2093 | break; |
2047 | case NDTPA_PROXY_DELAY: | 2094 | case NDTPA_PROXY_DELAY: |
2048 | p->proxy_delay = nla_get_msecs(tbp[i]); | 2095 | NEIGH_VAR_SET(p, PROXY_DELAY, |
2096 | nla_get_msecs(tbp[i])); | ||
2049 | break; | 2097 | break; |
2050 | case NDTPA_LOCKTIME: | 2098 | case NDTPA_LOCKTIME: |
2051 | p->locktime = nla_get_msecs(tbp[i]); | 2099 | NEIGH_VAR_SET(p, LOCKTIME, |
2100 | nla_get_msecs(tbp[i])); | ||
2052 | break; | 2101 | break; |
2053 | } | 2102 | } |
2054 | } | 2103 | } |
@@ -2789,133 +2838,167 @@ static int proc_unres_qlen(struct ctl_table *ctl, int write, | |||
2789 | return ret; | 2838 | return ret; |
2790 | } | 2839 | } |
2791 | 2840 | ||
2792 | enum { | 2841 | static struct neigh_parms *neigh_get_dev_parms_rcu(struct net_device *dev, |
2793 | NEIGH_VAR_MCAST_PROBE, | 2842 | int family) |
2794 | NEIGH_VAR_UCAST_PROBE, | 2843 | { |
2795 | NEIGH_VAR_APP_PROBE, | 2844 | switch (family) { |
2796 | NEIGH_VAR_RETRANS_TIME, | 2845 | case AF_INET: |
2797 | NEIGH_VAR_BASE_REACHABLE_TIME, | 2846 | return __in_dev_arp_parms_get_rcu(dev); |
2798 | NEIGH_VAR_DELAY_PROBE_TIME, | 2847 | case AF_INET6: |
2799 | NEIGH_VAR_GC_STALETIME, | 2848 | return __in6_dev_nd_parms_get_rcu(dev); |
2800 | NEIGH_VAR_QUEUE_LEN, | 2849 | } |
2801 | NEIGH_VAR_QUEUE_LEN_BYTES, | 2850 | return NULL; |
2802 | NEIGH_VAR_PROXY_QLEN, | 2851 | } |
2803 | NEIGH_VAR_ANYCAST_DELAY, | 2852 | |
2804 | NEIGH_VAR_PROXY_DELAY, | 2853 | static void neigh_copy_dflt_parms(struct net *net, struct neigh_parms *p, |
2805 | NEIGH_VAR_LOCKTIME, | 2854 | int index) |
2806 | NEIGH_VAR_RETRANS_TIME_MS, | 2855 | { |
2807 | NEIGH_VAR_BASE_REACHABLE_TIME_MS, | 2856 | struct net_device *dev; |
2808 | NEIGH_VAR_GC_INTERVAL, | 2857 | int family = neigh_parms_family(p); |
2809 | NEIGH_VAR_GC_THRESH1, | 2858 | |
2810 | NEIGH_VAR_GC_THRESH2, | 2859 | rcu_read_lock(); |
2811 | NEIGH_VAR_GC_THRESH3, | 2860 | for_each_netdev_rcu(net, dev) { |
2812 | NEIGH_VAR_MAX | 2861 | struct neigh_parms *dst_p = |
2813 | }; | 2862 | neigh_get_dev_parms_rcu(dev, family); |
2863 | |||
2864 | if (dst_p && !test_bit(index, dst_p->data_state)) | ||
2865 | dst_p->data[index] = p->data[index]; | ||
2866 | } | ||
2867 | rcu_read_unlock(); | ||
2868 | } | ||
2869 | |||
2870 | static void neigh_proc_update(struct ctl_table *ctl, int write) | ||
2871 | { | ||
2872 | struct net_device *dev = ctl->extra1; | ||
2873 | struct neigh_parms *p = ctl->extra2; | ||
2874 | struct net *net = neigh_parms_net(p); | ||
2875 | int index = (int *) ctl->data - p->data; | ||
2876 | |||
2877 | if (!write) | ||
2878 | return; | ||
2879 | |||
2880 | set_bit(index, p->data_state); | ||
2881 | if (!dev) /* NULL dev means this is default value */ | ||
2882 | neigh_copy_dflt_parms(net, p, index); | ||
2883 | } | ||
2884 | |||
2885 | static int neigh_proc_dointvec_zero_intmax(struct ctl_table *ctl, int write, | ||
2886 | void __user *buffer, | ||
2887 | size_t *lenp, loff_t *ppos) | ||
2888 | { | ||
2889 | struct ctl_table tmp = *ctl; | ||
2890 | int ret; | ||
2891 | |||
2892 | tmp.extra1 = &zero; | ||
2893 | tmp.extra2 = &int_max; | ||
2894 | |||
2895 | ret = proc_dointvec_minmax(&tmp, write, buffer, lenp, ppos); | ||
2896 | neigh_proc_update(ctl, write); | ||
2897 | return ret; | ||
2898 | } | ||
2899 | |||
2900 | int neigh_proc_dointvec(struct ctl_table *ctl, int write, | ||
2901 | void __user *buffer, size_t *lenp, loff_t *ppos) | ||
2902 | { | ||
2903 | int ret = proc_dointvec(ctl, write, buffer, lenp, ppos); | ||
2904 | |||
2905 | neigh_proc_update(ctl, write); | ||
2906 | return ret; | ||
2907 | } | ||
2908 | EXPORT_SYMBOL(neigh_proc_dointvec); | ||
2909 | |||
2910 | int neigh_proc_dointvec_jiffies(struct ctl_table *ctl, int write, | ||
2911 | void __user *buffer, | ||
2912 | size_t *lenp, loff_t *ppos) | ||
2913 | { | ||
2914 | int ret = proc_dointvec_jiffies(ctl, write, buffer, lenp, ppos); | ||
2915 | |||
2916 | neigh_proc_update(ctl, write); | ||
2917 | return ret; | ||
2918 | } | ||
2919 | EXPORT_SYMBOL(neigh_proc_dointvec_jiffies); | ||
2920 | |||
2921 | static int neigh_proc_dointvec_userhz_jiffies(struct ctl_table *ctl, int write, | ||
2922 | void __user *buffer, | ||
2923 | size_t *lenp, loff_t *ppos) | ||
2924 | { | ||
2925 | int ret = proc_dointvec_userhz_jiffies(ctl, write, buffer, lenp, ppos); | ||
2926 | |||
2927 | neigh_proc_update(ctl, write); | ||
2928 | return ret; | ||
2929 | } | ||
2930 | |||
2931 | int neigh_proc_dointvec_ms_jiffies(struct ctl_table *ctl, int write, | ||
2932 | void __user *buffer, | ||
2933 | size_t *lenp, loff_t *ppos) | ||
2934 | { | ||
2935 | int ret = proc_dointvec_ms_jiffies(ctl, write, buffer, lenp, ppos); | ||
2936 | |||
2937 | neigh_proc_update(ctl, write); | ||
2938 | return ret; | ||
2939 | } | ||
2940 | EXPORT_SYMBOL(neigh_proc_dointvec_ms_jiffies); | ||
2941 | |||
2942 | static int neigh_proc_dointvec_unres_qlen(struct ctl_table *ctl, int write, | ||
2943 | void __user *buffer, | ||
2944 | size_t *lenp, loff_t *ppos) | ||
2945 | { | ||
2946 | int ret = proc_unres_qlen(ctl, write, buffer, lenp, ppos); | ||
2947 | |||
2948 | neigh_proc_update(ctl, write); | ||
2949 | return ret; | ||
2950 | } | ||
2951 | |||
2952 | #define NEIGH_PARMS_DATA_OFFSET(index) \ | ||
2953 | (&((struct neigh_parms *) 0)->data[index]) | ||
2954 | |||
2955 | #define NEIGH_SYSCTL_ENTRY(attr, data_attr, name, mval, proc) \ | ||
2956 | [NEIGH_VAR_ ## attr] = { \ | ||
2957 | .procname = name, \ | ||
2958 | .data = NEIGH_PARMS_DATA_OFFSET(NEIGH_VAR_ ## data_attr), \ | ||
2959 | .maxlen = sizeof(int), \ | ||
2960 | .mode = mval, \ | ||
2961 | .proc_handler = proc, \ | ||
2962 | } | ||
2963 | |||
2964 | #define NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(attr, name) \ | ||
2965 | NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_zero_intmax) | ||
2966 | |||
2967 | #define NEIGH_SYSCTL_JIFFIES_ENTRY(attr, name) \ | ||
2968 | NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_jiffies) | ||
2969 | |||
2970 | #define NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(attr, name) \ | ||
2971 | NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_userhz_jiffies) | ||
2972 | |||
2973 | #define NEIGH_SYSCTL_MS_JIFFIES_ENTRY(attr, name) \ | ||
2974 | NEIGH_SYSCTL_ENTRY(attr, attr, name, 0644, neigh_proc_dointvec_ms_jiffies) | ||
2975 | |||
2976 | #define NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(attr, data_attr, name) \ | ||
2977 | NEIGH_SYSCTL_ENTRY(attr, data_attr, name, 0644, neigh_proc_dointvec_ms_jiffies) | ||
2978 | |||
2979 | #define NEIGH_SYSCTL_UNRES_QLEN_REUSED_ENTRY(attr, data_attr, name) \ | ||
2980 | NEIGH_SYSCTL_ENTRY(attr, data_attr, name, 0644, neigh_proc_dointvec_unres_qlen) | ||
2814 | 2981 | ||
2815 | static struct neigh_sysctl_table { | 2982 | static struct neigh_sysctl_table { |
2816 | struct ctl_table_header *sysctl_header; | 2983 | struct ctl_table_header *sysctl_header; |
2817 | struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1]; | 2984 | struct ctl_table neigh_vars[NEIGH_VAR_MAX + 1]; |
2818 | } neigh_sysctl_template __read_mostly = { | 2985 | } neigh_sysctl_template __read_mostly = { |
2819 | .neigh_vars = { | 2986 | .neigh_vars = { |
2820 | [NEIGH_VAR_MCAST_PROBE] = { | 2987 | NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(MCAST_PROBES, "mcast_solicit"), |
2821 | .procname = "mcast_solicit", | 2988 | NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(UCAST_PROBES, "ucast_solicit"), |
2822 | .maxlen = sizeof(int), | 2989 | NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(APP_PROBES, "app_solicit"), |
2823 | .mode = 0644, | 2990 | NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(RETRANS_TIME, "retrans_time"), |
2824 | .extra1 = &zero, | 2991 | NEIGH_SYSCTL_JIFFIES_ENTRY(BASE_REACHABLE_TIME, "base_reachable_time"), |
2825 | .extra2 = &int_max, | 2992 | NEIGH_SYSCTL_JIFFIES_ENTRY(DELAY_PROBE_TIME, "delay_first_probe_time"), |
2826 | .proc_handler = proc_dointvec_minmax, | 2993 | NEIGH_SYSCTL_JIFFIES_ENTRY(GC_STALETIME, "gc_stale_time"), |
2827 | }, | 2994 | NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(QUEUE_LEN_BYTES, "unres_qlen_bytes"), |
2828 | [NEIGH_VAR_UCAST_PROBE] = { | 2995 | NEIGH_SYSCTL_ZERO_INTMAX_ENTRY(PROXY_QLEN, "proxy_qlen"), |
2829 | .procname = "ucast_solicit", | 2996 | NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(ANYCAST_DELAY, "anycast_delay"), |
2830 | .maxlen = sizeof(int), | 2997 | NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(PROXY_DELAY, "proxy_delay"), |
2831 | .mode = 0644, | 2998 | NEIGH_SYSCTL_USERHZ_JIFFIES_ENTRY(LOCKTIME, "locktime"), |
2832 | .extra1 = &zero, | 2999 | NEIGH_SYSCTL_UNRES_QLEN_REUSED_ENTRY(QUEUE_LEN, QUEUE_LEN_BYTES, "unres_qlen"), |
2833 | .extra2 = &int_max, | 3000 | NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(RETRANS_TIME_MS, RETRANS_TIME, "retrans_time_ms"), |
2834 | .proc_handler = proc_dointvec_minmax, | 3001 | NEIGH_SYSCTL_MS_JIFFIES_REUSED_ENTRY(BASE_REACHABLE_TIME_MS, BASE_REACHABLE_TIME, "base_reachable_time_ms"), |
2835 | }, | ||
2836 | [NEIGH_VAR_APP_PROBE] = { | ||
2837 | .procname = "app_solicit", | ||
2838 | .maxlen = sizeof(int), | ||
2839 | .mode = 0644, | ||
2840 | .extra1 = &zero, | ||
2841 | .extra2 = &int_max, | ||
2842 | .proc_handler = proc_dointvec_minmax, | ||
2843 | }, | ||
2844 | [NEIGH_VAR_RETRANS_TIME] = { | ||
2845 | .procname = "retrans_time", | ||
2846 | .maxlen = sizeof(int), | ||
2847 | .mode = 0644, | ||
2848 | .proc_handler = proc_dointvec_userhz_jiffies, | ||
2849 | }, | ||
2850 | [NEIGH_VAR_BASE_REACHABLE_TIME] = { | ||
2851 | .procname = "base_reachable_time", | ||
2852 | .maxlen = sizeof(int), | ||
2853 | .mode = 0644, | ||
2854 | .proc_handler = proc_dointvec_jiffies, | ||
2855 | }, | ||
2856 | [NEIGH_VAR_DELAY_PROBE_TIME] = { | ||
2857 | .procname = "delay_first_probe_time", | ||
2858 | .maxlen = sizeof(int), | ||
2859 | .mode = 0644, | ||
2860 | .proc_handler = proc_dointvec_jiffies, | ||
2861 | }, | ||
2862 | [NEIGH_VAR_GC_STALETIME] = { | ||
2863 | .procname = "gc_stale_time", | ||
2864 | .maxlen = sizeof(int), | ||
2865 | .mode = 0644, | ||
2866 | .proc_handler = proc_dointvec_jiffies, | ||
2867 | }, | ||
2868 | [NEIGH_VAR_QUEUE_LEN] = { | ||
2869 | .procname = "unres_qlen", | ||
2870 | .maxlen = sizeof(int), | ||
2871 | .mode = 0644, | ||
2872 | .proc_handler = proc_unres_qlen, | ||
2873 | }, | ||
2874 | [NEIGH_VAR_QUEUE_LEN_BYTES] = { | ||
2875 | .procname = "unres_qlen_bytes", | ||
2876 | .maxlen = sizeof(int), | ||
2877 | .mode = 0644, | ||
2878 | .extra1 = &zero, | ||
2879 | .proc_handler = proc_dointvec_minmax, | ||
2880 | }, | ||
2881 | [NEIGH_VAR_PROXY_QLEN] = { | ||
2882 | .procname = "proxy_qlen", | ||
2883 | .maxlen = sizeof(int), | ||
2884 | .mode = 0644, | ||
2885 | .extra1 = &zero, | ||
2886 | .extra2 = &int_max, | ||
2887 | .proc_handler = proc_dointvec_minmax, | ||
2888 | }, | ||
2889 | [NEIGH_VAR_ANYCAST_DELAY] = { | ||
2890 | .procname = "anycast_delay", | ||
2891 | .maxlen = sizeof(int), | ||
2892 | .mode = 0644, | ||
2893 | .proc_handler = proc_dointvec_userhz_jiffies, | ||
2894 | }, | ||
2895 | [NEIGH_VAR_PROXY_DELAY] = { | ||
2896 | .procname = "proxy_delay", | ||
2897 | .maxlen = sizeof(int), | ||
2898 | .mode = 0644, | ||
2899 | .proc_handler = proc_dointvec_userhz_jiffies, | ||
2900 | }, | ||
2901 | [NEIGH_VAR_LOCKTIME] = { | ||
2902 | .procname = "locktime", | ||
2903 | .maxlen = sizeof(int), | ||
2904 | .mode = 0644, | ||
2905 | .proc_handler = proc_dointvec_userhz_jiffies, | ||
2906 | }, | ||
2907 | [NEIGH_VAR_RETRANS_TIME_MS] = { | ||
2908 | .procname = "retrans_time_ms", | ||
2909 | .maxlen = sizeof(int), | ||
2910 | .mode = 0644, | ||
2911 | .proc_handler = proc_dointvec_ms_jiffies, | ||
2912 | }, | ||
2913 | [NEIGH_VAR_BASE_REACHABLE_TIME_MS] = { | ||
2914 | .procname = "base_reachable_time_ms", | ||
2915 | .maxlen = sizeof(int), | ||
2916 | .mode = 0644, | ||
2917 | .proc_handler = proc_dointvec_ms_jiffies, | ||
2918 | }, | ||
2919 | [NEIGH_VAR_GC_INTERVAL] = { | 3002 | [NEIGH_VAR_GC_INTERVAL] = { |
2920 | .procname = "gc_interval", | 3003 | .procname = "gc_interval", |
2921 | .maxlen = sizeof(int), | 3004 | .maxlen = sizeof(int), |
@@ -2951,31 +3034,23 @@ static struct neigh_sysctl_table { | |||
2951 | }; | 3034 | }; |
2952 | 3035 | ||
2953 | int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | 3036 | int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, |
2954 | char *p_name, proc_handler *handler) | 3037 | proc_handler *handler) |
2955 | { | 3038 | { |
3039 | int i; | ||
2956 | struct neigh_sysctl_table *t; | 3040 | struct neigh_sysctl_table *t; |
2957 | const char *dev_name_source = NULL; | 3041 | const char *dev_name_source; |
2958 | char neigh_path[ sizeof("net//neigh/") + IFNAMSIZ + IFNAMSIZ ]; | 3042 | char neigh_path[ sizeof("net//neigh/") + IFNAMSIZ + IFNAMSIZ ]; |
3043 | char *p_name; | ||
2959 | 3044 | ||
2960 | t = kmemdup(&neigh_sysctl_template, sizeof(*t), GFP_KERNEL); | 3045 | t = kmemdup(&neigh_sysctl_template, sizeof(*t), GFP_KERNEL); |
2961 | if (!t) | 3046 | if (!t) |
2962 | goto err; | 3047 | goto err; |
2963 | 3048 | ||
2964 | t->neigh_vars[NEIGH_VAR_MCAST_PROBE].data = &p->mcast_probes; | 3049 | for (i = 0; i < NEIGH_VAR_GC_INTERVAL; i++) { |
2965 | t->neigh_vars[NEIGH_VAR_UCAST_PROBE].data = &p->ucast_probes; | 3050 | t->neigh_vars[i].data += (long) p; |
2966 | t->neigh_vars[NEIGH_VAR_APP_PROBE].data = &p->app_probes; | 3051 | t->neigh_vars[i].extra1 = dev; |
2967 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].data = &p->retrans_time; | 3052 | t->neigh_vars[i].extra2 = p; |
2968 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].data = &p->base_reachable_time; | 3053 | } |
2969 | t->neigh_vars[NEIGH_VAR_DELAY_PROBE_TIME].data = &p->delay_probe_time; | ||
2970 | t->neigh_vars[NEIGH_VAR_GC_STALETIME].data = &p->gc_staletime; | ||
2971 | t->neigh_vars[NEIGH_VAR_QUEUE_LEN].data = &p->queue_len_bytes; | ||
2972 | t->neigh_vars[NEIGH_VAR_QUEUE_LEN_BYTES].data = &p->queue_len_bytes; | ||
2973 | t->neigh_vars[NEIGH_VAR_PROXY_QLEN].data = &p->proxy_qlen; | ||
2974 | t->neigh_vars[NEIGH_VAR_ANYCAST_DELAY].data = &p->anycast_delay; | ||
2975 | t->neigh_vars[NEIGH_VAR_PROXY_DELAY].data = &p->proxy_delay; | ||
2976 | t->neigh_vars[NEIGH_VAR_LOCKTIME].data = &p->locktime; | ||
2977 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].data = &p->retrans_time; | ||
2978 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].data = &p->base_reachable_time; | ||
2979 | 3054 | ||
2980 | if (dev) { | 3055 | if (dev) { |
2981 | dev_name_source = dev->name; | 3056 | dev_name_source = dev->name; |
@@ -2990,26 +3065,32 @@ int neigh_sysctl_register(struct net_device *dev, struct neigh_parms *p, | |||
2990 | t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = (int *)(p + 1) + 3; | 3065 | t->neigh_vars[NEIGH_VAR_GC_THRESH3].data = (int *)(p + 1) + 3; |
2991 | } | 3066 | } |
2992 | 3067 | ||
2993 | |||
2994 | if (handler) { | 3068 | if (handler) { |
2995 | /* RetransTime */ | 3069 | /* RetransTime */ |
2996 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].proc_handler = handler; | 3070 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].proc_handler = handler; |
2997 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME].extra1 = dev; | ||
2998 | /* ReachableTime */ | 3071 | /* ReachableTime */ |
2999 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = handler; | 3072 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].proc_handler = handler; |
3000 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME].extra1 = dev; | ||
3001 | /* RetransTime (in milliseconds)*/ | 3073 | /* RetransTime (in milliseconds)*/ |
3002 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler; | 3074 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].proc_handler = handler; |
3003 | t->neigh_vars[NEIGH_VAR_RETRANS_TIME_MS].extra1 = dev; | ||
3004 | /* ReachableTime (in milliseconds) */ | 3075 | /* ReachableTime (in milliseconds) */ |
3005 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler; | 3076 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].proc_handler = handler; |
3006 | t->neigh_vars[NEIGH_VAR_BASE_REACHABLE_TIME_MS].extra1 = dev; | ||
3007 | } | 3077 | } |
3008 | 3078 | ||
3009 | /* Don't export sysctls to unprivileged users */ | 3079 | /* Don't export sysctls to unprivileged users */ |
3010 | if (neigh_parms_net(p)->user_ns != &init_user_ns) | 3080 | if (neigh_parms_net(p)->user_ns != &init_user_ns) |
3011 | t->neigh_vars[0].procname = NULL; | 3081 | t->neigh_vars[0].procname = NULL; |
3012 | 3082 | ||
3083 | switch (neigh_parms_family(p)) { | ||
3084 | case AF_INET: | ||
3085 | p_name = "ipv4"; | ||
3086 | break; | ||
3087 | case AF_INET6: | ||
3088 | p_name = "ipv6"; | ||
3089 | break; | ||
3090 | default: | ||
3091 | BUG(); | ||
3092 | } | ||
3093 | |||
3013 | snprintf(neigh_path, sizeof(neigh_path), "net/%s/neigh/%s", | 3094 | snprintf(neigh_path, sizeof(neigh_path), "net/%s/neigh/%s", |
3014 | p_name, dev_name_source); | 3095 | p_name, dev_name_source); |
3015 | t->sysctl_header = | 3096 | t->sysctl_header = |