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