aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_fib.h7
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_semantics.c31
3 files changed, 31 insertions, 9 deletions
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 523a170b0ecb..0e140830b85a 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -60,6 +60,7 @@ struct fib_nh {
60#endif 60#endif
61 int nh_oif; 61 int nh_oif;
62 __be32 nh_gw; 62 __be32 nh_gw;
63 __be32 nh_saddr;
63}; 64};
64 65
65/* 66/*
@@ -139,11 +140,13 @@ struct fib_result_nl {
139 140
140#endif /* CONFIG_IP_ROUTE_MULTIPATH */ 141#endif /* CONFIG_IP_ROUTE_MULTIPATH */
141 142
142#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res)) 143#define FIB_RES_SADDR(res) (FIB_RES_NH(res).nh_saddr)
143#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw) 144#define FIB_RES_GW(res) (FIB_RES_NH(res).nh_gw)
144#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev) 145#define FIB_RES_DEV(res) (FIB_RES_NH(res).nh_dev)
145#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif) 146#define FIB_RES_OIF(res) (FIB_RES_NH(res).nh_oif)
146 147
148#define FIB_RES_PREFSRC(res) ((res).fi->fib_prefsrc ? : FIB_RES_SADDR(res))
149
147struct fib_table { 150struct fib_table {
148 struct hlist_node tb_hlist; 151 struct hlist_node tb_hlist;
149 u32 tb_id; 152 u32 tb_id;
@@ -224,8 +227,8 @@ extern void fib_select_default(struct fib_result *res);
224extern int ip_fib_check_default(__be32 gw, struct net_device *dev); 227extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
225extern int fib_sync_down_dev(struct net_device *dev, int force); 228extern int fib_sync_down_dev(struct net_device *dev, int force);
226extern int fib_sync_down_addr(struct net *net, __be32 local); 229extern int fib_sync_down_addr(struct net *net, __be32 local);
230extern void fib_update_nh_saddrs(struct net_device *dev);
227extern int fib_sync_up(struct net_device *dev); 231extern int fib_sync_up(struct net_device *dev);
228extern __be32 __fib_res_prefsrc(struct fib_result *res);
229extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res); 232extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
230 233
231/* Exported by fib_trie.c */ 234/* Exported by fib_trie.c */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index ad0778a3fa53..1d2233cd99e6 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -890,10 +890,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
890#ifdef CONFIG_IP_ROUTE_MULTIPATH 890#ifdef CONFIG_IP_ROUTE_MULTIPATH
891 fib_sync_up(dev); 891 fib_sync_up(dev);
892#endif 892#endif
893 fib_update_nh_saddrs(dev);
893 rt_cache_flush(dev_net(dev), -1); 894 rt_cache_flush(dev_net(dev), -1);
894 break; 895 break;
895 case NETDEV_DOWN: 896 case NETDEV_DOWN:
896 fib_del_ifaddr(ifa); 897 fib_del_ifaddr(ifa);
898 fib_update_nh_saddrs(dev);
897 if (ifa->ifa_dev->ifa_list == NULL) { 899 if (ifa->ifa_dev->ifa_list == NULL) {
898 /* Last address was deleted from this interface. 900 /* Last address was deleted from this interface.
899 * Disable IP. 901 * Disable IP.
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/*