Deal with the IPCB() area away from the fraglist iterator. The bridge codebase has its own control buffer layout, move specific IP control buffer into function. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- net/ipv4/ip_output.c | 21 +++++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index 23cdeb2d004a..bf02c7d37acd 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c @@ -523,9 +523,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from) skb_copy_hash(to, from); - /* Copy the flags to each fragment. */ - IPCB(to)->flags = IPCB(from)->flags; - #ifdef CONFIG_NET_SCHED to->tc_index = from->tc_index; #endif @@ -580,6 +577,18 @@ void ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph, } EXPORT_SYMBOL(ip_fraglist_init); +static void ip_fraglist_ipcb_prepare(struct sk_buff *skb, + struct ip_fraglist_iter *iter) +{ + struct sk_buff *to = iter->frag; + + /* Copy the flags to each fragment. */ + IPCB(to)->flags = IPCB(skb)->flags; + + if (iter->offset == 0) + ip_options_fragment(to); +} + void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter) { unsigned int hlen = iter->hlen; @@ -596,8 +605,6 @@ void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter) iph = iter->iph; iph->tot_len = htons(frag->len); ip_copy_metadata(frag, skb); - if (iter->offset == 0) - ip_options_fragment(frag); iter->offset += skb->len - hlen; iph->frag_off = htons(iter->offset >> 3); if (frag->next) @@ -797,8 +804,10 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb, for (;;) { /* Prepare header of the next frame, * before previous one went down. */ - if (iter.frag) + if (iter.frag) { + ip_fraglist_ipcb_prepare(skb, &iter); ip_fraglist_prepare(skb, &iter); + } err = output(net, sk, skb); -- 2.11.0