]>
Commit | Line | Data |
---|---|---|
2cb7cef9 BS |
1 | From: David Teigland <teigland@redhat.com> |
2 | commit 44be6fdf1056b685eb79e53e42bd2d321b085cfc | |
3 | Author: David Teigland <teigland@redhat.com> | |
4 | Date: Thu Aug 28 11:36:19 2008 -0500 | |
5 | Subject: dlm: fix address compare | |
6 | ||
7 | Compare only the addr and port fields of sockaddr structures. | |
8 | Fixes a problem with ipv6 where sin6_scope_id does not match. | |
9 | ||
10 | Signed-off-by: David Teigland <teigland@redhat.com> | |
11 | Signed-off-by: Coly Li <coly.li@suse.de> | |
12 | ||
13 | diff --git a/fs/dlm/config.c b/fs/dlm/config.c | |
14 | index 89d2fb7..1359be3 100644 | |
15 | --- a/fs/dlm/config.c | |
16 | +++ b/fs/dlm/config.c | |
17 | @@ -14,6 +14,9 @@ | |
18 | #include <linux/kernel.h> | |
19 | #include <linux/module.h> | |
20 | #include <linux/configfs.h> | |
21 | +#include <linux/in.h> | |
22 | +#include <linux/in6.h> | |
23 | +#include <net/ipv6.h> | |
24 | #include <net/sock.h> | |
25 | ||
26 | #include "config.h" | |
27 | @@ -776,6 +779,33 @@ static void put_space(struct dlm_space *sp) | |
28 | config_item_put(&sp->group.cg_item); | |
29 | } | |
30 | ||
31 | +static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y) | |
32 | +{ | |
33 | + switch (x->ss_family) { | |
34 | + case AF_INET: { | |
35 | + struct sockaddr_in *sinx = (struct sockaddr_in *)x; | |
36 | + struct sockaddr_in *siny = (struct sockaddr_in *)y; | |
37 | + if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr) | |
38 | + return 0; | |
39 | + if (sinx->sin_port != siny->sin_port) | |
40 | + return 0; | |
41 | + break; | |
42 | + } | |
43 | + case AF_INET6: { | |
44 | + struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x; | |
45 | + struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y; | |
46 | + if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr)) | |
47 | + return 0; | |
48 | + if (sinx->sin6_port != siny->sin6_port) | |
49 | + return 0; | |
50 | + break; | |
51 | + } | |
52 | + default: | |
53 | + return 0; | |
54 | + } | |
55 | + return 1; | |
56 | +} | |
57 | + | |
58 | static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | |
59 | { | |
60 | struct config_item *i; | |
61 | @@ -797,8 +827,7 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | |
62 | config_item_get(i); | |
63 | break; | |
64 | } else { | |
65 | - if (!cm->addr_count || | |
66 | - memcmp(cm->addr[0], addr, sizeof(*addr))) | |
67 | + if (!cm->addr_count || !addr_compare(cm->addr[0], addr)) | |
68 | continue; | |
69 | found = 1; | |
70 | config_item_get(i); |