[CRIU] [PATCH 1/2] ipv6: only save scopeid when it is required
Tycho Andersen
tycho.andersen at canonical.com
Mon Nov 30 11:34:12 PST 2015
The kernel only requires that we supply a scope id to bind() when the
source address is of certain types, so lets only save/supply the scope id
in these cases.
Signed-off-by: Tycho Andersen <tycho.andersen at canonical.com>
---
sk-inet.c | 43 +++++++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 10 deletions(-)
diff --git a/sk-inet.c b/sk-inet.c
index 53e568c..4d11107 100644
--- a/sk-inet.c
+++ b/sk-inet.c
@@ -240,6 +240,26 @@ static int dump_ip_opts(int sk, IpOptsEntry *ioe)
return ret;
}
+
+/* Stolen from the kernel's __ipv6_addr_type/__ipv6_addr_needs_scopeid;
+ * link local and (multicast + loopback + linklocal) addrs require a
+ * scope id.
+ */
+#define IPV6_ADDR_SCOPE_NODELOCAL 0x01
+#define IPV6_ADDR_SCOPE_LINKLOCAL 0x02
+static bool needs_scope_id(uint32_t *src_addr)
+{
+ if ((src_addr[0] & htonl(0xFF00000)) == htonl(0xFF000000)) {
+ if (src_addr[1] & (IPV6_ADDR_SCOPE_LINKLOCAL|IPV6_ADDR_SCOPE_NODELOCAL))
+ return true;
+ }
+
+ if ((src_addr[0] & htonl(0xFFC00000)) == htonl(0xFE800000))
+ return true;
+
+ return false;
+}
+
static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int family)
{
struct inet_sk_desc *sk;
@@ -304,17 +324,20 @@ static int do_dump_one_inet_fd(int lfd, u32 id, const struct fd_parms *p, int fa
/* ifindex only matters on source ports for bind, so let's
* find only that ifindex. */
- if (getsockopt(lfd, SOL_SOCKET, SO_BINDTODEVICE, device, &len) < 0) {
- pr_perror("can't get ifname");
- goto err;
- }
-
- if (len > 0) {
- ie.ifname = xstrdup(device);
- if (!ie.ifname)
+ if (sk->src_port && needs_scope_id(sk->src_addr)) {
+ if (getsockopt(lfd, SOL_SOCKET, SO_BINDTODEVICE, device, &len) < 0) {
+ pr_perror("can't get ifname");
+ goto err;
+ }
+
+ if (len > 0) {
+ ie.ifname = xstrdup(device);
+ if (!ie.ifname)
+ goto err;
+ } else {
+ pr_err("couldn't find ifname for %d, can't bind\n", id);
goto err;
- } else {
- pr_warn("couldn't find ifname for %d, can't bind\n", id);
+ }
}
}
--
2.6.2
More information about the CRIU
mailing list