Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 101936
b: refs/heads/master
c: d8e7748
h: refs/heads/master
v: v3
  • Loading branch information
Chuck Lever authored and Trond Myklebust committed Jul 9, 2008
1 parent 55b2bfd commit 264e604
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 2 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ce3b7e1906ebbe96753fe090b36de6ffb8e0e0e7
refs/heads/master: d8e7748ab8322171ebfd78f6155ff35e7d57ac32
41 changes: 40 additions & 1 deletion trunk/fs/nfs/super.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
#include <linux/inet.h>
#include <linux/in6.h>
#include <net/ipv6.h>
#include <linux/netdevice.h>
#include <linux/nfs_xdr.h>
#include <linux/magic.h>
#include <linux/parser.h>
Expand Down Expand Up @@ -725,21 +726,59 @@ static void nfs_parse_ipv4_address(char *string, size_t str_len,
*addr_len = 0;
}

#define IPV6_SCOPE_DELIMITER '%'

#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
static void nfs_parse_ipv6_scope_id(const char *string, const size_t str_len,
const char *delim,
struct sockaddr_in6 *sin6)
{
char *p;
size_t len;

if (!(ipv6_addr_type(&sin6->sin6_addr) & IPV6_ADDR_LINKLOCAL))
return ;
if (*delim != IPV6_SCOPE_DELIMITER)
return;

len = (string + str_len) - delim - 1;
p = kstrndup(delim + 1, len, GFP_KERNEL);
if (p) {
unsigned long scope_id = 0;
struct net_device *dev;

dev = dev_get_by_name(&init_net, p);
if (dev != NULL) {
scope_id = dev->ifindex;
dev_put(dev);
} else {
/* scope_id is set to zero on error */
strict_strtoul(p, 10, &scope_id);
}

kfree(p);
sin6->sin6_scope_id = scope_id;
dfprintk(MOUNT, "NFS: IPv6 scope ID = %lu\n", scope_id);
}
}

static void nfs_parse_ipv6_address(char *string, size_t str_len,
struct sockaddr *sap, size_t *addr_len)
{
struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)sap;
u8 *addr = (u8 *)&sin6->sin6_addr.in6_u;
const char *delim;

if (str_len <= INET6_ADDRSTRLEN) {
dfprintk(MOUNT, "NFS: parsing IPv6 address %*s\n",
(int)str_len, string);

sin6->sin6_family = AF_INET6;
*addr_len = sizeof(*sin6);
if (in6_pton(string, str_len, addr, '\0', NULL))
if (in6_pton(string, str_len, addr, IPV6_SCOPE_DELIMITER, &delim)) {
nfs_parse_ipv6_scope_id(string, str_len, delim, sin6);
return;
}
}

sap->sa_family = AF_UNSPEC;
Expand Down

0 comments on commit 264e604

Please sign in to comment.