Skip to content

Commit d5566fd

Browse files
sowminivdavem330
authored andcommitted
rtnetlink: RTEXT_FILTER_SKIP_STATS support to avoid dumping inet/inet6 stats
Many commonly used functions like getifaddrs() invoke RTM_GETLINK to dump the interface information, and do not need the the AF_INET6 statististics that are always returned by default from rtnl_fill_ifinfo(). Computing the statistics can be an expensive operation that impacts scaling, so it is desirable to avoid this if the information is not needed. This patch adds a the RTEXT_FILTER_SKIP_STATS extended info flag that can be passed with netlink_request() to avoid statistics computation for the ifinfo path. Signed-off-by: Sowmini Varadhan <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent ad1e7b9 commit d5566fd

File tree

5 files changed

+15
-7
lines changed

5 files changed

+15
-7
lines changed

include/net/rtnetlink.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,8 @@ struct rtnl_af_ops {
122122
int family;
123123

124124
int (*fill_link_af)(struct sk_buff *skb,
125-
const struct net_device *dev);
125+
const struct net_device *dev,
126+
u32 ext_filter_mask);
126127
size_t (*get_link_af_size)(const struct net_device *dev);
127128

128129
int (*validate_link_af)(const struct net_device *dev,

include/uapi/linux/rtnetlink.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -667,6 +667,7 @@ struct tcamsg {
667667
#define RTEXT_FILTER_VF (1 << 0)
668668
#define RTEXT_FILTER_BRVLAN (1 << 1)
669669
#define RTEXT_FILTER_BRVLAN_COMPRESSED (1 << 2)
670+
#define RTEXT_FILTER_SKIP_STATS (1 << 3)
670671

671672
/* End of information exported to user level */
672673

net/core/rtnetlink.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1272,7 +1272,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
12721272
if (!(af = nla_nest_start(skb, af_ops->family)))
12731273
goto nla_put_failure;
12741274

1275-
err = af_ops->fill_link_af(skb, dev);
1275+
err = af_ops->fill_link_af(skb, dev, ext_filter_mask);
12761276

12771277
/*
12781278
* Caller may return ENODATA to indicate that there

net/ipv4/devinet.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1654,7 +1654,8 @@ static size_t inet_get_link_af_size(const struct net_device *dev)
16541654
return nla_total_size(IPV4_DEVCONF_MAX * 4); /* IFLA_INET_CONF */
16551655
}
16561656

1657-
static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
1657+
static int inet_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
1658+
u32 ext_filter_mask)
16581659
{
16591660
struct in_device *in_dev = rcu_dereference_rtnl(dev->ip_ptr);
16601661
struct nlattr *nla;

net/ipv6/addrconf.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4729,7 +4729,8 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
47294729
}
47304730
}
47314731

4732-
static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
4732+
static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev,
4733+
u32 ext_filter_mask)
47334734
{
47344735
struct nlattr *nla;
47354736
struct ifla_cacheinfo ci;
@@ -4749,6 +4750,9 @@ static int inet6_fill_ifla6_attrs(struct sk_buff *skb, struct inet6_dev *idev)
47494750

47504751
/* XXX - MC not implemented */
47514752

4753+
if (ext_filter_mask & RTEXT_FILTER_SKIP_STATS)
4754+
return 0;
4755+
47524756
nla = nla_reserve(skb, IFLA_INET6_STATS, IPSTATS_MIB_MAX * sizeof(u64));
47534757
if (!nla)
47544758
goto nla_put_failure;
@@ -4784,14 +4788,15 @@ static size_t inet6_get_link_af_size(const struct net_device *dev)
47844788
return inet6_ifla6_size();
47854789
}
47864790

4787-
static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev)
4791+
static int inet6_fill_link_af(struct sk_buff *skb, const struct net_device *dev,
4792+
u32 ext_filter_mask)
47884793
{
47894794
struct inet6_dev *idev = __in6_dev_get(dev);
47904795

47914796
if (!idev)
47924797
return -ENODATA;
47934798

4794-
if (inet6_fill_ifla6_attrs(skb, idev) < 0)
4799+
if (inet6_fill_ifla6_attrs(skb, idev, ext_filter_mask) < 0)
47954800
return -EMSGSIZE;
47964801

47974802
return 0;
@@ -4946,7 +4951,7 @@ static int inet6_fill_ifinfo(struct sk_buff *skb, struct inet6_dev *idev,
49464951
if (!protoinfo)
49474952
goto nla_put_failure;
49484953

4949-
if (inet6_fill_ifla6_attrs(skb, idev) < 0)
4954+
if (inet6_fill_ifla6_attrs(skb, idev, 0) < 0)
49504955
goto nla_put_failure;
49514956

49524957
nla_nest_end(skb, protoinfo);

0 commit comments

Comments
 (0)