forked from mirrors/linux
		
	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:
                                 Attach    Align(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.
MAINTAINERS | add two new files 'crypto.h' & 'crypto.c' in tipc
Acked-by: Ying Xue <ying.xue@windreiver.com>
Acked-by: Jon Maloy <jon.maloy@ericsson.com>
Signed-off-by: Tuong Lien <tuong.t.lien@dektech.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
			
			
This commit is contained in:
		
							parent
							
								
									134bdac397
								
							
						
					
					
						commit
						fc1b6d6de2
					
				
					 17 changed files with 2386 additions and 47 deletions
				
			
		|  | @ -35,6 +35,21 @@ 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 | ||||
| 	select CRYPTO | ||||
| 	select CRYPTO_AES | ||||
| 	select CRYPTO_GCM | ||||
| 	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" | ||||
|  |  | |||
|  | @ -16,6 +16,7 @@ CFLAGS_trace.o += -I$(src) | |||
| tipc-$(CONFIG_TIPC_MEDIA_UDP)	+= udp_media.o | ||||
| tipc-$(CONFIG_TIPC_MEDIA_IB)	+= ib_media.o | ||||
| tipc-$(CONFIG_SYSCTL)		+= sysctl.o | ||||
| tipc-$(CONFIG_TIPC_CRYPTO)	+= crypto.o | ||||
| 
 | ||||
| 
 | ||||
| obj-$(CONFIG_TIPC_DIAG)	+= diag.o | ||||
|  |  | |||
|  | @ -84,7 +84,7 @@ static struct tipc_bc_base *tipc_bc_base(struct net *net) | |||
|  */ | ||||
| int tipc_bcast_get_mtu(struct net *net) | ||||
| { | ||||
| 	return tipc_link_mtu(tipc_bc_sndlink(net)) - INT_H_SIZE; | ||||
| 	return tipc_link_mss(tipc_bc_sndlink(net)); | ||||
| } | ||||
| 
 | ||||
| void tipc_bcast_disable_rcast(struct net *net) | ||||
|  |  | |||
|  | @ -44,6 +44,7 @@ | |||
| #include "netlink.h" | ||||
| #include "udp_media.h" | ||||
| #include "trace.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| #define MAX_ADDR_STR 60 | ||||
| 
 | ||||
|  | @ -516,10 +517,15 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id, | |||
| 
 | ||||
| 	rcu_read_lock(); | ||||
| 	b = bearer_get(net, bearer_id); | ||||
| 	if (likely(b && (test_bit(0, &b->up) || msg_is_reset(hdr)))) | ||||
| 		b->media->send_msg(net, skb, b, dest); | ||||
| 	else | ||||
| 	if (likely(b && (test_bit(0, &b->up) || msg_is_reset(hdr)))) { | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 		tipc_crypto_xmit(net, &skb, b, dest, NULL); | ||||
| 		if (skb) | ||||
| #endif | ||||
| 			b->media->send_msg(net, skb, b, dest); | ||||
| 	} else { | ||||
| 		kfree_skb(skb); | ||||
| 	} | ||||
| 	rcu_read_unlock(); | ||||
| } | ||||
| 
 | ||||
|  | @ -527,7 +533,8 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id, | |||
|  */ | ||||
| void tipc_bearer_xmit(struct net *net, u32 bearer_id, | ||||
| 		      struct sk_buff_head *xmitq, | ||||
| 		      struct tipc_media_addr *dst) | ||||
| 		      struct tipc_media_addr *dst, | ||||
| 		      struct tipc_node *__dnode) | ||||
| { | ||||
| 	struct tipc_bearer *b; | ||||
| 	struct sk_buff *skb, *tmp; | ||||
|  | @ -541,10 +548,15 @@ void tipc_bearer_xmit(struct net *net, u32 bearer_id, | |||
| 		__skb_queue_purge(xmitq); | ||||
| 	skb_queue_walk_safe(xmitq, skb, tmp) { | ||||
| 		__skb_dequeue(xmitq); | ||||
| 		if (likely(test_bit(0, &b->up) || msg_is_reset(buf_msg(skb)))) | ||||
| 			b->media->send_msg(net, skb, b, dst); | ||||
| 		else | ||||
| 		if (likely(test_bit(0, &b->up) || msg_is_reset(buf_msg(skb)))) { | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 			tipc_crypto_xmit(net, &skb, b, dst, __dnode); | ||||
| 			if (skb) | ||||
| #endif | ||||
| 				b->media->send_msg(net, skb, b, dst); | ||||
| 		} else { | ||||
| 			kfree_skb(skb); | ||||
| 		} | ||||
| 	} | ||||
| 	rcu_read_unlock(); | ||||
| } | ||||
|  | @ -555,6 +567,7 @@ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id, | |||
| 			 struct sk_buff_head *xmitq) | ||||
| { | ||||
| 	struct tipc_net *tn = tipc_net(net); | ||||
| 	struct tipc_media_addr *dst; | ||||
| 	int net_id = tn->net_id; | ||||
| 	struct tipc_bearer *b; | ||||
| 	struct sk_buff *skb, *tmp; | ||||
|  | @ -569,7 +582,12 @@ void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id, | |||
| 		msg_set_non_seq(hdr, 1); | ||||
| 		msg_set_mc_netid(hdr, net_id); | ||||
| 		__skb_dequeue(xmitq); | ||||
| 		b->media->send_msg(net, skb, b, &b->bcast_addr); | ||||
| 		dst = &b->bcast_addr; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 		tipc_crypto_xmit(net, &skb, b, dst, NULL); | ||||
| 		if (skb) | ||||
| #endif | ||||
| 			b->media->send_msg(net, skb, b, dst); | ||||
| 	} | ||||
| 	rcu_read_unlock(); | ||||
| } | ||||
|  | @ -596,6 +614,7 @@ static int tipc_l2_rcv_msg(struct sk_buff *skb, struct net_device *dev, | |||
| 	if (likely(b && test_bit(0, &b->up) && | ||||
| 		   (skb->pkt_type <= PACKET_MULTICAST))) { | ||||
| 		skb_mark_not_on_list(skb); | ||||
| 		TIPC_SKB_CB(skb)->flags = 0; | ||||
| 		tipc_rcv(dev_net(b->pt.dev), skb, b); | ||||
| 		rcu_read_unlock(); | ||||
| 		return NET_RX_SUCCESS; | ||||
|  |  | |||
|  | @ -232,7 +232,8 @@ void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id, | |||
| 			  struct tipc_media_addr *dest); | ||||
| void tipc_bearer_xmit(struct net *net, u32 bearer_id, | ||||
| 		      struct sk_buff_head *xmitq, | ||||
| 		      struct tipc_media_addr *dst); | ||||
| 		      struct tipc_media_addr *dst, | ||||
| 		      struct tipc_node *__dnode); | ||||
| void tipc_bearer_bc_xmit(struct net *net, u32 bearer_id, | ||||
| 			 struct sk_buff_head *xmitq); | ||||
| void tipc_clone_to_loopback(struct net *net, struct sk_buff_head *pkts); | ||||
|  |  | |||
|  | @ -44,6 +44,7 @@ | |||
| #include "socket.h" | ||||
| #include "bcast.h" | ||||
| #include "node.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| #include <linux/module.h> | ||||
| 
 | ||||
|  | @ -68,6 +69,11 @@ static int __net_init tipc_init_net(struct net *net) | |||
| 	INIT_LIST_HEAD(&tn->node_list); | ||||
| 	spin_lock_init(&tn->node_list_lock); | ||||
| 
 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	err = tipc_crypto_start(&tn->crypto_tx, net, NULL); | ||||
| 	if (err) | ||||
| 		goto out_crypto; | ||||
| #endif | ||||
| 	err = tipc_sk_rht_init(net); | ||||
| 	if (err) | ||||
| 		goto out_sk_rht; | ||||
|  | @ -93,6 +99,11 @@ static int __net_init tipc_init_net(struct net *net) | |||
| out_nametbl: | ||||
| 	tipc_sk_rht_destroy(net); | ||||
| out_sk_rht: | ||||
| 
 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	tipc_crypto_stop(&tn->crypto_tx); | ||||
| out_crypto: | ||||
| #endif | ||||
| 	return err; | ||||
| } | ||||
| 
 | ||||
|  | @ -103,6 +114,9 @@ static void __net_exit tipc_exit_net(struct net *net) | |||
| 	tipc_bcast_stop(net); | ||||
| 	tipc_nametbl_stop(net); | ||||
| 	tipc_sk_rht_destroy(net); | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	tipc_crypto_stop(&tipc_net(net)->crypto_tx); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| static void __net_exit tipc_pernet_pre_exit(struct net *net) | ||||
|  |  | |||
|  | @ -68,6 +68,9 @@ struct tipc_link; | |||
| struct tipc_name_table; | ||||
| struct tipc_topsrv; | ||||
| struct tipc_monitor; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| struct tipc_crypto; | ||||
| #endif | ||||
| 
 | ||||
| #define TIPC_MOD_VER "2.0.0" | ||||
| 
 | ||||
