2 * lib/fib_lookup/request.c FIB Lookup Request
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation version 2.1
9 * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch>
14 * @defgroup flreq Request
19 #include <netlink-local.h>
20 #include <netlink/netlink.h>
21 #include <netlink/attr.h>
22 #include <netlink/utils.h>
23 #include <netlink/object.h>
24 #include <netlink/fib_lookup/request.h>
27 #define REQUEST_ATTR_ADDR 0x01
28 #define REQUEST_ATTR_FWMARK 0x02
29 #define REQUEST_ATTR_TOS 0x04
30 #define REQUEST_ATTR_SCOPE 0x08
31 #define REQUEST_ATTR_TABLE 0x10
35 * @name Lookup Request Creation/Deletion
40 * Allocate and initialize new lookup request object.
41 * @note Free the memory after usage using flnl_request_put() or
42 * flnl_request_free().
43 * @return Newly allocated lookup request object or NULL if an error occured.
45 struct flnl_request *flnl_request_alloc(void)
47 struct flnl_request *req;
49 req = calloc(1, sizeof(*req));
59 * Request undestroyable reference of lookup request object.
60 * @arg req Lookup request object.
61 * @return Lookup request object of which the reference was given.
63 struct flnl_request *flnl_request_get(struct flnl_request *req)
71 * Give back reference of lookup request object.
72 * @arg req Lookup request object to be given back.
74 * Decrements the reference counter and destroys the object if the
75 * last reference was given back.
77 void flnl_request_put(struct flnl_request *req)
82 if (req->lr_refcnt <= 1)
83 flnl_request_free(req);
89 * Free lookup request object.
90 * @arg req Lookup request object to be freed.
92 void flnl_request_free(struct flnl_request *req)
97 if (req->lr_refcnt != 1)
106 * @name Attribute Access
111 * Set firewall mark of lookup request object.
112 * @arg req Lookup request object.
113 * @arg fwmark Firewall mark.
115 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
117 req->lr_fwmark = fwmark;
118 req->lr_mask |= REQUEST_ATTR_FWMARK;
122 * Get firewall mark of lookup request object.
123 * @arg req Lookup request object.
124 * @return Firewall mark or UINT_LEAST64_MAX if not available.
126 uint64_t flnl_request_get_fwmark(struct flnl_request *req)
128 if (req->lr_mask & REQUEST_ATTR_FWMARK)
129 return req->lr_fwmark;
131 return UINT_LEAST64_MAX;
135 * Set Type of Service of lookup request object.
136 * @arg req Lookup request object.
137 * @arg tos Type of Service.
139 void flnl_request_set_tos(struct flnl_request *req, int tos)
142 req->lr_mask |= REQUEST_ATTR_TOS;
146 * Get Type of Service of lookup request object.
147 * @arg req Lookup request object.
148 * @return Type of Service or -1 if not available.
150 int flnl_request_get_tos(struct flnl_request *req)
152 if (req->lr_mask & REQUEST_ATTR_TOS)
159 * Set Scope of lookup request object.
160 * @arg req Lookup request oject.
161 * @arg scope Routing scope.
163 void flnl_request_set_scope(struct flnl_request *req, int scope)
165 req->lr_scope = scope;
166 req->lr_mask |= REQUEST_ATTR_SCOPE;
170 * Get scope of lookup request object.
171 * @arg req Lookup request object.
172 * @return Scope or -1 if not available.
174 int flnl_request_get_scope(struct flnl_request *req)
176 if (req->lr_mask & REQUEST_ATTR_SCOPE)
177 return req->lr_scope;
183 * Set routing table of lookup request object.
184 * @arg req Lookup request object.
185 * @arg table Routing table.
187 void flnl_request_set_table(struct flnl_request *req, int table)
189 req->lr_table = table;
190 req->lr_mask |= REQUEST_ATTR_TABLE;
194 * Get routing table of lookup request object.
195 * @arg req Lookup request object.
196 * @return Routing table or -1 if not available.
198 int flnl_request_get_table(struct flnl_request *req)
200 if (req->lr_mask & REQUEST_ATTR_TABLE)
201 return req->lr_table;
207 * Set destination address of lookup request object.
208 * @arg req Lookup request object.
209 * @arg addr IPv4 destination address.
211 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
213 if (addr->a_family != AF_INET)
214 return nl_error(EINVAL, "Address must be an IPv4 address");
217 nl_addr_put(req->lr_addr);
222 req->lr_mask |= REQUEST_ATTR_ADDR;
228 * Get destination address of lookup request object.
229 * @arg req Lookup request object.
230 * @return Destination address or NULL if not available.
232 struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
234 if (req->lr_mask & REQUEST_ATTR_ADDR)
243 * @name Miscellaneous
248 * Compares two lookup request objects.
249 * @arg a Lookup request object.
250 * @arg b Another lookup request object.
252 * @return Integer less than, equal to or greather than zero if \c is found,
253 * respectively to be less than, to, or be greater than \c b.
255 int flnl_request_cmp(struct flnl_request *a, struct flnl_request *b)
257 #define REQ(F) (a->lr_mask & REQUEST_ATTR_##F)
258 #define AVAIL(F) (b->lr_mask & REQUEST_ATTR_##F)
259 #define F_CUS(F, EXPR) (REQ(F) && (!AVAIL(F) || (EXPR)))
260 #define F_INT(F, N) (REQ(F) && (!AVAIL(F) || (a->N != b->N)))
262 if (F_INT(FWMARK, lr_fwmark) ||
263 F_INT(TOS, lr_tos) ||
264 F_INT(SCOPE, lr_scope) ||
265 F_INT(TABLE, lr_table) ||
266 F_CUS(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)))