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