* [Ocfs2-devel] [PATCH 3/5] ocfs2/cluster: support IPv6 socket connection between nodes
@ 2018-10-25 10:35 piaojun
0 siblings, 0 replies; only message in thread
From: piaojun @ 2018-10-25 10:35 UTC (permalink / raw)
To: ocfs2-devel
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;
--
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2018-10-25 10:35 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2018-10-25 10:35 [Ocfs2-devel] [PATCH 3/5] ocfs2/cluster: support IPv6 socket connection between nodes piaojun
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.