Skip to content

Commit 1104d9b

Browse files
tomratbertdavem330
authored andcommitted
lwtunnel: Add destroy state operation
Users of lwt tunnels may set up some secondary state in build_state function. Add a corresponding destroy_state function to allow users to clean up state. This destroy state function is called from lwstate_free. Also, we now free lwstate using kfree_rcu so user can assume structure is not freed before rcu. Acked-by: Roopa Prabhu <[email protected]> Signed-off-by: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 02dc765 commit 1104d9b

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

include/net/lwtunnel.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,15 @@ struct lwtunnel_state {
2929
int (*orig_input)(struct sk_buff *);
3030
int len;
3131
__u16 headroom;
32+
struct rcu_head rcu;
3233
__u8 data[0];
3334
};
3435

3536
struct lwtunnel_encap_ops {
3637
int (*build_state)(struct net_device *dev, struct nlattr *encap,
3738
unsigned int family, const void *cfg,
3839
struct lwtunnel_state **ts);
40+
void (*destroy_state)(struct lwtunnel_state *lws);
3941
int (*output)(struct net *net, struct sock *sk, struct sk_buff *skb);
4042
int (*input)(struct sk_buff *skb);
4143
int (*fill_encap)(struct sk_buff *skb,
@@ -46,10 +48,7 @@ struct lwtunnel_encap_ops {
4648
};
4749

4850
#ifdef CONFIG_LWTUNNEL
49-
static inline void lwtstate_free(struct lwtunnel_state *lws)
50-
{
51-
kfree(lws);
52-
}
51+
void lwtstate_free(struct lwtunnel_state *lws);
5352

5453
static inline struct lwtunnel_state *
5554
lwtstate_get(struct lwtunnel_state *lws)

net/core/lwtunnel.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,19 @@ int lwtunnel_build_state(struct net_device *dev, u16 encap_type,
130130
}
131131
EXPORT_SYMBOL(lwtunnel_build_state);
132132

133+
void lwtstate_free(struct lwtunnel_state *lws)
134+
{
135+
const struct lwtunnel_encap_ops *ops = lwtun_encaps[lws->type];
136+
137+
if (ops->destroy_state) {
138+
ops->destroy_state(lws);
139+
kfree_rcu(lws, rcu);
140+
} else {
141+
kfree(lws);
142+
}
143+
}
144+
EXPORT_SYMBOL(lwtstate_free);
145+
133146
int lwtunnel_fill_encap(struct sk_buff *skb, struct lwtunnel_state *lwtstate)
134147
{
135148
const struct lwtunnel_encap_ops *ops;

0 commit comments

Comments
 (0)