diff options
Diffstat (limited to 'net/ipv6/route.c')
-rw-r--r-- | net/ipv6/route.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4011617cca68..6ebdb7b6744c 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1273,6 +1273,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark) | |||
1273 | struct flowi6 fl6; | 1273 | struct flowi6 fl6; |
1274 | 1274 | ||
1275 | memset(&fl6, 0, sizeof(fl6)); | 1275 | memset(&fl6, 0, sizeof(fl6)); |
1276 | fl6.flowi6_iif = LOOPBACK_IFINDEX; | ||
1276 | fl6.flowi6_oif = oif; | 1277 | fl6.flowi6_oif = oif; |
1277 | fl6.flowi6_mark = mark; | 1278 | fl6.flowi6_mark = mark; |
1278 | fl6.daddr = iph->daddr; | 1279 | fl6.daddr = iph->daddr; |
@@ -1294,6 +1295,7 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif, | |||
1294 | struct flowi6 fl6; | 1295 | struct flowi6 fl6; |
1295 | 1296 | ||
1296 | memset(&fl6, 0, sizeof(fl6)); | 1297 | memset(&fl6, 0, sizeof(fl6)); |
1298 | fl6.flowi6_iif = LOOPBACK_IFINDEX; | ||
1297 | fl6.flowi6_oif = oif; | 1299 | fl6.flowi6_oif = oif; |
1298 | fl6.flowi6_mark = mark; | 1300 | fl6.flowi6_mark = mark; |
1299 | fl6.daddr = msg->dest; | 1301 | fl6.daddr = msg->dest; |
@@ -2232,6 +2234,27 @@ void rt6_remove_prefsrc(struct inet6_ifaddr *ifp) | |||
2232 | fib6_clean_all(net, fib6_remove_prefsrc, &adni); | 2234 | fib6_clean_all(net, fib6_remove_prefsrc, &adni); |
2233 | } | 2235 | } |
2234 | 2236 | ||
2237 | #define RTF_RA_ROUTER (RTF_ADDRCONF | RTF_DEFAULT | RTF_GATEWAY) | ||
2238 | #define RTF_CACHE_GATEWAY (RTF_GATEWAY | RTF_CACHE) | ||
2239 | |||
2240 | /* Remove routers and update dst entries when gateway turn into host. */ | ||
2241 | static int fib6_clean_tohost(struct rt6_info *rt, void *arg) | ||
2242 | { | ||
2243 | struct in6_addr *gateway = (struct in6_addr *)arg; | ||
2244 | |||
2245 | if ((((rt->rt6i_flags & RTF_RA_ROUTER) == RTF_RA_ROUTER) || | ||
2246 | ((rt->rt6i_flags & RTF_CACHE_GATEWAY) == RTF_CACHE_GATEWAY)) && | ||
2247 | ipv6_addr_equal(gateway, &rt->rt6i_gateway)) { | ||
2248 | return -1; | ||
2249 | } | ||
2250 | return 0; | ||
2251 | } | ||
2252 | |||
2253 | void rt6_clean_tohost(struct net *net, struct in6_addr *gateway) | ||
2254 | { | ||
2255 | fib6_clean_all(net, fib6_clean_tohost, gateway); | ||
2256 | } | ||
2257 | |||
2235 | struct arg_dev_net { | 2258 | struct arg_dev_net { |
2236 | struct net_device *dev; | 2259 | struct net_device *dev; |
2237 | struct net *net; | 2260 | struct net *net; |
@@ -2707,6 +2730,9 @@ static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh) | |||
2707 | if (tb[RTA_OIF]) | 2730 | if (tb[RTA_OIF]) |
2708 | oif = nla_get_u32(tb[RTA_OIF]); | 2731 | oif = nla_get_u32(tb[RTA_OIF]); |
2709 | 2732 | ||
2733 | if (tb[RTA_MARK]) | ||
2734 | fl6.flowi6_mark = nla_get_u32(tb[RTA_MARK]); | ||
2735 | |||
2710 | if (iif) { | 2736 | if (iif) { |
2711 | struct net_device *dev; | 2737 | struct net_device *dev; |
2712 | int flags = 0; | 2738 | int flags = 0; |