@@ -525,9 +525,6 @@ static void ip_copy_metadata(struct sk_buff *to, struct sk_buff *from)
525
525
526
526
skb_copy_hash (to , from );
527
527
528
- /* Copy the flags to each fragment. */
529
- IPCB (to )-> flags = IPCB (from )-> flags ;
530
-
531
528
#ifdef CONFIG_NET_SCHED
532
529
to -> tc_index = from -> tc_index ;
533
530
#endif
@@ -582,6 +579,18 @@ void ip_fraglist_init(struct sk_buff *skb, struct iphdr *iph,
582
579
}
583
580
EXPORT_SYMBOL (ip_fraglist_init );
584
581
582
+ static void ip_fraglist_ipcb_prepare (struct sk_buff * skb ,
583
+ struct ip_fraglist_iter * iter )
584
+ {
585
+ struct sk_buff * to = iter -> frag ;
586
+
587
+ /* Copy the flags to each fragment. */
588
+ IPCB (to )-> flags = IPCB (skb )-> flags ;
589
+
590
+ if (iter -> offset == 0 )
591
+ ip_options_fragment (to );
592
+ }
593
+
585
594
void ip_fraglist_prepare (struct sk_buff * skb , struct ip_fraglist_iter * iter )
586
595
{
587
596
unsigned int hlen = iter -> hlen ;
@@ -598,8 +607,6 @@ void ip_fraglist_prepare(struct sk_buff *skb, struct ip_fraglist_iter *iter)
598
607
iph = iter -> iph ;
599
608
iph -> tot_len = htons (frag -> len );
600
609
ip_copy_metadata (frag , skb );
601
- if (iter -> offset == 0 )
602
- ip_options_fragment (frag );
603
610
iter -> offset += skb -> len - hlen ;
604
611
iph -> frag_off = htons (iter -> offset >> 3 );
605
612
if (frag -> next )
@@ -627,6 +634,25 @@ void ip_frag_init(struct sk_buff *skb, unsigned int hlen,
627
634
}
628
635
EXPORT_SYMBOL (ip_frag_init );
629
636
637
+ static void ip_frag_ipcb (struct sk_buff * from , struct sk_buff * to ,
638
+ bool first_frag , struct ip_frag_state * state )
639
+ {
640
+ /* Copy the flags to each fragment. */
641
+ IPCB (to )-> flags = IPCB (from )-> flags ;
642
+
643
+ if (IPCB (from )-> flags & IPSKB_FRAG_PMTU )
644
+ state -> iph -> frag_off |= htons (IP_DF );
645
+
646
+ /* ANK: dirty, but effective trick. Upgrade options only if
647
+ * the segment to be fragmented was THE FIRST (otherwise,
648
+ * options are already fixed) and make it ONCE
649
+ * on the initial skb, so that all the following fragments
650
+ * will inherit fixed options.
651
+ */
652
+ if (first_frag )
653
+ ip_options_fragment (from );
654
+ }
655
+
630
656
struct sk_buff * ip_frag_next (struct sk_buff * skb , struct ip_frag_state * state )
631
657
{
632
658
unsigned int len = state -> left ;
@@ -685,18 +711,6 @@ struct sk_buff *ip_frag_next(struct sk_buff *skb, struct ip_frag_state *state)
685
711
iph = ip_hdr (skb2 );
686
712
iph -> frag_off = htons ((state -> offset >> 3 ));
687
713
688
- if (IPCB (skb )-> flags & IPSKB_FRAG_PMTU )
689
- iph -> frag_off |= htons (IP_DF );
690
-
691
- /* ANK: dirty, but effective trick. Upgrade options only if
692
- * the segment to be fragmented was THE FIRST (otherwise,
693
- * options are already fixed) and make it ONCE
694
- * on the initial skb, so that all the following fragments
695
- * will inherit fixed options.
696
- */
697
- if (state -> offset == 0 )
698
- ip_options_fragment (skb );
699
-
700
714
/*
701
715
* Added AC : If we are fragmenting a fragment that's not the
702
716
* last fragment then keep MF on each bit
@@ -799,8 +813,10 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
799
813
for (;;) {
800
814
/* Prepare header of the next frame,
801
815
* before previous one went down. */
802
- if (iter .frag )
816
+ if (iter .frag ) {
817
+ ip_fraglist_ipcb_prepare (skb , & iter );
803
818
ip_fraglist_prepare (skb , & iter );
819
+ }
804
820
805
821
err = output (net , sk , skb );
806
822
@@ -844,11 +860,14 @@ int ip_do_fragment(struct net *net, struct sock *sk, struct sk_buff *skb,
844
860
*/
845
861
846
862
while (state .left > 0 ) {
863
+ bool first_frag = (state .offset == 0 );
864
+
847
865
skb2 = ip_frag_next (skb , & state );
848
866
if (IS_ERR (skb2 )) {
849
867
err = PTR_ERR (skb2 );
850
868
goto fail ;
851
869
}
870
+ ip_frag_ipcb (skb , skb2 , first_frag , & state );
852
871
853
872
/*
854
873
* Put this fragment into the sending queue.
0 commit comments