[qca-nss-qdisc] Handle NULL opt
New version of TC provides a NULL netlink message when users dont configure
any of the supported tunable parameters. Therefore a create request with NULL
message is still valid and has to be processed.
This affects qdiscs that only have non-mandatory input parameters. In our
list of supported qdiscs nssbf, nsshtb and nssprio falls in this category.
Change-Id: Ic303eeea38fca0f0af25de8a7fee66d89c9d2b61
Signed-off-by: Sakthi Vignesh Radhakrishnan <sradhakr@codeaurora.org>
diff --git a/nss_qdisc/nss_bf.c b/nss_qdisc/nss_bf.c
index df2f820..7aecb95 100644
--- a/nss_qdisc/nss_bf.c
+++ b/nss_qdisc/nss_bf.c
@@ -16,8 +16,11 @@
#include "nss_qdisc.h"
+/*
+ * nss_bf class instance structure
+ */
struct nss_bf_class_data {
- struct nss_qdisc nq; /* Base class used by nss_qdisc */
+ struct nss_qdisc nq; /* Base class used by nss_qdisc */
struct Qdisc_class_common cl_common; /* Common class structure */
u32 rate; /* Allowed bandwidth for this class */
u32 burst; /* Allowed burst for this class */
@@ -26,13 +29,20 @@
struct Qdisc *qdisc; /* Pointer to child qdisc */
};
+/*
+ * nss_bf qdisc instance structure
+ */
struct nss_bf_sched_data {
- struct nss_qdisc nq; /* Base class used by nss_qdisc */
+ struct nss_qdisc nq; /* Base class used by nss_qdisc */
u16 defcls; /* default class id */
struct nss_bf_class_data root; /* root class */
struct Qdisc_class_hash clhash; /* class hash */
};
+/*
+ * nss_bf_find_class()
+ * Returns a pointer to class if classid matches with a class under this qdisc.
+ */
static inline struct nss_bf_class_data *nss_bf_find_class(u32 classid,
struct Qdisc *sch)
{
@@ -46,10 +56,17 @@
return container_of(clc, struct nss_bf_class_data, cl_common);
}
+/*
+ * nss_bf_policy structure
+ */
static const struct nla_policy nss_bf_policy[TCA_NSSBF_MAX + 1] = {
[TCA_NSSBF_CLASS_PARMS] = { .len = sizeof(struct tc_nssbf_class_qopt) },
};
+/*
+ * nss_bf_change_class()
+ * Configures a new class.
+ */
static int nss_bf_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
struct nlattr **tca, unsigned long *arg)
{
@@ -63,15 +80,15 @@
struct net_device *dev = qdisc_dev(sch);
nss_qdisc_info("%s: Changing bf class %u\n", __func__, classid);
- if (opt == NULL)
- return -EINVAL;
+ if (opt == NULL)
+ return -EINVAL;
- err = nla_parse_nested(na, TCA_NSSBF_MAX, opt, nss_bf_policy);
- if (err < 0)
- return err;
+ err = nla_parse_nested(na, TCA_NSSBF_MAX, opt, nss_bf_policy);
+ if (err < 0)
+ return err;
- if (na[TCA_NSSBF_CLASS_PARMS] == NULL)
- return -EINVAL;
+ if (na[TCA_NSSBF_CLASS_PARMS] == NULL)
+ return -EINVAL;
/*
* If class with a given classid is not found, we allocate a new one
@@ -206,6 +223,10 @@
return 0;
}
+/*
+ * nss_bf_destroy_class()
+ * Detaches all child nodes and destroys the class.
+ */
static void nss_bf_destroy_class(struct Qdisc *sch, struct nss_bf_class_data *cl)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
@@ -260,6 +281,10 @@
kfree(cl);
}
+/*
+ * nss_bf_delete_class()
+ * Detaches a class from operation, but does not destroy it.
+ */
static int nss_bf_delete_class(struct Qdisc *sch, unsigned long arg)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
@@ -298,6 +323,10 @@
return 0;
}
+/*
+ * nss_bf_graft_class()
+ * Replaces the qdisc attached to the provided class.
+ */
static int nss_bf_graft_class(struct Qdisc *sch, unsigned long arg, struct Qdisc *new,
struct Qdisc **old)
{
@@ -362,6 +391,10 @@
return 0;
}
+/*
+ * nss_bf_leaf_class()
+ * Returns pointer to qdisc if leaf class.
+ */
static struct Qdisc *nss_bf_leaf_class(struct Qdisc *sch, unsigned long arg)
{
struct nss_bf_class_data *cl = (struct nss_bf_class_data *)arg;
@@ -374,6 +407,10 @@
return cl->qdisc;
}
+/*
+ * nss_bf_qlen_notify()
+ * We dont maintain a live set of stats in linux, so this function is not implemented.
+ */
static void nss_bf_qlen_notify(struct Qdisc *sch, unsigned long arg)
{
nss_qdisc_info("bf qlen notify %p\n", sch);
@@ -383,6 +420,10 @@
*/
}
+/*
+ * nss_bf_get_class()
+ * Fetches the class pointer if provided the classid.
+ */
static unsigned long nss_bf_get_class(struct Qdisc *sch, u32 classid)
{
struct nss_bf_class_data *cl = nss_bf_find_class(classid, sch);
@@ -395,6 +436,10 @@
return (unsigned long)cl;
}
+/*
+ * nss_bf_put_class()
+ * Reduces reference count for this class.
+ */
static void nss_bf_put_class(struct Qdisc *sch, unsigned long arg)
{
struct nss_bf_class_data *cl = (struct nss_bf_class_data *)arg;
@@ -409,6 +454,10 @@
}
}
+/*
+ * nss_bf_dump_class()
+ * Dumps all configurable parameters pertaining to this class.
+ */
static int nss_bf_dump_class(struct Qdisc *sch, unsigned long arg, struct sk_buff *skb,
struct tcmsg *tcm)
{
@@ -443,6 +492,10 @@
return -EMSGSIZE;
}
+/*
+ * nss_bf_dump_class_stats()
+ * Dumps class statistics.
+ */
static int nss_bf_dump_class_stats(struct Qdisc *sch, unsigned long arg, struct gnet_dump *d)
{
struct nss_qdisc *nq = (struct nss_qdisc *)arg;
@@ -455,6 +508,10 @@
return 0;
}
+/*
+ * nss_bf_walk()
+ * Used to walk the tree.
+ */
static void nss_bf_walk(struct Qdisc *sch, struct qdisc_walker *arg)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
@@ -482,71 +539,66 @@
}
}
-static int nss_bf_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
-{
- struct nss_bf_sched_data *q = qdisc_priv(sch);
- struct tc_nssbf_qopt *qopt;
- int err;
-
- nss_qdisc_info("Init bf qdisc %p\n", sch);
- if (opt == NULL || nla_len(opt) < sizeof(*qopt))
- return -EINVAL;
- qopt = nla_data(opt);
-
- q->defcls = qopt->defcls;
- err = qdisc_class_hash_init(&q->clhash);
- if (err < 0)
- return err;
-
- q->root.cl_common.classid = sch->handle;
- q->root.qdisc = &noop_qdisc;
-
- qdisc_class_hash_insert(&q->clhash, &q->root.cl_common);
- qdisc_class_hash_grow(sch, &q->clhash);
-
- /*
- * Initialize the NSSBF shaper in NSS
- */
- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_BF, 0) < 0)
- return -EINVAL;
-
- nss_qdisc_info("Nssbf initialized - handle %x parent %x\n", sch->handle, sch->parent);
-
- /*
- * Start the stats polling timer
- */
- nss_qdisc_start_basic_stats_polling(&q->nq);
-
- return 0;
-}
-
+/*
+ * nss_bf_change_qdisc()
+ * Can be used to configure a nssbf qdisc.
+ */
static int nss_bf_change_qdisc(struct Qdisc *sch, struct nlattr *opt)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
struct tc_nssbf_qopt *qopt;
/*
- * NSSBF does not care about the defcls, so we dont send down any
- * configuration parameter.
+ * Since nssbf can be created with no arguments, opt might be NULL
+ * (depending on the kernel version). This is still a valid create
+ * request.
*/
- nss_qdisc_info("Changing bf qdisc %p\n", sch);
- if (opt == NULL || nla_len(opt) < sizeof(*qopt))
- return -EINVAL;
- qopt = nla_data(opt);
+ if (opt == NULL) {
+ /*
+ * If no parameter is passed, set it to 0 and continue
+ * creating the qdisc.
+ */
+ sch_tree_lock(sch);
+ q->defcls = 0;
+ sch_tree_unlock(sch);
+ return 0;
+ }
+
+ /*
+ * If it is not NULL, check if the size of message is valid.
+ */
+ if (nla_len(opt) < sizeof(*qopt)) {
+ nss_qdisc_warning("Invalid message length: size %d expected >= %u\n", nla_len(opt), sizeof(*qopt));
+ return -EINVAL;
+ }
+ qopt = nla_data(opt);
sch_tree_lock(sch);
q->defcls = qopt->defcls;
sch_tree_unlock(sch);
+ /*
+ * This information is unused in the NSS. So we do not send
+ * a configuration message down.
+ */
+
return 0;
}
+/*
+ * nss_bf_reset_class()
+ * Resets child qdisc of class to be reset.
+ */
static void nss_bf_reset_class(struct nss_bf_class_data *cl)
{
nss_qdisc_reset(cl->qdisc);
nss_qdisc_info("Nssbf class resetted %p\n", cl->qdisc);
}
+/*
+ * nss_bf_reset_qdisc()
+ * Resets nssbf qdisc and its classes.
+ */
static void nss_bf_reset_qdisc(struct Qdisc *sch)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
@@ -563,6 +615,10 @@
nss_qdisc_info("Nssbf qdisc resetted %p\n", sch);
}
+/*
+ * nss_bf_destroy_qdisc()
+ * Call to destroy a nssbf qdisc and its associated classes.
+ */
static void nss_bf_destroy_qdisc(struct Qdisc *sch)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
@@ -629,6 +685,55 @@
nss_qdisc_info("Nssbf destroyed %p\n", sch);
}
+/*
+ * nss_bf_init_qdisc()
+ * Initializes the nssbf qdisc.
+ */
+static int nss_bf_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct nss_bf_sched_data *q = qdisc_priv(sch);
+ int err;
+
+ nss_qdisc_info("Init bf qdisc %p\n", sch);
+
+ err = qdisc_class_hash_init(&q->clhash);
+ if (err < 0)
+ return err;
+
+ q->root.cl_common.classid = sch->handle;
+ q->root.qdisc = &noop_qdisc;
+
+ qdisc_class_hash_insert(&q->clhash, &q->root.cl_common);
+ qdisc_class_hash_grow(sch, &q->clhash);
+
+ /*
+ * Initialize the NSSBF shaper in NSS
+ */
+ if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_BF, 0) < 0)
+ return -EINVAL;
+
+ nss_qdisc_info("Nssbf initialized - handle %x parent %x\n", sch->handle, sch->parent);
+
+ /*
+ * Tune nss_bf parameters.
+ */
+ if (nss_bf_change_qdisc(sch, opt) < 0) {
+ nss_qdisc_destroy(&q->nq);
+ return -EINVAL;
+ }
+
+ /*
+ * Start the stats polling timer
+ */
+ nss_qdisc_start_basic_stats_polling(&q->nq);
+
+ return 0;
+}
+
+/*
+ * nss_bf_dump_qdisc()
+ * Dumps nssbf qdisc's configurable parameters.
+ */
static int nss_bf_dump_qdisc(struct Qdisc *sch, struct sk_buff *skb)
{
struct nss_bf_sched_data *q = qdisc_priv(sch);
@@ -652,22 +757,39 @@
return -1;
}
+/*
+ * nss_bf_enqueue()
+ * Enqueues a skb to nssbf qdisc.
+ */
static int nss_bf_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
return nss_qdisc_enqueue(skb, sch);
}
+/*
+ * nss_bf_dequeue()
+ * Dequeues a skb to nssbf qdisc.
+ */
static struct sk_buff *nss_bf_dequeue(struct Qdisc *sch)
{
return nss_qdisc_dequeue(sch);
}
+/*
+ * nss_bf_drop()
+ * Drops a single skb from linux queue, if not empty.
+ *
+ * Does not drop packets that are queued in the NSS.
+ */
static unsigned int nss_bf_drop(struct Qdisc *sch)
{
printk("In bf drop\n");
return nss_qdisc_drop(sch);
}
+/*
+ * Registration structure for nssbf class
+ */
const struct Qdisc_class_ops nss_bf_class_ops = {
.change = nss_bf_change_class,
.delete = nss_bf_delete_class,
@@ -681,6 +803,9 @@
.walk = nss_bf_walk
};
+/*
+ * Registration structure for nssbf qdisc
+ */
struct Qdisc_ops nss_bf_qdisc_ops __read_mostly = {
.id = "nssbf",
.init = nss_bf_init_qdisc,
@@ -696,4 +821,3 @@
.priv_size = sizeof(struct nss_bf_sched_data),
.owner = THIS_MODULE
};
-
diff --git a/nss_qdisc/nss_htb.c b/nss_qdisc/nss_htb.c
index a01c101..e617bf9 100644
--- a/nss_qdisc/nss_htb.c
+++ b/nss_qdisc/nss_htb.c
@@ -668,54 +668,6 @@
}
/*
- * nss_htb_init_qdisc()
- * Initializes the htb qdisc.
- */
-static int nss_htb_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
-{
- struct nss_htb_sched_data *q = qdisc_priv(sch);
- struct tc_nsshtb_qopt *qopt;
- int err;
-
- nss_qdisc_trace("%s: initializing htb qdisc %x\n", __func__, sch->handle);
-
- if (opt == NULL || nla_len(opt) < sizeof(*qopt)) {
- nss_qdisc_error("%s: error in input parameter for htb qdisc %x\n",
- __func__, sch->handle);
- return -EINVAL;
- }
-
- qopt = nla_data(opt);
-
- sch_tree_lock(sch);
- q->r2q = qopt->r2q;
- sch_tree_unlock(sch);
-
- err = qdisc_class_hash_init(&q->clhash);
- if (err < 0) {
- nss_qdisc_error("%s: hash init failed for htb qdisc %x", __func__, sch->handle);
- return err;
- }
-
- /*
- * Initialize the NSSHTB shaper in NSS
- */
- if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_HTB, 0) < 0) {
- nss_qdisc_error("%s: failed to initialize htb qdisc %x in nss", __func__, sch->handle);
- return -EINVAL;
- }
-
- nss_qdisc_info("%s: htb qdisc initialized with handle %x\n", __func__, sch->handle);
-
- /*
- * Start the stats polling timer
- */
- nss_qdisc_start_basic_stats_polling(&q->nq);
-
- return 0;
-}
-
-/*
* nss_htb_change_qdisc()
* Can be used to configure a htb qdisc.
*/
@@ -724,19 +676,41 @@
struct nss_htb_sched_data *q = qdisc_priv(sch);
struct tc_nsshtb_qopt *qopt;
- nss_qdisc_trace("%s: configuring htb qdisc %x\n", __func__, sch->handle);
- if (opt == NULL || nla_len(opt) < sizeof(*qopt)) {
- nss_qdisc_error("%s: error in configuration parameter for qdisc %x\n",
- __func__, sch->handle);
- return -EINVAL;
+ /*
+ * Since nsshtb can be created with no arguments, opt might be NULL
+ * (depending on the kernel version). This is still a valid create
+ * request.
+ */
+ if (opt == NULL) {
+
+ /*
+ * If no parameter is passed, set it to 0 and continue
+ * creating the qdisc.
+ */
+ sch_tree_lock(sch);
+ q->r2q = 0;
+ sch_tree_unlock(sch);
+ return 0;
}
+ /*
+ * If it is not NULL, check if the size of message is valid.
+ */
+ if (nla_len(opt) < sizeof(*qopt)) {
+ nss_qdisc_warning("Invalid message length: size %d expected >= %u\n", nla_len(opt), sizeof(*qopt));
+ return -EINVAL;
+ }
qopt = nla_data(opt);
sch_tree_lock(sch);
q->r2q = qopt->r2q;
sch_tree_unlock(sch);
+ /*
+ * The r2q parameter is not needed in the firmware. So we do not
+ * send down a configuration message.
+ */
+
return 0;
}
@@ -825,6 +799,49 @@
}
/*
+ * nss_htb_init_qdisc()
+ * Initializes the htb qdisc.
+ */
+static int nss_htb_init_qdisc(struct Qdisc *sch, struct nlattr *opt)
+{
+ struct nss_htb_sched_data *q = qdisc_priv(sch);
+ int err;
+
+ nss_qdisc_trace("%s: initializing htb qdisc %x\n", __func__, sch->handle);
+
+ err = qdisc_class_hash_init(&q->clhash);
+ if (err < 0) {
+ nss_qdisc_error("%s: hash init failed for htb qdisc %x", __func__, sch->handle);
+ return err;
+ }
+
+ /*
+ * Initialize the NSSHTB shaper in NSS
+ */
+ if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_HTB, 0) < 0) {
+ nss_qdisc_error("%s: failed to initialize htb qdisc %x in nss", __func__, sch->handle);
+ return -EINVAL;
+ }
+
+ nss_qdisc_info("%s: htb qdisc initialized with handle %x\n", __func__, sch->handle);
+
+ /*
+ * Tune HTB parameters
+ */
+ if (nss_htb_change_qdisc(sch, opt) < 0) {
+ nss_qdisc_destroy(&q->nq);
+ return -EINVAL;
+ }
+
+ /*
+ * Start the stats polling timer
+ */
+ nss_qdisc_start_basic_stats_polling(&q->nq);
+
+ return 0;
+}
+
+/*
* nss_htb_dump_qdisc()
* Dumps htb qdisc's configurable parameters.
*/
@@ -871,7 +888,7 @@
/*
* nss_htb_drop()
- * Drops a single sbk from linux queue, if not empty.
+ * Drops a single skb from linux queue, if not empty.
*
* Does not drop packets that are queued in the NSS.
*/
diff --git a/nss_qdisc/nss_prio.c b/nss_qdisc/nss_prio.c
index fc91c42..2d5ecea 100644
--- a/nss_qdisc/nss_prio.c
+++ b/nss_qdisc/nss_prio.c
@@ -16,38 +16,67 @@
#include "nss_qdisc.h"
+/*
+ * nssprio qdisc instance structure
+ */
struct nss_prio_sched_data {
- struct nss_qdisc nq; /* Common base class for all nss qdiscs */
+ struct nss_qdisc nq; /* Common base class for all nss qdiscs */
int bands; /* Number of priority bands to use */
struct Qdisc *queues[TCA_NSSPRIO_MAX_BANDS];
/* Array of child qdisc holder */
};
+/*
+ * nss_prio_enqueue()
+ * Enqueues a skb to nssprio qdisc.
+ */
static int nss_prio_enqueue(struct sk_buff *skb, struct Qdisc *sch)
{
return nss_qdisc_enqueue(skb, sch);
}
+/*
+ * nss_prio_dequeue()
+ * Dequeues a skb to nssprio qdisc.
+ */
static struct sk_buff *nss_prio_dequeue(struct Qdisc *sch)
{
return nss_qdisc_dequeue(sch);
}
+/*
+ * nss_prio_drop()
+ * Drops a single skb from linux queue, if not empty.
+ *
+ * Does not drop packets that are queued in the NSS.
+ */
static unsigned int nss_prio_drop(struct Qdisc *sch)
{
return nss_qdisc_drop(sch);
}
+/*
+ * nss_prio_peek()
+ * Peeks the first packet in queue for this qdisc.
+ */
static struct sk_buff *nss_prio_peek(struct Qdisc *sch)
{
return nss_qdisc_peek(sch);
}
+/*
+ * nss_prio_reset()
+ * Reset the nssprio qdisc
+ */
static void nss_prio_reset(struct Qdisc *sch)
{
return nss_qdisc_reset(sch);
}
+/*
+ * nss_prio_destroy()
+ * Destroy the nssprio qdisc
+ */
static void nss_prio_destroy(struct Qdisc *sch)
{
struct nss_prio_sched_data *q = qdisc_priv(sch);
@@ -95,10 +124,17 @@
nss_qdisc_destroy(&q->nq);
}
+/*
+ * nssprio policy structure
+ */
static const struct nla_policy nss_prio_policy[TCA_NSSPRIO_MAX + 1] = {
[TCA_NSSPRIO_PARMS] = { .len = sizeof(struct tc_nssprio_qopt) },
};
+/*
+ * nss_prio_change()
+ * Function call to configure the nssprio parameters
+ */
static int nss_prio_change(struct Qdisc *sch, struct nlattr *opt)
{
struct nss_prio_sched_data *q;
@@ -108,8 +144,20 @@
q = qdisc_priv(sch);
+ /*
+ * Since nssprio can be created with no arguments, opt might be NULL
+ * (depending on the kernel version). This is still a valid create
+ * request.
+ */
if (opt == NULL) {
- return -EINVAL;
+
+ /*
+ * If no parameter is passed, set it to the default value.
+ */
+ sch_tree_lock(sch);
+ q->bands = TCA_NSSPRIO_MAX_BANDS;
+ sch_tree_unlock(sch);
+ return 0;
}
err = nla_parse_nested(na, TCA_NSSPRIO_MAX, opt, nss_prio_policy);
@@ -127,24 +175,32 @@
return -EINVAL;
}
+ sch_tree_lock(sch);
q->bands = qopt->bands;
+ sch_tree_unlock(sch);
nss_qdisc_info("Bands = %u\n", qopt->bands);
+ /*
+ * We do not pass on this information to NSS since
+ * it not required for operation of prio. This parameter
+ * is needed only for the proxy operation.
+ */
+
return 0;
}
+/*
+ * nss_prio_init()
+ * Initializes the nssprio qdisc
+ */
static int nss_prio_init(struct Qdisc *sch, struct nlattr *opt)
{
struct nss_prio_sched_data *q = qdisc_priv(sch);
int i;
- if (opt == NULL)
- return -EINVAL;
-
for (i = 0; i < TCA_NSSPRIO_MAX_BANDS; i++)
q->queues[i] = &noop_qdisc;
- q->bands = 0;
if (nss_qdisc_init(sch, &q->nq, NSS_SHAPER_NODE_TYPE_PRIO, 0) < 0)
return -EINVAL;
@@ -163,6 +219,10 @@
return 0;
}
+/*
+ * nss_prio_dump()
+ * Dump the parameters of nssprio
+ */
static int nss_prio_dump(struct Qdisc *sch, struct sk_buff *skb)
{
struct nss_prio_sched_data *q = qdisc_priv(sch);
@@ -184,6 +244,10 @@
return -EMSGSIZE;
}
+/*
+ * nss_prio_graft()
+ * Replaces existing child qdisc with the new qdisc that is passed.
+ */
static int nss_prio_graft(struct Qdisc *sch, unsigned long arg,
struct Qdisc *new, struct Qdisc **old)
{
@@ -235,6 +299,10 @@
return 0;
}
+/*
+ * nss_prio_leaf_class()
+ * Returns pointer to qdisc if leaf class.
+ */
static struct Qdisc *nss_prio_leaf(struct Qdisc *sch, unsigned long arg)
{
struct nss_prio_sched_data *q = qdisc_priv(sch);
@@ -248,6 +316,10 @@
return q->queues[band];
}
+/*
+ * nss_prio_get()
+ * Returns the band if provided the classid.
+ */
static unsigned long nss_prio_get(struct Qdisc *sch, u32 classid)
{
struct nss_prio_sched_data *q = qdisc_priv(sch);
@@ -261,11 +333,19 @@
return band;
}
+/*
+ * nss_prio_put()
+ * Unused API.
+ */
static void nss_prio_put(struct Qdisc *sch, unsigned long arg)
{
- nss_qdisc_info("Inside prio get\n");
+ nss_qdisc_info("Inside prio put\n");
}
+/*
+ * nss_prio_walk()
+ * Walks the priority band.
+ */
static void nss_prio_walk(struct Qdisc *sch, struct qdisc_walker *arg)
{
struct nss_prio_sched_data *q = qdisc_priv(sch);
@@ -288,6 +368,10 @@
nss_qdisc_info("Nssprio walk called\n");
}
+/*
+ * nss_prio_dump_class()
+ * Dumps all configurable parameters pertaining to this class.
+ */
static int nss_prio_dump_class(struct Qdisc *sch, unsigned long cl,
struct sk_buff *skb, struct tcmsg *tcm)
{
@@ -300,6 +384,10 @@
return 0;
}
+/*
+ * nss_prio_dump_class_stats()
+ * Dumps class statistics.
+ */
static int nss_prio_dump_class_stats(struct Qdisc *sch, unsigned long cl,
struct gnet_dump *d)
{
@@ -316,6 +404,9 @@
return 0;
}
+/*
+ * Registration structure for nssprio class
+ */
const struct Qdisc_class_ops nss_prio_class_ops = {
.graft = nss_prio_graft,
.leaf = nss_prio_leaf,
@@ -326,6 +417,9 @@
.dump_stats = nss_prio_dump_class_stats,
};
+/*
+ * Registration structure for nssprio qdisc
+ */
struct Qdisc_ops nss_prio_qdisc_ops __read_mostly = {
.next = NULL,
.id = "nssprio",
@@ -342,4 +436,3 @@
.dump = nss_prio_dump,
.owner = THIS_MODULE,
};
-