diff options
Diffstat (limited to 'net/rds/tcp.c')
-rw-r--r-- | net/rds/tcp.c | 32 |
1 files changed, 29 insertions, 3 deletions
diff --git a/net/rds/tcp.c b/net/rds/tcp.c index 351a28474667..dadb33790333 100644 --- a/net/rds/tcp.c +++ b/net/rds/tcp.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (c) 2006 Oracle. All rights reserved. | 2 | * Copyright (c) 2006, 2017 Oracle and/or its affiliates. All rights reserved. |
3 | * | 3 | * |
4 | * This software is available to you under a choice of one of two | 4 | * This software is available to you under a choice of one of two |
5 | * licenses. You may choose to be licensed under the terms of the GNU | 5 | * licenses. You may choose to be licensed under the terms of the GNU |
@@ -37,6 +37,8 @@ | |||
37 | #include <net/tcp.h> | 37 | #include <net/tcp.h> |
38 | #include <net/net_namespace.h> | 38 | #include <net/net_namespace.h> |
39 | #include <net/netns/generic.h> | 39 | #include <net/netns/generic.h> |
40 | #include <net/tcp.h> | ||
41 | #include <net/addrconf.h> | ||
40 | 42 | ||
41 | #include "rds.h" | 43 | #include "rds.h" |
42 | #include "tcp.h" | 44 | #include "tcp.h" |
@@ -262,9 +264,33 @@ out: | |||
262 | spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags); | 264 | spin_unlock_irqrestore(&rds_tcp_tc_list_lock, flags); |
263 | } | 265 | } |
264 | 266 | ||
265 | static int rds_tcp_laddr_check(struct net *net, __be32 addr) | 267 | static int rds_tcp_laddr_check(struct net *net, const struct in6_addr *addr, |
268 | __u32 scope_id) | ||
266 | { | 269 | { |
267 | if (inet_addr_type(net, addr) == RTN_LOCAL) | 270 | struct net_device *dev = NULL; |
271 | int ret; | ||
272 | |||
273 | if (ipv6_addr_v4mapped(addr)) { | ||
274 | if (inet_addr_type(net, addr->s6_addr32[3]) == RTN_LOCAL) | ||
275 | return 0; | ||
276 | return -EADDRNOTAVAIL; | ||
277 | } | ||
278 | |||
279 | /* If the scope_id is specified, check only those addresses | ||
280 | * hosted on the specified interface. | ||
281 | */ | ||
282 | if (scope_id != 0) { | ||
283 | rcu_read_lock(); | ||
284 | dev = dev_get_by_index_rcu(net, scope_id); | ||
285 | /* scope_id is not valid... */ | ||
286 | if (!dev) { | ||
287 | rcu_read_unlock(); | ||
288 | return -EADDRNOTAVAIL; | ||
289 | } | ||
290 | rcu_read_unlock(); | ||
291 | } | ||
292 | ret = ipv6_chk_addr(net, addr, dev, 0); | ||
293 | if (ret) | ||
268 | return 0; | 294 | return 0; |
269 | return -EADDRNOTAVAIL; | 295 | return -EADDRNOTAVAIL; |
270 | } | 296 | } |