From: piaojun <piaojun@huawei.com>
To: ocfs2-devel@oss.oracle.com
Subject: [Ocfs2-devel] [PATCH 3/5] ocfs2/cluster: support IPv6 socket connection between nodes
Date: Thu, 25 Oct 2018 18:35:02 +0800 [thread overview]
Message-ID: <5BD19C56.5040201@huawei.com> (raw)
Both IPv4 and IPv6 will be supported when connecting or accepting other
nodes in cluster according to configuration by uppper user.
Signed-off-by: Jun Piao <piaojun@huawei.com>
---
fs/ocfs2/cluster/nodemanager.c | 4 +-
fs/ocfs2/cluster/nodemanager.h | 2 +-
fs/ocfs2/cluster/tcp.c | 190 ++++++++++++++++++++++++++++++-----------
3 files changed, 141 insertions(+), 55 deletions(-)
diff --git a/fs/ocfs2/cluster/nodemanager.c b/fs/ocfs2/cluster/nodemanager.c
index 292f5dd..6813517 100644
--- a/fs/ocfs2/cluster/nodemanager.c
+++ b/fs/ocfs2/cluster/nodemanager.c
@@ -115,7 +115,7 @@ static struct o2nm_node *o2nm_node_ip_tree_lookup(struct o2nm_cluster *cluster,
return ret;
}
-struct o2nm_node *o2nm_get_node_by_ip(__be32 addr)
+struct o2nm_node *o2nm_get_node_by_ip(u8 addr[])
{
struct o2nm_node *node = NULL;
struct o2nm_cluster *cluster = o2nm_single_cluster;
@@ -124,7 +124,7 @@ struct o2nm_node *o2nm_get_node_by_ip(__be32 addr)
goto out;
read_lock(&cluster->cl_nodes_lock);
- node = o2nm_node_ip_tree_lookup(cluster, (u8 *)&addr, NULL, NULL);
+ node = o2nm_node_ip_tree_lookup(cluster, addr, NULL, NULL);
if (node)
config_item_get(&node->nd_item);
read_unlock(&cluster->cl_nodes_lock);
diff --git a/fs/ocfs2/cluster/nodemanager.h b/fs/ocfs2/cluster/nodemanager.h
index 1f3cfc5..e5f8701 100644
--- a/fs/ocfs2/cluster/nodemanager.h
+++ b/fs/ocfs2/cluster/nodemanager.h
@@ -85,7 +85,7 @@ struct o2nm_cluster {
int o2nm_configured_node_map(unsigned long *map, unsigned bytes);
struct o2nm_node *o2nm_get_node_by_num(u8 node_num);
-struct o2nm_node *o2nm_get_node_by_ip(__be32 addr);
+struct o2nm_node *o2nm_get_node_by_ip(u8 addr[]);
void o2nm_node_get(struct o2nm_node *node);
void o2nm_node_put(struct o2nm_node *node);
diff --git a/fs/ocfs2/cluster/tcp.c b/fs/ocfs2/cluster/tcp.c
index 1296f78..82fa8da 100644
--- a/fs/ocfs2/cluster/tcp.c
+++ b/fs/ocfs2/cluster/tcp.c
@@ -1583,10 +1583,13 @@ static void o2net_start_connect(struct work_struct *work)
struct o2net_sock_container *sc = NULL;
struct o2nm_node *node = NULL, *mynode = NULL;
struct socket *sock = NULL;
+ struct sockaddr *mysa = NULL, *remotesa = NULL;
struct sockaddr_in myaddr = {0, }, remoteaddr = {0, };
- int ret = 0, stop;
+ struct sockaddr_in6 myaddr6 = {0, }, remoteaddr6 = {0, };
+ int ret = 0, stop, addr_len;
unsigned int timeout;
unsigned int noio_flag;
+ unsigned short sa_family;
/*
* sock_create allocates the sock with GFP_KERNEL. We must set
@@ -1633,7 +1636,33 @@ static void o2net_start_connect(struct work_struct *work)
goto out;
}
- ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+ if (mynode->nd_ipnet_type == IPV4_TYPE) {
+ myaddr.sin_family = sa_family = AF_INET;
+ myaddr.sin_addr.s_addr = mynode->nd_ipv4_address;
+ myaddr.sin_port = htons(0); /* any port */
+ mysa = (struct sockaddr *)&myaddr;
+
+ remoteaddr.sin_family = AF_INET;
+ remoteaddr.sin_addr.s_addr = node->nd_ipv4_address;
+ remoteaddr.sin_port = node->nd_ipv4_port;
+ remotesa = (struct sockaddr *)&remoteaddr;
+ addr_len = sizeof(myaddr);
+ } else {
+ myaddr6.sin6_family = sa_family = AF_INET6;
+ memcpy(&myaddr6.sin6_addr, mynode->nd_ipv6_address,
+ sizeof(mynode->nd_ipv6_address));
+ myaddr6.sin6_port = htons(0); /* any port */
+ mysa = (struct sockaddr *)&myaddr6;
+
+ remoteaddr6.sin6_family = AF_INET6;
+ memcpy(&remoteaddr6.sin6_addr, node->nd_ipv6_address,
+ sizeof(node->nd_ipv6_address));
+ remoteaddr6.sin6_port = node->nd_ipv6_port;
+ remotesa = (struct sockaddr *)&remoteaddr6;
+ addr_len = sizeof(myaddr6);
+ }
+
+ ret = sock_create(sa_family, SOCK_STREAM, IPPROTO_TCP, &sock);
if (ret < 0) {
mlog(0, "can't create socket: %d\n", ret);
goto out;
@@ -1642,15 +1671,14 @@ static void o2net_start_connect(struct work_struct *work)
sock->sk->sk_allocation = GFP_ATOMIC;
- myaddr.sin_family = AF_INET;
- myaddr.sin_addr.s_addr = mynode->nd_ipv4_address;
- myaddr.sin_port = htons(0); /* any port */
-
- ret = sock->ops->bind(sock, (struct sockaddr *)&myaddr,
- sizeof(myaddr));
+ ret = sock->ops->bind(sock, mysa, addr_len);
if (ret) {
- mlog(ML_ERROR, "bind failed with %d at address %pI4\n",
- ret, &mynode->nd_ipv4_address);
+ if (mynode->nd_ipnet_type == IPV4_TYPE)
+ mlog(ML_ERROR, "bind failed with %d at address %pI4\n",
+ ret, &mynode->nd_ipv4_address);
+ else
+ mlog(ML_ERROR, "bind failed with %d at address %pI6\n",
+ ret, mynode->nd_ipv6_address);
goto out;
}
@@ -1673,13 +1701,9 @@ static void o2net_start_connect(struct work_struct *work)
o2net_set_nn_state(nn, sc, 0, 0);
spin_unlock(&nn->nn_lock);
- remoteaddr.sin_family = AF_INET;
- remoteaddr.sin_addr.s_addr = node->nd_ipv4_address;
- remoteaddr.sin_port = node->nd_ipv4_port;
-
ret = sc->sc_sock->ops->connect(sc->sc_sock,
- (struct sockaddr *)&remoteaddr,
- sizeof(remoteaddr),
+ remotesa,
+ addr_len,
O_NONBLOCK);
if (ret == -EINPROGRESS)
ret = 0;
@@ -1819,11 +1843,13 @@ int o2net_register_hb_callbacks(void)
static int o2net_accept_one(struct socket *sock, int *more)
{
- int ret;
+ int ret, slen;
+ struct sockaddr *sa = NULL;
struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
struct socket *new_sock = NULL;
struct o2nm_node *node = NULL;
- struct o2nm_node *local_node = NULL;
+ struct o2nm_node *local_node = o2nm_get_node_by_num(o2nm_this_node());
struct o2net_sock_container *sc = NULL;
struct o2net_node *nn;
unsigned int noio_flag;
@@ -1864,22 +1890,39 @@ static int o2net_accept_one(struct socket *sock, int *more)
goto out;
}
- ret = new_sock->ops->getname(new_sock, (struct sockaddr *) &sin, 1);
+ if (local_node->nd_ipnet_type == IPV4_TYPE) {
+ sa = (struct sockaddr *)&sin;
+ slen = sizeof(sin);
+ } else {
+ sa = (struct sockaddr *)&sin6;
+ slen = sizeof(sin6);
+ }
+ ret = new_sock->ops->getname(new_sock, sa, 1);
if (ret < 0)
goto out;
- node = o2nm_get_node_by_ip(sin.sin_addr.s_addr);
- if (node == NULL) {
- printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
- "node@%pI4:%d\n", &sin.sin_addr.s_addr,
- ntohs(sin.sin_port));
- ret = -EINVAL;
- goto out;
+ if (local_node->nd_ipnet_type == IPV4_TYPE) {
+ node = o2nm_get_node_by_ip((u8 *)&sin.sin_addr.s_addr);
+ if (node == NULL) {
+ printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
+ "node at %pI4:%d\n", &sin.sin_addr.s_addr,
+ ntohs(sin.sin_port));
+ ret = -EINVAL;
+ goto out;
+ }
+ } else {
+ node = o2nm_get_node_by_ip(sin6.sin6_addr.s6_addr);
+ if (node == NULL) {
+ printk(KERN_NOTICE "o2net: Attempt to connect from unknown "
+ "node at %pI6:%d\n", sin6.sin6_addr.s6_addr,
+ ntohs(sin6.sin6_port));
+ ret = -EINVAL;
+ goto out;
+ }
}
if (o2nm_this_node() >= node->nd_num) {
- local_node = o2nm_get_node_by_num(o2nm_this_node());
- if (local_node)
+ if (local_node->nd_ipnet_type == IPV4_TYPE)
printk(KERN_NOTICE "o2net: Unexpected connect attempt "
"seen at node '%s' (%u, %pI4:%d) from "
"node '%s' (%u, %pI4:%d)\n",
@@ -1889,6 +1932,16 @@ static int o2net_accept_one(struct socket *sock, int *more)
node->nd_name,
node->nd_num, &sin.sin_addr.s_addr,
ntohs(sin.sin_port));
+ else
+ printk(KERN_NOTICE "o2net: Unexpected connect attempt "
+ "seen at node '%s' (%u, %pI6:%d) from "
+ "node '%s' (%u, %pI6:%d)\n",
+ local_node->nd_name, local_node->nd_num,
+ local_node->nd_ipv6_address,
+ ntohs(local_node->nd_ipv6_port),
+ node->nd_name,
+ node->nd_num, sin6.sin6_addr.s6_addr,
+ ntohs(sin6.sin6_port));
ret = -EINVAL;
goto out;
}
@@ -1896,10 +1949,16 @@ static int o2net_accept_one(struct socket *sock, int *more)
/* this happens all the time when the other node sees our heartbeat
* and tries to connect before we see their heartbeat */
if (!o2hb_check_node_heartbeating_from_callback(node->nd_num)) {
- mlog(ML_CONN, "attempt to connect from node '%s' at "
- "%pI4:%d but it isn't heartbeating\n",
- node->nd_name, &sin.sin_addr.s_addr,
- ntohs(sin.sin_port));
+ if (local_node->nd_ipnet_type == IPV4_TYPE)
+ mlog(ML_CONN, "attempt to connect from node '%s' at "
+ "%pI4:%d but it isn't heartbeating\n",
+ node->nd_name, &sin.sin_addr.s_addr,
+ ntohs(sin.sin_port));
+ else
+ mlog(ML_CONN, "attempt to connect from node '%s' at "
+ "%pI6:%d but it isn't heartbeating\n",
+ node->nd_name, sin6.sin6_addr.s6_addr,
+ ntohs(sin6.sin6_port));
ret = -EINVAL;
goto out;
}
@@ -1913,10 +1972,16 @@ static int o2net_accept_one(struct socket *sock, int *more)
ret = 0;
spin_unlock(&nn->nn_lock);
if (ret) {
- printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
- "at %pI4:%d but it already has an open connection\n",
- node->nd_name, &sin.sin_addr.s_addr,
- ntohs(sin.sin_port));
+ if (local_node->nd_ipnet_type == IPV4_TYPE)
+ printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
+ "at %pI4:%d but it already has an open connection\n",
+ node->nd_name, &sin.sin_addr.s_addr,
+ ntohs(sin.sin_port));
+ else
+ printk(KERN_NOTICE "o2net: Attempt to connect from node '%s' "
+ "at %pI6:%d but it already has an open connection\n",
+ node->nd_name, sin6.sin6_addr.s6_addr,
+ ntohs(sin6.sin6_port));
goto out;
}
@@ -2022,17 +2087,30 @@ static void o2net_listen_data_ready(struct sock *sk)
ready(sk);
}
-static int o2net_open_listening_sock(__be32 addr, __be16 port)
+static int o2net_open_listening_sock(struct o2nm_node *node)
{
struct socket *sock = NULL;
- int ret;
- struct sockaddr_in sin = {
- .sin_family = PF_INET,
- .sin_addr = { .s_addr = addr },
- .sin_port = port,
- };
+ int ret, addr_len;
+ struct sockaddr *sa = NULL;
+ struct sockaddr_in sin;
+ struct sockaddr_in6 sin6;
+ unsigned short sa_family;
+
+ if (node->nd_ipnet_type == IPV4_TYPE) {
+ sin.sin_family = sa_family = PF_INET;
+ sin.sin_addr.s_addr = node->nd_ipv4_address;
+ sin.sin_port = node->nd_ipv4_port;
+ sa = (struct sockaddr *)&sin;
+ addr_len = sizeof(sin);
+ } else {
+ sin6.sin6_family = sa_family = PF_INET6;
+ memcpy(&sin6.sin6_addr, node->nd_ipv6_address, sizeof(sin6.sin6_addr));
+ sin6.sin6_port = node->nd_ipv6_port;
+ sa = (struct sockaddr *)&sin6;
+ addr_len = sizeof(sin6);
+ }
- ret = sock_create(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock);
+ ret = sock_create(sa_family, SOCK_STREAM, IPPROTO_TCP, &sock);
if (ret < 0) {
printk(KERN_ERR "o2net: Error %d while creating socket\n", ret);
goto out;
@@ -2049,17 +2127,26 @@ static int o2net_open_listening_sock(__be32 addr, __be16 port)
INIT_WORK(&o2net_listen_work, o2net_accept_many);
sock->sk->sk_reuse = SK_CAN_REUSE;
- ret = sock->ops->bind(sock, (struct sockaddr *)&sin, sizeof(sin));
+ ret = sock->ops->bind(sock, sa, addr_len);
if (ret < 0) {
- printk(KERN_ERR "o2net: Error %d while binding socket@"
- "%pI4:%u\n", ret, &addr, ntohs(port));
+ if (node->nd_ipnet_type == IPV4_TYPE)
+ printk(KERN_ERR "o2net: Error %d while binding socket at "
+ "%pI4:%u\n", ret, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+ else
+ printk(KERN_ERR "o2net: Error %d while binding socket at "
+ "%pI6:%u\n", ret, sin6.sin6_addr.s6_addr, ntohs(sin6.sin6_port));
goto out;
}
ret = sock->ops->listen(sock, 64);
- if (ret < 0)
- printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n",
- ret, &addr, ntohs(port));
+ if (ret < 0) {
+ if (node->nd_ipnet_type == IPV4_TYPE)
+ printk(KERN_ERR "o2net: Error %d while listening on %pI4:%u\n",
+ ret, &sin.sin_addr.s_addr, ntohs(sin.sin_port));
+ else
+ printk(KERN_ERR "o2net: Error %d while listening on %pI6:%u\n",
+ ret, sin6.sin6_addr.s6_addr, ntohs(sin6.sin6_port));
+ }
out:
if (ret) {
@@ -2091,8 +2178,7 @@ int o2net_start_listening(struct o2nm_node *node)
return -ENOMEM; /* ? */
}
- ret = o2net_open_listening_sock(node->nd_ipv4_address,
- node->nd_ipv4_port);
+ ret = o2net_open_listening_sock(node);
if (ret) {
destroy_workqueue(o2net_wq);
o2net_wq = NULL;
--
reply other threads:[~2018-10-25 10:35 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=5BD19C56.5040201@huawei.com \
--to=piaojun@huawei.com \
--cc=ocfs2-devel@oss.oracle.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.