aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-07 23:54:48 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-07 23:54:48 -0500
commit1fc050a13473348f5c439de2bb41c8e92dba5588 (patch)
treeb2cecf15f5de87997fb44b4a1025b48d473cd038 /net/ipv4/fib_semantics.c
parent6118e35a7126c1062b1a0f6737b84b4fe4d5c8d4 (diff)
ipv4: Cache source address in nexthop entries.
When doing output route lookups, we have to select the source address if the user has not specified an explicit one. First, if the route has an explicit preferred source address specified, then we use that. Otherwise we search the route's outgoing interface for a suitable address. This search can be precomputed and cached at route insertion time. The only missing part is that we have to refresh this precomputed value any time addresses are added or removed from the interface, and this is accomplished by fib_update_nh_saddrs(). Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 6349a21692ec..952c737f2a27 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -853,6 +853,12 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
853 goto err_inval; 853 goto err_inval;
854 } 854 }
855 855
856 change_nexthops(fi) {
857 nexthop_nh->nh_saddr = inet_select_addr(nexthop_nh->nh_dev,
858 nexthop_nh->nh_gw,
859 nexthop_nh->nh_scope);
860 } endfor_nexthops(fi)
861
856link_it: 862link_it:
857 ofi = fib_find_info(fi); 863 ofi = fib_find_info(fi);
858 if (ofi) { 864 if (ofi) {
@@ -898,13 +904,6 @@ failure:
898 return ERR_PTR(err); 904 return ERR_PTR(err);
899} 905}
900 906
901/* Find appropriate source address to this destination */
902
903__be32 __fib_res_prefsrc(struct fib_result *res)
904{
905 return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
906}
907
908int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, 907int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
909 u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos, 908 u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos,
910 struct fib_info *fi, unsigned int flags) 909 struct fib_info *fi, unsigned int flags)
@@ -1128,6 +1127,24 @@ out:
1128 return; 1127 return;
1129} 1128}
1130 1129
1130void fib_update_nh_saddrs(struct net_device *dev)
1131{
1132 struct hlist_head *head;
1133 struct hlist_node *node;
1134 struct fib_nh *nh;
1135 unsigned int hash;
1136
1137 hash = fib_devindex_hashfn(dev->ifindex);
1138 head = &fib_info_devhash[hash];
1139 hlist_for_each_entry(nh, node, head, nh_hash) {
1140 if (nh->nh_dev != dev)
1141 continue;
1142 nh->nh_saddr = inet_select_addr(nh->nh_dev,
1143 nh->nh_gw,
1144 nh->nh_scope);
1145 }
1146}
1147
1131#ifdef CONFIG_IP_ROUTE_MULTIPATH 1148#ifdef CONFIG_IP_ROUTE_MULTIPATH
1132 1149
1133/* 1150/*