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 <pa...@netfilter.org>
---
 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

Reply via email to