forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-08 01573e231f18eb2d99162747186f59511f56b64d
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;
....@@ -966,10 +964,16 @@
966964 (ntohs(ip_hdr(skb)->tot_len) > skb->len - nhoff))
967965 truncate = true;
968966
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;
967
+ if (skb->protocol == htons(ETH_P_IPV6)) {
968
+ int thoff;
969
+
970
+ if (skb_transport_header_was_set(skb))
971
+ thoff = skb_transport_header(skb) - skb_mac_header(skb);
972
+ else
973
+ thoff = nhoff + sizeof(struct ipv6hdr);
974
+ if (ntohs(ipv6_hdr(skb)->payload_len) > skb->len - thoff)
975
+ truncate = true;
976
+ }
973977
974978 if (skb_cow_head(skb, dev->needed_headroom ?: t->hlen))
975979 goto tx_err;
....@@ -981,15 +985,13 @@
981985 * for native mode, call prepare_ip6gre_xmit_{ipv4,ipv6}.
982986 */
983987 if (t->parms.collect_md) {
984
- struct ip_tunnel_info *tun_info;
985988 const struct ip_tunnel_key *key;
986989 struct erspan_metadata *md;
987990 __be32 tun_id;
988991
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))
992
+ tun_info = skb_tunnel_info_txcheck(skb);
993
+ if (IS_ERR(tun_info) ||
994
+ unlikely(ip_tunnel_info_af(tun_info) != AF_INET6))
993995 goto tx_err;
994996
995997 key = &tun_info->key;
....@@ -998,6 +1000,7 @@
9981000 fl6.daddr = key->u.ipv6.dst;
9991001 fl6.flowlabel = key->label;
10001002 fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL);
1003
+ fl6.fl6_gre_key = tunnel_id_to_key32(key->tun_id);
10011004
10021005 dsfield = key->tos;
10031006 if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT))
....@@ -1058,7 +1061,7 @@
10581061 /* Push GRE header. */
10591062 proto = (t->parms.erspan_ver == 1) ? htons(ETH_P_ERSPAN)
10601063 : htons(ETH_P_ERSPAN2);
1061
- gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(t->o_seqno++));
1064
+ gre_build_header(skb, 8, TUNNEL_SEQ, proto, 0, htonl(atomic_fetch_inc(&t->o_seqno)));
10621065
10631066 /* TooBig packet may have updated dst->dev's mtu */
10641067 if (!t->parms.collect_md && dst && dst_mtu(dst) > dst->dev->mtu)
....@@ -1070,10 +1073,10 @@
10701073 /* XXX: send ICMP error even if DF is not set. */
10711074 if (err == -EMSGSIZE) {
10721075 if (skb->protocol == htons(ETH_P_IP))
1073
- icmp_send(skb, ICMP_DEST_UNREACH,
1074
- ICMP_FRAG_NEEDED, htonl(mtu));
1076
+ icmp_ndo_send(skb, ICMP_DEST_UNREACH,
1077
+ ICMP_FRAG_NEEDED, htonl(mtu));
10751078 else
1076
- icmpv6_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
1079
+ icmpv6_ndo_send(skb, ICMPV6_PKT_TOOBIG, 0, mtu);
10771080 }
10781081
10791082 goto tx_err;
....@@ -1082,7 +1085,8 @@
10821085
10831086 tx_err:
10841087 stats = &t->dev->stats;
1085
- stats->tx_errors++;
1088
+ if (!IS_ERR(tun_info))
1089
+ stats->tx_errors++;
10861090 stats->tx_dropped++;
10871091 kfree_skb(skb);
10881092 return NETDEV_TX_OK;
....@@ -1105,6 +1109,7 @@
11051109 fl6->flowi6_oif = p->link;
11061110 fl6->flowlabel = 0;
11071111 fl6->flowi6_proto = IPPROTO_GRE;
1112
+ fl6->fl6_gre_key = t->parms.o_key;
11081113
11091114 if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS))
11101115 fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo;
....@@ -1148,14 +1153,16 @@
11481153 dev->needed_headroom = dst_len;
11491154
11501155 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;
1156
+ int mtu = rt->dst.dev->mtu - t_hlen;
11561157
1157
- if (dev->mtu < IPV6_MIN_MTU)
1158
- dev->mtu = IPV6_MIN_MTU;
1158
+ if (!(t->parms.flags & IP6_TNL_F_IGN_ENCAP_LIMIT))
1159
+ mtu -= 8;
1160
+ if (dev->type == ARPHRD_ETHER)
1161
+ mtu -= ETH_HLEN;
1162
+
1163
+ if (mtu < IPV6_MIN_MTU)
1164
+ mtu = IPV6_MIN_MTU;
1165
+ WRITE_ONCE(dev->mtu, mtu);
11591166 }
11601167 }
11611168 ip6_rt_put(rt);
....@@ -1550,7 +1557,7 @@
15501557 static struct inet6_protocol ip6gre_protocol __read_mostly = {
15511558 .handler = gre_rcv,
15521559 .err_handler = ip6gre_err,
1553
- .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
1560
+ .flags = INET6_PROTO_FINAL,
15541561 };
15551562
15561563 static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
....@@ -1931,12 +1938,6 @@
19311938 netif_keep_dst(dev);
19321939 }
19331940
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
-
19401941 static bool ip6gre_netlink_encap_parms(struct nlattr *data[],
19411942 struct ip_tunnel_encap *ipencap)
19421943 {
....@@ -2205,8 +2206,8 @@
22052206 [IFLA_GRE_OFLAGS] = { .type = NLA_U16 },
22062207 [IFLA_GRE_IKEY] = { .type = NLA_U32 },
22072208 [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) },
2209
+ [IFLA_GRE_LOCAL] = { .len = sizeof_field(struct ipv6hdr, saddr) },
2210
+ [IFLA_GRE_REMOTE] = { .len = sizeof_field(struct ipv6hdr, daddr) },
22102211 [IFLA_GRE_TTL] = { .type = NLA_U8 },
22112212 [IFLA_GRE_ENCAP_LIMIT] = { .type = NLA_U8 },
22122213 [IFLA_GRE_FLOWINFO] = { .type = NLA_U32 },