[RFC] iproute2, ifindex option

Denys Fedoryshchenko
2011-07-18T08:38:37Z

[-- Attachment #1: Type: text/plain, Size: 1176 bytes --]

After battling with iproute2 interface name caching, i decided to try
to introduce ifindex option, where i can specify manually device index,
and avoid expensive device index lookups, especially during massive
changes for qdisc/class.
In batch mode ll_map cache will cause problems on servers with ppp
interfaces (same name after while can have another index), and also if i
run command too often, each start it will retrieve list of all
interfaces, on 3k+ interfaces it will be CPU hog.

This is sample of patch, just for qdisc/class/filter modify and show
operation.

Here is some changes in logic, because before qdisc code during _list
operation was not checking duplicate "dev" argument, as it done in
_modify code and class/filter list code.

Also maybe i need to change duparg to something else? Because:
centaur iproute2-newifindex # tc/tc -s -d filter show ifindex 23 dev
sdf
Error: duplicate "ifindex": "sdf" is the second value.
Or it is ok like this?

I'm sorry that patch is not inline, seems my webmail can't do it now, i
will try to install normal mail client.

---
System administrator
Denys Fedoryshchenko
Virtual ISP S.A.L.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: ifindex-option.diff --]
[-- Type: text/x-diff; name=ifindex-option.diff, Size: 4455 bytes --]

diff -Naur iproute2/tc/tc_class.c iproute2-newifindex/tc/tc_class.c
--- iproute2/tc/tc_class.c 2011-07-18 11:10:41.390973397 +0300
+++ iproute2-newifindex/tc/tc_class.c 2011-07-18 11:29:50.177611576 +0300
@@ -67,7 +67,16 @@
NEXT_ARG();
if (d[0])
duparg("dev", *argv);
+ if (req.t.tcm_ifindex)
+ duparg("ifindex", *argv);
strncpy(d, *argv, sizeof(d)-1);
+ } else if (strcmp(*argv, "ifindex") == 0) {
+ NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (req.t.tcm_ifindex)
+ duparg("ifindex", *argv);
+ req.t.tcm_ifindex = atoi(*argv);
} else if (strcmp(*argv, "classid") == 0) {
__u32 handle;
NEXT_ARG();
@@ -246,7 +255,16 @@
NEXT_ARG();
if (d[0])
duparg("dev", *argv);
+ if (t.tcm_ifindex)
+ duparg("ifindex", *argv);
strncpy(d, *argv, sizeof(d)-1);
+ } else if (strcmp(*argv, "ifindex") == 0) {
+ NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (t.tcm_ifindex)
+ duparg("ifindex", *argv);
+ t.tcm_ifindex = atoi(*argv);
} else if (strcmp(*argv, "qdisc") == 0) {
NEXT_ARG();
if (filter_qdisc)
@@ -290,9 +308,10 @@
fprintf(stderr, "Cannot find device \"%s\"\n", d);
return 1;
}
- filter_ifindex = t.tcm_ifindex;
}

+ filter_ifindex = t.tcm_ifindex;
+
if (rtnl_dump_request(&rth, RTM_GETTCLASS, &t, sizeof(t)) < 0) {
perror("Cannot send dump request");
return 1;
diff -Naur iproute2/tc/tc_filter.c iproute2-newifindex/tc/tc_filter.c
--- iproute2/tc/tc_filter.c 2011-07-18 11:10:41.390973397 +0300
+++ iproute2-newifindex/tc/tc_filter.c 2011-07-18 11:28:18.097762745 +0300
@@ -80,7 +80,16 @@
NEXT_ARG();
if (d[0])
duparg("dev", *argv);
+ if (req.t.tcm_ifindex)
+ duparg("ifindex", *argv);
strncpy(d, *argv, sizeof(d)-1);
+ } else if (strcmp(*argv, "ifindex") == 0) {
+ NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (req.t.tcm_ifindex)
+ duparg("ifindex", *argv);
+ req.t.tcm_ifindex = atoi(*argv);
} else if (strcmp(*argv, "root") == 0) {
if (req.t.tcm_parent) {
fprintf(stderr, "Error: \"root\" is duplicate parent ID\n");
@@ -277,7 +286,16 @@
NEXT_ARG();
if (d[0])
duparg("dev", *argv);
+ if (t.tcm_ifindex)
+ duparg("ifindex", *argv);
strncpy(d, *argv, sizeof(d)-1);
+ } else if (strcmp(*argv, "ifindex") == 0) {
+ NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (t.tcm_ifindex)
+ duparg("ifindex", *argv);
+ t.tcm_ifindex = atoi(*argv);
} else if (strcmp(*argv, "root") == 0) {
if (t.tcm_parent) {
fprintf(stderr, "Error: \"root\" is duplicate parent ID\n");
@@ -332,10 +350,11 @@
if ((t.tcm_ifindex = ll_name_to_index(d)) == 0) {
fprintf(stderr, "Cannot find device \"%s\"\n", d);
return 1;
- }
- filter_ifindex = t.tcm_ifindex;
+ }
}

+ filter_ifindex = t.tcm_ifindex;
+
if (rtnl_dump_request(&rth, RTM_GETTFILTER, &t, sizeof(t)) < 0) {
perror("Cannot send dump request");
return 1;
diff -Naur iproute2/tc/tc_qdisc.c iproute2-newifindex/tc/tc_qdisc.c
--- iproute2/tc/tc_qdisc.c 2011-07-18 11:10:41.390973397 +0300
+++ iproute2-newifindex/tc/tc_qdisc.c 2011-07-18 11:29:09.322122349 +0300
@@ -76,7 +76,16 @@
NEXT_ARG();
if (d[0])
duparg("dev", *argv);
+ if (req.t.tcm_ifindex)
+ duparg("ifindex", *argv);
strncpy(d, *argv, sizeof(d)-1);
+ } else if (strcmp(*argv, "ifindex") == 0) {
+ NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (req.t.tcm_ifindex)
+ duparg("ifindex", *argv);
+ req.t.tcm_ifindex = atoi(*argv);
} else if (strcmp(*argv, "handle") == 0) {
__u32 handle;
if (req.t.tcm_handle)
@@ -289,7 +298,18 @@
while (argc > 0) {
if (strcmp(*argv, "dev") == 0) {
NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (t.tcm_ifindex)
+ duparg("ifindex", *argv);
strncpy(d, *argv, sizeof(d)-1);
+ } else if (strcmp(*argv, "ifindex") == 0) {
+ NEXT_ARG();
+ if (d[0])
+ duparg("dev", *argv);
+ if (t.tcm_ifindex)
+ duparg("ifindex", *argv);
+ t.tcm_ifindex = atoi(*argv);
#ifdef TC_H_INGRESS
} else if (strcmp(*argv, "ingress") == 0) {
if (t.tcm_parent) {
@@ -315,9 +335,10 @@
fprintf(stderr, "Cannot find device \"%s\"\n", d);
return 1;
}
- filter_ifindex = t.tcm_ifindex;
}

+ filter_ifindex = t.tcm_ifindex;
+
if (rtnl_dump_request(&rth, RTM_GETQDISC, &t, sizeof(t)) < 0) {
perror("Cannot send dump request");
return 1;