]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
tc: use ll_init_map() only when needed
authorEric Dumazet <edumazet@google.com>
Tue, 28 Apr 2026 08:28:51 +0000 (08:28 +0000)
committerDavid Ahern <dsahern@kernel.org>
Sat, 2 May 2026 18:06:15 +0000 (12:06 -0600)
Some setups can have thousands of devices.

ll_init_map() is rather expensive for them.

Only call ll_init_map() in the following cases:

1) tc runs in batch mode.
2) tc runs in monitor mode.
3) tc dumps qdiscs/classes/filters for all netdev.

This greatly reduces RTNL pressure on common operations.

Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: David Ahern <dsahern@kernel.org>
tc/f_route.c
tc/m_mirred.c
tc/tc.c
tc/tc_class.c
tc/tc_filter.c
tc/tc_qdisc.c

index 96b99b06be179c90dfb0d24d9577b5206dd98ef1..c234ddf0cb9309556844c85047d0f9ef53a2fd7b 100644 (file)
@@ -76,7 +76,6 @@ static int route_parse_opt(const struct filter_util *qu, char *handle, int argc,
                        __u32 id;
 
                        NEXT_ARG();
-                       ll_init_map(&rth);
                        if ((id = ll_name_to_index(*argv)) <= 0) {
                                fprintf(stderr, "Illegal \"fromif\"\n");
                                return -1;
index f4da3c76284460d7f4bb73c7c3c172732f054632..e9ae5199432e828026f15ce226c5f5f84998c660 100644 (file)
@@ -213,8 +213,6 @@ parse_direction(const struct action_util *a, int *argc_p, char ***argv_p,
        if (d[0])  {
                int idx;
 
-               ll_init_map(&rth);
-
                idx = ll_name_to_index(d);
                if (!idx)
                        return nodev(d);
diff --git a/tc/tc.c b/tc/tc.c
index 0fc658c881f0f553f1f1f8d87b46943d4d0eed8f..7d69e4d533a98b9c071cb954443a049a52252f2c 100644 (file)
--- a/tc/tc.c
+++ b/tc/tc.c
@@ -243,6 +243,7 @@ static int batch(const char *name)
                return -1;
        }
 
+       ll_init_map(&rth);
        ret = do_batch(name, force, tc_batch_cmd, NULL);
 
        rtnl_close(&rth);
index ea6d986ae9cf1f64cc3468dc5aa82478c3208c09..310514ce560ab6c1b42665cb6c75314e45b84cd6 100644 (file)
@@ -136,11 +136,11 @@ static int tc_class_modify(int cmd, unsigned int flags, int argc, char **argv)
        }
 
        if (d[0])  {
-               ll_init_map(&rth);
-
                req.t.tcm_ifindex = ll_name_to_index(d);
                if (!req.t.tcm_ifindex)
                        return -nodev(d);
+       } else {
+               ll_init_map(&rth);
        }
 
        if (rtnl_talk(&rth, &req.n, NULL) < 0)
@@ -436,8 +436,6 @@ static int tc_class_list(int argc, char **argv)
                argc--; argv++;
        }
 
-       ll_init_map(&rth);
-
        if (d[0]) {
                t.tcm_ifindex = ll_name_to_index(d);
                if (!t.tcm_ifindex)
index b1dcf1bae54e508e21af89030f9e084dcd17c0d4..7b50402953685fe1eaba1ab7a291076cafa1e47e 100644 (file)
@@ -188,16 +188,17 @@ static int tc_filter_modify(int cmd, unsigned int flags, int argc, char **argv)
                addattr_l(&req.n, sizeof(req), TCA_KIND, k, strlen(k)+1);
 
        if (d[0])  {
-               ll_init_map(&rth);
-
                req.t.tcm_ifindex = ll_name_to_index(d);
                if (req.t.tcm_ifindex == 0) {
                        fprintf(stderr, "Cannot find device \"%s\"\n", d);
                        return 1;
                }
-       } else if (block_index) {
-               req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
-               req.t.tcm_block_index = block_index;
+       } else {
+               ll_init_map(&rth);
+               if (block_index) {
+                       req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
+                       req.t.tcm_block_index = block_index;
+               }
        }
 
        if (q) {
@@ -538,8 +539,6 @@ static int tc_filter_get(int cmd, unsigned int flags, int argc, char **argv)
        }
 
        if (d[0])  {
-               ll_init_map(&rth);
-
                req.t.tcm_ifindex = ll_name_to_index(d);
                if (!req.t.tcm_ifindex)
                        return -nodev(d);
@@ -703,21 +702,23 @@ static int tc_filter_list(int cmd, int argc, char **argv)
 
        req.t.tcm_info = TC_H_MAKE(prio<<16, protocol);
 
-       ll_init_map(&rth);
-
        if (d[0]) {
                req.t.tcm_ifindex = ll_name_to_index(d);
                if (!req.t.tcm_ifindex)
                        return -nodev(d);
                filter_ifindex = req.t.tcm_ifindex;
-       } else if (block_index) {
-               if (!tc_qdisc_block_exists(block_index)) {
-                       fprintf(stderr, "Cannot find block \"%u\"\n", block_index);
-                       return 1;
+       } else {
+               ll_init_map(&rth);
+               if (block_index) {
+                       if (!tc_qdisc_block_exists(block_index)) {
+                               fprintf(stderr, "Cannot find block \"%u\"\n",
+                                       block_index);
+                               return 1;
+                       }
+                       req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
+                       req.t.tcm_block_index = block_index;
+                       filter_block_index = block_index;
                }
-               req.t.tcm_ifindex = TCM_IFINDEX_MAGIC_BLOCK;
-               req.t.tcm_block_index = block_index;
-               filter_block_index = block_index;
        }
 
        if (filter_chain_index_set)
index 634d5f70b48a389bde75fc2349afecd43f97e9b4..b3c395b65c2f6b47abbcb6aa37b7dc1f080032e8 100644 (file)
@@ -193,8 +193,6 @@ static int tc_qdisc_modify(int cmd, unsigned int flags, int argc, char **argv)
        if (d[0])  {
                int idx;
 
-               ll_init_map(&rth);
-
                idx = ll_name_to_index(d);
                if (!idx)
                        return -nodev(d);
@@ -410,13 +408,14 @@ static int tc_qdisc_list(int argc, char **argv)
                argc--; argv++;
        }
 
-       ll_init_map(&rth);
 
        if (d[0]) {
                req.t.tcm_ifindex = ll_name_to_index(d);
                if (!req.t.tcm_ifindex)
                        return -nodev(d);
                filter_ifindex = req.t.tcm_ifindex;
+       } else {
+               ll_init_map(&rth);
        }
 
        if (dump_invisible) {