[tipc-discussion] [net-next 2/2] tipc: reduce sensitive to retransmit failures
With huge cluster (e.g >200nodes), the amount of that flow: gap -> retransmit packet -> acked will take time in case of STATE_MSG dropped/delayed because a lot of traffic. This lead to 1.5 sec tolerance value criteria made link easy failure around 2nd, 3rd of failed retransmission attempts. Instead of re-introduced criteria of 99 faled retransmissions to fix the issue, we increase failure detection timer to ten times tolerance value. Fixes: 77cf8edbc0e7 ("tipc: simplify stale link failure criteria") Acked-by: Jon Maloy Signed-off-by: Hoang Le --- net/tipc/link.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/net/tipc/link.c b/net/tipc/link.c index 038861bad72b..2aed7a958a8c 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -1087,7 +1087,7 @@ static bool link_retransmit_failure(struct tipc_link *l, struct tipc_link *r, return false; if (!time_after(jiffies, TIPC_SKB_CB(skb)->retr_stamp + - msecs_to_jiffies(r->tolerance))) + msecs_to_jiffies(r->tolerance * 10))) return false; hdr = buf_msg(skb); -- 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [net-next 1/2] tipc: update cluster capabilities if node deleted
There are two improvements when re-calculate cluster capabilities: - When deleting a specific down node, need to re-calculate. - In tipc_node_cleanup(), do not need to re-calculate if node is still existing in cluster. Acked-by: Jon Maloy Signed-off-by: Hoang Le --- net/tipc/node.c | 12 +++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/net/tipc/node.c b/net/tipc/node.c index 742c04756d72..a20fabd09e7e 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -665,6 +665,11 @@ static bool tipc_node_cleanup(struct tipc_node *peer) } tipc_node_write_unlock(peer); + if (!deleted) { + spin_unlock_bh(>node_list_lock); + return deleted; + } + /* Calculate cluster capabilities */ tn->capabilities = TIPC_NODE_CAPABILITIES; list_for_each_entry_rcu(temp_node, >node_list, list) { @@ -2041,7 +2046,7 @@ int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info) struct net *net = sock_net(skb->sk); struct tipc_net *tn = net_generic(net, tipc_net_id); struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; - struct tipc_node *peer; + struct tipc_node *peer, *temp_node; u32 addr; int err; @@ -2082,6 +2087,11 @@ int tipc_nl_peer_rm(struct sk_buff *skb, struct genl_info *info) tipc_node_write_unlock(peer); tipc_node_delete(peer); + /* Calculate cluster capabilities */ + tn->capabilities = TIPC_NODE_CAPABILITIES; + list_for_each_entry_rcu(temp_node, >node_list, list) { + tn->capabilities &= temp_node->capabilities; + } err = 0; err_out: tipc_node_put(peer); -- 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [net-next] tipc: eliminate checking netns if node acknowledge
At current we do check netns local for every neighbor discovery that is being sent from external netns node. This is become unnecessary for node acknowledge. We now improve above checking for peer node come back and discovery message sent from unacknowledge node. Fixes: f73b12812a3d ("tipc: improve throughput between nodes in netns") Signed-off-by: Hoang Le --- net/tipc/node.c | 16 +++- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/net/tipc/node.c b/net/tipc/node.c index 4b60928049ea..742c04756d72 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -472,10 +472,8 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, tipc_bc_sndlink(net), >bc_entry.link)) { pr_warn("Broadcast rcv link creation failed, no memory\n"); - if (n->peer_net) { - n->peer_net = NULL; - n->peer_hash_mix = 0; - } + n->peer_net = NULL; + n->peer_hash_mix = 0; kfree(n); n = NULL; goto exit; @@ -1068,6 +1066,9 @@ void tipc_node_check_dest(struct net *net, u32 addr, if (sign_match && addr_match && link_up) { /* All is fine. Do nothing. */ reset = false; + /* Peer node is not a container/netns local */ + if (!n->peer_hash_mix) + n->peer_hash_mix = hash_mixes; } else if (sign_match && addr_match && !link_up) { /* Respond. The link will come up in due time */ *respond = true; @@ -1393,11 +1394,8 @@ static void node_lost_contact(struct tipc_node *n, /* Notify publications from this node */ n->action_flags |= TIPC_NOTIFY_NODE_DOWN; - - if (n->peer_net) { - n->peer_net = NULL; - n->peer_hash_mix = 0; - } + n->peer_net = NULL; + n->peer_hash_mix = 0; /* Notify sockets connected to node */ list_for_each_entry_safe(conn, safe, conns, list) { skb = tipc_msg_create(TIPC_CRITICAL_IMPORTANCE, TIPC_CONN_MSG, -- 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] binding table update via broadcast/multicast
Hi, I searched through the tipc-discussion archives, and found a patch from Ying that explains the problem, and try to remedy it. https://sourceforge.net/p/tipc/mailman/message/29490037/. However, we never moved binding table updates to be sent over broadcast in upstream TIPC, simply because it is working well now, and we saw no reason to add any extra risks. If we are scaling up clusters to > 200 nodes this may become very different, so maybe it is worth trying. I think the chances for doing this successfully are much better now. ///jon ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
Re: [tipc-discussion] [net-next] tipc: reduce sensitive to retransmit failures
Acked. But you *must* use the monitor functionality for any cluster > 100. Otherwise this is never going to work. BR ///jon > -Original Message- > From: Hoang Le > Sent: 30-Oct-19 02:26 > To: Jon Maloy ; ma...@donjonn.com; > tipc-discussion@lists.sourceforge.net; > ying@windriver.com > Subject: [net-next] tipc: reduce sensitive to retransmit failures > > With huge cluster (e.g >200nodes), the amount of that flow: > gap -> retransmit packet -> acked will take time in case of STATE_MSG > dropped/delayed because a lot of traffic. This lead to 1.5 sec tolerance > value criteria made link easy failure around 2nd, 3rd of failed > retransmission attempts. > > Instead of re-introduced criteria of 99 failed retransmissions to fix the > issue, we increase failure detection timer to ten times tolerance value. > > Fixes: 77cf8edbc0e7 ("tipc: simplify stale link failure criteria") > Signed-off-by: Hoang Le > --- > net/tipc/link.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/tipc/link.c b/net/tipc/link.c > index 7d7a66178607..9f524c325c0d 100644 > --- a/net/tipc/link.c > +++ b/net/tipc/link.c > @@ -1084,7 +1084,7 @@ static bool link_retransmit_failure(struct tipc_link > *l, struct tipc_link *r, > return false; > > if (!time_after(jiffies, TIPC_SKB_CB(skb)->retr_stamp + > - msecs_to_jiffies(r->tolerance))) > + msecs_to_jiffies(r->tolerance * 10))) > return false; > > hdr = buf_msg(skb); > -- > 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
Re: [tipc-discussion] [net-next] tipc: update cluster capabilities if node deleted
Acked, ///jon > -Original Message- > From: Hoang Le > Sent: 30-Oct-19 05:38 > To: Jon Maloy ; ma...@donjonn.com; > tipc-discussion@lists.sourceforge.net; > ying@windriver.com > Subject: [net-next] tipc: update cluster capabilities if node deleted > > There are two improvements when re-calculate cluster capabilities: > > - When deleting a specific down node, need to re-calculate. > - In tipc_node_cleanup(), do not need to re-calculate if node > is still existing in cluster. > > Signed-off-by: Hoang Le > --- > net/tipc/node.c | 12 +++- > 1 file changed, 11 insertions(+), 1 deletion(-) > > diff --git a/net/tipc/node.c b/net/tipc/node.c > index 4b60928049ea..1f1584518221 100644 > --- a/net/tipc/node.c > +++ b/net/tipc/node.c > @@ -667,6 +667,11 @@ static bool tipc_node_cleanup(struct tipc_node *peer) > } > tipc_node_write_unlock(peer); > > + if (!deleted) { > + spin_unlock_bh(>node_list_lock); > + return deleted; > + } > + > /* Calculate cluster capabilities */ > tn->capabilities = TIPC_NODE_CAPABILITIES; > list_for_each_entry_rcu(temp_node, >node_list, list) { > @@ -2043,7 +2048,7 @@ int tipc_nl_peer_rm(struct sk_buff *skb, struct > genl_info *info) > struct net *net = sock_net(skb->sk); > struct tipc_net *tn = net_generic(net, tipc_net_id); > struct nlattr *attrs[TIPC_NLA_NET_MAX + 1]; > - struct tipc_node *peer; > + struct tipc_node *peer, *temp_node; > u32 addr; > int err; > > @@ -2084,6 +2089,11 @@ int tipc_nl_peer_rm(struct sk_buff *skb, struct > genl_info *info) > tipc_node_write_unlock(peer); > tipc_node_delete(peer); > > + /* Calculate cluster capabilities */ > + tn->capabilities = TIPC_NODE_CAPABILITIES; > + list_for_each_entry_rcu(temp_node, >node_list, list) { > + tn->capabilities &= temp_node->capabilities; > + } > err = 0; > err_out: > tipc_node_put(peer); > -- > 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [PATCH v2 3/5] tipc: add new AEAD key structure for user API
The new structure 'tipc_aead_key' is added to the 'tipc.h' for user to be able to transfer a key to TIPC in kernel. Netlink will be used for this purpose in the later commits. Signed-off-by: Tuong Lien --- include/uapi/linux/tipc.h | 21 + 1 file changed, 21 insertions(+) diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h index 76421b878767..add01db1daef 100644 --- a/include/uapi/linux/tipc.h +++ b/include/uapi/linux/tipc.h @@ -233,6 +233,27 @@ struct tipc_sioc_nodeid_req { char node_id[TIPC_NODEID_LEN]; }; +/* + * TIPC Crypto, AEAD + */ +#define TIPC_AEAD_ALG_NAME (32) + +struct tipc_aead_key { + char alg_name[TIPC_AEAD_ALG_NAME]; + unsigned int keylen;/* in bytes */ + char key[]; +}; + +#define TIPC_AEAD_KEYLEN_MIN (16 + 4) +#define TIPC_AEAD_KEYLEN_MAX (32 + 4) +#define TIPC_AEAD_KEY_SIZE_MAX (sizeof(struct tipc_aead_key) + \ + TIPC_AEAD_KEYLEN_MAX) + +static inline int tipc_aead_key_size(struct tipc_aead_key *key) +{ + return sizeof(*key) + key->keylen; +} + /* The macros and functions below are deprecated: */ -- 2.13.7 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [PATCH v2 1/5] tipc: add reference counter to bearer
As a need to support the crypto asynchronous operations in the later commits, apart from the current RCU mechanism for bearer pointer, we add a 'refcnt' to the bearer object as well. So, a bearer can be hold via 'tipc_bearer_hold()' without being freed even though the bearer or interface can be disabled in the meanwhile. If that happens, the bearer will be released then when the crypto operation is completed and 'tipc_bearer_put()' is called. Signed-off-by: Tuong Lien --- net/tipc/bearer.c | 14 +- net/tipc/bearer.h | 3 +++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 0214aa1c4427..6e15b9b1f1ef 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -315,6 +315,7 @@ static int tipc_enable_bearer(struct net *net, const char *name, b->net_plane = bearer_id + 'A'; b->priority = prio; test_and_set_bit_lock(0, >up); + refcount_set(>refcnt, 1); res = tipc_disc_create(net, b, >bcast_addr, ); if (res) { @@ -351,6 +352,17 @@ static int tipc_reset_bearer(struct net *net, struct tipc_bearer *b) return 0; } +bool tipc_bearer_hold(struct tipc_bearer *b) +{ + return (b && refcount_inc_not_zero(>refcnt)); +} + +void tipc_bearer_put(struct tipc_bearer *b) +{ + if (b && refcount_dec_and_test(>refcnt)) + kfree_rcu(b, rcu); +} + /** * bearer_disable * @@ -369,7 +381,7 @@ static void bearer_disable(struct net *net, struct tipc_bearer *b) if (b->disc) tipc_disc_delete(b->disc); RCU_INIT_POINTER(tn->bearer_list[bearer_id], NULL); - kfree_rcu(b, rcu); + tipc_bearer_put(b); tipc_mon_delete(net, bearer_id); } diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index ea0f3c49cbed..faca696d422f 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -165,6 +165,7 @@ struct tipc_bearer { struct tipc_discoverer *disc; char net_plane; unsigned long up; + refcount_t refcnt; }; struct tipc_bearer_names { @@ -210,6 +211,8 @@ int tipc_media_set_window(const char *name, u32 new_value); int tipc_media_addr_printf(char *buf, int len, struct tipc_media_addr *a); int tipc_enable_l2_media(struct net *net, struct tipc_bearer *b, struct nlattr *attrs[]); +bool tipc_bearer_hold(struct tipc_bearer *b); +void tipc_bearer_put(struct tipc_bearer *b); void tipc_disable_l2_media(struct tipc_bearer *b); int tipc_l2_send_msg(struct net *net, struct sk_buff *buf, struct tipc_bearer *b, struct tipc_media_addr *dest); -- 2.13.7 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [PATCH v2 5/5] tipc: add support for AEAD key setting via netlink
This commit adds two netlink commands to TIPC in order for user to be able to set or remove AEAD keys: - TIPC_NL_KEY_SET - TIPC_NL_KEY_FLUSH When the 'KEY_SET' is given along with the key data, the key will be initiated and attached to TIPC crypto. On the other hand, the 'KEY_FLUSH' command will remove all existing keys if any. v2: rebase, add new kernel option ("TIPC_CRYPTO") Signed-off-by: Tuong Lien --- include/uapi/linux/tipc_netlink.h | 8 +++ net/tipc/netlink.c| 20 +- net/tipc/node.c | 135 ++ net/tipc/node.h | 4 ++ 4 files changed, 166 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index efb958fd167d..d712e5d7b3e1 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -63,6 +63,10 @@ enum { TIPC_NL_PEER_REMOVE, TIPC_NL_BEARER_ADD, TIPC_NL_UDP_GET_REMOTEIP, +#ifdef CONFIG_TIPC_CRYPTO + TIPC_NL_KEY_SET, + TIPC_NL_KEY_FLUSH, +#endif __TIPC_NL_CMD_MAX, TIPC_NL_CMD_MAX = __TIPC_NL_CMD_MAX - 1 @@ -160,6 +164,10 @@ enum { TIPC_NLA_NODE_UNSPEC, TIPC_NLA_NODE_ADDR, /* u32 */ TIPC_NLA_NODE_UP, /* flag */ +#ifdef CONFIG_TIPC_CRYPTO + TIPC_NLA_NODE_ID, /* data */ + TIPC_NLA_NODE_KEY, /* data */ +#endif __TIPC_NLA_NODE_MAX, TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1 diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index d32bbd0f5e46..b63461c6db02 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c @@ -102,7 +102,13 @@ const struct nla_policy tipc_nl_link_policy[TIPC_NLA_LINK_MAX + 1] = { const struct nla_policy tipc_nl_node_policy[TIPC_NLA_NODE_MAX + 1] = { [TIPC_NLA_NODE_UNSPEC] = { .type = NLA_UNSPEC }, [TIPC_NLA_NODE_ADDR]= { .type = NLA_U32 }, - [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG } + [TIPC_NLA_NODE_UP] = { .type = NLA_FLAG }, +#ifdef CONFIG_TIPC_CRYPTO + [TIPC_NLA_NODE_ID] = { .type = NLA_BINARY, + .len = TIPC_NODEID_LEN}, + [TIPC_NLA_NODE_KEY] = { .type = NLA_BINARY, + .len = TIPC_AEAD_KEY_SIZE_MAX}, +#endif }; /* Properties valid for media, bearer and link */ @@ -257,6 +263,18 @@ static const struct genl_ops tipc_genl_v2_ops[] = { .dumpit = tipc_udp_nl_dump_remoteip, }, #endif +#ifdef CONFIG_TIPC_CRYPTO + { + .cmd= TIPC_NL_KEY_SET, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = tipc_nl_node_set_key, + }, + { + .cmd= TIPC_NL_KEY_FLUSH, + .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, + .doit = tipc_nl_node_flush_key, + }, +#endif }; struct genl_family tipc_genl_family __ro_after_init = { diff --git a/net/tipc/node.c b/net/tipc/node.c index 61d4656c7ccd..710315e778f8 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -2784,6 +2784,141 @@ int tipc_nl_node_dump_monitor_peer(struct sk_buff *skb, return skb->len; } +#ifdef CONFIG_TIPC_CRYPTO +static int tipc_nl_retrieve_key(struct nlattr **attrs, + struct tipc_aead_key **key) +{ + struct nlattr *attr = attrs[TIPC_NLA_NODE_KEY]; + + if (!attr) + return -ENODATA; + + *key = (struct tipc_aead_key *)nla_data(attr); + if (nla_len(attr) < tipc_aead_key_size(*key)) + return -EINVAL; + + return 0; +} + +static int tipc_nl_retrieve_nodeid(struct nlattr **attrs, u8 **node_id) +{ + struct nlattr *attr = attrs[TIPC_NLA_NODE_ID]; + + if (!attr) + return -ENODATA; + + if (nla_len(attr) < TIPC_NODEID_LEN) + return -EINVAL; + + *node_id = (u8 *)nla_data(attr); + return 0; +} + +int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info) +{ + struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1]; + struct net *net = sock_net(skb->sk); + struct tipc_net *tn = tipc_net(net); + struct tipc_node *n = NULL; + struct tipc_aead_key *ukey; + struct tipc_crypto *c; + u8 *id, *own_id; + int rc = 0; + + if (!info->attrs[TIPC_NLA_NODE]) + return -EINVAL; + + rc = nla_parse_nested(attrs, TIPC_NLA_NODE_MAX, + info->attrs[TIPC_NLA_NODE], + tipc_nl_node_policy, info->extack); + if (rc) + goto exit; + + own_id = tipc_own_id(net); + if (!own_id) { + rc = -EPERM; + goto exit; + } + + rc = tipc_nl_retrieve_key(attrs, ); + if (rc) + goto exit; + + rc
[tipc-discussion] [PATCH v2 4/5] tipc: introduce TIPC encryption & authentication
This commit offers an option to encrypt and authenticate all messaging, including the neighbor discovery messages. The currently most advanced algorithm supported is the AEAD AES-GCM (like IPSec or TLS). All encryption/decryption is done at the bearer layer, just before leaving or after entering TIPC. Supported features: - Encryption & authentication of all TIPC messages (header + data); - Two symmetric-key modes: Cluster and Per-node; - Automatic key switching; - Key-expired revoking (sequence number wrapped); - Lock-free encryption/decryption (RCU); - Asynchronous crypto, Intel AES-NI supported; - Multiple cipher transforms; - Logs & statistics; Two key modes: - Cluster key mode: One single key is used for both TX & RX in all nodes in the cluster. - Per-node key mode: Each nodes in the cluster has one specific TX key. For RX, a node requires its peers' TX key to be able to decrypt the messages from those peers. Key setting from user-space is performed via netlink by a user program (e.g. the iproute2 'tipc' tool). Internal key state machine: AttachAlign(RX) +-+ +-+ | V | V +-+ Attach +-+ | IDLE |>| PENDING |(user = 0) +-+ +-+ A A Switch| A | | | | | | Free(switch/revoked)| | (Free)| +--+ | |Timeout | (TX)| | |(RX) | | | | | | v | +-+ Switch +-+ | PASSIVE |<| ACTIVE | +-+ (RX) +-+ (user = 1) (user >= 1) The number of TFMs is 10 by default and can be changed via the procfs 'net/tipc/max_tfms'. At this moment, as for simplicity, this file is also used to print the crypto statistics at runtime: echo 0xfff1 > /proc/sys/net/tipc/max_tfms The patch defines a new TIPC version (v7) for the encryption message (- backward compatibility as well). The message is basically encapsulated as follows: +--+ | TIPCv7 encryption | Original TIPCv2| Authentication | | header | packet (encrypted) | Tag| +--+ The throughput is about ~40% for small messages (compared with non- encryption) and ~9% for large messages. With the support from hardware crypto i.e. the Intel AES-NI CPU instructions, the throughput increases upto ~85% for small messages and ~55% for large messages. By default, the new feature is inactive (i.e. no encryption) until user sets a key for TIPC. There is however also a new option - "TIPC_CRYPTO" in the kernel configuration to enable/disable the new code when needed. v2: rebase, add new kernel option ("TIPC_CRYPTO") MAINTAINERS | add two new files 'crypto.h' & 'crypto.c' in tipc Signed-off-by: Tuong Lien --- net/tipc/Kconfig | 12 + net/tipc/Makefile|1 + net/tipc/bcast.c |2 +- net/tipc/bearer.c| 40 +- net/tipc/bearer.h|8 +- net/tipc/core.c | 18 + net/tipc/core.h |8 + net/tipc/crypto.c| 1986 ++ net/tipc/crypto.h| 167 + net/tipc/link.c | 19 +- net/tipc/link.h |1 + net/tipc/msg.c | 15 +- net/tipc/msg.h | 46 +- net/tipc/node.c | 117 ++- net/tipc/node.h |8 + net/tipc/sysctl.c| 11 + net/tipc/udp_media.c |1 + 17 files changed, 2422 insertions(+), 38 deletions(-) create mode 100644 net/tipc/crypto.c create mode 100644 net/tipc/crypto.h diff --git a/net/tipc/Kconfig b/net/tipc/Kconfig index b83e16ade4d2..6d94ccf7a9e9 100644 --- a/net/tipc/Kconfig +++ b/net/tipc/Kconfig @@ -35,6 +35,18 @@ config TIPC_MEDIA_UDP Saying Y here will enable support for running TIPC over IP/UDP bool default y +config TIPC_CRYPTO + bool "TIPC encryption support" + depends on TIPC + help + Saying Y here will enable support for TIPC encryption. + All TIPC messages will be encrypted/decrypted by using the currently most + advanced algorithm: AEAD AES-GCM (like IPSec or TLS) before leaving/ + entering the TIPC stack. + Key setting from user-space is performed via netlink by a user program + (e.g. the iproute2 'tipc' tool). + bool + default y config TIPC_DIAG tristate "TIPC: socket monitoring interface" diff --git a/net/tipc/Makefile b/net/tipc/Makefile index c86aba0282af..11255e970dd4 100644 --- a/net/tipc/Makefile +++ b/net/tipc/Makefile @@ -16,6 +16,7 @@ CFLAGS_trace.o += -I$(src) tipc-$(CONFIG_TIPC_MEDIA_UDP) += udp_media.o
[tipc-discussion] [PATCH v2 2/5] tipc: enable creating a "preliminary" node
When user sets RX key for a peer not existing on the own node, a new node entry is needed to which the RX key will be attached. However, since the peer node address (& capabilities) is unknown at that moment, only the node-ID is provided, this commit allows the creation of a node with only the data that we call as “preliminary”. A preliminary node is not the object of the “tipc_node_find()” but the “tipc_node_find_by_id()”. Once the first message i.e. LINK_CONFIG comes from that peer, and is successfully decrypted by the own node, the actual peer node data will be properly updated and the node will function as usual. In addition, the node timer always starts when a node object is created so if a preliminary node is not used, it will be cleaned up. The later encryption functions will also use the node timer and be able to create a preliminary node automatically when needed. v2: rebase Signed-off-by: Tuong Lien --- net/tipc/node.c | 103 +++- net/tipc/node.h | 1 + 2 files changed, 73 insertions(+), 31 deletions(-) diff --git a/net/tipc/node.c b/net/tipc/node.c index 4b60928049ea..5d5c95c9b4e6 100644 --- a/net/tipc/node.c +++ b/net/tipc/node.c @@ -89,6 +89,7 @@ struct tipc_bclink_entry { * @links: array containing references to all links to node * @action_flags: bit mask of different types of node actions * @state: connectivity state vs peer node + * @preliminary: a preliminary node or not * @sync_point: sequence number where synch/failover is finished * @list: links to adjacent nodes in sorted list of cluster's nodes * @working_links: number of working links to node (both active and standby) @@ -112,6 +113,7 @@ struct tipc_node { int action_flags; struct list_head list; int state; + bool preliminary; bool failover_sent; u16 sync_point; int link_cnt; @@ -120,6 +122,7 @@ struct tipc_node { u32 signature; u32 link_id; u8 peer_id[16]; + char peer_id_string[NODE_ID_STR_LEN]; struct list_head publ_list; struct list_head conn_sks; unsigned long keepalive_intv; @@ -245,6 +248,16 @@ u16 tipc_node_get_capabilities(struct net *net, u32 addr) return caps; } +u32 tipc_node_get_addr(struct tipc_node *node) +{ + return (node) ? node->addr : 0; +} + +char *tipc_node_get_id_str(struct tipc_node *node) +{ + return node->peer_id_string; +} + static void tipc_node_kref_release(struct kref *kref) { struct tipc_node *n = container_of(kref, struct tipc_node, kref); @@ -274,7 +287,7 @@ static struct tipc_node *tipc_node_find(struct net *net, u32 addr) rcu_read_lock(); hlist_for_each_entry_rcu(node, >node_htable[thash], hash) { - if (node->addr != addr) + if (node->addr != addr || node->preliminary) continue; if (!kref_get_unless_zero(>kref)) node = NULL; @@ -400,17 +413,39 @@ static void tipc_node_assign_peer_net(struct tipc_node *n, u32 hash_mixes) static struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id, u16 capabilities, - u32 signature, u32 hash_mixes) + u32 hash_mixes, bool preliminary) { struct tipc_net *tn = net_generic(net, tipc_net_id); struct tipc_node *n, *temp_node; struct tipc_link *l; + unsigned long intv; int bearer_id; int i; spin_lock_bh(>node_list_lock); - n = tipc_node_find(net, addr); + n = tipc_node_find(net, addr) ?: + tipc_node_find_by_id(net, peer_id); if (n) { + if (!n->preliminary) + goto update; + if (preliminary) + goto exit; + /* A preliminary node becomes "real" now, refresh its data */ + tipc_node_write_lock(n); + n->preliminary = false; + n->addr = addr; + hlist_del_rcu(>hash); + hlist_add_head_rcu(>hash, + >node_htable[tipc_hashfn(addr)]); + list_del_rcu(>list); + list_for_each_entry_rcu(temp_node, >node_list, list) { + if (n->addr < temp_node->addr) + break; + } + list_add_tail_rcu(>list, _node->list); + tipc_node_write_unlock_fast(n); + +update: if (n->peer_hash_mix ^ hash_mixes) tipc_node_assign_peer_net(n, hash_mixes); if (n->capabilities == capabilities) @@ -438,7 +473,9 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, pr_warn("Node creation failed, no memory\n"); goto exit; } +
[tipc-discussion] [PATCH v2 0/5] TIPC encryption
This series provides TIPC encryption feature, kernel part. There will be another one in the 'iproute2/tipc' for user space to set key. Tuong Lien (5): tipc: add reference counter to bearer tipc: enable creating a "preliminary" node tipc: add new AEAD key structure for user API tipc: introduce TIPC encryption & authentication tipc: add support for AEAD key setting via netlink include/uapi/linux/tipc.h | 21 + include/uapi/linux/tipc_netlink.h |8 + net/tipc/Kconfig | 12 + net/tipc/Makefile |1 + net/tipc/bcast.c |2 +- net/tipc/bearer.c | 54 +- net/tipc/bearer.h | 11 +- net/tipc/core.c | 18 + net/tipc/core.h |8 + net/tipc/crypto.c | 1986 + net/tipc/crypto.h | 167 net/tipc/link.c | 19 +- net/tipc/link.h |1 + net/tipc/msg.c| 15 +- net/tipc/msg.h| 46 +- net/tipc/netlink.c| 20 +- net/tipc/node.c | 347 ++- net/tipc/node.h | 13 + net/tipc/sysctl.c | 11 + net/tipc/udp_media.c |1 + 20 files changed, 2694 insertions(+), 67 deletions(-) create mode 100644 net/tipc/crypto.c create mode 100644 net/tipc/crypto.h -- 2.13.7 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [iproute2-next 2/2] tipc: add column to indicate netns-local
Example: Node IdentityHash Is container? State 1001002 01001002 noup 1001010 31000101 noup 1001011 31010101 noup 1001012 31020101 noup 1001003 31030001 yes up 1001013 31030101 noup 1001004 31040001 yes up 1001014 31040101 noup 1001015 31050101 noup 1001006 31060001 yes up 1001016 31060101 noup 1001007 31070001 yes up 1001008 31080001 yes up 1001009 31090001 yes up 100100a 31510001 yes up 100100b 31520001 yes up 100100c 31530001 yes up 100100d 31540001 noup 100100e 31550001 noup 100100f 31560001 noup Signed-off-by: Hoang Le --- include/uapi/linux/tipc_netlink.h | 1 + tipc/node.c | 7 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/include/uapi/linux/tipc_netlink.h b/include/uapi/linux/tipc_netlink.h index efb958fd167d..1a071268bf5d 100644 --- a/include/uapi/linux/tipc_netlink.h +++ b/include/uapi/linux/tipc_netlink.h @@ -160,6 +160,7 @@ enum { TIPC_NLA_NODE_UNSPEC, TIPC_NLA_NODE_ADDR, /* u32 */ TIPC_NLA_NODE_UP, /* flag */ + TIPC_NLA_NODE_LOCAL,/* flag */ __TIPC_NLA_NODE_MAX, TIPC_NLA_NODE_MAX = __TIPC_NLA_NODE_MAX - 1 diff --git a/tipc/node.c b/tipc/node.c index 2fec6753c974..b4203af014d3 100644 --- a/tipc/node.c +++ b/tipc/node.c @@ -42,6 +42,11 @@ static int node_list_cb(const struct nlmsghdr *nlh, void *data) addr = mnl_attr_get_u32(attrs[TIPC_NLA_NODE_ADDR]); hash2nodestr(addr, str); printf("%-32s %08x ", str, addr); + if (attrs[TIPC_NLA_NODE_LOCAL]) + printf("%-12s ", "yes"); + else + printf("%-12s ", "no"); + if (attrs[TIPC_NLA_NODE_UP]) printf("up\n"); else @@ -63,7 +68,7 @@ static int cmd_node_list(struct nlmsghdr *nlh, const struct cmd *cmd, fprintf(stderr, "error, message initialisation failed\n"); return -1; } - printf("Node IdentityHash State\n"); + printf("Node IdentityHash Is container? State\n"); return msg_dumpit(nlh, node_list_cb, NULL); } -- 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
[tipc-discussion] [iproute2-next 1/2] tipc: support 128bit node identity for peer removing
We add the support to remove a specific node down with 128bit node identifier, as an alternative to legacy 32-bit node address. v2: improve usage for 'tipc peer remove' command Signed-off-by: Hoang Le --- tipc/peer.c | 53 - 1 file changed, 52 insertions(+), 1 deletion(-) diff --git a/tipc/peer.c b/tipc/peer.c index f6380777033d..f14ec35e6f71 100644 --- a/tipc/peer.c +++ b/tipc/peer.c @@ -59,17 +59,68 @@ static int cmd_peer_rm_addr(struct nlmsghdr *nlh, const struct cmd *cmd, return msg_doit(nlh, NULL, NULL); } +static int cmd_peer_rm_nodeid(struct nlmsghdr *nlh, const struct cmd *cmd, + struct cmdl *cmdl, void *data) +{ + char buf[MNL_SOCKET_BUFFER_SIZE]; + __u8 id[16] = {0,}; + __u64 *w0 = (__u64 *)[0]; + __u64 *w1 = (__u64 *)[8]; + struct nlattr *nest; + char *str; + + if (cmdl->argc != cmdl->optind + 1) { + fprintf(stderr, "Usage: %s peer remove identity NODEID\n", + cmdl->argv[0]); + return -EINVAL; + } + + str = shift_cmdl(cmdl); + if (str2nodeid(str, id)) { + fprintf(stderr, "Invalid node identity\n"); + return -EINVAL; + } + + nlh = msg_init(buf, TIPC_NL_PEER_REMOVE); + if (!nlh) { + fprintf(stderr, "error, message initialisation failed\n"); + return -1; + } + + nest = mnl_attr_nest_start(nlh, TIPC_NLA_NET); + mnl_attr_put_u64(nlh, TIPC_NLA_NET_NODEID, *w0); + mnl_attr_put_u64(nlh, TIPC_NLA_NET_NODEID_W1, *w1); + mnl_attr_nest_end(nlh, nest); + + return msg_doit(nlh, NULL, NULL); +} + static void cmd_peer_rm_help(struct cmdl *cmdl) +{ + fprintf(stderr, "Usage: %s peer remove PROPERTY\n\n" + "PROPERTIES\n" + " identity NODEID - Remove peer node identity\n", + cmdl->argv[0]); +} + +static void cmd_peer_rm_addr_help(struct cmdl *cmdl) { fprintf(stderr, "Usage: %s peer remove address ADDRESS\n", cmdl->argv[0]); } +static void cmd_peer_rm_nodeid_help(struct cmdl *cmdl) +{ + fprintf(stderr, "Usage: %s peer remove identity NODEID\n", + cmdl->argv[0]); +} + static int cmd_peer_rm(struct nlmsghdr *nlh, const struct cmd *cmd, struct cmdl *cmdl, void *data) { const struct cmd cmds[] = { - { "address",cmd_peer_rm_addr, cmd_peer_rm_help }, + { "address", cmd_peer_rm_addr, cmd_peer_rm_addr_help }, + { "identity", cmd_peer_rm_nodeid, cmd_peer_rm_nodeid_help }, { NULL } }; -- 2.20.1 ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion
Re: [tipc-discussion] [PATCH RFC 0/5] TIPC encryption
On 11/5/19 5:33 AM, Jon Maloy wrote: > Tuong, Ying > I am ok with a kernel option, as long as it is enabled by default. I can > imagine smaller embedded systems where the deployer want a small module, and > encryption anyway is managed differently, or not at all. > > ///jon When I gave the suggestion to add a new kernel option, I also ever figured out how to reach this goal based on this series of patches. In my opinion, we don't need to modify the patches of making some preparation things. For example, we don't need to change patch #1 at all. Patch #3, #4 and #5 are almost completely separate with current code. The only thing is that we need to consider how to modify patch #2. In sum, it looks like it's not very difficult to introduce the new kernel configuration option. The kernel option not only can help us keep TIPC module size smaller, but also can help us maintain it easily particularly with TIPC becoming more and more complex. Lastly, probably it can help to make it possible that the series of patches can be easily accepted by upstream if user can disable the feature with a kernel option. ___ tipc-discussion mailing list tipc-discussion@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/tipc-discussion