-
Notifications
You must be signed in to change notification settings - Fork 165
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add helpers for Linux Traffic Control (TC) filter #209
base: main
Are you sure you want to change the base?
Conversation
Add a helper, for_each_tcf_chain(), to iterate over all TC filter chains on a block (struct tcf_block *). As an example: >>> eth0 = netdev_get_by_name(prog, "eth0") >>> htb = qdisc_lookup(eth0, 0x1) >>> block = Object(prog, "struct htb_sched *", htb.privdata.address_).block >>> for chain in for_each_tcf_chain(block): ... print(chain.index) ... 0 1 2 This is only supported since Linux kernel commit 2190d1d0944f ("net: sched: introduce helpers to work with filter chains") in v4.13. Signed-off-by: Peilin Ye <[email protected]>
Add a helper, get_tcf_chain_by_index(), to get a TC filter chain from a block given the chain index number. As an example: >>> eth0 = netdev_get_by_name(prog, "eth0") >>> htb = qdisc_lookup(eth0, 0x1) >>> block = Object(prog, "struct htb_sched *", htb.privdata.address_).block >>> chain = get_tcf_chain_by_index(block, 0) >>> chain.filter_chain.ops.kind b'u32' This is only supported since Linux kernel commit 5bc1701881e3 ("net: sched: introduce multichain support for filters") in v4.13. Signed-off-by: Peilin Ye <[email protected]>
Add a helper, for_each_tcf_proto(), to iterate over all TC filters (struct tcf_proto *) on a filter chain. As an example: >>> eth0 = netdev_get_by_name(prog, "eth0") >>> htb = qdisc_lookup(eth0, 0x1) >>> block = Object(prog, "struct htb_sched *", htb.privdata.address_).block >>> chain = get_tcf_chain_by_index(block, 0) >>> for filter in for for_each_tcf_proto(chain): ... print(filter.ops.kind) b'u32' b'matchall' b'flower' This is only supported since Linux kernel commit 2190d1d0944f ("net: sched: introduce helpers to work with filter chains") in v4.13. Signed-off-by: Peilin Ye <[email protected]>
Add a helper, get_tcf_proto_by_prio(), to get a TC filter (struct tcf_proto *) from a chain given the priority (preference) number. As an example: >>> eth0 = netdev_get_by_name(prog, "eth0") >>> htb = qdisc_lookup(eth0, 0x1) >>> block = Object(prog, "struct htb_sched *", htb.privdata.address_).block >>> chain = get_tcf_chain_by_index(block, 0) >>> u32 = get_tcf_proto_by_prio(chain, 10) >>> u32.ops.kind b'u32' This is only supported since Linux kernel commit 2190d1d0944f ("net: sched: introduce helpers to work with filter chains") in v4.13. Signed-off-by: Peilin Ye <[email protected]>
Since we are planning to add more TestTc() tests, factor out common code and shared variables (e.g. drgn Object for network namespace). Signed-off-by: Peilin Ye <[email protected]>
Add a TestTc() test, test_tcf_chain_and_tcf_proto(), for the following helpers: for_each_tcf_chain() for_each_tcf_proto() get_tcf_chain_by_index() get_tcf_proto_by_prio() It depends on Linux kernel CONFIG_NET_SCH_HTB and CONFIG_NET_CLS_U32 configs, and is skipped if kernel is older than v4.13 (commit 5bc1701881e3 ("net: sched: introduce multichain support for filters")). It depends on the TCA_CHAIN netlink message attribute, which pyroute2 does not support yet. Use a customized class tcmsg for now. Signed-off-by: Peilin Ye <[email protected]>
2f4d457
to
43c214f
Compare
Fixed a |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I only gave this a quick look and had some questions about the kernel versions involved. I'll give it a more thorough review once that's cleared up. Thank you!
# Before Linux kernel commit 5bc1701881e3 ("net: sched: introduce | ||
# multichain support for filters") (in v4.13), each block contained only | ||
# one chain. | ||
try: | ||
chain_list = block.chain_list.address_of_() | ||
except AttributeError: | ||
# Before Linux kernel commit 2190d1d0944f ("net: sched: introduce | ||
# helpers to work with filter chains") (in v4.13), struct tcf_chain | ||
# didn't exist. | ||
return block.chain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like both of these commits went in during v4.13-rc1. I wouldn't bother checking for the intermediate state between those two commits; let's just assume that the kernel is an official tagged release, which I think will simplify this.
""" | ||
Iterate over all TC filter chains on a block. | ||
|
||
This is only supported since Linux v4.13. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not familiar with TC at all, but looking at the commits you reference here, it looks like TC filter chains didn't exist at all before 4.13, is that correct? Maybe we can say something like "This is only supported since Linux v4.13, before which TC filter chains didn't exist.".
for chain in list_for_each_entry("struct tcf_chain", chain_list, "list"): | ||
yield chain |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you can simplify this to:
for chain in list_for_each_entry("struct tcf_chain", chain_list, "list"): | |
yield chain | |
return list_for_each_entry("struct tcf_chain", chain_list, "list") |
Hi all,
These are helpers for Linux TC filter (
struct tcf_proto
) and filter chain (struct tcf_chain
) that I found useful when debugging TC issues. They are only supported since Linux v4.13 because several related data structures didn't exist before that.The test is skipped if kernel is older than v4.13 commit 5bc1701881e3 ("net: sched: introduce multichain support for filters"), and depends on config
CONFIG_NET_SCH_HTB
andCONFIG_NET_CLS_U32
. It uses theTCA_CHAIN
Netlink message attribute, which pyroute2 doesn't fully support yet, which is why the test may look a bit over-complicated. I will addTCA_CHAIN
support to pyroute2 and clean it up.Thanks,
Peilin Ye