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