Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 318932
b: refs/heads/master
c: c6cffba
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Jul 26, 2012
1 parent 6d52aea commit 5024d8c
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 38 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4487e64de63b8e42efe5a5543871c42c5a5859d9
refs/heads/master: c6cffba4ffa26a8ffacd0bb9f3144e34f20da7de
19 changes: 17 additions & 2 deletions trunk/include/net/route.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <net/inet_sock.h>
#include <linux/in_route.h>
#include <linux/rtnetlink.h>
#include <linux/rcupdate.h>
#include <linux/route.h>
#include <linux/ip.h>
#include <linux/cache.h>
Expand Down Expand Up @@ -157,8 +158,22 @@ static inline struct rtable *ip_route_output_gre(struct net *net, struct flowi4
return ip_route_output_key(net, fl4);
}

extern int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
u8 tos, struct net_device *devin);
extern int ip_route_input_noref(struct sk_buff *skb, __be32 dst, __be32 src,
u8 tos, struct net_device *devin);

static inline int ip_route_input(struct sk_buff *skb, __be32 dst, __be32 src,
u8 tos, struct net_device *devin)
{
int err;

rcu_read_lock();
err = ip_route_input_noref(skb, dst, src, tos, devin);
if (!err)
skb_dst_force(skb);
rcu_read_unlock();

return err;
}

extern void ipv4_update_pmtu(struct sk_buff *skb, struct net *net, u32 mtu,
int oif, u32 mark, u8 protocol, int flow_flags);
Expand Down
2 changes: 1 addition & 1 deletion trunk/net/ipv4/arp.c
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ static int arp_process(struct sk_buff *skb)
}

if (arp->ar_op == htons(ARPOP_REQUEST) &&
ip_route_input(skb, tip, sip, 0, dev) == 0) {
ip_route_input_noref(skb, tip, sip, 0, dev) == 0) {

rt = skb_rtable(skb);
addr_type = rt->rt_type;
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/fib_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ static void free_fib_info_rcu(struct rcu_head *head)
if (nexthop_nh->nh_exceptions)
free_nh_exceptions(nexthop_nh);
if (nexthop_nh->nh_rth_output)
dst_release(&nexthop_nh->nh_rth_output->dst);
dst_free(&nexthop_nh->nh_rth_output->dst);
if (nexthop_nh->nh_rth_input)
dst_release(&nexthop_nh->nh_rth_input->dst);
dst_free(&nexthop_nh->nh_rth_input->dst);
} endfor_nexthops(fi);

release_net(fi->fib_net);
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/ip_fragment.c
Original file line number Diff line number Diff line change
Expand Up @@ -258,8 +258,8 @@ static void ip_expire(unsigned long arg)
/* skb dst is stale, drop it, and perform route lookup again */
skb_dst_drop(head);
iph = ip_hdr(head);
err = ip_route_input(head, iph->daddr, iph->saddr,
iph->tos, head->dev);
err = ip_route_input_noref(head, iph->daddr, iph->saddr,
iph->tos, head->dev);
if (err)
goto out_rcu_unlock;

Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/ip_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,8 +339,8 @@ static int ip_rcv_finish(struct sk_buff *skb)
* how the packet travels inside Linux networking.
*/
if (!skb_dst(skb)) {
int err = ip_route_input(skb, iph->daddr, iph->saddr,
iph->tos, skb->dev);
int err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
iph->tos, skb->dev);
if (unlikely(err)) {
if (err == -EXDEV)
NET_INC_STATS_BH(dev_net(skb->dev),
Expand Down
48 changes: 22 additions & 26 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1199,10 +1199,9 @@ static void rt_bind_exception(struct rtable *rt, struct fib_nh_exception *fnhe,
fnhe->fnhe_stamp = jiffies;
}

static inline void rt_release_rcu(struct rcu_head *head)
static inline void rt_free(struct rtable *rt)
{
struct dst_entry *dst = container_of(head, struct dst_entry, rcu_head);
dst_release(dst);
call_rcu_bh(&rt->dst.rcu_head, dst_rcu_free);
}

static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)
Expand All @@ -1216,9 +1215,15 @@ static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)

prev = cmpxchg(p, orig, rt);
if (prev == orig) {
dst_clone(&rt->dst);
if (orig)
call_rcu_bh(&orig->dst.rcu_head, rt_release_rcu);
rt_free(orig);
} else {
/* Routes we intend to cache in the FIB nexthop have
* the DST_NOCACHE bit clear. However, if we are
* unsuccessful at storing this route into the cache
* we really need to set it.
*/
rt->dst.flags |= DST_NOCACHE;
}
}

