This commit was generated by cvs2svn to compensate for changes in r786,
[libnl.git] / lib / fib_lookup / request.c
diff --git a/lib/fib_lookup/request.c b/lib/fib_lookup/request.c
new file mode 100644 (file)
index 0000000..1986063
--- /dev/null
@@ -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 <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;
+}
+
+/** @} */
+
+/** @} */