Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

mpls: Add mpls_route_input().

mpls_route_input_rcu() is called from mpls_forward() and
mpls_getroute().

The former is under RCU, and the latter is under RTNL, so
mpls_route_input_rcu() uses rcu_dereference_rtnl().

Let's use rcu_dereference() in mpls_route_input_rcu() and
add an RTNL variant for mpls_getroute().

Later, we will remove rtnl_dereference() there.

Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Guillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/20251029173344.2934622-9-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Kuniyuki Iwashima and committed by
Jakub Kicinski
73e40539 1fb462de

+18 -10
+18 -10
net/mpls/af_mpls.c
··· 75 75 struct nlmsghdr *nlh, struct net *net, u32 portid, 76 76 unsigned int nlm_flags); 77 77 78 - static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned index) 78 + static struct mpls_route *mpls_route_input(struct net *net, unsigned int index) 79 79 { 80 - struct mpls_route *rt = NULL; 80 + struct mpls_route __rcu **platform_label; 81 81 82 - if (index < net->mpls.platform_labels) { 83 - struct mpls_route __rcu **platform_label = 84 - rcu_dereference_rtnl(net->mpls.platform_label); 85 - rt = rcu_dereference_rtnl(platform_label[index]); 86 - } 87 - return rt; 82 + platform_label = rtnl_dereference(net->mpls.platform_label); 83 + return rtnl_dereference(platform_label[index]); 84 + } 85 + 86 + static struct mpls_route *mpls_route_input_rcu(struct net *net, unsigned int index) 87 + { 88 + struct mpls_route __rcu **platform_label; 89 + 90 + if (index >= net->mpls.platform_labels) 91 + return NULL; 92 + 93 + platform_label = rcu_dereference(net->mpls.platform_label); 94 + return rcu_dereference(platform_label[index]); 88 95 } 89 96 90 97 bool mpls_output_possible(const struct net_device *dev) ··· 2380 2373 u32 portid = NETLINK_CB(in_skb).portid; 2381 2374 u32 in_label = LABEL_NOT_SPECIFIED; 2382 2375 struct nlattr *tb[RTA_MAX + 1]; 2376 + struct mpls_route *rt = NULL; 2383 2377 u32 labels[MAX_NEW_LABELS]; 2384 2378 struct mpls_shim_hdr *hdr; 2385 2379 unsigned int hdr_size = 0; 2386 2380 const struct mpls_nh *nh; 2387 2381 struct net_device *dev; 2388 - struct mpls_route *rt; 2389 2382 struct rtmsg *rtm, *r; 2390 2383 struct nlmsghdr *nlh; 2391 2384 struct sk_buff *skb; ··· 2413 2406 } 2414 2407 } 2415 2408 2416 - rt = mpls_route_input_rcu(net, in_label); 2409 + if (in_label < net->mpls.platform_labels) 2410 + rt = mpls_route_input(net, in_label); 2417 2411 if (!rt) { 2418 2412 err = -ENETUNREACH; 2419 2413 goto errout;