hc
2024-10-09 05e59e5fb0064c97a1c10921ecd549f2d4a58565
kernel/net/ipv6/seg6_iptunnel.c
....@@ -1,14 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * SR-IPv6 implementation
34 *
45 * Author:
56 * David Lebrun <david.lebrun@uclouvain.be>
6
- *
7
- *
8
- * This program is free software; you can redistribute it and/or
9
- * modify it under the terms of the GNU General Public License
10
- * as published by the Free Software Foundation; either version
11
- * 2 of the License, or (at your option) any later version.
127 */
138
149 #include <linux/types.h>
....@@ -32,9 +27,26 @@
3227 #include <net/seg6_hmac.h>
3328 #endif
3429
30
+static size_t seg6_lwt_headroom(struct seg6_iptunnel_encap *tuninfo)
31
+{
32
+ int head = 0;
33
+
34
+ switch (tuninfo->mode) {
35
+ case SEG6_IPTUN_MODE_INLINE:
36
+ break;
37
+ case SEG6_IPTUN_MODE_ENCAP:
38
+ head = sizeof(struct ipv6hdr);
39
+ break;
40
+ case SEG6_IPTUN_MODE_L2ENCAP:
41
+ return 0;
42
+ }
43
+
44
+ return ((tuninfo->srh->hdrlen + 1) << 3) + head;
45
+}
46
+
3547 struct seg6_lwt {
3648 struct dst_cache cache;
37
- struct seg6_iptunnel_encap tuninfo[0];
49
+ struct seg6_iptunnel_encap tuninfo[];
3850 };
3951
4052 static inline struct seg6_lwt *seg6_lwt_lwtunnel(struct lwtunnel_state *lwt)
....@@ -176,6 +188,8 @@
176188 }
177189 #endif
178190
191
+ hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
192
+
179193 skb_postpush_rcsum(skb, hdr, tot_len);
180194
181195 return 0;
....@@ -227,6 +241,8 @@
227241 return err;
228242 }
229243 #endif
244
+
245
+ hdr->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
230246
231247 skb_postpush_rcsum(skb, hdr, sizeof(struct ipv6hdr) + hdrlen);
232248
....@@ -281,7 +297,7 @@
281297 skb_mac_header_rebuild(skb);
282298 skb_push(skb, skb->mac_len);
283299
284
- err = seg6_do_srh_encap(skb, tinfo->srh, NEXTHDR_NONE);
300
+ err = seg6_do_srh_encap(skb, tinfo->srh, IPPROTO_ETHERNET);
285301 if (err)
286302 return err;
287303
....@@ -289,7 +305,6 @@
289305 break;
290306 }
291307
292
- ipv6_hdr(skb)->payload_len = htons(skb->len - sizeof(struct ipv6hdr));
293308 skb_set_transport_header(skb, sizeof(struct ipv6hdr));
294309
295310 return 0;
....@@ -389,7 +404,7 @@
389404 return err;
390405 }
391406
392
-static int seg6_build_state(struct nlattr *nla,
407
+static int seg6_build_state(struct net *net, struct nlattr *nla,
393408 unsigned int family, const void *cfg,
394409 struct lwtunnel_state **ts,
395410 struct netlink_ext_ack *extack)
....@@ -404,8 +419,8 @@
404419 if (family != AF_INET && family != AF_INET6)
405420 return -EINVAL;
406421
407
- err = nla_parse_nested(tb, SEG6_IPTUNNEL_MAX, nla,
408
- seg6_iptunnel_policy, extack);
422
+ err = nla_parse_nested_deprecated(tb, SEG6_IPTUNNEL_MAX, nla,
423
+ seg6_iptunnel_policy, extack);
409424
410425 if (err < 0)
411426 return err;
....@@ -439,7 +454,7 @@
439454 }
440455
441456 /* verify that SRH is consistent */
442
- if (!seg6_validate_srh(tuninfo->srh, tuninfo_len - sizeof(*tuninfo)))
457
+ if (!seg6_validate_srh(tuninfo->srh, tuninfo_len - sizeof(*tuninfo), false))
443458 return -EINVAL;
444459
445460 newts = lwtunnel_state_alloc(tuninfo_len + sizeof(*slwt));