FD.io VPP  v20.01-48-g3e0dafb74
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 <dhcp/dhcp_proxy.h>
26 #include <dhcp/client.h>
30 #include <vnet/fib/fib_table.h>
31 #include <vnet/ip/ip_types_api.h>
32 
33 /* define message IDs */
34 #include <vnet/format_fns.h>
35 #include <dhcp/dhcp.api_enum.h>
36 #include <dhcp/dhcp.api_types.h>
37 
38 /**
39  * Base message ID fot the plugin
40  */
42 #define REPLY_MSG_ID_BASE dhcp_base_msg_id
43 
45 
46 #define DHCP_PLUGIN_VERSION_MAJOR 1
47 #define DHCP_PLUGIN_VERSION_MINOR 0
48 
49 static void
51  mp)
52 {
54  int msg_size = sizeof (*rmp);
56 
58  if (!reg)
59  return;
60 
61  rmp = vl_msg_api_alloc (msg_size);
62  clib_memset (rmp, 0, msg_size);
63  rmp->_vl_msg_id =
64  ntohs (VL_API_DHCP_PLUGIN_GET_VERSION_REPLY + REPLY_MSG_ID_BASE);
65  rmp->context = mp->context;
66  rmp->major = htonl (DHCP_PLUGIN_VERSION_MAJOR);
67  rmp->minor = htonl (DHCP_PLUGIN_VERSION_MINOR);
68 
69  vl_api_send_msg (reg, (u8 *) rmp);
70 }
71 
72 static void
74  mp)
75 {
77  int rv = 0;
78 
79  /* *INDENT-OFF* */
80  REPLY_MACRO2 (VL_API_DHCP_PLUGIN_CONTROL_PING_REPLY,
81  ({
82  rmp->vpe_pid = ntohl (getpid ());
83  }));
84  /* *INDENT-ON* */
85 }
86 
87 static void
89 {
90  vl_api_dhcp6_duid_ll_set_reply_t *rmp;
92  int rv = 0;
93 
94  duid = (dhcpv6_duid_ll_string_t *) mp->duid_ll;
95  if (duid->duid_type != htonl (DHCPV6_DUID_LL))
96  {
97  rv = VNET_API_ERROR_INVALID_VALUE;
98  goto reply;
99  }
100  clib_memcpy (&client_duid, &duid, sizeof (client_duid));
101 
102 reply:
103  REPLY_MACRO (VL_API_DHCP6_DUID_LL_SET_REPLY);
104 }
105 
106 static void
108 {
109  vl_api_dhcp_proxy_set_vss_reply_t *rmp;
110  u8 *vpn_ascii_id;
111  int rv;
112 
113  mp->vpn_ascii_id[sizeof (mp->vpn_ascii_id) - 1] = 0;
114  vpn_ascii_id = format (0, "%s", mp->vpn_ascii_id);
115  rv =
117  ntohl (mp->tbl_id), ntohl (mp->vss_type),
118  vpn_ascii_id, ntohl (mp->oui), ntohl (mp->vpn_index),
119  mp->is_add == 0);
120 
121  REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
122 }
123 
124 
127 {
128  vl_api_dhcp_proxy_set_vss_reply_t *rmp;
129  ip46_address_t src, server;
130  int rv = -1;
131 
132  if (mp->dhcp_src_address.af != mp->dhcp_server.af)
133  {
134  rv = VNET_API_ERROR_INVALID_ARGUMENT;
135  goto reply;
136  }
137 
138  ip_address_decode (&mp->dhcp_src_address, &src);
139  ip_address_decode (&mp->dhcp_server, &server);
140 
141  if (mp->dhcp_src_address.af == ADDRESS_IP4)
142  {
143  rv = dhcp4_proxy_set_server (&server,
144  &src,
145  (u32) ntohl (mp->rx_vrf_id),
146  (u32) ntohl (mp->server_vrf_id),
147  (int) (mp->is_add == 0));
148  }
149  else
150  {
151  rv = dhcp6_proxy_set_server (&server,
152  &src,
153  (u32) ntohl (mp->rx_vrf_id),
154  (u32) ntohl (mp->server_vrf_id),
155  (int) (mp->is_add == 0));
156  }
157 
158 reply:
159  REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
160 }
161 
162 static void
164 {
166 
168  if (!reg)
169  return;;
170 
171  dhcp_proxy_dump ((mp->is_ip6 == 1 ?
173 }
174 
175 void
177  void *opaque, u32 context, dhcp_proxy_t * proxy)
178 {
180  vl_api_registration_t *reg = opaque;
181  vl_api_dhcp_server_t *v_server;
182  dhcp_server_t *server;
183  fib_table_t *s_fib;
184  dhcp_vss_t *vss;
185  u32 count;
186  size_t n;
187 
188  count = vec_len (proxy->dhcp_servers);
189  n = sizeof (*mp) + (count * sizeof (vl_api_dhcp_server_t));
190  mp = vl_msg_api_alloc (n);
191  if (!mp)
192  return;
193  clib_memset (mp, 0, n);
194  mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_DETAILS + REPLY_MSG_ID_BASE);
195  mp->context = context;
196  mp->count = count;
197 
198  mp->is_ipv6 = (proto == FIB_PROTOCOL_IP6);
199  mp->rx_vrf_id =
200  htonl (dhcp_proxy_rx_table_get_table_id (proto, proxy->rx_fib_index));
201 
202  vss = dhcp_get_vss_info (&dhcp_proxy_main, proxy->rx_fib_index, proto);
203 
204  if (vss)
205  {
206  mp->vss_type = ntohl (vss->vss_type);
207  if (vss->vss_type == VSS_TYPE_ASCII)
208  {
209  u32 id_len = vec_len (vss->vpn_ascii_id);
210  clib_memcpy (mp->vss_vpn_ascii_id, vss->vpn_ascii_id, id_len);
211  }
212  else if (vss->vss_type == VSS_TYPE_VPN_ID)
213  {
214  u32 oui = ((u32) vss->vpn_id[0] << 16) + ((u32) vss->vpn_id[1] << 8)
215  + ((u32) vss->vpn_id[2]);
216  u32 fib_id = ((u32) vss->vpn_id[3] << 24) +
217  ((u32) vss->vpn_id[4] << 16) + ((u32) vss->vpn_id[5] << 8) +
218  ((u32) vss->vpn_id[6]);
219  mp->vss_oui = htonl (oui);
220  mp->vss_fib_id = htonl (fib_id);
221  }
222  }
223  else
225 
226  vec_foreach_index (count, proxy->dhcp_servers)
227  {
228  server = &proxy->dhcp_servers[count];
229  v_server = &mp->servers[count];
230 
231  s_fib = fib_table_get (server->server_fib_index, proto);
232 
233  v_server->server_vrf_id = htonl (s_fib->ft_table_id);
234 
235  if (mp->is_ipv6)
236  {
237  memcpy (&v_server->dhcp_server.un, &server->dhcp_server.ip6, 16);
238  }
239  else
240  {
241  /* put the address in the first bytes */
242  memcpy (&v_server->dhcp_server.un, &server->dhcp_server.ip4, 4);
243  }
244  }
245 
246  if (mp->is_ipv6)
247  {
248  memcpy (&mp->dhcp_src_address.un, &proxy->dhcp_src_address.ip6, 16);
249  }
250  else
251  {
252  /* put the address in the first bytes */
253  memcpy (&mp->dhcp_src_address.un, &proxy->dhcp_src_address.ip4, 4);
254  }
255  vl_api_send_msg (reg, (u8 *) mp);
256 }
257 
258 static void
259 dhcp_client_lease_encode (vl_api_dhcp_lease_t * lease,
260  const dhcp_client_t * client)
261 {
262  size_t len;
263  u8 i;
264 
265  lease->is_ipv6 = 0; // only support IPv6 clients
266  lease->sw_if_index = ntohl (client->sw_if_index);
267  lease->state = ntohl (client->state);
268  len = clib_min (sizeof (lease->hostname) - 1, vec_len (client->hostname));
269  clib_memcpy (&lease->hostname, client->hostname, len);
270  lease->hostname[len] = 0;
271 
272  lease->mask_width = client->installed.subnet_mask_width;
273  clib_memcpy (&lease->host_address.un,
274  (u8 *) & client->installed.leased_address,
275  sizeof (ip4_address_t));
276  clib_memcpy (&lease->router_address.un,
277  (u8 *) & client->installed.router_address,
278  sizeof (ip4_address_t));
279 
280  lease->count = vec_len (client->domain_server_address);
281  for (i = 0; i < lease->count; i++)
282  clib_memcpy (&lease->domain_server[i].address,
283  (u8 *) & client->domain_server_address[i],
284  sizeof (ip4_address_t));
285 
286  clib_memcpy (&lease->host_mac[0], client->client_hardware_address, 6);
287 }
288 
289 static void
290 dhcp_client_data_encode (vl_api_dhcp_client_t * vclient,
291  const dhcp_client_t * client)
292 {
293  size_t len;
294 
295  vclient->sw_if_index = ntohl (client->sw_if_index);
296  len = clib_min (sizeof (vclient->hostname) - 1, vec_len (client->hostname));
297  clib_memcpy (&vclient->hostname, client->hostname, len);
298  vclient->hostname[len] = 0;
299 
300  len = clib_min (sizeof (vclient->id) - 1,
301  vec_len (client->client_identifier));
302  clib_memcpy (&vclient->id, client->client_identifier, len);
303  vclient->id[len] = 0;
304 
305  if (NULL != client->event_callback)
306  vclient->want_dhcp_event = 1;
307  else
308  vclient->want_dhcp_event = 0;
309  vclient->set_broadcast_flag = client->set_broadcast_flag;
310  vclient->dscp = ip_dscp_encode (client->dscp);
311  vclient->pid = client->pid;
312 }
313 
314 static void
315 dhcp_compl_event_callback (u32 client_index, const dhcp_client_t * client)
316 {
319 
320  reg = vl_api_client_index_to_registration (client_index);
321  if (!reg)
322  return;
323 
324  mp = vl_msg_api_alloc (sizeof (*mp));
325  mp->client_index = client_index;
326  mp->pid = client->pid;
327  dhcp_client_lease_encode (&mp->lease, client);
328 
329  mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT + REPLY_MSG_ID_BASE);
330 
331  vl_api_send_msg (reg, (u8 *) mp);
332 }
333 
336 {
338  vl_api_dhcp_client_config_reply_t *rmp;
340  ip_dscp_t dscp;
341  int rv = 0;
342 
343  VALIDATE_SW_IF_INDEX (&(mp->client));
344 
345  sw_if_index = ntohl (mp->client.sw_if_index);
346  dscp = ip_dscp_decode (mp->client.dscp);
347 
348  rv = dhcp_client_config (mp->is_add,
349  mp->client_index,
350  vm,
351  sw_if_index,
352  mp->client.hostname,
353  mp->client.id,
354  (mp->client.want_dhcp_event ?
356  NULL),
357  mp->client.set_broadcast_flag,
358  dscp, mp->client.pid);
359 
361  REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
362 }
363 
365 {
369 
370 static int
371 send_dhcp_client_entry (const dhcp_client_t * client, void *arg)
372 {
375  u32 count;
376  size_t n;
377 
378  ctx = arg;
379 
380  count = vec_len (client->domain_server_address);
381  n = sizeof (*mp) + (count * sizeof (vl_api_domain_server_t));
382  mp = vl_msg_api_alloc (n);
383  if (!mp)
384  return 0;
385  clib_memset (mp, 0, n);
386 
387  mp->_vl_msg_id = ntohs (VL_API_DHCP_CLIENT_DETAILS + REPLY_MSG_ID_BASE);
388  mp->context = ctx->context;
389 
390  dhcp_client_data_encode (&mp->client, client);
391  dhcp_client_lease_encode (&mp->lease, client);
392 
393  vl_api_send_msg (ctx->reg, (u8 *) mp);
394 
395  return (1);
396 }
397 
398 static void
400 {
402 
404  if (!reg)
405  return;
406 
408  .reg = reg,
409  .context = mp->context,
410  };
412 }
413 
414 static void
417 {
418  vl_api_dhcp6_clients_enable_disable_reply_t *rmp;
419  int rv = 0;
420 
422 
423  REPLY_MACRO (VL_API_DHCP6_CLIENTS_ENABLE_DISABLE_REPLY);
424 }
425 
426 void
429 {
431  vl_api_want_dhcp6_reply_events_reply_t *rmp;
432  int rv = 0;
433 
434  uword *p =
435  hash_get (am->dhcp6_reply_events_registration_hash, mp->client_index);
437  if (p)
438  {
439  if (mp->enable_disable)
440  {
441  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
442  rv = VNET_API_ERROR_INVALID_REGISTRATION;
443  goto reply;
444  }
445  else
446  {
447  rp = pool_elt_at_index (am->dhcp6_reply_events_registrations, p[0]);
448  pool_put (am->dhcp6_reply_events_registrations, rp);
449  hash_unset (am->dhcp6_reply_events_registration_hash,
450  mp->client_index);
451  if (pool_elts (am->dhcp6_reply_events_registrations) == 0)
453  goto reply;
454  }
455  }
456  if (mp->enable_disable == 0)
457  {
458  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
459  rv = VNET_API_ERROR_INVALID_REGISTRATION;
460  goto reply;
461  }
462  pool_get (am->dhcp6_reply_events_registrations, rp);
463  rp->client_index = mp->client_index;
464  rp->client_pid = ntohl (mp->pid);
465  hash_set (am->dhcp6_reply_events_registration_hash, rp->client_index,
466  rp - am->dhcp6_reply_events_registrations);
469 
470 reply:
471  REPLY_MACRO (VL_API_WANT_DHCP6_REPLY_EVENTS_REPLY);
472 }
473 
474 void
477 {
479  vl_api_want_dhcp6_pd_reply_events_reply_t *rmp;
480  int rv = 0;
481 
482  uword *p =
483  hash_get (am->dhcp6_pd_reply_events_registration_hash, mp->client_index);
485  if (p)
486  {
487  if (mp->enable_disable)
488  {
489  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
490  rv = VNET_API_ERROR_INVALID_REGISTRATION;
491  goto reply;
492  }
493  else
494  {
495  rp =
496  pool_elt_at_index (am->dhcp6_pd_reply_events_registrations, p[0]);
497  pool_put (am->dhcp6_pd_reply_events_registrations, rp);
498  hash_unset (am->dhcp6_pd_reply_events_registration_hash,
499  mp->client_index);
500  if (pool_elts (am->dhcp6_pd_reply_events_registrations) == 0)
502  goto reply;
503  }
504  }
505  if (mp->enable_disable == 0)
506  {
507  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
508  rv = VNET_API_ERROR_INVALID_REGISTRATION;
509  goto reply;
510  }
511  pool_get (am->dhcp6_pd_reply_events_registrations, rp);
512  rp->client_index = mp->client_index;
513  rp->client_pid = ntohl (mp->pid);
514  hash_set (am->dhcp6_pd_reply_events_registration_hash, rp->client_index,
515  rp - am->dhcp6_pd_reply_events_registrations);
516  dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index,
518 
519 reply:
520  REPLY_MACRO (VL_API_WANT_DHCP6_PD_REPLY_EVENTS_REPLY);
521 }
522 
523 void
526 {
527  vl_api_dhcp6_send_client_message_reply_t *rmp;
530  u32 n_addresses;
531  u32 i;
532  int rv = 0;
533 
535 
537  REPLY_MACRO (VL_API_DHCP6_SEND_CLIENT_MESSAGE_REPLY);
538 
539  if (rv != 0)
540  return;
541 
542  params.sw_if_index = ntohl (mp->sw_if_index);
543  params.server_index = ntohl (mp->server_index);
544  params.irt = ntohl (mp->irt);
545  params.mrt = ntohl (mp->mrt);
546  params.mrc = ntohl (mp->mrc);
547  params.mrd = ntohl (mp->mrd);
548  params.msg_type = ntohl (mp->msg_type);
549  params.T1 = ntohl (mp->T1);
550  params.T2 = ntohl (mp->T2);
551  n_addresses = ntohl (mp->n_addresses);
552  params.addresses = 0;
553  if (n_addresses > 0)
554  vec_validate (params.addresses, n_addresses - 1);
555  for (i = 0; i < n_addresses; i++)
556  {
557  vl_api_dhcp6_address_info_t *ai = &mp->addresses[i];
559  addr->preferred_lt = ntohl (ai->preferred_time);
560  addr->valid_lt = ntohl (ai->valid_time);
561  ip6_address_decode (ai->address, &addr->address);
562  }
563 
564  dhcp6_send_client_message (vm, ntohl (mp->sw_if_index), mp->stop, &params);
565 }
566 
567 void
570 {
571  vl_api_dhcp6_pd_send_client_message_reply_t *rmp;
574  u32 n_prefixes;
575  u32 i;
576  int rv = 0;
577 
579 
581  REPLY_MACRO (VL_API_DHCP6_PD_SEND_CLIENT_MESSAGE_REPLY);
582 
583  if (rv != 0)
584  return;
585 
586  params.sw_if_index = ntohl (mp->sw_if_index);
587  params.server_index = ntohl (mp->server_index);
588  params.irt = ntohl (mp->irt);
589  params.mrt = ntohl (mp->mrt);
590  params.mrc = ntohl (mp->mrc);
591  params.mrd = ntohl (mp->mrd);
592  params.msg_type = ntohl (mp->msg_type);
593  params.T1 = ntohl (mp->T1);
594  params.T2 = ntohl (mp->T2);
595  n_prefixes = ntohl (mp->n_prefixes);
596  params.prefixes = 0;
597  if (n_prefixes > 0)
598  vec_validate (params.prefixes, n_prefixes - 1);
599  for (i = 0; i < n_prefixes; i++)
600  {
601  vl_api_dhcp6_pd_prefix_info_t *pi = &mp->prefixes[i];
603  &params.prefixes[i];
604  pref->preferred_lt = ntohl (pi->preferred_time);
605  pref->valid_lt = ntohl (pi->valid_time);
606  ip6_address_decode (pi->prefix.address, &pref->prefix);
607  pref->prefix_length = pi->prefix.len;
608  }
609 
610  dhcp6_pd_send_client_message (vm, ntohl (mp->sw_if_index), mp->stop,
611  &params);
612 }
613 
614 static clib_error_t *
616  _vnet_dhcp6_reply_event_function_list_elt_t
617  * elt)
618 {
619  clib_error_t *error = 0;
620 
621  while (elt)
622  {
623  error = elt->fp (data);
624  if (error)
625  return error;
626  elt = elt->next_dhcp6_reply_event_function;
627  }
628 
629  return error;
630 }
631 
632 static uword
634  vlib_frame_t * f)
635 {
636  /* These cross the longjmp boundary (vlib_process_wait_for_event)
637  * and need to be volatile - to prevent them from being optimized into
638  * a register - which could change during suspension */
639 
640  while (1)
641  {
643  uword event_type = DHCP6_DP_REPLY_REPORT;
644  void *event_data = vlib_process_get_event_data (vm, &event_type);
645 
646  int i;
647  if (event_type == DHCP6_DP_REPLY_REPORT)
648  {
649  address_report_t *events = event_data;
650  for (i = 0; i < vec_len (events); i++)
651  {
652  u32 event_size =
653  sizeof (vl_api_dhcp6_reply_event_t) +
654  vec_len (events[i].addresses) *
655  sizeof (vl_api_dhcp6_address_info_t);
656  vl_api_dhcp6_reply_event_t *event = clib_mem_alloc (event_size);
657  clib_memset (event, 0, event_size);
658 
659  event->sw_if_index = htonl (events[i].body.sw_if_index);
660  event->server_index = htonl (events[i].body.server_index);
661  event->msg_type = events[i].body.msg_type;
662  event->T1 = htonl (events[i].body.T1);
663  event->T2 = htonl (events[i].body.T2);
664  event->inner_status_code =
665  htons (events[i].body.inner_status_code);
666  event->status_code = htons (events[i].body.status_code);
667  event->preference = events[i].body.preference;
668 
669  event->n_addresses = htonl (vec_len (events[i].addresses));
670  vl_api_dhcp6_address_info_t *address =
671  (typeof (address)) event->addresses;
672  u32 j;
673  for (j = 0; j < vec_len (events[i].addresses); j++)
674  {
675  dhcp6_address_info_t *info = &events[i].addresses[j];
676  ip6_address_encode (&info->address, address->address);
677  address->valid_time = htonl (info->valid_time);
678  address->preferred_time = htonl (info->preferred_time);
679  address++;
680  }
681  vec_free (events[i].addresses);
682 
686 
688  /* *INDENT-OFF* */
689  pool_foreach(reg, vpe_api_main.dhcp6_reply_events_registrations,
690  ({
691  vl_api_registration_t *vl_reg;
692  vl_reg =
693  vl_api_client_index_to_registration (reg->client_index);
694  if (vl_reg && vl_api_can_send_msg (vl_reg))
695  {
696  vl_api_dhcp6_reply_event_t *msg =
697  vl_msg_api_alloc (event_size);
698  clib_memcpy (msg, event, event_size);
699  msg->_vl_msg_id = htons (VL_API_DHCP6_REPLY_EVENT + REPLY_MSG_ID_BASE);
700  msg->client_index = reg->client_index;
701  msg->pid = reg->client_pid;
702  vl_api_send_msg (vl_reg, (u8 *) msg);
703  }
704  }));
705  /* *INDENT-ON* */
706 
707  clib_mem_free (event);
708  }
709  }
710  vlib_process_put_event_data (vm, event_data);
711  }
712 
713  return 0;
714 }
715 
716 /* *INDENT-OFF* */
718  .function = dhcp6_reply_process,
719  .type = VLIB_NODE_TYPE_PROCESS,
720  .name = "dhcp6-reply-publisher-process",
721 };
722 /* *INDENT-ON* */
723 
724 static clib_error_t *
726  _vnet_dhcp6_pd_reply_event_function_list_elt_t
727  * elt)
728 {
729  clib_error_t *error = 0;
730 
731  while (elt)
732  {
733  error = elt->fp (data);
734  if (error)
735  return error;
736  elt = elt->next_dhcp6_pd_reply_event_function;
737  }
738 
739  return error;
740 }
741 
742 static uword
744  vlib_frame_t * f)
745 {
746  /* These cross the longjmp boundary (vlib_process_wait_for_event)
747  * and need to be volatile - to prevent them from being optimized into
748  * a register - which could change during suspension */
749 
750  while (1)
751  {
753  uword event_type = DHCP6_PD_DP_REPLY_REPORT;
754  void *event_data = vlib_process_get_event_data (vm, &event_type);
755 
756  int i;
757  if (event_type == DHCP6_PD_DP_REPLY_REPORT)
758  {
759  prefix_report_t *events = event_data;
760  for (i = 0; i < vec_len (events); i++)
761  {
762  u32 event_size =
764  vec_len (events[i].prefixes) *
765  sizeof (vl_api_dhcp6_pd_prefix_info_t);
767  clib_mem_alloc (event_size);
768  clib_memset (event, 0, event_size);
769 
770  event->sw_if_index = htonl (events[i].body.sw_if_index);
771  event->server_index = htonl (events[i].body.server_index);
772  event->msg_type = events[i].body.msg_type;
773  event->T1 = htonl (events[i].body.T1);
774  event->T2 = htonl (events[i].body.T2);
775  event->inner_status_code =
776  htons (events[i].body.inner_status_code);
777  event->status_code = htons (events[i].body.status_code);
778  event->preference = events[i].body.preference;
779 
780  event->n_prefixes = htonl (vec_len (events[i].prefixes));
781  vl_api_dhcp6_pd_prefix_info_t *prefix =
782  (typeof (prefix)) event->prefixes;
783  u32 j;
784  for (j = 0; j < vec_len (events[i].prefixes); j++)
785  {
786  dhcp6_prefix_info_t *info = &events[i].prefixes[j];
787  ip6_address_encode (&info->prefix, prefix->prefix.address);
788  prefix->prefix.len = info->prefix_length;
789  prefix->valid_time = htonl (info->valid_time);
790  prefix->preferred_time = htonl (info->preferred_time);
791  prefix++;
792  }
793  vec_free (events[i].prefixes);
794 
798 
800  /* *INDENT-OFF* */
801  pool_foreach(reg, vpe_api_main.dhcp6_pd_reply_events_registrations,
802  ({
803  vl_api_registration_t *vl_reg;
804  vl_reg =
805  vl_api_client_index_to_registration (reg->client_index);
806  if (vl_reg && vl_api_can_send_msg (vl_reg))
807  {
808  vl_api_dhcp6_pd_reply_event_t *msg =
809  vl_msg_api_alloc (event_size);
810  clib_memcpy (msg, event, event_size);
811  msg->_vl_msg_id = htons (VL_API_DHCP6_PD_REPLY_EVENT + REPLY_MSG_ID_BASE);
812  msg->client_index = reg->client_index;
813  msg->pid = reg->client_pid;
814  vl_api_send_msg (vl_reg, (u8 *) msg);
815  }
816  }));
817  /* *INDENT-ON* */
818 
819  clib_mem_free (event);
820  }
821  }
822  vlib_process_put_event_data (vm, event_data);
823  }
824 
825  return 0;
826 }
827 
828 /* *INDENT-OFF* */
829 VLIB_REGISTER_NODE (dhcp6_pd_reply_process_node) = {
830  .function = dhcp6_pd_reply_process,
831  .type = VLIB_NODE_TYPE_PROCESS,
832  .name = "dhcp6-pd-reply-publisher-process",
833 };
834 /* *INDENT-ON* */
835 
836 /*
837  * dhcp_api_hookup
838  * Add vpe's API message handlers to the table.
839  * vlib has already mapped shared memory and
840  * added the client registration handlers.
841  * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
842  */
843 #include <dhcp/dhcp.api.c>
844 
845 static clib_error_t *
847 {
848  /*
849  * Set up the (msg_name, crc, message-id) table
850  */
851  dhcp_base_msg_id = setup_message_id_table ();
852 
853  dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index,
857 
858  return 0;
859 }
860 
862 
863 #include <vlib/unix/plugin.h>
864 #include <vpp/app/version.h>
865 
866 /* *INDENT-OFF* */
868  .version = VPP_BUILD_VER,
869  .description = "Dynamic Host Configuration Protocol (DHCP)",
870 };
871 /* *INDENT-ON* */
872 
873 /*
874  * fd.io coding-style-patch-verification: ON
875  *
876  * Local Variables:
877  * eval: (c-set-style "gnu")
878  * End:
879  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:440
Send DHCPv6 PD client message of specified type.
Definition: dhcp.api:388
Enable/disable listening on DHCPv6 client port.
Definition: dhcp.api:297
u8 count
Definition: dhcp.api:208
DHCP Proxy set / unset vss request.
Definition: dhcp.api:132
Set DHCPv6 DUID-LL.
Definition: dhcp.api:286
vl_api_dhcp_lease_t lease
Definition: dhcp.api:244
#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:255
u8 proto
Definition: acl_types.api:47
#define hash_set(h, key, value)
Definition: hash.h:255
#define clib_min(x, y)
Definition: clib.h:295
vl_api_address_t dhcp_src_address
Definition: dhcp.api:118
vl_api_dhcpv6_msg_type_t msg_type
Definition: dhcp.api:399
#define hash_unset(h, key)
Definition: hash.h:261
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:593
static clib_error_t * dhcp_api_hookup(vlib_main_t *vm)
Definition: dhcp_api.c:846
#define VSS_TYPE_INVALID
Definition: dhcp_proxy.h:68
ip4_address_t router_address
The address of this client&#39;s default gateway - may not be present.
Definition: client.h:60
DHCP Client details returned from dump.
Definition: dhcp.api:240
static void vl_api_dhcp6_duid_ll_set_t_handler(vl_api_dhcp6_duid_ll_set_t *mp)
Definition: dhcp_api.c:88
dhcp_server_t * dhcp_servers
The set of DHCP servers to which messages are relayed.
Definition: dhcp_proxy.h:111
ip_dscp_t dscp
Definition: client.h:114
#define REPLY_MACRO2(t, body)
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
dhcp_proxy_main_t dhcp_proxy_main
Shard 4/6 instance of DHCP main.
Definition: dhcp_proxy.c:25
_vnet_dhcp6_reply_event_function_list_elt_t * functions
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:35
void ip6_address_decode(const vl_api_ip6_address_t in, ip6_address_t *out)
Definition: ip_types_api.c:117
ip46_address_t dhcp_src_address
The source address to use in relayed messaes.
Definition: dhcp_proxy.h:126
The Virtual Sub-net Selection information for a given RX FIB.
Definition: dhcp_proxy.h:57
vl_api_address_t src
Definition: gre.api:60
dhcp6_pd_send_client_message_params_prefix_t * prefixes
for(i=1;i<=collision_buckets;i++)
int i
u32 sw_if_index
Definition: client.h:68
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:176
u32 rx_fib_index
The FIB index (not the external Table-ID) in which the client is resides.
Definition: dhcp_proxy.h:132
void dhcp6_pd_send_client_message(vlib_main_t *vm, u32 sw_if_index, u8 stop, dhcp6_pd_send_client_message_params_t *params)
static uword dhcp6_reply_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: dhcp_api.c:633
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
void vl_api_dhcp6_pd_send_client_message_t_handler(vl_api_dhcp6_pd_send_client_message_t *mp)
Definition: dhcp_api.c:569
static u32 dhcp_base_msg_id
Base message ID fot the plugin.
Definition: dhcp_api.c:41
dhcp_client_fwd_addresses_t installed
Definition: client.h:86
vl_api_prefix_t prefix
Definition: ip.api:144
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:65
static void vl_api_dhcp_client_dump_t_handler(vl_api_dhcp_client_dump_t *mp)
Definition: dhcp_api.c:399
dhcp_client_state_t state
Definition: client.h:65
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:237
void * vl_msg_api_alloc(int nbytes)
vhost_vring_addr_t addr
Definition: vhost_user.h:147
unsigned char u8
Definition: types.h:56
void dhcp6_set_publisher_node(uword node_index, uword event_type)
static clib_error_t * call_dhcp6_reply_event_callbacks(void *data, _vnet_dhcp6_reply_event_function_list_elt_t *elt)
Definition: dhcp_api.c:615
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
Dump the DHCP client configurations.
Definition: dhcp.api:230
#define clib_memcpy(d, s, n)
Definition: string.h:180
void dhcp_proxy_dump(fib_protocol_t proto, void *opaque, u32 context)
Dump the proxy configs to the API.
Definition: dhcp_proxy.c:248
void vl_api_want_dhcp6_reply_events_t_handler(vl_api_want_dhcp6_reply_events_t *mp)
Definition: dhcp_api.c:428
vl_api_dhcp_client_t client
Definition: dhcp.api:243
vl_api_dhcp_server_t servers[count]
Definition: dhcp.api:278
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
static void vl_api_dhcp_proxy_config_t_handler(vl_api_dhcp_proxy_config_t *mp)
Definition: dhcp_api.c:126
#define DHCP_PLUGIN_VERSION_MINOR
Definition: dhcp_api.c:47
static int send_dhcp_client_entry(const dhcp_client_t *client, void *arg)
Definition: dhcp_api.c:371
Send DHCPv6 client message of specified type.
Definition: dhcp.api:349
dhcp_event_cb_t event_callback
Definition: client.h:116
static void vl_api_dhcp_plugin_get_version_t_handler(vl_api_dhcp_plugin_get_version_t *mp)
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:66
unsigned int u32
Definition: types.h:88
void vl_api_dhcp6_send_client_message_t_handler(vl_api_dhcp6_send_client_message_t *mp)
Definition: dhcp_api.c:525
ip46_type_t ip_address_decode(const vl_api_address_t *in, ip46_address_t *out)
Definition: ip_types_api.c:161
ip_dscp_t ip_dscp_decode(u8 in)
Definition: ip_types_api.c:99
u8 set_broadcast_flag
Definition: client.h:106
u32 server_fib_index
The FIB index (not the external Table-ID) in which the server is reachable.
Definition: dhcp_proxy.h:95
vl_api_ip_dscp_t dscp
Definition: dhcp.api:163
#define hash_get(h, key)
Definition: hash.h:249
#define DHCP_PLUGIN_VERSION_MAJOR
Definition: dhcp_api.c:46
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
struct dhcp_client_send_walk_ctx_t_ dhcp_client_send_walk_ctx_t
long ctx[MAX_CONNS]
Definition: main.c:144
ip4_address_t leased_address
the address assigned to this client and it&#39;s mask
Definition: client.h:52
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
dhcp6_pd_client_public_main_t dhcp6_pd_client_public_main
vl_api_dhcpv6_msg_type_t msg_type
Definition: dhcp.api:360
#define REPLY_MACRO(t)
static void vl_api_dhcp_proxy_dump_t_handler(vl_api_dhcp_proxy_dump_t *mp)
Definition: dhcp_api.c:163
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
Control ping from client to api server request.
Definition: dhcp.api:80
static void dhcp_client_data_encode(vl_api_dhcp_client_t *vclient, const dhcp_client_t *client)
Definition: dhcp_api.c:290
vlib_main_t * vm
Definition: in2out_ed.c:1810
u8 client_hardware_address[6]
Definition: client.h:108
dhcpv6_duid_ll_string_t client_duid
static clib_error_t * call_dhcp6_pd_reply_event_callbacks(void *data, _vnet_dhcp6_pd_reply_event_function_list_elt_t *elt)
Definition: dhcp_api.c:725
u8 len
Definition: ip_types.api:91
dhcp6_ia_na_client_public_main_t dhcp6_ia_na_client_public_main
_vnet_dhcp6_pd_reply_event_function_list_elt_t * functions
static void vl_api_dhcp_plugin_control_ping_t_handler(vl_api_dhcp_plugin_control_ping_t *mp)
Definition: dhcp_api.c:73
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
#define BAD_SW_IF_INDEX_LABEL
vl_api_vss_type_t vss_type
Definition: dhcp.api:137
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
u8 * vpn_ascii_id
Type 0 ASCII VPN Identifier.
Definition: dhcp_proxy.h:77
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:92
dhcp6_send_client_message_params_address_t * addresses
ip4_address_t * domain_server_address
Definition: client.h:90
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
static void dhcp_compl_event_callback(u32 client_index, const dhcp_client_t *client)
Definition: dhcp_api.c:315
#define clib_warning(format, args...)
Definition: error.h:59
string vss_vpn_ascii_id[129]
Definition: dhcp.api:275
vl_api_registration_t * reg
Definition: dhcp_api.c:366
A representation of a single DHCP Server within a given VRF config.
Definition: dhcp_proxy.h:83
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
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:89
manual_print typedef address
Definition: ip_types.api:84
u8 data[128]
Definition: ipsec_types.api:87
enum ip_dscp_t_ ip_dscp_t
dhcp6_report_common_t body
VLIB_API_INIT_FUNCTION(dhcp_api_hookup)
static void clib_mem_free(void *p)
Definition: mem.h:226
static void vl_api_dhcp6_clients_enable_disable_t_handler(vl_api_dhcp6_clients_enable_disable_t *mp)
Definition: dhcp_api.c:416
#define REPLY_MSG_ID_BASE
Definition: dhcp_api.c:42
void dhcp_client_walk(dhcp_client_walk_cb_t cb, void *ctx)
Walk (visit each) DHCP client configuration.
Definition: client.c:1111
Tell client about a DHCPv6 PD server reply event.
Definition: dhcp.api:490
void ip6_address_encode(const ip6_address_t *in, vl_api_ip6_address_t out)
Definition: ip_types_api.c:111
void dhcp6_send_client_message(vlib_main_t *vm, u32 sw_if_index, u8 stop, dhcp6_send_client_message_params_t *params)
vl_api_dhcp_lease_t lease
Definition: dhcp.api:221
static void * clib_mem_alloc(uword size)
Definition: mem.h:153
vl_api_dhcp6_pd_prefix_info_t prefixes[n_prefixes]
Definition: dhcp.api:403
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
static uword dhcp6_pd_reply_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: dhcp_api.c:743
Tell client about a DHCP completion event.
Definition: dhcp.api:267
Register for DHCPv6 PD reply events.
Definition: dhcp.api:436
Tell client about a DHCPv6 server reply event.
Definition: dhcp.api:459
vl_api_address_t dhcp_src_address
Definition: dhcp.api:276
A DHCP proxy representation fpr per-client VRF config.
Definition: dhcp_proxy.h:101
Reply to get the plugin version.
Definition: dhcp.api:69
vl_api_interface_index_t sw_if_index
Definition: dhcp.api:353
u8 * client_identifier
Definition: client.h:99
static void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:463
#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:73
vl_api_address_t dhcp_server
Definition: dhcp.api:117
Get the plugin version.
Definition: dhcp.api:57
vl_api_interface_index_t sw_if_index
Definition: dhcp.api:392
u64 uword
Definition: types.h:112
dhcp6_address_info_t * addresses
vl_api_dhcp6_address_info_t addresses[n_addresses]
Definition: dhcp.api:364
vl_api_dhcp_client_t client
Definition: dhcp.api:178
#define VSS_TYPE_VPN_ID
Definition: dhcp_proxy.h:67
static void vl_api_dhcp_client_config_t_handler(vl_api_dhcp_client_config_t *mp)
Definition: dhcp_api.c:335
Register for DHCPv6 reply events.
Definition: dhcp.api:422
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:29
void vl_api_want_dhcp6_pd_reply_events_t_handler(vl_api_want_dhcp6_pd_reply_events_t *mp)
Definition: dhcp_api.c:476
static void vl_api_dhcp_proxy_set_vss_t_handler(vl_api_dhcp_proxy_set_vss_t *mp)
Definition: dhcp_api.c:107
void dhcp6_clients_enable_disable(u8 enable)
VLIB_PLUGIN_REGISTER()
Dump DHCP proxy table.
Definition: dhcp.api:251
u8 * hostname
Definition: client.h:98
Control ping from the client to the server response.
Definition: dhcp.api:92
u8 ip_dscp_encode(ip_dscp_t dscp)
Definition: ip_types_api.c:105
static void vlib_process_put_event_data(vlib_main_t *vm, void *event_data)
Definition: node_funcs.h:500
vlib_node_registration_t dhcp6_reply_process_node
(constructor) VLIB_REGISTER_NODE (dhcp6_reply_process_node)
Definition: dhcp_api.c:717
static void setup_message_id_table(snat_main_t *sm, api_main_t *am)
Definition: nat_api.c:3410
string vpn_ascii_id[129]
Definition: dhcp.api:138
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:259
vl_api_vss_type_t vss_type
Definition: dhcp.api:273
dhcp6_report_common_t body
vpe_api_main_t vpe_api_main
Definition: interface_api.c:54
Tell client about a DHCP completion event.
Definition: dhcp.api:217
dhcp6_prefix_info_t * prefixes
DHCP Client config add / del request.
Definition: dhcp.api:173
DHCP Proxy config add / del request.
Definition: dhcp.api:110
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:71
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, ip_dscp_t dscp, u32 pid)
Add/Delete DHCP clients.
Definition: client.c:1026
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128