1*4dc78e53SAndroid Build Coastguard Worker /* SPDX-License-Identifier: LGPL-2.1-only */
2*4dc78e53SAndroid Build Coastguard Worker /*
3*4dc78e53SAndroid Build Coastguard Worker * Copyright (c) 2003-2008 Thomas Graf <[email protected]>
4*4dc78e53SAndroid Build Coastguard Worker */
5*4dc78e53SAndroid Build Coastguard Worker
6*4dc78e53SAndroid Build Coastguard Worker /**
7*4dc78e53SAndroid Build Coastguard Worker * @ingroup fib_lookup
8*4dc78e53SAndroid Build Coastguard Worker * @defgroup flreq Request
9*4dc78e53SAndroid Build Coastguard Worker * @brief
10*4dc78e53SAndroid Build Coastguard Worker * @{
11*4dc78e53SAndroid Build Coastguard Worker */
12*4dc78e53SAndroid Build Coastguard Worker
13*4dc78e53SAndroid Build Coastguard Worker #include "nl-default.h"
14*4dc78e53SAndroid Build Coastguard Worker
15*4dc78e53SAndroid Build Coastguard Worker #include <netlink/netlink.h>
16*4dc78e53SAndroid Build Coastguard Worker #include <netlink/attr.h>
17*4dc78e53SAndroid Build Coastguard Worker #include <netlink/utils.h>
18*4dc78e53SAndroid Build Coastguard Worker #include <netlink/object.h>
19*4dc78e53SAndroid Build Coastguard Worker #include <netlink/fib_lookup/request.h>
20*4dc78e53SAndroid Build Coastguard Worker
21*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/nl-core.h"
22*4dc78e53SAndroid Build Coastguard Worker #include "nl-priv-dynamic-core/object-api.h"
23*4dc78e53SAndroid Build Coastguard Worker
24*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops request_obj_ops;
25*4dc78e53SAndroid Build Coastguard Worker
26*4dc78e53SAndroid Build Coastguard Worker /** @cond SKIP */
27*4dc78e53SAndroid Build Coastguard Worker struct flnl_request
28*4dc78e53SAndroid Build Coastguard Worker {
29*4dc78e53SAndroid Build Coastguard Worker NLHDR_COMMON
30*4dc78e53SAndroid Build Coastguard Worker
31*4dc78e53SAndroid Build Coastguard Worker struct nl_addr * lr_addr;
32*4dc78e53SAndroid Build Coastguard Worker uint32_t lr_fwmark;
33*4dc78e53SAndroid Build Coastguard Worker uint8_t lr_tos;
34*4dc78e53SAndroid Build Coastguard Worker uint8_t lr_scope;
35*4dc78e53SAndroid Build Coastguard Worker uint8_t lr_table;
36*4dc78e53SAndroid Build Coastguard Worker };
37*4dc78e53SAndroid Build Coastguard Worker
38*4dc78e53SAndroid Build Coastguard Worker #define REQUEST_ATTR_ADDR 0x01
39*4dc78e53SAndroid Build Coastguard Worker #define REQUEST_ATTR_FWMARK 0x02
40*4dc78e53SAndroid Build Coastguard Worker #define REQUEST_ATTR_TOS 0x04
41*4dc78e53SAndroid Build Coastguard Worker #define REQUEST_ATTR_SCOPE 0x08
42*4dc78e53SAndroid Build Coastguard Worker #define REQUEST_ATTR_TABLE 0x10
43*4dc78e53SAndroid Build Coastguard Worker /** @endcond */
44*4dc78e53SAndroid Build Coastguard Worker
request_free_data(struct nl_object * obj)45*4dc78e53SAndroid Build Coastguard Worker static void request_free_data(struct nl_object *obj)
46*4dc78e53SAndroid Build Coastguard Worker {
47*4dc78e53SAndroid Build Coastguard Worker struct flnl_request *req = REQUEST_CAST(obj);
48*4dc78e53SAndroid Build Coastguard Worker
49*4dc78e53SAndroid Build Coastguard Worker if (req)
50*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(req->lr_addr);
51*4dc78e53SAndroid Build Coastguard Worker }
52*4dc78e53SAndroid Build Coastguard Worker
request_clone(struct nl_object * _dst,struct nl_object * _src)53*4dc78e53SAndroid Build Coastguard Worker static int request_clone(struct nl_object *_dst, struct nl_object *_src)
54*4dc78e53SAndroid Build Coastguard Worker {
55*4dc78e53SAndroid Build Coastguard Worker struct flnl_request *dst = nl_object_priv(_dst);
56*4dc78e53SAndroid Build Coastguard Worker struct flnl_request *src = nl_object_priv(_src);
57*4dc78e53SAndroid Build Coastguard Worker
58*4dc78e53SAndroid Build Coastguard Worker dst->lr_addr = NULL;
59*4dc78e53SAndroid Build Coastguard Worker
60*4dc78e53SAndroid Build Coastguard Worker if (src->lr_addr) {
61*4dc78e53SAndroid Build Coastguard Worker if (!(dst->lr_addr = nl_addr_clone(src->lr_addr)))
62*4dc78e53SAndroid Build Coastguard Worker return -NLE_NOMEM;
63*4dc78e53SAndroid Build Coastguard Worker }
64*4dc78e53SAndroid Build Coastguard Worker
65*4dc78e53SAndroid Build Coastguard Worker return 0;
66*4dc78e53SAndroid Build Coastguard Worker }
67*4dc78e53SAndroid Build Coastguard Worker
request_compare(struct nl_object * _a,struct nl_object * _b,uint64_t attrs,int flags)68*4dc78e53SAndroid Build Coastguard Worker static uint64_t request_compare(struct nl_object *_a, struct nl_object *_b,
69*4dc78e53SAndroid Build Coastguard Worker uint64_t attrs, int flags)
70*4dc78e53SAndroid Build Coastguard Worker {
71*4dc78e53SAndroid Build Coastguard Worker struct flnl_request *a = (struct flnl_request *) _a;
72*4dc78e53SAndroid Build Coastguard Worker struct flnl_request *b = (struct flnl_request *) _b;
73*4dc78e53SAndroid Build Coastguard Worker uint64_t diff = 0;
74*4dc78e53SAndroid Build Coastguard Worker
75*4dc78e53SAndroid Build Coastguard Worker #define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, ATTR, a, b, EXPR)
76*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(REQUEST_ATTR_FWMARK, a->lr_fwmark != b->lr_fwmark);
77*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(REQUEST_ATTR_TOS, a->lr_tos != b->lr_tos);
78*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(REQUEST_ATTR_SCOPE, a->lr_scope != b->lr_scope);
79*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(REQUEST_ATTR_TABLE, a->lr_table != b->lr_table);
80*4dc78e53SAndroid Build Coastguard Worker diff |= _DIFF(REQUEST_ATTR_ADDR, nl_addr_cmp(a->lr_addr, b->lr_addr));
81*4dc78e53SAndroid Build Coastguard Worker #undef _DIFF
82*4dc78e53SAndroid Build Coastguard Worker
83*4dc78e53SAndroid Build Coastguard Worker return diff;
84*4dc78e53SAndroid Build Coastguard Worker }
85*4dc78e53SAndroid Build Coastguard Worker
86*4dc78e53SAndroid Build Coastguard Worker
87*4dc78e53SAndroid Build Coastguard Worker /**
88*4dc78e53SAndroid Build Coastguard Worker * @name Lookup Request Creation/Deletion
89*4dc78e53SAndroid Build Coastguard Worker * @{
90*4dc78e53SAndroid Build Coastguard Worker */
91*4dc78e53SAndroid Build Coastguard Worker
flnl_request_alloc(void)92*4dc78e53SAndroid Build Coastguard Worker struct flnl_request *flnl_request_alloc(void)
93*4dc78e53SAndroid Build Coastguard Worker {
94*4dc78e53SAndroid Build Coastguard Worker return REQUEST_CAST(nl_object_alloc(&request_obj_ops));
95*4dc78e53SAndroid Build Coastguard Worker }
96*4dc78e53SAndroid Build Coastguard Worker
97*4dc78e53SAndroid Build Coastguard Worker /** @} */
98*4dc78e53SAndroid Build Coastguard Worker
99*4dc78e53SAndroid Build Coastguard Worker /**
100*4dc78e53SAndroid Build Coastguard Worker * @name Attributes
101*4dc78e53SAndroid Build Coastguard Worker * @{
102*4dc78e53SAndroid Build Coastguard Worker */
103*4dc78e53SAndroid Build Coastguard Worker
flnl_request_set_fwmark(struct flnl_request * req,uint64_t fwmark)104*4dc78e53SAndroid Build Coastguard Worker void flnl_request_set_fwmark(struct flnl_request *req, uint64_t fwmark)
105*4dc78e53SAndroid Build Coastguard Worker {
106*4dc78e53SAndroid Build Coastguard Worker req->lr_fwmark = fwmark;
107*4dc78e53SAndroid Build Coastguard Worker req->ce_mask |= REQUEST_ATTR_FWMARK;
108*4dc78e53SAndroid Build Coastguard Worker }
109*4dc78e53SAndroid Build Coastguard Worker
flnl_request_get_fwmark(struct flnl_request * req)110*4dc78e53SAndroid Build Coastguard Worker uint64_t flnl_request_get_fwmark(struct flnl_request *req)
111*4dc78e53SAndroid Build Coastguard Worker {
112*4dc78e53SAndroid Build Coastguard Worker if (req->ce_mask & REQUEST_ATTR_FWMARK)
113*4dc78e53SAndroid Build Coastguard Worker return req->lr_fwmark;
114*4dc78e53SAndroid Build Coastguard Worker else
115*4dc78e53SAndroid Build Coastguard Worker return UINT_LEAST64_MAX;
116*4dc78e53SAndroid Build Coastguard Worker }
117*4dc78e53SAndroid Build Coastguard Worker
flnl_request_set_tos(struct flnl_request * req,int tos)118*4dc78e53SAndroid Build Coastguard Worker void flnl_request_set_tos(struct flnl_request *req, int tos)
119*4dc78e53SAndroid Build Coastguard Worker {
120*4dc78e53SAndroid Build Coastguard Worker req->lr_tos = tos;
121*4dc78e53SAndroid Build Coastguard Worker req->ce_mask |= REQUEST_ATTR_TOS;
122*4dc78e53SAndroid Build Coastguard Worker }
123*4dc78e53SAndroid Build Coastguard Worker
flnl_request_get_tos(struct flnl_request * req)124*4dc78e53SAndroid Build Coastguard Worker int flnl_request_get_tos(struct flnl_request *req)
125*4dc78e53SAndroid Build Coastguard Worker {
126*4dc78e53SAndroid Build Coastguard Worker if (req->ce_mask & REQUEST_ATTR_TOS)
127*4dc78e53SAndroid Build Coastguard Worker return req->lr_tos;
128*4dc78e53SAndroid Build Coastguard Worker else
129*4dc78e53SAndroid Build Coastguard Worker return -1;
130*4dc78e53SAndroid Build Coastguard Worker }
131*4dc78e53SAndroid Build Coastguard Worker
flnl_request_set_scope(struct flnl_request * req,int scope)132*4dc78e53SAndroid Build Coastguard Worker void flnl_request_set_scope(struct flnl_request *req, int scope)
133*4dc78e53SAndroid Build Coastguard Worker {
134*4dc78e53SAndroid Build Coastguard Worker req->lr_scope = scope;
135*4dc78e53SAndroid Build Coastguard Worker req->ce_mask |= REQUEST_ATTR_SCOPE;
136*4dc78e53SAndroid Build Coastguard Worker }
137*4dc78e53SAndroid Build Coastguard Worker
flnl_request_get_scope(struct flnl_request * req)138*4dc78e53SAndroid Build Coastguard Worker int flnl_request_get_scope(struct flnl_request *req)
139*4dc78e53SAndroid Build Coastguard Worker {
140*4dc78e53SAndroid Build Coastguard Worker if (req->ce_mask & REQUEST_ATTR_SCOPE)
141*4dc78e53SAndroid Build Coastguard Worker return req->lr_scope;
142*4dc78e53SAndroid Build Coastguard Worker else
143*4dc78e53SAndroid Build Coastguard Worker return -1;
144*4dc78e53SAndroid Build Coastguard Worker }
145*4dc78e53SAndroid Build Coastguard Worker
flnl_request_set_table(struct flnl_request * req,int table)146*4dc78e53SAndroid Build Coastguard Worker void flnl_request_set_table(struct flnl_request *req, int table)
147*4dc78e53SAndroid Build Coastguard Worker {
148*4dc78e53SAndroid Build Coastguard Worker req->lr_table = table;
149*4dc78e53SAndroid Build Coastguard Worker req->ce_mask |= REQUEST_ATTR_TABLE;
150*4dc78e53SAndroid Build Coastguard Worker }
151*4dc78e53SAndroid Build Coastguard Worker
flnl_request_get_table(struct flnl_request * req)152*4dc78e53SAndroid Build Coastguard Worker int flnl_request_get_table(struct flnl_request *req)
153*4dc78e53SAndroid Build Coastguard Worker {
154*4dc78e53SAndroid Build Coastguard Worker if (req->ce_mask & REQUEST_ATTR_TABLE)
155*4dc78e53SAndroid Build Coastguard Worker return req->lr_table;
156*4dc78e53SAndroid Build Coastguard Worker else
157*4dc78e53SAndroid Build Coastguard Worker return -1;
158*4dc78e53SAndroid Build Coastguard Worker }
159*4dc78e53SAndroid Build Coastguard Worker
flnl_request_set_addr(struct flnl_request * req,struct nl_addr * addr)160*4dc78e53SAndroid Build Coastguard Worker int flnl_request_set_addr(struct flnl_request *req, struct nl_addr *addr)
161*4dc78e53SAndroid Build Coastguard Worker {
162*4dc78e53SAndroid Build Coastguard Worker if (addr->a_family != AF_INET)
163*4dc78e53SAndroid Build Coastguard Worker return -NLE_AF_NOSUPPORT;
164*4dc78e53SAndroid Build Coastguard Worker
165*4dc78e53SAndroid Build Coastguard Worker if (req->lr_addr)
166*4dc78e53SAndroid Build Coastguard Worker nl_addr_put(req->lr_addr);
167*4dc78e53SAndroid Build Coastguard Worker
168*4dc78e53SAndroid Build Coastguard Worker nl_addr_get(addr);
169*4dc78e53SAndroid Build Coastguard Worker req->lr_addr = addr;
170*4dc78e53SAndroid Build Coastguard Worker
171*4dc78e53SAndroid Build Coastguard Worker req->ce_mask |= REQUEST_ATTR_ADDR;
172*4dc78e53SAndroid Build Coastguard Worker
173*4dc78e53SAndroid Build Coastguard Worker return 0;
174*4dc78e53SAndroid Build Coastguard Worker }
175*4dc78e53SAndroid Build Coastguard Worker
flnl_request_get_addr(struct flnl_request * req)176*4dc78e53SAndroid Build Coastguard Worker struct nl_addr *flnl_request_get_addr(struct flnl_request *req)
177*4dc78e53SAndroid Build Coastguard Worker {
178*4dc78e53SAndroid Build Coastguard Worker if (req->ce_mask & REQUEST_ATTR_ADDR)
179*4dc78e53SAndroid Build Coastguard Worker return req->lr_addr;
180*4dc78e53SAndroid Build Coastguard Worker else
181*4dc78e53SAndroid Build Coastguard Worker return NULL;
182*4dc78e53SAndroid Build Coastguard Worker }
183*4dc78e53SAndroid Build Coastguard Worker
184*4dc78e53SAndroid Build Coastguard Worker /** @} */
185*4dc78e53SAndroid Build Coastguard Worker
186*4dc78e53SAndroid Build Coastguard Worker static struct nl_object_ops request_obj_ops = {
187*4dc78e53SAndroid Build Coastguard Worker .oo_name = "fib_lookup/request",
188*4dc78e53SAndroid Build Coastguard Worker .oo_size = sizeof(struct flnl_request),
189*4dc78e53SAndroid Build Coastguard Worker .oo_free_data = request_free_data,
190*4dc78e53SAndroid Build Coastguard Worker .oo_clone = request_clone,
191*4dc78e53SAndroid Build Coastguard Worker .oo_compare = request_compare,
192*4dc78e53SAndroid Build Coastguard Worker .oo_id_attrs = ~0,
193*4dc78e53SAndroid Build Coastguard Worker };
194*4dc78e53SAndroid Build Coastguard Worker
195*4dc78e53SAndroid Build Coastguard Worker /** @} */
196