diff options
Diffstat (limited to 'net/ipv4/route.c')
-rw-r--r-- | net/ipv4/route.c | 37 |
1 files changed, 22 insertions, 15 deletions
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index 28205e5bfa9b..f20060ac2f09 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -1064,7 +1064,8 @@ work_done: | |||
1064 | out: return 0; | 1064 | out: return 0; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | static int rt_intern_hash(unsigned hash, struct rtable *rt, struct rtable **rp) | 1067 | static int rt_intern_hash(unsigned hash, struct rtable *rt, |
1068 | struct rtable **rp, struct sk_buff *skb) | ||
1068 | { | 1069 | { |
1069 | struct rtable *rth, **rthp; | 1070 | struct rtable *rth, **rthp; |
1070 | unsigned long now; | 1071 | unsigned long now; |
@@ -1114,7 +1115,10 @@ restart: | |||
1114 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1115 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1115 | 1116 | ||
1116 | rt_drop(rt); | 1117 | rt_drop(rt); |
1117 | *rp = rth; | 1118 | if (rp) |
1119 | *rp = rth; | ||
1120 | else | ||
1121 | skb->dst = &rth->u.dst; | ||
1118 | return 0; | 1122 | return 0; |
1119 | } | 1123 | } |
1120 | 1124 | ||
@@ -1210,7 +1214,10 @@ restart: | |||
1210 | rcu_assign_pointer(rt_hash_table[hash].chain, rt); | 1214 | rcu_assign_pointer(rt_hash_table[hash].chain, rt); |
1211 | 1215 | ||
1212 | spin_unlock_bh(rt_hash_lock_addr(hash)); | 1216 | spin_unlock_bh(rt_hash_lock_addr(hash)); |
1213 | *rp = rt; | 1217 | if (rp) |
1218 | *rp = rt; | ||
1219 | else | ||
1220 | skb->dst = &rt->u.dst; | ||
1214 | return 0; | 1221 | return 0; |
1215 | } | 1222 | } |
1216 | 1223 | ||
@@ -1407,7 +1414,7 @@ void ip_rt_redirect(__be32 old_gw, __be32 daddr, __be32 new_gw, | |||
1407 | &netevent); | 1414 | &netevent); |
1408 | 1415 | ||
1409 | rt_del(hash, rth); | 1416 | rt_del(hash, rth); |
1410 | if (!rt_intern_hash(hash, rt, &rt)) | 1417 | if (!rt_intern_hash(hash, rt, &rt, NULL)) |
1411 | ip_rt_put(rt); | 1418 | ip_rt_put(rt); |
1412 | goto do_next; | 1419 | goto do_next; |
1413 | } | 1420 | } |
@@ -1473,7 +1480,7 @@ static struct dst_entry *ipv4_negative_advice(struct dst_entry *dst) | |||
1473 | 1480 | ||
1474 | void ip_rt_send_redirect(struct sk_buff *skb) | 1481 | void ip_rt_send_redirect(struct sk_buff *skb) |
1475 | { | 1482 | { |
1476 | struct rtable *rt = skb->rtable; | 1483 | struct rtable *rt = skb_rtable(skb); |
1477 | struct in_device *in_dev = in_dev_get(rt->u.dst.dev); | 1484 | struct in_device *in_dev = in_dev_get(rt->u.dst.dev); |
1478 | 1485 | ||
1479 | if (!in_dev) | 1486 | if (!in_dev) |
@@ -1521,7 +1528,7 @@ out: | |||
1521 | 1528 | ||
1522 | static int ip_error(struct sk_buff *skb) | 1529 | static int ip_error(struct sk_buff *skb) |
1523 | { | 1530 | { |
1524 | struct rtable *rt = skb->rtable; | 1531 | struct rtable *rt = skb_rtable(skb); |
1525 | unsigned long now; | 1532 | unsigned long now; |
1526 | int code; | 1533 | int code; |
1527 | 1534 | ||
@@ -1698,7 +1705,7 @@ static void ipv4_link_failure(struct sk_buff *skb) | |||
1698 | 1705 | ||
1699 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); | 1706 | icmp_send(skb, ICMP_DEST_UNREACH, ICMP_HOST_UNREACH, 0); |
1700 | 1707 | ||
1701 | rt = skb->rtable; | 1708 | rt = skb_rtable(skb); |
1702 | if (rt) | 1709 | if (rt) |
1703 | dst_set_expires(&rt->u.dst, 0); | 1710 | dst_set_expires(&rt->u.dst, 0); |
1704 | } | 1711 | } |
@@ -1858,7 +1865,7 @@ static int ip_route_input_mc(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
1858 | 1865 | ||
1859 | in_dev_put(in_dev); | 1866 | in_dev_put(in_dev); |
1860 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); | 1867 | hash = rt_hash(daddr, saddr, dev->ifindex, rt_genid(dev_net(dev))); |
1861 | return rt_intern_hash(hash, rth, &skb->rtable); | 1868 | return rt_intern_hash(hash, rth, NULL, skb); |
1862 | 1869 | ||
1863 | e_nobufs: | 1870 | e_nobufs: |
1864 | in_dev_put(in_dev); | 1871 | in_dev_put(in_dev); |
@@ -2019,7 +2026,7 @@ static int ip_mkroute_input(struct sk_buff *skb, | |||
2019 | /* put it into the cache */ | 2026 | /* put it into the cache */ |
2020 | hash = rt_hash(daddr, saddr, fl->iif, | 2027 | hash = rt_hash(daddr, saddr, fl->iif, |
2021 | rt_genid(dev_net(rth->u.dst.dev))); | 2028 | rt_genid(dev_net(rth->u.dst.dev))); |
2022 | return rt_intern_hash(hash, rth, &skb->rtable); | 2029 | return rt_intern_hash(hash, rth, NULL, skb); |
2023 | } | 2030 | } |
2024 | 2031 | ||
2025 | /* | 2032 | /* |
@@ -2175,7 +2182,7 @@ local_input: | |||
2175 | } | 2182 | } |
2176 | rth->rt_type = res.type; | 2183 | rth->rt_type = res.type; |
2177 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); | 2184 | hash = rt_hash(daddr, saddr, fl.iif, rt_genid(net)); |
2178 | err = rt_intern_hash(hash, rth, &skb->rtable); | 2185 | err = rt_intern_hash(hash, rth, NULL, skb); |
2179 | goto done; | 2186 | goto done; |
2180 | 2187 | ||
2181 | no_route: | 2188 | no_route: |
@@ -2244,7 +2251,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr, | |||
2244 | dst_use(&rth->u.dst, jiffies); | 2251 | dst_use(&rth->u.dst, jiffies); |
2245 | RT_CACHE_STAT_INC(in_hit); | 2252 | RT_CACHE_STAT_INC(in_hit); |
2246 | rcu_read_unlock(); | 2253 | rcu_read_unlock(); |
2247 | skb->rtable = rth; | 2254 | skb->dst = &rth->u.dst; |
2248 | return 0; | 2255 | return 0; |
2249 | } | 2256 | } |
2250 | RT_CACHE_STAT_INC(in_hlist_search); | 2257 | RT_CACHE_STAT_INC(in_hlist_search); |
@@ -2420,7 +2427,7 @@ static int ip_mkroute_output(struct rtable **rp, | |||
2420 | if (err == 0) { | 2427 | if (err == 0) { |
2421 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, | 2428 | hash = rt_hash(oldflp->fl4_dst, oldflp->fl4_src, oldflp->oif, |
2422 | rt_genid(dev_net(dev_out))); | 2429 | rt_genid(dev_net(dev_out))); |
2423 | err = rt_intern_hash(hash, rth, rp); | 2430 | err = rt_intern_hash(hash, rth, rp, NULL); |
2424 | } | 2431 | } |
2425 | 2432 | ||
2426 | return err; | 2433 | return err; |
@@ -2763,7 +2770,7 @@ static int rt_fill_info(struct net *net, | |||
2763 | struct sk_buff *skb, u32 pid, u32 seq, int event, | 2770 | struct sk_buff *skb, u32 pid, u32 seq, int event, |
2764 | int nowait, unsigned int flags) | 2771 | int nowait, unsigned int flags) |
2765 | { | 2772 | { |
2766 | struct rtable *rt = skb->rtable; | 2773 | struct rtable *rt = skb_rtable(skb); |
2767 | struct rtmsg *r; | 2774 | struct rtmsg *r; |
2768 | struct nlmsghdr *nlh; | 2775 | struct nlmsghdr *nlh; |
2769 | long expires; | 2776 | long expires; |
@@ -2907,7 +2914,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2907 | err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); | 2914 | err = ip_route_input(skb, dst, src, rtm->rtm_tos, dev); |
2908 | local_bh_enable(); | 2915 | local_bh_enable(); |
2909 | 2916 | ||
2910 | rt = skb->rtable; | 2917 | rt = skb_rtable(skb); |
2911 | if (err == 0 && rt->u.dst.error) | 2918 | if (err == 0 && rt->u.dst.error) |
2912 | err = -rt->u.dst.error; | 2919 | err = -rt->u.dst.error; |
2913 | } else { | 2920 | } else { |
@@ -2927,7 +2934,7 @@ static int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void | |||
2927 | if (err) | 2934 | if (err) |
2928 | goto errout_free; | 2935 | goto errout_free; |
2929 | 2936 | ||
2930 | skb->rtable = rt; | 2937 | skb->dst = &rt->u.dst; |
2931 | if (rtm->rtm_flags & RTM_F_NOTIFY) | 2938 | if (rtm->rtm_flags & RTM_F_NOTIFY) |
2932 | rt->rt_flags |= RTCF_NOTIFY; | 2939 | rt->rt_flags |= RTCF_NOTIFY; |
2933 | 2940 | ||