patch-2_6_7-vs1_9_1_12
[linux-2.6.git] / net / core / dst.c
index ba4856c..571ef1f 100644 (file)
@@ -100,15 +100,15 @@ out:
        spin_unlock(&dst_lock);
 }
 
-static int dst_discard(struct sk_buff *skb)
+static int dst_discard_in(struct sk_buff *skb)
 {
        kfree_skb(skb);
        return 0;
 }
 
-static int dst_blackhole(struct sk_buff *skb)
+static int dst_discard_out(struct sk_buff **pskb)
 {
-       kfree_skb(skb);
+       kfree_skb(*pskb);
        return 0;
 }
 
@@ -128,8 +128,8 @@ void * dst_alloc(struct dst_ops * ops)
        dst->ops = ops;
        dst->lastuse = jiffies;
        dst->path = dst;
-       dst->input = dst_discard;
-       dst->output = dst_blackhole;
+       dst->input = dst_discard_in;
+       dst->output = dst_discard_out;
 #if RT_CACHE_DEBUG >= 2 
        atomic_inc(&dst_total);
 #endif
@@ -143,8 +143,8 @@ static void ___dst_free(struct dst_entry * dst)
           protocol module is unloaded.
         */
        if (dst->dev == NULL || !(dst->dev->flags&IFF_UP)) {
-               dst->input = dst_discard;
-               dst->output = dst_blackhole;
+               dst->input = dst_discard_in;
+               dst->output = dst_discard_out;
        }
        dst->obsolete = 2;
 }
@@ -228,20 +228,22 @@ static int dst_dev_event(struct notifier_block *this, unsigned long event, void
                                   _race_ _condition_.
                                 */
                                if (event!=NETDEV_DOWN &&
-                                   dst->output == dst_blackhole) {
+                                   dst->output == dst_discard_out) {
                                        dst->dev = &loopback_dev;
-                                       dev_put(dev);
                                        dev_hold(&loopback_dev);
-                                       dst->output = dst_discard;
+                                       dev_put(dev);
+                                       dst->output = dst_discard_out;
                                        if (dst->neighbour && dst->neighbour->dev == dev) {
                                                dst->neighbour->dev = &loopback_dev;
                                                dev_put(dev);
                                                dev_hold(&loopback_dev);
                                        }
                                } else {
-                                       dst->input = dst_discard;
-                                       dst->output = dst_blackhole;
+                                       dst->input = dst_discard_in;
+                                       dst->output = dst_discard_out;
                                }
+                               if (dst->ops->ifdown)
+                                       dst->ops->ifdown(dst, event != NETDEV_DOWN);
                        }
                }
                spin_unlock_bh(&dst_lock);