--- /dev/null
+/*
+ * 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 <tgraf@suug.ch>
+ */
+
+/**
+ * @ingroup fib_lookup
+ * @defgroup flreq Request
+ * @brief
+ * @{
+ */
+
+#include <netlink-local.h>
+#include <netlink/netlink.h>
+#include <netlink/attr.h>
+#include <netlink/utils.h>
+#include <netlink/object.h>
+#include <netlink/fib_lookup/request.h>
+
+/** @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;
+}
+
+/** @} */
+
+/** @} */