[<prev] [next>] [day] [month] [year] [list]
Message-Id: <20120727.211819.1418384920189495051.davem@davemloft.net>
Date: Fri, 27 Jul 2012 21:18:19 -0700 (PDT)
From: David Miller <davem@...emloft.net>
To: alexander.duyck@...il.com
Cc: eric.dumazet@...il.com, netdev@...r.kernel.org
Subject: [PATCH 1/7] ipv4: Provide fib_nh instead of fib_info in fib_result.
The latter can be obtained via nh->nh_parent, and this makes
the fib_result->nh_sel member no longer necessary.
Signed-off-by: David S. Miller <davem@...emloft.net>
---
include/net/ip_fib.h | 43 +++++++++++-------------
net/ipv4/devinet.c | 2 +-
net/ipv4/fib_frontend.c | 28 +++++++++-------
net/ipv4/fib_lookup.h | 11 -------
net/ipv4/fib_semantics.c | 54 +++++++++++++++---------------
net/ipv4/fib_trie.c | 7 ++--
net/ipv4/route.c | 82 ++++++++++++++++++++++------------------------
7 files changed, 108 insertions(+), 119 deletions(-)
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index e69c3a4..eb62a2f 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -123,14 +123,14 @@ struct fib_rule;
struct fib_table;
struct fib_result {
- unsigned char prefixlen;
- unsigned char nh_sel;
- unsigned char type;
- unsigned char scope;
- u32 tclassid;
- struct fib_info *fi;
- struct fib_table *table;
- struct list_head *fa_head;
+ unsigned char prefixlen;
+ unsigned char __pad;
+ unsigned char type;
+ unsigned char scope;
+ u32 tclassid;
+ struct fib_nh *nh;
+ struct fib_table *table;
+ struct list_head *fa_head;
};
struct fib_result_nl {
@@ -150,31 +150,28 @@ struct fib_result_nl {
#ifdef CONFIG_IP_ROUTE_MULTIPATH
-#define FIB_RES_NH(res) ((res).fi->fib_nh[(res).nh_sel])
-
#define FIB_TABLE_HASHSZ 2
#else /* CONFIG_IP_ROUTE_MULTIPATH */
-#define FIB_RES_NH(res) ((res).fi->fib_nh[0])
-
#define FIB_TABLE_HASHSZ 256
#endif /* CONFIG_IP_ROUTE_MULTIPATH */
extern __be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh);
-#define FIB_RES_SADDR(net, res) \
- ((FIB_RES_NH(res).nh_saddr_genid == \
- atomic_read(&(net)->ipv4.dev_addr_genid)) ? \
- FIB_RES_NH(res).nh_saddr : \
- fib_info_update_nh_saddr((net), &FIB_RES_NH(res)))
-#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
-#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
-#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
+static inline __be32 fib_res_prefsrc(struct net *net, struct fib_result *res)
+{
+ struct fib_nh *nh = res->nh;
+ struct fib_info *fi;
-#define FIB_RES_PREFSRC(net, res) ((res).fi->fib_prefsrc ? : \
- FIB_RES_SADDR(net, res))
+ fi = nh->nh_parent;
+ if (fi->fib_prefsrc)
+ return fi->fib_prefsrc;
+ if (nh->nh_saddr_genid == atomic_read(&net->ipv4.dev_addr_genid))
+ return nh->nh_saddr;
+ return fib_info_update_nh_saddr(net, nh);
+}
struct fib_table {
struct hlist_node tb_hlist;
@@ -302,7 +299,7 @@ static inline void fib_combine_itag(u32 *itag, const struct fib_result *res)
#ifdef CONFIG_IP_MULTIPLE_TABLES
u32 rtag;
#endif
- *itag = FIB_RES_NH(*res).nh_tclassid<<16;
+ *itag = res->nh->nh_tclassid<<16;
#ifdef CONFIG_IP_MULTIPLE_TABLES
rtag = res->tclassid;
if (*itag == 0)
diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c
index 44bf82e..1baaa53 100644
--- a/net/ipv4/devinet.c
+++ b/net/ipv4/devinet.c
@@ -164,7 +164,7 @@ struct net_device *__ip_dev_find(struct net *net, __be32 addr, bool devref)
if (local &&
!fib_table_lookup(local, &fl4, &res, FIB_LOOKUP_NOREF) &&
res.type == RTN_LOCAL)
- result = FIB_RES_DEV(res);
+ result = res.nh->nh_dev;
}
if (result && devref)
dev_hold(result);
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 8732cc7..d2e8dbe 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -174,7 +174,7 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
ret = RTN_UNICAST;
rcu_read_lock();
if (!fib_table_lookup(local_table, &fl4, &res, FIB_LOOKUP_NOREF)) {
- if (!dev || dev == res.fi->fib_dev)
+ if (!dev || dev == res.nh->nh_dev)
ret = res.type;
}
rcu_read_unlock();
@@ -225,7 +225,7 @@ __be32 fib_compute_spec_dst(struct sk_buff *skb)
fl4.flowi4_scope = scope;
fl4.flowi4_mark = IN_DEV_SRC_VMARK(in_dev) ? skb->mark : 0;
if (!fib_lookup(net, &fl4, &res))
- return FIB_RES_PREFSRC(net, res);
+ return fib_res_prefsrc(net, &res);
} else {
scope = RT_SCOPE_LINK;
}
@@ -247,6 +247,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
{
int ret, no_addr, accept_local;
struct fib_result res;
+ struct fib_info *fi;
struct flowi4 fl4;
struct net *net;
bool dev_match;
@@ -273,21 +274,17 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
fib_combine_itag(itag, &res);
dev_match = false;
-#ifdef CONFIG_IP_ROUTE_MULTIPATH
- for (ret = 0; ret < res.fi->fib_nhs; ret++) {
- struct fib_nh *nh = &res.fi->fib_nh[ret];
+ fi = res.nh->nh_parent;
+ for (ret = 0; ret < fi->fib_nhs; ret++) {
+ struct fib_nh *nh = &fi->fib_nh[ret];
if (nh->nh_dev == dev) {
dev_match = true;
break;
}
}
-#else
- if (FIB_RES_DEV(res) == dev)
- dev_match = true;
-#endif
if (dev_match) {
- ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
+ ret = res.nh->nh_scope >= RT_SCOPE_HOST;
return ret;
}
if (no_addr)
@@ -299,7 +296,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
ret = 0;
if (fib_lookup(net, &fl4, &res) == 0) {
if (res.type == RTN_UNICAST)
- ret = FIB_RES_NH(res).nh_scope >= RT_SCOPE_HOST;
+ ret = res.nh->nh_scope >= RT_SCOPE_HOST;
}
return ret;
@@ -939,8 +936,15 @@ static void nl_fib_lookup(struct fib_result_nl *frn, struct fib_table *tb)
frn->err = fib_table_lookup(tb, &fl4, &res, FIB_LOOKUP_NOREF);
if (!frn->err) {
+ struct fib_nh *nh = res.nh;
+ struct fib_info *fi;
+ int nhsel;
+
+ fi = nh->nh_parent;
+ nhsel = nh - &fi->fib_nh[0];
+
frn->prefixlen = res.prefixlen;
- frn->nh_sel = res.nh_sel;
+ frn->nh_sel = nhsel;
frn->type = res.type;
frn->scope = res.scope;
}
diff --git a/net/ipv4/fib_lookup.h b/net/ipv4/fib_lookup.h
index af0f14a..5f110b6 100644
--- a/net/ipv4/fib_lookup.h
+++ b/net/ipv4/fib_lookup.h
@@ -36,17 +36,6 @@ extern void rtmsg_fib(int event, __be32 key, struct fib_alias *fa,
unsigned int nlm_flags);
extern struct fib_alias *fib_find_alias(struct list_head *fah,
u8 tos, u32 prio);
-extern int fib_detect_death(struct fib_info *fi, int order,
- struct fib_info **last_resort,
- int *last_idx, int dflt);
-
-static inline void fib_result_assign(struct fib_result *res,
- struct fib_info *fi)
-{
- /* we used to play games with refcounts, but we now use RCU */
- res->fi = fi;
-}
-
struct fib_prop {
int error;
u8 scope;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index da0cc2e..b830245 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -393,13 +393,14 @@ struct fib_alias *fib_find_alias(struct list_head *fah, u8 tos, u32 prio)
return NULL;
}
-int fib_detect_death(struct fib_info *fi, int order,
- struct fib_info **last_resort, int *last_idx, int dflt)
+int fib_detect_death(struct fib_nh *nh, int order,
+ struct fib_nh **last_resort, int *last_idx,
+ int dflt)
{
struct neighbour *n;
int state = NUD_NONE;
- n = neigh_lookup(&arp_tbl, &fi->fib_nh[0].nh_gw, fi->fib_dev);
+ n = neigh_lookup(&arp_tbl, &nh->nh_gw, nh->nh_dev);
if (n) {
state = n->nud_state;
neigh_release(n);
@@ -410,7 +411,7 @@ int fib_detect_death(struct fib_info *fi, int order,
return 0;
if ((state & NUD_VALID) ||
(*last_idx < 0 && order > dflt)) {
- *last_resort = fi;
+ *last_resort = nh;
*last_idx = order;
}
return 1;
@@ -612,8 +613,8 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
if (res.type != RTN_UNICAST && res.type != RTN_LOCAL)
goto out;
nh->nh_scope = res.scope;
- nh->nh_oif = FIB_RES_OIF(res);
- nh->nh_dev = dev = FIB_RES_DEV(res);
+ nh->nh_oif = res.nh->nh_oif;
+ nh->nh_dev = dev = res.nh->nh_dev;
if (!dev)
goto out;
dev_hold(dev);
@@ -1130,54 +1131,55 @@ int fib_sync_down_dev(struct net_device *dev, int force)
/* Must be invoked inside of an RCU protected region. */
void fib_select_default(struct fib_result *res)
{
- struct fib_info *fi = NULL, *last_resort = NULL;
+ struct fib_nh *nh = NULL, *last_resort = NULL;
struct list_head *fa_head = res->fa_head;
struct fib_table *tb = res->table;
int order = -1, last_idx = -1;
struct fib_alias *fa;
list_for_each_entry_rcu(fa, fa_head, fa_list) {
- struct fib_info *next_fi = fa->fa_info;
+ struct fib_nh *next_nh = &fa->fa_info->fib_nh[0];
- if (next_fi->fib_scope != res->scope ||
+ if (next_nh->nh_parent->fib_scope != res->scope ||
fa->fa_type != RTN_UNICAST)
continue;
- if (next_fi->fib_priority > res->fi->fib_priority)
+ if (next_nh->nh_parent->fib_priority >
+ res->nh->nh_parent->fib_priority)
break;
- if (!next_fi->fib_nh[0].nh_gw ||
- next_fi->fib_nh[0].nh_scope != RT_SCOPE_LINK)
+
+ if (!next_nh->nh_gw || next_nh->nh_scope != RT_SCOPE_LINK)
continue;
fib_alias_accessed(fa);
- if (fi == NULL) {
- if (next_fi != res->fi)
+ if (nh == NULL) {
+ if (next_nh != res->nh)
break;
- } else if (!fib_detect_death(fi, order, &last_resort,
+ } else if (!fib_detect_death(nh, order, &last_resort,
&last_idx, tb->tb_default)) {
- fib_result_assign(res, fi);
+ res->nh = nh;
tb->tb_default = order;
goto out;
}
- fi = next_fi;
+ nh = next_nh;
order++;
}
- if (order <= 0 || fi == NULL) {
+ if (order <= 0 || nh == NULL) {
tb->tb_default = -1;
goto out;
}
- if (!fib_detect_death(fi, order, &last_resort, &last_idx,
- tb->tb_default)) {
- fib_result_assign(res, fi);
+ if (!fib_detect_death(nh, order, &last_resort, &last_idx,
+ tb->tb_default)) {
+ res->nh = nh;
tb->tb_default = order;
goto out;
}
if (last_idx >= 0)
- fib_result_assign(res, last_resort);
+ res->nh = last_resort;
tb->tb_default = last_idx;
out:
return;
@@ -1249,7 +1251,7 @@ int fib_sync_up(struct net_device *dev)
*/
void fib_select_multipath(struct fib_result *res)
{
- struct fib_info *fi = res->fi;
+ struct fib_info *fi = res->nh->nh_parent;
int w;
spin_lock_bh(&fib_multipath_lock);
@@ -1265,7 +1267,7 @@ void fib_select_multipath(struct fib_result *res)
if (power <= 0) {
spin_unlock_bh(&fib_multipath_lock);
/* Race condition: route has just become dead. */
- res->nh_sel = 0;
+ res->nh = &fi->fib_nh[0];
return;
}
}
@@ -1284,7 +1286,7 @@ void fib_select_multipath(struct fib_result *res)
if (w <= 0) {
nexthop_nh->nh_power--;
fi->fib_power--;
- res->nh_sel = nhsel;
+ res->nh = &fi->fib_nh[nhsel];
spin_unlock_bh(&fib_multipath_lock);
return;
}
@@ -1292,7 +1294,7 @@ void fib_select_multipath(struct fib_result *res)
} endfor_nexthops(fi);
/* Race condition: route has just become dead. */
- res->nh_sel = 0;
+ res->nh = &fi->fib_nh[0];
spin_unlock_bh(&fib_multipath_lock);
}
#endif
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c
index 18cbc15..04b0e26 100644
--- a/net/ipv4/fib_trie.c
+++ b/net/ipv4/fib_trie.c
@@ -1384,7 +1384,7 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
if (fi->fib_flags & RTNH_F_DEAD)
continue;
for (nhsel = 0; nhsel < fi->fib_nhs; nhsel++) {
- const struct fib_nh *nh = &fi->fib_nh[nhsel];
+ struct fib_nh *nh = &fi->fib_nh[nhsel];
if (nh->nh_flags & RTNH_F_DEAD)
continue;
@@ -1395,10 +1395,9 @@ static int check_leaf(struct fib_table *tb, struct trie *t, struct leaf *l,
t->stats.semantic_match_passed++;
#endif
res->prefixlen = li->plen;
- res->nh_sel = nhsel;
res->type = fa->fa_type;
- res->scope = fa->fa_info->fib_scope;
- res->fi = fi;
+ res->scope = fi->fib_scope;
+ res->nh = nh;
res->table = tb;
res->fa_head = &li->falh;
if (!(fib_flags & FIB_LOOKUP_NOREF))
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index fc1a81c..0b3277c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -722,7 +722,7 @@ static void __ip_do_redirect(struct rtable *rt, struct sk_buff *skb, struct flow
neigh_event_send(n, NULL);
} else {
if (fib_lookup(net, fl4, &res) == 0) {
- struct fib_nh *nh = &FIB_RES_NH(res);
+ struct fib_nh *nh = res.nh;
update_or_create_fnhe(nh, fl4->daddr, new_gw,
0, 0);
@@ -926,7 +926,7 @@ static u32 __ip_rt_update_pmtu(struct rtable *rt, struct flowi4 *fl4, u32 mtu)
mtu = ip_rt_min_pmtu;
if (fib_lookup(dev_net(rt->dst.dev), fl4, &res) == 0) {
- struct fib_nh *nh = &FIB_RES_NH(res);
+ struct fib_nh *nh = res.nh;
update_or_create_fnhe(nh, fl4->daddr, 0, mtu,
jiffies + ip_rt_mtu_expires);
@@ -1085,7 +1085,7 @@ void ip_rt_get_source(u8 *addr, struct sk_buff *skb, struct rtable *rt)
rcu_read_lock();
if (fib_lookup(dev_net(rt->dst.dev), &fl4, &res) == 0)
- src = FIB_RES_PREFSRC(dev_net(rt->dst.dev), res);
+ src = fib_res_prefsrc(dev_net(rt->dst.dev), &res);
else
src = inet_select_addr(rt->dst.dev,
rt_nexthop(rt, iph->daddr),
@@ -1237,16 +1237,14 @@ static bool rt_cache_valid(const struct rtable *rt)
static void rt_set_nexthop(struct rtable *rt, __be32 daddr,
const struct fib_result *res,
struct fib_nh_exception *fnhe,
- struct fib_info *fi, u16 type, u32 itag)
+ struct fib_nh *nh, u16 type, u32 itag)
{
- if (fi) {
- struct fib_nh *nh = &FIB_RES_NH(*res);
-
+ if (nh) {
if (nh->nh_gw && nh->nh_scope == RT_SCOPE_LINK)
rt->rt_gateway = nh->nh_gw;
if (unlikely(fnhe))
rt_bind_exception(rt, fnhe, daddr);
- dst_init_metrics(&rt->dst, fi->fib_metrics, true);
+ dst_init_metrics(&rt->dst, nh->nh_parent->fib_metrics, true);
#ifdef CONFIG_IP_ROUTE_CLASSID
rt->dst.tclassid = nh->nh_tclassid;
#endif
@@ -1373,6 +1371,7 @@ static int __mkroute_input(struct sk_buff *skb,
struct in_device *in_dev,
__be32 daddr, __be32 saddr, u32 tos)
{
+ struct fib_nh *nh = res->nh;
struct rtable *rth;
int err;
struct in_device *out_dev;
@@ -1381,14 +1380,14 @@ static int __mkroute_input(struct sk_buff *skb,
u32 itag;
/* get a working reference to the output device */
- out_dev = __in_dev_get_rcu(FIB_RES_DEV(*res));
+ out_dev = __in_dev_get_rcu(nh->nh_dev);
if (out_dev == NULL) {
net_crit_ratelimited("Bug in ip_route_input_slow(). Please report.\n");
return -EINVAL;
}
- err = fib_validate_source(skb, saddr, daddr, tos, FIB_RES_OIF(*res),
+ err = fib_validate_source(skb, saddr, daddr, tos, nh->nh_oif,
in_dev->dev, in_dev, &itag);
if (err < 0) {
ip_handle_martian_source(in_dev->dev, in_dev, skb, daddr,
@@ -1399,7 +1398,7 @@ static int __mkroute_input(struct sk_buff *skb,
if (out_dev == in_dev && err &&
(IN_DEV_SHARED_MEDIA(out_dev) ||
- inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
+ inet_addr_onlink(out_dev, saddr, nh->nh_gw)))
flags |= RTCF_DOREDIRECT;
if (skb->protocol != htons(ETH_P_IP)) {
@@ -1418,15 +1417,13 @@ static int __mkroute_input(struct sk_buff *skb,
}
do_cache = false;
- if (res->fi) {
- if (!itag) {
- rth = FIB_RES_NH(*res).nh_rth_input;
- if (rt_cache_valid(rth)) {
- skb_dst_set_noref(skb, &rth->dst);
- goto out;
- }
- do_cache = true;
+ if (!itag) {
+ rth = nh->nh_rth_input;
+ if (rt_cache_valid(rth)) {
+ skb_dst_set_noref(skb, &rth->dst);
+ goto out;
}
+ do_cache = true;
}
rth = rt_dst_alloc(out_dev->dev,
@@ -1448,7 +1445,7 @@ static int __mkroute_input(struct sk_buff *skb,
rth->dst.input = ip_forward;
rth->dst.output = ip_output;
- rt_set_nexthop(rth, daddr, res, NULL, res->fi, res->type, itag);
+ rt_set_nexthop(rth, daddr, res, NULL, nh, res->type, itag);
skb_dst_set(skb, &rth->dst);
out:
err = 0;
@@ -1463,7 +1460,7 @@ static int ip_mkroute_input(struct sk_buff *skb,
__be32 daddr, __be32 saddr, u32 tos)
{
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res->fi && res->fi->fib_nhs > 1)
+ if (res->nh->nh_parent->fib_nhs > 1)
fib_select_multipath(res);
#endif
@@ -1507,7 +1504,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;
+ res.nh = NULL;
if (ipv4_is_lbcast(daddr) || (saddr == 0 && daddr == 0))
goto brd_input;
@@ -1580,9 +1577,9 @@ brd_input:
local_input:
do_cache = false;
- if (res.fi) {
+ if (res.nh) {
if (!itag) {
- rth = FIB_RES_NH(res).nh_rth_input;
+ rth = res.nh->nh_rth_input;
if (rt_cache_valid(rth)) {
skb_dst_set_noref(skb, &rth->dst);
err = 0;
@@ -1616,7 +1613,7 @@ local_input:
rth->rt_flags &= ~RTCF_LOCAL;
}
if (do_cache)
- rt_cache_route(&FIB_RES_NH(res), rth);
+ rt_cache_route(res.nh, rth);
skb_dst_set(skb, &rth->dst);
err = 0;
goto out;
@@ -1706,8 +1703,8 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
struct net_device *dev_out,
unsigned int flags)
{
- struct fib_info *fi = res->fi;
struct fib_nh_exception *fnhe;
+ struct fib_nh *nh = res->nh;
struct in_device *in_dev;
u16 type = res->type;
struct rtable *rth;
@@ -1732,7 +1729,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
if (type == RTN_BROADCAST) {
flags |= RTCF_BROADCAST | RTCF_LOCAL;
- fi = NULL;
+ nh = NULL;
} else if (type == RTN_MULTICAST) {
flags |= RTCF_MULTICAST | RTCF_LOCAL;
if (!ip_check_mc_rcu(in_dev, fl4->daddr, fl4->saddr,
@@ -1742,15 +1739,15 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
* default one, but do not gateway in this case.
* Yes, it is hack.
*/
- if (fi && res->prefixlen < 4)
- fi = NULL;
+ if (nh && res->prefixlen < 4)
+ nh = NULL;
}
fnhe = NULL;
- if (fi) {
- fnhe = find_exception(&FIB_RES_NH(*res), fl4->daddr);
+ if (nh) {
+ fnhe = find_exception(nh, fl4->daddr);
if (!fnhe) {
- rth = FIB_RES_NH(*res).nh_rth_output;
+ rth = nh->nh_rth_output;
if (rt_cache_valid(rth)) {
dst_hold(&rth->dst);
return rth;
@@ -1760,7 +1757,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
rth = rt_dst_alloc(dev_out,
IN_DEV_CONF_GET(in_dev, NOPOLICY),
IN_DEV_CONF_GET(in_dev, NOXFRM),
- fi && !fnhe);
+ nh && !fnhe);
if (!rth)
return ERR_PTR(-ENOBUFS);
@@ -1795,7 +1792,7 @@ static struct rtable *__mkroute_output(const struct fib_result *res,
#endif
}
- rt_set_nexthop(rth, fl4->daddr, res, fnhe, fi, type, 0);
+ rt_set_nexthop(rth, fl4->daddr, res, fnhe, nh, type, 0);
return rth;
}
@@ -1814,7 +1811,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
int orig_oif;
res.tclassid = 0;
- res.fi = NULL;
+ res.nh = NULL;
res.table = NULL;
orig_oif = fl4->flowi4_oif;
@@ -1915,7 +1912,7 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
}
if (fib_lookup(net, fl4, &res)) {
- res.fi = NULL;
+ res.nh = NULL;
res.table = NULL;
if (fl4->flowi4_oif) {
/* Apparently, routing tables are wrong. Assume,
@@ -1948,20 +1945,21 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
if (res.type == RTN_LOCAL) {
if (!fl4->saddr) {
- if (res.fi->fib_prefsrc)
- fl4->saddr = res.fi->fib_prefsrc;
+ struct fib_info *fi = res.nh->nh_parent;
+ if (fi->fib_prefsrc)
+ fl4->saddr = fi->fib_prefsrc;
else
fl4->saddr = fl4->daddr;
}
dev_out = net->loopback_dev;
fl4->flowi4_oif = dev_out->ifindex;
- res.fi = NULL;
+ res.nh = NULL;
flags |= RTCF_LOCAL;
goto make_route;
}
#ifdef CONFIG_IP_ROUTE_MULTIPATH
- if (res.fi->fib_nhs > 1 && fl4->flowi4_oif == 0)
+ if (res.nh->nh_parent->fib_nhs > 1 && fl4->flowi4_oif == 0)
fib_select_multipath(&res);
else
#endif
@@ -1971,9 +1969,9 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4)
fib_select_default(&res);
if (!fl4->saddr)
- fl4->saddr = FIB_RES_PREFSRC(net, res);
+ fl4->saddr = fib_res_prefsrc(net, &res);
- dev_out = FIB_RES_DEV(res);
+ dev_out = res.nh->nh_dev;
fl4->flowi4_oif = dev_out->ifindex;
--
1.7.10.4
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists