diff options
Diffstat (limited to 'net/tipc')
| -rw-r--r-- | net/tipc/bearer.c | 17 | ||||
| -rw-r--r-- | net/tipc/bearer.h | 3 | ||||
| -rw-r--r-- | net/tipc/link.c | 9 | ||||
| -rw-r--r-- | net/tipc/socket.c | 4 | ||||
| -rw-r--r-- | net/tipc/udp_media.c | 5 | 
5 files changed, 29 insertions, 9 deletions
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 35cac7733fd3..53881406e200 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -541,6 +541,19 @@ int tipc_bearer_mtu(struct net *net, u32 bearer_id)  	return mtu;  } +int tipc_bearer_min_mtu(struct net *net, u32 bearer_id) +{ +	int mtu = TIPC_MIN_BEARER_MTU; +	struct tipc_bearer *b; + +	rcu_read_lock(); +	b = bearer_get(net, bearer_id); +	if (b) +		mtu += b->encap_hlen; +	rcu_read_unlock(); +	return mtu; +} +  /* tipc_bearer_xmit_skb - sends buffer to destination over bearer   */  void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id, @@ -1138,8 +1151,8 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info)  				return -EINVAL;  			}  #ifdef CONFIG_TIPC_MEDIA_UDP -			if (tipc_udp_mtu_bad(nla_get_u32 -					     (props[TIPC_NLA_PROP_MTU]))) { +			if (nla_get_u32(props[TIPC_NLA_PROP_MTU]) < +			    b->encap_hlen + TIPC_MIN_BEARER_MTU) {  				NL_SET_ERR_MSG(info->extack,  					       "MTU value is out-of-range");  				return -EINVAL; diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h index 490ad6e5f7a3..bd0cc5c287ef 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -146,6 +146,7 @@ struct tipc_media {   * @identity: array index of this bearer within TIPC bearer array   * @disc: ptr to link setup request   * @net_plane: network plane ('A' through 'H') currently associated with bearer + * @encap_hlen: encap headers length   * @up: bearer up flag (bit 0)   * @refcnt: tipc_bearer reference counter   * @@ -170,6 +171,7 @@ struct tipc_bearer {  	u32 identity;  	struct tipc_discoverer *disc;  	char net_plane; +	u16 encap_hlen;  	unsigned long up;  	refcount_t refcnt;  }; @@ -232,6 +234,7 @@ int tipc_bearer_setup(void);  void tipc_bearer_cleanup(void);  void tipc_bearer_stop(struct net *net);  int tipc_bearer_mtu(struct net *net, u32 bearer_id); +int tipc_bearer_min_mtu(struct net *net, u32 bearer_id);  bool tipc_bearer_bcast_support(struct net *net, u32 bearer_id);  void tipc_bearer_xmit_skb(struct net *net, u32 bearer_id,  			  struct sk_buff *skb, diff --git a/net/tipc/link.c b/net/tipc/link.c index b3ce24823f50..2eff1c7949cb 100644 --- a/net/tipc/link.c +++ b/net/tipc/link.c @@ -2200,7 +2200,7 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,  	struct tipc_msg *hdr = buf_msg(skb);  	struct tipc_gap_ack_blks *ga = NULL;  	bool reply = msg_probe(hdr), retransmitted = false; -	u32 dlen = msg_data_sz(hdr), glen = 0; +	u32 dlen = msg_data_sz(hdr), glen = 0, msg_max;  	u16 peers_snd_nxt =  msg_next_sent(hdr);  	u16 peers_tol = msg_link_tolerance(hdr);  	u16 peers_prio = msg_linkprio(hdr); @@ -2239,6 +2239,9 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,  	switch (mtyp) {  	case RESET_MSG:  	case ACTIVATE_MSG: +		msg_max = msg_max_pkt(hdr); +		if (msg_max < tipc_bearer_min_mtu(l->net, l->bearer_id)) +			break;  		/* Complete own link name with peer's interface name */  		if_name =  strrchr(l->name, ':') + 1;  		if (sizeof(l->name) - (if_name - l->name) <= TIPC_MAX_IF_NAME) @@ -2283,8 +2286,8 @@ static int tipc_link_proto_rcv(struct tipc_link *l, struct sk_buff *skb,  		l->peer_session = msg_session(hdr);  		l->in_session = true;  		l->peer_bearer_id = msg_bearer_id(hdr); -		if (l->mtu > msg_max_pkt(hdr)) -			l->mtu = msg_max_pkt(hdr); +		if (l->mtu > msg_max) +			l->mtu = msg_max;  		break;  	case STATE_MSG: diff --git a/net/tipc/socket.c b/net/tipc/socket.c index 37edfe10f8c6..dd73d71c02a9 100644 --- a/net/tipc/socket.c +++ b/net/tipc/socket.c @@ -314,9 +314,9 @@ static void tsk_rej_rx_queue(struct sock *sk, int error)  		tipc_sk_respond(sk, skb, error);  } -static bool tipc_sk_connected(struct sock *sk) +static bool tipc_sk_connected(const struct sock *sk)  { -	return sk->sk_state == TIPC_ESTABLISHED; +	return READ_ONCE(sk->sk_state) == TIPC_ESTABLISHED;  }  /* tipc_sk_type_connectionless - check if the socket is datagram socket diff --git a/net/tipc/udp_media.c b/net/tipc/udp_media.c index c2bb818704c8..0a85244fd618 100644 --- a/net/tipc/udp_media.c +++ b/net/tipc/udp_media.c @@ -738,8 +738,8 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,  			udp_conf.local_ip.s_addr = local.ipv4.s_addr;  		udp_conf.use_udp_checksums = false;  		ub->ifindex = dev->ifindex; -		if (tipc_mtu_bad(dev, sizeof(struct iphdr) + -				      sizeof(struct udphdr))) { +		b->encap_hlen = sizeof(struct iphdr) + sizeof(struct udphdr); +		if (tipc_mtu_bad(dev, b->encap_hlen)) {  			err = -EINVAL;  			goto err;  		} @@ -760,6 +760,7 @@ static int tipc_udp_enable(struct net *net, struct tipc_bearer *b,  		else  			udp_conf.local_ip6 = local.ipv6;  		ub->ifindex = dev->ifindex; +		b->encap_hlen = sizeof(struct ipv6hdr) + sizeof(struct udphdr);  		b->mtu = 1280;  #endif  	} else {  | 
