Commit f779bf79 authored by Tuong Lien's avatar Tuong Lien Committed by David S. Miller

tipc: optimize key switching time and logic

We reduce the lasting time for a pending TX key to be active as well as
for a passive RX key to be freed which generally helps speed up the key
switching. It is not expected to be too fast but should not be too slow
either. Also the key handling logic is simplified that a pending RX key
will be removed automatically if it is found not working after a number
of times; the probing for a pending TX key is now carried on a specific
message user ('LINK_PROTOCOL' or 'LINK_CONFIG') which is more efficient
than using a timer on broadcast messages, the timer is reserved for use
later as needed.

The kernel logs or 'pr***()' are now made as clear as possible to user.
Some prints are added, removed or changed to the debug-level. The
'TIPC_CRYPTO_DEBUG' definition is removed, and the 'pr_debug()' is used
instead which will be much helpful in runtime.

Besides we also optimize the code in some other places as a preparation
for later commits.

v2: silent more kernel logs, also use 'info->extack' for a message
emitted due to netlink operations instead (- David's comments).
Acked-by: default avatarJon Maloy <jmaloy@redhat.com>
Signed-off-by: default avatarTuong Lien <tuong.t.lien@dektech.com.au>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent cb589a55
This diff is collapsed.
...@@ -160,7 +160,7 @@ int tipc_crypto_rcv(struct net *net, struct tipc_crypto *rx, ...@@ -160,7 +160,7 @@ int tipc_crypto_rcv(struct net *net, struct tipc_crypto *rx,
int tipc_crypto_key_init(struct tipc_crypto *c, struct tipc_aead_key *ukey, int tipc_crypto_key_init(struct tipc_crypto *c, struct tipc_aead_key *ukey,
u8 mode); u8 mode);
void tipc_crypto_key_flush(struct tipc_crypto *c); void tipc_crypto_key_flush(struct tipc_crypto *c);
int tipc_aead_key_validate(struct tipc_aead_key *ukey); int tipc_aead_key_validate(struct tipc_aead_key *ukey, struct genl_info *info);
bool tipc_ehdr_validate(struct sk_buff *skb); bool tipc_ehdr_validate(struct sk_buff *skb);
#endif /* _TIPC_CRYPTO_H */ #endif /* _TIPC_CRYPTO_H */
......
...@@ -2872,11 +2872,10 @@ static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info) ...@@ -2872,11 +2872,10 @@ static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
{ {
struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1]; struct nlattr *attrs[TIPC_NLA_NODE_MAX + 1];
struct net *net = sock_net(skb->sk); struct net *net = sock_net(skb->sk);
struct tipc_net *tn = tipc_net(net); struct tipc_crypto *tx = tipc_net(net)->crypto_tx, *c = tx;
struct tipc_node *n = NULL; struct tipc_node *n = NULL;
struct tipc_aead_key *ukey; struct tipc_aead_key *ukey;
struct tipc_crypto *c; u8 *id, *own_id, mode;
u8 *id, *own_id;
int rc = 0; int rc = 0;
if (!info->attrs[TIPC_NLA_NODE]) if (!info->attrs[TIPC_NLA_NODE])
...@@ -2886,52 +2885,52 @@ static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info) ...@@ -2886,52 +2885,52 @@ static int __tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
info->attrs[TIPC_NLA_NODE], info->attrs[TIPC_NLA_NODE],
tipc_nl_node_policy, info->extack); tipc_nl_node_policy, info->extack);
if (rc) if (rc)
goto exit; return rc;
own_id = tipc_own_id(net); own_id = tipc_own_id(net);
if (!own_id) { if (!own_id) {
rc = -EPERM; GENL_SET_ERR_MSG(info, "not found own node identity (set id?)");
goto exit; return -EPERM;
} }
rc = tipc_nl_retrieve_key(attrs, &ukey); rc = tipc_nl_retrieve_key(attrs, &ukey);
if (rc) if (rc)
goto exit; return rc;
rc = tipc_aead_key_validate(ukey); rc = tipc_aead_key_validate(ukey, info);
if (rc) if (rc)
goto exit; return rc;
rc = tipc_nl_retrieve_nodeid(attrs, &id); rc = tipc_nl_retrieve_nodeid(attrs, &id);
switch (rc) { switch (rc) {
case -ENODATA: case -ENODATA:
/* Cluster key mode */ mode = CLUSTER_KEY;
rc = tipc_crypto_key_init(tn->crypto_tx, ukey, CLUSTER_KEY);
break; break;
case 0: case 0:
/* Per-node key mode */ mode = PER_NODE_KEY;
if (!memcmp(id, own_id, NODE_ID_LEN)) { if (memcmp(id, own_id, NODE_ID_LEN)) {
c = tn->crypto_tx;
} else {
n = tipc_node_find_by_id(net, id) ?: n = tipc_node_find_by_id(net, id) ?:
tipc_node_create(net, 0, id, 0xffffu, 0, true); tipc_node_create(net, 0, id, 0xffffu, 0, true);
if (unlikely(!n)) { if (unlikely(!n))
rc = -ENOMEM; return -ENOMEM;
break;
}
c = n->crypto_rx; c = n->crypto_rx;
} }
rc = tipc_crypto_key_init(c, ukey, PER_NODE_KEY);
if (n)
tipc_node_put(n);
break; break;
default: default:
break; return rc;
} }
exit: /* Initiate the TX/RX key */
return (rc < 0) ? rc : 0; rc = tipc_crypto_key_init(c, ukey, mode);
if (n)
tipc_node_put(n);
if (rc < 0) {
GENL_SET_ERR_MSG(info, "unable to initiate or attach new key");
return rc;
}
return 0;
} }
int tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info) int tipc_nl_node_set_key(struct sk_buff *skb, struct genl_info *info)
...@@ -2958,7 +2957,6 @@ static int __tipc_nl_node_flush_key(struct sk_buff *skb, ...@@ -2958,7 +2957,6 @@ static int __tipc_nl_node_flush_key(struct sk_buff *skb,
tipc_crypto_key_flush(n->crypto_rx); tipc_crypto_key_flush(n->crypto_rx);
rcu_read_unlock(); rcu_read_unlock();
pr_info("All keys are flushed!\n");
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment