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