diff options
-rw-r--r-- | include/net/ip_fib.h | 7 | ||||
-rw-r--r-- | net/ipv4/fib_frontend.c | 2 | ||||
-rw-r--r-- | net/ipv4/fib_semantics.c | 31 |
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 | |||
147 | struct fib_table { | 150 | struct 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); | |||
224 | extern int ip_fib_check_default(__be32 gw, struct net_device *dev); | 227 | extern int ip_fib_check_default(__be32 gw, struct net_device *dev); |
225 | extern int fib_sync_down_dev(struct net_device *dev, int force); | 228 | extern int fib_sync_down_dev(struct net_device *dev, int force); |
226 | extern int fib_sync_down_addr(struct net *net, __be32 local); | 229 | extern int fib_sync_down_addr(struct net *net, __be32 local); |
230 | extern void fib_update_nh_saddrs(struct net_device *dev); | ||
227 | extern int fib_sync_up(struct net_device *dev); | 231 | extern int fib_sync_up(struct net_device *dev); |
228 | extern __be32 __fib_res_prefsrc(struct fib_result *res); | ||
229 | extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res); | 232 | extern 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 | |||
856 | link_it: | 862 | link_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 | |||
908 | int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event, | 907 | int 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 | ||
1130 | void 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 | /* |