libnl 1.1
|
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-2006 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 goto errout; 00052 00053 return 0; 00054 errout: 00055 return nl_get_errno(); 00056 } 00057 00058 static int request_compare(struct nl_object *_a, struct nl_object *_b, 00059 uint32_t attrs, int flags) 00060 { 00061 struct flnl_request *a = (struct flnl_request *) _a; 00062 struct flnl_request *b = (struct flnl_request *) _b; 00063 int diff = 0; 00064 00065 #define REQ_DIFF(ATTR, EXPR) ATTR_DIFF(attrs, REQUEST_ATTR_##ATTR, a, b, EXPR) 00066 00067 diff |= REQ_DIFF(FWMARK, a->lr_fwmark != b->lr_fwmark); 00068 diff |= REQ_DIFF(TOS, a->lr_tos != b->lr_tos); 00069 diff |= REQ_DIFF(SCOPE, a->lr_scope != b->lr_scope); 00070 diff |= REQ_DIFF(TABLE, a->lr_table != b->lr_table); 00071 diff |= REQ_DIFF(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)); 00072 00073 #undef REQ_DIFF 00074 00075 return diff; 00076 } 00077 00078 00079 /** 00080 * @name Lookup Request Creation/Deletion 00081 * @{ 00082 */ 00083 00084 struct flnl_request *flnl_request_alloc(void) 00085 { 00086 return REQUEST_CAST(nl_object_alloc(&request_obj_ops)); 00087 } 00088 00089 /** @} */ 00090 00091 /** 00092 * @name Attributes 00093 * @{ 00094 */ 00095 00096 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark) 00097 { 00098 req->lr_fwmark = fwmark; 00099 req->ce_mask |= REQUEST_ATTR_FWMARK; 00100 } 00101 00102 uint64_t flnl_request_get_fwmark(struct flnl_request *req) 00103 { 00104 if (req->ce_mask & REQUEST_ATTR_FWMARK) 00105 return req->lr_fwmark; 00106 else 00107 return UINT_LEAST64_MAX; 00108 } 00109 00110 void flnl_request_set_tos(struct flnl_request *req, int tos) 00111 { 00112 req->lr_tos = tos; 00113 req->ce_mask |= REQUEST_ATTR_TOS; 00114 } 00115 00116 int flnl_request_get_tos(struct flnl_request *req) 00117 { 00118 if (req->ce_mask & REQUEST_ATTR_TOS) 00119 return req->lr_tos; 00120 else 00121 return -1; 00122 } 00123 00124 void flnl_request_set_scope(struct flnl_request *req, int scope) 00125 { 00126 req->lr_scope = scope; 00127 req->ce_mask |= REQUEST_ATTR_SCOPE; 00128 } 00129 00130 int flnl_request_get_scope(struct flnl_request *req) 00131 { 00132 if (req->ce_mask & REQUEST_ATTR_SCOPE) 00133 return req->lr_scope; 00134 else 00135 return -1; 00136 } 00137 00138 void flnl_request_set_table(struct flnl_request *req, int table) 00139 { 00140 req->lr_table = table; 00141 req->ce_mask |= REQUEST_ATTR_TABLE; 00142 } 00143 00144 int flnl_request_get_table(struct flnl_request *req) 00145 { 00146 if (req->ce_mask & REQUEST_ATTR_TABLE) 00147 return req->lr_table; 00148 else 00149 return -1; 00150 } 00151 00152 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr) 00153 { 00154 if (addr->a_family != AF_INET) 00155 return nl_error(EINVAL, "Address must be an IPv4 address"); 00156 00157 if (req->lr_addr) 00158 nl_addr_put(req->lr_addr); 00159 00160 nl_addr_get(addr); 00161 req->lr_addr = addr; 00162 00163 req->ce_mask |= REQUEST_ATTR_ADDR; 00164 00165 return 0; 00166 } 00167 00168 struct nl_addr *flnl_request_get_addr(struct flnl_request *req) 00169 { 00170 if (req->ce_mask & REQUEST_ATTR_ADDR) 00171 return req->lr_addr; 00172 else 00173 return NULL; 00174 } 00175 00176 /** @} */ 00177 00178 static struct nl_object_ops request_obj_ops = { 00179 .oo_name = "fib_lookup/request", 00180 .oo_size = sizeof(struct flnl_request), 00181 .oo_free_data = request_free_data, 00182 .oo_clone = request_clone, 00183 .oo_compare = request_compare, 00184 .oo_id_attrs = ~0, 00185 }; 00186 00187 /** @} */