aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/fib_semantics.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-24 20:42:21 -0400
committerDavid S. Miller <davem@davemloft.net>2011-03-24 20:42:21 -0400
commit436c3b66ec9824a633724ae42de1c416af4f2063 (patch)
tree8da6452386b6e900c4226c9b67694d1ea21e847e /net/ipv4/fib_semantics.c
parentf7594d42944c0dfca90318f50978a4bdf8504086 (diff)
ipv4: Invalidate nexthop cache nh_saddr more correctly.
Any operation that: 1) Brings up an interface 2) Adds an IP address to an interface 3) Deletes an IP address from an interface can potentially invalidate the nh_saddr value, requiring it to be recomputed. Perform the recomputation lazily using a generation ID. Reported-by: Julian Anastasov <ja@ssi.bg> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/fib_semantics.c')
-rw-r--r--net/ipv4/fib_semantics.c32
1 files changed, 11 insertions, 21 deletions
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 75b9fb5d5d37..2d4bebca671a 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -695,6 +695,16 @@ static void fib_info_hash_move(struct hlist_head *new_info_hash,
695 fib_info_hash_free(old_laddrhash, bytes); 695 fib_info_hash_free(old_laddrhash, bytes);
696} 696}
697 697
698__be32 fib_info_update_nh_saddr(struct net *net, struct fib_nh *nh)
699{
700 nh->nh_saddr = inet_select_addr(nh->nh_dev,
701 nh->nh_gw,
702 nh->nh_cfg_scope);
703 nh->nh_saddr_genid = atomic_read(&net->ipv4.dev_addr_genid);
704
705 return nh->nh_saddr;
706}
707
698struct fib_info *fib_create_info(struct fib_config *cfg) 708struct fib_info *fib_create_info(struct fib_config *cfg)
699{ 709{
700 int err; 710 int err;
@@ -855,9 +865,7 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
855 865
856 change_nexthops(fi) { 866 change_nexthops(fi) {
857 nexthop_nh->nh_cfg_scope = cfg->fc_scope; 867 nexthop_nh->nh_cfg_scope = cfg->fc_scope;
858 nexthop_nh->nh_saddr = inet_select_addr(nexthop_nh->nh_dev, 868 fib_info_update_nh_saddr(net, nexthop_nh);
859 nexthop_nh->nh_gw,
860 nexthop_nh->nh_cfg_scope);
861 } endfor_nexthops(fi) 869 } endfor_nexthops(fi)
862 870
863link_it: 871link_it:
@@ -1128,24 +1136,6 @@ out:
1128 return; 1136 return;
1129} 1137}
1130 1138
1131void fib_update_nh_saddrs(struct net_device *dev)
1132{
1133 struct hlist_head *head;
1134 struct hlist_node *node;
1135 struct fib_nh *nh;
1136 unsigned int hash;
1137
1138 hash = fib_devindex_hashfn(dev->ifindex);
1139 head = &fib_info_devhash[hash];
1140 hlist_for_each_entry(nh, node, head, nh_hash) {
1141 if (nh->nh_dev != dev)
1142 continue;
1143 nh->nh_saddr = inet_select_addr(nh->nh_dev,
1144 nh->nh_gw,
1145 nh->nh_cfg_scope);
1146 }
1147}
1148
1149#ifdef CONFIG_IP_ROUTE_MULTIPATH 1139#ifdef CONFIG_IP_ROUTE_MULTIPATH
1150 1140
1151/* 1141/*