|
@@ -1064,7 +1064,8 @@ work_done:
|
|
out: return 0;
|
|
out: return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp)
|
|
|
|
|
|
+static int rt_intern_hash(unsigned hash, struct rtable *rt,
|
|
|
|
+ struct rtable **rp, struct sk_buff *skb)
|
|
{
|
|
{
|
|
struct rtable *rth, **rthp;
|
|
struct rtable *rth, **rthp;
|
|
unsigned long now;
|
|
unsigned long now;
|
|
@@ -1114,7 +1115,10 @@ restart:
|
|
spin_unlock_bh(rt_hash_lock_addr(hash));
|
|
spin_unlock_bh(rt_hash_lock_addr(hash));
|
|
|
|
|
|
rt_drop(rt);
|
|
rt_drop(rt);
|
|
- *rp = rth;
|
|
|
|
|
|
+ if (rp)
|
|
|
|
+ *rp = rth;
|
|
|
|
+ else
|
|
|
|
+ skb->dst = &rth->u.dst;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1210,7 +1214,10 @@ restart:
|
|
rcu_assign_pointer(rt_hash_table[hash].chain, rt);
|
|
rcu_assign_pointer(rt_hash_table[hash].chain, rt);
|
|
|
|
|
|
spin_unlock_bh(rt_hash_lock_addr(hash));
|
|
spin_unlock_bh(rt_hash_lock_addr(hash));
|
|
- *rp = rt;
|
|
|
|
|
|
+ if (rp)
|
|
|
|
+ *rp = rt;
|
|
|
|
+ else
|
|
|
|
+ skb->dst = &rt->u.dst;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1407,7 +1414,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw,
|
|
&netevent);
|
|
&netevent);
|
|
|
|
|
|
rt_del(hash, rth);
|
|
rt_del(hash, rth);
|
|
- if (!rt_intern_hash(hash, rt, &rt))
|
|
|
|
|
|
+ if (!rt_intern_hash(hash, rt, &rt, NULL))
|
|
ip_rt_put(rt);
|
|
ip_rt_put(rt);
|
|
goto do_next;
|
|
goto do_next;
|
|
}
|
|
}
|
|
@@ -1473,7 +1480,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst)
|
|
|
|
|
|
void ip_rt_send_redirect(struct sk_buff *skb)
|
|
void ip_rt_send_redirect(struct sk_buff *skb)
|
|
{
|
|
{
|
|
- struct rtable *rt = skb->rtable;
|
|
|
|
|
|
+ struct rtable *rt = skb_rtable(skb);
|
|
struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
|
|
struct in_device *in_dev = in_dev_get(rt->u.dst.dev);
|
|
|
|
|
|
if (!in_dev)
|
|
if (!in_dev)
|
|
@@ -1521,7 +1528,7 @@ out:
|
|
|
|
|
|
static int ip_error(struct sk_buff *skb)
|
|
static int ip_error(struct sk_buff *skb)
|
|
{
|
|
{
|
|
- struct rtable *rt = skb->rtable;
|
|
|
|
|
|
+ struct rtable *rt = skb_rtable(skb);
|
|
unsigned long now;
|
|
unsigned long now;
|
|
int code;
|
|
int code;
|
|
|
|
|
|
@@ -1698,7 +1705,7 @@ static void ipv4_link_failure(struct sk_buff *skb)
|
|
|
|
|
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
|
icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0);
|
|
|
|
|
|
- rt = skb->rtable;
|
|
|
|
|
|
+ rt = skb_rtable(skb);
|
|
if (rt)
|
|
if (rt)
|
|
dst_set_expires(&rt->u.dst, 0);
|
|
dst_set_expires(&rt->u.dst, 0);
|
|
}
|
|
}
|
|
@@ -1858,7 +1865,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
|
|
|
|
|
in_dev_put(in_dev);
|
|
in_dev_put(in_dev);
|
|
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
|
|
hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev)));
|
|
- return rt_intern_hash(hash, rth, &skb->rtable);
|
|
|
|
|
|
+ return rt_intern_hash(hash, rth, NULL, skb);
|
|
|
|
|
|
e_nobufs:
|
|
e_nobufs:
|
|
in_dev_put(in_dev);
|
|
in_dev_put(in_dev);
|
|
@@ -2019,7 +2026,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
|
|
/* put it into the cache */
|
|
/* put it into the cache */
|
|
hash = rt_hash(daddr, saddr, fl->iif,
|
|
hash = rt_hash(daddr, saddr, fl->iif,
|
|
rt_genid(dev_net(rth->u.dst.dev)));
|
|
rt_genid(dev_net(rth->u.dst.dev)));
|
|
- return rt_intern_hash(hash, rth, &skb->rtable);
|
|
|
|
|
|
+ return rt_intern_hash(hash, rth, NULL, skb);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -2175,7 +2182,7 @@ local_input:
|
|
}
|
|
}
|
|
rth->rt_type = res.type;
|
|
rth->rt_type = res.type;
|
|
hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
|
|
hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net));
|
|
- err = rt_intern_hash(hash, rth, &skb->rtable);
|
|
|
|
|
|
+ err = rt_intern_hash(hash, rth, NULL, skb);
|
|
goto done;
|
|
goto done;
|
|
|
|
|
|
no_route:
|
|
no_route:
|
|
@@ -2244,7 +2251,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
|
|
dst_use(&rth->u.dst, jiffies);
|
|
dst_use(&rth->u.dst, jiffies);
|
|
RT_CACHE_STAT_INC(in_hit);
|
|
RT_CACHE_STAT_INC(in_hit);
|
|
rcu_read_unlock();
|
|
rcu_read_unlock();
|
|
- skb->rtable = rth;
|
|
|
|
|
|
+ skb->dst = &rth->u.dst;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
RT_CACHE_STAT_INC(in_hlist_search);
|
|
RT_CACHE_STAT_INC(in_hlist_search);
|
|
@@ -2420,7 +2427,7 @@ static int ip_mkroute_output(struct rtable **rp,
|
|
if (err == 0) {
|
|
if (err == 0) {
|
|
hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
|
|
hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif,
|
|
rt_genid(dev_net(dev_out)));
|
|
rt_genid(dev_net(dev_out)));
|
|
- err = rt_intern_hash(hash, rth, rp);
|
|
|
|
|
|
+ err = rt_intern_hash(hash, rth, rp, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
return err;
|
|
return err;
|
|
@@ -2763,7 +2770,7 @@ static int rt_fill_info(struct net *net,
|
|
struct sk_buff *skb, u32 pid, u32 seq, int event,
|
|
struct sk_buff *skb, u32 pid, u32 seq, int event,
|
|
int nowait, unsigned int flags)
|
|
int nowait, unsigned int flags)
|
|
{
|
|
{
|
|
- struct rtable *rt = skb->rtable;
|
|
|
|
|
|
+ struct rtable *rt = skb_rtable(skb);
|
|
struct rtmsg *r;
|
|
struct rtmsg *r;
|
|
struct nlmsghdr *nlh;
|
|
struct nlmsghdr *nlh;
|
|
long expires;
|
|
long expires;
|
|
@@ -2907,7 +2914,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
|
|
err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
|
|
err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev);
|
|
local_bh_enable();
|
|
local_bh_enable();
|
|
|
|
|
|
- rt = skb->rtable;
|
|
|
|
|
|
+ rt = skb_rtable(skb);
|
|
if (err == 0 && rt->u.dst.error)
|
|
if (err == 0 && rt->u.dst.error)
|
|
err = -rt->u.dst.error;
|
|
err = -rt->u.dst.error;
|
|
} else {
|
|
} else {
|
|
@@ -2927,7 +2934,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void
|
|
if (err)
|
|
if (err)
|
|
goto errout_free;
|
|
goto errout_free;
|
|
|
|
|
|
- skb->rtable = rt;
|
|
|
|
|
|
+ skb->dst = &rt->u.dst;
|
|
if (rtm->rtm_flags & RTM_F_NOTIFY)
|
|
if (rtm->rtm_flags & RTM_F_NOTIFY)
|
|
rt->rt_flags |= RTCF_NOTIFY;
|
|
rt->rt_flags |= RTCF_NOTIFY;
|
|
|
|
|