net: net_pkt_append: Take into account MTU when adding data to a packet

If we were asked to add 10KB to a packet, adding it won't help -
such packet won't be even sent by hardware on our side, and if
it is, it will be dropped by receiving side. So, make sure we
never add more data than MTU as set for the owning interface.
This actually gets a bit tricky, because we need also to account
for protocol header space. Typically, when net_pkt_append() is
called, protocol headers aren't even added to packet yet (they
are added in net_context_send() currently), so we have little
choice than to assume the standard header length, without any
extensions.

Signed-off-by: Paul Sokolovsky <paul.sokolovsky@linaro.org>
This commit is contained in:
Paul Sokolovsky 2017-05-03 23:48:28 +03:00 committed by Jukka Rissanen
parent 706ac7fe07
commit 4718dac560

View file

@ -1163,6 +1163,8 @@ u16_t net_pkt_append(struct net_pkt *pkt, u16_t len, const u8_t *data,
s32_t timeout)
{
struct net_buf *frag;
struct net_context *ctx;
size_t max_len;
if (!pkt || !data) {
return 0;
@ -1177,6 +1179,40 @@ u16_t net_pkt_append(struct net_pkt *pkt, u16_t len, const u8_t *data,
net_pkt_frag_add(pkt, frag);
}
/* Make sure we don't send more data in one packet than
* MTU allows.
* This check really belongs to net_pkt_append_bytes(),
* but instead done here for efficiency, we assume
* (at least for now) that that callers of
* net_pkt_append_bytes() are smart enough to not
* overflow MTU.
*/
max_len = 0x10000;
ctx = net_pkt_context(pkt);
if (ctx) {
#if defined(CONFIG_NET_TCP)
if (ctx->tcp) {
max_len = ctx->tcp->send_mss;
} else
#endif
{
struct net_if *iface = net_context_get_iface(ctx);
max_len = net_if_get_mtu(iface);
/* Optimize for number of jumps in the code ("if"
* instead of "if/else").
*/
max_len -= NET_IPV4TCPH_LEN;
if (net_context_get_family(ctx) != AF_INET) {
max_len -= NET_IPV6TCPH_LEN - NET_IPV4TCPH_LEN;
}
}
}
if (len > max_len) {
len = max_len;
}
return net_pkt_append_bytes(pkt, data, len, timeout);
}