Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 315800
b: refs/heads/master
c: d2d68ba
h: refs/heads/master
v: v3
  • Loading branch information
David S. Miller committed Jul 20, 2012
1 parent e69d822 commit 8c74378
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 13 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: f2bb4bedf35d5167a073dcdddf16543f351ef3ae
refs/heads/master: d2d68ba9fe8b38eb03124b3176a013bb8aa2b5e5
1 change: 1 addition & 0 deletions trunk/include/net/ip_fib.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ struct fib_nh {
__be32 nh_saddr;
int nh_saddr_genid;
struct rtable *nh_rth_output;
struct rtable *nh_rth_input;
struct fnhe_hash_bucket *nh_exceptions;
};

Expand Down
2 changes: 2 additions & 0 deletions trunk/net/ipv4/fib_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,8 @@ static void free_fib_info_rcu(struct rcu_head *head)
free_nh_exceptions(nexthop_nh);
if (nexthop_nh->nh_rth_output)
dst_release(&nexthop_nh->nh_rth_output->dst);
if (nexthop_nh->nh_rth_input)
dst_release(&nexthop_nh->nh_rth_input->dst);
} endfor_nexthops(fi);

release_net(fi->fib_net);
Expand Down
55 changes: 43 additions & 12 deletions trunk/net/ipv4/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -1231,6 +1231,9 @@ static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)
{
struct rtable *orig, *prev, **p = &nh->nh_rth_output;

if (rt_is_input_route(rt))
p = &nh->nh_rth_input;

orig = *p;

prev = cmpxchg(p, orig, rt);
Expand All @@ -1241,6 +1244,11 @@ static void rt_cache_route(struct fib_nh *nh, struct rtable *rt)
}
}

static bool rt_cache_valid(struct rtable *rt)
{
return (rt && rt->dst.obsolete == DST_OBSOLETE_FORCE_CHK);
}

static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
const struct fib_result *res,
struct fib_nh_exception *fnhe,
Expand All @@ -1257,8 +1265,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) &&
rt_is_output_route(rt))
if (!(rt->dst.flags & DST_HOST))
rt_cache_route(nh, rt);
}

Expand Down Expand Up @@ -1384,11 +1391,11 @@ static int __mkroute_input(struct sk_buff *skb,
__be32 daddr, __be32 saddr, u32 tos,
struct rtable **result)
{
struct fib_nh_exception *fnhe;
struct rtable *rth;
int err;
struct in_device *out_dev;
unsigned int flags = 0;
bool do_cache;
u32 itag;

/* get a working reference to the output device */
Expand Down Expand Up @@ -1431,13 +1438,21 @@ static int __mkroute_input(struct sk_buff *skb,
}
}

fnhe = NULL;
if (res->fi)
fnhe = find_exception(&FIB_RES_NH(*res), daddr);
do_cache = false;
if (res->fi) {
if (!(flags & RTCF_DIRECTSRC) && !itag) {
rth = FIB_RES_NH(*res).nh_rth_input;
if (rt_cache_valid(rth)) {
dst_use(&rth->dst, jiffies);
goto out;
}
do_cache = true;
}
}

rth = rt_dst_alloc(out_dev->dev,
IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(out_dev, NOXFRM), false);
IN_DEV_CONF_GET(out_dev, NOXFRM), do_cache);
if (!rth) {
err = -ENOBUFS;
goto cleanup;
Expand All @@ -1456,8 +1471,8 @@ static int __mkroute_input(struct sk_buff *skb,
rth->dst.input = ip_forward;
rth->dst.output = ip_output;

rt_set_nexthop(rth, daddr, res, fnhe, res->fi, res->type, itag);

rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
out:
*result = rth;
err = 0;
cleanup:
Expand Down Expand Up @@ -1509,6 +1524,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
struct rtable *rth;
int err = -EINVAL;
struct net *net = dev_net(dev);
bool do_cache;

/* IP on this device is disabled. */

Expand All @@ -1522,6 +1538,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
if (ipv4_is_multicast(saddr) || ipv4_is_lbcast(saddr))
goto martian_source;

res.fi = NULL;
if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0))
goto brd_input;

Expand Down Expand Up @@ -1597,8 +1614,20 @@ out: return err;
RT_CACHE_STAT_INC(in_brd);

local_input:
do_cache = false;
if (res.fi) {
if (!(flags & RTCF_DIRECTSRC) && !itag) {
rth = FIB_RES_NH(res).nh_rth_input;
if (rt_cache_valid(rth)) {
dst_use(&rth->dst, jiffies);
goto set_and_out;
}
do_cache = true;
}
}

rth = rt_dst_alloc(net->loopback_dev,
IN_DEV_CONF_GET(in_dev, NOPOLICY), false, false);
IN_DEV_CONF_GET(in_dev, NOPOLICY), false, do_cache);
if (!rth)
goto e_nobufs;

Expand All @@ -1622,6 +1651,9 @@ out: return err;
rth->dst.error= -err;
rth->rt_flags &= ~RTCF_LOCAL;
}
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 @@ -1756,8 +1788,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
fnhe = find_exception(&FIB_RES_NH(*res), fl4->daddr);
if (!fnhe) {
rth = FIB_RES_NH(*res).nh_rth_output;
if (rth &&
rth->dst.obsolete == DST_OBSOLETE_FORCE_CHK) {
if (rt_cache_valid(rth)) {
dst_use(&rth->dst, jiffies);
return rth;
}
Expand Down

0 comments on commit 8c74378

Please sign in to comment.