]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/blobdiff - net/core/neighbour.c
IPVS: use pr_err and friends instead of IP_VS_ERR and friends
[mirror_ubuntu-bionic-kernel.git] / net / core / neighbour.c
index a1cbce7fdae5851f6534f433eb0aa3be3a06e1e6..c6f9ad8e4c7a2e80d6e8fa34056907fad871ab26 100644 (file)
@@ -771,6 +771,28 @@ static __inline__ int neigh_max_probes(struct neighbour *n)
                p->ucast_probes + p->app_probes + p->mcast_probes);
 }
 
+static void neigh_invalidate(struct neighbour *neigh)
+{
+       struct sk_buff *skb;
+
+       NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
+       NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
+       neigh->updated = jiffies;
+
+       /* It is very thin place. report_unreachable is very complicated
+          routine. Particularly, it can hit the same neighbour entry!
+
+          So that, we try to be accurate and avoid dead loop. --ANK
+        */
+       while (neigh->nud_state == NUD_FAILED &&
+              (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
+               write_unlock(&neigh->lock);
+               neigh->ops->error_report(neigh, skb);
+               write_lock(&neigh->lock);
+       }
+       skb_queue_purge(&neigh->arp_queue);
+}
+
 /* Called when a timer expires for a neighbour entry. */
 
 static void neigh_timer_handler(unsigned long arg)
@@ -835,26 +857,9 @@ static void neigh_timer_handler(unsigned long arg)
 
        if ((neigh->nud_state & (NUD_INCOMPLETE | NUD_PROBE)) &&
            atomic_read(&neigh->probes) >= neigh_max_probes(neigh)) {
-               struct sk_buff *skb;
-
                neigh->nud_state = NUD_FAILED;
-               neigh->updated = jiffies;
                notify = 1;
-               NEIGH_CACHE_STAT_INC(neigh->tbl, res_failed);
-               NEIGH_PRINTK2("neigh %p is failed.\n", neigh);
-
-               /* It is very thin place. report_unreachable is very complicated
-                  routine. Particularly, it can hit the same neighbour entry!
-
-                  So that, we try to be accurate and avoid dead loop. --ANK
-                */
-               while (neigh->nud_state == NUD_FAILED &&
-                      (skb = __skb_dequeue(&neigh->arp_queue)) != NULL) {
-                       write_unlock(&neigh->lock);
-                       neigh->ops->error_report(neigh, skb);
-                       write_lock(&neigh->lock);
-               }
-               skb_queue_purge(&neigh->arp_queue);
+               neigh_invalidate(neigh);
        }
 
        if (neigh->nud_state & NUD_IN_TIMER) {
@@ -1001,6 +1006,11 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                neigh->nud_state = new;
                err = 0;
                notify = old & NUD_VALID;
+               if ((old & (NUD_INCOMPLETE | NUD_PROBE)) &&
+                   (new & NUD_FAILED)) {
+                       neigh_invalidate(neigh);
+                       notify = 1;
+               }
                goto out;
        }
 
@@ -1088,8 +1098,8 @@ int neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new,
                        struct neighbour *n1 = neigh;
                        write_unlock_bh(&neigh->lock);
                        /* On shaper/eql skb->dst->neighbour != neigh :( */
-                       if (skb->dst && skb->dst->neighbour)
-                               n1 = skb->dst->neighbour;
+                       if (skb_dst(skb) && skb_dst(skb)->neighbour)
+                               n1 = skb_dst(skb)->neighbour;
                        n1->output(skb);
                        write_lock_bh(&neigh->lock);
                }
@@ -1182,7 +1192,7 @@ EXPORT_SYMBOL(neigh_compat_output);
 
 int neigh_resolve_output(struct sk_buff *skb)
 {
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh;
        int rc = 0;
 
@@ -1229,7 +1239,7 @@ EXPORT_SYMBOL(neigh_resolve_output);
 int neigh_connected_output(struct sk_buff *skb)
 {
        int err;
-       struct dst_entry *dst = skb->dst;
+       struct dst_entry *dst = skb_dst(skb);
        struct neighbour *neigh = dst->neighbour;
        struct net_device *dev = neigh->dev;
 
@@ -1298,8 +1308,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
                if (time_before(tbl->proxy_timer.expires, sched_next))
                        sched_next = tbl->proxy_timer.expires;
        }
-       dst_release(skb->dst);
-       skb->dst = NULL;
+       skb_dst_drop(skb);
        dev_hold(skb->dev);
        __skb_queue_tail(&tbl->proxy_queue, skb);
        mod_timer(&tbl->proxy_timer, sched_next);
@@ -1307,7 +1316,7 @@ void pneigh_enqueue(struct neigh_table *tbl, struct neigh_parms *p,
 }
 EXPORT_SYMBOL(pneigh_enqueue);
 
-static inline struct neigh_parms *lookup_neigh_params(struct neigh_table *tbl,
+static inline struct neigh_parms *lookup_neigh_parms(struct neigh_table *tbl,
                                                      struct net *net, int ifindex)
 {
        struct neigh_parms *p;
@@ -1328,7 +1337,7 @@ struct neigh_parms *neigh_parms_alloc(struct net_device *dev,
        struct net *net = dev_net(dev);
        const struct net_device_ops *ops = dev->netdev_ops;
 
-       ref = lookup_neigh_params(tbl, net, 0);
+       ref = lookup_neigh_parms(tbl, net, 0);
        if (!ref)
                return NULL;
 
@@ -1897,7 +1906,7 @@ static int neightbl_set(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
                if (tbp[NDTPA_IFINDEX])
                        ifindex = nla_get_u32(tbp[NDTPA_IFINDEX]);
 
-               p = lookup_neigh_params(tbl, net, ifindex);
+               p = lookup_neigh_parms(tbl, net, ifindex);
                if (p == NULL) {
                        err = -ENOENT;
                        goto errout_tbl_lock;