| /* |
| * 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> |
| |
| static struct nl_object_ops request_obj_ops; |
| |
| /** @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 */ |
| |
| static void request_free_data(struct nl_object *obj) |
| { |
| struct flnl_request *req = REQUEST_CAST(obj); |
| |
| if (req) |
| nl_addr_put(req->lr_addr); |
| } |
| |
| static int request_clone(struct nl_object *_dst, struct nl_object *_src) |
| { |
| struct flnl_request *dst = nl_object_priv(_dst); |
| struct flnl_request *src = nl_object_priv(_src); |
| |
| if (src->lr_addr) |
| if (!(dst->lr_addr = nl_addr_clone(src->lr_addr))) |
| goto errout; |
| |
| return 0; |
| errout: |
| return nl_get_errno(); |
| } |
| |
| static int request_compare(struct nl_object *_a, struct nl_object *_b, |
| uint32_t attrs, int flags) |
| { |
| struct flnl_request *a = (struct flnl_request *) _a; |
| struct flnl_request *b = (struct flnl_request *) _b; |
| int diff = 0; |
| |
| #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR) |
| |
| diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark); |
| diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos); |
| diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope); |
| diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table); |
| diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)); |
| |
| #undef REQ_DIFF |
| |
| return diff; |
| } |
| |
| |
| /** |
| * @name Lookup Request Creation/Deletion |
| * @{ |
| */ |
| |
| struct flnl_request *flnl_request_alloc(void) |
| { |
| return REQUEST_CAST(nl_object_alloc(&request_obj_ops)); |
| } |
| |
| /** @} */ |
| |
| /** |
| * @name Attributes |
| * @{ |
| */ |
| |
| void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark) |
| { |
| req->lr_fwmark = fwmark; |
| req->ce_mask |= REQUEST_ATTR_FWMARK; |
| } |
| |
| uint64_t flnl_request_get_fwmark(struct flnl_request *req) |
| { |
| if (req->ce_mask & REQUEST_ATTR_FWMARK) |
| return req->lr_fwmark; |
| else |
| return UINT_LEAST64_MAX; |
| } |
| |
| void flnl_request_set_tos(struct flnl_request *req, int tos) |
| { |
| req->lr_tos = tos; |
| req->ce_mask |= REQUEST_ATTR_TOS; |
| } |
| |
| int flnl_request_get_tos(struct flnl_request *req) |
| { |
| if (req->ce_mask & REQUEST_ATTR_TOS) |
| return req->lr_tos; |
| else |
| return -1; |
| } |
| |
| void flnl_request_set_scope(struct flnl_request *req, int scope) |
| { |
| req->lr_scope = scope; |
| req->ce_mask |= REQUEST_ATTR_SCOPE; |
| } |
| |
| int flnl_request_get_scope(struct flnl_request *req) |
| { |
| if (req->ce_mask & REQUEST_ATTR_SCOPE) |
| return req->lr_scope; |
| else |
| return -1; |
| } |
| |
| void flnl_request_set_table(struct flnl_request *req, int table) |
| { |
| req->lr_table = table; |
| req->ce_mask |= REQUEST_ATTR_TABLE; |
| } |
| |
| int flnl_request_get_table(struct flnl_request *req) |
| { |
| if (req->ce_mask & REQUEST_ATTR_TABLE) |
| return req->lr_table; |
| else |
| return -1; |
| } |
| |
| 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->ce_mask |= REQUEST_ATTR_ADDR; |
| |
| return 0; |
| } |
| |
| struct nl_addr *flnl_request_get_addr(struct flnl_request *req) |
| { |
| if (req->ce_mask & REQUEST_ATTR_ADDR) |
| return req->lr_addr; |
| else |
| return NULL; |
| } |
| |
| /** @} */ |
| |
| static struct nl_object_ops request_obj_ops = { |
| .oo_name = "fib_lookup/request", |
| .oo_size = sizeof(struct flnl_request), |
| .oo_free_data = request_free_data, |
| .oo_clone = request_clone, |
| .oo_compare = request_compare, |
| .oo_id_attrs = ~0, |
| }; |
| |
| /** @} */ |