hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/ipv6/ip6_gre.c
....@@ -1,13 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * GRE over IPv6 protocol decoder.
34 *
45 * Authors: Dmitry Kozlov (xeb@mail.ru)
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License
8
- * as published by the Free Software Foundation; either version
9
- * 2 of the License, or (at your option) any later version.
10
- *
116 */
127
138 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -425,59 +420,42 @@
425420 }
426421
427422
428
-static void ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
423
+static int ip6gre_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
429424 u8 type, u8 code, int offset, __be32 info)
430425 {
431426 struct net *net = dev_net(skb->dev);
432
- const struct gre_base_hdr *greh;
433427 const struct ipv6hdr *ipv6h;
434
- int grehlen = sizeof(*greh);
428
+ struct tnl_ptk_info tpi;
435429 struct ip6_tnl *t;
436
- int key_off = 0;
437
- __be16 flags;
438
- __be32 key;
439430
440
- if (!pskb_may_pull(skb, offset + grehlen))
441
- return;
442
- greh = (const struct gre_base_hdr *)(skb->data + offset);
443
- flags = greh->flags;
444
- if (flags & (GRE_VERSION | GRE_ROUTING))
445
- return;
446
- if (flags & GRE_CSUM)
447
- grehlen += 4;
448
- if (flags & GRE_KEY) {
449
- key_off = grehlen + offset;
450
- grehlen += 4;
451
- }
431
+ if (gre_parse_header(skb, &tpi, NULL, htons(ETH_P_IPV6),
432
+ offset) < 0)
433
+ return -EINVAL;
452434
453
- if (!pskb_may_pull(skb, offset + grehlen))
454
- return;
455435 ipv6h = (const struct ipv6hdr *)skb->data;
456
- greh = (const struct gre_base_hdr *)(skb->data + offset);
457
- key = key_off ? *(__be32 *)(skb->data + key_off) : 0;
458
-
459436 t = ip6gre_tunnel_lookup(skb->dev, &ipv6h->daddr, &ipv6h->saddr,
460
- key, greh->protocol);
437
+ tpi.key, tpi.proto);
461438 if (!t)
462
- return;
439
+ return -ENOENT;
463440
464441 switch (type) {
465
- struct ipv6_tlv_tnl_enc_lim *tel;
466
- __u32 teli;
467442 case ICMPV6_DEST_UNREACH:
468443 net_dbg_ratelimited("%s: Path to destination invalid or inactive!\n",
469444 t->parms.name);
470445 if (code != ICMPV6_PORT_UNREACH)
471446 break;
472
- return;
447
+ return 0;
473448 case ICMPV6_TIME_EXCEED:
474449 if (code == ICMPV6_EXC_HOPLIMIT) {
475450 net_dbg_ratelimited("%s: Too small hop limit or routing loop in tunnel!\n",
476451 t->parms.name);
477452 break;
478453 }
479
- return;
480
- case ICMPV6_PARAMPROB:
454
+ return 0;
455
+ case ICMPV6_PARAMPROB: {
456
+ struct ipv6_tlv_tnl_enc_lim *tel;
457
+ __u32 teli;
458
+
481459 teli = 0;
482460 if (code == ICMPV6_HDR_FIELD)
483461 teli = ip6_tnl_parse_tlv_enc_lim(skb, skb->data);
....@@ -492,14 +470,15 @@
492470 net_dbg_ratelimited("%s: Recipient unable to parse tunneled packet!\n",
493471 t->parms.name);
494472 }
495
- return;
473
+ return 0;
474
+ }
496475 case ICMPV6_PKT_TOOBIG:
497476 ip6_update_pmtu(skb, net, info, 0, 0, sock_net_uid(net, NULL));
498
- return;
477
+ return 0;
499478 case NDISC_REDIRECT:
500479 ip6_redirect(skb, net, skb->dev->ifindex, 0,
501480 sock_net_uid(net, NULL));
502
- return;
481
+ return 0;
503482 }
504483
505484 if (time_before(jiffies, t->err_time + IP6TUNNEL_ERR_TIMEO))
....@@ -507,6 +486,8 @@
507486 else
508487 t->err_count = 1;
509488 t->err_time = jiffies;
489
+
490
+ return 0;
510491 }
511492
512493 static int ip6gre_rcv(struct sk_buff *skb, const struct tnl_ptk_info *tpi)
....@@ -542,7 +523,8 @@
542523 return PACKET_REJECT;
543524 }
544525
545
-static int ip6erspan_rcv(struct sk_buff *skb, struct tnl_ptk_info *tpi,
526
+static int ip6erspan_rcv(struct sk_buff *skb,
527
+ struct tnl_ptk_info *tpi,
546528 int gre_hdr_len)
547529 {
548530 struct erspan_base_hdr *ershdr;
....@@ -695,8 +677,8 @@
695677
696678 tel = (struct ipv6_tlv_tnl_enc_lim *)&skb_network_header(skb)[offset];
697679 if (tel->encap_limit == 0) {
698
- icmpv6_send(skb, ICMPV6_PARAMPROB,
699
- ICMPV6_HDR_FIELD, offset + 2);
680
+ icmpv6_ndo_send(skb, ICMPV6_PARAMPROB,
681
+ ICMPV6_HDR_FIELD, offset + 2);
700682 return -1;
701683 }
702684 *encap_limit = tel->encap_limit - 1;
....@@ -724,6 +706,17 @@
724706 return 0;
725707 }
726708
709
+static struct ip_tunnel_info *skb_tunnel_info_txcheck(struct sk_buff *skb)
710
+{
711
+ struct ip_tunnel_info *tun_info;
712
+
713
+ tun_info = skb_tunnel_info(skb);
714
+ if (unlikely(!tun_info || !(tun_info->mode & IP_TUNNEL_INFO_TX)))
715
+ return ERR_PTR(-EINVAL);
716
+
717
+ return tun_info;
718
+}
719
+
727720 static netdev_tx_t __gre6_xmit(struct sk_buff *skb,
728721 struct net_device *dev, __u8 dsfield,
729722 struct flowi6 *fl6, int encap_limit,
....@@ -731,6 +724,7 @@
731724 {
732725 struct ip6_tnl *tunnel = netdev_priv(dev);
733726 __be16 protocol;
727
+ __be16 flags;
734728
735729 if (dev->type == ARPHRD_ETHER)
736730 IPCB(skb)->flags = 0;
....@@ -740,21 +734,17 @@
740734 else
741735 fl6->daddr = tunnel->parms.raddr;
742736
743
- if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen))
744
- return -ENOMEM;
745
-
746737 /* Push GRE header. */
747738 protocol = (dev->type == ARPHRD_ETHER) ? htons(ETH_P_TEB) : proto;
748739
749740 if (tunnel->parms.collect_md) {
750741 struct ip_tunnel_info *tun_info;
751742 const struct ip_tunnel_key *key;
752
- __be16 flags;
743
+ int tun_hlen;
753744
754
- tun_info = skb_tunnel_info(skb);
755
- if (unlikely(!tun_info ||
756
- !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
757
- ip_tunnel_info_af(tun_info) != AF_INET6))
745
+ tun_info = skb_tunnel_info_txcheck(skb);
746
+ if (IS_ERR(tun_info) ||
747
+ unlikely(ip_tunnel_info_af(tun_info) != AF_INET6))
758748 return -EINVAL;
759749
760750 key = &tun_info->key;
....@@ -763,25 +753,32 @@
763753 fl6->daddr = key->u.ipv6.dst;
764754 fl6->flowlabel = key->label;
765755 fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL);
756
+ fl6->fl6_gre_key = tunnel_id_to_key32(key->tun_id);
766757
767758 dsfield = key->tos;
768759 flags = key->tun_flags &
769760 (TUNNEL_CSUM | TUNNEL_KEY | TUNNEL_SEQ);
770
- tunnel->tun_hlen = gre_calc_hlen(flags);
761
+ tun_hlen = gre_calc_hlen(flags);
771762
772
- gre_build_header(skb, tunnel->tun_hlen,
763
+ if (skb_cow_head(skb, dev->needed_headroom ?: tun_hlen + tunnel->encap_hlen))
764
+ return -ENOMEM;
765
+
766
+ gre_build_header(skb, tun_hlen,
773767 flags, protocol,
774768 tunnel_id_to_key32(tun_info->key.tun_id),
775
- (flags & TUNNEL_SEQ) ? htonl(tunnel->o_seqno++)
769
+ (flags & TUNNEL_SEQ) ? htonl(atomic_fetch_inc(&tunnel->o_seqno))
776770 : 0);
777771
778772 } else {
779
- if (tunnel->parms.o_flags & TUNNEL_SEQ)
780
- tunnel->o_seqno++;
773
+ if (skb_cow_head(skb, dev->needed_headroom ?: tunnel->hlen))
774
+ return -ENOMEM;
781775
782
- gre_build_header(skb, tunnel->tun_hlen, tunnel->parms.o_flags,
776
+ flags = tunnel->parms.o_flags;
777
+
778
+ gre_build_header(skb, tunnel->tun_hlen, flags,
783779 protocol, tunnel->parms.o_key,
784
- htonl(tunnel->o_seqno));
780
+ (flags & TUNNEL_SEQ) ? htonl(atomic_fetch_inc(&tunnel->o_seqno))
781
+ : 0);
785782 }
786783
787784 return ip6_tnl_xmit(skb, dev, dsfield, fl6, encap_limit, pmtu,
....@@ -812,8 +809,8 @@
812809 if (err != 0) {
813810 /* XXX: send ICMP error even if DF is not set. */
814811 if (err == -EMSGSIZE)
815
- icmp_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
816
- htonl(mtu));
812
+ icmp_ndo_send(skb, ICMP_DEST_UNREACH, ICMP_FRAG_NEEDED,
813
+ htonl(mtu));
817814 return -1;
818815 }
819816
....@@ -844,7 +841,7 @@
844841 &mtu, skb->protocol);
845842 if (err != 0) {
846843 if (err == -EMSGSIZE)
847
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
844
+ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
848845 return -1;
849846 }
850847
....@@ -925,7 +922,8 @@
925922 return NETDEV_TX_OK;
926923
927924 tx_err:
928
- stats->tx_errors++;
925
+ if (!t->parms.collect_md || !IS_ERR(skb_tunnel_info_txcheck(skb)))
926
+ stats->tx_errors++;
929927 stats->tx_dropped++;
930928 kfree_skb(skb);
931929 return NETDEV_TX_OK;
....@@ -934,6 +932,7 @@
934932 static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb,
935933 struct net_device *dev)
936934 {
935
+ struct ip_tunnel_info *tun_info = NULL;
937936 struct ip6_tnl *t = netdev_priv(dev);
938937 struct dst_entry *dst = skb_dst(skb);
939938 struct net_device_stats *stats;
....@@ -945,7 +944,6 @@
945944 __be16 proto;
946945 __u32 mtu;
947946 int nhoff;
948
- int thoff;
949947
950948 if (!pskb_inet_may_pull(skb))
951949 goto tx_err;
....@@ -957,19 +955,26 @@
957955 goto tx_err;
958956
959957 if (skb->len > dev->mtu + dev->hard_header_len) {
960
- pskb_trim(skb, dev->mtu + dev->hard_header_len);
958
+ if (pskb_trim(skb, dev->mtu + dev->hard_header_len))
959
+ goto tx_err;
961960 truncate = true;
962961 }
963962
964
- nhoff = skb_network_header(skb) - skb_mac_header(skb);
963
+ nhoff = skb_network_offset(skb);
965964 if (skb->protocol == htons(ETH_P_IP) &&
966965 (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
967966 truncate = true;
968967
969
- thoff = skb_transport_header(skb) - skb_mac_header(skb);
970
- if (skb->protocol == htons(ETH_P_IPV6) &&
971
- (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff))
972
- truncate = true;
968
+ if (skb->protocol == htons(ETH_P_IPV6)) {
969
+ int thoff;
970
+
971
+ if (skb_transport_header_was_set(skb))
972
+ thoff = skb_transport_offset(skb);
973
+ else
974
+ thoff = nhoff + sizeof(struct ipv6hdr);
975
+ if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
976
+ truncate = true;
977
+ }
973978
974979 if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen))
975980 goto tx_err;
....@@ -981,15 +986,13 @@
981986 * for native mode, call prepare_ip6gre_xmit_{ipv4,ipv6}.
982987 */
983988 if (t->parms.collect_md) {
984
- struct ip_tunnel_info *tun_info;
985989 const struct ip_tunnel_key *key;
986990 struct erspan_metadata *md;
987991 __be32 tun_id;
988992
989
- tun_info = skb_tunnel_info(skb);
990
- if (unlikely(!tun_info ||
991
- !(tun_info->mode & IP_TUNNEL_INFO_TX) ||
992
- ip_tunnel_info_af(tun_info) != AF_INET6))
993
+ tun_info = skb_tunnel_info_txcheck(skb);
994
+ if (IS_ERR(tun_info) ||
995
+ unlikely(ip_tunnel_info_af(tun_info) != AF_INET6))
993996 goto tx_err;
994997
995998 key = &tun_info->key;
....@@ -998,6 +1001,7 @@
9981001 fl6.daddr = key->u.ipv6.dst;
9991002 fl6.flowlabel = key->label;
10001003 fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
1004
+ fl6.fl6_gre_key = tunnel_id_to_key32(key->tun_id);
10011005
10021006 dsfield = key->tos;
10031007 if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
....@@ -1012,12 +1016,14 @@
10121016 ntohl(tun_id),
10131017 ntohl(md->u.index), truncate,
10141018 false);
1019
+ proto = htons(ETH_P_ERSPAN);
10151020 } else if (md->version == 2) {
10161021 erspan_build_header_v2(skb,
10171022 ntohl(tun_id),
10181023 md->u.md2.dir,
10191024 get_hwid(&md->u.md2),
10201025 truncate, false);
1026
+ proto = htons(ETH_P_ERSPAN2);
10211027 } else {
10221028 goto tx_err;
10231029 }
....@@ -1040,25 +1046,26 @@
10401046 break;
10411047 }
10421048
1043
- if (t->parms.erspan_ver == 1)
1049
+ if (t->parms.erspan_ver == 1) {
10441050 erspan_build_header(skb, ntohl(t->parms.o_key),
10451051 t->parms.index,
10461052 truncate, false);
1047
- else if (t->parms.erspan_ver == 2)
1053
+ proto = htons(ETH_P_ERSPAN);
1054
+ } else if (t->parms.erspan_ver == 2) {
10481055 erspan_build_header_v2(skb, ntohl(t->parms.o_key),
10491056 t->parms.dir,
10501057 t->parms.hwid,
10511058 truncate, false);
1052
- else
1059
+ proto = htons(ETH_P_ERSPAN2);
1060
+ } else {
10531061 goto tx_err;
1062
+ }
10541063
10551064 fl6.daddr = t->parms.raddr;
10561065 }
10571066
10581067 /* Push GRE header. */
1059
- proto = (t->parms.erspan_ver == 1) ? htons(ETH_P_ERSPAN)
1060
- : htons(ETH_P_ERSPAN2);
1061
- gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(t->o_seqno++));
1068
+ gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(atomic_fetch_inc(&t->o_seqno)));
10621069
10631070 /* TooBig packet may have updated dst->dev's mtu */
10641071 if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu)
....@@ -1070,10 +1077,10 @@
10701077 /* XXX: send ICMP error even if DF is not set. */
10711078 if (err == -EMSGSIZE) {
10721079 if (skb->protocol == htons(ETH_P_IP))
1073
- icmp_send(skb, ICMP_DEST_UNREACH,
1074
- ICMP_FRAG_NEEDED, htonl(mtu));
1080
+ icmp_ndo_send(skb, ICMP_DEST_UNREACH,
1081
+ ICMP_FRAG_NEEDED, htonl(mtu));
10751082 else
1076
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
1083
+ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
10771084 }
10781085
10791086 goto tx_err;
....@@ -1082,7 +1089,8 @@
10821089
10831090 tx_err:
10841091 stats = &t->dev->stats;
1085
- stats->tx_errors++;
1092
+ if (!IS_ERR(tun_info))
1093
+ stats->tx_errors++;
10861094 stats->tx_dropped++;
10871095 kfree_skb(skb);
10881096 return NETDEV_TX_OK;
....@@ -1105,6 +1113,7 @@
11051113 fl6->flowi6_oif = p->link;
11061114 fl6->flowlabel = 0;
11071115 fl6->flowi6_proto = IPPROTO_GRE;
1116
+ fl6->fl6_gre_key = t->parms.o_key;
11081117
11091118 if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
11101119 fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
....@@ -1148,14 +1157,16 @@
11481157 dev->needed_headroom = dst_len;
11491158
11501159 if (set_mtu) {
1151
- dev->mtu = rt->dst.dev->mtu - t_hlen;
1152
- if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1153
- dev->mtu -= 8;
1154
- if (dev->type == ARPHRD_ETHER)
1155
- dev->mtu -= ETH_HLEN;
1160
+ int mtu = rt->dst.dev->mtu - t_hlen;
11561161
1157
- if (dev->mtu < IPV6_MIN_MTU)
1158
- dev->mtu = IPV6_MIN_MTU;
1162
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1163
+ mtu -= 8;
1164
+ if (dev->type == ARPHRD_ETHER)
1165
+ mtu -= ETH_HLEN;
1166
+
1167
+ if (mtu < IPV6_MIN_MTU)
1168
+ mtu = IPV6_MIN_MTU;
1169
+ WRITE_ONCE(dev->mtu, mtu);
11591170 }
11601171 }
11611172 ip6_rt_put(rt);
....@@ -1550,7 +1561,7 @@
15501561 static struct inet6_protocol ip6gre_protocol __read_mostly = {
15511562 .handler = gre_rcv,
15521563 .err_handler = ip6gre_err,
1553
- .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1564
+ .flags = INET6_PROTO_FINAL,
15541565 };
15551566
15561567 static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
....@@ -1931,12 +1942,6 @@
19311942 netif_keep_dst(dev);
19321943 }
19331944
1934
-bool is_ip6gretap_dev(const struct net_device *dev)
1935
-{
1936
- return dev->netdev_ops == &ip6gre_tap_netdev_ops;
1937
-}
1938
-EXPORT_SYMBOL_GPL(is_ip6gretap_dev);
1939
-
19401945 static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
19411946 struct ip_tunnel_encap *ipencap)
19421947 {
....@@ -2205,8 +2210,8 @@
22052210 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
22062211 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
22072212 [IFLA_GRE_OKEY] = { .type = NLA_U32 },
2208
- [IFLA_GRE_LOCAL] = { .len = FIELD_SIZEOF(struct ipv6hdr, saddr) },
2209
- [IFLA_GRE_REMOTE] = { .len = FIELD_SIZEOF(struct ipv6hdr, daddr) },
2213
+ [IFLA_GRE_LOCAL] = { .len = sizeof_field(struct ipv6hdr, saddr) },
2214
+ [IFLA_GRE_REMOTE] = { .len = sizeof_field(struct ipv6hdr, daddr) },
22102215 [IFLA_GRE_TTL] = { .type = NLA_U8 },
22112216 [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
22122217 [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 },