libnl 1.1
Data Structures | Modules

Queueing Disciplines

Traffic Control

Data Structures

struct  rtnl_qdisc_ops
 Qdisc Operations. More...

Modules

 Queueing Discipline Modules
 Queueing Discipline Object

QDisc Addition

struct nl_msg * rtnl_qdisc_build_add_request (struct rtnl_qdisc *qdisc, int flags)
 Build a netlink message to add a new qdisc.
int rtnl_qdisc_add (struct nl_handle *handle, struct rtnl_qdisc *qdisc, int flags)
 Add a new qdisc.

QDisc Modification

struct nl_msg * rtnl_qdisc_build_change_request (struct rtnl_qdisc *qdisc, struct rtnl_qdisc *new)
 Build a netlink message to change attributes of a existing qdisc.
int rtnl_qdisc_change (struct nl_handle *handle, struct rtnl_qdisc *qdisc, struct rtnl_qdisc *new)
 Change attributes of a qdisc.

QDisc Deletion

struct nl_msg * rtnl_qdisc_build_delete_request (struct rtnl_qdisc *qdisc)
 Build a netlink request message to delete a qdisc.
int rtnl_qdisc_delete (struct nl_handle *handle, struct rtnl_qdisc *qdisc)
 Delete a qdisc.

Qdisc Cache Management

struct nl_cache * rtnl_qdisc_alloc_cache (struct nl_handle *handle)
 Build a qdisc cache including all qdiscs currently configured in the kernel.
struct rtnl_qdisc * rtnl_qdisc_get_by_parent (struct nl_cache *cache, int ifindex, uint32_t parent)
 Look up qdisc by its parent in the provided cache.
struct rtnl_qdisc * rtnl_qdisc_get (struct nl_cache *cache, int ifindex, uint32_t handle)
 Look up qdisc by its handle in the provided cache.

Detailed Description

Qdisc Handles
In general, qdiscs are identified by the major part of a traffic control handle (the upper 16 bits). A few special values exist though:
  • TC_H_ROOT: root qdisc (directly attached to the device)
  • TC_H_INGRESS: ingress qdisc (directly attached to the device)
  • TC_H_UNSPEC: unspecified qdisc (no reference)
1) Adding a Qdisc
 // Allocate a new empty qdisc to be filled out
 struct rtnl_qdisc *qdisc = rtnl_qdisc_alloc();

 // ... specify the kind of the Qdisc
 rtnl_qdisc_set_kind(qdisc, "pfifo");

 // Specify the device the qdisc should be attached to
 rtnl_qdisc_set_ifindex(qdisc, ifindex);

 // ... specify the parent qdisc
 rtnl_qdisc_set_parent(qdisc, TC_H_ROOT);

 // Specifying the handle is not required but makes reidentifying easier
 // and may help to avoid adding a qdisc twice.
 rtnl_qdisc_set_handle(qdisc, 0x000A0000);

 // Now on to specify the qdisc specific options, see the relevant qdisc
 // modules for documentation, in this example we set the upper limit of
 // the packet fifo qdisc to 64
 rtnl_qdisc_fifo_set_limit(qdisc, 64);

 rtnl_qdisc_add(handle, qdisc, NLM_R_REPLACE);

 // Free up the memory
 rtnl_qdisc_put(qdisc);
2) Deleting a Qdisc
 // Allocate a new empty qdisc to be filled out with the parameters
 // specifying the qdisc to be deleted. Alternatively a fully equiped
 // Qdisc object from a cache can be used.
 struct rtnl_qdisc *qdisc = rtnl_qdisc_alloc();

 // The interface index of the device the qdisc is on and the parent handle
 // are the least required fields to be filled out.
 // Note: Specify TC_H_ROOT or TC_H_INGRESS as parent handle to delete the
 //       root respectively root ingress qdisc.
 rtnl_qdisc_set_ifindex(qdisc, ifindex);
 rtnl_qdisc_set_parent(qdisc, parent_handle);

 // If required for identification, the handle can be specified as well.
 rtnl_qdisc_set_handle(qdisc, qdisc_handle);

 // Not required but maybe helpful as sanity check, the kind of the qdisc
 // can be specified to avoid mistakes.
 rtnl_qdisc_set_kind(qdisc, "pfifo");

 // Finally delete the qdisc with rtnl_qdisc_delete(), alternatively
 // rtnl_qdisc_build_delete_request() can be invoked to generate an
 // appropritate netlink message to send out.
 rtnl_qdisc_delete(handle, qdisc);

 // Free up the memory
 rtnl_qdisc_put(qdisc);

Function Documentation

struct nl_msg* rtnl_qdisc_build_add_request ( struct rtnl_qdisc *  qdisc,
int  flags 
) [read]
Parameters:
qdiscqdisc to add
flagsadditional netlink message flags

Builds a new netlink message requesting an addition of a qdisc. The netlink message header isn't fully equipped with all relevant fields and must be sent out via nl_send_auto_complete() or supplemented as needed.

Common message flags used:

  • NLM_F_REPLACE - replace a potential existing qdisc
Returns:
New netlink message

Definition at line 197 of file qdisc.c.

References NLM_F_CREATE.

Referenced by rtnl_qdisc_add().

{
        struct nl_msg *msg;

        msg = qdisc_build(qdisc, RTM_NEWQDISC, NLM_F_CREATE | flags);
        if (!msg)
                nl_errno(ENOMEM);

        return msg;
}
int rtnl_qdisc_add ( struct nl_handle *  handle,
struct rtnl_qdisc *  qdisc,
int  flags 
)
Parameters:
handlenetlink handle
qdiscqdisc to delete
flagsadditional netlink message flags

Builds a netlink message by calling rtnl_qdisc_build_add_request(), sends the request to the kernel and waits for the ACK to be received and thus blocks until the request has been processed.

Common message flags used:

  • NLM_F_REPLACE - replace a potential existing qdisc
Returns:
0 on success or a negative error code

Definition at line 224 of file qdisc.c.

References nl_send_auto_complete(), nl_wait_for_ack(), nlmsg_free(), and rtnl_qdisc_build_add_request().

{
        struct nl_msg *msg;
        int err;

        msg = rtnl_qdisc_build_add_request(qdisc, flags);
        if (!msg)
                return nl_errno(ENOMEM);

        err = nl_send_auto_complete(handle, msg);
        if (err < 0)
                return err;

        nlmsg_free(msg);
        return nl_wait_for_ack(handle);
}
struct nl_msg* rtnl_qdisc_build_change_request ( struct rtnl_qdisc *  qdisc,
struct rtnl_qdisc *  new 
) [read]
Parameters:
qdiscqdisc to change
newnew qdisc attributes

Builds a new netlink message requesting an change of qdisc attributes. The netlink message header isn't fully equipped with all relevant fields and must be sent out via nl_send_auto_complete() or supplemented as needed.

Returns:
New netlink message

Definition at line 261 of file qdisc.c.

References NLM_F_REPLACE.

Referenced by rtnl_qdisc_change().

{
        return qdisc_build(qdisc, RTM_NEWQDISC, NLM_F_REPLACE);
}
int rtnl_qdisc_change ( struct nl_handle *  handle,
struct rtnl_qdisc *  qdisc,
struct rtnl_qdisc *  new 
)
Parameters:
handlenetlink handle
qdiscqdisc to change
newnew qdisc attributes

Builds a netlink message by calling rtnl_qdisc_build_change_request(), sends the request to the kernel and waits for the ACK to be received and thus blocks until the request has been processed.

Returns:
0 on success or a negative error code

Definition at line 279 of file qdisc.c.

References nl_send_auto_complete(), nl_wait_for_ack(), nlmsg_free(), and rtnl_qdisc_build_change_request().

{
        struct nl_msg *msg;
        int err;

        msg = rtnl_qdisc_build_change_request(qdisc, new);
        if (!msg)
                return nl_errno(ENOMEM);

        err = nl_send_auto_complete(handle, msg);
        if (err < 0)
                return err;

        nlmsg_free(msg);
        return nl_wait_for_ack(handle);
}
struct nl_msg* rtnl_qdisc_build_delete_request ( struct rtnl_qdisc *  qdisc) [read]
Parameters:
qdiscqdisc to delete

Builds a new netlink message requesting a deletion of a qdisc. The netlink message header isn't fully equipped with all relevant fields and must thus be sent out via nl_send_auto_complete() or supplemented as needed.

Returns:
New netlink message

Definition at line 315 of file qdisc.c.

References nlmsg_alloc_simple(), and nlmsg_append().

Referenced by rtnl_qdisc_delete().

{
        struct nl_msg *msg;
        struct tcmsg tchdr;
        int required = TCA_ATTR_IFINDEX | TCA_ATTR_PARENT;

        if ((qdisc->ce_mask & required) != required)
                BUG();

        msg = nlmsg_alloc_simple(RTM_DELQDISC, 0);
        if (!msg)
                return NULL;

        tchdr.tcm_family = AF_UNSPEC,
        tchdr.tcm_handle = qdisc->q_handle,
        tchdr.tcm_parent = qdisc->q_parent,
        tchdr.tcm_ifindex = qdisc->q_ifindex,
        nlmsg_append(msg, &tchdr, sizeof(tchdr), NLMSG_ALIGNTO);

        return msg;
}
int rtnl_qdisc_delete ( struct nl_handle *  handle,
struct rtnl_qdisc *  qdisc 
)
Parameters:
handlenetlink handle
qdiscqdisc to delete

Builds a netlink message by calling rtnl_qdisc_build_delete_request(), sends the request to the kernel and waits for the ACK to be received and thus blocks until the request has been processed.

Returns:
0 on success or a negative error code

Definition at line 348 of file qdisc.c.

References nl_send_auto_complete(), nl_wait_for_ack(), nlmsg_free(), and rtnl_qdisc_build_delete_request().

{
        struct nl_msg *msg;
        int err;

        msg = rtnl_qdisc_build_delete_request(qdisc);
        if (!msg)
                return nl_errno(ENOMEM);

        err = nl_send_auto_complete(handle, msg);
        if (err < 0)
                return err;

        nlmsg_free(msg);
        return nl_wait_for_ack(handle);
}
struct nl_cache* rtnl_qdisc_alloc_cache ( struct nl_handle *  handle) [read]
Parameters:
handlenetlink handle

Allocates a new cache, initializes it properly and updates it to include all qdiscs currently configured in the kernel.

Note:
The caller is responsible for destroying and freeing the cache after using it.
Returns:
The cache or NULL if an error has occured.

Definition at line 384 of file qdisc.c.

References nl_cache_alloc(), nl_cache_free(), and nl_cache_refill().

{
        struct nl_cache * cache;
        
        cache = nl_cache_alloc(&rtnl_qdisc_ops);
        if (cache == NULL)
                return NULL;

        if (handle && nl_cache_refill(handle, cache) < 0) {
                nl_cache_free(cache);
                return NULL;
        }

        return cache;
}
struct rtnl_qdisc* rtnl_qdisc_get_by_parent ( struct nl_cache *  cache,
int  ifindex,
uint32_t  parent 
) [read]
Parameters:
cacheqdisc cache
ifindexinterface the qdisc is attached to
parentparent handle
Returns:
pointer to qdisc inside the cache or NULL if no match was found.

Definition at line 407 of file qdisc.c.

References nl_object_get().

Referenced by rtnl_class_leaf_qdisc().

{
        struct rtnl_qdisc *q;

        if (cache->c_ops != &rtnl_qdisc_ops)
                return NULL;

        nl_list_for_each_entry(q, &cache->c_items, ce_list) {
                if (q->q_parent == parent && q->q_ifindex == ifindex) {
                        nl_object_get((struct nl_object *) q);
                        return q;
                }
        }

        return NULL;
}
struct rtnl_qdisc* rtnl_qdisc_get ( struct nl_cache *  cache,
int  ifindex,
uint32_t  handle 
) [read]
Parameters:
cacheqdisc cache
ifindexinterface the qdisc is attached to
handleqdisc handle
Returns:
pointer to qdisc inside the cache or NULL if no match was found.

Definition at line 432 of file qdisc.c.

References nl_object_get().

{
        struct rtnl_qdisc *q;

        if (cache->c_ops != &rtnl_qdisc_ops)
                return NULL;

        nl_list_for_each_entry(q, &cache->c_items, ce_list) {
                if (q->q_handle == handle && q->q_ifindex == ifindex) {
                        nl_object_get((struct nl_object *) q);
                        return q;
                }
        }

        return NULL;
}