static struct dst_entry *ipv4_dst_check(struct dst_entry *dst, u32 cookie);
static void ipv4_dst_destroy(struct dst_entry *dst);
+static void ipv4_dst_ifdown(struct dst_entry *dst, int how);
static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst);
static void ipv4_link_failure(struct sk_buff *skb);
static void ip_rt_update_pmtu(struct dst_entry *dst, u32 mtu);
.gc = rt_garbage_collect,
.check = ipv4_dst_check,
.destroy = ipv4_dst_destroy,
+ .ifdown = ipv4_dst_ifdown,
.negative_advice = ipv4_negative_advice,
.link_failure = ipv4_link_failure,
.update_pmtu = ip_rt_update_pmtu,
rt->u.dst.child = NULL;
if (rt->u.dst.dev)
dev_hold(rt->u.dst.dev);
+ if (rt->idev)
+ in_dev_hold(rt->idev);
rt->u.dst.obsolete = 0;
rt->u.dst.lastuse = jiffies;
rt->u.dst.path = &rt->u.dst;
{
struct rtable *rt = (struct rtable *) dst;
struct inet_peer *peer = rt->peer;
+ struct in_device *idev = rt->idev;
if (peer) {
rt->peer = NULL;
inet_putpeer(peer);
}
+
+ if (idev) {
+ rt->idev = NULL;
+ in_dev_put(idev);
+ }
+}
+
+static void ipv4_dst_ifdown(struct dst_entry *dst, int how)
+{
+ struct rtable *rt = (struct rtable *) dst;
+ struct in_device *idev = rt->idev;
+ if (idev) {
+ rt->idev = NULL;
+ in_dev_put(idev);
+ }
}
static void ipv4_link_failure(struct sk_buff *skb)
dst_set_expires(&rt->u.dst, 0);
}
-static int ip_rt_bug(struct sk_buff *skb)
+static int ip_rt_bug(struct sk_buff **pskb)
{
+ struct sk_buff *skb = *pskb;
+
printk(KERN_DEBUG "ip_rt_bug: %u.%u.%u.%u -> %u.%u.%u.%u, %s\n",
NIPQUAD(skb->nh.iph->saddr), NIPQUAD(skb->nh.iph->daddr),
skb->dev ? skb->dev->name : "?");
rth->fl.iif = dev->ifindex;
rth->u.dst.dev = &loopback_dev;
dev_hold(rth->u.dst.dev);
+ rth->idev = in_dev_get(rth->u.dst.dev);
rth->fl.oif = 0;
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
rth->fl.iif = dev->ifindex;
rth->u.dst.dev = out_dev->dev;
dev_hold(rth->u.dst.dev);
+ rth->idev = in_dev_get(rth->u.dst.dev);
rth->fl.oif = 0;
rth->rt_spec_dst= spec_dst;
rth->fl.iif = dev->ifindex;
rth->u.dst.dev = &loopback_dev;
dev_hold(rth->u.dst.dev);
+ rth->idev = in_dev_get(rth->u.dst.dev);
rth->rt_gateway = daddr;
rth->rt_spec_dst= spec_dst;
rth->u.dst.input= ip_local_deliver;
rth->rt_iif = oldflp->oif ? : dev_out->ifindex;
rth->u.dst.dev = dev_out;
dev_hold(dev_out);
+ rth->idev = in_dev_get(dev_out);
rth->rt_gateway = fl.fl4_dst;
rth->rt_spec_dst= fl.fl4_src;
static int flush_delay;
static int ipv4_sysctl_rtcache_flush(ctl_table *ctl, int write,
- struct file *filp, void *buffer,
+ struct file *filp, void __user *buffer,
size_t *lenp)
{
if (write) {
return -EINVAL;
}
-static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table, int *name,
- int nlen, void *oldval,
- size_t *oldlenp, void *newval,
- size_t newlen, void **context)
+static int ipv4_sysctl_rtcache_flush_strategy(ctl_table *table,
+ int __user *name,
+ int nlen,
+ void __user *oldval,
+ size_t __user *oldlenp,
+ void __user *newval,
+ size_t newlen,
+ void **context)
{
int delay;
if (newlen != sizeof(int))
return -EINVAL;
- if (get_user(delay, (int *)newval))
+ if (get_user(delay, (int __user *)newval))
return -EFAULT;
rt_cache_flush(delay);
return 0;