Expand All @@ -1245,7 +1250,7 @@ static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
#ifdef CONFIG_IP_ROUTE_CLASSID
rt->dst.tclassid = nh->nh_tclassid;
#endif
if (!(rt->dst.flags & DST_HOST))
if (!(rt->dst.flags & DST_NOCACHE))
rt_cache_route(nh, rt);
}

Expand All @@ -1261,7 +1266,7 @@ static struct rtable *rt_dst_alloc(struct net_device *dev,
bool nopolicy, bool noxfrm, bool will_cache)
{
return dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
(will_cache ? 0 : DST_HOST) | DST_NOCACHE |
(will_cache ? 0 : (DST_HOST | DST_NOCACHE)) |
(nopolicy ? DST_NOPOLICY : 0) |
(noxfrm ? DST_NOXFRM : 0));
}
Expand Down Expand Up @@ -1366,8 +1371,7 @@ static void ip_handle_martian_source(struct net_device *dev,
static int __mkroute_input(struct sk_buff *skb,
const struct fib_result *res,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos,
struct rtable **result)
__be32 daddr, __be32 saddr, u32 tos)
{
struct rtable *rth;
int err;
Expand Down Expand Up @@ -1418,7 +1422,7 @@ static int __mkroute_input(struct sk_buff *skb,
if (!itag) {
rth = FIB_RES_NH(*res).nh_rth_input;
if (rt_cache_valid(rth)) {
dst_hold(&rth->dst);
skb_dst_set_noref(skb, &rth->dst);
goto out;
}
do_cache = true;
Expand All @@ -1445,8 +1449,8 @@ static int __mkroute_input(struct sk_buff *skb,
rth->dst.output = ip_output;

rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
skb_dst_set(skb, &rth->dst);
out:
*result = rth;
err = 0;
cleanup:
return err;
Expand All @@ -1458,21 +1462,13 @@ static int ip_mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
struct rtable *rth = NULL;
int err;

#ifdef CONFIG_IP_ROUTE_MULTIPATH
if (res->fi && res->fi->fib_nhs > 1)
fib_select_multipath(res);
#endif

/* create a routing cache entry */
err = __mkroute_input(skb, res, in_dev, daddr, saddr, tos, &rth);
if (err)
return err;

skb_dst_set(skb, &rth->dst);
return 0;
return __mkroute_input(skb, res, in_dev, daddr, saddr, tos);
}

/*
Expand Down Expand Up @@ -1588,8 +1584,9 @@ out: return err;
if (!itag) {
rth = FIB_RES_NH(res).nh_rth_input;
if (rt_cache_valid(rth)) {
dst_hold(&rth->dst);
goto set_and_out;
skb_dst_set_noref(skb, &rth->dst);
err = 0;
goto out;
}
do_cache = true;
}
Expand Down Expand Up @@ -1620,7 +1617,6 @@ out: return err;
}
if (do_cache)
rt_cache_route(&FIB_RES_NH(res), rth);
set_and_out:
skb_dst_set(skb, &rth->dst);
err = 0;
goto out;
Expand Down Expand Up @@ -1658,8 +1654,8 @@ out: return err;
goto out;
}

int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev)
int ip_route_input_noref(struct sk_buff *skb, __be32 daddr, __be32 saddr,
u8 tos, struct net_device *dev)
{
int res;

Expand Down Expand Up @@ -1702,7 +1698,7 @@ int ip_route_input(struct sk_buff *skb, __be32 daddr, __be32 saddr,
rcu_read_unlock();
return res;
}
EXPORT_SYMBOL(ip_route_input);
EXPORT_SYMBOL(ip_route_input_noref);

/* called with rcu_read_lock() */
static struct rtable *__mkroute_output(const struct fib_result *res,
Expand Down
4 changes: 2 additions & 2 deletions trunk/net/ipv4/xfrm4_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ static inline int xfrm4_rcv_encap_finish(struct sk_buff *skb)
if (skb_dst(skb) == NULL) {
const struct iphdr *iph = ip_hdr(skb);

if (ip_route_input(skb, iph->daddr, iph->saddr,
iph->tos, skb->dev))
if (ip_route_input_noref(skb, iph->daddr, iph->saddr,
iph->tos, skb->dev))
goto drop;
}
return dst_input(skb);
Expand Down

0 comments on commit 5024d8c

Please sign in to comment.