summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSusant Sahani <ssahani@vmware.com>2019-12-07 17:46:37 +0100
committerYu Watanabe <watanabe.yu+github@gmail.com>2019-12-11 00:06:31 +0900
commitd808102008327864d2194c1917002fbc0b1e4386 (patch)
tree4d93e4f6bafa0f2d845dfd38f2937c9a2da51689
parentbfb68540d5016a107975ada8352ec843fa1c532e (diff)
downloadsystemd-d808102008327864d2194c1917002fbc0b1e4386.tar.gz
network tc: qdisc parent add support to set ingress
``` $ network tc qdisc qdisc noqueue 0: dev dummy99 root refcnt 2 qdisc ingress ffff: dev dummy99 parent ffff:fff1 ---------------- $ network cat dumm99.network [Match] Name=dummy99 [TrafficControlQueueingDiscipline] Parent=ingress ```
-rw-r--r--man/systemd.network.xml4
-rw-r--r--src/network/tc/qdisc.c40
-rw-r--r--src/network/tc/qdisc.h1
3 files changed, 29 insertions, 16 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 692a686020..a23f0e6c23 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -2327,8 +2327,8 @@
<varlistentry>
<term><varname>Parent=</varname></term>
<listitem>
- <para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>
- or <literal>clsact</literal>. Defaults to <literal>root</literal>.</para>
+ <para>Specifies the parent Queueing Discipline (qdisc). Takes one of <literal>root</literal>,
+ <literal>clsact</literal> or <literal>ingress</literal>. Defaults to <literal>root</literal>.</para>
</listitem>
</varlistentry>
diff --git a/src/network/tc/qdisc.c b/src/network/tc/qdisc.c
index 74b2b7a2c2..57e3025d7c 100644
--- a/src/network/tc/qdisc.c
+++ b/src/network/tc/qdisc.c
@@ -84,6 +84,7 @@ void qdisc_free(QDisc *qdisc) {
network_config_section_free(qdisc->section);
+ free(qdisc->tca_kind);
free(qdisc);
}
@@ -116,6 +117,7 @@ static int qdisc_handler(sd_netlink *rtnl, sd_netlink_message *m, Link *link) {
int qdisc_configure(Link *link, QDisc *qdisc) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *req = NULL;
_cleanup_free_ char *tca_kind = NULL;
+ char *p;
int r;
assert(link);
@@ -131,12 +133,8 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
if (r < 0)
return log_link_error_errno(link, r, "Could not create tcm_parent message: %m");
- if (qdisc->parent == TC_H_CLSACT) {
- tca_kind = strdup("clsact");
- if (!tca_kind)
- return log_oom();
-
- r = sd_rtnl_message_set_qdisc_handle(req, TC_H_MAKE(TC_H_CLSACT, 0));
+ if (qdisc->handle != TC_H_UNSPEC) {
+ r = sd_rtnl_message_set_qdisc_handle(req, qdisc->handle);
if (r < 0)
return log_link_error_errno(link, r, "Could not set tcm_handle message: %m");
}
@@ -171,8 +169,9 @@ int qdisc_configure(Link *link, QDisc *qdisc) {
return r;
}
- if (tca_kind) {
- r = sd_netlink_message_append_string(req, TCA_KIND, tca_kind);
+ p = tca_kind ?:qdisc->tca_kind;
+ if (p) {
+ r = sd_netlink_message_append_string(req, TCA_KIND, p);
if (r < 0)
return log_link_error_errno(link, r, "Could not append TCA_KIND attribute: %m");
}
@@ -218,10 +217,10 @@ int qdisc_section_verify(QDisc *qdisc, bool *has_root, bool *has_clsact) {
"Ignoring [TrafficControlQueueingDiscipline] section from line %u.",
qdisc->section->filename, qdisc->section->line);
*has_root = true;
- } else if (qdisc->parent == TC_H_CLSACT) {
+ } else if (qdisc->parent == TC_H_CLSACT) { /* TC_H_CLSACT == TC_H_INGRESS */
if (*has_clsact)
return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
- "%s: More than one clsact TrafficControlQueueingDiscipline sections are defined. "
+ "%s: More than one clsact or ingress TrafficControlQueueingDiscipline sections are defined. "
"Ignoring [TrafficControlQueueingDiscipline] section from line %u.",
qdisc->section->filename, qdisc->section->line);
*has_clsact = true;
@@ -255,17 +254,30 @@ int config_parse_tc_qdiscs_parent(
if (r < 0)
return r;
- if (streq(rvalue, "root"))
+ if (streq(rvalue, "root")) {
qdisc->parent = TC_H_ROOT;
- else if (streq(rvalue, "clsact"))
+ qdisc->handle = TC_H_UNSPEC;
+ } else if (streq(rvalue, "clsact")) {
qdisc->parent = TC_H_CLSACT;
- else {
+ qdisc->handle = TC_H_MAKE(TC_H_CLSACT, 0);
+ } else if (streq(rvalue, "ingress")) {
+ qdisc->parent = TC_H_INGRESS;
+ qdisc->handle = TC_H_MAKE(TC_H_INGRESS, 0);
+ } else {
log_syntax(unit, LOG_ERR, filename, line, r,
- "Failed to parse [QueueDiscs] 'Parent=', ignoring assignment: %s",
+ "Failed to parse 'Parent=', ignoring assignment: %s",
rvalue);
return 0;
}
+ if (streq(rvalue, "root"))
+ qdisc->tca_kind = mfree(qdisc->tca_kind);
+ else {
+ r = free_and_strdup(&qdisc->tca_kind, rvalue);
+ if (r < 0)
+ return log_oom();
+ }
+
qdisc = NULL;
return 0;
diff --git a/src/network/tc/qdisc.h b/src/network/tc/qdisc.h
index 1d06dc53f4..cc68bdfaa7 100644
--- a/src/network/tc/qdisc.h
+++ b/src/network/tc/qdisc.h
@@ -21,6 +21,7 @@ typedef struct QDisc {
uint32_t handle;
uint32_t parent;
+ char *tca_kind;
bool has_network_emulator:1;
bool has_token_buffer_filter:1;
bool has_stochastic_fairness_queueing:1;