diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c index 60a6f4a3c0fb..bad8a513d91c 100644 --- a/net/tipc/bearer.c +++ b/net/tipc/bearer.c @@ -579,9 +579,22 @@ int tipc_bearer_mtu(struct net *net, u32 bearer_id) return mtu; } +/* tipc_bearer_mtu_floor - smallest bearer MTU, excluding the media + * encapsulation header, that leaves room for a fragment header plus a + * full message header after the link MSS reductions (see tipc_link_mss()) + */ +u32 tipc_bearer_mtu_floor(void) +{ +#ifdef CONFIG_TIPC_CRYPTO + return TIPC_MIN_BEARER_MTU + EMSG_OVERHEAD; +#else + return TIPC_MIN_BEARER_MTU; +#endif +} + int tipc_bearer_min_mtu(struct net *net, u32 bearer_id) { - int mtu = TIPC_MIN_BEARER_MTU; + int mtu = tipc_bearer_mtu_floor(); struct tipc_bearer *b; rcu_read_lock(); @@ -1197,7 +1210,7 @@ int __tipc_nl_bearer_set(struct sk_buff *skb, struct genl_info *info) } #ifdef CONFIG_TIPC_MEDIA_UDP if (nla_get_u32(props[TIPC_NLA_PROP_MTU]) < - b->encap_hlen + TIPC_MIN_BEARER_MTU) { + b->encap_hlen + tipc_bearer_mtu_floor()) { 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 f9bfcc9a7765..72abfcac90cb 100644 --- a/net/tipc/bearer.h +++ b/net/tipc/bearer.h @@ -60,8 +60,10 @@ #define TIPC_MEDIA_TYPE_IB 2 #define TIPC_MEDIA_TYPE_UDP 3 -/* Minimum bearer MTU */ -#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + INT_H_SIZE) +/* Minimum bearer MTU, not counting the crypto overhead, see + * tipc_bearer_mtu_floor() + */ +#define TIPC_MIN_BEARER_MTU (MAX_H_SIZE + 2 * INT_H_SIZE) /* Maximum bearer MTU * @@ -241,6 +243,7 @@ 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); +u32 tipc_bearer_mtu_floor(void); 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, @@ -265,7 +268,7 @@ static inline void tipc_loopback_trace(struct net *net, /* check if device MTU is usable for tipc bearers */ static inline bool tipc_mtu_bad(struct net_device *dev) { - if (dev->mtu >= TIPC_MIN_BEARER_MTU && + if (dev->mtu >= tipc_bearer_mtu_floor() && dev->mtu <= TIPC_MAX_BEARER_MTU) return false; netdev_warn(dev, "MTU not usable for tipc bearer\n"); diff --git a/net/tipc/udp_media.h b/net/tipc/udp_media.h index e7455cc73e16..030e00ad1629 100644 --- a/net/tipc/udp_media.h +++ b/net/tipc/udp_media.h @@ -48,7 +48,7 @@ int tipc_udp_nl_dump_remoteip(struct sk_buff *skb, struct netlink_callback *cb); /* check if configured MTU is too low for tipc headers */ static inline bool tipc_udp_mtu_bad(u32 mtu) { - if (mtu >= (TIPC_MIN_BEARER_MTU + sizeof(struct iphdr) + + if (mtu >= (tipc_bearer_mtu_floor() + sizeof(struct iphdr) + sizeof(struct udphdr))) return false;