From: Eric Dumazet <edumazet@google.com>
To: "David S . Miller" <davem@davemloft.net>,
Jakub Kicinski <kuba@kernel.org>,
Paolo Abeni <pabeni@redhat.com>
Cc: Simon Horman <horms@kernel.org>,
Andrew Lunn <andrew+netdev@lunn.ch>,
Ido Schimmel <idosch@nvidia.com>,
Kuniyuki Iwashima <kuniyu@google.com>,
Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>,
Artem Lytkin <iprintercanon@gmail.com>,
netdev@vger.kernel.org, eric.dumazet@gmail.com,
Eric Dumazet <edumazet@google.com>
Subject: [PATCH net-next 8/9] sit: convert configuration to RCU protection
Date: Mon, 7 Sep 2026 07:58:45 +0000 [thread overview]
Message-ID: <20260907075846.2913645-9-edumazet@google.com> (raw)
In-Reply-To: <20260907075846.2913645-1-edumazet@google.com>
Now that SIT parameters are dynamically allocated, convert
tunnel->sit_parms to an RCU-protected pointer.
Updates in ipip6_tunnel_update() allocate a new parameter block,
publish it using rcu_assign_pointer(), and free the old one
via kfree_rcu().
We only need to unlink and re-link the tunnel in the hash table
if either saddr or daddr changed. When neither address changes,
the unhash/re-hash and synchronize_net() can be completely skipped.
Readers in ipip6_tunnel_lookup(), ipip6_tunnel_xmit(), ipip6_err(),
and ipip6_rcv() now safely dereference tunnel->sit_parms under RCU.
Signed-off-by: Eric Dumazet <edumazet@google.com>
---
include/net/ip_tunnels.h | 3 +-
net/ipv6/sit.c | 245 +++++++++++++++++++++++++--------------
2 files changed, 157 insertions(+), 91 deletions(-)
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h
index f464c4480edaf35f9ace1c5081c564ce51fed636..be4cc10f88ed64114cebac7f2e01bea21f5419da 100644
--- a/include/net/ip_tunnels.h
+++ b/include/net/ip_tunnels.h
@@ -149,6 +149,7 @@ struct ip_tunnel_parm_kern {
__be32 o_key;
int link;
struct iphdr iph;
+ struct rcu_head rcu;
};
struct ip_tunnel {
@@ -190,7 +191,7 @@ struct ip_tunnel {
#endif
struct ip_tunnel_prl_entry __rcu *prl; /* potential router list */
unsigned int prl_count; /* # of entries in PRL */
- struct ip_tunnel_parm_kern *sit_parms;
+ struct ip_tunnel_parm_kern __rcu *sit_parms;
unsigned int ip_tnl_net_id;
struct gro_cells gro_cells;
__u32 fwmark;
diff --git a/net/ipv6/sit.c b/net/ipv6/sit.c
index dc37c7109af5324f2ced0301b289e7622dd1a55f..c9049ab87e010eed5f53a342460ed10006083cd7 100644
--- a/net/ipv6/sit.c
+++ b/net/ipv6/sit.c
@@ -108,24 +108,33 @@ static struct ip_tunnel *ipip6_tunnel_lookup(struct net *net,
int ifindex = dev ? dev->ifindex : 0;
for_each_ip_tunnel_rcu(t, sitn->tunnels_r_l[h0 ^ h1]) {
- if (local == t->sit_parms->iph.saddr &&
- remote == t->sit_parms->iph.daddr &&
- (!dev || !t->sit_parms->link || ifindex == t->sit_parms->link ||
- sifindex == t->sit_parms->link) &&
+ const struct ip_tunnel_parm_kern *parms;
+
+ parms = rcu_dereference(t->sit_parms);
+ if (local == parms->iph.saddr &&
+ remote == parms->iph.daddr &&
+ (!dev || !parms->link || ifindex == parms->link ||
+ sifindex == parms->link) &&
(t->dev->flags & IFF_UP))
return t;
}
for_each_ip_tunnel_rcu(t, sitn->tunnels_r[h0]) {
- if (remote == t->sit_parms->iph.daddr &&
- (!dev || !t->sit_parms->link || ifindex == t->sit_parms->link ||
- sifindex == t->sit_parms->link) &&
+ const struct ip_tunnel_parm_kern *parms;
+
+ parms = rcu_dereference(t->sit_parms);
+ if (remote == parms->iph.daddr &&
+ (!dev || !parms->link || ifindex == parms->link ||
+ sifindex == parms->link) &&
(t->dev->flags & IFF_UP))
return t;
}
for_each_ip_tunnel_rcu(t, sitn->tunnels_l[h1]) {
- if (local == t->sit_parms->iph.saddr &&
- (!dev || !t->sit_parms->link || ifindex == t->sit_parms->link ||
- sifindex == t->sit_parms->link) &&
+ const struct ip_tunnel_parm_kern *parms;
+
+ parms = rcu_dereference(t->sit_parms);
+ if (local == parms->iph.saddr &&
+ (!dev || !parms->link || ifindex == parms->link ||
+ sifindex == parms->link) &&
(t->dev->flags & IFF_UP))
return t;
}
@@ -157,7 +166,7 @@ __ipip6_bucket(struct sit_net *sitn, struct ip_tunnel_parm_kern *parms)
static inline struct ip_tunnel __rcu **ipip6_bucket(struct sit_net *sitn,
struct ip_tunnel *t)
{
- return __ipip6_bucket(sitn, t->sit_parms);
+ return __ipip6_bucket(sitn, rtnl_dereference(t->sit_parms));
}
static void ipip6_tunnel_unlink(struct sit_net *sitn, struct ip_tunnel *t)
@@ -230,17 +239,19 @@ static int ipip6_tunnel_create(struct net_device *dev)
{
struct ip_tunnel *t = netdev_priv(dev);
struct sit_net *sitn = net_generic(t->net, sit_net_id);
+ struct ip_tunnel_parm_kern *parms;
int err;
err = ipip6_tunnel_clone_6rd(dev, sitn);
if (err < 0)
goto out;
- t->parms = *t->sit_parms;
- __dev_addr_set(dev, &t->sit_parms->iph.saddr, 4);
- memcpy(dev->broadcast, &t->sit_parms->iph.daddr, 4);
+ parms = rtnl_dereference(t->sit_parms);
+ t->parms = *parms;
+ __dev_addr_set(dev, &parms->iph.saddr, 4);
+ memcpy(dev->broadcast, &parms->iph.daddr, 4);
- if (test_bit(IP_TUNNEL_SIT_ISATAP_BIT, t->sit_parms->i_flags))
+ if (test_bit(IP_TUNNEL_SIT_ISATAP_BIT, parms->i_flags))
dev->priv_flags |= IFF_ISATAP;
dev->rtnl_link_ops = &sit_link_ops;
@@ -264,6 +275,7 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
__be32 local = parms->iph.saddr;
struct ip_tunnel *t, *nt;
struct ip_tunnel __rcu **tp;
+ struct ip_tunnel_parm_kern *nt_parms;
struct net_device *dev;
char name[IFNAMSIZ];
struct sit_net *sitn = net_generic(net, sit_net_id);
@@ -271,9 +283,12 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
for (tp = __ipip6_bucket(sitn, parms);
(t = rtnl_dereference(*tp)) != NULL;
tp = &t->next) {
- if (local == t->sit_parms->iph.saddr &&
- remote == t->sit_parms->iph.daddr &&
- parms->link == t->sit_parms->link) {
+ const struct ip_tunnel_parm_kern *tparms;
+
+ tparms = rtnl_dereference(t->sit_parms);
+ if (local == tparms->iph.saddr &&
+ remote == tparms->iph.daddr &&
+ parms->link == tparms->link) {
if (create)
return NULL;
else
@@ -300,10 +315,11 @@ static struct ip_tunnel *ipip6_tunnel_locate(struct net *net,
nt = netdev_priv(dev);
nt->net = net;
- nt->sit_parms = kmalloc_obj(*nt->sit_parms);
- if (!nt->sit_parms)
+ nt_parms = kmalloc_obj(*nt_parms);
+ if (!nt_parms)
goto failed_free;
- *nt->sit_parms = *parms;
+ *nt_parms = *parms;
+ rcu_assign_pointer(nt->sit_parms, nt_parms);
if (ipip6_tunnel_create(dev) < 0)
goto failed_free;
@@ -599,41 +615,45 @@ static int ipip6_err(struct sk_buff *skb, u32 info)
err = -ENOENT;
sifindex = netif_is_l3_master(skb->dev) ? IPCB(skb)->iif : 0;
+ rcu_read_lock();
t = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
iph->daddr, iph->saddr, sifindex);
- if (!t)
- goto out;
+ if (t) {
+ const struct ip_tunnel_parm_kern *parms;
- if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
- ipv4_update_pmtu(skb, dev_net(skb->dev), info,
- t->sit_parms->link, iph->protocol);
- err = 0;
- goto out;
- }
- if (type == ICMP_REDIRECT) {
- ipv4_redirect(skb, dev_net(skb->dev), t->sit_parms->link,
- iph->protocol);
- err = 0;
- goto out;
- }
+ parms = rcu_dereference(t->sit_parms);
+ if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) {
+ ipv4_update_pmtu(skb, dev_net(skb->dev), info,
+ parms->link, iph->protocol);
+ err = 0;
+ goto out;
+ }
+ if (type == ICMP_REDIRECT) {
+ ipv4_redirect(skb, dev_net(skb->dev), parms->link,
+ iph->protocol);
+ err = 0;
+ goto out;
+ }
- err = 0;
- if (__in6_dev_get(skb->dev) &&
- !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
- goto out;
+ err = 0;
+ if (__in6_dev_get(skb->dev) &&
+ !ip6_err_gen_icmpv6_unreach(skb, iph->ihl * 4, type, data_len))
+ goto out;
- if (t->sit_parms->iph.daddr == 0)
- goto out;
+ if (parms->iph.daddr == 0)
+ goto out;
- if (t->sit_parms->iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
- goto out;
+ if (parms->iph.ttl == 0 && type == ICMP_TIME_EXCEEDED)
+ goto out;
- if (time_before(jiffies, READ_ONCE(t->err_time) + IPTUNNEL_ERR_TIMEO))
- WRITE_ONCE(t->err_count, READ_ONCE(t->err_count) + 1);
- else
- WRITE_ONCE(t->err_count, 1);
- WRITE_ONCE(t->err_time, jiffies);
+ if (time_before(jiffies, READ_ONCE(t->err_time) + IPTUNNEL_ERR_TIMEO))
+ WRITE_ONCE(t->err_count, READ_ONCE(t->err_count) + 1);
+ else
+ WRITE_ONCE(t->err_count, 1);
+ WRITE_ONCE(t->err_time, jiffies);
+ }
out:
+ rcu_read_unlock();
return err;
}
@@ -726,8 +746,11 @@ static int ipip6_rcv(struct sk_buff *skb)
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
iph->saddr, iph->daddr, sifindex);
if (tunnel) {
- if (tunnel->sit_parms->iph.protocol != IPPROTO_IPV6 &&
- tunnel->sit_parms->iph.protocol != 0)
+ const struct ip_tunnel_parm_kern *parms;
+
+ parms = rcu_dereference(tunnel->sit_parms);
+ if (parms->iph.protocol != IPPROTO_IPV6 &&
+ parms->iph.protocol != 0)
goto out;
skb->mac_header = skb->network_header;
@@ -800,10 +823,12 @@ static int sit_tunnel_rcv(struct sk_buff *skb, u8 ipproto)
tunnel = ipip6_tunnel_lookup(dev_net(skb->dev), skb->dev,
iph->saddr, iph->daddr, sifindex);
if (tunnel) {
+ const struct ip_tunnel_parm_kern *parms;
const struct tnl_ptk_info *tpi;
- if (tunnel->sit_parms->iph.protocol != ipproto &&
- tunnel->sit_parms->iph.protocol != 0)
+ parms = rcu_dereference(tunnel->sit_parms);
+ if (parms->iph.protocol != ipproto &&
+ parms->iph.protocol != 0)
goto drop;
if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb))
@@ -942,20 +967,27 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- const struct iphdr *tiph = &tunnel->sit_parms->iph;
+ const struct ip_tunnel_parm_kern *parms;
+ const struct iphdr *tiph;
const struct ipv6hdr *iph6 = ipv6_hdr(skb);
- u8 tos = tunnel->sit_parms->iph.tos;
- __be16 df = tiph->frag_off;
+ u8 tos;
+ __be16 df;
struct rtable *rt; /* Route to the other host */
struct net_device *tdev; /* Device to other host */
unsigned int max_headroom; /* The extra header space needed */
- __be32 dst = tiph->daddr;
+ __be32 dst;
int err_count, mtu;
struct flowi4 fl4;
u8 ttl;
u8 protocol = IPPROTO_IPV6;
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+ parms = rcu_dereference(tunnel->sit_parms);
+ tiph = &parms->iph;
+ tos = parms->iph.tos;
+ df = tiph->frag_off;
+ dst = tiph->daddr;
+
if (tos == 1)
tos = ipv6_get_dsfield(iph6);
@@ -970,7 +1002,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
if (!dst && !ipip6_tunnel_dst_find(skb, &dst, false))
goto tx_error;
- flowi4_init_output(&fl4, tunnel->sit_parms->link, READ_ONCE(tunnel->fwmark),
+ flowi4_init_output(&fl4, parms->link, READ_ONCE(tunnel->fwmark),
tos & INET_DSCP_MASK, RT_SCOPE_UNIVERSE,
IPPROTO_IPV6, 0, dst, tiph->saddr, 0, 0,
sock_net_uid(tunnel->net, NULL));
@@ -1018,7 +1050,7 @@ static netdev_tx_t ipip6_tunnel_xmit(struct sk_buff *skb,
df = 0;
}
- if (tunnel->sit_parms->iph.daddr)
+ if (parms->iph.daddr)
skb_dst_update_pmtu_no_confirm(skb, mtu);
if (skb->len > mtu && !skb_is_gso(skb)) {
@@ -1087,13 +1119,17 @@ static netdev_tx_t sit_tunnel_xmit__(struct sk_buff *skb,
struct net_device *dev, u8 ipproto)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- const struct iphdr *tiph = &tunnel->sit_parms->iph;
+ const struct ip_tunnel_parm_kern *parms;
+ const struct iphdr *tiph;
if (iptunnel_handle_offloads(skb, SKB_GSO_IPXIP4))
goto tx_error;
skb_set_inner_ipproto(skb, ipproto);
+ parms = rcu_dereference(tunnel->sit_parms);
+ tiph = &parms->iph;
+
ip_tunnel_xmit(skb, dev, tiph, ipproto);
return NETDEV_TX_OK;
tx_error:
@@ -1108,6 +1144,7 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
if (!pskb_inet_may_pull(skb))
goto tx_err;
+ rcu_read_lock();
switch (skb->protocol) {
case htons(ETH_P_IP):
sit_tunnel_xmit__(skb, dev, IPPROTO_IPIP);
@@ -1121,8 +1158,10 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
break;
#endif
default:
+ rcu_read_unlock();
goto tx_err;
}
+ rcu_read_unlock();
return NETDEV_TX_OK;
@@ -1130,19 +1169,20 @@ static netdev_tx_t sit_tunnel_xmit(struct sk_buff *skb,
DEV_STATS_INC(dev, tx_errors);
kfree_skb(skb);
return NETDEV_TX_OK;
-
}
static void ipip6_tunnel_bind_dev(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
int t_hlen = tunnel->hlen + sizeof(struct iphdr);
+ const struct ip_tunnel_parm_kern *parms;
struct net_device *tdev = NULL;
int hlen = LL_MAX_HEADER;
const struct iphdr *iph;
struct flowi4 fl4;
- iph = &tunnel->sit_parms->iph;
+ parms = rtnl_dereference(tunnel->sit_parms);
+ iph = &parms->iph;
if (iph->daddr) {
struct rtable *rt = ip_route_output_ports(tunnel->net, &fl4,
@@ -1151,7 +1191,7 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
0, 0,
IPPROTO_IPV6,
iph->tos & INET_DSCP_MASK,
- tunnel->sit_parms->link);
+ parms->link);
if (!IS_ERR(rt)) {
tdev = rt->dst.dev;
@@ -1160,8 +1200,8 @@ static void ipip6_tunnel_bind_dev(struct net_device *dev)
dev->flags |= IFF_POINTOPOINT;
}
- if (!tdev && tunnel->sit_parms->link)
- tdev = __dev_get_by_index(tunnel->net, tunnel->sit_parms->link);
+ if (!tdev && parms->link)
+ tdev = __dev_get_by_index(tunnel->net, parms->link);
if (tdev && !netif_is_l3_master(tdev)) {
int mtu;
@@ -1182,8 +1222,9 @@ static int ipip6_tunnel_update(struct ip_tunnel *t,
struct net *net = t->net;
struct sit_net *sitn = net_generic(net, sit_net_id);
struct ip_tunnel_parm_kern *new_p, *old_p;
+ bool move;
- old_p = t->sit_parms;
+ old_p = rtnl_dereference(t->sit_parms);
new_p = kmalloc_obj(*new_p);
if (!new_p)
return -ENOMEM;
@@ -1194,21 +1235,29 @@ static int ipip6_tunnel_update(struct ip_tunnel *t,
new_p->iph.tos = p->iph.tos;
new_p->iph.frag_off = p->iph.frag_off;
new_p->link = p->link;
- ipip6_tunnel_unlink(sitn, t);
- synchronize_net();
- t->sit_parms = new_p;
+ move = old_p->iph.saddr != p->iph.saddr ||
+ old_p->iph.daddr != p->iph.daddr;
+
+ if (move)
+ ipip6_tunnel_unlink(sitn, t);
+
t->parms.iph = new_p->iph;
WRITE_ONCE(t->parms.link, new_p->link);
- __dev_addr_set(t->dev, &p->iph.saddr, 4);
- memcpy(t->dev->broadcast, &p->iph.daddr, 4);
- ipip6_tunnel_link(sitn, t);
+ rcu_assign_pointer(t->sit_parms, new_p);
+
+ if (move) {
+ synchronize_net();
+ __dev_addr_set(t->dev, &p->iph.saddr, 4);
+ memcpy(t->dev->broadcast, &p->iph.daddr, 4);
+ ipip6_tunnel_link(sitn, t);
+ }
if (old_p->link != p->link || t->fwmark != fwmark) {
WRITE_ONCE(t->fwmark, fwmark);
ipip6_tunnel_bind_dev(t->dev);
}
dst_cache_reset(&t->dst_cache);
netdev_state_change(t->dev);
- kfree(old_p);
+ kfree_rcu(old_p, rcu);
return 0;
}
@@ -1336,12 +1385,14 @@ static int
ipip6_tunnel_get(struct net_device *dev, struct ip_tunnel_parm_kern *p)
{
struct ip_tunnel *t = netdev_priv(dev);
+ const struct ip_tunnel_parm_kern *parms;
if (dev == dev_to_sit_net(dev)->fb_tunnel_dev)
t = ipip6_tunnel_locate(t->net, p, 0);
if (!t)
t = netdev_priv(dev);
- memcpy(p, t->sit_parms, sizeof(*p));
+ parms = rtnl_dereference(t->sit_parms);
+ memcpy(p, parms, sizeof(*p));
return 0;
}
@@ -1464,8 +1515,15 @@ ipip6_tunnel_siocdevprivate(struct net_device *dev, struct ifreq *ifr,
static int ipip6_get_iflink(const struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
+ const struct ip_tunnel_parm_kern *parms;
+ int link;
- return READ_ONCE(tunnel->sit_parms->link);
+ rcu_read_lock();
+ parms = rcu_dereference(tunnel->sit_parms);
+ link = parms ? parms->link : 0;
+ rcu_read_unlock();
+
+ return link;
}
static const struct net_device_ops ipip6_netdev_ops = {
@@ -1480,6 +1538,7 @@ static const struct net_device_ops ipip6_netdev_ops = {
static void ipip6_dev_free(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
+ struct ip_tunnel_parm_kern *parms;
#ifdef CONFIG_IPV6_SIT_6RD
struct ip_tunnel_6rd_parm *ip6rd;
@@ -1487,8 +1546,9 @@ static void ipip6_dev_free(struct net_device *dev)
RCU_INIT_POINTER(tunnel->ip6rd, NULL);
kfree(ip6rd);
#endif
- kfree(tunnel->sit_parms);
- tunnel->sit_parms = NULL;
+ parms = rcu_dereference_protected(tunnel->sit_parms, 1);
+ RCU_INIT_POINTER(tunnel->sit_parms, NULL);
+ kfree(parms);
if (tunnel->dst_cache.cache) {
dst_cache_destroy(&tunnel->dst_cache);
tunnel->dst_cache.cache = NULL;
@@ -1528,10 +1588,12 @@ static void ipip6_tunnel_setup(struct net_device *dev)
static int ipip6_tunnel_init(struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
+ struct ip_tunnel_parm_kern *parms;
int err;
tunnel->dev = dev;
- strscpy(tunnel->sit_parms->name, dev->name);
+ parms = rtnl_dereference(tunnel->sit_parms);
+ strscpy(parms->name, dev->name);
ipip6_tunnel_bind_dev(dev);
@@ -1549,7 +1611,6 @@ static void __net_init ipip6_fb_tunnel_init(struct net_device *dev)
struct ip_tunnel *tunnel = netdev_priv(dev);
struct net *net = dev_net(dev);
struct sit_net *sitn = net_generic(net, sit_net_id);
-
rcu_assign_pointer(sitn->tunnels_wc[0], tunnel);
}
@@ -1636,6 +1697,7 @@ static int ipip6_newlink(struct net_device *dev,
#ifdef CONFIG_IPV6_SIT_6RD
struct ip_tunnel_6rd ip6rd;
#endif
+ struct ip_tunnel_parm_kern *nt_parms;
struct ip_tunnel_parm_kern p;
struct net *net;
int err;
@@ -1655,10 +1717,11 @@ static int ipip6_newlink(struct net_device *dev,
if (ipip6_tunnel_locate(net, &p, 0))
return -EEXIST;
- nt->sit_parms = kmalloc_obj(*nt->sit_parms);
- if (!nt->sit_parms)
+ nt_parms = kmalloc_obj(*nt_parms);
+ if (!nt_parms)
return -ENOMEM;
- *nt->sit_parms = p;
+ *nt_parms = p;
+ rcu_assign_pointer(nt->sit_parms, nt_parms);
err = ipip6_tunnel_create(dev);
if (err < 0) {
@@ -1783,7 +1846,7 @@ static size_t ipip6_get_size(const struct net_device *dev)
static int ipip6_fill_info(struct sk_buff *skb, const struct net_device *dev)
{
struct ip_tunnel *tunnel = netdev_priv(dev);
- struct ip_tunnel_parm_kern *parm = tunnel->sit_parms;
+ const struct ip_tunnel_parm_kern *parm = rtnl_dereference(tunnel->sit_parms);
#ifdef CONFIG_IPV6_SIT_6RD
const struct ip_tunnel_6rd_parm *ip6rd;
#endif
@@ -1929,6 +1992,7 @@ static void __net_exit sit_exit_rtnl_net(struct net *net, struct list_head *head
static int __net_init sit_init_net(struct net *net)
{
struct sit_net *sitn = net_generic(net, sit_net_id);
+ struct ip_tunnel_parm_kern *nt_parms;
struct ip_tunnel *t;
int err;
@@ -1956,17 +2020,18 @@ static int __net_init sit_init_net(struct net *net)
t = netdev_priv(sitn->fb_tunnel_dev);
t->net = net;
- t->sit_parms = kzalloc_obj(*t->sit_parms);
- if (!t->sit_parms) {
+ nt_parms = kzalloc_obj(*nt_parms);
+ if (!nt_parms) {
err = -ENOMEM;
goto err_reg_dev;
}
- t->sit_parms->iph.version = 4;
- t->sit_parms->iph.protocol = IPPROTO_IPV6;
- t->sit_parms->iph.ihl = 5;
- t->sit_parms->iph.ttl = 64;
- strscpy(t->sit_parms->name, sitn->fb_tunnel_dev->name);
- t->parms = *t->sit_parms;
+ nt_parms->iph.version = 4;
+ nt_parms->iph.protocol = IPPROTO_IPV6;
+ nt_parms->iph.ihl = 5;
+ nt_parms->iph.ttl = 64;
+ strscpy(nt_parms->name, sitn->fb_tunnel_dev->name);
+ t->parms = *nt_parms;
+ rcu_assign_pointer(t->sit_parms, nt_parms);
err = ipip6_tunnel_clone_6rd(sitn->fb_tunnel_dev, sitn);
if (err < 0)
--
2.55.0.979.g7e5102b832-goog
next prev parent reply other threads:[~2026-09-07 7:59 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-07 7:58 [PATCH net-next 0/9] sit: convert configuration to RCU and lockless fill_info Eric Dumazet
2026-09-07 7:58 ` [PATCH net-next 1/9] sit: fix UAF in ipip6_tunnel_del_prl() Eric Dumazet
2026-09-07 12:28 ` Lorenzo Bianconi
2026-09-07 7:58 ` [PATCH net-next 2/9] sit: charge ip_tunnel_prl_entry allocations to memcg Eric Dumazet
2026-09-07 12:35 ` Lorenzo Bianconi
2026-09-07 7:58 ` [PATCH net-next 3/9] ip_tunnel: use WRITE_ONCE in ip_tunnel_encap_setup Eric Dumazet
2026-09-07 15:12 ` Lorenzo Bianconi
2026-09-08 11:00 ` netdev-bot+sashiko
2026-09-07 7:58 ` [PATCH net-next 4/9] sit: annotate data-races around tunnel->fwmark Eric Dumazet
2026-09-07 15:12 ` Lorenzo Bianconi
2026-09-08 11:00 ` netdev-bot+sashiko
2026-09-07 7:58 ` [PATCH net-next 5/9] sit: convert 6RD configuration to RCU protection Eric Dumazet
2026-09-07 13:00 ` Lorenzo Bianconi
2026-09-08 11:00 ` netdev-bot+sashiko
2026-09-07 7:58 ` [PATCH net-next 6/9] sit: implement ipip6_get_iflink() Eric Dumazet
2026-09-07 13:01 ` Lorenzo Bianconi
2026-09-07 7:58 ` [PATCH net-next 7/9] sit: dynamically allocate struct ip_tunnel_parm_kern Eric Dumazet
2026-09-07 13:16 ` Lorenzo Bianconi
2026-09-07 13:34 ` Artem Lytkin
2026-09-07 13:48 ` Eric Dumazet
2026-09-08 11:00 ` netdev-bot+sashiko
2026-09-07 7:58 ` Eric Dumazet [this message]
2026-09-07 14:32 ` [PATCH net-next 8/9] sit: convert configuration to RCU protection Lorenzo Bianconi
2026-09-07 14:42 ` Eric Dumazet
2026-09-08 11:00 ` netdev-bot+sashiko
2026-09-07 7:58 ` [PATCH net-next 9/9] sit: no longer rely on RTNL in ipip6_fill_info() Eric Dumazet
2026-09-07 15:04 ` Lorenzo Bianconi
2026-09-11 1:40 ` [PATCH net-next 0/9] sit: convert configuration to RCU and lockless fill_info patchwork-bot+netdevbpf
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260907075846.2913645-9-edumazet@google.com \
--to=edumazet@google.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=eric.dumazet@gmail.com \
--cc=horms@kernel.org \
--cc=idosch@nvidia.com \
--cc=iprintercanon@gmail.com \
--cc=kuba@kernel.org \
--cc=kuniyu@google.com \
--cc=lorenzo.bianconi@oss.qualcomm.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox