diff --git a/lib/kernel/if.c b/lib/kernel/if.c index 846fc2d4c..5dd863420 100644 --- a/lib/kernel/if.c +++ b/lib/kernel/if.c @@ -72,7 +72,7 @@ int if_start(struct interface *i) { INDENT /* Set affinity for network interfaces (skip _loopback_ dev) */ //if_set_affinity(i, i->affinity); - + /* Assign fwmark's to socket nodes which have netem options */ int ret, mark = 0; for (size_t j = 0; j < list_length(&i->sockets); j++) { @@ -86,14 +86,6 @@ int if_start(struct interface *i) if (mark == 0) return 0; - /* Check if all kernel modules are loaded */ - if (kernel_module_load("sch_prio")) - error("Missing kernel module: sch_prio"); - if (kernel_module_load("sch_netem")) - error("Missing kernel module: sch_netem"); - if (kernel_module_load("cls_fw")) - error("Missing kernel module: cls_fw"); - /* Replace root qdisc */ ret = tc_prio(i, &i->tc_qdisc, TC_HANDLE(1, 0), TC_H_ROOT, mark); if (ret) @@ -107,7 +99,7 @@ int if_start(struct interface *i) ret = tc_mark(i, &s->tc_classifier, TC_HANDLE(1, s->mark), s->mark); if (ret) error("Failed to setup FW mark classifier: %s", nl_geterror(ret)); - + char *buf = tc_print(s->tc_qdisc); debug(LOG_IF | 5, "Starting network emulation on interface '%s' for FW mark %u: %s", rtnl_link_get_name(i->nl_link), s->mark, buf); diff --git a/lib/kernel/tc.c b/lib/kernel/tc.c index 9332e36e2..1d113b4fb 100644 --- a/lib/kernel/tc.c +++ b/lib/kernel/tc.c @@ -28,6 +28,7 @@ #include +#include "kernel/kernel.h" #include "kernel/if.h" #include "kernel/tc.h" #include "kernel/nl.h" @@ -154,6 +155,10 @@ int tc_prio(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hdl struct nl_sock *sock = nl_init(); struct rtnl_qdisc *q = rtnl_qdisc_alloc(); + ret = kernel_module_load("sch_prio"); + if (ret) + error("Failed to load kernel module: sch_prio (%d)", ret); + /* This is the default priomap used by the tc-prio qdisc * We will use the first 'bands' bands internally */ uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP; @@ -179,15 +184,20 @@ int tc_prio(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hdl int tc_netem(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hdl_t parent) { + int ret; struct nl_sock *sock = nl_init(); struct rtnl_qdisc *q = *qd; + ret = kernel_module_load("sch_netem"); + if (ret) + error("Failed to load kernel module: sch_netem (%d)", ret); + rtnl_tc_set_link(TC_CAST(q), i->nl_link); rtnl_tc_set_parent(TC_CAST(q), parent); rtnl_tc_set_handle(TC_CAST(q), handle); //rtnl_tc_set_kind(TC_CAST(q), "netem"); - int ret = rtnl_qdisc_add(sock, q, NLM_F_CREATE); + ret = rtnl_qdisc_add(sock, q, NLM_F_CREATE); *qd = q; @@ -198,9 +208,14 @@ int tc_netem(struct interface *i, struct rtnl_qdisc **qd, tc_hdl_t handle, tc_hd int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_t mark) { + int ret; struct nl_sock *sock = nl_init(); struct rtnl_cls *c = rtnl_cls_alloc(); + ret = kernel_module_load("cls_fw"); + if (ret) + error("Failed to load kernel module: cls_fw"); + rtnl_tc_set_link(TC_CAST(c), i->nl_link); rtnl_tc_set_handle(TC_CAST(c), mark); rtnl_tc_set_kind(TC_CAST(c), "fw"); @@ -210,7 +225,7 @@ int tc_mark(struct interface *i, struct rtnl_cls **cls, tc_hdl_t flowid, uint32_ rtnl_fw_set_classid(c, flowid); rtnl_fw_set_mask(c, 0xFFFFFFFF); - int ret = rtnl_cls_add(sock, c, NLM_F_CREATE); + ret = rtnl_cls_add(sock, c, NLM_F_CREATE); *cls = c;