diff options
Diffstat (limited to 'lib/route/cls.c')
-rw-r--r-- | lib/route/cls.c | 186 |
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) |