Skip to content

Commit 898b297

Browse files
williamtudavem330
authored andcommitted
ip6_gre: Refactor ip6gre xmit codes
This patch refactors the ip6gre_xmit_{ipv4, ipv6}. It is a prep work to add the ip6erspan tunnel. Signed-off-by: William Tu <u9012063@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent a3222dc commit 898b297

File tree

1 file changed

+75
-48
lines changed

1 file changed

+75
-48
lines changed

net/ipv6/ip6_gre.c

Lines changed: 75 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,78 @@ static int gre_handle_offloads(struct sk_buff *skb, bool csum)
496496
csum ? SKB_GSO_GRE_CSUM : SKB_GSO_GRE);
497497
}
498498

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+
499571
static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
500572
struct net_device *dev, __u8 dsfield,
501573
struct flowi6 *fl6, int encap_limit,
@@ -527,7 +599,6 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
527599
static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
528600
{
529601
struct ip6_tnl *t = netdev_priv(dev);
530-
const struct iphdr *iph = ip_hdr(skb);
531602
int encap_limit = -1;
532603
struct flowi6 fl6;
533604
__u8 dsfield;
@@ -536,21 +607,7 @@ static inline int ip6gre_xmit_ipv4(struct sk_buff *skb, struct net_device *dev)
536607

537608
memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
538609

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);
554611

555612
err = gre_handle_offloads(skb, !!(t->parms.o_flags & TUNNEL_CSUM));
556613
if (err)
@@ -574,7 +631,6 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
574631
struct ip6_tnl *t = netdev_priv(dev);
575632
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
576633
int encap_limit = -1;
577-
__u16 offset;
578634
struct flowi6 fl6;
579635
__u8 dsfield;
580636
__u32 mtu;
@@ -583,37 +639,8 @@ static inline int ip6gre_xmit_ipv6(struct sk_buff *skb, struct net_device *dev)
583639
if (ipv6_addr_equal(&t->parms.raddr, &ipv6h->saddr))
584640
return -1;
585641

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;
617644

618645
if (gre_handle_offloads(skb, !!(t->parms.o_flags & TUNNEL_CSUM)))
619646
return -1;

0 commit comments

Comments
 (0)