Skip to content

Commit c3ef5aa

Browse files
pshelardavem330
authored andcommitted
geneve: Merge ipv4 and ipv6 geneve_build_skb()
There are minimal difference in building Geneve header between ipv4 and ipv6 geneve tunnels. Following patch refactors code to unify it. Signed-off-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 9b4437a commit c3ef5aa

File tree

1 file changed

+26
-74
lines changed

1 file changed

+26
-74
lines changed

drivers/net/geneve.c

Lines changed: 26 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -630,67 +630,34 @@ static int geneve_stop(struct net_device *dev)
630630
}
631631

632632
static void geneve_build_header(struct genevehdr *geneveh,
633-
__be16 tun_flags, u8 vni[3],
634-
u8 options_len, u8 *options)
633+
const struct ip_tunnel_info *info)
635634
{
636635
geneveh->ver = GENEVE_VER;
637-
geneveh->opt_len = options_len / 4;
638-
geneveh->oam = !!(tun_flags & TUNNEL_OAM);
639-
geneveh->critical = !!(tun_flags & TUNNEL_CRIT_OPT);
636+
geneveh->opt_len = info->options_len / 4;
637+
geneveh->oam = !!(info->key.tun_flags & TUNNEL_OAM);
638+
geneveh->critical = !!(info->key.tun_flags & TUNNEL_CRIT_OPT);
640639
geneveh->rsvd1 = 0;
641-
memcpy(geneveh->vni, vni, 3);
640+
tunnel_id_to_vni(info->key.tun_id, geneveh->vni);
642641
geneveh->proto_type = htons(ETH_P_TEB);
643642
geneveh->rsvd2 = 0;
644643

645-
memcpy(geneveh->options, options, options_len);
644+
ip_tunnel_info_opts_get(geneveh->options, info);
646645
}
647646

648-
static int geneve_build_skb(struct rtable *rt, struct sk_buff *skb,
649-
__be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
650-
bool xnet)
651-
{
652-
bool udp_sum = !!(tun_flags & TUNNEL_CSUM);
653-
struct genevehdr *gnvh;
654-
int min_headroom;
655-
int err;
656-
657-
skb_scrub_packet(skb, xnet);
658-
659-
min_headroom = LL_RESERVED_SPACE(rt->dst.dev) + rt->dst.header_len
660-
+ GENEVE_BASE_HLEN + opt_len + sizeof(struct iphdr);
661-
err = skb_cow_head(skb, min_headroom);
662-
if (unlikely(err))
663-
goto free_rt;
664-
665-
err = udp_tunnel_handle_offloads(skb, udp_sum);
666-
if (err)
667-
goto free_rt;
668-
669-
gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
670-
geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
671-
672-
skb_set_inner_protocol(skb, htons(ETH_P_TEB));
673-
return 0;
674-
675-
free_rt:
676-
ip_rt_put(rt);
677-
return err;
678-
}
679-
680-
#if IS_ENABLED(CONFIG_IPV6)
681-
static int geneve6_build_skb(struct dst_entry *dst, struct sk_buff *skb,
682-
__be16 tun_flags, u8 vni[3], u8 opt_len, u8 *opt,
683-
bool xnet)
647+
static int geneve_build_skb(struct dst_entry *dst, struct sk_buff *skb,
648+
const struct ip_tunnel_info *info,
649+
bool xnet, int ip_hdr_len)
684650
{
685-
bool udp_sum = !!(tun_flags & TUNNEL_CSUM);
651+
bool udp_sum = !!(info->key.tun_flags & TUNNEL_CSUM);
686652
struct genevehdr *gnvh;
687653
int min_headroom;
688654
int err;
689655

656+
skb_reset_mac_header(skb);
690657
skb_scrub_packet(skb, xnet);
691658

692-
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
693-
+ GENEVE_BASE_HLEN + opt_len + sizeof(struct ipv6hdr);
659+
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len +
660+
GENEVE_BASE_HLEN + info->options_len + ip_hdr_len;
694661
err = skb_cow_head(skb, min_headroom);
695662
if (unlikely(err))
696663
goto free_dst;
@@ -699,22 +666,21 @@ static int geneve6_build_skb(struct dst_entry *dst, struct sk_buff *skb,
699666
if (err)
700667
goto free_dst;
701668

702-
gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) + opt_len);
703-
geneve_build_header(gnvh, tun_flags, vni, opt_len, opt);
704-
669+
gnvh = (struct genevehdr *)__skb_push(skb, sizeof(*gnvh) +
670+
info->options_len);
671+
geneve_build_header(gnvh, info);
705672
skb_set_inner_protocol(skb, htons(ETH_P_TEB));
706673
return 0;
707674

708675
free_dst:
709676
dst_release(dst);
710677
return err;
711678
}
712-
#endif
713679

