summaryrefslogtreecommitdiffstats
path: root/lib/route/cls.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/route/cls.c')
-rw-r--r--lib/route/cls.c186
1 files changed, 109 insertions, 77 deletions
diff --git a/lib/route/cls.c b/lib/route/cls.c
index a041baa..aa79b09 100644
--- a/lib/route/cls.c
+++ b/lib/route/cls.c
@@ -6,21 +6,12 @@
* License as published by the Free Software Foundation version 2.1
* of the License.
*
- * Copyright (c) 2003-2009 Thomas Graf <tgraf@suug.ch>
+ * Copyright (c) 2003-2011 Thomas Graf <tgraf@suug.ch>
*/
/**
* @ingroup tc
* @defgroup cls Classifiers
- *
- * @par Classifier Identification
- * - protocol
- * - priority
- * - parent
- * - interface
- * - kind
- * - handle
- *
* @{
*/
@@ -46,6 +37,12 @@ static int cls_build(struct rtnl_cls *cls, int type, int flags,
{
int err, prio, proto;
struct tcmsg *tchdr;
+ int required = TCA_ATTR_IFINDEX;
+
+ if ((cls->ce_mask & required) != required) {
+ APPBUG("ifindex must be specified");
+ return -NLE_MISSING_ATTR;
+ }
err = rtnl_tc_msg_build(TC_CAST(cls), type, flags, result);
if (err < 0)
@@ -119,42 +116,70 @@ uint16_t rtnl_cls_get_protocol(struct rtnl_cls *cls)
/**
- * @name Classifier Addition/Modification/Deletion
+ * @name Addition/Modification/Deletion
* @{
*/
/**
- * Build a netlink message to add a new classifier
- * @arg cls classifier to add
- * @arg flags additional netlink message flags
- * @arg result Pointer to store resulting message.
+ * Build a netlink message requesting the addition of a classifier
+ * @arg cls Classifier to add
+ * @arg flags Additional netlink message flags
+ * @arg result Pointer to store resulting netlink message
+ *
+ * The behaviour of this function is identical to rtnl_cls_add() with
+ * the exception that it will not send the message but return it int the
+ * provided return pointer instead.
*
- * Builds a new netlink message requesting an addition of a classifier
- * 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. \a classifier must contain the attributes of
- * the new classifier set via \c rtnl_cls_set_* functions. \a opts
- * may point to the clsasifier specific options.
+ * @see rtnl_cls_add()
*
* @return 0 on success or a negative error code.
*/
int rtnl_cls_build_add_request(struct rtnl_cls *cls, int flags,
struct nl_msg **result)
{
- return cls_build(cls, RTM_NEWTFILTER, NLM_F_CREATE | flags, result);
+ if (!(flags & NLM_F_CREATE) && !(cls->ce_mask & CLS_ATTR_PRIO)) {
+ APPBUG("prio must be specified if not a new classifier");
+ return -NLE_MISSING_ATTR;
+ }
+
+ return cls_build(cls, RTM_NEWTFILTER, flags, result);
}
/**
- * Add a new classifier
- * @arg sk Netlink socket.
- * @arg cls classifier to add
- * @arg flags additional netlink message flags
+ * Add/Update classifier
+ * @arg sk Netlink socket
+ * @arg cls Classifier to add/update
+ * @arg flags Additional netlink message flags
*
- * Builds a netlink message by calling rtnl_cls_build_add_request(),
- * sends the request to the kernel and waits for the next ACK to be
- * received and thus blocks until the request has been processed.
+ * Builds a \c RTM_NEWTFILTER netlink message requesting the addition
+ * of a new classifier and sends the message to the kernel. The
+ * configuration of the classifier is derived from the attributes of
+ * the specified traffic class.
*
- * @return 0 on sucess or a negative error if an error occured.
+ * The following flags may be specified:
+ * - \c NLM_F_CREATE: Create classifier if it does not exist,
+ * otherwise -NLE_OBJ_NOTFOUND is returned.
+ * - \c NLM_F_EXCL: Return -NLE_EXISTS if a classifier with
+ * matching handle exists already.
+ *
+ * Existing classifiers with matching handles will be updated, unless
+ * the flag \c NLM_F_EXCL is specified. If no matching classifier
+ * exists, it will be created if the flag \c NLM_F_CREATE is set,
+ * otherwise the error -NLE_OBJ_NOTFOUND is returned.
+ *
+ * If the parent qdisc does not support classes, the error
+ * \c NLE_OPNOTSUPP is returned.
+ *
+ * After sending, the function will wait for the ACK or an eventual
+ * error message to be received and will therefore block until the
+ * operation has been completed.
+ *
+ * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause
+ * this function to return immediately after sending. In this case,
+ * it is the responsibility of the caller to handle any error
+ * messages returned.
+ *
+ * @return 0 on success or a negative error code.
*/
int rtnl_cls_add(struct nl_sock *sk, struct rtnl_cls *cls, int flags)
{
@@ -163,13 +188,8 @@ int rtnl_cls_add(struct nl_sock *sk, struct rtnl_cls *cls, int flags)
if ((err = rtnl_cls_build_add_request(cls, flags, &msg)) < 0)
return err;
-
- err = nl_send_auto_complete(sk, msg);
- nlmsg_free(msg);
- if (err < 0)
- return err;
- return nl_wait_for_ack(sk);
+ return nl_send_sync(sk, msg);
}
/**
@@ -211,45 +231,64 @@ int rtnl_cls_change(struct nl_sock *sk, struct rtnl_cls *cls, int flags)
if ((err = rtnl_cls_build_change_request(cls, flags, &msg)) < 0)
return err;
- err = nl_send_auto_complete(sk, msg);
- nlmsg_free(msg);
- if (err < 0)
- return err;
-
- return nl_wait_for_ack(sk);
+ return nl_send_sync(sk, msg);
}
/**
- * Build a netlink request message to delete a classifier
- * @arg cls classifier to delete
- * @arg flags additional netlink message flags
- * @arg result Pointer to store resulting message.
+ * Build netlink message requesting the deletion of a classifier
+ * @arg cls Classifier to delete
+ * @arg result Pointer to store resulting netlink message
*
- * Builds a new netlink message requesting a deletion of a classifier.
- * 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.
+ * The behaviour of this function is identical to rtnl_cls_delete() with
+ * the exception that it will not send the message but return it in the
+ * provided return pointer instead.
+ *
+ * @see rtnl_cls_delete()
*
* @return 0 on success or a negative error code.
*/
int rtnl_cls_build_delete_request(struct rtnl_cls *cls, int flags,
struct nl_msg **result)
{
+ int required = CLS_ATTR_PRIO;
+
+ if ((cls->ce_mask & required) != required) {
+ APPBUG("prio must be specified");
+ return -NLE_MISSING_ATTR;
+ }
+
return cls_build(cls, RTM_DELTFILTER, flags, result);
}
-
/**
- * Delete a classifier
- * @arg sk Netlink socket.
- * @arg cls classifier to delete
- * @arg flags additional netlink message flags
+ * Delete classifier
+ * @arg sk Netlink socket
+ * @arg cls Classifier to delete
*
- * Builds a netlink message by calling rtnl_cls_build_delete_request(),
- * sends the request to the kernel and waits for the next ACK to be
- * received and thus blocks until the request has been processed.
+ * Builds a \c RTM_DELTFILTER netlink message requesting the deletion
+ * of a classifier and sends the message to the kernel.
*
- * @return 0 on sucess or a negative error if an error occured.
+ * The message is constructed out of the following attributes:
+ * - \c ifindex (required)
+ * - \c prio (required)
+ * - \c protocol (required)
+ * - \c handle (required)
+ * - \c parent (optional, if not specified parent equals root-qdisc)
+ * - \c kind (optional, must match if provided)
+ *
+ * All other classifier attributes including all class type specific
+ * attributes are ignored.
+ *
+ * After sending, the function will wait for the ACK or an eventual
+ * error message to be received and will therefore block until the
+ * operation has been completed.
+ *
+ * @note Disabling auto-ack (nl_socket_disable_auto_ack()) will cause
+ * this function to return immediately after sending. In this case,
+ * it is the responsibility of the caller to handle any error
+ * messages returned.
+ *
+ * @return 0 on success or a negative error code.
*/
int rtnl_cls_delete(struct nl_sock *sk, struct rtnl_cls *cls, int flags)
{
@@ -259,35 +298,28 @@ int rtnl_cls_delete(struct nl_sock *sk, struct rtnl_cls *cls, int flags)
if ((err = rtnl_cls_build_delete_request(cls, flags, &msg)) < 0)
return err;
- err = nl_send_auto_complete(sk, msg);
- nlmsg_free(msg);
- if (err < 0)
- return err;
-
- return nl_wait_for_ack(sk);
+ return nl_send_sync(sk, msg);
}
/** @} */
/**
- * @name Cache Management
+ * @name Cache Related Functions
* @{
*/
/**
- * Build a classifier cache including all classifiers attached to the
- * specified class/qdisc on eht specified interface.
- * @arg sk Netlink socket.
- * @arg ifindex interface index of the link the classes are
- * attached to.
- * @arg parent parent qdisc/class
- * @arg result Pointer to store resulting cache.
+ * Allocate a cache and fill it with all configured classifiers
+ * @arg sk Netlink socket
+ * @arg ifindex Interface index of the network device
+ * @arg parent Parent qdisc/traffic class class
+ * @arg result Pointer to store the created cache
*
- * Allocates a new cache, initializes it properly and updates it to
- * include all classes attached to the specified interface.
+ * Allocates a new classifier cache and fills it with a list of all
+ * configured classifier attached to the specified parent qdisc/traffic
+ * class on the specified network device. Release the cache with
+ * nl_cache_free().
*
- * @note The caller is responsible for destroying and freeing the
- * cache after using it.
* @return 0 on success or a negative error code.
*/
int rtnl_cls_alloc_cache(struct nl_sock *sk, int ifindex, uint32_t parent, struct nl_cache **result)