libnl  3.7.0
nat.c
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2016 Magnus Öberg <magnus.oberg@westermo.se>
4  */
5 
6 /**
7  * @ingroup act
8  * @defgroup act_nat NAT
9  *
10  * @{
11  */
12 
13 #include <netlink-private/netlink.h>
14 #include <netlink-private/tc.h>
15 #include <netlink/netlink.h>
16 #include <netlink/attr.h>
17 #include <netlink/utils.h>
18 #include <netlink-private/route/tc-api.h>
19 #include <netlink/route/act/nat.h>
20 #include <netlink/route/tc.h>
21 
22 static struct nla_policy nat_policy[TCA_NAT_MAX + 1] = {
23  [TCA_NAT_PARMS] = { .minlen = sizeof(struct tc_nat) },
24 };
25 
26 /**
27  * nat operations
28  */
29 
30 static int nat_msg_parser(struct rtnl_tc *tc, void *data)
31 {
32  struct tc_nat *nat = data;
33  struct nlattr *tb[TCA_NAT_MAX + 1];
34  int err;
35 
36  err = tca_parse(tb, TCA_NAT_MAX, tc, nat_policy);
37  if (err < 0)
38  return err;
39 
40  if (!tb[TCA_NAT_PARMS])
41  return -NLE_MISSING_ATTR;
42 
43  nla_memcpy(nat, tb[TCA_NAT_PARMS], sizeof(*nat));
44 
45  return NLE_SUCCESS;
46 }
47 
48 static void nat_free_data(struct rtnl_tc *tc, void *data)
49 {
50 }
51 
52 static int nat_msg_fill(struct rtnl_tc *tc, void *data, struct nl_msg *msg)
53 {
54  struct tc_nat *nat = data;
55 
56  if (!nat)
57  return -NLE_OBJ_NOTFOUND;
58 
59  NLA_PUT(msg, TCA_NAT_PARMS, sizeof(*nat), nat);
60 
61  return NLE_SUCCESS;
62 
63 nla_put_failure:
64  return -NLE_NOMEM;
65 }
66 
67 static void nat_dump_line(struct rtnl_tc *tc, void *data,
68  struct nl_dump_params *p)
69 {
70  struct tc_nat *nat = data;
71  char buf[32];
72  uint32_t mask;
73  int pfx = 0;
74 
75  if (!nat)
76  return;
77 
78  if (nat->flags & TCA_NAT_FLAG_EGRESS)
79  nl_dump(p, " egress");
80  else
81  nl_dump(p, " ingress");
82 
83  mask = nat->mask;
84  while (mask > 0) {
85  mask = mask >> 1;
86  pfx++;
87  }
88 
89  inet_ntop(AF_INET, &nat->old_addr, buf, sizeof(buf));
90  nl_dump(p, " %s", buf);
91  if (pfx < 32)
92  nl_dump(p, "/%d", pfx);
93 
94  inet_ntop(AF_INET, &nat->new_addr, buf, sizeof(buf));
95  nl_dump(p, " %s", buf);
96  if (pfx < 32)
97  nl_dump(p, "/%d", pfx);
98 }
99 
100 /**
101  * @name Attribute Modifications
102  * @{
103  */
104 
105 /**
106  * Set old IPv4 address on a netlink NAT action object
107  * @arg act Action object
108  * @arg addr Binary IPv4 address in host byte order
109  *
110  * @return 0 on success or negative error code in case of an error.
111  */
112 int rtnl_nat_set_old_addr(struct rtnl_act *act, in_addr_t addr)
113 {
114  struct tc_nat *nat;
115 
116  if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
117  return -NLE_NOMEM;
118 
119  nat->old_addr = addr;
120 
121  return NLE_SUCCESS;
122 }
123 
124 int rtnl_nat_get_old_addr(struct rtnl_act *act, in_addr_t *addr)
125 {
126  struct tc_nat *nat;
127 
128  if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
129  return -NLE_NOATTR;
130 
131  *addr = nat->old_addr;
132 
133  return NLE_SUCCESS;
134 }
135 
136 /**
137  * Set new IPv4 address on a netlink NAT action object
138  * @arg act Action object
139  * @arg addr Binary IPv4 address in host byte order
140  *
141  * @return 0 on success or negative error code in case of an error.
142  */
143 int rtnl_nat_set_new_addr(struct rtnl_act *act, in_addr_t addr)
144 {
145  struct tc_nat *nat;
146 
147  if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
148  return -NLE_NOMEM;
149 
150  nat->new_addr = addr;
151 
152  return NLE_SUCCESS;
153 }
154 
155 int rtnl_nat_get_new_addr(struct rtnl_act *act, in_addr_t *addr)
156 {
157  struct tc_nat *nat;
158 
159  if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
160  return -NLE_NOATTR;
161 
162  *addr = nat->new_addr;
163 
164  return NLE_SUCCESS;
165 }
166 
167 /**
168  * Set IPv4 address mask on a netlink NAT action object
169  * @arg act Action object
170  * @arg mask IPv4 address mask
171  *
172  * @return 0 on success or negative error code in case of an error.
173  */
174 int rtnl_nat_set_mask(struct rtnl_act *act, in_addr_t bitmask)
175 {
176  struct tc_nat *nat;
177 
178  if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
179  return -NLE_NOMEM;
180 
181  nat->mask = bitmask;
182 
183  return NLE_SUCCESS;
184 }
185 
186 int rtnl_nat_get_mask(struct rtnl_act *act, in_addr_t *bitmask)
187 {
188  struct tc_nat *nat;
189 
190  if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
191  return -NLE_NOATTR;
192 
193  *bitmask = nat->mask;
194 
195  return NLE_SUCCESS;
196 }
197 
198 /**
199  * Set flags for a netlink NAT action object
200  * @arg act Action object
201  * @arg flags TCA_NAT_FLAG_* flags.
202  *
203  * Currently only TCA_NAT_FLAG_EGRESS is defined. Selects NAT on
204  * egress/IP src if set, ingress/IP dst otherwise.
205  *
206  * @return 0 on success or negative error code in case of an error.
207  */
208 int rtnl_nat_set_flags(struct rtnl_act *act, uint32_t flags)
209 {
210  struct tc_nat *nat;
211 
212  if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
213  return -NLE_NOMEM;
214 
215  nat->flags = flags;
216 
217  return NLE_SUCCESS;
218 }
219 
220 int rtnl_nat_get_flags(struct rtnl_act *act, uint32_t *flags)
221 {
222  struct tc_nat *nat;
223 
224  if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
225  return -NLE_NOATTR;
226 
227  *flags = nat->flags;
228 
229  return NLE_SUCCESS;
230 }
231 
232 int rtnl_nat_set_action(struct rtnl_act *act, int action)
233 {
234  struct tc_nat *nat;
235 
236  if (!(nat = (struct tc_nat *)rtnl_tc_data(TC_CAST(act))))
237  return -NLE_NOMEM;
238 
239  if (action < TC_ACT_UNSPEC)
240  return -NLE_INVAL;
241 
242  nat->action = action;
243 
244  return NLE_SUCCESS;
245 }
246 
247 int rtnl_nat_get_action(struct rtnl_act *act, int *action)
248 {
249  struct tc_nat *nat;
250 
251  if (!(nat = (struct tc_nat *)rtnl_tc_data_peek(TC_CAST(act))))
252  return -NLE_NOATTR;
253 
254  *action = nat->action;
255 
256  return NLE_SUCCESS;
257 }
258 
259 /**
260  * @}
261  */
262 
263 static struct rtnl_tc_ops nat_ops = {
264  .to_kind = "nat",
265  .to_type = RTNL_TC_TYPE_ACT,
266  .to_size = sizeof(struct tc_nat),
267  .to_msg_parser = nat_msg_parser,
268  .to_free_data = nat_free_data,
269  .to_clone = NULL,
270  .to_msg_fill = nat_msg_fill,
271  .to_dump = {
272  [NL_DUMP_LINE] = nat_dump_line,
273  },
274 };
275 
276 static void __init nat_init(void)
277 {
278  rtnl_tc_register(&nat_ops);
279 }
280 
281 static void __exit nat_exit(void)
282 {
283  rtnl_tc_unregister(&nat_ops);
284 }
285 
286 /**
287  * @}
288  */
int rtnl_nat_set_new_addr(struct rtnl_act *act, in_addr_t addr)
Set new IPv4 address on a netlink NAT action object.
Definition: nat.c:143
int rtnl_nat_set_flags(struct rtnl_act *act, uint32_t flags)
Set flags for a netlink NAT action object.
Definition: nat.c:208
int rtnl_nat_set_old_addr(struct rtnl_act *act, in_addr_t addr)
Set old IPv4 address on a netlink NAT action object.
Definition: nat.c:112
int rtnl_nat_set_mask(struct rtnl_act *act, in_addr_t bitmask)
Set IPv4 address mask on a netlink NAT action object.
Definition: nat.c:174
#define NLA_PUT(msg, attrtype, attrlen, data)
Add unspecific attribute to netlink message.
Definition: attr.h:159
int nla_memcpy(void *dest, const struct nlattr *src, int count)
Copy attribute payload to another memory area.
Definition: attr.c:346
void * rtnl_tc_data(struct rtnl_tc *tc)
Return pointer to private data of traffic control object.
Definition: tc.c:1076
void * rtnl_tc_data_peek(struct rtnl_tc *tc)
Returns the private data of the traffic control object.
Definition: tc.c:1062
#define TC_CAST(ptr)
Macro to cast qdisc/class/classifier to tc object.
Definition: tc.h:50
int rtnl_tc_register(struct rtnl_tc_ops *ops)
Register a traffic control module.
Definition: tc.c:1015
void rtnl_tc_unregister(struct rtnl_tc_ops *ops)
Unregister a traffic control module.
Definition: tc.c:1049
void nl_dump(struct nl_dump_params *params, const char *fmt,...)
Dump a formatted character string.
Definition: utils.c:955
@ NL_DUMP_LINE
Dump object briefly on one line.
Definition: types.h:16
Dumping parameters.
Definition: types.h:28
Attribute validation policy.
Definition: attr.h:63
uint16_t minlen
Minimal length of payload required.
Definition: attr.h:68