| /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
| |
| #include "macro.h" |
| #include "qdisc.h" |
| #include "tc.h" |
| #include "tclass.h" |
| |
| void traffic_control_free(TrafficControl *tc) { |
| if (!tc) |
| return; |
| |
| switch (tc->kind) { |
| case TC_KIND_QDISC: |
| qdisc_free(TC_TO_QDISC(tc)); |
| break; |
| case TC_KIND_TCLASS: |
| tclass_free(TC_TO_TCLASS(tc)); |
| break; |
| default: |
| assert_not_reached("Invalid traffic control type"); |
| } |
| } |
| |
| static int traffic_control_configure(Link *link, TrafficControl *tc) { |
| assert(link); |
| assert(tc); |
| |
| switch(tc->kind) { |
| case TC_KIND_QDISC: |
| return qdisc_configure(link, TC_TO_QDISC(tc)); |
| case TC_KIND_TCLASS: |
| return tclass_configure(link, TC_TO_TCLASS(tc)); |
| default: |
| assert_not_reached("Invalid traffic control type"); |
| } |
| } |
| |
| int link_configure_traffic_control(Link *link) { |
| TrafficControl *tc; |
| int r; |
| |
| assert(link); |
| assert(link->network); |
| |
| if (link->tc_messages != 0) { |
| log_link_debug(link, "Traffic control is configuring."); |
| return 0; |
| } |
| |
| link->tc_configured = false; |
| |
| ORDERED_HASHMAP_FOREACH(tc, link->network->tc_by_section) { |
| r = traffic_control_configure(link, tc); |
| if (r < 0) |
| return r; |
| } |
| |
| if (link->tc_messages == 0) |
| link->tc_configured = true; |
| else |
| log_link_debug(link, "Configuring traffic control"); |
| |
| return 0; |
| } |
| |
| static int traffic_control_section_verify(TrafficControl *tc, bool *qdisc_has_root, bool *qdisc_has_clsact) { |
| assert(tc); |
| |
| switch(tc->kind) { |
| case TC_KIND_QDISC: |
| return qdisc_section_verify(TC_TO_QDISC(tc), qdisc_has_root, qdisc_has_clsact); |
| case TC_KIND_TCLASS: |
| return tclass_section_verify(TC_TO_TCLASS(tc)); |
| default: |
| assert_not_reached("Invalid traffic control type"); |
| } |
| } |
| |
| void network_drop_invalid_traffic_control(Network *network) { |
| bool has_root = false, has_clsact = false; |
| TrafficControl *tc; |
| |
| assert(network); |
| |
| ORDERED_HASHMAP_FOREACH(tc, network->tc_by_section) |
| if (traffic_control_section_verify(tc, &has_root, &has_clsact) < 0) |
| traffic_control_free(tc); |
| } |