Skip to content

Commit

Permalink
netns: ip6mr: store netns in struct mfc6_cache
Browse files Browse the repository at this point in the history
This patch stores into struct mfc6_cache the network namespace each
mfc6_cache belongs to. The new member is mfc6_net.

mfc6_net is assigned at cache allocation and doesn't change during
the rest of the cache entry life.

This will help to retrieve the current netns around the IPv6 multicast
forwarding code.

At the moment, all mfc6_cache are allocated in init_net.

Changelog:
==========
* Use write_pnet()/read_pnet() to set and get mfc6_net.

Signed-off-by: Benjamin Thery <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
bthery authored and davem330 committed Dec 11, 2008
1 parent 4e16880 commit 58701ad
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 9 deletions.
15 changes: 15 additions & 0 deletions include/linux/mroute6.h
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,9 @@ struct mif_device
struct mfc6_cache
{
struct mfc6_cache *next; /* Next entry on cache line */
#ifdef CONFIG_NET_NS
struct net *mfc6_net;
#endif
struct in6_addr mf6c_mcastgrp; /* Group the entry belongs to */
struct in6_addr mf6c_origin; /* Source of packet */
mifi_t mf6c_parent; /* Source interface */
Expand All @@ -210,6 +213,18 @@ struct mfc6_cache
} mfc_un;
};

static inline
struct net *mfc6_net(const struct mfc6_cache *mfc)
{
return read_pnet(&mfc->mfc6_net);
}

static inline
void mfc6_net_set(struct mfc6_cache *mfc, struct net *net)
{
write_pnet(&mfc->mfc6_net, hold_net(net));
}

#define MFC_STATIC 1
#define MFC_NOTIFY 2

Expand Down
26 changes: 17 additions & 9 deletions net/ipv6/ip6mr.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,12 @@ static int mif6_delete(int vifi)
return 0;
}

static inline void ip6mr_cache_free(struct mfc6_cache *c)
{
release_net(mfc6_net(c));
kmem_cache_free(mrt_cachep, c);
}

/* Destroy an unresolved cache entry, killing queued skbs
and reporting error to netlink readers.
*/
Expand All @@ -528,7 +534,7 @@ static void ip6mr_destroy_unres(struct mfc6_cache *c)
kfree_skb(skb);
}

kmem_cache_free(mrt_cachep, c);
ip6mr_cache_free(c);
}


Expand Down Expand Up @@ -685,22 +691,24 @@ static struct mfc6_cache *ip6mr_cache_find(struct in6_addr *origin, struct in6_a
/*
* Allocate a multicast cache entry
*/
static struct mfc6_cache *ip6mr_cache_alloc(void)
static struct mfc6_cache *ip6mr_cache_alloc(struct net *net)
{
struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_KERNEL);
if (c == NULL)
return NULL;
c->mfc_un.res.minvif = MAXMIFS;
mfc6_net_set(c, net);
return c;
}

static struct mfc6_cache *ip6mr_cache_alloc_unres(void)
static struct mfc6_cache *ip6mr_cache_alloc_unres(struct net *net)
{
struct mfc6_cache *c = kmem_cache_zalloc(mrt_cachep, GFP_ATOMIC);
if (c == NULL)
return NULL;
skb_queue_head_init(&c->mfc_un.unres.unresolved);
c->mfc_un.unres.expires = jiffies + 10 * HZ;
mfc6_net_set(c, net);
return c;
}

Expand Down Expand Up @@ -856,7 +864,7 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb)
*/

if (atomic_read(&cache_resolve_queue_len) >= 10 ||
(c = ip6mr_cache_alloc_unres()) == NULL) {
(c = ip6mr_cache_alloc_unres(&init_net)) == NULL) {
spin_unlock_bh(&mfc_unres_lock);

kfree_skb(skb);
Expand All @@ -879,7 +887,7 @@ ip6mr_cache_unresolved(mifi_t mifi, struct sk_buff *skb)
*/
spin_unlock_bh(&mfc_unres_lock);

kmem_cache_free(mrt_cachep, c);
ip6mr_cache_free(c);
kfree_skb(skb);
return err;
}
Expand Down Expand Up @@ -924,7 +932,7 @@ static int ip6mr_mfc_delete(struct mf6cctl *mfc)
*cp = c->next;
write_unlock_bh(&mrt_lock);

kmem_cache_free(mrt_cachep, c);
ip6mr_cache_free(c);
return 0;
}
}
Expand Down Expand Up @@ -1073,7 +1081,7 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)
if (!ipv6_addr_is_multicast(&mfc->mf6cc_mcastgrp.sin6_addr))
return -EINVAL;

c = ip6mr_cache_alloc();
c = ip6mr_cache_alloc(&init_net);
if (c == NULL)
return -ENOMEM;

Expand Down Expand Up @@ -1108,7 +1116,7 @@ static int ip6mr_mfc_add(struct mf6cctl *mfc, int mrtsock)

if (uc) {
ip6mr_cache_resolve(uc, c);
kmem_cache_free(mrt_cachep, uc);
ip6mr_cache_free(uc);
}
return 0;
}
Expand Down Expand Up @@ -1145,7 +1153,7 @@ static void mroute_clean_tables(struct sock *sk)
*cp = c->next;
write_unlock_bh(&mrt_lock);

kmem_cache_free(mrt_cachep, c);
ip6mr_cache_free(c);
}
}

Expand Down

0 comments on commit 58701ad

Please sign in to comment.