diff --git a/src/core/ipv4/ip4_frag.c b/src/core/ipv4/ip4_frag.c index 75599791..3c0d3c15 100644 --- a/src/core/ipv4/ip4_frag.c +++ b/src/core/ipv4/ip4_frag.c @@ -752,6 +752,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) int last; u16_t poff = IP_HLEN; u16_t tmp; + int mf_set; original_iphdr = (struct ip_hdr *)p->payload; iphdr = original_iphdr; @@ -764,7 +765,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) /* Save original offset */ tmp = lwip_ntohs(IPH_OFFSET(iphdr)); ofo = tmp & IP_OFFMASK; - LWIP_ERROR("ip_frag(): MF already set", (tmp & IP_MF) == 0, return ERR_VAL); + /* already fragmented? if so, the last fragment we create must have MF, too */ + mf_set = tmp & IP_MF; left = (u16_t)(p->tot_len - IP_HLEN); @@ -850,7 +852,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) /* Set new offset and MF flag */ tmp = (IP_OFFMASK & (ofo)); - if (!last) { + if (!last || mf_set) { + /* the last fragment has MF set if the input frame had it */ tmp = tmp | IP_MF; } IPH_OFFSET_SET(iphdr, lwip_htons(tmp));