X-Git-Url: http://git.onelab.eu/?p=libnl.git;a=blobdiff_plain;f=lib%2Ffib_lookup%2Frequest.c;fp=lib%2Ffib_lookup%2Frequest.c;h=1986063e8cee6b8e6cfcaa3ecc5958ab44e2f58b;hp=0000000000000000000000000000000000000000;hb=4cee2ecb3b8afa0637e6f5fe4c57985a4bc740ff;hpb=2df2fbe518d5a221ce6e3ee88a3fb23fb1b94b27 diff --git a/lib/fib_lookup/request.c b/lib/fib_lookup/request.c new file mode 100644 index 0000000..1986063 --- /dev/null +++ b/lib/fib_lookup/request.c @@ -0,0 +1,277 @@ +/* + * lib/fib_lookup/request.c FIB Lookup Request + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation version 2.1 + * of the License. + * + * Copyright (c) 2003-2006 Thomas Graf + */ + +/** + * @ingroup fib_lookup + * @defgroup flreq Request + * @brief + * @{ + */ + +#include +#include +#include +#include +#include +#include + +/** @cond SKIP */ +#define REQUEST_ATTR_ADDR 0x01 +#define REQUEST_ATTR_FWMARK 0x02 +#define REQUEST_ATTR_TOS 0x04 +#define REQUEST_ATTR_SCOPE 0x08 +#define REQUEST_ATTR_TABLE 0x10 +/** @endcond */ + +/** + * @name Lookup Request Creation/Deletion + * @{ + */ + +/** + * Allocate and initialize new lookup request object. + * @note Free the memory after usage using flnl_request_put() or + * flnl_request_free(). + * @return Newly allocated lookup request object or NULL if an error occured. + */ +struct flnl_request *flnl_request_alloc(void) +{ + struct flnl_request *req; + + req = calloc(1, sizeof(*req)); + if (req) + req->lr_refcnt = 1; + else + nl_errno(ENOMEM); + + return req; +} + +/** + * Request undestroyable reference of lookup request object. + * @arg req Lookup request object. + * @return Lookup request object of which the reference was given. + */ +struct flnl_request *flnl_request_get(struct flnl_request *req) +{ + req->lr_refcnt++; + + return req; +} + +/** + * Give back reference of lookup request object. + * @arg req Lookup request object to be given back. + * + * Decrements the reference counter and destroys the object if the + * last reference was given back. + */ +void flnl_request_put(struct flnl_request *req) +{ + if (!req) + return; + + if (req->lr_refcnt <= 1) + flnl_request_free(req); + else + req->lr_refcnt--; +} + +/** + * Free lookup request object. + * @arg req Lookup request object to be freed. + */ +void flnl_request_free(struct flnl_request *req) +{ + if (!req) + return; + + if (req->lr_refcnt != 1) + BUG(); + + free(req); +} + +/** @} */ + +/** + * @name Attribute Access + * @{ + */ + +/** + * Set firewall mark of lookup request object. + * @arg req Lookup request object. + * @arg fwmark Firewall mark. + */ +void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark) +{ + req->lr_fwmark = fwmark; + req->lr_mask |= REQUEST_ATTR_FWMARK; +} + +/** + * Get firewall mark of lookup request object. + * @arg req Lookup request object. + * @return Firewall mark or UINT_LEAST64_MAX if not available. + */ +uint64_t flnl_request_get_fwmark(struct flnl_request *req) +{ + if (req->lr_mask & REQUEST_ATTR_FWMARK) + return req->lr_fwmark; + else + return UINT_LEAST64_MAX; +} + +/** + * Set Type of Service of lookup request object. + * @arg req Lookup request object. + * @arg tos Type of Service. + */ +void flnl_request_set_tos(struct flnl_request *req, int tos) +{ + req->lr_tos = tos; + req->lr_mask |= REQUEST_ATTR_TOS; +} + +/** + * Get Type of Service of lookup request object. + * @arg req Lookup request object. + * @return Type of Service or -1 if not available. + */ +int flnl_request_get_tos(struct flnl_request *req) +{ + if (req->lr_mask & REQUEST_ATTR_TOS) + return req->lr_tos; + else + return -1; +} + +/** + * Set Scope of lookup request object. + * @arg req Lookup request oject. + * @arg scope Routing scope. + */ +void flnl_request_set_scope(struct flnl_request *req, int scope) +{ + req->lr_scope = scope; + req->lr_mask |= REQUEST_ATTR_SCOPE; +} + +/** + * Get scope of lookup request object. + * @arg req Lookup request object. + * @return Scope or -1 if not available. + */ +int flnl_request_get_scope(struct flnl_request *req) +{ + if (req->lr_mask & REQUEST_ATTR_SCOPE) + return req->lr_scope; + else + return -1; +} + +/** + * Set routing table of lookup request object. + * @arg req Lookup request object. + * @arg table Routing table. + */ +void flnl_request_set_table(struct flnl_request *req, int table) +{ + req->lr_table = table; + req->lr_mask |= REQUEST_ATTR_TABLE; +} + +/** + * Get routing table of lookup request object. + * @arg req Lookup request object. + * @return Routing table or -1 if not available. + */ +int flnl_request_get_table(struct flnl_request *req) +{ + if (req->lr_mask & REQUEST_ATTR_TABLE) + return req->lr_table; + else + return -1; +} + +/** + * Set destination address of lookup request object. + * @arg req Lookup request object. + * @arg addr IPv4 destination address. + */ +int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr) +{ + if (addr->a_family != AF_INET) + return nl_error(EINVAL, "Address must be an IPv4 address"); + + if (req->lr_addr) + nl_addr_put(req->lr_addr); + + nl_addr_get(addr); + req->lr_addr = addr; + + req->lr_mask |= REQUEST_ATTR_ADDR; + + return 0; +} + +/** + * Get destination address of lookup request object. + * @arg req Lookup request object. + * @return Destination address or NULL if not available. + */ +struct nl_addr *flnl_request_get_addr(struct flnl_request *req) +{ + if (req->lr_mask & REQUEST_ATTR_ADDR) + return req->lr_addr; + else + return NULL; +} + +/** @} */ + +/** + * @name Miscellaneous + * @{ + */ + +/** + * Compares two lookup request objects. + * @arg a Lookup request object. + * @arg b Another lookup request object. + * + * @return Integer less than, equal to or greather than zero if \c is found, + * respectively to be less than, to, or be greater than \c b. + */ +int flnl_request_cmp(struct flnl_request *a, struct flnl_request *b) +{ +#define REQ(F) (a->lr_mask & REQUEST_ATTR_##F) +#define AVAIL(F) (b->lr_mask & REQUEST_ATTR_##F) +#define F_CUS(F, EXPR) (REQ(F) && (!AVAIL(F) || (EXPR))) +#define F_INT(F, N) (REQ(F) && (!AVAIL(F) || (a->N != b->N))) + + if (F_INT(FWMARK, lr_fwmark) || + F_INT(TOS, lr_tos) || + F_INT(SCOPE, lr_scope) || + F_INT(TABLE, lr_table) || + F_CUS(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr))) + return 0; +#undef REQ +#undef AVAIL +#undef F_CUS +#undef F_INT + return 1; +} + +/** @} */ + +/** @} */