|  | @ -129,6 +132,11 @@ struct tipc_net { | |||
| 
 | ||||
| 	/* Tracing of node internal messages */ | ||||
| 	struct packet_type loopback_pt; | ||||
| 
 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	/* TX crypto handler */ | ||||
| 	struct tipc_crypto *crypto_tx; | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| static inline struct tipc_net *tipc_net(struct net *net) | ||||
|  |  | |||
							
								
								
									
										1986
									
								
								net/tipc/crypto.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1986
									
								
								net/tipc/crypto.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										167
									
								
								net/tipc/crypto.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										167
									
								
								net/tipc/crypto.h
									
									
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,167 @@ | |||
| /* SPDX-License-Identifier: GPL-2.0 */ | ||||
| /**
 | ||||
|  * net/tipc/crypto.h: Include file for TIPC crypto | ||||
|  * | ||||
|  * Copyright (c) 2019, Ericsson AB | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  * Redistribution and use in source and binary forms, with or without | ||||
|  * modification, are permitted provided that the following conditions are met: | ||||
|  * | ||||
|  * 1. Redistributions of source code must retain the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer. | ||||
|  * 2. Redistributions in binary form must reproduce the above copyright | ||||
|  *    notice, this list of conditions and the following disclaimer in the | ||||
|  *    documentation and/or other materials provided with the distribution. | ||||
|  * 3. Neither the names of the copyright holders nor the names of its | ||||
|  *    contributors may be used to endorse or promote products derived from | ||||
|  *    this software without specific prior written permission. | ||||
|  * | ||||
|  * Alternatively, this software may be distributed under the terms of the | ||||
|  * GNU General Public License ("GPL") version 2 as published by the Free | ||||
|  * Software Foundation. | ||||
|  * | ||||
|  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" | ||||
|  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||||
|  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | ||||
|  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE | ||||
|  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | ||||
|  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | ||||
|  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | ||||
|  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN | ||||
|  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | ||||
|  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ||||
|  * POSSIBILITY OF SUCH DAMAGE. | ||||
|  */ | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| #ifndef _TIPC_CRYPTO_H | ||||
| #define _TIPC_CRYPTO_H | ||||
| 
 | ||||
| #include "core.h" | ||||
| #include "node.h" | ||||
| #include "msg.h" | ||||
| #include "bearer.h" | ||||
| 
 | ||||
| #define TIPC_EVERSION			7 | ||||
| 
 | ||||
| /* AEAD aes(gcm) */ | ||||
| #define TIPC_AES_GCM_KEY_SIZE_128	16 | ||||
| #define TIPC_AES_GCM_KEY_SIZE_192	24 | ||||
| #define TIPC_AES_GCM_KEY_SIZE_256	32 | ||||
| 
 | ||||
| #define TIPC_AES_GCM_SALT_SIZE		4 | ||||
| #define TIPC_AES_GCM_IV_SIZE		12 | ||||
| #define TIPC_AES_GCM_TAG_SIZE		16 | ||||
| 
 | ||||
| /**
 | ||||
|  * TIPC crypto modes: | ||||
|  * - CLUSTER_KEY: | ||||
|  *	One single key is used for both TX & RX in all nodes in the cluster. | ||||
|  * - PER_NODE_KEY: | ||||
|  *	Each nodes in the cluster has one TX key, for RX a node needs to know | ||||
|  *	its peers' TX key for the decryption of messages from those nodes. | ||||
|  */ | ||||
| enum { | ||||
| 	CLUSTER_KEY = 1, | ||||
| 	PER_NODE_KEY = (1 << 1), | ||||
| }; | ||||
| 
 | ||||
| extern int sysctl_tipc_max_tfms __read_mostly; | ||||
| 
 | ||||
| /**
 | ||||
|  * TIPC encryption message format: | ||||
|  * | ||||
|  *     3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 | ||||
|  *     1 0 9 8 7 6 5 4|3 2 1 0 9 8 7 6|5 4 3 2 1 0 9 8|7 6 5 4 3 2 1 0 | ||||
|  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  * w0:|Ver=7| User  |D|TX |RX |K|                 Rsvd                | | ||||
|  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  * w1:|                             Seqno                             | | ||||
|  * w2:|                           (8 octets)                          | | ||||
|  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  * w3:\                            Prevnode                           \ | ||||
|  *    /                        (4 or 16 octets)                       / | ||||
|  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  *    \                                                               \ | ||||
|  *    /       Encrypted complete TIPC V2 header and user data         / | ||||
|  *    \                                                               \ | ||||
|  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  *    |                                                               | | ||||
|  *    |                             AuthTag                           | | ||||
|  *    |                           (16 octets)                         | | ||||
|  *    |                                                               | | ||||
|  *    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||||
|  * | ||||
|  * Word0: | ||||
|  *	Ver	: = 7 i.e. TIPC encryption message version | ||||
|  *	User	: = 7 (for LINK_PROTOCOL); = 13 (for LINK_CONFIG) or = 0 | ||||
|  *	D	: The destined bit i.e. the message's destination node is | ||||
|  *	          "known" or not at the message encryption | ||||
|  *	TX	: TX key used for the message encryption | ||||
|  *	RX	: Currently RX active key corresponding to the destination | ||||
|  *	          node's TX key (when the "D" bit is set) | ||||
|  *	K	: Keep-alive bit (for RPS, LINK_PROTOCOL/STATE_MSG only) | ||||
|  *	Rsvd	: Reserved bit, field | ||||
|  * Word1-2: | ||||
|  *	Seqno	: The 64-bit sequence number of the encrypted message, also | ||||
|  *		  part of the nonce used for the message encryption/decryption | ||||
|  * Word3-: | ||||
|  *	Prevnode: The source node address, or ID in case LINK_CONFIG only | ||||
|  *	AuthTag	: The authentication tag for the message integrity checking | ||||
|  *		  generated by the message encryption | ||||
|  */ | ||||
| struct tipc_ehdr { | ||||
| 	union { | ||||
| 		struct { | ||||
| #if defined(__LITTLE_ENDIAN_BITFIELD) | ||||
| 			__u8	destined:1, | ||||
| 				user:4, | ||||
| 				version:3; | ||||
| 			__u8	reserved_1:3, | ||||
| 				keepalive:1, | ||||
| 				rx_key_active:2, | ||||
| 				tx_key:2; | ||||
| #elif defined(__BIG_ENDIAN_BITFIELD) | ||||
| 			__u8	version:3, | ||||
| 				user:4, | ||||
| 				destined:1; | ||||
| 			__u8	tx_key:2, | ||||
| 				rx_key_active:2, | ||||
| 				keepalive:1, | ||||
| 				reserved_1:3; | ||||
| #else | ||||
| #error  "Please fix <asm/byteorder.h>" | ||||
| #endif | ||||
| 			__be16	reserved_2; | ||||
| 		} __packed; | ||||
| 		__be32 w0; | ||||
| 	}; | ||||
| 	__be64 seqno; | ||||
| 	union { | ||||
| 		__be32 addr; | ||||
| 		__u8 id[NODE_ID_LEN]; /* For a LINK_CONFIG message only! */ | ||||
| 	}; | ||||
| #define EHDR_SIZE	(offsetof(struct tipc_ehdr, addr) + sizeof(__be32)) | ||||
| #define EHDR_CFG_SIZE	(sizeof(struct tipc_ehdr)) | ||||
| #define EHDR_MIN_SIZE	(EHDR_SIZE) | ||||
| #define EHDR_MAX_SIZE	(EHDR_CFG_SIZE) | ||||
| #define EMSG_OVERHEAD	(EHDR_SIZE + TIPC_AES_GCM_TAG_SIZE) | ||||
| } __packed; | ||||
| 
 | ||||
| int tipc_crypto_start(struct tipc_crypto **crypto, struct net *net, | ||||
| 		      struct tipc_node *node); | ||||
| void tipc_crypto_stop(struct tipc_crypto **crypto); | ||||
| void tipc_crypto_timeout(struct tipc_crypto *rx); | ||||
| int tipc_crypto_xmit(struct net *net, struct sk_buff **skb, | ||||
| 		     struct tipc_bearer *b, struct tipc_media_addr *dst, | ||||
| 		     struct tipc_node *__dnode); | ||||
| int tipc_crypto_rcv(struct net *net, struct tipc_crypto *rx, | ||||
| 		    struct sk_buff **skb, struct tipc_bearer *b); | ||||
| int tipc_crypto_key_init(struct tipc_crypto *c, struct tipc_aead_key *ukey, | ||||
| 			 u8 mode); | ||||
| void tipc_crypto_key_flush(struct tipc_crypto *c); | ||||
| int tipc_aead_key_validate(struct tipc_aead_key *ukey); | ||||
| bool tipc_ehdr_validate(struct sk_buff *skb); | ||||
| 
 | ||||
| #endif /* _TIPC_CRYPTO_H */ | ||||
| #endif | ||||
|  | @ -44,6 +44,7 @@ | |||
| #include "netlink.h" | ||||
| #include "monitor.h" | ||||
| #include "trace.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| #include <linux/pkt_sched.h> | ||||
| 
 | ||||
|  | @ -397,6 +398,15 @@ int tipc_link_mtu(struct tipc_link *l) | |||
| 	return l->mtu; | ||||
| } | ||||
| 
 | ||||
