hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/net/core/lwtunnel.c
....@@ -1,13 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * lwtunnel Infrastructure for light weight tunnels like mpls
34 *
45 * Authors: Roopa Prabhu, <roopa@cumulusnetworks.com>
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 #include <linux/capability.h>
....@@ -26,7 +21,7 @@
2621 #include <net/lwtunnel.h>
2722 #include <net/rtnetlink.h>
2823 #include <net/ip6_fib.h>
29
-#include <net/nexthop.h>
24
+#include <net/rtnh.h>
3025
3126 #ifdef CONFIG_MODULES
3227
....@@ -46,6 +41,8 @@
4641 return "BPF";
4742 case LWTUNNEL_ENCAP_SEG6_LOCAL:
4843 return "SEG6LOCAL";
44
+ case LWTUNNEL_ENCAP_RPL:
45
+ return "RPL";
4946 case LWTUNNEL_ENCAP_IP6:
5047 case LWTUNNEL_ENCAP_IP:
5148 case LWTUNNEL_ENCAP_NONE:
....@@ -103,7 +100,7 @@
103100 }
104101 EXPORT_SYMBOL_GPL(lwtunnel_encap_del_ops);
105102
106
-int lwtunnel_build_state(u16 encap_type,
103
+int lwtunnel_build_state(struct net *net, u16 encap_type,
107104 struct nlattr *encap, unsigned int family,
108105 const void *cfg, struct lwtunnel_state **lws,
109106 struct netlink_ext_ack *extack)
....@@ -122,18 +119,18 @@
122119 ret = -EOPNOTSUPP;
123120 rcu_read_lock();
124121 ops = rcu_dereference(lwtun_encaps[encap_type]);
125
- if (likely(ops && ops->build_state && try_module_get(ops->owner))) {
122
+ if (likely(ops && ops->build_state && try_module_get(ops->owner)))
126123 found = true;
127
- ret = ops->build_state(encap, family, cfg, lws, extack);
128
- if (ret)
129
- module_put(ops->owner);
130
- }
131124 rcu_read_unlock();
132125
133
- /* don't rely on -EOPNOTSUPP to detect match as build_state
134
- * handlers could return it
135
- */
136
- if (!found) {
126
+ if (found) {
127
+ ret = ops->build_state(net, encap, family, cfg, lws, extack);
128
+ if (ret)
129
+ module_put(ops->owner);
130
+ } else {
131
+ /* don't rely on -EOPNOTSUPP to detect match as build_state
132
+ * handlers could return it
133
+ */
137134 NL_SET_ERR_MSG_ATTR(extack, encap,
138135 "LWT encapsulation type not supported");
139136 }
....@@ -195,6 +192,10 @@
195192 nla_entype = nla_find(attrs, attrlen, RTA_ENCAP_TYPE);
196193
197194 if (nla_entype) {
195
+ if (nla_len(nla_entype) < sizeof(u16)) {
196
+ NL_SET_ERR_MSG(extack, "Invalid RTA_ENCAP_TYPE");
197
+ return -EINVAL;
198
+ }
198199 encap_type = nla_get_u16(nla_entype);
199200
200201 if (lwtunnel_valid_encap_type(encap_type,
....@@ -223,7 +224,8 @@
223224 }
224225 EXPORT_SYMBOL_GPL(lwtstate_free);
225226
226
-int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate)
227
+int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate,
228
+ int encap_attr, int encap_type_attr)
227229 {
228230 const struct lwtunnel_encap_ops *ops;
229231 struct nlattr *nest;
....@@ -236,7 +238,7 @@
236238 lwtstate->type > LWTUNNEL_ENCAP_MAX)
237239 return 0;
238240
239
- nest = nla_nest_start(skb, RTA_ENCAP);
241
+ nest = nla_nest_start_noflag(skb, encap_attr);
240242 if (!nest)
241243 return -EMSGSIZE;
242244
....@@ -250,7 +252,7 @@
250252 if (ret)
251253 goto nla_put_failure;
252254 nla_nest_end(skb, nest);
253
- ret = nla_put_u16(skb, RTA_ENCAP_TYPE, lwtstate->type);
255
+ ret = nla_put_u16(skb, encap_type_attr, lwtstate->type);
254256 if (ret)
255257 goto nla_put_failure;
256258