ipv6: Don't put artificial limit on routing table size.
IPV6, unlike IPV4, doesn't have a routing cache. Routing table entries, as well as clones made in response to route lookup requests, all live in the same table. And all of these things are together collected in the destination cache table for ipv6. This means that routing table entries count against the garbage collection limits, even though such entries cannot ever be reclaimed and are added explicitly by the administrator (rather than being created in response to lookups). Therefore it makes no sense to count ipv6 routing table entries against the GC limits. Add a DST_NOCOUNT destination cache entry flag, and skip the counting if it is set. Use this flag bit in ipv6 when adding routing table entries. Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Родитель
11d53b4990
Коммит
957c665f37
|
@ -77,6 +77,7 @@ struct dst_entry {
|
|||
#define DST_NOPOLICY 0x0004
|
||||
#define DST_NOHASH 0x0008
|
||||
#define DST_NOCACHE 0x0010
|
||||
#define DST_NOCOUNT 0x0020
|
||||
union {
|
||||
struct dst_entry *next;
|
||||
struct rtable __rcu *rt_next;
|
||||
|
|
|
@ -190,6 +190,7 @@ void *dst_alloc(struct dst_ops *ops, struct net_device *dev,
|
|||
dst->lastuse = jiffies;
|
||||
dst->flags = flags;
|
||||
dst->next = NULL;
|
||||
if (!(flags & DST_NOCOUNT))
|
||||
dst_entries_add(ops, 1);
|
||||
return dst;
|
||||
}
|
||||
|
@ -243,6 +244,7 @@ again:
|
|||
neigh_release(neigh);
|
||||
}
|
||||
|
||||
if (!(dst->flags & DST_NOCOUNT))
|
||||
dst_entries_add(dst->ops, -1);
|
||||
|
||||
if (dst->ops->destroy)
|
||||
|
|
|
@ -228,9 +228,10 @@ static struct rt6_info ip6_blk_hole_entry_template = {
|
|||
|
||||
/* allocate dst with ip6_dst_ops */
|
||||
static inline struct rt6_info *ip6_dst_alloc(struct dst_ops *ops,
|
||||
struct net_device *dev)
|
||||
struct net_device *dev,
|
||||
int flags)
|
||||
{
|
||||
struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, 0);
|
||||
struct rt6_info *rt = dst_alloc(ops, dev, 0, 0, flags);
|
||||
|
||||
memset(&rt->rt6i_table, 0, sizeof(*rt) - sizeof(struct dst_entry));
|
||||
|
||||
|
@ -1042,7 +1043,7 @@ struct dst_entry *icmp6_dst_alloc(struct net_device *dev,
|
|||
if (unlikely(idev == NULL))
|
||||
return NULL;
|
||||
|
||||
rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev);
|
||||
rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, dev, 0);
|
||||
if (unlikely(rt == NULL)) {
|
||||
in6_dev_put(idev);
|
||||
goto out;
|
||||
|
@ -1206,7 +1207,7 @@ int ip6_route_add(struct fib6_config *cfg)
|
|||
goto out;
|
||||
}
|
||||
|
||||
rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL);
|
||||
rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops, NULL, DST_NOCOUNT);
|
||||
|
||||
if (rt == NULL) {
|
||||
err = -ENOMEM;
|
||||
|
@ -1726,7 +1727,7 @@ static struct rt6_info * ip6_rt_copy(struct rt6_info *ort)
|
|||
{
|
||||
struct net *net = dev_net(ort->rt6i_dev);
|
||||
struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
|
||||
ort->dst.dev);
|
||||
ort->dst.dev, 0);
|
||||
|
||||
if (rt) {
|
||||
rt->dst.input = ort->dst.input;
|
||||
|
@ -2005,7 +2006,7 @@ struct rt6_info *addrconf_dst_alloc(struct inet6_dev *idev,
|
|||
{
|
||||
struct net *net = dev_net(idev->dev);
|
||||
struct rt6_info *rt = ip6_dst_alloc(&net->ipv6.ip6_dst_ops,
|
||||
net->loopback_dev);
|
||||
net->loopback_dev, 0);
|
||||
struct neighbour *neigh;
|
||||
|
||||
if (rt == NULL) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче