From b09ab448b8553742ce0bf1a7df806dcac84bca7c Mon Sep 17 00:00:00 2001 From: Denys Vlasenko Date: Tue, 27 Sep 2016 21:02:35 +0200 Subject: [PATCH] mount: for cifs, dont insert "ip=ADDR" option if user gave it explicitly This makes it possible to use scoped IPv6 addresses: mount -t cifs -o ip=% ///test test Signed-off-by: Denys Vlasenko --- util-linux/mount.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/util-linux/mount.c b/util-linux/mount.c index 305e41a3d..eb8b7ba7b 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c @@ -1931,7 +1931,6 @@ static int singlemount(struct mntent *mp, int ignore_busy) int len; char c; char *hostname, *share; - char *dotted, *ip; len_and_sockaddr *lsa; // Parse mp->mnt_fsname of the form "//hostname/share[/dir1/dir2]" @@ -1971,19 +1970,26 @@ static int singlemount(struct mntent *mp, int ignore_busy) if (!lsa) goto report_error; - // Insert "ip=..." option into options - dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); - if (ENABLE_FEATURE_CLEAN_UP) free(lsa); - ip = xasprintf("ip=%s", dotted); - if (ENABLE_FEATURE_CLEAN_UP) free(dotted); + // If there is no "ip=..." option yet + if (!is_prefixed_with(filteropts, ",ip="+1) + && !strstr(filteropts, ",ip=") + ) { + char *dotted, *ip; + // Insert "ip=..." option into options + dotted = xmalloc_sockaddr2dotted_noport(&lsa->u.sa); + if (ENABLE_FEATURE_CLEAN_UP) free(lsa); + ip = xasprintf("ip=%s", dotted); + if (ENABLE_FEATURE_CLEAN_UP) free(dotted); // Note: IPv6 scoped addresses ("host%iface", see RFC 4007) should be // handled by libc in getnameinfo() (inside xmalloc_sockaddr2dotted_noport()). // Currently, glibc does not support that (has no NI_NUMERICSCOPE), // musl apparently does. This results in "ip=numericIPv6%iface_name" // (instead of _numeric_ iface_id) with glibc. // This probably should be fixed in glibc, not here. - parse_mount_options(ip, &filteropts); - if (ENABLE_FEATURE_CLEAN_UP) free(ip); +// The workaround is to manually specify correct "ip=ADDR%n" option. + parse_mount_options(ip, &filteropts); + if (ENABLE_FEATURE_CLEAN_UP) free(ip); + } mp->mnt_type = (char*)"cifs"; rc = mount_it_now(mp, vfsflags, filteropts);