@@ -496,6 +496,78 @@ static int gre_handle_offloads(struct sk_buff *skb, bool csum)
496
496
csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE );
497
497
}
498
498
499
+ static void prepare_ip6gre_xmit_ipv4 (struct sk_buff * skb ,
500
+ struct net_device * dev ,
501
+ struct flowi6 * fl6 , __u8 * dsfield ,
502
+ int * encap_limit )
503
+ {
504
+ const struct iphdr * iph = ip_hdr (skb );
505
+ struct ip6_tnl * t = netdev_priv (dev );
506
+
507
+ if (!(t -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT ))
508
+ * encap_limit = t -> parms .encap_limit ;
509
+
510
+ memcpy (fl6 , & t -> fl .u .ip6 , sizeof (* fl6 ));
511
+
512
+ if (t -> parms .flags & IP6_TNL_F_USE_ORIG_TCLASS )
513
+ * dsfield = ipv4_get_dsfield (iph );
514
+ else
515
+ * dsfield = ip6_tclass (t -> parms .flowinfo );
516
+
517
+ if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FWMARK )
518
+ fl6 -> flowi6_mark = skb -> mark ;
519
+ else
520
+ fl6 -> flowi6_mark = t -> parms .fwmark ;
521
+
522
+ fl6 -> flowi6_uid = sock_net_uid (dev_net (dev ), NULL );
523
+ }
524
+
525
+ static int prepare_ip6gre_xmit_ipv6 (struct sk_buff * skb ,
526
+ struct net_device * dev ,
527
+ struct flowi6 * fl6 , __u8 * dsfield ,
528
+ int * encap_limit )
529
+ {
530
+ struct ipv6hdr * ipv6h = ipv6_hdr (skb );
531
+ struct ip6_tnl * t = netdev_priv (dev );
532
+ __u16 offset ;
533
+
534
+ offset = ip6_tnl_parse_tlv_enc_lim (skb , skb_network_header (skb ));
535
+ /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */
536
+
537
+ if (offset > 0 ) {
538
+ struct ipv6_tlv_tnl_enc_lim * tel ;
539
+
540
+ tel = (struct ipv6_tlv_tnl_enc_lim * )& skb_network_header (skb )[offset ];
541
+ if (tel -> encap_limit == 0 ) {
542
+ icmpv6_send (skb , ICMPV6_PARAMPROB ,
543
+ ICMPV6_HDR_FIELD , offset + 2 );
544
+ return -1 ;
545
+ }
546
+ * encap_limit = tel -> encap_limit - 1 ;
547
+ } else if (!(t -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT )) {
548
+ * encap_limit = t -> parms .encap_limit ;
549
+ }
550
+
551
+ memcpy (fl6 , & t -> fl .u .ip6 , sizeof (* fl6 ));
552
+
553
+ if (t -> parms .flags & IP6_TNL_F_USE_ORIG_TCLASS )
554
+ * dsfield = ipv6_get_dsfield (ipv6h );
555
+ else
556
+ * dsfield = ip6_tclass (t -> parms .flowinfo );
557
+
558
+ if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FLOWLABEL )
559
+ fl6 -> flowlabel |= ip6_flowlabel (ipv6h );
560
+
561
+ if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FWMARK )
562
+ fl6 -> flowi6_mark = skb -> mark ;
563
+ else
564
+ fl6 -> flowi6_mark = t -> parms .fwmark ;
565
+
566
+ fl6 -> flowi6_uid = sock_net_uid (dev_net (dev ), NULL );
567
+
568
+ return 0 ;
569
+ }
570
+
499
571
static netdev_tx_t __gre6_xmit (struct sk_buff * skb ,
500
572
struct net_device * dev , __u8 dsfield ,
501
573
struct flowi6 * fl6 , int encap_limit ,
@@ -527,7 +599,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
527
599
static inline int ip6gre_xmit_ipv4 (struct sk_buff * skb , struct net_device * dev )
528
600
{
529
601
struct ip6_tnl * t = netdev_priv (dev );
530
- const struct iphdr * iph = ip_hdr (skb );
531
602
int encap_limit = -1 ;
532
603
struct flowi6 fl6 ;
533
604
__u8 dsfield ;
@@ -536,21 +607,7 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
536
607
537
608
memset (& (IPCB (skb )-> opt ), 0 , sizeof (IPCB (skb )-> opt ));
538
609
539
- if (!(t -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT ))
540
- encap_limit = t -> parms .encap_limit ;
541
-
542
- memcpy (& fl6 , & t -> fl .u .ip6 , sizeof (fl6 ));
543
-
544
- if (t -> parms .flags & IP6_TNL_F_USE_ORIG_TCLASS )
545
- dsfield = ipv4_get_dsfield (iph );
546
- else
547
- dsfield = ip6_tclass (t -> parms .flowinfo );
548
- if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FWMARK )
549
- fl6 .flowi6_mark = skb -> mark ;
550
- else
551
- fl6 .flowi6_mark = t -> parms .fwmark ;
552
-
553
- fl6 .flowi6_uid = sock_net_uid (dev_net (dev ), NULL );
610
+ prepare_ip6gre_xmit_ipv4 (skb , dev , & fl6 , & dsfield , & encap_limit );
554
611
555
612
err = gre_handle_offloads (skb , !!(t -> parms .o_flags & TUNNEL_CSUM ));
556
613
if (err )
@@ -574,7 +631,6 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
574
631
struct ip6_tnl * t = netdev_priv (dev );
575
632
struct ipv6hdr * ipv6h = ipv6_hdr (skb );
576
633
int encap_limit = -1 ;
577
- __u16 offset ;
578
634
struct flowi6 fl6 ;
579
635
__u8 dsfield ;
580
636
__u32 mtu ;
@@ -583,37 +639,8 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
583
639
if (ipv6_addr_equal (& t -> parms .raddr , & ipv6h -> saddr ))
584
640
return -1 ;
585
641
586
- offset = ip6_tnl_parse_tlv_enc_lim (skb , skb_network_header (skb ));
587
- /* ip6_tnl_parse_tlv_enc_lim() might have reallocated skb->head */
588
- ipv6h = ipv6_hdr (skb );
589
-
590
- if (offset > 0 ) {
591
- struct ipv6_tlv_tnl_enc_lim * tel ;
592
- tel = (struct ipv6_tlv_tnl_enc_lim * )& skb_network_header (skb )[offset ];
593
- if (tel -> encap_limit == 0 ) {
594
- icmpv6_send (skb , ICMPV6_PARAMPROB ,
595
- ICMPV6_HDR_FIELD , offset + 2 );
596
- return -1 ;
597
- }
598
- encap_limit = tel -> encap_limit - 1 ;
599
- } else if (!(t -> parms .flags & IP6_TNL_F_IGN_ENCAP_LIMIT ))
600
- encap_limit = t -> parms .encap_limit ;
601
-
602
- memcpy (& fl6 , & t -> fl .u .ip6 , sizeof (fl6 ));
603
-
604
- if (t -> parms .flags & IP6_TNL_F_USE_ORIG_TCLASS )
605
- dsfield = ipv6_get_dsfield (ipv6h );
606
- else
607
- dsfield = ip6_tclass (t -> parms .flowinfo );
608
-
609
- if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FLOWLABEL )
610
- fl6 .flowlabel |= ip6_flowlabel (ipv6h );
611
- if (t -> parms .flags & IP6_TNL_F_USE_ORIG_FWMARK )
612
- fl6 .flowi6_mark = skb -> mark ;
613
- else
614
- fl6 .flowi6_mark = t -> parms .fwmark ;
615
-
616
- fl6 .flowi6_uid = sock_net_uid (dev_net (dev ), NULL );
642
+ if (prepare_ip6gre_xmit_ipv6 (skb , dev , & fl6 , & dsfield , & encap_limit ))
643
+ return -1 ;
617
644
618
645
if (gre_handle_offloads (skb , !!(t -> parms .o_flags & TUNNEL_CSUM )))
619
646
return -1 ;
0 commit comments