libnl
3.2.3
|
00001 /* 00002 * lib/fib_lookup/request.c FIB Lookup Request 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup fib_lookup 00014 * @defgroup flreq Request 00015 * @brief 00016 * @{ 00017 */ 00018 00019 #include <netlink-local.h> 00020 #include <netlink/netlink.h> 00021 #include <netlink/attr.h> 00022 #include <netlink/utils.h> 00023 #include <netlink/object.h> 00024 #include <netlink/fib_lookup/request.h> 00025 00026 static struct nl_object_ops request_obj_ops; 00027 00028 /** @cond SKIP */ 00029 #define REQUEST_ATTR_ADDR 0x01 00030 #define REQUEST_ATTR_FWMARK 0x02 00031 #define REQUEST_ATTR_TOS 0x04 00032 #define REQUEST_ATTR_SCOPE 0x08 00033 #define REQUEST_ATTR_TABLE 0x10 00034 /** @endcond */ 00035 00036 static void request_free_data(struct nl_object *obj) 00037 { 00038 struct flnl_request *req = REQUEST_CAST(obj); 00039 00040 if (req) 00041 nl_addr_put(req->lr_addr); 00042 } 00043 00044 static int request_clone(struct nl_object *_dst, struct nl_object *_src) 00045 { 00046 struct flnl_request *dst = nl_object_priv(_dst); 00047 struct flnl_request *src = nl_object_priv(_src); 00048 00049 if (src->lr_addr) 00050 if (!(dst->lr_addr = nl_addr_clone(src->lr_addr))) 00051 return -NLE_NOMEM; 00052 00053 return 0; 00054 } 00055 00056 static int request_compare(struct nl_object *_a, struct nl_object *_b, 00057 uint32_t attrs, int flags) 00058 { 00059 struct flnl_request *a = (struct flnl_request *) _a; 00060 struct flnl_request *b = (struct flnl_request *) _b; 00061 int diff = 0; 00062 00063 #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR) 00064 00065 diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark); 00066 diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos); 00067 diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope); 00068 diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table); 00069 diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)); 00070 00071 #undef REQ_DIFF 00072 00073 return diff; 00074 } 00075 00076 00077 /** 00078 * @name Lookup Request Creation/Deletion 00079 * @{ 00080 */ 00081 00082 struct flnl_request *flnl_request_alloc(void) 00083 { 00084 return REQUEST_CAST(nl_object_alloc(&request_obj_ops)); 00085 } 00086 00087 /** @} */ 00088 00089 /** 00090 * @name Attributes 00091 * @{ 00092 */ 00093 00094 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark) 00095 { 00096 req->lr_fwmark = fwmark; 00097 req->ce_mask |= REQUEST_ATTR_FWMARK; 00098 } 00099 00100 uint64_t flnl_request_get_fwmark(struct flnl_request *req) 00101 { 00102 if (req->ce_mask & REQUEST_ATTR_FWMARK) 00103 return req->lr_fwmark; 00104 else 00105 return UINT_LEAST64_MAX; 00106 } 00107 00108 void flnl_request_set_tos(struct flnl_request *req, int tos) 00109 { 00110 req->lr_tos = tos; 00111 req->ce_mask |= REQUEST_ATTR_TOS; 00112 } 00113 00114 int flnl_request_get_tos(struct flnl_request *req) 00115 { 00116 if (req->ce_mask & REQUEST_ATTR_TOS) 00117 return req->lr_tos; 00118 else 00119 return -1; 00120 } 00121 00122 void flnl_request_set_scope(struct flnl_request *req, int scope) 00123 { 00124 req->lr_scope = scope; 00125 req->ce_mask |= REQUEST_ATTR_SCOPE; 00126 } 00127 00128 int flnl_request_get_scope(struct flnl_request *req) 00129 { 00130 if (req->ce_mask & REQUEST_ATTR_SCOPE) 00131 return req->lr_scope; 00132 else 00133 return -1; 00134 } 00135 00136 void flnl_request_set_table(struct flnl_request *req, int table) 00137 { 00138 req->lr_table = table; 00139 req->ce_mask |= REQUEST_ATTR_TABLE; 00140 } 00141 00142 int flnl_request_get_table(struct flnl_request *req) 00143 { 00144 if (req->ce_mask & REQUEST_ATTR_TABLE) 00145 return req->lr_table; 00146 else 00147 return -1; 00148 } 00149 00150 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr) 00151 { 00152 if (addr->a_family != AF_INET) 00153 return -NLE_AF_NOSUPPORT; 00154 00155 if (req->lr_addr) 00156 nl_addr_put(req->lr_addr); 00157 00158 nl_addr_get(addr); 00159 req->lr_addr = addr; 00160 00161 req->ce_mask |= REQUEST_ATTR_ADDR; 00162 00163 return 0; 00164 } 00165 00166 struct nl_addr *flnl_request_get_addr(struct flnl_request *req) 00167 { 00168 if (req->ce_mask & REQUEST_ATTR_ADDR) 00169 return req->lr_addr; 00170 else 00171 return NULL; 00172 } 00173 00174 /** @} */ 00175 00176 static struct nl_object_ops request_obj_ops = { 00177 .oo_name = "fib_lookup/request", 00178 .oo_size = sizeof(struct flnl_request), 00179 .oo_free_data = request_free_data, 00180 .oo_clone = request_clone, 00181 .oo_compare = request_compare, 00182 .oo_id_attrs = ~0, 00183 }; 00184 00185 /** @} */