714680
static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
715681
struct net_device *dev,
716682
struct flowi4 *fl4,
717-
struct ip_tunnel_info *info)
683+
const struct ip_tunnel_info *info)
718684
{
719685
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
720686
struct geneve_dev *geneve = netdev_priv(dev);
@@ -738,7 +704,7 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
738704
}
739705
fl4->flowi4_tos = RT_TOS(tos);
740706

741-
dst_cache = &info->dst_cache;
707+
dst_cache = (struct dst_cache *)&info->dst_cache;
742708
if (use_cache) {
743709
rt = dst_cache_get_ip4(dst_cache, &fl4->saddr);
744710
if (rt)
@@ -763,7 +729,7 @@ static struct rtable *geneve_get_v4_rt(struct sk_buff *skb,
763729
static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
764730
struct net_device *dev,
765731
struct flowi6 *fl6,
766-
struct ip_tunnel_info *info)
732+
const struct ip_tunnel_info *info)
767733
{
768734
bool use_cache = ip_tunnel_dst_cache_usable(skb, info);
769735
struct geneve_dev *geneve = netdev_priv(dev);
@@ -789,7 +755,7 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
789755

790756
fl6->flowlabel = ip6_make_flowinfo(RT_TOS(prio),
791757
info->key.label);
792-
dst_cache = &info->dst_cache;
758+
dst_cache = (struct dst_cache *)&info->dst_cache;
793759
if (use_cache) {
794760
dst = dst_cache_get_ip6(dst_cache, &fl6->saddr);
795761
if (dst)
@@ -812,19 +778,18 @@ static struct dst_entry *geneve_get_v6_dst(struct sk_buff *skb,
812778
#endif
813779

814780
static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
815-
struct geneve_dev *geneve, struct ip_tunnel_info *info)
781+
struct geneve_dev *geneve,
782+
const struct ip_tunnel_info *info)
816783
{
817784
bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
818785
struct geneve_sock *gs4 = rcu_dereference(geneve->sock4);
819786
const struct ip_tunnel_key *key = &info->key;
820787
struct rtable *rt;
821788
int err = -EINVAL;
822789
struct flowi4 fl4;
823-
u8 *opts = NULL;
824790
__u8 tos, ttl;
825791
__be16 sport;
826792
__be16 df;
827-
u8 vni[3];
828793

829794
if (!gs4)
830795
return err;
@@ -843,13 +808,7 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
843808
}
844809
df = key->tun_flags & TUNNEL_DONT_FRAGMENT ? htons(IP_DF) : 0;
845810

846-
tunnel_id_to_vni(key->tun_id, vni);
847-
if (info->options_len)
848-
opts = ip_tunnel_info_opts(info);
849-
850-
skb_reset_mac_header(skb);
851-
err = geneve_build_skb(rt, skb, key->tun_flags, vni,
852-
info->options_len, opts, xnet);
811+
err = geneve_build_skb(&rt->dst, skb, info, xnet, sizeof(struct iphdr));
853812
if (unlikely(err))
854813
return err;
855814

@@ -862,18 +821,17 @@ static int geneve_xmit_skb(struct sk_buff *skb, struct net_device *dev,
862821

863822
#if IS_ENABLED(CONFIG_IPV6)
864823
static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
865-
struct geneve_dev *geneve, struct ip_tunnel_info *info)
824+
struct geneve_dev *geneve,
825+
const struct ip_tunnel_info *info)
866826
{
867827
bool xnet = !net_eq(geneve->net, dev_net(geneve->dev));
868828
struct geneve_sock *gs6 = rcu_dereference(geneve->sock6);
869829
const struct ip_tunnel_key *key = &info->key;
870830
struct dst_entry *dst = NULL;
871831
int err = -EINVAL;
872832
struct flowi6 fl6;
873-
u8 *opts = NULL;
874833
__u8 prio, ttl;
875834
__be16 sport;
876-
u8 vni[3];
877835

878836
if (!gs6)
879837
return err;
@@ -891,13 +849,7 @@ static int geneve6_xmit_skb(struct sk_buff *skb, struct net_device *dev,
891849
ip_hdr(skb), skb);
892850
ttl = key->ttl ? : ip6_dst_hoplimit(dst);
893851
}
894-
tunnel_id_to_vni(key->tun_id, vni);
895-
if (info->options_len)
896-
opts = ip_tunnel_info_opts(info);
897-
898-
skb_reset_mac_header(skb);
899-
err = geneve6_build_skb(dst, skb, key->tun_flags, vni,
900-
info->options_len, opts, xnet);
852+
err = geneve_build_skb(dst, skb, info, xnet, sizeof(struct iphdr));
901853
if (unlikely(err))
902854
return err;
903855

0 commit comments

Comments
 (0)