| int tipc_link_mss(struct tipc_link *l) | ||||
| { | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	return l->mtu - INT_H_SIZE - EMSG_OVERHEAD; | ||||
| #else | ||||
| 	return l->mtu - INT_H_SIZE; | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| u16 tipc_link_rcv_nxt(struct tipc_link *l) | ||||
| { | ||||
| 	return l->rcv_nxt; | ||||
|  | @ -948,6 +958,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list, | |||
| 	u16 seqno = l->snd_nxt; | ||||
| 	int pkt_cnt = skb_queue_len(list); | ||||
| 	int imp = msg_importance(hdr); | ||||
| 	unsigned int mss = tipc_link_mss(l); | ||||
| 	unsigned int maxwin = l->window; | ||||
| 	unsigned int mtu = l->mtu; | ||||
| 	bool new_bundle; | ||||
|  | @ -1000,8 +1011,7 @@ int tipc_link_xmit(struct tipc_link *l, struct sk_buff_head *list, | |||
| 			continue; | ||||
| 		} | ||||
| 		if (tipc_msg_try_bundle(l->backlog[imp].target_bskb, &skb, | ||||
| 					mtu - INT_H_SIZE, l->addr, | ||||
| 					&new_bundle)) { | ||||
| 					mss, l->addr, &new_bundle)) { | ||||
| 			if (skb) { | ||||
| 				/* Keep a ref. to the skb for next try */ | ||||
| 				l->backlog[imp].target_bskb = skb; | ||||
|  | @ -1154,7 +1164,7 @@ static int tipc_link_bc_retrans(struct tipc_link *l, struct tipc_link *r, | |||
| 		if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr)) | ||||
| 			continue; | ||||
| 		TIPC_SKB_CB(skb)->nxt_retr = TIPC_BC_RETR_LIM; | ||||
| 		_skb = __pskb_copy(skb, LL_MAX_HEADER + MIN_H_SIZE, GFP_ATOMIC); | ||||
| 		_skb = pskb_copy(skb, GFP_ATOMIC); | ||||
| 		if (!_skb) | ||||
| 			return 0; | ||||
| 		hdr = buf_msg(_skb); | ||||
|  | @ -1430,8 +1440,7 @@ static int tipc_link_advance_transmq(struct tipc_link *l, u16 acked, u16 gap, | |||
| 			if (time_before(jiffies, TIPC_SKB_CB(skb)->nxt_retr)) | ||||
| 				continue; | ||||
| 			TIPC_SKB_CB(skb)->nxt_retr = TIPC_UC_RETR_TIME; | ||||
| 			_skb = __pskb_copy(skb, LL_MAX_HEADER + MIN_H_SIZE, | ||||
| 					   GFP_ATOMIC); | ||||
| 			_skb = pskb_copy(skb, GFP_ATOMIC); | ||||
| 			if (!_skb) | ||||
| 				continue; | ||||
| 			hdr = buf_msg(_skb); | ||||
|  |  | |||
|  | @ -141,6 +141,7 @@ void tipc_link_remove_bc_peer(struct tipc_link *snd_l, | |||
| int tipc_link_bc_peers(struct tipc_link *l); | ||||
| void tipc_link_set_mtu(struct tipc_link *l, int mtu); | ||||
| int tipc_link_mtu(struct tipc_link *l); | ||||
| int tipc_link_mss(struct tipc_link *l); | ||||
| void tipc_link_bc_ack_rcv(struct tipc_link *l, u16 acked, | ||||
| 			  struct sk_buff_head *xmitq); | ||||
| void tipc_link_build_bc_sync_msg(struct tipc_link *l, | ||||
|  |  | |||
|  | @ -39,10 +39,16 @@ | |||
| #include "msg.h" | ||||
| #include "addr.h" | ||||
| #include "name_table.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| #define MAX_FORWARD_SIZE 1024 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| #define BUF_HEADROOM ALIGN(((LL_MAX_HEADER + 48) + EHDR_MAX_SIZE), 16) | ||||
| #define BUF_TAILROOM (TIPC_AES_GCM_TAG_SIZE) | ||||
| #else | ||||
| #define BUF_HEADROOM (LL_MAX_HEADER + 48) | ||||
| #define BUF_TAILROOM 16 | ||||
| #endif | ||||
| 
 | ||||
| static unsigned int align(unsigned int i) | ||||
| { | ||||
|  | @ -61,7 +67,11 @@ static unsigned int align(unsigned int i) | |||
| struct sk_buff *tipc_buf_acquire(u32 size, gfp_t gfp) | ||||
| { | ||||
| 	struct sk_buff *skb; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	unsigned int buf_size = (BUF_HEADROOM + size + BUF_TAILROOM + 3) & ~3u; | ||||
| #else | ||||
| 	unsigned int buf_size = (BUF_HEADROOM + size + 3) & ~3u; | ||||
| #endif | ||||
| 
 | ||||
| 	skb = alloc_skb_fclone(buf_size, gfp); | ||||
| 	if (skb) { | ||||
|  | @ -173,7 +183,7 @@ int tipc_buf_append(struct sk_buff **headbuf, struct sk_buff **buf) | |||
| 	} | ||||
| 
 | ||||
| 	if (fragid == LAST_FRAGMENT) { | ||||
| 		TIPC_SKB_CB(head)->validated = false; | ||||
| 		TIPC_SKB_CB(head)->validated = 0; | ||||
| 		if (unlikely(!tipc_msg_validate(&head))) | ||||
| 			goto err; | ||||
| 		*buf = head; | ||||
|  | @ -271,6 +281,7 @@ bool tipc_msg_validate(struct sk_buff **_skb) | |||
| 
 | ||||
| 	if (unlikely(TIPC_SKB_CB(skb)->validated)) | ||||
| 		return true; | ||||
| 
 | ||||
| 	if (unlikely(!pskb_may_pull(skb, MIN_H_SIZE))) | ||||
| 		return false; | ||||
| 
 | ||||
|  | @ -292,7 +303,7 @@ bool tipc_msg_validate(struct sk_buff **_skb) | |||
| 	if (unlikely(skb->len < msz)) | ||||
| 		return false; | ||||
| 
 | ||||
| 	TIPC_SKB_CB(skb)->validated = true; | ||||
| 	TIPC_SKB_CB(skb)->validated = 1; | ||||
| 	return true; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -102,16 +102,42 @@ struct plist; | |||
| #define TIPC_MEDIA_INFO_OFFSET	5 | ||||
| 
 | ||||
| struct tipc_skb_cb { | ||||
| 	struct sk_buff *tail; | ||||
| 	unsigned long nxt_retr; | ||||
| 	unsigned long retr_stamp; | ||||
| 	u32 bytes_read; | ||||
| 	u32 orig_member; | ||||
| 	u16 chain_imp; | ||||
| 	u16 ackers; | ||||
| 	u16 retr_cnt; | ||||
| 	bool validated; | ||||
| }; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			struct sk_buff *tail; | ||||
| 			unsigned long nxt_retr; | ||||
| 			unsigned long retr_stamp; | ||||
| 			u32 bytes_read; | ||||
| 			u32 orig_member; | ||||
| 			u16 chain_imp; | ||||
| 			u16 ackers; | ||||
| 			u16 retr_cnt; | ||||
| 		} __packed; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 		struct { | ||||
| 			struct tipc_crypto *rx; | ||||
| 			struct tipc_aead *last; | ||||
| 			u8 recurs; | ||||
| 		} tx_clone_ctx __packed; | ||||
| #endif | ||||
| 	} __packed; | ||||
| 	union { | ||||
| 		struct { | ||||
| 			u8 validated:1; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 			u8 encrypted:1; | ||||
| 			u8 decrypted:1; | ||||
| 			u8 probe:1; | ||||
| 			u8 tx_clone_deferred:1; | ||||
| #endif | ||||
| 		}; | ||||
| 		u8 flags; | ||||
| 	}; | ||||
| 	u8 reserved; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	void *crypto_ctx; | ||||
| #endif | ||||
| } __packed; | ||||
| 
 | ||||
| #define TIPC_SKB_CB(__skb) ((struct tipc_skb_cb *)&((__skb)->cb[0])) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										101
									
								
								net/tipc/node.c
									
									
									
									
									
								
							
							
						
						
									
										101
									
								
								net/tipc/node.c
									
									
									
									
									
								
							|  | @ -44,6 +44,7 @@ | |||
| #include "discover.h" | ||||
| #include "netlink.h" | ||||
| #include "trace.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| #define INVALID_NODE_SIG	0x10000 | ||||
| #define NODE_CLEANUP_AFTER	300000 | ||||
|  | @ -100,6 +101,7 @@ struct tipc_bclink_entry { | |||
|  * @publ_list: list of publications | ||||
|  * @rcu: rcu struct for tipc_node | ||||
|  * @delete_at: indicates the time for deleting a down node | ||||
|  * @crypto_rx: RX crypto handler | ||||
|  */ | ||||
| struct tipc_node { | ||||
| 	u32 addr; | ||||
|  | @ -131,6 +133,9 @@ struct tipc_node { | |||
| 	unsigned long delete_at; | ||||
| 	struct net *peer_net; | ||||
| 	u32 peer_hash_mix; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	struct tipc_crypto *crypto_rx; | ||||
| #endif | ||||
| }; | ||||
| 
 | ||||
| /* Node FSM states and events:
 | ||||
|  | @ -168,7 +173,6 @@ static void tipc_node_timeout(struct timer_list *t); | |||
| static void tipc_node_fsm_evt(struct tipc_node *n, int evt); | ||||
| static struct tipc_node *tipc_node_find(struct net *net, u32 addr); | ||||
| static struct tipc_node *tipc_node_find_by_id(struct net *net, u8 *id); | ||||
| static void tipc_node_put(struct tipc_node *node); | ||||
| static bool node_is_up(struct tipc_node *n); | ||||
| static void tipc_node_delete_from_list(struct tipc_node *node); | ||||
| 
 | ||||
|  | @ -258,15 +262,41 @@ char *tipc_node_get_id_str(struct tipc_node *node) | |||
| 	return node->peer_id_string; | ||||
| } | ||||
| 
 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| /**
 | ||||
|  * tipc_node_crypto_rx - Retrieve crypto RX handle from node | ||||
|  * Note: node ref counter must be held first! | ||||
|  */ | ||||
| struct tipc_crypto *tipc_node_crypto_rx(struct tipc_node *__n) | ||||
| { | ||||
| 	return (__n) ? __n->crypto_rx : NULL; | ||||
| } | ||||
| 
 | ||||
| struct tipc_crypto *tipc_node_crypto_rx_by_list(struct list_head *pos) | ||||
| { | ||||
| 	return container_of(pos, struct tipc_node, list)->crypto_rx; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| void tipc_node_free(struct rcu_head *rp) | ||||
| { | ||||
| 	struct tipc_node *n = container_of(rp, struct tipc_node, rcu); | ||||
| 
 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	tipc_crypto_stop(&n->crypto_rx); | ||||
| #endif | ||||
| 	kfree(n); | ||||
| } | ||||
| 
 | ||||
| static void tipc_node_kref_release(struct kref *kref) | ||||
| { | ||||
| 	struct tipc_node *n = container_of(kref, struct tipc_node, kref); | ||||
| 
 | ||||
| 	kfree(n->bc_entry.link); | ||||
| 	kfree_rcu(n, rcu); | ||||
| 	call_rcu(&n->rcu, tipc_node_free); | ||||
| } | ||||
| 
 | ||||
| static void tipc_node_put(struct tipc_node *node) | ||||
| void tipc_node_put(struct tipc_node *node) | ||||
| { | ||||
| 	kref_put(&node->kref, tipc_node_kref_release); | ||||
| } | ||||
|  | @ -411,9 +441,9 @@ 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 hash_mixes, bool preliminary) | ||||
| struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id, | ||||
| 				   u16 capabilities, u32 hash_mixes, | ||||
| 				   bool preliminary) | ||||
| { | ||||
| 	struct tipc_net *tn = net_generic(net, tipc_net_id); | ||||
| 	struct tipc_node *n, *temp_node; | ||||
|  | @ -474,6 +504,14 @@ static struct tipc_node *tipc_node_create(struct net *net, u32 addr, | |||
| 		goto exit; | ||||
| 	} | ||||
| 	tipc_nodeid2string(n->peer_id_string, peer_id); | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	if (unlikely(tipc_crypto_start(&n->crypto_rx, net, n))) { | ||||
| 		pr_warn("Failed to start crypto RX(%s)!\n", n->peer_id_string); | ||||
| 		kfree(n); | ||||
| 		n = NULL; | ||||
| 		goto exit; | ||||
| 	} | ||||
| #endif | ||||
| 	n->addr = addr; | ||||
| 	n->preliminary = preliminary; | ||||
| 	memcpy(&n->peer_id, peer_id, 16); | ||||
|  | @ -725,6 +763,10 @@ static void tipc_node_timeout(struct timer_list *t) | |||
| 		return; | ||||
| 	} | ||||
| 
 | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	/* Take any crypto key related actions first */ | ||||
| 	tipc_crypto_timeout(n->crypto_rx); | ||||
| #endif | ||||
| 	__skb_queue_head_init(&xmitq); | ||||
| 
 | ||||
| 	/* Initial node interval to value larger (10 seconds), then it will be
 | ||||
|  | @ -745,7 +787,7 @@ static void tipc_node_timeout(struct timer_list *t) | |||
| 			remains--; | ||||
| 		} | ||||
| 		tipc_node_read_unlock(n); | ||||
| 		tipc_bearer_xmit(n->net, bearer_id, &xmitq, &le->maddr); | ||||
| 		tipc_bearer_xmit(n->net, bearer_id, &xmitq, &le->maddr, n); | ||||
| 		if (rc & TIPC_LINK_DOWN_EVT) | ||||
| 			tipc_node_link_down(n, bearer_id, false); | ||||
| 	} | ||||
|  | @ -777,7 +819,7 @@ static void __tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
| 	n->link_id = tipc_link_id(nl); | ||||
| 
 | ||||
| 	/* Leave room for tunnel header when returning 'mtu' to users: */ | ||||
| 	n->links[bearer_id].mtu = tipc_link_mtu(nl) - INT_H_SIZE; | ||||
| 	n->links[bearer_id].mtu = tipc_link_mss(nl); | ||||
| 
 | ||||
| 	tipc_bearer_add_dest(n->net, bearer_id, n->addr); | ||||
| 	tipc_bcast_inc_bearer_dst_cnt(n->net, bearer_id); | ||||
|  | @ -831,7 +873,7 @@ static void tipc_node_link_up(struct tipc_node *n, int bearer_id, | |||
| 	tipc_node_write_lock(n); | ||||
| 	__tipc_node_link_up(n, bearer_id, xmitq); | ||||
| 	maddr = &n->links[bearer_id].maddr; | ||||
| 	tipc_bearer_xmit(n->net, bearer_id, xmitq, maddr); | ||||
| 	tipc_bearer_xmit(n->net, bearer_id, xmitq, maddr, n); | ||||
| 	tipc_node_write_unlock(n); | ||||
| } | ||||
| 
 | ||||
|  | @ -986,7 +1028,7 @@ static void tipc_node_link_down(struct tipc_node *n, int bearer_id, bool delete) | |||
| 	if (delete) | ||||
| 		tipc_mon_remove_peer(n->net, n->addr, old_bearer_id); | ||||
| 	if (!skb_queue_empty(&xmitq)) | ||||
| 		tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr); | ||||
| 		tipc_bearer_xmit(n->net, bearer_id, &xmitq, maddr, n); | ||||
| 	tipc_sk_rcv(n->net, &le->inputq); | ||||
| } | ||||
| 
 | ||||
|  | @ -1640,7 +1682,7 @@ int tipc_node_xmit(struct net *net, struct sk_buff_head *list, | |||
| 	if (unlikely(rc == -ENOBUFS)) | ||||
| 		tipc_node_link_down(n, bearer_id, false); | ||||
| 	else | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr, n); | ||||
| 
 | ||||
| 	tipc_node_put(n); | ||||
| 
 | ||||
|  | @ -1788,7 +1830,7 @@ static void tipc_node_bc_rcv(struct net *net, struct sk_buff *skb, int bearer_id | |||
| 	} | ||||
| 
 | ||||
| 	if (!skb_queue_empty(&xmitq)) | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr, n); | ||||
| 
 | ||||
| 	if (!skb_queue_empty(&be->inputq1)) | ||||
| 		tipc_node_mcast_rcv(n); | ||||
|  | @ -1966,20 +2008,38 @@ static bool tipc_node_check_state(struct tipc_node *n, struct sk_buff *skb, | |||
| void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | ||||
| { | ||||
| 	struct sk_buff_head xmitq; | ||||
| 	struct tipc_node *n; | ||||
| 	struct tipc_msg *hdr; | ||||
| 	int bearer_id = b->identity; | ||||
| 	struct tipc_link_entry *le; | ||||
| 	struct tipc_msg *hdr; | ||||
| 	struct tipc_node *n; | ||||
| 	int bearer_id = b->identity; | ||||
| 	u32 self = tipc_own_addr(net); | ||||
| 	int usr, rc = 0; | ||||
| 	u16 bc_ack; | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	struct tipc_ehdr *ehdr; | ||||
| 
 | ||||
| 	__skb_queue_head_init(&xmitq); | ||||
| 	/* Check if message must be decrypted first */ | ||||
| 	if (TIPC_SKB_CB(skb)->decrypted || !tipc_ehdr_validate(skb)) | ||||
| 		goto rcv; | ||||
| 
 | ||||
| 	ehdr = (struct tipc_ehdr *)skb->data; | ||||
| 	if (likely(ehdr->user != LINK_CONFIG)) { | ||||
| 		n = tipc_node_find(net, ntohl(ehdr->addr)); | ||||
| 		if (unlikely(!n)) | ||||
| 			goto discard; | ||||
| 	} else { | ||||
| 		n = tipc_node_find_by_id(net, ehdr->id); | ||||
| 	} | ||||
| 	tipc_crypto_rcv(net, (n) ? n->crypto_rx : NULL, &skb, b); | ||||
| 	if (!skb) | ||||
| 		return; | ||||
| 
 | ||||
| rcv: | ||||
| #endif | ||||
| 	/* Ensure message is well-formed before touching the header */ | ||||
| 	TIPC_SKB_CB(skb)->validated = false; | ||||
| 	if (unlikely(!tipc_msg_validate(&skb))) | ||||
| 		goto discard; | ||||
| 	__skb_queue_head_init(&xmitq); | ||||
| 	hdr = buf_msg(skb); | ||||
| 	usr = msg_user(hdr); | ||||
| 	bc_ack = msg_bcast_ack(hdr); | ||||
|  | @ -2050,7 +2110,7 @@ void tipc_rcv(struct net *net, struct sk_buff *skb, struct tipc_bearer *b) | |||
| 		tipc_sk_rcv(net, &le->inputq); | ||||
| 
 | ||||
| 	if (!skb_queue_empty(&xmitq)) | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr); | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &le->maddr, n); | ||||
| 
 | ||||
| 	tipc_node_put(n); | ||||
| discard: | ||||
|  | @ -2081,7 +2141,7 @@ void tipc_node_apply_property(struct net *net, struct tipc_bearer *b, | |||
| 				tipc_link_set_mtu(e->link, b->mtu); | ||||
| 		} | ||||
| 		tipc_node_write_unlock(n); | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &e->maddr); | ||||
| 		tipc_bearer_xmit(net, bearer_id, &xmitq, &e->maddr, NULL); | ||||
| 	} | ||||
| 
 | ||||
| 	rcu_read_unlock(); | ||||
|  | @ -2323,7 +2383,8 @@ int tipc_nl_node_set_link(struct sk_buff *skb, struct genl_info *info) | |||
| 
 | ||||
| out: | ||||
| 	tipc_node_read_unlock(node); | ||||
| 	tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr); | ||||
| 	tipc_bearer_xmit(net, bearer_id, &xmitq, &node->links[bearer_id].maddr, | ||||
| 			 NULL); | ||||
| 	return res; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -76,6 +76,14 @@ void tipc_node_stop(struct net *net); | |||
| bool tipc_node_get_id(struct net *net, u32 addr, u8 *id); | ||||
| u32 tipc_node_get_addr(struct tipc_node *node); | ||||
| char *tipc_node_get_id_str(struct tipc_node *node); | ||||
| void tipc_node_put(struct tipc_node *node); | ||||
| struct tipc_node *tipc_node_create(struct net *net, u32 addr, u8 *peer_id, | ||||
| 				   u16 capabilities, u32 hash_mixes, | ||||
| 				   bool preliminary); | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| struct tipc_crypto *tipc_node_crypto_rx(struct tipc_node *__n); | ||||
| struct tipc_crypto *tipc_node_crypto_rx_by_list(struct list_head *pos); | ||||
| #endif | ||||
| u32 tipc_node_try_addr(struct net *net, u8 *id, u32 addr); | ||||
| void tipc_node_check_dest(struct net *net, u32 onode, u8 *peer_id128, | ||||
| 			  struct tipc_bearer *bearer, | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ | |||
| 
 | ||||
| #include "core.h" | ||||
| #include "trace.h" | ||||
| #include "crypto.h" | ||||
| 
 | ||||
| #include <linux/sysctl.h> | ||||
| 
 | ||||
|  | @ -64,6 +65,16 @@ static struct ctl_table tipc_table[] = { | |||
| 		.mode           = 0644, | ||||
| 		.proc_handler   = proc_doulongvec_minmax, | ||||
| 	}, | ||||
| #ifdef CONFIG_TIPC_CRYPTO | ||||
| 	{ | ||||
| 		.procname	= "max_tfms", | ||||
| 		.data		= &sysctl_tipc_max_tfms, | ||||
| 		.maxlen		= sizeof(sysctl_tipc_max_tfms), | ||||
| 		.mode		= 0644, | ||||
| 		.proc_handler	= proc_dointvec_minmax, | ||||
| 		.extra1         = SYSCTL_ONE, | ||||
| 	}, | ||||
| #endif | ||||
| 	{} | ||||
| }; | ||||
| 
 | ||||
|  |  | |||
|  | @ -372,6 +372,7 @@ static int tipc_udp_recv(struct sock *sk, struct sk_buff *skb) | |||
| 		goto out; | ||||
| 
 | ||||
| 	if (b && test_bit(0, &b->up)) { | ||||
| 		TIPC_SKB_CB(skb)->flags = 0; | ||||
| 		tipc_rcv(sock_net(sk), skb, b); | ||||
| 		return 0; | ||||
| 	} | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Tuong Lien
						Tuong Lien