00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
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
00027 #define REQUEST_ATTR_ADDR 0x01
00028 #define REQUEST_ATTR_FWMARK 0x02
00029 #define REQUEST_ATTR_TOS 0x04
00030 #define REQUEST_ATTR_SCOPE 0x08
00031 #define REQUEST_ATTR_TABLE 0x10
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 struct flnl_request *flnl_request_alloc(void)
00046 {
00047 struct flnl_request *req;
00048
00049 req = calloc(1, sizeof(*req));
00050 if (req)
00051 req->lr_refcnt = 1;
00052 else
00053 nl_errno(ENOMEM);
00054
00055 return req;
00056 }
00057
00058
00059
00060
00061
00062
00063 struct flnl_request *flnl_request_get(struct flnl_request *req)
00064 {
00065 req->lr_refcnt++;
00066
00067 return req;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077 void flnl_request_put(struct flnl_request *req)
00078 {
00079 if (!req)
00080 return;
00081
00082 if (req->lr_refcnt <= 1)
00083 flnl_request_free(req);
00084 else
00085 req->lr_refcnt--;
00086 }
00087
00088
00089
00090
00091
00092 void flnl_request_free(struct flnl_request *req)
00093 {
00094 if (!req)
00095 return;
00096
00097 if (req->lr_refcnt != 1)
00098 BUG();
00099
00100 free(req);
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115 void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
00116 {
00117 req->lr_fwmark = fwmark;
00118 req->lr_mask |= REQUEST_ATTR_FWMARK;
00119 }
00120
00121
00122
00123
00124
00125
00126 uint64_t flnl_request_get_fwmark(struct flnl_request *req)
00127 {
00128 if (req->lr_mask & REQUEST_ATTR_FWMARK)
00129 return req->lr_fwmark;
00130 else
00131 return UINT_LEAST64_MAX;
00132 }
00133
00134
00135
00136
00137
00138
00139 void flnl_request_set_tos(struct flnl_request *req, int tos)
00140 {
00141 req->lr_tos = tos;
00142 req->lr_mask |= REQUEST_ATTR_TOS;
00143 }
00144
00145
00146
00147
00148
00149
00150 int flnl_request_get_tos(struct flnl_request *req)
00151 {
00152 if (req->lr_mask & REQUEST_ATTR_TOS)
00153 return req->lr_tos;
00154 else
00155 return -1;
00156 }
00157
00158
00159
00160
00161
00162
00163 void flnl_request_set_scope(struct flnl_request *req, int scope)
00164 {
00165 req->lr_scope = scope;
00166 req->lr_mask |= REQUEST_ATTR_SCOPE;
00167 }
00168
00169
00170
00171
00172
00173
00174 int flnl_request_get_scope(struct flnl_request *req)
00175 {
00176 if (req->lr_mask & REQUEST_ATTR_SCOPE)
00177 return req->lr_scope;
00178 else
00179 return -1;
00180 }
00181
00182
00183
00184
00185
00186
00187 void flnl_request_set_table(struct flnl_request *req, int table)
00188 {
00189 req->lr_table = table;
00190 req->lr_mask |= REQUEST_ATTR_TABLE;
00191 }
00192
00193
00194
00195
00196
00197
00198 int flnl_request_get_table(struct flnl_request *req)
00199 {
00200 if (req->lr_mask & REQUEST_ATTR_TABLE)
00201 return req->lr_table;
00202 else
00203 return -1;
00204 }
00205
00206
00207
00208
00209
00210
00211 int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
00212 {
00213 if (addr->a_family != AF_INET)
00214 return nl_error(EINVAL, "Address must be an IPv4 address");
00215
00216 if (req->lr_addr)
00217 nl_addr_put(req->lr_addr);
00218
00219 nl_addr_get(addr);
00220 req->lr_addr = addr;
00221
00222 req->lr_mask |= REQUEST_ATTR_ADDR;
00223
00224 return 0;
00225 }
00226
00227
00228
00229
00230
00231
00232 struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
00233 {
00234 if (req->lr_mask & REQUEST_ATTR_ADDR)
00235 return req->lr_addr;
00236 else
00237 return NULL;
00238 }
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 int flnl_request_cmp(struct flnl_request *a, struct flnl_request *b)
00256 {
00257 #define REQ(F) (a->lr_mask & REQUEST_ATTR_##F)
00258 #define AVAIL(F) (b->lr_mask & REQUEST_ATTR_##F)
00259 #define F_CUS(F, EXPR) (REQ(F) && (!AVAIL(F) || (EXPR)))
00260 #define F_INT(F, N) (REQ(F) && (!AVAIL(F) || (a->N != b->N)))
00261
00262 if (F_INT(FWMARK, lr_fwmark) ||
00263 F_INT(TOS, lr_tos) ||
00264 F_INT(SCOPE, lr_scope) ||
00265 F_INT(TABLE, lr_table) ||
00266 F_CUS(ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr)))
00267 return 0;
00268 #undef REQ
00269 #undef AVAIL
00270 #undef F_CUS
00271 #undef F_INT
00272 return 1;
00273 }
00274
00275
00276
00277