ip4_frag: correctly refragment packets that already have MF set

see patch #9645

Signed-off-by: Simon Goldschmidt <goldsimon@gmx.de>
This commit is contained in:
Simon Goldschmidt 2018-06-13 14:56:18 +02:00
parent 25497bb387
commit a75332a407

View File

@ -752,6 +752,7 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
int last; int last;
u16_t poff = IP_HLEN; u16_t poff = IP_HLEN;
u16_t tmp; u16_t tmp;
int mf_set;
original_iphdr = (struct ip_hdr *)p->payload; original_iphdr = (struct ip_hdr *)p->payload;
iphdr = original_iphdr; iphdr = original_iphdr;
@ -764,7 +765,8 @@ ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest)
/* Save original offset */ /* Save original offset */
tmp = lwip_ntohs(IPH_OFFSET(iphdr)); tmp = lwip_ntohs(IPH_OFFSET(iphdr));
ofo = tmp & IP_OFFMASK; 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); 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 */ /* Set new offset and MF flag */
tmp = (IP_OFFMASK & (ofo)); 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; tmp = tmp | IP_MF;
} }
IPH_OFFSET_SET(iphdr, lwip_htons(tmp)); IPH_OFFSET_SET(iphdr, lwip_htons(tmp));