diff options
author | David Teigland <teigland@redhat.com> | 2008-08-28 12:36:19 -0400 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2008-09-02 15:32:08 -0400 |
commit | 44be6fdf1056b685eb79e53e42bd2d321b085cfc (patch) | |
tree | 3af8658e3400b5090b78f730591da8e347cde327 /fs/dlm/config.c | |
parent | c1dcf65ffc5796bf4ff75c13f448e63b3a416fd6 (diff) |
dlm: fix address compare
Compare only the addr and port fields of sockaddr structures.
Fixes a problem with ipv6 where sin6_scope_id does not match.
Signed-off-by: David Teigland <teigland@redhat.com>
Diffstat (limited to 'fs/dlm/config.c')
-rw-r--r-- | fs/dlm/config.c | 33 |
1 files changed, 31 insertions, 2 deletions
diff --git a/fs/dlm/config.c b/fs/dlm/config.c index 89d2fb7b991a..1359be3b0bb6 100644 --- a/fs/dlm/config.c +++ b/fs/dlm/config.c | |||
@@ -14,6 +14,9 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/configfs.h> | 16 | #include <linux/configfs.h> |
17 | #include <linux/in.h> | ||
18 | #include <linux/in6.h> | ||
19 | #include <net/ipv6.h> | ||
17 | #include <net/sock.h> | 20 | #include <net/sock.h> |
18 | 21 | ||
19 | #include "config.h" | 22 | #include "config.h" |
@@ -776,6 +779,33 @@ static void put_space(struct dlm_space *sp) | |||
776 | config_item_put(&sp->group.cg_item); | 779 | config_item_put(&sp->group.cg_item); |
777 | } | 780 | } |
778 | 781 | ||
782 | static int addr_compare(struct sockaddr_storage *x, struct sockaddr_storage *y) | ||
783 | { | ||
784 | switch (x->ss_family) { | ||
785 | case AF_INET: { | ||
786 | struct sockaddr_in *sinx = (struct sockaddr_in *)x; | ||
787 | struct sockaddr_in *siny = (struct sockaddr_in *)y; | ||
788 | if (sinx->sin_addr.s_addr != siny->sin_addr.s_addr) | ||
789 | return 0; | ||
790 | if (sinx->sin_port != siny->sin_port) | ||
791 | return 0; | ||
792 | break; | ||
793 | } | ||
794 | case AF_INET6: { | ||
795 | struct sockaddr_in6 *sinx = (struct sockaddr_in6 *)x; | ||
796 | struct sockaddr_in6 *siny = (struct sockaddr_in6 *)y; | ||
797 | if (!ipv6_addr_equal(&sinx->sin6_addr, &siny->sin6_addr)) | ||
798 | return 0; | ||
799 | if (sinx->sin6_port != siny->sin6_port) | ||
800 | return 0; | ||
801 | break; | ||
802 | } | ||
803 | default: | ||
804 | return 0; | ||
805 | } | ||
806 | return 1; | ||
807 | } | ||
808 | |||
779 | static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | 809 | static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) |
780 | { | 810 | { |
781 | struct config_item *i; | 811 | struct config_item *i; |
@@ -797,8 +827,7 @@ static struct dlm_comm *get_comm(int nodeid, struct sockaddr_storage *addr) | |||
797 | config_item_get(i); | 827 | config_item_get(i); |
798 | break; | 828 | break; |
799 | } else { | 829 | } else { |
800 | if (!cm->addr_count || | 830 | if (!cm->addr_count || !addr_compare(cm->addr[0], addr)) |
801 | memcmp(cm->addr[0], addr, sizeof(*addr))) | ||
802 | continue; | 831 | continue; |
803 | found = 1; | 832 | found = 1; |
804 | config_item_get(i); | 833 | config_item_get(i); |