FD.io VPP  v18.10-34-gcce845e
Vector Packet Processing
dhcp_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * dhcp_api.c - dhcp api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vnet/dhcp/dhcp_proxy.h>
26 #include <vnet/dhcp/client.h>
30 #include <vnet/fib/fib_table.h>
31 
32 #include <vnet/vnet_msg_enum.h>
33 
34 #define vl_typedefs /* define message structures */
35 #include <vnet/vnet_all_api_h.h>
36 #undef vl_typedefs
37 
38 #define vl_endianfun /* define message structures */
39 #include <vnet/vnet_all_api_h.h>
40 #undef vl_endianfun
41 
42 /* instantiate all the print functions we know about */
43 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
44 #define vl_printfun
45 #include <vnet/vnet_all_api_h.h>
46 #undef vl_printfun
47 
49 
50 #define foreach_vpe_api_msg \
51 _(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
52 _(DHCP_PROXY_DUMP,dhcp_proxy_dump) \
53 _(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
54 _(DHCP_CLIENT_CONFIG, dhcp_client_config) \
55 _(DHCP_CLIENT_DUMP, dhcp_client_dump) \
56 _(WANT_DHCP6_PD_REPLY_EVENTS, want_dhcp6_pd_reply_events) \
57 _(DHCP6_PD_SEND_CLIENT_MESSAGE, dhcp6_pd_send_client_message) \
58 _(WANT_DHCP6_REPLY_EVENTS, want_dhcp6_reply_events) \
59 _(DHCP6_SEND_CLIENT_MESSAGE, dhcp6_send_client_message) \
60 _(DHCP6_CLIENTS_ENABLE_DISABLE, dhcp6_clients_enable_disable) \
61 _(DHCP6_DUID_LL_SET, dhcp6_duid_ll_set)
62 
63 
64 static void
66 {
67  vl_api_dhcp_proxy_set_vss_reply_t *rmp;
68  u8 *vpn_ascii_id;
69  int rv;
70 
71  mp->vpn_ascii_id[sizeof (mp->vpn_ascii_id) - 1] = 0;
72  vpn_ascii_id = format (0, "%s", mp->vpn_ascii_id);
73  rv =
75  ntohl (mp->tbl_id), mp->vss_type, vpn_ascii_id,
76  ntohl (mp->oui), ntohl (mp->vpn_index),
77  mp->is_add == 0);
78 
79  REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
80 }
81 
82 
85 {
86  vl_api_dhcp_proxy_set_vss_reply_t *rmp;
87  ip46_address_t src, server;
88  int rv = -1;
89 
90  if (mp->is_ipv6)
91  {
92  clib_memcpy (&src.ip6, mp->dhcp_src_address, sizeof (src.ip6));
93  clib_memcpy (&server.ip6, mp->dhcp_server, sizeof (server.ip6));
94 
95  rv = dhcp6_proxy_set_server (&server,
96  &src,
97  (u32) ntohl (mp->rx_vrf_id),
98  (u32) ntohl (mp->server_vrf_id),
99  (int) (mp->is_add == 0));
100  }
101  else
102  {
103  ip46_address_reset (&src);
104  ip46_address_reset (&server);
105 
106  clib_memcpy (&src.ip4, mp->dhcp_src_address, sizeof (src.ip4));
107  clib_memcpy (&server.ip4, mp->dhcp_server, sizeof (server.ip4));
108 
109  rv = dhcp4_proxy_set_server (&server,
110  &src,
111  (u32) ntohl (mp->rx_vrf_id),
112  (u32) ntohl (mp->server_vrf_id),
113  (int) (mp->is_add == 0));
114  }
115 
116 
117  REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
118 }
119 
120 static void
122 {
124 
126  if (!reg)
127  return;;
128 
129  dhcp_proxy_dump ((mp->is_ip6 == 1 ?
131 }
132 
133 void
135  void *opaque, u32 context, dhcp_proxy_t * proxy)
136 {
138  vl_api_registration_t *reg = opaque;
139  vl_api_dhcp_server_t *v_server;
140  dhcp_server_t *server;
141  fib_table_t *s_fib;
142  dhcp_vss_t *vss;
143  u32 count;
144  size_t n;
145 
146  count = vec_len (proxy->dhcp_servers);
147  n = sizeof (*mp) + (count * sizeof (vl_api_dhcp_server_t));
148  mp = vl_msg_api_alloc (n);
149  if (!mp)
150  return;
151  memset (mp, 0, n);
152  mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_DETAILS);
153  mp->context = context;
154  mp->count = count;
155 
156  mp->is_ipv6 = (proto == FIB_PROTOCOL_IP6);
157  mp->rx_vrf_id =
158  htonl (dhcp_proxy_rx_table_get_table_id (proto, proxy->rx_fib_index));
159 
160  vss = dhcp_get_vss_info (&dhcp_proxy_main, proxy->rx_fib_index, proto);
161 
162  if (vss)
163  {
164  mp->vss_type = vss->vss_type;
165  if (vss->vss_type == VSS_TYPE_ASCII)
166  {
167  u32 id_len = vec_len (vss->vpn_ascii_id);
168  clib_memcpy (mp->vss_vpn_ascii_id, vss->vpn_ascii_id, id_len);
169  }
170  else if (vss->vss_type == VSS_TYPE_VPN_ID)
171  {
172  u32 oui = ((u32) vss->vpn_id[0] << 16) + ((u32) vss->vpn_id[1] << 8)
173  + ((u32) vss->vpn_id[2]);
174  u32 fib_id = ((u32) vss->vpn_id[3] << 24) +
175  ((u32) vss->vpn_id[4] << 16) + ((u32) vss->vpn_id[5] << 8) +
176  ((u32) vss->vpn_id[6]);
177  mp->vss_oui = htonl (oui);
178  mp->vss_fib_id = htonl (fib_id);
179  }
180  }
181  else
183 
184  vec_foreach_index (count, proxy->dhcp_servers)
185  {
186  server = &proxy->dhcp_servers[count];
187  v_server = &mp->servers[count];
188 
189  s_fib = fib_table_get (server->server_fib_index, proto);
190 
191  v_server->server_vrf_id = htonl (s_fib->ft_table_id);
192 
193  if (mp->is_ipv6)
194  {
195  memcpy (v_server->dhcp_server, &server->dhcp_server.ip6, 16);
196  }
197  else
198  {
199  /* put the address in the first bytes */
200  memcpy (v_server->dhcp_server, &server->dhcp_server.ip4, 4);
201  }
202  }
203 
204  if (mp->is_ipv6)
205  {
206  memcpy (mp->dhcp_src_address, &proxy->dhcp_src_address.ip6, 16);
207  }
208  else
209  {
210  /* put the address in the first bytes */
211  memcpy (mp->dhcp_src_address, &proxy->dhcp_src_address.ip4, 4);
212  }
213  vl_api_send_msg (reg, (u8 *) mp);
214 }
215 
216 static void
218  const dhcp_client_t * client)
219 {
220  size_t len;
221 
222  lease->is_ipv6 = 0; // only support IPv6 clients
223  lease->sw_if_index = ntohl (client->sw_if_index);
224  lease->state = client->state;
225  len = clib_min (sizeof (lease->hostname) - 1, vec_len (client->hostname));
226  clib_memcpy (&lease->hostname, client->hostname, len);
227  lease->hostname[len] = 0;
228 
229  lease->mask_width = client->subnet_mask_width;
230  clib_memcpy (&lease->host_address[0], (u8 *) & client->leased_address, 4);
231  clib_memcpy (&lease->router_address[0], (u8 *) & client->router_address, 4);
232 
233  if (NULL != client->l2_rewrite)
234  clib_memcpy (&lease->host_mac[0], client->l2_rewrite + 6, 6);
235 }
236 
237 static void
239  const dhcp_client_t * client)
240 {
241  size_t len;
242 
243  vclient->sw_if_index = ntohl (client->sw_if_index);
244  len = clib_min (sizeof (vclient->hostname) - 1, vec_len (client->hostname));
245  clib_memcpy (&vclient->hostname, client->hostname, len);
246  vclient->hostname[len] = 0;
247 
248  len = clib_min (sizeof (vclient->id) - 1,
249  vec_len (client->client_identifier));
250  clib_memcpy (&vclient->id, client->client_identifier, len);
251  vclient->id[len] = 0;
252 
253  if (NULL != client->event_callback)
254  vclient->want_dhcp_event = 1;
255  else
256  vclient->want_dhcp_event = 0;
257  vclient->set_broadcast_flag = client->set_broadcast_flag;
258  vclient->pid = client->pid;
259 }
260 
261 static void
262 dhcp_compl_event_callback (u32 client_index, const dhcp_client_t * client)
263 {
266 
267  reg = vl_api_client_index_to_registration (client_index);
268  if (!reg)
269  return;
270 
271  mp = vl_msg_api_alloc (sizeof (*mp));
272  mp->client_index = client_index;
273  mp->pid = client->pid;
274  dhcp_client_lease_encode (&mp->lease, client);
275 
276  mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
277 
278  vl_api_send_msg (reg, (u8 *) mp);
279 }
280 
283 {
285  vl_api_dhcp_client_config_reply_t *rmp;
287  int rv = 0;
288 
289  sw_if_index = ntohl (mp->client.sw_if_index);
290  if (!vnet_sw_if_index_is_api_valid (sw_if_index))
291  {
292  rv = VNET_API_ERROR_INVALID_SW_IF_INDEX;
293  goto bad_sw_if_index;
294  }
295 
296  rv = dhcp_client_config (mp->is_add,
297  mp->client_index,
298  vm,
299  sw_if_index,
300  mp->client.hostname,
301  mp->client.id,
302  (mp->client.want_dhcp_event ?
304  NULL),
306 
308 
309  REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
310 }
311 
313 {
317 
318 static int
319 send_dhcp_client_entry (const dhcp_client_t * client, void *arg)
320 {
323 
324  ctx = arg;
325 
326  mp = vl_msg_api_alloc (sizeof (*mp));
327  memset (mp, 0, sizeof (*mp));
328 
329  mp->_vl_msg_id = ntohs (VL_API_DHCP_CLIENT_DETAILS);
330  mp->context = ctx->context;
331 
332  dhcp_client_data_encode (&mp->client, client);
333  dhcp_client_lease_encode (&mp->lease, client);
334 
335  vl_api_send_msg (ctx->reg, (u8 *) mp);
336 
337  return (1);
338 }
339 
340 static void
342 {
344 
346  if (!reg)
347  return;
348 
350  .reg = reg,
351  .context = mp->context,
352  };
354 }
355 
356 /*
357  * dhcp_api_hookup
358  * Add vpe's API message handlers to the table.
359  * vlib has alread mapped shared memory and
360  * added the client registration handlers.
361  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
362  */
363 #define vl_msg_name_crc_list
364 #include <vnet/vnet_all_api_h.h>
365 #undef vl_msg_name_crc_list
366 
367 static void
369 {
370 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
371  foreach_vl_msg_name_crc_dhcp;
372 #undef _
373 }
374 
375 static clib_error_t *
377 {
378  api_main_t *am = &api_main;
379 
380 #define _(N,n) \
381  vl_msg_api_set_handlers(VL_API_##N, #n, \
382  vl_api_##n##_t_handler, \
383  vl_noop_handler, \
384  vl_api_##n##_t_endian, \
385  vl_api_##n##_t_print, \
386  sizeof(vl_api_##n##_t), 1);
388 #undef _
389 
390  /*
391  * Set up the (msg_name, crc, message-id) table
392  */
394 
399 
400  return 0;
401 }
402 
404 
405 /*
406  * fd.io coding-style-patch-verification: ON
407  *
408  * Local Variables:
409  * eval: (c-set-style "gnu")
410  * End:
411  */
DHCP Proxy set / unset vss request.
Definition: dhcp.api:52
vl_api_dhcp_lease_t lease
Definition: dhcp.api:152
#define vec_foreach_index(var, v)
Iterate over vector indices.
static dhcp_vss_t * dhcp_get_vss_info(dhcp_proxy_main_t *dm, u32 rx_fib_index, fib_protocol_t proto)
Get the VSS data for the FIB index.
Definition: dhcp_proxy.h:237
vl_api_address_t src
Definition: vxlan_gbp.api:33
#define clib_min(x, y)
Definition: clib.h:291
static clib_error_t * dhcp_api_hookup(vlib_main_t *vm)
Definition: dhcp_api.c:376
#define VSS_TYPE_INVALID
Definition: dhcp_proxy.h:62
DHCP Client details returned from dump.
Definition: dhcp.api:148
dhcp_server_t * dhcp_servers
The set of DHCP servers to which messages are relayed.
Definition: dhcp_proxy.h:105
DHCP Client config data.
Definition: dhcp.api:75
#define NULL
Definition: clib.h:57
dhcp_proxy_main_t dhcp_proxy_main
Shard 4/6 instance of DHCP main.
Definition: dhcp_proxy.c:25
int dhcp6_proxy_set_server(ip46_address_t *addr, ip46_address_t *src_addr, u32 rx_table_id, u32 server_table_id, int is_del)
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
ip46_address_t dhcp_src_address
The source address to use in relayed messaes.
Definition: dhcp_proxy.h:120
The Virtual Sub-net Selection information for a given RX FIB.
Definition: dhcp_proxy.h:51
vlib_node_registration_t dhcp6_reply_process_node
(constructor) VLIB_REGISTER_NODE (dhcp6_reply_process_node)
u32 sw_if_index
Definition: client.h:50
void dhcp_send_details(fib_protocol_t proto, void *opaque, u32 context, dhcp_proxy_t *proxy)
Send the details of a proxy session to the API client during a dump.
Definition: dhcp_api.c:134
u32 rx_fib_index
The FIB index (not the external Table-ID) in which the client is resides.
Definition: dhcp_proxy.h:126
void dhcp_client_walk(dhcp_client_walk_cb_t cb, void *ctx)
Walk (visit each) DHCP client configuration.
Definition: client.c:1061
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
u8 vss_type
VSS type as defined in RFC 6607: 0 for NVT ASCII VPN Identifier 1 for RFC 2685 VPN-ID of 7 octects - ...
Definition: dhcp_proxy.h:59
static void vl_api_dhcp_client_dump_t_handler(vl_api_dhcp_client_dump_t *mp)
Definition: dhcp_api.c:341
dhcp_client_state_t state
Definition: client.h:47
void * vl_msg_api_alloc(int nbytes)
unsigned char u8
Definition: types.h:56
void dhcp6_set_publisher_node(uword node_index, uword event_type)
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
Dump the DHCP client configurations.
Definition: dhcp.api:138
void dhcp_proxy_dump(fib_protocol_t proto, void *opaque, u32 context)
Dump the proxy configs to the API.
Definition: dhcp_proxy.c:248
vl_api_dhcp_client_t client
Definition: dhcp.api:151
vl_api_dhcp_server_t servers[count]
Definition: dhcp.api:186
memset(h->entries, 0, sizeof(h->entries[0])*entries)
static void vl_api_dhcp_proxy_config_t_handler(vl_api_dhcp_proxy_config_t *mp)
Definition: dhcp_api.c:84
static int send_dhcp_client_entry(const dhcp_client_t *client, void *arg)
Definition: dhcp_api.c:319
u32 sw_if_index
Definition: vxlan_gbp.api:39
dhcp_event_cb_t event_callback
Definition: client.h:89
#define foreach_vpe_api_msg
Definition: dhcp_api.c:50
void dhcp6_pd_set_publisher_node(uword node_index, uword event_type)
#define VSS_TYPE_ASCII
Definition: dhcp_proxy.h:60
unsigned int u32
Definition: types.h:88
u8 set_broadcast_flag
Definition: client.h:84
u32 server_fib_index
The FIB index (not the external Table-ID) in which the server is reachable.
Definition: dhcp_proxy.h:89
ip4_address_t leased_address
Definition: client.h:63
struct dhcp_client_send_walk_ctx_t_ dhcp_client_send_walk_ctx_t
long ctx[MAX_CONNS]
Definition: main.c:144
int dhcp_client_config(u32 is_add, u32 client_index, vlib_main_t *vm, u32 sw_if_index, u8 *hostname, u8 *client_id, dhcp_event_cb_t event_callback, u8 set_broadcast_flag, u32 pid)
Add/Delete DHCP clients.
Definition: client.c:975
u8 * l2_rewrite
Definition: client.h:73
Data learned by the client during the DHCP process.
Definition: dhcp.api:108
#define REPLY_MACRO(t)
static void vl_api_dhcp_proxy_dump_t_handler(vl_api_dhcp_proxy_dump_t *mp)
Definition: dhcp_api.c:121
int dhcp_proxy_set_vss(fib_protocol_t proto, u32 tbl_id, u8 vss_type, u8 *vpn_ascii_id, u32 oui, u32 vpn_index, u8 is_del)
Configure/set a new VSS info.
Definition: dhcp_proxy.c:309
static void dhcp_client_data_encode(vl_api_dhcp_client_t *vclient, const dhcp_client_t *client)
Definition: dhcp_api.c:238
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
An API client registration, only in vpp/vlib.
Definition: api_common.h:44
#define BAD_SW_IF_INDEX_LABEL
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
u8 * vpn_ascii_id
Type 0 ASCII VPN Identifier.
Definition: dhcp_proxy.h:71
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
vlib_main_t * vm
Definition: buffer.c:294
static void dhcp_compl_event_callback(u32 client_index, const dhcp_client_t *client)
Definition: dhcp_api.c:262
#define clib_memcpy(a, b, c)
Definition: string.h:75
vl_api_registration_t * reg
Definition: dhcp_api.c:314
A representation of a single DHCP Server within a given VRF config.
Definition: dhcp_proxy.h:77
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
u8 router_address[16]
Definition: dhcp.api:116
int dhcp4_proxy_set_server(ip46_address_t *addr, ip46_address_t *src_addr, u32 rx_table_id, u32 server_table_id, int is_del)
ip46_address_t dhcp_server
The address of the DHCP server to which to relay the client&#39;s messages.
Definition: dhcp_proxy.h:83
VLIB_API_INIT_FUNCTION(dhcp_api_hookup)
size_t count
Definition: vapi.c:46
u32 subnet_mask_width
Definition: client.h:65
vl_api_dhcp_lease_t lease
Definition: dhcp.api:129
ip4_address_t router_address
Definition: client.h:66
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u8 dhcp_server[16]
Definition: dhcp.api:169
Tell client about a DHCP completion event.
Definition: dhcp.api:175
#define ip46_address_reset(ip46)
Definition: ip6_packet.h:91
A DHCP proxy represenation fpr per-client VRF config.
Definition: dhcp_proxy.h:95
u8 * client_identifier
Definition: client.h:77
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u8 vpn_id[7]
Type 1 VPN-ID.
Definition: dhcp_proxy.h:67
vl_api_dhcp_client_t client
Definition: dhcp.api:96
static void setup_message_id_table(api_main_t *am)
Definition: dhcp_api.c:368
#define VSS_TYPE_VPN_ID
Definition: dhcp_proxy.h:61
static void vl_api_dhcp_client_config_t_handler(vl_api_dhcp_client_config_t *mp)
Definition: dhcp_api.c:282
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:27
static void vl_api_dhcp_proxy_set_vss_t_handler(vl_api_dhcp_proxy_set_vss_t *mp)
Definition: dhcp_api.c:65
Dump DHCP proxy table.
Definition: dhcp.api:159
u8 * hostname
Definition: client.h:76
vlib_node_registration_t dhcp6_pd_reply_process_node
(constructor) VLIB_REGISTER_NODE (dhcp6_pd_reply_process_node)
u32 dhcp_proxy_rx_table_get_table_id(fib_protocol_t proto, u32 fib_index)
Definition: dhcp_proxy.c:46
static void dhcp_client_lease_encode(vl_api_dhcp_lease_t *lease, const dhcp_client_t *client)
Definition: dhcp_api.c:217
Tell client about a DHCP completion event.
Definition: dhcp.api:125
api_main_t api_main
Definition: api_shared.c:35
DHCP Client config add / del request.
Definition: dhcp.api:91
u8 host_address[16]
Definition: dhcp.api:115
DHCP Proxy config add / del request.
Definition: dhcp.api:29
A protocol Independent FIB table.
Definition: fib_table.h:69