]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
libnetlink: Add filtering to rtnl_statsdump_req_filter()
authorPetr Machata <petrm@nvidia.com>
Fri, 22 Apr 2022 08:30:50 +0000 (10:30 +0200)
committerDavid Ahern <dsahern@kernel.org>
Thu, 28 Apr 2022 02:12:42 +0000 (20:12 -0600)
A number of functions in the rtnl_*_req family accept a caller-provided
callback to set up arbitrary filtering. rtnl_statsdump_req_filter()
currently only allows setting a field in the IFSM header, not custom
attributes. So far these were not necessary, but with introduction of more
detailed filtering settings, the callback becomes necessary.

To that end, add a filter_fn and filter_data arguments to the function.
Unlike the other filters, this one is typed to expect an IFSM pointer, to
permit tweaking the header itself as well.

Pass NULLs in the existing callers.

Signed-off-by: Petr Machata <petrm@nvidia.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
bridge/vlan.c
include/libnetlink.h
ip/iplink.c
ip/iplink_xstats.c
lib/libnetlink.c
misc/ifstat.c

index 8300f353f1a7b48d7f54572ea743e6be845f8df5..390a2037db49fc90912a7ed1a7964c879fed2544 100644 (file)
@@ -1179,7 +1179,8 @@ static int vlan_show(int argc, char **argv, int subject)
                __u32 filt_mask;
 
                filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_XSTATS);
-               if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask) < 0) {
+               if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask,
+                                             NULL, NULL) < 0) {
                        perror("Cannot send dump request");
                        exit(1);
                }
@@ -1194,7 +1195,8 @@ static int vlan_show(int argc, char **argv, int subject)
                }
 
                filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_XSTATS_SLAVE);
-               if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask) < 0) {
+               if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask,
+                                             NULL, NULL) < 0) {
                        perror("Cannot send slave dump request");
                        exit(1);
                }
index 9e4cc101adeb18d43c1b43b16663fc9b9129ac6c..372c370629b13dc9d9f67135e9a9b16cb3ae4e72 100644 (file)
@@ -37,6 +37,12 @@ struct nlmsg_chain {
        struct nlmsg_list *tail;
 };
 
+struct ipstats_req {
+       struct nlmsghdr nlh;
+       struct if_stats_msg ifsm;
+       char buf[128];
+};
+
 extern int rcvbuf;
 
 int rtnl_open(struct rtnl_handle *rth, unsigned int subscriptions)
@@ -88,7 +94,10 @@ int rtnl_fdb_linkdump_req_filter_fn(struct rtnl_handle *rth,
 int rtnl_nsiddump_req_filter_fn(struct rtnl_handle *rth, int family,
                                req_filter_fn_t filter_fn)
        __attribute__((warn_unused_result));
-int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask)
+int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask,
+                             int (*filter_fn)(struct ipstats_req *req,
+                                              void *data),
+                             void *filter_data)
        __attribute__((warn_unused_result));
 int rtnl_dump_request(struct rtnl_handle *rth, int type, void *req,
                             int len)
index dc76a12b58eb2d041b4bf15189daf788f477e097..23eb6c6e2bfe755e1d0a9700039e523536f94928 100644 (file)
@@ -1644,7 +1644,8 @@ static int iplink_afstats(int argc, char **argv)
                }
        }
 
-       if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask) < 0) {
+       if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask,
+                                     NULL, NULL) < 0) {
                perror("Cannont send dump request");
                return 1;
        }
index c64e6885678c6f20f672be920fe3de3f68afd851..1d180b0bdada242ceab79e883fc952288f021383 100644 (file)
@@ -65,7 +65,8 @@ int iplink_ifla_xstats(int argc, char **argv)
        else
                filt_mask = IFLA_STATS_FILTER_BIT(IFLA_STATS_LINK_XSTATS);
 
-       if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask) < 0) {
+       if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC, filt_mask,
+                                     NULL, NULL) < 0) {
                perror("Cannont send dump request");
                return -1;
        }
index 6d1b11876dc4c8706e3148a7d26d0137f8f9735b..4d33e4dd17f559ef5c6d2ce9cdb31fdb4c801826 100644 (file)
@@ -619,12 +619,13 @@ int rtnl_fdb_linkdump_req_filter_fn(struct rtnl_handle *rth,
        return send(rth->fd, &req, sizeof(req), 0);
 }
 
-int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask)
+int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam,
+                             __u32 filt_mask,
+                             int (*filter_fn)(struct ipstats_req *req,
+                                              void *data),
+                             void *filter_data)
 {
-       struct {
-               struct nlmsghdr nlh;
-               struct if_stats_msg ifsm;
-       } req;
+       struct ipstats_req req;
 
        memset(&req, 0, sizeof(req));
        req.nlh.nlmsg_len = NLMSG_LENGTH(sizeof(struct if_stats_msg));
@@ -635,6 +636,14 @@ int rtnl_statsdump_req_filter(struct rtnl_handle *rth, int fam, __u32 filt_mask)
        req.ifsm.family = fam;
        req.ifsm.filter_mask = filt_mask;
 
+       if (filter_fn) {
+               int err;
+
+               err = filter_fn(&req, filter_data);
+               if (err)
+                       return err;
+       }
+
        return send(rth->fd, &req, sizeof(req), 0);
 }
 
index d4a33429dc507b37743841e321ca2e40aac113ed..291f288b3752f34e5051aa1aaefd625f3c233855 100644 (file)
@@ -202,7 +202,7 @@ static void load_info(void)
                ll_init_map(&rth);
                filter_mask = IFLA_STATS_FILTER_BIT(filter_type);
                if (rtnl_statsdump_req_filter(&rth, AF_UNSPEC,
-                                             filter_mask) < 0) {
+                                             filter_mask, NULL, NULL) < 0) {
                        perror("Cannot send dump request");
                        exit(1);
                }