@@ -316,9 +316,18 @@ static void pneigh_queue_purge(struct sk_buff_head *list, struct net *net)
316
316
skb = skb_peek (list );
317
317
while (skb != NULL ) {
318
318
struct sk_buff * skb_next = skb_peek_next (skb , list );
319
- if (net == NULL || net_eq (dev_net (skb -> dev ), net )) {
319
+ struct net_device * dev = skb -> dev ;
320
+ if (net == NULL || net_eq (dev_net (dev ), net )) {
321
+ struct in_device * in_dev ;
322
+
323
+ rcu_read_lock ();
324
+ in_dev = __in_dev_get_rcu (dev );
325
+ if (in_dev )
326
+ in_dev -> arp_parms -> qlen -- ;
327
+ rcu_read_unlock ();
320
328
__skb_unlink (skb , list );
321
- dev_put (skb -> dev );
329
+
330
+ dev_put (dev );
322
331
kfree_skb (skb );
323
332
}
324
333
skb = skb_next ;
@@ -1606,8 +1615,15 @@ static void neigh_proxy_process(struct timer_list *t)
1606
1615
1607
1616
if (tdif <= 0 ) {
1608
1617
struct net_device * dev = skb -> dev ;
1618
+ struct in_device * in_dev ;
1609
1619
1620
+ rcu_read_lock ();
1621
+ in_dev = __in_dev_get_rcu (dev );
1622
+ if (in_dev )
1623
+ in_dev -> arp_parms -> qlen -- ;
1624
+ rcu_read_unlock ();
1610
1625
__skb_unlink (skb , & tbl -> proxy_queue );
1626
+
1611
1627
if (tbl -> proxy_redo && netif_running (dev )) {
1612
1628
rcu_read_lock ();
1613
1629
tbl -> proxy_redo (skb );
@@ -1632,7 +1648,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
1632
1648
unsigned long sched_next = jiffies +
1633
1649
prandom_u32_max (NEIGH_VAR (p , PROXY_DELAY ));
1634
1650
1635
- if (tbl -> proxy_queue . qlen > NEIGH_VAR (p , PROXY_QLEN )) {
1651
+ if (p -> qlen > NEIGH_VAR (p , PROXY_QLEN )) {
1636
1652
kfree_skb (skb );
1637
1653
return ;
1638
1654
}
@@ -1648,6 +1664,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
1648
1664
skb_dst_drop (skb );
1649
1665
dev_hold (skb -> dev );
1650
1666
__skb_queue_tail (& tbl -> proxy_queue , skb );
1667
+ p -> qlen ++ ;
1651
1668
mod_timer (& tbl -> proxy_timer , sched_next );
1652
1669
spin_unlock (& tbl -> proxy_queue .lock );
1653
1670
}
@@ -1680,6 +1697,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
1680
1697
refcount_set (& p -> refcnt , 1 );
1681
1698
p -> reachable_time =
1682
1699
neigh_rand_reach_time (NEIGH_VAR (p , BASE_REACHABLE_TIME ));
1700
+ p -> qlen = 0 ;
1683
1701
netdev_hold (dev , & p -> dev_tracker , GFP_KERNEL );
1684
1702
p -> dev = dev ;
1685
1703
write_pnet (& p -> net , net );
@@ -1745,6 +1763,7 @@ void neigh_table_init(int index, struct neigh_table *tbl)
1745
1763
refcount_set (& tbl -> parms .refcnt , 1 );
1746
1764
tbl -> parms .reachable_time =
1747
1765
neigh_rand_reach_time (NEIGH_VAR (& tbl -> parms , BASE_REACHABLE_TIME ));
1766
+ tbl -> parms .qlen = 0 ;
1748
1767
1749
1768
tbl -> stats = alloc_percpu (struct neigh_statistics );
1750
1769
if (!tbl -> stats )
0 commit comments