aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet
diff options
context:
space:
mode:
authorNeale Ranns <nranns@cisco.com>2019-10-07 00:39:28 -0700
committerDave Barach <openvpp@barachs.net>2019-10-07 19:33:39 +0000
commit02bfd641b69aab83397e217b9ca4e35a6aab05c8 (patch)
tree665e232425f90d0662bc3d29729e11bb5e8727fc /src/vnet
parent2c41a61d5fc87737b9b46b88cb9271d0f987721e (diff)
dhcp: Move to plugin
Type: feature Change-Id: I3fe27a8ef577741d9a5c4f090ec91cf68fb44fe3 Signed-off-by: Neale Ranns <nranns@cisco.com>
Diffstat (limited to 'src/vnet')
-rw-r--r--src/vnet/CMakeLists.txt48
-rw-r--r--src/vnet/dhcp/client.c1255
-rw-r--r--src/vnet/dhcp/client.h179
-rw-r--r--src/vnet/dhcp/dhcp.api462
-rw-r--r--src/vnet/dhcp/dhcp4_packet.h80
-rw-r--r--src/vnet/dhcp/dhcp4_proxy_error.def32
-rw-r--r--src/vnet/dhcp/dhcp4_proxy_node.c1090
-rw-r--r--src/vnet/dhcp/dhcp6_client_common_dp.c493
-rw-r--r--src/vnet/dhcp/dhcp6_client_common_dp.h118
-rw-r--r--src/vnet/dhcp/dhcp6_ia_na_client_cp.api38
-rw-r--r--src/vnet/dhcp/dhcp6_ia_na_client_cp.c837
-rw-r--r--src/vnet/dhcp/dhcp6_ia_na_client_dp.c658
-rw-r--r--src/vnet/dhcp/dhcp6_ia_na_client_dp.h176
-rw-r--r--src/vnet/dhcp/dhcp6_packet.h271
-rw-r--r--src/vnet/dhcp/dhcp6_pd_client_cp.api61
-rw-r--r--src/vnet/dhcp/dhcp6_pd_client_cp.c1414
-rw-r--r--src/vnet/dhcp/dhcp6_pd_client_dp.c665
-rw-r--r--src/vnet/dhcp/dhcp6_pd_client_dp.h179
-rw-r--r--src/vnet/dhcp/dhcp6_pd_doc.md86
-rw-r--r--src/vnet/dhcp/dhcp6_proxy_error.def29
-rw-r--r--src/vnet/dhcp/dhcp6_proxy_node.c1186
-rw-r--r--src/vnet/dhcp/dhcp_api.c420
-rw-r--r--src/vnet/dhcp/dhcp_client_detect.c324
-rw-r--r--src/vnet/dhcp/dhcp_proxy.c375
-rw-r--r--src/vnet/dhcp/dhcp_proxy.h306
-rw-r--r--src/vnet/vnet_all_api_h.h3
26 files changed, 0 insertions, 10785 deletions
diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt
index 6ce383350bf..b107365a105 100644
--- a/src/vnet/CMakeLists.txt
+++ b/src/vnet/CMakeLists.txt
@@ -891,54 +891,6 @@ list(APPEND VNET_HEADERS
list(APPEND VNET_API_FILES lisp-gpe/lisp_gpe.api)
##############################################################################
-# DHCP client
-##############################################################################
-list(APPEND VNET_SOURCES
- dhcp/client.c
- dhcp/dhcp_client_detect.c
- dhcp/dhcp6_client_common_dp.c
- dhcp/dhcp6_pd_client_dp.c
- dhcp/dhcp6_pd_client_cp.c
- dhcp/dhcp6_ia_na_client_dp.c
- dhcp/dhcp6_ia_na_client_cp.c
- dhcp/dhcp_api.c
-)
-
-list(APPEND VNET_MULTIARCH_SOURCES
- dhcp/dhcp_client_detect.c
-)
-
-list(APPEND VNET_HEADERS
- dhcp/client.h
- dhcp/dhcp6_client_common_dp.h
- dhcp/dhcp6_pd_client_dp.h
- dhcp/dhcp6_ia_na_client_dp.h
-)
-
-list(APPEND VNET_API_FILES
- dhcp/dhcp.api
- dhcp/dhcp6_pd_client_cp.api
- dhcp/dhcp6_ia_na_client_cp.api
-)
-
-##############################################################################
-# DHCP proxy
-##############################################################################
-list(APPEND VNET_SOURCES
- dhcp/dhcp6_proxy_node.c
- dhcp/dhcp4_proxy_node.c
- dhcp/dhcp_proxy.c
-)
-
-list(APPEND VNET_HEADERS
- dhcp/dhcp4_packet.h
- dhcp/dhcp6_packet.h
- dhcp/dhcp_proxy.h
- dhcp/dhcp6_proxy_error.def
- dhcp/dhcp4_proxy_error.def
-)
-
-##############################################################################
# ipv6 segment routing
##############################################################################
diff --git a/src/vnet/dhcp/client.c b/src/vnet/dhcp/client.c
deleted file mode 100644
index aaeda96327d..00000000000
--- a/src/vnet/dhcp/client.c
+++ /dev/null
@@ -1,1255 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vlib/vlib.h>
-#include <vlibmemory/api.h>
-#include <vnet/dhcp/client.h>
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/fib/fib_table.h>
-#include <vnet/qos/qos_types.h>
-
-dhcp_client_main_t dhcp_client_main;
-static u8 *format_dhcp_client_state (u8 * s, va_list * va);
-static vlib_node_registration_t dhcp_client_process_node;
-
-#define foreach_dhcp_sent_packet_stat \
-_(DISCOVER, "DHCP discover packets sent") \
-_(OFFER, "DHCP offer packets sent") \
-_(REQUEST, "DHCP request packets sent") \
-_(ACK, "DHCP ack packets sent")
-
-#define foreach_dhcp_error_counter \
-_(NOT_FOR_US, "DHCP packets for other hosts, dropped") \
-_(NAK, "DHCP nak packets received") \
-_(NON_OFFER_DISCOVER, "DHCP non-offer packets in discover state") \
-_(ODDBALL, "DHCP non-ack, non-offer packets received") \
-_(BOUND, "DHCP bind success")
-
-typedef enum
-{
-#define _(sym,str) DHCP_STAT_##sym,
- foreach_dhcp_sent_packet_stat foreach_dhcp_error_counter
-#undef _
- DHCP_STAT_UNKNOWN,
- DHCP_STAT_N_STAT,
-} sample_error_t;
-
-static char *dhcp_client_process_stat_strings[] = {
-#define _(sym,string) string,
- foreach_dhcp_sent_packet_stat foreach_dhcp_error_counter
-#undef _
- "DHCP unknown packets sent",
-};
-
-static void
-dhcp_client_acquire_address (dhcp_client_main_t * dcm, dhcp_client_t * c)
-{
- /*
- * Install any/all info gleaned from dhcp, right here
- */
- ip4_add_del_interface_address (dcm->vlib_main, c->sw_if_index,
- (void *) &c->leased_address,
- c->subnet_mask_width, 0 /*is_del */ );
-}
-
-static void
-dhcp_client_release_address (dhcp_client_main_t * dcm, dhcp_client_t * c)
-{
- /*
- * Remove any/all info gleaned from dhcp, right here. Caller(s)
- * have not wiped out the info yet.
- */
-
- ip4_add_del_interface_address (dcm->vlib_main, c->sw_if_index,
- (void *) &c->leased_address,
- c->subnet_mask_width, 1 /*is_del */ );
-}
-
-static void
-dhcp_client_proc_callback (uword * client_index)
-{
- vlib_main_t *vm = vlib_get_main ();
- ASSERT (vlib_get_thread_index () == 0);
- vlib_process_signal_event (vm, dhcp_client_process_node.index,
- EVENT_DHCP_CLIENT_WAKEUP, *client_index);
-}
-
-static void
-dhcp_client_addr_callback (dhcp_client_t * c)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
-
- /* disable the feature */
- vnet_feature_enable_disable ("ip4-unicast",
- "ip4-dhcp-client-detect",
- c->sw_if_index, 0 /* disable */ , 0, 0);
- c->client_detect_feature_enabled = 0;
-
- /* if renewing the lease, the address and route have already been added */
- if (c->state == DHCP_BOUND)
- return;
-
- /* add the address to the interface */
- dhcp_client_acquire_address (dcm, c);
-
- /*
- * Configure default IP route:
- */
- if (c->router_address.as_u32)
- {
- fib_prefix_t all_0s = {
- .fp_len = 0,
- .fp_addr.ip4.as_u32 = 0x0,
- .fp_proto = FIB_PROTOCOL_IP4,
- };
- ip46_address_t nh = {
- .ip4 = c->router_address,
- };
-
- /* *INDENT-OFF* */
- fib_table_entry_path_add (
- fib_table_get_index_for_sw_if_index (
- FIB_PROTOCOL_IP4,
- c->sw_if_index),
- &all_0s,
- FIB_SOURCE_DHCP,
- FIB_ENTRY_FLAG_NONE,
- DPO_PROTO_IP4,
- &nh, c->sw_if_index,
- ~0, 1, NULL, // no label stack
- FIB_ROUTE_PATH_FLAG_NONE);
- /* *INDENT-ON* */
- }
- if (c->dhcp_server.as_u32)
- {
- ip46_address_t dst = {
- .ip4 = c->dhcp_server,
- };
- c->ai_ucast = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
- VNET_LINK_IP4, &dst, c->sw_if_index);
- }
-
- /*
- * Call the user's event callback to report DHCP information
- */
- if (c->event_callback)
- c->event_callback (c->client_index, c);
-}
-
-/*
- * dhcp_client_for_us - server-to-client callback.
- * Called from proxy_node.c:dhcp_proxy_to_client_input().
- * This function first decides that the packet in question is
- * actually for the dhcp client code in case we're also acting as
- * a dhcp proxy. Ay caramba, what a folly!
- */
-int
-dhcp_client_for_us (u32 bi, vlib_buffer_t * b,
- ip4_header_t * ip,
- udp_header_t * udp, dhcp_header_t * dhcp)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
- vlib_main_t *vm = dcm->vlib_main;
- dhcp_client_t *c;
- uword *p;
- f64 now = vlib_time_now (dcm->vlib_main);
- u8 dhcp_message_type = 0;
- dhcp_option_t *o;
-
- /*
- * Doing dhcp client on this interface?
- * Presumably we will always receive dhcp clnt for-us pkts on
- * the interface that's asking for an address.
- */
- p = hash_get (dcm->client_by_sw_if_index,
- vnet_buffer (b)->sw_if_index[VLIB_RX]);
- if (p == 0)
- return 0; /* no */
-
- c = pool_elt_at_index (dcm->clients, p[0]);
-
- /* Mixing dhcp relay and dhcp proxy? DGMS... */
- if (c->state == DHCP_BOUND && c->retry_count == 0)
- return 0;
-
- /* Packet not for us? Turf it... */
- if (memcmp (dhcp->client_hardware_address, c->client_hardware_address,
- sizeof (c->client_hardware_address)))
- {
- vlib_node_increment_counter (vm, dhcp_client_process_node.index,
- DHCP_STAT_NOT_FOR_US, 1);
- return 0;
- }
-
- /* parse through the packet, learn what we can */
- if (dhcp->your_ip_address.as_u32)
- c->leased_address.as_u32 = dhcp->your_ip_address.as_u32;
-
- c->dhcp_server.as_u32 = dhcp->server_ip_address.as_u32;
-
- o = (dhcp_option_t *) dhcp->options;
-
- while (o->option != 0xFF /* end of options */ &&
- (u8 *) o < (b->data + b->current_data + b->current_length))
- {
- switch (o->option)
- {
- case 53: /* dhcp message type */
- dhcp_message_type = o->data[0];
- break;
-
- case 51: /* lease time */
- {
- u32 lease_time_in_seconds =
- clib_host_to_net_u32 (o->data_as_u32[0]);
- // for debug: lease_time_in_seconds = 20; /*$$$$*/
- c->lease_expires = now + (f64) lease_time_in_seconds;
- c->lease_lifetime = lease_time_in_seconds;
- /* Set a sensible default, in case we don't get opt 58 */
- c->lease_renewal_interval = lease_time_in_seconds / 2;
- }
- break;
-
- case 58: /* lease renew time in seconds */
- {
- u32 lease_renew_time_in_seconds =
- clib_host_to_net_u32 (o->data_as_u32[0]);
- c->lease_renewal_interval = lease_renew_time_in_seconds;
- }
- break;
-
- case 54: /* dhcp server address */
- c->dhcp_server.as_u32 = o->data_as_u32[0];
- break;
-
- case 1: /* subnet mask */
- {
- u32 subnet_mask = clib_host_to_net_u32 (o->data_as_u32[0]);
- c->subnet_mask_width = count_set_bits (subnet_mask);
- }
- break;
- case 3: /* router address */
- {
- u32 router_address = o->data_as_u32[0];
- c->router_address.as_u32 = router_address;
- }
- break;
- case 6: /* domain server address */
- {
- vec_free (c->domain_server_address);
- vec_validate (c->domain_server_address,
- o->length / sizeof (ip4_address_t) - 1);
- clib_memcpy (c->domain_server_address, o->data, o->length);
- }
- break;
- case 12: /* hostname */
- {
- /* Replace the existing hostname if necessary */
- vec_free (c->hostname);
- vec_validate (c->hostname, o->length - 1);
- clib_memcpy (c->hostname, o->data, o->length);
- }
- break;
-
- /* $$$$ Your message in this space, parse more options */
- default:
- break;
- }
-
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
-
- switch (c->state)
- {
- case DHCP_DISCOVER:
- if (dhcp_message_type != DHCP_PACKET_OFFER)
- {
- vlib_node_increment_counter (vm, dhcp_client_process_node.index,
- DHCP_STAT_NON_OFFER_DISCOVER, 1);
- c->next_transmit = now + 5.0;
- break;
- }
-
- /* Received an offer, go send a request */
- c->state = DHCP_REQUEST;
- c->retry_count = 0;
- c->next_transmit = 0; /* send right now... */
- /* Poke the client process, which will send the request */
- uword client_id = c - dcm->clients;
- vl_api_rpc_call_main_thread (dhcp_client_proc_callback,
- (u8 *) & client_id, sizeof (uword));
- break;
-
- case DHCP_BOUND:
- case DHCP_REQUEST:
- if (dhcp_message_type == DHCP_PACKET_NAK)
- {
- vlib_node_increment_counter (vm, dhcp_client_process_node.index,
- DHCP_STAT_NAK, 1);
- /* Probably never happens in bound state, but anyhow... */
- if (c->state == DHCP_BOUND)
- {
- ip4_add_del_interface_address (dcm->vlib_main, c->sw_if_index,
- (void *) &c->leased_address,
- c->subnet_mask_width,
- 1 /*is_del */ );
- vnet_feature_enable_disable ("ip4-unicast",
- "ip4-dhcp-client-detect",
- c->sw_if_index, 1 /* enable */ ,
- 0, 0);
- c->client_detect_feature_enabled = 1;
- }
- /* Wipe out any memory of the address we had... */
- c->state = DHCP_DISCOVER;
- c->next_transmit = now;
- c->retry_count = 0;
- c->leased_address.as_u32 = 0;
- c->subnet_mask_width = 0;
- c->router_address.as_u32 = 0;
- c->lease_renewal_interval = 0;
- c->dhcp_server.as_u32 = 0;
- vec_free (c->domain_server_address);
- break;
- }
-
- if (dhcp_message_type != DHCP_PACKET_ACK &&
- dhcp_message_type != DHCP_PACKET_OFFER)
- {
- vlib_node_increment_counter (vm, dhcp_client_process_node.index,
- DHCP_STAT_NON_OFFER_DISCOVER, 1);
- clib_warning ("sw_if_index %d state %U message type %d",
- c->sw_if_index, format_dhcp_client_state,
- c->state, dhcp_message_type);
- c->next_transmit = now + 5.0;
- break;
- }
- /* OK, we own the address (etc), add to the routing table(s) */
- vl_api_rpc_call_main_thread (dhcp_client_addr_callback,
- (u8 *) c, sizeof (*c));
-
- c->state = DHCP_BOUND;
- c->retry_count = 0;
- c->next_transmit = now + (f64) c->lease_renewal_interval;
- c->lease_expires = now + (f64) c->lease_lifetime;
- vlib_node_increment_counter (vm, dhcp_client_process_node.index,
- DHCP_STAT_BOUND, 1);
- break;
-
- default:
- clib_warning ("client %d bogus state %d", c - dcm->clients, c->state);
- break;
- }
-
- /* drop the pkt, return 1 */
- vlib_buffer_free (vm, &bi, 1);
- return 1;
-}
-
-static void
-send_dhcp_pkt (dhcp_client_main_t * dcm, dhcp_client_t * c,
- dhcp_packet_type_t type, int is_broadcast)
-{
- vlib_main_t *vm = dcm->vlib_main;
- vnet_main_t *vnm = dcm->vnet_main;
- vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, c->sw_if_index);
- vnet_sw_interface_t *sup_sw
- = vnet_get_sup_sw_interface (vnm, c->sw_if_index);
- vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, c->sw_if_index);
- vlib_buffer_t *b;
- u32 bi;
- ip4_header_t *ip;
- udp_header_t *udp;
- dhcp_header_t *dhcp;
- u32 *to_next;
- vlib_frame_t *f;
- dhcp_option_t *o;
- u16 udp_length, ip_length;
- u32 counter_index, node_index;
-
- /* Interface(s) down? */
- if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
- return;
- if ((sup_sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
- return;
- if ((sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
- return;
-
- if (vlib_buffer_alloc (vm, &bi, 1) != 1)
- {
- clib_warning ("buffer allocation failure");
- c->next_transmit = 0;
- return;
- }
-
- /* Build a dhcpv4 pkt from whole cloth */
- b = vlib_get_buffer (vm, bi);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
-
- ASSERT (b->current_data == 0);
-
- vnet_buffer (b)->sw_if_index[VLIB_RX] = c->sw_if_index;
-
- if (is_broadcast)
- {
- node_index = ip4_rewrite_node.index;
- vnet_buffer (b)->ip.adj_index[VLIB_TX] = c->ai_bcast;
- }
- else
- {
- ip_adjacency_t *adj = adj_get (c->ai_ucast);
-
- if (IP_LOOKUP_NEXT_ARP == adj->lookup_next_index)
- node_index = ip4_arp_node.index;
- else
- node_index = ip4_rewrite_node.index;
- vnet_buffer (b)->ip.adj_index[VLIB_TX] = c->ai_ucast;
- }
-
- /* Enqueue the packet right now */
- f = vlib_get_frame_to_node (vm, node_index);
- to_next = vlib_frame_vector_args (f);
- to_next[0] = bi;
- f->n_vectors = 1;
- vlib_put_frame_to_node (vm, node_index, f);
-
- /* build the headers */
- ip = vlib_buffer_get_current (b);
- udp = (udp_header_t *) (ip + 1);
- dhcp = (dhcp_header_t *) (udp + 1);
-
- /* $$$ optimize, maybe */
- clib_memset (ip, 0, sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp));
-
- ip->ip_version_and_header_length = 0x45;
- ip->ttl = 128;
- ip->protocol = IP_PROTOCOL_UDP;
-
- ip->tos = c->dscp;
-
- if (ip->tos)
- {
- /*
- * Setup the buffer's QoS settings so any QoS marker on the egress
- * interface, that might set VLAN CoS bits, based on this DSCP setting
- */
- vnet_buffer2 (b)->qos.source = QOS_SOURCE_IP;
- vnet_buffer2 (b)->qos.bits = ip->tos;
- b->flags |= VNET_BUFFER_F_QOS_DATA_VALID;
- }
-
- if (is_broadcast)
- {
- /* src = 0.0.0.0, dst = 255.255.255.255 */
- ip->dst_address.as_u32 = ~0;
- }
- else
- {
- /* Renewing an active lease, plain old ip4 src/dst */
- ip->src_address.as_u32 = c->leased_address.as_u32;
- ip->dst_address.as_u32 = c->dhcp_server.as_u32;
- }
-
- udp->src_port = clib_host_to_net_u16 (UDP_DST_PORT_dhcp_to_client);
- udp->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_dhcp_to_server);
-
- /* Send the interface MAC address */
- clib_memcpy (dhcp->client_hardware_address,
- vnet_sw_interface_get_hw_address (vnm, c->sw_if_index), 6);
-
- /* And remember it for rx-packet-for-us checking */
- clib_memcpy (c->client_hardware_address, dhcp->client_hardware_address,
- sizeof (c->client_hardware_address));
-
- /* Lease renewal, set up client_ip_address */
- if (is_broadcast == 0)
- dhcp->client_ip_address.as_u32 = c->leased_address.as_u32;
-
- dhcp->opcode = 1; /* request, all we send */
- dhcp->hardware_type = 1; /* ethernet */
- dhcp->hardware_address_length = 6;
- dhcp->transaction_identifier = c->transaction_id;
- dhcp->flags =
- clib_host_to_net_u16 (is_broadcast && c->set_broadcast_flag ?
- DHCP_FLAG_BROADCAST : 0);
- dhcp->magic_cookie.as_u32 = DHCP_MAGIC;
-
- o = (dhcp_option_t *) dhcp->options;
-
- /* Send option 53, the DHCP message type */
- o->option = DHCP_PACKET_OPTION_MSG_TYPE;
- o->length = 1;
- o->data[0] = type;
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
-
- /* Send option 57, max msg length */
- if (0 /* not needed, apparently */ )
- {
- o->option = 57;
- o->length = 2;
- {
- u16 *o2 = (u16 *) o->data;
- *o2 = clib_host_to_net_u16 (1152);
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
- }
-
- /*
- * If server ip address is available with non-zero value,
- * option 54 (DHCP Server Identifier) is sent.
- */
- if (c->dhcp_server.as_u32)
- {
- o->option = 54;
- o->length = 4;
- clib_memcpy (o->data, &c->dhcp_server.as_u32, 4);
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
-
- /* send option 50, requested IP address */
- if (c->leased_address.as_u32)
- {
- o->option = 50;
- o->length = 4;
- clib_memcpy (o->data, &c->leased_address.as_u32, 4);
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
-
- /* send option 12, host name */
- if (vec_len (c->hostname))
- {
- o->option = 12;
- o->length = vec_len (c->hostname);
- clib_memcpy (o->data, c->hostname, vec_len (c->hostname));
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
-
- /* send option 61, client_id */
- if (vec_len (c->client_identifier))
- {
- o->option = 61;
- o->length = vec_len (c->client_identifier);
- clib_memcpy (o->data, c->client_identifier,
- vec_len (c->client_identifier));
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
-
- /* $$ maybe send the client s/w version if anyone cares */
-
- /*
- * send option 55, parameter request list
- * The current list - see below, matches the Linux dhcp client's list
- * Any specific dhcp server config and/or dhcp server may or may
- * not yield specific options.
- */
- o->option = 55;
- o->length = vec_len (c->option_55_data);
- clib_memcpy (o->data, c->option_55_data, vec_len (c->option_55_data));
- o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
-
- /* End of list */
- o->option = 0xff;
- o->length = 0;
- o++;
-
- b->current_length = ((u8 *) o) - b->data;
-
- /* fix ip length, checksum and udp length */
- ip_length = vlib_buffer_length_in_chain (vm, b);
-
- ip->length = clib_host_to_net_u16 (ip_length);
- ip->checksum = ip4_header_checksum (ip);
-
- udp_length = ip_length - (sizeof (*ip));
- udp->length = clib_host_to_net_u16 (udp_length);
-
- switch (type)
- {
-#define _(a,b) case DHCP_PACKET_##a: {counter_index = DHCP_STAT_##a; break;}
- foreach_dhcp_sent_packet_stat
-#undef _
- default:
- counter_index = DHCP_STAT_UNKNOWN;
- break;
- }
-
- vlib_node_increment_counter (vm, dhcp_client_process_node.index,
- counter_index, 1);
-}
-
-static int
-dhcp_discover_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
-{
- /*
- * State machine "DISCOVER" state. Send a dhcp discover packet,
- * eventually back off the retry rate.
- */
-
- if (c->client_detect_feature_enabled == 0)
- {
- vnet_feature_enable_disable ("ip4-unicast",
- "ip4-dhcp-client-detect",
- c->sw_if_index, 1 /* enable */ , 0, 0);
- c->client_detect_feature_enabled = 1;
- }
-
- send_dhcp_pkt (dcm, c, DHCP_PACKET_DISCOVER, 1 /* is_broadcast */ );
-
- c->retry_count++;
- if (c->retry_count > 10)
- c->next_transmit = now + 5.0;
- else
- c->next_transmit = now + 1.0;
- return 0;
-}
-
-static int
-dhcp_request_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
-{
- /*
- * State machine "REQUEST" state. Send a dhcp request packet,
- * eventually drop back to the discover state.
- */
- send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 1 /* is_broadcast */ );
-
- c->retry_count++;
- if (c->retry_count > 7 /* lucky you */ )
- {
- c->state = DHCP_DISCOVER;
- c->next_transmit = now;
- c->retry_count = 0;
- return 1;
- }
- c->next_transmit = now + 1.0;
- return 0;
-}
-
-static int
-dhcp_bound_state (dhcp_client_main_t * dcm, dhcp_client_t * c, f64 now)
-{
- /*
- * State machine "BOUND" state. Send a dhcp request packet to renew
- * the lease.
- * Eventually, when the lease expires, forget the dhcp data
- * and go back to the stone age.
- */
-
- /*
- * We disable the client detect feature when we bind a
- * DHCP address. Turn it back on again on first renew attempt.
- * Otherwise, if the DHCP server replies we'll never see it.
- */
- if (c->client_detect_feature_enabled == 0)
- {
- vnet_feature_enable_disable ("ip4-unicast",
- "ip4-dhcp-client-detect",
- c->sw_if_index, 1 /* enable */ , 0, 0);
- c->client_detect_feature_enabled = 1;
- }
-
- send_dhcp_pkt (dcm, c, DHCP_PACKET_REQUEST, 0 /* is_broadcast */ );
-
- c->retry_count++;
- if (c->retry_count > 10)
- c->next_transmit = now + 5.0;
- else
- c->next_transmit = now + 1.0;
-
- if (now > c->lease_expires)
- {
- /* Remove the default route */
- if (c->router_address.as_u32)
- {
- fib_prefix_t all_0s = {
- .fp_len = 0,
- .fp_addr.ip4.as_u32 = 0x0,
- .fp_proto = FIB_PROTOCOL_IP4,
- };
- ip46_address_t nh = {
- .ip4 = c->router_address,
- };
-
- fib_table_entry_path_remove (fib_table_get_index_for_sw_if_index
- (FIB_PROTOCOL_IP4, c->sw_if_index),
- &all_0s, FIB_SOURCE_DHCP,
- DPO_PROTO_IP4, &nh, c->sw_if_index, ~0,
- 1, FIB_ROUTE_PATH_FLAG_NONE);
- }
- /* Remove the interface address */
- dhcp_client_release_address (dcm, c);
- c->state = DHCP_DISCOVER;
- c->next_transmit = now;
- c->retry_count = 0;
- /* Wipe out any memory of the address we had... */
- c->leased_address.as_u32 = 0;
- c->subnet_mask_width = 0;
- c->router_address.as_u32 = 0;
- c->lease_renewal_interval = 0;
- c->dhcp_server.as_u32 = 0;
- return 1;
- }
- return 0;
-}
-
-static f64
-dhcp_client_sm (f64 now, f64 timeout, uword pool_index)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
- dhcp_client_t *c;
-
- /* deleted, pooched, yadda yadda yadda */
- if (pool_is_free_index (dcm->clients, pool_index))
- return timeout;
-
- c = pool_elt_at_index (dcm->clients, pool_index);
-
- /* Time for us to do something with this client? */
- if (now < c->next_transmit)
- return timeout;
-
-again:
- switch (c->state)
- {
- case DHCP_DISCOVER: /* send a discover */
- if (dhcp_discover_state (dcm, c, now))
- goto again;
- break;
-
- case DHCP_REQUEST: /* send a request */
- if (dhcp_request_state (dcm, c, now))
- goto again;
- break;
-
- case DHCP_BOUND: /* bound, renew needed? */
- if (dhcp_bound_state (dcm, c, now))
- goto again;
- break;
-
- default:
- clib_warning ("dhcp client %d bogus state %d",
- c - dcm->clients, c->state);
- break;
- }
-
- if (c->next_transmit < now + timeout)
- return c->next_transmit - now;
-
- return timeout;
-}
-
-static uword
-dhcp_client_process (vlib_main_t * vm,
- vlib_node_runtime_t * rt, vlib_frame_t * f)
-{
- f64 timeout = 100.0;
- f64 now;
- uword event_type;
- uword *event_data = 0;
- dhcp_client_main_t *dcm = &dhcp_client_main;
- dhcp_client_t *c;
- int i;
-
- while (1)
- {
- vlib_process_wait_for_event_or_clock (vm, timeout);
-
- event_type = vlib_process_get_events (vm, &event_data);
-
- now = vlib_time_now (vm);
-
- switch (event_type)
- {
- case EVENT_DHCP_CLIENT_WAKEUP:
- for (i = 0; i < vec_len (event_data); i++)
- timeout = dhcp_client_sm (now, timeout, event_data[i]);
- break;
-
- case ~0:
- /* *INDENT-OFF* */
- pool_foreach (c, dcm->clients,
- ({
- timeout = dhcp_client_sm (now, timeout,
- (uword) (c - dcm->clients));
- }));
- /* *INDENT-ON* */
- if (pool_elts (dcm->clients) == 0)
- timeout = 100.0;
- break;
- }
-
- vec_reset_length (event_data);
- }
-
- /* NOTREACHED */
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp_client_process_node,static) = {
- .function = dhcp_client_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dhcp-client-process",
- .process_log2_n_stack_bytes = 16,
- .n_errors = ARRAY_LEN(dhcp_client_process_stat_strings),
- .error_strings = dhcp_client_process_stat_strings,
-};
-/* *INDENT-ON* */
-
-static u8 *
-format_dhcp_client_state (u8 * s, va_list * va)
-{
- dhcp_client_state_t state = va_arg (*va, dhcp_client_state_t);
- char *str = "BOGUS!";
-
- switch (state)
- {
-#define _(a) \
- case a: \
- str = #a; \
- break;
- foreach_dhcp_client_state;
-#undef _
- default:
- break;
- }
-
- s = format (s, "%s", str);
- return s;
-}
-
-static u8 *
-format_dhcp_client (u8 * s, va_list * va)
-{
- dhcp_client_main_t *dcm = va_arg (*va, dhcp_client_main_t *);
- dhcp_client_t *c = va_arg (*va, dhcp_client_t *);
- int verbose = va_arg (*va, int);
- ip4_address_t *addr;
-
- s = format (s, "[%d] %U state %U ", c - dcm->clients,
- format_vnet_sw_if_index_name, dcm->vnet_main, c->sw_if_index,
- format_dhcp_client_state, c->state);
-
- if (0 != c->dscp)
- s = format (s, "dscp %d ", c->dscp);
-
- if (c->leased_address.as_u32)
- {
- s = format (s, "addr %U/%d gw %U",
- format_ip4_address, &c->leased_address,
- c->subnet_mask_width, format_ip4_address,
- &c->router_address);
-
- vec_foreach (addr, c->domain_server_address)
- s = format (s, " dns %U", format_ip4_address, addr);
- }
- else
- {
- s = format (s, "no address\n");
- }
-
- if (verbose)
- {
- s =
- format (s,
- "\n lease: lifetime:%d renewal-interval:%d expires:%.2f (now:%.2f)",
- c->lease_lifetime, c->lease_renewal_interval,
- c->lease_expires, vlib_time_now (dcm->vlib_main));
- s =
- format (s, "\n retry-count:%d, next-xmt:%.2f", c->retry_count,
- c->next_transmit);
- s =
- format (s, "\n adjacencies:[unicast:%d broadcast:%d]", c->ai_ucast,
- c->ai_bcast);
- }
- return s;
-}
-
-static clib_error_t *
-show_dhcp_client_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
- dhcp_client_t *c;
- int verbose = 0;
- u32 sw_if_index = ~0;
- uword *p;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "intfc %U",
- unformat_vnet_sw_interface, dcm->vnet_main, &sw_if_index))
- ;
- else if (unformat (input, "verbose"))
- verbose = 1;
- else
- break;
- }
-
- if (sw_if_index != ~0)
- {
- p = hash_get (dcm->client_by_sw_if_index, sw_if_index);
- if (p == 0)
- return clib_error_return (0, "dhcp client not configured");
- c = pool_elt_at_index (dcm->clients, p[0]);
- vlib_cli_output (vm, "%U", format_dhcp_client, dcm, c, verbose);
- return 0;
- }
-
- /* *INDENT-OFF* */
- pool_foreach (c, dcm->clients,
- ({
- vlib_cli_output (vm, "%U",
- format_dhcp_client, dcm,
- c, verbose);
- }));
- /* *INDENT-ON* */
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (show_dhcp_client_command, static) = {
- .path = "show dhcp client",
- .short_help = "show dhcp client [intfc <intfc>][verbose]",
- .function = show_dhcp_client_command_fn,
-};
-/* *INDENT-ON* */
-
-
-int
-dhcp_client_add_del (dhcp_client_add_del_args_t * a)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
- vlib_main_t *vm = dcm->vlib_main;
- dhcp_client_t *c;
- uword *p;
- fib_prefix_t all_0s = {
- .fp_len = 0,
- .fp_addr.ip4.as_u32 = 0x0,
- .fp_proto = FIB_PROTOCOL_IP4,
- };
-
- p = hash_get (dcm->client_by_sw_if_index, a->sw_if_index);
-
- if ((p && a->is_add) || (!p && a->is_add == 0))
- return VNET_API_ERROR_INVALID_VALUE;
-
- if (a->is_add)
- {
- dhcp_maybe_register_udp_ports (DHCP_PORT_REG_CLIENT);
- pool_get (dcm->clients, c);
- clib_memset (c, 0, sizeof (*c));
- c->state = DHCP_DISCOVER;
- c->sw_if_index = a->sw_if_index;
- c->client_index = a->client_index;
- c->pid = a->pid;
- c->event_callback = a->event_callback;
- c->option_55_data = a->option_55_data;
- c->hostname = a->hostname;
- c->client_identifier = a->client_identifier;
- c->set_broadcast_flag = a->set_broadcast_flag;
- c->dscp = a->dscp;
- c->ai_ucast = ADJ_INDEX_INVALID;
- c->ai_bcast = adj_nbr_add_or_lock (FIB_PROTOCOL_IP4,
- VNET_LINK_IP4,
- &ADJ_BCAST_ADDR, c->sw_if_index);
-
- do
- {
- c->transaction_id = random_u32 (&dcm->seed);
- }
- while (c->transaction_id == 0);
-
- hash_set (dcm->client_by_sw_if_index, a->sw_if_index, c - dcm->clients);
-
- /*
- * In order to accept any OFFER, whether broadcasted or unicasted, we
- * need to configure the dhcp-client-detect feature as an input feature
- * so the DHCP OFFER is sent to the ip4-local node. Without this a
- * broadcasted OFFER hits the 255.255.255.255/32 address and a unicast
- * hits 0.0.0.0/0 both of which default to drop and the latter may forward
- * of box - not what we want. Nor to we want to change these route for
- * all interfaces in this table
- */
- vnet_feature_enable_disable ("ip4-unicast",
- "ip4-dhcp-client-detect",
- c->sw_if_index, 1 /* enable */ , 0, 0);
- c->client_detect_feature_enabled = 1;
-
- vlib_process_signal_event (vm, dhcp_client_process_node.index,
- EVENT_DHCP_CLIENT_WAKEUP, c - dcm->clients);
- }
- else
- {
- c = pool_elt_at_index (dcm->clients, p[0]);
-
- if (c->router_address.as_u32)
- {
- ip46_address_t nh = {
- .ip4 = c->router_address,
- };
-
- fib_table_entry_path_remove (fib_table_get_index_for_sw_if_index
- (FIB_PROTOCOL_IP4, c->sw_if_index),
- &all_0s, FIB_SOURCE_DHCP,
- DPO_PROTO_IP4, &nh, c->sw_if_index, ~0,
- 1, FIB_ROUTE_PATH_FLAG_NONE);
- }
- dhcp_client_release_address (dcm, c);
-
- adj_unlock (c->ai_ucast);
- adj_unlock (c->ai_bcast);
-
- vec_free (c->domain_server_address);
- vec_free (c->option_55_data);
- vec_free (c->hostname);
- vec_free (c->client_identifier);
- hash_unset (dcm->client_by_sw_if_index, c->sw_if_index);
- pool_put (dcm->clients, c);
- }
- return 0;
-}
-
-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)
-{
- dhcp_client_add_del_args_t _a, *a = &_a;
- int rv;
-
- clib_memset (a, 0, sizeof (*a));
- a->is_add = is_add;
- a->sw_if_index = sw_if_index;
- a->client_index = client_index;
- a->pid = pid;
- a->event_callback = event_callback;
- a->set_broadcast_flag = set_broadcast_flag;
- a->dscp = dscp;
- vec_validate (a->hostname, strlen ((char *) hostname) - 1);
- strncpy ((char *) a->hostname, (char *) hostname, vec_len (a->hostname));
- vec_validate (a->client_identifier, strlen ((char *) client_id) - 1);
- strncpy ((char *) a->client_identifier, (char *) client_id,
- vec_len (a->client_identifier));
-
- /*
- * Option 55 request list. These data precisely match
- * the Ubuntu dhcp client. YMMV.
- */
-
- /* Subnet Mask */
- vec_add1 (a->option_55_data, 1);
- /* Broadcast address */
- vec_add1 (a->option_55_data, 28);
- /* time offset */
- vec_add1 (a->option_55_data, 2);
- /* Router */
- vec_add1 (a->option_55_data, 3);
- /* Domain Name */
- vec_add1 (a->option_55_data, 15);
- /* DNS */
- vec_add1 (a->option_55_data, 6);
- /* Domain search */
- vec_add1 (a->option_55_data, 119);
- /* Host name */
- vec_add1 (a->option_55_data, 12);
- /* NetBIOS name server */
- vec_add1 (a->option_55_data, 44);
- /* NetBIOS Scope */
- vec_add1 (a->option_55_data, 47);
- /* MTU */
- vec_add1 (a->option_55_data, 26);
- /* Classless static route */
- vec_add1 (a->option_55_data, 121);
- /* NTP servers */
- vec_add1 (a->option_55_data, 42);
-
- rv = dhcp_client_add_del (a);
-
- switch (rv)
- {
- case 0:
- break;
-
- case VNET_API_ERROR_INVALID_VALUE:
-
- vec_free (a->hostname);
- vec_free (a->client_identifier);
- vec_free (a->option_55_data);
-
- if (is_add)
- clib_warning ("dhcp client already enabled on intf_idx %d",
- sw_if_index);
- else
- clib_warning ("dhcp client not enabled on on intf_idx %d",
- sw_if_index);
- break;
-
- default:
- clib_warning ("dhcp_client_add_del returned %d", rv);
- }
-
- return rv;
-}
-
-void
-dhcp_client_walk (dhcp_client_walk_cb_t cb, void *ctx)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
- dhcp_client_t *c;
-
- /* *INDENT-OFF* */
- pool_foreach (c, dcm->clients,
- ({
- if (!cb(c, ctx))
- break;
- }));
- /* *INDENT-ON* */
-
-}
-
-static clib_error_t *
-dhcp_client_set_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
-
- dhcp_client_main_t *dcm = &dhcp_client_main;
- u32 sw_if_index;
- u8 *hostname = 0;
- u8 sw_if_index_set = 0;
- u8 set_broadcast_flag = 1;
- int is_add = 1;
- dhcp_client_add_del_args_t _a, *a = &_a;
- int rv;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "intfc %U",
- unformat_vnet_sw_interface, dcm->vnet_main, &sw_if_index))
- sw_if_index_set = 1;
- else if (unformat (input, "hostname %v", &hostname))
- ;
- else if (unformat (input, "del"))
- is_add = 0;
- else if (unformat (input, "broadcast", &set_broadcast_flag))
- is_add = 0;
- else
- break;
- }
-
- if (sw_if_index_set == 0)
- return clib_error_return (0, "interface not specified");
-
- clib_memset (a, 0, sizeof (*a));
- a->is_add = is_add;
- a->sw_if_index = sw_if_index;
- a->hostname = hostname;
- a->client_identifier = format (0, "vpe 1.0%c", 0);
- a->set_broadcast_flag = set_broadcast_flag;
-
- /*
- * Option 55 request list. These data precisely match
- * the Ubuntu dhcp client. YMMV.
- */
-
- /* Subnet Mask */
- vec_add1 (a->option_55_data, 1);
- /* Broadcast address */
- vec_add1 (a->option_55_data, 28);
- /* time offset */
- vec_add1 (a->option_55_data, 2);
- /* Router */
- vec_add1 (a->option_55_data, 3);
- /* Domain Name */
- vec_add1 (a->option_55_data, 15);
- /* DNS */
- vec_add1 (a->option_55_data, 6);
- /* Domain search */
- vec_add1 (a->option_55_data, 119);
- /* Host name */
- vec_add1 (a->option_55_data, 12);
- /* NetBIOS name server */
- vec_add1 (a->option_55_data, 44);
- /* NetBIOS Scope */
- vec_add1 (a->option_55_data, 47);
- /* MTU */
- vec_add1 (a->option_55_data, 26);
- /* Classless static route */
- vec_add1 (a->option_55_data, 121);
- /* NTP servers */
- vec_add1 (a->option_55_data, 42);
-
- rv = dhcp_client_add_del (a);
-
- switch (rv)
- {
- case 0:
- break;
-
- case VNET_API_ERROR_INVALID_VALUE:
-
- vec_free (a->hostname);
- vec_free (a->client_identifier);
- vec_free (a->option_55_data);
- if (is_add)
- return clib_error_return (0, "dhcp client already enabled on %U",
- format_vnet_sw_if_index_name,
- dcm->vnet_main, sw_if_index);
- else
- return clib_error_return (0, "dhcp client not enabled on %U",
- format_vnet_sw_if_index_name,
- dcm->vnet_main, sw_if_index);
- break;
-
- default:
- vlib_cli_output (vm, "dhcp_client_add_del returned %d", rv);
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp_client_set_command, static) = {
- .path = "set dhcp client",
- .short_help = "set dhcp client [del] intfc <interface> [hostname <name>]",
- .function = dhcp_client_set_command_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcp_client_init (vlib_main_t * vm)
-{
- dhcp_client_main_t *dcm = &dhcp_client_main;
-
- dcm->vlib_main = vm;
- dcm->vnet_main = vnet_get_main ();
- dcm->seed = (u32) clib_cpu_time_now ();
- return 0;
-}
-
-VLIB_INIT_FUNCTION (dhcp_client_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/client.h b/src/vnet/dhcp/client.h
deleted file mode 100644
index 5191fcf0fa8..00000000000
--- a/src/vnet/dhcp/client.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2015 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/*
- * client.h: dhcp client
- */
-
-#ifndef included_dhcp_client_h
-#define included_dhcp_client_h
-
-#include <vnet/ip/ip.h>
-#include <vnet/dhcp/dhcp4_packet.h>
-
-#define foreach_dhcp_client_state \
-_(DHCP_DISCOVER) \
-_(DHCP_REQUEST) \
-_(DHCP_BOUND)
-
-typedef enum
-{
-#define _(a) a,
- foreach_dhcp_client_state
-#undef _
-} dhcp_client_state_t;
-
-struct dhcp_client_t_;
-
-/**
- * Callback function for DHCP complete events
- */
-typedef void (*dhcp_event_cb_t) (u32 client_index,
- const struct dhcp_client_t_ * client);
-
-typedef struct dhcp_client_t_
-{
- dhcp_client_state_t state;
-
- /* the interface in question */
- u32 sw_if_index;
-
- /* State machine retry counter */
- u32 retry_count;
-
- /* Send next pkt at this time */
- f64 next_transmit;
- f64 lease_expires;
-
- /* DHCP transaction ID, a random number */
- u32 transaction_id;
-
- /* leased address, other learned info DHCP */
- ip4_address_t leased_address; /* from your_ip_address field */
- ip4_address_t dhcp_server;
- u32 subnet_mask_width; /* option 1 */
- ip4_address_t router_address; /* option 3 */
- ip4_address_t *domain_server_address; /* option 6 */
- u32 lease_renewal_interval; /* option 51 */
- u32 lease_lifetime; /* option 59 */
-
- /* Requested data (option 55) */
- u8 *option_55_data;
-
- /* hostname and software client identifiers */
- u8 *hostname;
- u8 *client_identifier; /* software version, e.g. vpe 1.0 */
-
- /* Information used for event callback */
- u32 client_index;
- u32 pid;
-
- /* Set the broadcast Flag in the Discover/Request messages */
- u8 set_broadcast_flag;
- /* Interface MAC address, so we can do an rx-packet-for-us check */
- u8 client_hardware_address[6];
- u8 client_detect_feature_enabled;
-
- /* the unicast adjacency for the DHCP server */
- adj_index_t ai_ucast;
- /* the broadcast adjacency on the link */
- adj_index_t ai_bcast;
- /* IP DSCP to set in sent packets */
- ip_dscp_t dscp;
-
- dhcp_event_cb_t event_callback;
-} dhcp_client_t;
-
-typedef struct
-{
- /* DHCP client pool */
- dhcp_client_t *clients;
- uword *client_by_sw_if_index;
- u32 seed;
-
- /* convenience */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
-} dhcp_client_main_t;
-
-typedef struct
-{
- int is_add;
- u32 sw_if_index;
- u8 set_broadcast_flag;
-
- /* vectors, consumed by dhcp client code */
- u8 *hostname;
- u8 *client_identifier;
-
- /* Bytes containing requested option numbers */
- u8 *option_55_data;
-
- /* Information used for event callback */
- u32 client_index;
- u32 pid;
- ip_dscp_t dscp;
- dhcp_event_cb_t event_callback;
-} dhcp_client_add_del_args_t;
-
-extern dhcp_client_main_t dhcp_client_main;
-
-#define EVENT_DHCP_CLIENT_WAKEUP 1
-
-int dhcp_client_for_us (u32 bi0,
- vlib_buffer_t * b0,
- ip4_header_t * ip0,
- udp_header_t * u0, dhcp_header_t * dh0);
-
-/**
- * Add/Delete DHCP clients
- */
-extern 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);
-
-/**
- * callback function for clients walking the DHCP client configurations
- *
- * @param client The client being visitsed
- * @param data The data passed during the call to 'walk'
- * @return !0 to continue walking 0 to stop.
- */
-typedef int (*dhcp_client_walk_cb_t) (const dhcp_client_t * client,
- void *data);
-
-/**
- * Walk (visit each) DHCP client configuration
- *
- * @param cb The callback function invoked as each client is visited
- * @param ctx Context data passed back to the client in the invocation of
- * the callback.
- */
-extern void dhcp_client_walk (dhcp_client_walk_cb_t cb, void *ctx);
-
-#endif /* included_dhcp_client_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp.api b/src/vnet/dhcp/dhcp.api
deleted file mode 100644
index f3fef5135f1..00000000000
--- a/src/vnet/dhcp/dhcp.api
+++ /dev/null
@@ -1,462 +0,0 @@
-/*
- * Copyright (c) 2015-2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-option version = "3.0.1";
-
-import "vnet/interface_types.api";
-import "vnet/ip/ip_types.api";
-import "vnet/ethernet/ethernet_types.api";
-
-enum vss_type {
- VSS_TYPE_API_ASCII = 0,
- VSS_TYPE_API_VPN_ID = 1,
- VSS_TYPE_API_INVALID = 123,
- VSS_TYPE_API_DEFAULT = 255,
-};
-
-enum dhcp_client_state {
- DHCP_CLIENT_STATE_API_DISCOVER,
- DHCP_CLIENT_STATE_API_REQUEST,
- DHCP_CLIENT_STATE_API_BOUND,
-};
-
-enum dhcpv6_msg_type
-{
- DHCPV6_MSG_API_SOLICIT = 1,
- DHCPV6_MSG_API_ADVERTISE = 2,
- DHCPV6_MSG_API_REQUEST = 3,
- DHCPV6_MSG_API_CONFIRM = 4,
- DHCPV6_MSG_API_RENEW = 5,
- DHCPV6_MSG_API_REBIND = 6,
- DHCPV6_MSG_API_REPLY = 7,
- DHCPV6_MSG_API_RELEASE = 8,
- DHCPV6_MSG_API_DECLINE = 9,
- DHCPV6_MSG_API_RECONFIGURE = 10,
- DHCPV6_MSG_API_INFORMATION_REQUEST = 11,
- DHCPV6_MSG_API_RELAY_FORW = 12,
- DHCPV6_MSG_API_RELAY_REPL = 13,
-};
-
-/** \brief DHCP Proxy config add / del request
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param rx_vrf_id - Rx/interface vrf id
- @param server_vrf_id - server vrf id
- @param is_add - add the config if non-zero, else delete
- @param insert_circuit_id - option82 suboption 1 fib number
- @param dhcp_server[] - server address
- @param dhcp_src_address[] - <fix this, need details>
-*/
-autoreply define dhcp_proxy_config
-{
- u32 client_index;
- u32 context;
- u32 rx_vrf_id;
- u32 server_vrf_id;
- bool is_add;
- vl_api_address_t dhcp_server;
- vl_api_address_t dhcp_src_address;
-};
-
-/** \brief DHCP Proxy set / unset vss request
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param tbl_id - table id
- @vss_type - 0: use ASCI vpn_id; 1: use oui/vpn_index; 255: global vpn
- @vpn_ascii - null terminated ASCII VPN ID up to 128 characters
- @param oui - first part of rfc2685 vpn id, 3 bytes oui
- @param vpn_index - second part of rfc2685 vpn id, 4 bytes vpn index
- @param is_ipv6 - ip6 if non-zero, else ip4
- @param is_add - set vss if non-zero, else delete
-*/
-autoreply define dhcp_proxy_set_vss
-{
- u32 client_index;
- u32 context;
- u32 tbl_id;
- vl_api_vss_type_t vss_type;
- string vpn_ascii_id[129];
- u32 oui;
- u32 vpn_index;
- bool is_ipv6;
- bool is_add;
-};
-
-/** \brief DHCP Client config data
- @param sw_if_index - index of the interface for DHCP client
- @param hostname - hostname
- @param id - Client ID - option 61
- @param want_dhcp_event - DHCP event sent to the sender
- via dhcp_compl_event API message if non-zero
- @param set_broadcast_flag - in the DHCP Discover to control
- how the resulting OFFER is addressed.
- @param dscp - DSCP value set in IP packets sent by the client
- @param pid - sender's pid
-*/
-typedef dhcp_client
-{
- vl_api_interface_index_t sw_if_index;
- string hostname[64];
- u8 id[64];
- bool want_dhcp_event;
- bool set_broadcast_flag;
- vl_api_ip_dscp_t dscp;
- u32 pid;
-};
-
-/** \brief DHCP Client config add / del request
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param is_add - add the config if non-zero, else delete
- @param client - client configuration data
-*/
-autoreply define dhcp_client_config
-{
- u32 client_index;
- u32 context;
- bool is_add;
- vl_api_dhcp_client_t client;
-};
-
-/** \brief Struct representing domain server
- @param address - IP address
-*/
-typedef domain_server
-{
- vl_api_address_t address;
-};
-
-/** \brief Data learned by the client during the DHCP process
- @param sw_if_index - the interface on which the client is configured
- @param state - the state of the lease
- @param is_ipv6 - if non-zero the address is ipv6, else ipv4
- @param mask_width - The length of the subnet mask assigned
- @param host_address - Host IP address
- @param router_address - Router IP address
- @param host_mac - Host MAC address
-*/
-typedef dhcp_lease
-{
- vl_api_interface_index_t sw_if_index;
- vl_api_dhcp_client_state_t state;
- bool is_ipv6;
- string hostname[64];
- u8 mask_width;
- vl_api_address_t host_address;
- vl_api_address_t router_address;
- vl_api_mac_address_t host_mac;
- u8 count;
- vl_api_domain_server_t domain_server[count];
-};
-
-/** \brief Tell client about a DHCP completion event
- @param client_index - opaque cookie to identify the sender
- @param pid - client pid registered to receive notification
- @param lease - Data learned during the DHCP process;
-*/
-define dhcp_compl_event
-{
- u32 client_index;
- u32 pid;
- vl_api_dhcp_lease_t lease;
-};
-
-service {
- rpc dhcp_client_config returns dhcp_client_config_reply events dhcp_compl_event;
-};
-
-/** \brief Dump the DHCP client configurations
- */
-define dhcp_client_dump
-{
- u32 client_index;
- u32 context;
-};
-
-/** \brief DHCP Client details returned from dump
- * @param client - The configured client
- * @param lease - The learned lease data
- */
-define dhcp_client_details
-{
- u32 context;
- vl_api_dhcp_client_t client;
- vl_api_dhcp_lease_t lease;
-};
-
-/** \brief Dump DHCP proxy table
- @param client_index - opaque cookie to identify the sender
- @param True for IPv6 proxy table
-*/
-define dhcp_proxy_dump
-{
- u32 client_index;
- u32 context;
- bool is_ip6;
-};
-
-typedef dhcp_server
-{
- u32 server_vrf_id;
- vl_api_address_t dhcp_server;
-};
-
-/** \brief Tell client about a DHCP completion event
- @param client_index - opaque cookie to identify the sender
-*/
-manual_endian manual_print define dhcp_proxy_details
-{
- u32 context;
- u32 rx_vrf_id;
- u32 vss_oui;
- u32 vss_fib_id;
- vl_api_vss_type_t vss_type;
- bool is_ipv6;
- string vss_vpn_ascii_id[129];
- vl_api_address_t dhcp_src_address;
- u8 count;
- vl_api_dhcp_server_t servers[count];
-};
-
-/** \brief Set DHCPv6 DUID-LL
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param duid_ll - DUID-LL binary string
-*/
-autoreply define dhcp6_duid_ll_set
-{
- u32 client_index;
- u32 context;
- u8 duid_ll[10];
-};
-
-/** \brief Enable/disable listening on DHCPv6 client port
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
-*/
-autoreply define dhcp6_clients_enable_disable
-{
- u32 client_index;
- u32 context;
- bool enable;
-};
-
-/** \brief Struct representing DHCPv6 address
- @param address - address
- @param valid_time - valid lifetime
- @param preferred_time - preferred lifetime
-*/
-typedef dhcp6_address_info
-{
- vl_api_ip6_address_t address;
- u32 valid_time;
- u32 preferred_time;
-};
-
-/** \brief Struct representing DHCPv6 PD prefix
- @param prefix - prefix
- @param valid_time - valid lifetime
- @param preferred_time - preferred lifetime
-*/
-typedef dhcp6_pd_prefix_info
-{
- vl_api_ip6_prefix_t prefix;
- u32 valid_time;
- u32 preferred_time;
-};
-
-/** \brief Send DHCPv6 client message of specified type
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param sw_if_index - index of TX interface, also identifies IAID
- @param server_index - used to dentify DHCPv6 server,
- unique for each DHCPv6 server on the link,
- value obrtained from dhcp6_reply_event API message,
- use ~0 to send message to all DHCPv6 servers
- @param irt - initial retransmission time
- @param mrt - maximum retransmission time
- @param mrc - maximum retransmission count
- @param mrd - maximum retransmission duration
- for sending the message
- @param stop - if non-zero then stop resending the message,
- otherwise start sending the message
- @param msg_type - message type
- @param T1 - value of T1 in IA_NA option
- @param T2 - value of T2 in IA_NA option
- @param n_addresses - number of addresses in IA_NA option
- @param addresses - list of addresses in IA_NA option
-*/
-autoreply define dhcp6_send_client_message
-{
- u32 client_index;
- u32 context;
- vl_api_interface_index_t sw_if_index;
- u32 server_index;
- u32 irt;
- u32 mrt;
- u32 mrc;
- u32 mrd;
- bool stop;
- vl_api_dhcpv6_msg_type_t msg_type;
- u32 T1;
- u32 T2;
- u32 n_addresses;
- vl_api_dhcp6_address_info_t addresses[n_addresses];
-};
-
-/** \brief Send DHCPv6 PD client message of specified type
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param sw_if_index - index of TX interface
- @param server_index - used to dentify DHCPv6 server,
- unique for each DHCPv6 server on the link,
- value obrtained from dhcp6_pd_reply_event API message,
- use ~0 to send message to all DHCPv6 servers
- @param irt - initial retransmission time
- @param mrt - maximum retransmission time
- @param mrc - maximum retransmission count
- @param mrd - maximum retransmission duration
- for sending the message
- @param stop - if non-zero then stop resending the message,
- otherwise start sending the message
- @param msg_type - message type
- @param T1 - value of T1 in IA_PD option
- @param T2 - value of T2 in IA_PD option
- @param n_prefixes - number of addresses in IA_PD option
- @param prefixes - list of prefixes in IA_PD option
-*/
-autoreply define dhcp6_pd_send_client_message
-{
- u32 client_index;
- u32 context;
- vl_api_interface_index_t sw_if_index;
- u32 server_index;
- u32 irt;
- u32 mrt;
- u32 mrc;
- u32 mrd;
- bool stop;
- vl_api_dhcpv6_msg_type_t msg_type;
- u32 T1;
- u32 T2;
- u32 n_prefixes;
- vl_api_dhcp6_pd_prefix_info_t prefixes[n_prefixes];
-};
-
-service {
- rpc want_dhcp6_reply_events returns want_dhcp6_reply_events_reply
- events dhcp6_reply_event;
-};
-
-service {
- rpc want_dhcp6_pd_reply_events returns want_dhcp6_pd_reply_events_reply
- events dhcp6_pd_reply_event;
-};
-
-/** \brief Register for DHCPv6 reply events
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param enable_disable - 1 => register for events, 0 => cancel registration
- @param pid - sender's pid
-*/
-autoreply define want_dhcp6_reply_events
-{
- u32 client_index;
- u32 context;
- u8 enable_disable;
- u32 pid;
-};
-
-/** \brief Register for DHCPv6 PD reply events
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param enable_disable - 1 => register for events, 0 => cancel registration
- @param pid - sender's pid
-*/
-autoreply define want_dhcp6_pd_reply_events
-{
- u32 client_index;
- u32 context;
- bool enable_disable;
- u32 pid;
-};
-
-/** \brief Tell client about a DHCPv6 server reply event
- @param client_index - opaque cookie to identify the sender
- @param pid - client pid registered to receive notification
- @param sw_if_index - index of RX interface, also identifies IAID
- @param server_index - used to dentify DHCPv6 server,
- unique for each DHCPv6 server on the link
- @param msg_type - message type
- @param T1 - value of T1 in IA_NA option
- @param T2 - value of T2 in IA_NA option
- @param inner_status_code - value of status code inside IA_NA option
- @param status_code - value of status code
- @param preference - value of preference option in reply message
- @param n_addresses - number of addresses in IA_NA option
- @param addresses - list of addresses in IA_NA option
-*/
-define dhcp6_reply_event
-{
- u32 client_index;
- u32 pid;
- vl_api_interface_index_t sw_if_index;
- u32 server_index;
- vl_api_dhcpv6_msg_type_t msg_type;
- u32 T1;
- u32 T2;
- u16 inner_status_code;
- u16 status_code;
- u8 preference;
- u32 n_addresses;
- vl_api_dhcp6_address_info_t addresses[n_addresses];
-};
-
-/** \brief Tell client about a DHCPv6 PD server reply event
- @param client_index - opaque cookie to identify the sender
- @param pid - client pid registered to receive notification
- @param sw_if_index - index of RX interface
- @param server_index - used to dentify DHCPv6 server,
- unique for each DHCPv6 server on the link
- @param msg_type - message type
- @param T1 - value of T1 in IA_PD option
- @param T2 - value of T2 in IA_PD option
- @param inner_status_code - value of status code inside IA_PD option
- @param status_code - value of the main status code of DHCPv6 message
- @param preference - value of preference option in reply message
- @param n_prefixes - number of prefixes in IA_PD option
- @param prefixes - list of prefixes in IA_PD option
-*/
-define dhcp6_pd_reply_event
-{
- u32 client_index;
- u32 pid;
- vl_api_interface_index_t sw_if_index;
- u32 server_index;
- vl_api_dhcpv6_msg_type_t msg_type;
- u32 T1;
- u32 T2;
- u16 inner_status_code;
- u16 status_code;
- u8 preference;
- u32 n_prefixes;
- vl_api_dhcp6_pd_prefix_info_t prefixes[n_prefixes];
-};
-
-/*
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp4_packet.h b/src/vnet/dhcp/dhcp4_packet.h
deleted file mode 100644
index 3076dd9529d..00000000000
--- a/src/vnet/dhcp/dhcp4_packet.h
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef included_vnet_dhcp4_packet_h
-#define included_vnet_dhcp4_packet_h
-
-/*
- * DHCP packet format
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vnet/ip/ip4_packet.h>
-
-typedef struct
-{
- u8 option;
- u8 length;
- union
- {
- u8 data[0];
- u32 data_as_u32[0];
- };
-} __attribute__ ((packed)) dhcp_option_t;
-
-typedef struct
-{
- u8 opcode; /* 1 = request, 2 = reply */
- u8 hardware_type; /* 1 = ethernet */
- u8 hardware_address_length;
- u8 hops;
- u32 transaction_identifier;
- u16 seconds;
- u16 flags;
-#define DHCP_FLAG_BROADCAST (1<<15)
- ip4_address_t client_ip_address;
- ip4_address_t your_ip_address; /* use this one */
- ip4_address_t server_ip_address;
- ip4_address_t gateway_ip_address; /* use option 3, not this one */
- u8 client_hardware_address[16];
- u8 server_name[64];
- u8 boot_filename[128];
- ip4_address_t magic_cookie;
- dhcp_option_t options[0];
-} dhcp_header_t;
-
-typedef enum
-{
- DHCP_PACKET_DISCOVER = 1,
- DHCP_PACKET_OFFER,
- DHCP_PACKET_REQUEST,
- DHCP_PACKET_ACK = 5,
- DHCP_PACKET_NAK,
-} dhcp_packet_type_t;
-
-typedef enum dhcp_packet_option_t_
-{
- DHCP_PACKET_OPTION_MSG_TYPE = 53,
- DHCP_PACKET_OPTION_END = 0xff,
-} dhcp_packet_option_t;
-
-/* charming antique: 99.130.83.99 is the dhcp magic cookie */
-#define DHCP_MAGIC (clib_host_to_net_u32(0x63825363))
-
-#endif /* included_vnet_dhcp4_packet_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp4_proxy_error.def b/src/vnet/dhcp/dhcp4_proxy_error.def
deleted file mode 100644
index adf04808fa3..00000000000
--- a/src/vnet/dhcp/dhcp4_proxy_error.def
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * dhcp_proxy_error.def: dhcp proxy errors
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-dhcp_proxy_error (NONE, "no error")
-dhcp_proxy_error (NO_SERVER, "no dhcp server configured")
-dhcp_proxy_error (RELAY_TO_SERVER, "DHCP packets relayed to the server")
-dhcp_proxy_error (RELAY_TO_CLIENT, "DHCP packets relayed to clients")
-dhcp_proxy_error (OPTION_82_ERROR, "DHCP failed to insert option 82")
-dhcp_proxy_error (NO_OPTION_82, "DHCP option 82 missing")
-dhcp_proxy_error (BAD_OPTION_82_ITF, "Bad DHCP option 82 interface value")
-dhcp_proxy_error (BAD_OPTION_82_ADDR, "Bad DHCP option 82 address value")
-dhcp_proxy_error (BAD_FIB_ID, "DHCP option 82 fib-id to fib-index map failure")
-dhcp_proxy_error (NO_INTERFACE_ADDRESS, "DHCP no interface address")
-dhcp_proxy_error (OPTION_82_VSS_NOT_PROCESSED, "DHCP VSS not processed by DHCP server")
-dhcp_proxy_error (BAD_YIADDR, "DHCP packets with bad your_ip_address fields")
-dhcp_proxy_error (BAD_SVR_FIB_OR_ADDRESS, "DHCP packets not from DHCP server or server FIB.")
-dhcp_proxy_error (PKT_TOO_BIG, "DHCP packets which are too big.")
-
diff --git a/src/vnet/dhcp/dhcp4_proxy_node.c b/src/vnet/dhcp/dhcp4_proxy_node.c
deleted file mode 100644
index 3576f0cbf35..00000000000
--- a/src/vnet/dhcp/dhcp4_proxy_node.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/*
- * proxy_node.c: dhcp proxy node processing
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vlib/vlib.h>
-#include <vnet/pg/pg.h>
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/dhcp/client.h>
-#include <vnet/fib/ip4_fib.h>
-
-static char *dhcp_proxy_error_strings[] = {
-#define dhcp_proxy_error(n,s) s,
-#include <vnet/dhcp/dhcp4_proxy_error.def>
-#undef dhcp_proxy_error
-};
-
-#define foreach_dhcp_proxy_to_server_input_next \
- _ (DROP, "error-drop") \
- _ (LOOKUP, "ip4-lookup") \
- _ (SEND_TO_CLIENT, "dhcp-proxy-to-client")
-
-typedef enum
-{
-#define _(s,n) DHCP_PROXY_TO_SERVER_INPUT_NEXT_##s,
- foreach_dhcp_proxy_to_server_input_next
-#undef _
- DHCP_PROXY_TO_SERVER_INPUT_N_NEXT,
-} dhcp_proxy_to_server_input_next_t;
-
-typedef struct
-{
- /* 0 => to server, 1 => to client */
- int which;
- ip4_address_t trace_ip4_address;
- u32 error;
- u32 sw_if_index;
- u32 original_sw_if_index;
-} dhcp_proxy_trace_t;
-
-#define VPP_DHCP_OPTION82_SUB1_SIZE 6
-#define VPP_DHCP_OPTION82_SUB5_SIZE 6
-#define VPP_DHCP_OPTION82_VSS_SIZE 12
-#define VPP_DHCP_OPTION82_SIZE (VPP_DHCP_OPTION82_SUB1_SIZE + \
- VPP_DHCP_OPTION82_SUB5_SIZE + \
- VPP_DHCP_OPTION82_VSS_SIZE +3)
-
-static vlib_node_registration_t dhcp_proxy_to_server_node;
-static vlib_node_registration_t dhcp_proxy_to_client_node;
-
-static u8 *
-format_dhcp_proxy_trace (u8 * s, va_list * args)
-{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- dhcp_proxy_trace_t *t = va_arg (*args, dhcp_proxy_trace_t *);
-
- if (t->which == 0)
- s = format (s, "DHCP proxy: sent to server %U\n",
- format_ip4_address, &t->trace_ip4_address, t->error);
- else
- s = format (s, "DHCP proxy: broadcast to client from %U\n",
- format_ip4_address, &t->trace_ip4_address);
-
- if (t->error != (u32) ~ 0)
- s = format (s, " error: %s\n", dhcp_proxy_error_strings[t->error]);
-
- s = format (s, " original_sw_if_index: %d, sw_if_index: %d\n",
- t->original_sw_if_index, t->sw_if_index);
-
- return s;
-}
-
-static u8 *
-format_dhcp_proxy_header_with_length (u8 * s, va_list * args)
-{
- dhcp_header_t *h = va_arg (*args, dhcp_header_t *);
- u32 max_header_bytes = va_arg (*args, u32);
- u32 header_bytes;
-
- header_bytes = sizeof (h[0]);
- if (max_header_bytes != 0 && header_bytes > max_header_bytes)
- return format (s, "dhcp header truncated");
-
- s = format (s, "DHCP Proxy");
-
- return s;
-}
-
-static uword
-dhcp_proxy_to_server_input (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
-{
- u32 n_left_from, next_index, *from, *to_next;
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- from = vlib_frame_vector_args (from_frame);
- n_left_from = from_frame->n_vectors;
- u32 pkts_to_server = 0, pkts_to_client = 0, pkts_no_server = 0;
- u32 pkts_no_interface_address = 0;
- u32 pkts_too_big = 0;
- ip4_main_t *im = &ip4_main;
-
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- udp_header_t *u0;
- dhcp_header_t *h0;
- ip4_header_t *ip0;
- u32 next0;
- u32 old0, new0;
- ip_csum_t sum0;
- u32 error0 = (u32) ~ 0;
- u32 sw_if_index = 0;
- u32 original_sw_if_index = 0;
- u32 fib_index;
- dhcp_proxy_t *proxy;
- dhcp_server_t *server;
- u32 rx_sw_if_index;
- dhcp_option_t *o, *end;
- u32 len = 0;
- u8 is_discover = 0;
- int space_left;
-
- bi0 = from[0];
- from += 1;
- n_left_from -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- h0 = vlib_buffer_get_current (b0);
-
- /*
- * udp_local hands us the DHCP header, need udp hdr,
- * ip hdr to relay to server
- */
- vlib_buffer_advance (b0, -(sizeof (*u0)));
- u0 = vlib_buffer_get_current (b0);
-
- /* This blows. Return traffic has src_port = 67, dst_port = 67 */
- if (u0->src_port ==
- clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_server))
- {
- vlib_buffer_advance (b0, sizeof (*u0));
- next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_SEND_TO_CLIENT;
- error0 = 0;
- pkts_to_client++;
- goto do_enqueue;
- }
-
- rx_sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- fib_index = im->fib_index_by_sw_if_index[rx_sw_if_index];
- proxy = dhcp_get_proxy (dpm, fib_index, FIB_PROTOCOL_IP4);
-
- if (PREDICT_FALSE (NULL == proxy))
- {
- error0 = DHCP_PROXY_ERROR_NO_SERVER;
- next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_server++;
- goto do_trace;
- }
-
- if (!vlib_buffer_chain_linearize (vm, b0))
- {
- error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
- next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_too_big++;
- goto do_trace;
- }
- space_left = vlib_buffer_space_left_at_end (vm, b0);
- /* cant parse chains...
- * and we need some space for option 82*/
- if ((b0->flags & VLIB_BUFFER_NEXT_PRESENT) != 0 ||
- space_left < VPP_DHCP_OPTION82_SIZE)
- {
- error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
- next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_too_big++;
- goto do_trace;
- }
-
- server = &proxy->dhcp_servers[0];
- vlib_buffer_advance (b0, -(sizeof (*ip0)));
- ip0 = vlib_buffer_get_current (b0);
-
- /* disable UDP checksum */
- u0->checksum = 0;
- sum0 = ip0->checksum;
- old0 = ip0->dst_address.as_u32;
- new0 = server->dhcp_server.ip4.as_u32;
- ip0->dst_address.as_u32 = server->dhcp_server.ip4.as_u32;
- sum0 = ip_csum_update (sum0, old0, new0,
- ip4_header_t /* structure */ ,
- dst_address /* changed member */ );
- ip0->checksum = ip_csum_fold (sum0);
-
- sum0 = ip0->checksum;
- old0 = ip0->src_address.as_u32;
- new0 = proxy->dhcp_src_address.ip4.as_u32;
- ip0->src_address.as_u32 = new0;
- sum0 = ip_csum_update (sum0, old0, new0,
- ip4_header_t /* structure */ ,
- src_address /* changed member */ );
- ip0->checksum = ip_csum_fold (sum0);
-
- /* Send to DHCP server via the configured FIB */
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = server->server_fib_index;
-
- h0->gateway_ip_address = proxy->dhcp_src_address.ip4;
- pkts_to_server++;
-
- o = h0->options;
- end = (void *) vlib_buffer_get_tail (b0);
-
- /* TLVs are not performance-friendly... */
- while (o->option != DHCP_PACKET_OPTION_END && o < end)
- {
- if (DHCP_PACKET_OPTION_MSG_TYPE == o->option)
- {
- if (DHCP_PACKET_DISCOVER == o->data[0])
- {
- is_discover = 1;
- }
- }
- o = (dhcp_option_t *) (o->data + o->length);
- }
-
- if (o->option == DHCP_PACKET_OPTION_END && o <= end)
- {
- vnet_main_t *vnm = vnet_get_main ();
- u16 old_l0, new_l0;
- ip4_address_t _ia0, *ia0 = &_ia0;
- dhcp_vss_t *vss;
- vnet_sw_interface_t *swif;
-
- original_sw_if_index = sw_if_index =
- vnet_buffer (b0)->sw_if_index[VLIB_RX];
- swif = vnet_get_sw_interface (vnm, sw_if_index);
- if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
- sw_if_index = swif->unnumbered_sw_if_index;
-
- /*
- * Get the first ip4 address on the [client-side]
- * RX interface, if not unnumbered. otherwise use
- * the loopback interface's ip address.
- */
- ia0 = ip4_interface_first_address (&ip4_main, sw_if_index, 0);
-
- if (ia0 == 0)
- {
- error0 = DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS;
- next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_interface_address++;
- goto do_trace;
- }
-
- /* Add option 82 */
- o->option = 82; /* option 82 */
- o->length = 12; /* 12 octets to follow */
- o->data[0] = 1; /* suboption 1, circuit ID (=FIB id) */
- o->data[1] = 4; /* length of suboption */
- u32 *o_ifid = (u32 *) & o->data[2];
- *o_ifid = clib_host_to_net_u32 (original_sw_if_index);
- o->data[6] = 5; /* suboption 5 (client RX intfc address) */
- o->data[7] = 4; /* length 4 */
- u32 *o_addr = (u32 *) & o->data[8];
- *o_addr = ia0->as_u32;
- o->data[12] = DHCP_PACKET_OPTION_END;
-
- vss = dhcp_get_vss_info (dpm, fib_index, FIB_PROTOCOL_IP4);
- if (vss)
- {
- u32 id_len; /* length of VPN ID */
-
- if (vss->vss_type == VSS_TYPE_VPN_ID)
- {
- id_len = sizeof (vss->vpn_id); /* vpn_id is 7 bytes */
- memcpy (&o->data[15], vss->vpn_id, id_len);
- }
- else if (vss->vss_type == VSS_TYPE_ASCII)
- {
- id_len = vec_len (vss->vpn_ascii_id);
- memcpy (&o->data[15], vss->vpn_ascii_id, id_len);
- }
- else /* must be VSS_TYPE_DEFAULT, no VPN ID */
- id_len = 0;
-
- o->data[12] = 151; /* vss suboption */
- o->data[13] = id_len + 1; /* length: vss_type + id_len */
- o->data[14] = vss->vss_type; /* vss option type */
- o->data[15 + id_len] = 152; /* vss control suboption */
- o->data[16 + id_len] = 0; /* length */
- o->data[17 + id_len] = DHCP_PACKET_OPTION_END; /* "end-of-options" (0xFF) */
- /* 5 bytes for suboption headers 151+len, 152+len and 0xFF */
- o->length += id_len + 5;
- }
-
- len = o->length + 3;
- b0->current_length += len;
- /* Fix IP header length and checksum */
- old_l0 = ip0->length;
- new_l0 = clib_net_to_host_u16 (old_l0);
- new_l0 += len;
- new_l0 = clib_host_to_net_u16 (new_l0);
- ip0->length = new_l0;
- sum0 = ip0->checksum;
- sum0 = ip_csum_update (sum0, old_l0, new_l0, ip4_header_t,
- length /* changed member */ );
- ip0->checksum = ip_csum_fold (sum0);
-
- /* Fix UDP length */
- new_l0 = clib_net_to_host_u16 (u0->length);
- new_l0 += len;
- u0->length = clib_host_to_net_u16 (new_l0);
- }
- else
- {
- vlib_node_increment_counter
- (vm, dhcp_proxy_to_server_node.index,
- DHCP_PROXY_ERROR_OPTION_82_ERROR, 1);
- }
-
- next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP;
-
- /*
- * If we have multiple servers configured and this is the
- * client's discover message, then send copies to each of
- * those servers
- */
- if (is_discover && vec_len (proxy->dhcp_servers) > 1)
- {
- u32 ii;
-
- for (ii = 1; ii < vec_len (proxy->dhcp_servers); ii++)
- {
- vlib_buffer_t *c0;
- u32 ci0;
-
- c0 = vlib_buffer_copy (vm, b0);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (c0);
- ci0 = vlib_get_buffer_index (vm, c0);
- server = &proxy->dhcp_servers[ii];
-
- ip0 = vlib_buffer_get_current (c0);
-
- sum0 = ip0->checksum;
- old0 = ip0->dst_address.as_u32;
- new0 = server->dhcp_server.ip4.as_u32;
- ip0->dst_address.as_u32 = server->dhcp_server.ip4.as_u32;
- sum0 = ip_csum_update (sum0, old0, new0,
- ip4_header_t /* structure */ ,
- dst_address /* changed member */ );
- ip0->checksum = ip_csum_fold (sum0);
-
- to_next[0] = ci0;
- to_next += 1;
- n_left_to_next -= 1;
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- ci0, next0);
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_proxy_trace_t *tr;
-
- tr = vlib_add_trace (vm, node, c0, sizeof (*tr));
- tr->which = 0; /* to server */
- tr->error = error0;
- tr->original_sw_if_index = original_sw_if_index;
- tr->sw_if_index = sw_if_index;
- if (next0 == DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
- tr->trace_ip4_address.as_u32 =
- server->dhcp_server.ip4.as_u32;
- }
-
- if (PREDICT_FALSE (0 == n_left_to_next))
- {
- vlib_put_next_frame (vm, node, next_index,
- n_left_to_next);
- vlib_get_next_frame (vm, node, next_index,
- to_next, n_left_to_next);
- }
- }
- }
- do_trace:
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_proxy_trace_t *tr = vlib_add_trace (vm, node,
- b0, sizeof (*tr));
- tr->which = 0; /* to server */
- tr->error = error0;
- tr->original_sw_if_index = original_sw_if_index;
- tr->sw_if_index = sw_if_index;
- if (next0 == DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
- tr->trace_ip4_address.as_u32 =
- proxy->dhcp_servers[0].dhcp_server.ip4.as_u32;
- }
-
- do_enqueue:
- to_next[0] = bi0;
- to_next += 1;
- n_left_to_next -= 1;
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
- vlib_node_increment_counter (vm, dhcp_proxy_to_server_node.index,
- DHCP_PROXY_ERROR_RELAY_TO_CLIENT,
- pkts_to_client);
- vlib_node_increment_counter (vm, dhcp_proxy_to_server_node.index,
- DHCP_PROXY_ERROR_RELAY_TO_SERVER,
- pkts_to_server);
- vlib_node_increment_counter (vm, dhcp_proxy_to_server_node.index,
- DHCP_PROXY_ERROR_NO_SERVER, pkts_no_server);
- vlib_node_increment_counter (vm, dhcp_proxy_to_server_node.index,
- DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS,
- pkts_no_interface_address);
- vlib_node_increment_counter (vm, dhcp_proxy_to_server_node.index,
- DHCP_PROXY_ERROR_PKT_TOO_BIG, pkts_too_big);
- return from_frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp_proxy_to_server_node, static) = {
- .function = dhcp_proxy_to_server_input,
- .name = "dhcp-proxy-to-server",
- /* Takes a vector of packets. */
- .vector_size = sizeof (u32),
-
- .n_errors = DHCP_PROXY_N_ERROR,
- .error_strings = dhcp_proxy_error_strings,
-
- .n_next_nodes = DHCP_PROXY_TO_SERVER_INPUT_N_NEXT,
- .next_nodes = {
-#define _(s,n) [DHCP_PROXY_TO_SERVER_INPUT_NEXT_##s] = n,
- foreach_dhcp_proxy_to_server_input_next
-#undef _
- },
-
- .format_buffer = format_dhcp_proxy_header_with_length,
- .format_trace = format_dhcp_proxy_trace,
-#if 0
- .unformat_buffer = unformat_dhcp_proxy_header,
-#endif
-};
-/* *INDENT-ON* */
-
-static uword
-dhcp_proxy_to_client_input (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
-{
- u32 n_left_from, *from;
- ethernet_main_t *em = vnet_get_ethernet_main ();
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- vnet_main_t *vnm = vnet_get_main ();
- ip4_main_t *im = &ip4_main;
-
- from = vlib_frame_vector_args (from_frame);
- n_left_from = from_frame->n_vectors;
-
- while (n_left_from > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- udp_header_t *u0;
- dhcp_header_t *h0;
- ip4_header_t *ip0 = 0;
- ip4_address_t *ia0 = 0;
- u32 old0, new0;
- ip_csum_t sum0;
- ethernet_interface_t *ei0;
- ethernet_header_t *mac0;
- vnet_hw_interface_t *hi0;
- vlib_frame_t *f0;
- u32 *to_next0;
- u32 sw_if_index = ~0;
- vnet_sw_interface_t *si0;
- u32 error0 = (u32) ~ 0;
- vnet_sw_interface_t *swif;
- u32 fib_index;
- dhcp_proxy_t *proxy;
- dhcp_server_t *server;
- u32 original_sw_if_index = (u32) ~ 0;
- ip4_address_t relay_addr = {
- .as_u32 = 0,
- };
-
- bi0 = from[0];
- from += 1;
- n_left_from -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- h0 = vlib_buffer_get_current (b0);
-
- /*
- * udp_local hands us the DHCP header, need udp hdr,
- * ip hdr to relay to client
- */
- vlib_buffer_advance (b0, -(sizeof (*u0)));
- u0 = vlib_buffer_get_current (b0);
-
- vlib_buffer_advance (b0, -(sizeof (*ip0)));
- ip0 = vlib_buffer_get_current (b0);
-
- /* Consumed by dhcp client code? */
- if (dhcp_client_for_us (bi0, b0, ip0, u0, h0))
- continue;
-
- if (1 /* dpm->insert_option_82 */ )
- {
- /* linearize needed to "unclone" and scan options */
- int rv = vlib_buffer_chain_linearize (vm, b0);
- if ((b0->flags & VLIB_BUFFER_NEXT_PRESENT) != 0 || !rv)
- {
- error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
- goto drop_packet;
- }
-
- dhcp_option_t *o = h0->options, *end =
- (void *) vlib_buffer_get_tail (b0);
-
- /* Parse through TLVs looking for option 82.
- The circuit-ID is the FIB number we need
- to track down the client-facing interface */
-
- while (o->option != DHCP_PACKET_OPTION_END && o < end)
- {
- if (o->option == 82)
- {
- u32 vss_exist = 0;
- u32 vss_ctrl = 0;
- dhcp_option_t *sub = (dhcp_option_t *) & o->data[0];
- dhcp_option_t *subend =
- (dhcp_option_t *) (o->data + o->length);
- while (sub->option != DHCP_PACKET_OPTION_END
- && sub < subend)
- {
- /* If this is one of ours, it will have
- total length 12, circuit-id suboption type,
- and the sw_if_index */
- if (sub->option == 1 && sub->length == 4)
- {
- sw_if_index = ((sub->data[0] << 24) |
- (sub->data[1] << 16) |
- (sub->data[2] << 8) |
- (sub->data[3]));
- }
- else if (sub->option == 5 && sub->length == 4)
- {
- relay_addr.as_u8[0] = sub->data[0];
- relay_addr.as_u8[1] = sub->data[1];
- relay_addr.as_u8[2] = sub->data[2];
- relay_addr.as_u8[3] = sub->data[3];
- }
- else if (sub->option == 151 &&
- sub->length == 7 && sub->data[0] == 1)
- vss_exist = 1;
- else if (sub->option == 152 && sub->length == 0)
- vss_ctrl = 1;
- sub = (dhcp_option_t *) (sub->data + sub->length);
- }
- if (vss_ctrl && vss_exist)
- vlib_node_increment_counter
- (vm, dhcp_proxy_to_client_node.index,
- DHCP_PROXY_ERROR_OPTION_82_VSS_NOT_PROCESSED, 1);
-
- }
- o = (dhcp_option_t *) (o->data + o->length);
- }
- }
-
- if (sw_if_index == (u32) ~ 0)
- {
- error0 = DHCP_PROXY_ERROR_NO_OPTION_82;
-
- drop_packet:
- vlib_node_increment_counter (vm, dhcp_proxy_to_client_node.index,
- error0, 1);
- f0 = vlib_get_frame_to_node (vm, dpm->error_drop_node_index);
- to_next0 = vlib_frame_vector_args (f0);
- to_next0[0] = bi0;
- f0->n_vectors = 1;
- vlib_put_frame_to_node (vm, dpm->error_drop_node_index, f0);
- goto do_trace;
- }
-
- if (relay_addr.as_u32 == 0)
- {
- error0 = DHCP_PROXY_ERROR_BAD_OPTION_82_ADDR;
- goto drop_packet;
- }
-
- if (sw_if_index >= vec_len (im->fib_index_by_sw_if_index))
- {
- error0 = DHCP_PROXY_ERROR_BAD_OPTION_82_ITF;
- goto drop_packet;
- }
-
- fib_index = im->fib_index_by_sw_if_index[sw_if_index];
- proxy = dhcp_get_proxy (dpm, fib_index, FIB_PROTOCOL_IP4);
-
- if (PREDICT_FALSE (NULL == proxy))
- {
- error0 = DHCP_PROXY_ERROR_NO_SERVER;
- goto drop_packet;
- }
-
- vec_foreach (server, proxy->dhcp_servers)
- {
- if (ip0->src_address.as_u32 == server->dhcp_server.ip4.as_u32)
- {
- goto server_found;
- }
- }
-
- error0 = DHCP_PROXY_ERROR_BAD_SVR_FIB_OR_ADDRESS;
- goto drop_packet;
-
- server_found:
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = sw_if_index;
-
- swif = vnet_get_sw_interface (vnm, sw_if_index);
- original_sw_if_index = sw_if_index;
- if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
- sw_if_index = swif->unnumbered_sw_if_index;
-
- ia0 = ip4_interface_first_address (&ip4_main, sw_if_index, 0);
- if (ia0 == 0)
- {
- error0 = DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS;
- goto drop_packet;
- }
-
- if (relay_addr.as_u32 != ia0->as_u32)
- {
- error0 = DHCP_PROXY_ERROR_BAD_YIADDR;
- goto drop_packet;
- }
-
- u0->checksum = 0;
- u0->dst_port = clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_client);
- sum0 = ip0->checksum;
- old0 = ip0->dst_address.as_u32;
- new0 = 0xFFFFFFFF;
- ip0->dst_address.as_u32 = new0;
- sum0 = ip_csum_update (sum0, old0, new0, ip4_header_t /* structure */ ,
- dst_address /* offset of changed member */ );
- ip0->checksum = ip_csum_fold (sum0);
-
- sum0 = ip0->checksum;
- old0 = ip0->src_address.as_u32;
- new0 = ia0->as_u32;
- ip0->src_address.as_u32 = new0;
- sum0 = ip_csum_update (sum0, old0, new0, ip4_header_t /* structure */ ,
- src_address /* offset of changed member */ );
- ip0->checksum = ip_csum_fold (sum0);
-
- vlib_buffer_advance (b0, -(sizeof (ethernet_header_t)));
- si0 = vnet_get_sw_interface (vnm, original_sw_if_index);
- if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
- vlib_buffer_advance (b0, -4 /* space for VLAN tag */ );
-
- mac0 = vlib_buffer_get_current (b0);
-
- hi0 = vnet_get_sup_hw_interface (vnm, original_sw_if_index);
- ei0 = pool_elt_at_index (em->interfaces, hi0->hw_instance);
- clib_memcpy (mac0->src_address, ei0->address, sizeof (ei0->address));
- clib_memset (mac0->dst_address, 0xff, sizeof (mac0->dst_address));
- mac0->type = (si0->type == VNET_SW_INTERFACE_TYPE_SUB) ?
- clib_net_to_host_u16 (0x8100) : clib_net_to_host_u16 (0x0800);
-
- if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
- {
- u32 *vlan_tag = (u32 *) (mac0 + 1);
- u32 tmp;
- tmp = (si0->sub.id << 16) | 0x0800;
- *vlan_tag = clib_host_to_net_u32 (tmp);
- }
-
- /* $$$ This needs to be rewritten, for sure */
- f0 = vlib_get_frame_to_node (vm, hi0->output_node_index);
- to_next0 = vlib_frame_vector_args (f0);
- to_next0[0] = bi0;
- f0->n_vectors = 1;
- vlib_put_frame_to_node (vm, hi0->output_node_index, f0);
-
- do_trace:
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_proxy_trace_t *tr = vlib_add_trace (vm, node,
- b0, sizeof (*tr));
- tr->which = 1; /* to client */
- tr->trace_ip4_address.as_u32 = ia0 ? ia0->as_u32 : 0;
- tr->error = error0;
- tr->original_sw_if_index = original_sw_if_index;
- tr->sw_if_index = sw_if_index;
- }
- }
-
- return from_frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp_proxy_to_client_node, static) = {
- .function = dhcp_proxy_to_client_input,
- .name = "dhcp-proxy-to-client",
- /* Takes a vector of packets. */
- .vector_size = sizeof (u32),
-
- .n_errors = DHCP_PROXY_N_ERROR,
- .error_strings = dhcp_proxy_error_strings,
- .format_buffer = format_dhcp_proxy_header_with_length,
- .format_trace = format_dhcp_proxy_trace,
-#if 0
- .unformat_buffer = unformat_dhcp_proxy_header,
-#endif
-};
-/* *INDENT-ON* */
-
-void
-dhcp_maybe_register_udp_ports (dhcp_port_reg_flags_t ports)
-{
- dhcp_proxy_main_t *dm = &dhcp_proxy_main;
- vlib_main_t *vm = dm->vlib_main;
- int port_regs_diff = dm->udp_ports_registered ^ ports;
-
- if (!port_regs_diff)
- return;
-
- if ((port_regs_diff & DHCP_PORT_REG_CLIENT) & ports)
- udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_client,
- dhcp_proxy_to_client_node.index, 1 /* is_ip4 */ );
-
- if ((port_regs_diff & DHCP_PORT_REG_SERVER) & ports)
- udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_server,
- dhcp_proxy_to_server_node.index, 1 /* is_ip4 */ );
-
- dm->udp_ports_registered |= ports;
-}
-
-static clib_error_t *
-dhcp4_proxy_init (vlib_main_t * vm)
-{
- dhcp_proxy_main_t *dm = &dhcp_proxy_main;
- vlib_node_t *error_drop_node;
-
- error_drop_node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
- dm->error_drop_node_index = error_drop_node->index;
- dm->vlib_main = vm;
-
- return 0;
-}
-
-
-VLIB_INIT_FUNCTION (dhcp4_proxy_init);
-
-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)
-{
- u32 rx_fib_index = 0;
- int rc = 0;
-
- const fib_prefix_t all_1s = {
- .fp_len = 32,
- .fp_addr.ip4.as_u32 = 0xffffffff,
- .fp_proto = FIB_PROTOCOL_IP4,
- };
-
- if (ip46_address_is_zero (addr))
- return VNET_API_ERROR_INVALID_DST_ADDRESS;
-
- if (ip46_address_is_zero (src_addr))
- return VNET_API_ERROR_INVALID_SRC_ADDRESS;
-
- dhcp_maybe_register_udp_ports (DHCP_PORT_REG_CLIENT | DHCP_PORT_REG_SERVER);
-
- rx_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4,
- rx_table_id,
- FIB_SOURCE_DHCP);
-
- if (is_del)
- {
- if (dhcp_proxy_server_del (FIB_PROTOCOL_IP4, rx_fib_index,
- addr, server_table_id))
- {
- fib_table_entry_special_remove (rx_fib_index,
- &all_1s, FIB_SOURCE_DHCP);
- fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_DHCP);
- }
- }
- else
- {
- if (dhcp_proxy_server_add (FIB_PROTOCOL_IP4,
- addr, src_addr,
- rx_fib_index, server_table_id))
- {
- fib_table_entry_special_add (rx_fib_index,
- &all_1s,
- FIB_SOURCE_DHCP, FIB_ENTRY_FLAG_LOCAL);
- fib_table_lock (rx_fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_DHCP);
- }
- }
- fib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP4, FIB_SOURCE_DHCP);
-
- return (rc);
-}
-
-static clib_error_t *
-dhcp4_proxy_set_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- ip46_address_t server_addr, src_addr;
- u32 server_table_id = 0, rx_table_id = 0;
- int is_del = 0;
- int set_src = 0, set_server = 0;
-
- clib_memset (&server_addr, 0, sizeof (server_addr));
- clib_memset (&src_addr, 0, sizeof (src_addr));
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "server %U",
- unformat_ip4_address, &server_addr.ip4))
- set_server = 1;
- else if (unformat (input, "server-fib-id %d", &server_table_id))
- ;
- else if (unformat (input, "rx-fib-id %d", &rx_table_id))
- ;
- else if (unformat (input, "src-address %U",
- unformat_ip4_address, &src_addr.ip4))
- set_src = 1;
- else if (unformat (input, "delete") || unformat (input, "del"))
- is_del = 1;
- else
- break;
- }
-
- if (is_del || (set_server && set_src))
- {
- int rv;
-
- rv = dhcp4_proxy_set_server (&server_addr, &src_addr, rx_table_id,
- server_table_id, is_del);
- switch (rv)
- {
- case 0:
- return 0;
-
- case VNET_API_ERROR_INVALID_DST_ADDRESS:
- return clib_error_return (0, "Invalid server address");
-
- case VNET_API_ERROR_INVALID_SRC_ADDRESS:
- return clib_error_return (0, "Invalid src address");
-
- case VNET_API_ERROR_NO_SUCH_ENTRY:
- return clib_error_return
- (0, "Fib id %d: no per-fib DHCP server configured", rx_table_id);
-
- default:
- return clib_error_return (0, "BUG: rv %d", rv);
- }
- }
- else
- return clib_error_return (0, "parse error`%U'",
- format_unformat_error, input);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp_proxy_set_command, static) = {
- .path = "set dhcp proxy",
- .short_help = "set dhcp proxy [del] server <ip-addr> src-address <ip-addr> [server-fib-id <n>] [rx-fib-id <n>]",
- .function = dhcp4_proxy_set_command_fn,
-};
-/* *INDENT-ON* */
-
-static u8 *
-format_dhcp4_proxy_server (u8 * s, va_list * args)
-{
- dhcp_proxy_t *proxy = va_arg (*args, dhcp_proxy_t *);
- ip4_fib_t *rx_fib, *server_fib;
- dhcp_server_t *server;
-
- if (proxy == 0)
- {
- s = format (s, "%=14s%=16s%s", "RX FIB", "Src Address",
- "Servers FIB,Address");
- return s;
- }
-
- rx_fib = ip4_fib_get (proxy->rx_fib_index);
-
- s = format (s, "%=14u%=16U",
- rx_fib->table_id,
- format_ip46_address, &proxy->dhcp_src_address, IP46_TYPE_ANY);
-
- vec_foreach (server, proxy->dhcp_servers)
- {
- server_fib = ip4_fib_get (server->server_fib_index);
- s = format (s, "%u,%U ",
- server_fib->table_id,
- format_ip46_address, &server->dhcp_server, IP46_TYPE_ANY);
- }
- return s;
-}
-
-static int
-dhcp4_proxy_show_walk (dhcp_proxy_t * server, void *ctx)
-{
- vlib_main_t *vm = ctx;
-
- vlib_cli_output (vm, "%U", format_dhcp4_proxy_server, server);
-
- return (1);
-}
-
-static clib_error_t *
-dhcp4_proxy_show_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- vlib_cli_output (vm, "%U", format_dhcp4_proxy_server,
- NULL /* header line */ );
-
- dhcp_proxy_walk (FIB_PROTOCOL_IP4, dhcp4_proxy_show_walk, vm);
-
- return (NULL);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp_proxy_show_command, static) = {
- .path = "show dhcp proxy",
- .short_help = "Display dhcp proxy server info",
- .function = dhcp4_proxy_show_command_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcp_option_82_vss_fn (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd)
-{
- u8 is_del = 0, vss_type = VSS_TYPE_DEFAULT;
- u32 oui = 0, fib_id = 0, tbl_id = ~0;
- u8 *vpn_ascii_id = 0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "table %d", &tbl_id))
- ;
- else if (unformat (input, "oui %d", &oui))
- vss_type = VSS_TYPE_VPN_ID;
- else if (unformat (input, "vpn-id %d", &fib_id))
- vss_type = VSS_TYPE_VPN_ID;
- else if (unformat (input, "vpn-ascii-id %s", &vpn_ascii_id))
- vss_type = VSS_TYPE_ASCII;
- else if (unformat (input, "delete") || unformat (input, "del"))
- is_del = 1;
- else
- break;
- }
-
- if (tbl_id == ~0)
- return clib_error_return (0, "no table ID specified.");
-
- int rv = dhcp_proxy_set_vss (FIB_PROTOCOL_IP4, tbl_id, vss_type,
- vpn_ascii_id, oui, fib_id, is_del);
- switch (rv)
- {
- case 0:
- return 0;
- case VNET_API_ERROR_NO_SUCH_ENTRY:
- return clib_error_return (0,
- "option 82 vss for table %d not found in in pool.",
- tbl_id);
- default:
- return clib_error_return (0, "BUG: rv %d", rv);
-
- }
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp_proxy_vss_command,static) = {
- .path = "set dhcp option-82 vss",
- .short_help = "set dhcp option-82 vss [del] table <table id> [oui <n> vpn-id <n> | vpn-ascii-id <text>]",
- .function = dhcp_option_82_vss_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcp_vss_show_command_fn (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd)
-{
- dhcp_vss_walk (FIB_PROTOCOL_IP4, dhcp_vss_show_walk, vm);
-
- return (NULL);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp_proxy_vss_show_command, static) = {
- .path = "show dhcp vss",
- .short_help = "show dhcp VSS",
- .function = dhcp_vss_show_command_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcp_option_82_address_show_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- u32 sw_if_index0 = 0, sw_if_index;
- vnet_sw_interface_t *swif;
- ip4_address_t *ia0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
-
- if (unformat (input, "%U",
- unformat_vnet_sw_interface, vnm, &sw_if_index0))
- {
- swif = vnet_get_sw_interface (vnm, sw_if_index0);
- sw_if_index = (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED) ?
- swif->unnumbered_sw_if_index : sw_if_index0;
- ia0 = ip4_interface_first_address (&ip4_main, sw_if_index, 0);
- if (ia0)
- {
- vlib_cli_output (vm, "%=20s%=20s", "interface",
- "source IP address");
-
- vlib_cli_output (vm, "%=20U%=20U",
- format_vnet_sw_if_index_name,
- vnm, sw_if_index0, format_ip4_address, ia0);
- }
- else
- vlib_cli_output (vm, "%=34s %=20U",
- "No IPv4 address configured on",
- format_vnet_sw_if_index_name, vnm, sw_if_index);
- }
- else
- break;
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp_proxy_address_show_command,static) = {
- .path = "show dhcp option-82-address interface",
- .short_help = "show dhcp option-82-address interface <interface>",
- .function = dhcp_option_82_address_show_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_client_common_dp.c b/src/vnet/dhcp/dhcp6_client_common_dp.c
deleted file mode 100644
index 7ca3b61defb..00000000000
--- a/src/vnet/dhcp/dhcp6_client_common_dp.c
+++ /dev/null
@@ -1,493 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vnet/ethernet/ethernet.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-#include <vnet/dhcp/dhcp6_ia_na_client_dp.h>
-#include <vnet/dhcp/dhcp6_pd_client_dp.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/udp/udp.h>
-
-dhcp6_client_common_main_t dhcp6_client_common_main;
-dhcpv6_duid_ll_string_t client_duid;
-
-u32
-server_index_get_or_create (u8 * data, u16 len)
-{
- dhcp6_client_common_main_t *ccm = &dhcp6_client_common_main;
- u32 i;
- server_id_t *se;
- server_id_t new_se;
-
- for (i = 0; i < vec_len (ccm->server_ids); i++)
- {
- se = &ccm->server_ids[i];
- if (se->len == len && 0 == memcmp (se->data, data, len))
- return i;
- }
-
- new_se.len = len;
- new_se.data = 0;
- vec_validate (new_se.data, len - 1);
- memcpy (new_se.data, data, len);
-
- vec_add1 (ccm->server_ids, new_se);
-
- return vec_len (ccm->server_ids) - 1;
-}
-
-void
-vl_api_dhcp6_duid_ll_set_t_handler (vl_api_dhcp6_duid_ll_set_t * mp)
-{
- vl_api_dhcp6_duid_ll_set_reply_t *rmp;
- dhcpv6_duid_ll_string_t *duid;
- int rv = 0;
-
- duid = (dhcpv6_duid_ll_string_t *) mp->duid_ll;
- if (duid->duid_type != htonl (DHCPV6_DUID_LL))
- {
- rv = VNET_API_ERROR_INVALID_VALUE;
- goto reply;
- }
- clib_memcpy (&client_duid, &duid, sizeof (client_duid));
-
-reply:
- REPLY_MACRO (VL_API_DHCP6_DUID_LL_SET_REPLY);
-}
-
-static void
-generate_client_duid (void)
-{
- client_duid.duid_type = htons (DHCPV6_DUID_LL);
- client_duid.hardware_type = htons (1);
-
- vnet_main_t *vnm = vnet_get_main ();
- vnet_interface_main_t *im = &vnm->interface_main;
- vnet_hw_interface_t *hi;
- ethernet_interface_t *eth_if = 0;
-
- /* *INDENT-OFF* */
- pool_foreach (hi, im->hw_interfaces,
- ({
- eth_if = ethernet_get_interface (&ethernet_main, hi->hw_if_index);
- if (eth_if)
- break;
- }));
- /* *INDENT-ON* */
-
- if (eth_if)
- clib_memcpy (client_duid.lla, eth_if->address, 6);
- else
- {
- clib_warning ("Failed to find any Ethernet interface, "
- "setting DHCPv6 DUID link-layer address to random value");
- u32 seed = random_default_seed ();
- random_u32 (&seed);
- client_duid.lla[0] = 0xc2; /* locally administered unicast */
- client_duid.lla[1] = 0x18;
- client_duid.lla[2] = 0x44;
- client_duid.lla[3] = random_u32 (&seed);
- client_duid.lla[4] = random_u32 (&seed);
- client_duid.lla[5] = random_u32 (&seed);
- }
-}
-
-#define foreach_dhcpv6_client \
- _(DROP, "error-drop") \
- _(LOOKUP, "ip6-lookup")
-
-typedef enum
-{
-#define _(sym,str) DHCPV6_CLIENT_NEXT_##sym,
- foreach_dhcpv6_client
-#undef _
- DHCPV6_CLIENT_N_NEXT,
-} dhcpv6_client_next_t;
-
-/**
- * per-packet trace data
- */
-typedef struct dhcpv6_client_trace_t_
-{
-} dhcpv6_client_trace_t;
-
-static u8 *
-format_dhcpv6_client_trace (u8 * s, va_list * args)
-{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- //dhcpv6_client_trace_t *t = va_arg (*args, dhcpv6_client_trace_t *);
-
- s = format (s, "nothing");
-
- return s;
-}
-
-static uword
-dhcpv6_client_node_fn (vlib_main_t * vm, vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- dhcp6_ia_na_client_main_t *icm = &dhcp6_ia_na_client_main;
- dhcp6_pd_client_main_t *pcm = &dhcp6_pd_client_main;
-
- dhcpv6_client_next_t next_index;
- u32 n_left_from, *from, *to_next;
- next_index = 0;
- n_left_from = frame->n_vectors;
- from = vlib_frame_vector_args (frame);
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- ip6_header_t *ip0;
- u32 options_length;
- dhcpv6_header_t *dhcpv60;
- dhcpv6_option_t *option;
- vlib_buffer_t *b0;
- dhcp6_report_common_t report;
- dhcp6_address_info_t *addresses = 0;
- dhcp6_prefix_info_t *prefixes = 0;
- u32 next0 = DHCPV6_CLIENT_NEXT_DROP;
- u32 bi0;
- u32 xid;
- u32 sw_if_index;
- u32 iaid;
- u8 client_id_present = 0;
- u8 discard = 0;
- u8 is_pd_packet = 0;
-
- dhcp6_ia_na_client_state_t *ia_na_client_state = NULL;
- dhcp6_pd_client_state_t *pd_client_state = NULL;
-
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- dhcpv60 = vlib_buffer_get_current (b0);
- ip0 = (void *) (b0->data + vnet_buffer (b0)->l3_hdr_offset);
- u32 dhcpv6_ip6_payload_offset =
- (u8 *) dhcpv60 - ((u8 *) ip0 + sizeof (*ip0));
- options_length =
- ntohs (ip0->payload_length) - dhcpv6_ip6_payload_offset -
- sizeof (*dhcpv60);
-
- clib_memset (&report, 0, sizeof (report));
-
- sw_if_index = vnet_buffer (b0)->sw_if_index[VLIB_RX];
- if (sw_if_index >= vec_len (icm->client_state_by_sw_if_index))
- ia_na_client_state = 0;
- else
- ia_na_client_state =
- &icm->client_state_by_sw_if_index[sw_if_index];
- if (sw_if_index >= vec_len (pcm->client_state_by_sw_if_index))
- pd_client_state = 0;
- else
- pd_client_state = &pcm->client_state_by_sw_if_index[sw_if_index];
-
- xid =
- (dhcpv60->xid[0] << 16) + (dhcpv60->xid[1] << 8) +
- dhcpv60->xid[2];
- if (ia_na_client_state && ia_na_client_state->transaction_id == xid)
- is_pd_packet = 0;
- else if (pd_client_state && pd_client_state->transaction_id == xid)
- is_pd_packet = 1;
- else
- {
- clib_warning
- ("Received DHCPv6 message with wrong Transaction ID");
- discard = 1;
- }
-
- report.sw_if_index = sw_if_index;
- report.msg_type = dhcpv60->msg_type;
- report.server_index = ~0;
-
- switch (dhcpv60->msg_type)
- {
- case DHCPV6_MSG_ADVERTISE:
- case DHCPV6_MSG_REPLY:
- option = (dhcpv6_option_t *) (dhcpv60 + 1);
- while (options_length > 0)
- {
- if (options_length <
- ntohs (option->length) + sizeof (*option))
- {
- clib_warning
- ("remaining payload length < option length (%d < %d)",
- options_length,
- ntohs (option->length) + sizeof (*option));
- break;
- }
- u16 oo = ntohs (option->option);
- if (oo == DHCPV6_OPTION_IA_NA || oo == DHCPV6_OPTION_IA_PD)
- {
- u8 discard_option = 0;
- dhcpv6_ia_header_t *ia_header = (void *) option;
- iaid = ntohl (ia_header->iaid);
- u32 T1 = ntohl (ia_header->t1);
- u32 T2 = ntohl (ia_header->t2);
- if (iaid != DHCPV6_CLIENT_IAID)
- discard_option = 1;
- if (T1 != 0 && T2 != 0 && T1 > T2)
- discard_option = 1;
- if (!discard_option)
- {
- report.T1 = T1;
- report.T2 = T2;
- }
- dhcpv6_option_t *inner_option =
- (void *) ia_header->data;
- u16 inner_options_length =
- ntohs (option->length) - (sizeof (*ia_header) -
- sizeof (dhcpv6_option_t));
- while (inner_options_length > 0)
- {
- u16 inner_oo = ntohs (inner_option->option);
- if (discard_option)
- ;
- else if (inner_oo == DHCPV6_OPTION_IAADDR)
- {
- dhcpv6_ia_opt_addr_t *iaaddr =
- (void *) inner_option;
- u32 n_addresses = vec_len (addresses);
- vec_validate (addresses, n_addresses);
- dhcp6_address_info_t *address_info =
- &addresses[n_addresses];
- address_info->preferred_time =
- ntohl (iaaddr->preferred);
- address_info->valid_time =
- ntohl (iaaddr->valid);
- address_info->address = iaaddr->addr;
- }
- else if (inner_oo == DHCPV6_OPTION_IAPREFIX)
- {
- dhcpv6_ia_opt_pd_t *iaprefix =
- (void *) inner_option;
- u32 n_prefixes = vec_len (prefixes);
- vec_validate (prefixes, n_prefixes);
- dhcp6_prefix_info_t *prefix_info =
- &prefixes[n_prefixes];
- prefix_info->preferred_time =
- ntohl (iaprefix->preferred);
- prefix_info->valid_time =
- ntohl (iaprefix->valid);
- prefix_info->prefix_length = iaprefix->prefix;
- prefix_info->prefix = iaprefix->addr;
- }
- else if (inner_oo == DHCPV6_OPTION_STATUS_CODE)
- {
- dhcpv6_status_code_t *sc =
- (void *) inner_option;
- report.inner_status_code =
- ntohs (sc->status_code);
- }
- inner_options_length -=
- sizeof (*inner_option) +
- ntohs (inner_option->length);
- inner_option =
- (void *) ((u8 *) inner_option +
- sizeof (*inner_option) +
- ntohs (inner_option->length));
- }
- }
- else if (oo == DHCPV6_OPTION_CLIENTID)
- {
- if (client_id_present)
- {
- clib_warning
- ("Duplicate Client ID in received DHVPv6 message");
- discard = 1;
- }
- else
- {
- u16 len = ntohs (option->length);
- client_id_present = 1;
- if (len != CLIENT_DUID_LENGTH ||
- 0 != memcmp (option->data,
- client_duid.bin_string,
- CLIENT_DUID_LENGTH))
- {
- clib_warning
- ("Unrecognized client DUID inside received DHVPv6 message");
- discard = 1;
- }
- }
- }
- else if (oo == DHCPV6_OPTION_SERVERID)
- {
- if (report.server_index != ~0)
- {
- clib_warning
- ("Duplicate Server ID in received DHVPv6 message");
- discard = 1;
- }
- else
- {
- u16 ol = ntohs (option->length);
- if (ol - 2 /* 2 byte DUID type code */ > 128)
- {
- clib_warning
- ("Server DUID (without type code) is longer than 128 octets");
- discard = 1;
- }
- else
- {
- report.server_index =
- server_index_get_or_create (option->data, ol);
- }
- }
- }
- else if (oo == DHCPV6_OPTION_PREFERENCE)
- {
- report.preference = option->data[0];
- }
- else if (oo == DHCPV6_OPTION_STATUS_CODE)
- {
- dhcpv6_status_code_t *sc = (void *) option;
- report.status_code = ntohs (sc->status_code);
- }
- options_length -= sizeof (*option) + ntohs (option->length);
- option =
- (void *) ((u8 *) option + sizeof (*option) +
- ntohs (option->length));
- }
-
- if (!client_id_present)
- {
- clib_warning
- ("Missing Client ID in received DHVPv6 message");
- discard = 1;
- }
- if (report.server_index == ~0)
- {
- clib_warning
- ("Missing Server ID in received DHVPv6 message");
- discard = 1;
- }
-
- if (!discard)
- {
- if (!is_pd_packet)
- {
- address_report_t r;
- r.body = report;
- r.n_addresses = vec_len (addresses);
- r.addresses = addresses;
- dhcp6_publish_report (&r);
- /* We just gave addresses to another process! */
- addresses = 0;
- }
- else
- {
- prefix_report_t r;
- r.body = report;
- r.n_prefixes = vec_len (prefixes);
- r.prefixes = prefixes;
- dhcp6_pd_publish_report (&r);
- /* We just gave prefixes to another process! */
- prefixes = 0;
- }
- }
- vec_free (addresses);
- vec_free (prefixes);
-
- break;
- default:
- break;
- }
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcpv6_client_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- }
-
- /* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- return frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcpv6_client_node, static) = {
- .function = dhcpv6_client_node_fn,
- .name = "dhcpv6-client",
- .vector_size = sizeof (u32),
-
- .n_errors = 0,
-
- .n_next_nodes = DHCPV6_CLIENT_N_NEXT,
- .next_nodes = {
- #define _(s,n) [DHCPV6_CLIENT_NEXT_##s] = n,
- foreach_dhcpv6_client
- #undef _
- },
-
- .format_trace = format_dhcpv6_client_trace,
-};
-/* *INDENT-ON* */
-
-void
-dhcp6_clients_enable_disable (u8 enable)
-{
- vlib_main_t *vm = vlib_get_main ();
-
- if (enable)
- {
- if (client_duid.duid_type == 0)
- generate_client_duid ();
- udp_register_dst_port (vm, UDP_DST_PORT_dhcpv6_to_client,
- dhcpv6_client_node.index, 0 /* is_ip6 */ );
- }
- else
- udp_unregister_dst_port (vm, UDP_DST_PORT_dhcpv6_to_client,
- 0 /* is_ip6 */ );
-}
-
-void
- vl_api_dhcp6_clients_enable_disable_t_handler
- (vl_api_dhcp6_clients_enable_disable_t * mp)
-{
- vl_api_dhcp6_clients_enable_disable_reply_t *rmp;
- int rv = 0;
-
- dhcp6_clients_enable_disable (mp->enable);
-
- REPLY_MACRO (VL_API_DHCP6_CLIENTS_ENABLE_DISABLE_REPLY);
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_client_common_dp.h b/src/vnet/dhcp/dhcp6_client_common_dp.h
deleted file mode 100644
index 0acef8408c6..00000000000
--- a/src/vnet/dhcp/dhcp6_client_common_dp.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef included_vnet_dhcp6_client_common_dp_h
-#define included_vnet_dhcp6_client_common_dp_h
-
-#include <vlib/vlib.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/vnet_msg_enum.h>
-#include <vlibapi/api_common.h>
-#include <vlibmemory/api.h>
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_endianfun
-
-/* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define vl_printfun
-#include <vnet/vnet_all_api_h.h>
-#undef vl_printfun
-
-#include <vlibapi/api_helper_macros.h>
-
-typedef struct
-{
- u32 sw_if_index;
- u32 server_index;
- u8 msg_type;
- u32 T1;
- u32 T2;
- u16 inner_status_code;
- u16 status_code;
- u8 preference;
-} dhcp6_report_common_t;
-
-typedef struct
-{
- u8 *data;
- u16 len;
-} server_id_t;
-
-typedef struct
-{
- server_id_t *server_ids;
-} dhcp6_client_common_main_t;
-
-extern dhcp6_client_common_main_t dhcp6_client_common_main;
-
-typedef union
-{
- CLIB_PACKED (struct
- {
- u16 duid_type;
- u16 hardware_type;
- u8 lla[6];
- });
- char bin_string[10];
-} dhcpv6_duid_ll_string_t;
-
-extern dhcpv6_duid_ll_string_t client_duid;
-#define CLIENT_DUID_LENGTH sizeof (client_duid)
-#define DHCPV6_CLIENT_IAID 1
-
-void dhcp6_clients_enable_disable (u8 enable);
-u32 server_index_get_or_create (u8 * data, u16 len);
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-void vl_api_dhcp6_duid_ll_set_t_handler (vl_api_dhcp6_duid_ll_set_t * mp);
-
-static_always_inline f64
-random_f64_from_to (f64 from, f64 to)
-{
- static u32 seed = 0;
- static u8 seed_set = 0;
- if (!seed_set)
- {
- seed = random_default_seed ();
- seed_set = 1;
- }
- return random_f64 (&seed) * (to - from) + from;
-}
-
-static const ip6_address_t all_dhcp6_relay_agents_and_servers = {
- .as_u8 = {
- 0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02}
-};
-
-#endif /* included_vnet_dhcp6_client_common_dp_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_ia_na_client_cp.api b/src/vnet/dhcp/dhcp6_ia_na_client_cp.api
deleted file mode 100644
index caa4fd4afc8..00000000000
--- a/src/vnet/dhcp/dhcp6_ia_na_client_cp.api
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-option version = "1.0.1";
-
-import "vnet/interface_types.api";
-
-/** \brief Enable/disable DHCPv6 client on interface
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param sw_if_index - interface to enable/disable client on
- @param enable - 1 to enable, 0 to disable
-*/
-autoreply define dhcp6_client_enable_disable
-{
- u32 client_index;
- u32 context;
- vl_api_interface_index_t sw_if_index;
- bool enable;
-};
-
-/*
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_ia_na_client_cp.c b/src/vnet/dhcp/dhcp6_ia_na_client_cp.c
deleted file mode 100644
index e440805d707..00000000000
--- a/src/vnet/dhcp/dhcp6_ia_na_client_cp.c
+++ /dev/null
@@ -1,837 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vnet/vnet.h>
-#include <vlibmemory/api.h>
-#include <vnet/vnet_msg_enum.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/dhcp/dhcp6_ia_na_client_dp.h>
-#include <vnet/ip/ip.h>
-#include <vnet/ip/ip6.h>
-#include <float.h>
-#include <math.h>
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_endianfun
-
-#include <vlibapi/api_helper_macros.h>
-
-#define foreach_dhcp6_client_cp_msg \
-_(DHCP6_CLIENT_ENABLE_DISABLE, dhcp6_client_enable_disable)
-
-#define vl_api_dhcp6_client_enable_disable_t_print vl_noop_handler
-
-typedef struct
-{
- u32 sw_if_index;
- ip6_address_t address;
- u32 preferred_lt;
- u32 valid_lt;
- f64 due_time;
-} address_info_t;
-
-typedef struct
-{
- u8 enabled;
- u32 server_index;
- u32 T1;
- u32 T2;
- f64 T1_due_time;
- f64 T2_due_time;
- u32 address_count;
- u8 rebinding;
-} client_state_t;
-
-typedef struct
-{
- address_info_t *address_pool;
- client_state_t *client_state_by_sw_if_index;
- u32 n_clients;
- f64 max_valid_due_time;
-
- /* convenience */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
- api_main_t *api_main;
- u32 node_index;
-} dhcp6_client_cp_main_t;
-
-static dhcp6_client_cp_main_t dhcp6_client_cp_main;
-
-enum
-{
- RD_CP_EVENT_INTERRUPT,
- RD_CP_EVENT_DISABLE,
-};
-
-static void
-send_client_message_start_stop (u32 sw_if_index, u32 server_index,
- u8 msg_type, address_info_t * address_list,
- u8 start)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- dhcp6_send_client_message_params_t params = { 0, };
- dhcp6_send_client_message_params_address_t *addresses = 0, *addr;
- u32 i;
-
- ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
- rm->client_state_by_sw_if_index[sw_if_index].enabled);
- client_state_t *client_state =
- &rm->client_state_by_sw_if_index[sw_if_index];
-
- params.sw_if_index = sw_if_index;
- params.server_index = server_index;
- params.msg_type = msg_type;
- if (start)
- {
- if (msg_type == DHCPV6_MSG_SOLICIT)
- {
- params.irt = 1;
- params.mrt = 120;
- }
- else if (msg_type == DHCPV6_MSG_REQUEST)
- {
- params.irt = 1;
- params.mrt = 30;
- params.mrc = 10;
- }
- else if (msg_type == DHCPV6_MSG_RENEW)
- {
- params.irt = 10;
- params.mrt = 600;
- f64 current_time = vlib_time_now (rm->vlib_main);
- i32 diff_time = client_state->T2 - current_time;
- if (diff_time < 0)
- diff_time = 0;
- params.mrd = diff_time;
- }
- else if (msg_type == DHCPV6_MSG_REBIND)
- {
- params.irt = 10;
- params.mrt = 600;
- f64 current_time = vlib_time_now (rm->vlib_main);
- i32 diff_time = rm->max_valid_due_time - current_time;
- if (diff_time < 0)
- diff_time = 0;
- params.mrd = diff_time;
- }
- else if (msg_type == DHCPV6_MSG_RELEASE)
- {
- params.mrc = 1;
- }
- }
-
- params.T1 = 0;
- params.T2 = 0;
- if (vec_len (address_list) != 0)
- vec_validate (addresses, vec_len (address_list) - 1);
- for (i = 0; i < vec_len (address_list); i++)
- {
- address_info_t *address = &address_list[i];
- addr = &addresses[i];
- addr->valid_lt = address->valid_lt;
- addr->preferred_lt = address->preferred_lt;
- addr->address = address->address;
- }
- params.addresses = addresses;
-
- dhcp6_send_client_message (rm->vlib_main, sw_if_index, !start, &params);
-
- vec_free (params.addresses);
-}
-
-static void interrupt_process (void);
-
-static u32
-ip6_enable (u32 sw_if_index)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- clib_error_t *rv;
-
- rv = enable_ip6_interface (rm->vlib_main, sw_if_index);
-
- return rv != 0;
-}
-
-static u8
-ip6_addresses_equal (ip6_address_t * address1, ip6_address_t * address2)
-{
- if (address1->as_u64[0] != address2->as_u64[0])
- return 0;
- return address1->as_u64[1] == address2->as_u64[1];
-}
-
-static clib_error_t *
-dhcp6_reply_event_handler (vl_api_dhcp6_reply_event_t * mp)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
- client_state_t *client_state;
- ip6_address_t *address;
- u32 sw_if_index;
- u32 n_addresses;
- vl_api_dhcp6_address_info_t *api_address;
- u32 inner_status_code;
- u32 status_code;
- u32 server_index;
- f64 current_time;
- clib_error_t *error = 0;
- u32 i;
-
- current_time = vlib_time_now (vm);
-
- sw_if_index = ntohl (mp->sw_if_index);
-
- if (sw_if_index >= vec_len (rm->client_state_by_sw_if_index))
- return 0;
-
- client_state = &rm->client_state_by_sw_if_index[sw_if_index];
-
- if (!client_state->enabled)
- return 0;
-
- server_index = ntohl (mp->server_index);
-
- n_addresses = ntohl (mp->n_addresses);
-
- inner_status_code = ntohs (mp->inner_status_code);
- status_code = ntohs (mp->status_code);
-
- if (mp->msg_type == DHCPV6_MSG_API_ADVERTISE
- && client_state->server_index == ~0)
- {
- address_info_t *address_list = 0, *address_info;
-
- if (inner_status_code == DHCPV6_STATUS_NOADDRS_AVAIL)
- {
- clib_warning
- ("Advertise message arrived with NoAddrsAvail status code");
- return 0;
- }
-
- if (n_addresses > 0)
- vec_validate (address_list, n_addresses - 1);
- for (i = 0; i < n_addresses; i++)
- {
- api_address = &mp->addresses[i];
- address = (ip6_address_t *) api_address->address;
-
- address_info = &address_list[i];
- address_info->address = *address;
- address_info->preferred_lt = 0;
- address_info->valid_lt = 0;
- }
-
- client_state->server_index = server_index;
-
- send_client_message_start_stop (sw_if_index, server_index,
- DHCPV6_MSG_REQUEST, address_list, 1);
- vec_free (address_list);
- }
-
- if (mp->msg_type != DHCPV6_MSG_API_REPLY)
- return 0;
-
- if (!client_state->rebinding && client_state->server_index != server_index)
- {
- clib_warning ("Reply message arrived with Server ID different "
- "from that in Request or Renew message");
- return 0;
- }
-
- if (inner_status_code == DHCPV6_STATUS_NOADDRS_AVAIL)
- {
- clib_warning ("Reply message arrived with NoAddrsAvail status code");
- if (n_addresses > 0)
- {
- clib_warning
- ("Invalid Reply message arrived: It contains NoAddrsAvail "
- "status code but also contains addresses");
- return 0;
- }
- }
-
- if (status_code == DHCPV6_STATUS_UNSPEC_FAIL)
- {
- clib_warning ("Reply message arrived with UnspecFail status code");
- return 0;
- }
-
- send_client_message_start_stop (sw_if_index, server_index,
- mp->msg_type, 0, 0);
-
- for (i = 0; i < n_addresses; i++)
- {
- address_info_t *address_info = 0;
- u32 valid_time;
- u32 preferred_time;
-
- api_address = &mp->addresses[i];
-
- address = (ip6_address_t *) api_address->address;
-
- if (ip6_address_is_link_local_unicast (address))
- continue;
-
- valid_time = ntohl (api_address->valid_time);
- preferred_time = ntohl (api_address->preferred_time);
-
- if (preferred_time > valid_time)
- continue;
-
- u8 address_already_present = 0;
- /* *INDENT-OFF* */
- pool_foreach (address_info, rm->address_pool,
- ({
- if (address_info->sw_if_index != sw_if_index)
- ;
- else if (!ip6_addresses_equal (&address_info->address, address))
- ;
- else
- {
- address_already_present = 1;
- goto address_pool_foreach_out;
- }
- }));
- /* *INDENT-ON* */
- address_pool_foreach_out:
-
- if (address_already_present)
- {
- address_info->preferred_lt = preferred_time;
- address_info->valid_lt = valid_time;
- address_info->due_time = current_time + valid_time;
- if (address_info->due_time > rm->max_valid_due_time)
- rm->max_valid_due_time = address_info->due_time;
- continue;
- }
-
- if (valid_time == 0)
- continue;
-
- pool_get (rm->address_pool, address_info);
- address_info->sw_if_index = sw_if_index;
- address_info->address = *address;
- address_info->preferred_lt = preferred_time;
- address_info->valid_lt = valid_time;
- address_info->due_time = current_time + valid_time;
- if (address_info->due_time > rm->max_valid_due_time)
- rm->max_valid_due_time = address_info->due_time;
- rm->client_state_by_sw_if_index[sw_if_index].address_count++;
-
- error = ip6_add_del_interface_address (vm, sw_if_index,
- &address_info->address, 64, 0);
- if (error)
- clib_warning ("Failed to add interface address");
- }
-
- client_state->server_index = server_index;
- client_state->T1 = ntohl (mp->T1);
- client_state->T2 = ntohl (mp->T2);
- if (client_state->T1 != 0)
- client_state->T1_due_time = current_time + client_state->T1;
- if (client_state->T2 != 0)
- client_state->T2_due_time = current_time + client_state->T2;
- client_state->rebinding = 0;
-
- interrupt_process ();
-
- return error;
-}
-
-static address_info_t *
-create_address_list (u32 sw_if_index)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- address_info_t *address_info, *address_list = 0;;
-
- /* *INDENT-OFF* */
- pool_foreach (address_info, rm->address_pool,
- ({
- if (address_info->sw_if_index == sw_if_index)
- {
- u32 pos = vec_len (address_list);
- vec_validate (address_list, pos);
- clib_memcpy (&address_list[pos], address_info, sizeof (*address_info));
- }
- }));
- /* *INDENT-ON* */
-
- return address_list;
-}
-
-VNET_DHCP6_REPLY_EVENT_FUNCTION (dhcp6_reply_event_handler);
-
-static uword
-dhcp6_client_cp_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
- vlib_frame_t * f)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- address_info_t *address_info;
- client_state_t *client_state;
- f64 sleep_time = 1e9;
- clib_error_t *error;
- f64 current_time;
- f64 due_time;
- uword event_type;
- uword *event_data = 0;
- int i;
-
- while (1)
- {
- vlib_process_wait_for_event_or_clock (vm, sleep_time);
- event_type = vlib_process_get_events (vm, &event_data);
- vec_reset_length (event_data);
-
- if (event_type == RD_CP_EVENT_DISABLE)
- {
- vlib_node_set_state (vm, rm->node_index, VLIB_NODE_STATE_DISABLED);
- sleep_time = 1e9;
- continue;
- }
-
- current_time = vlib_time_now (vm);
- do
- {
- due_time = current_time + 1e9;
- /* *INDENT-OFF* */
- pool_foreach (address_info, rm->address_pool,
- ({
- if (address_info->due_time > current_time)
- {
- if (address_info->due_time < due_time)
- due_time = address_info->due_time;
- }
- else
- {
- u32 sw_if_index = address_info->sw_if_index;
- error = ip6_add_del_interface_address (vm, sw_if_index,
- &address_info->address,
- 64, 1);
- if (error)
- clib_warning ("Failed to delete interface address");
- pool_put (rm->address_pool, address_info);
- /* make sure ip6 stays enabled */
- ip6_enable (sw_if_index);
- client_state = &rm->client_state_by_sw_if_index[sw_if_index];
- if (--client_state->address_count == 0)
- {
- client_state->rebinding = 0;
- client_state->server_index = ~0;
- send_client_message_start_stop (sw_if_index, ~0,
- DHCPV6_MSG_SOLICIT,
- 0, 1);
- }
- }
- }));
- /* *INDENT-ON* */
- for (i = 0; i < vec_len (rm->client_state_by_sw_if_index); i++)
- {
- client_state_t *cs = &rm->client_state_by_sw_if_index[i];
- if (cs->enabled && cs->server_index != ~0)
- {
- if (cs->T2_due_time > current_time)
- {
- if (cs->T2_due_time < due_time)
- due_time = cs->T2_due_time;
- if (cs->T1_due_time > current_time)
- {
- if (cs->T1_due_time < due_time)
- due_time = cs->T1_due_time;
- }
- else
- {
- cs->T1_due_time = DBL_MAX;
- address_info_t *address_list;
- address_list = create_address_list (i);
- cs->rebinding = 1;
- send_client_message_start_stop (i, cs->server_index,
- DHCPV6_MSG_RENEW,
- address_list, 1);
- vec_free (address_list);
- }
- }
- else
- {
- cs->T2_due_time = DBL_MAX;
- address_info_t *address_list;
- address_list = create_address_list (i);
- cs->rebinding = 1;
- send_client_message_start_stop (i, ~0,
- DHCPV6_MSG_REBIND,
- address_list, 1);
- vec_free (address_list);
- }
- }
- }
- current_time = vlib_time_now (vm);
- }
- while (due_time < current_time);
-
- sleep_time = due_time - current_time;
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp6_client_cp_process_node) = {
- .function = dhcp6_client_cp_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dhcp6-client-cp-process",
-};
-/* *INDENT-ON* */
-
-static void
-interrupt_process (void)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
-
- vlib_process_signal_event (vm, dhcp6_client_cp_process_node.index,
- RD_CP_EVENT_INTERRUPT, 0);
-}
-
-static void
-disable_process (void)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
-
- vlib_process_signal_event (vm, dhcp6_client_cp_process_node.index,
- RD_CP_EVENT_DISABLE, 0);
-}
-
-static void
-enable_process (void)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
- vlib_node_t *node;
-
- node = vec_elt (vm->node_main.nodes, rm->node_index);
-
- vlib_node_set_state (vm, rm->node_index, VLIB_NODE_STATE_POLLING);
- vlib_start_process (vm, node->runtime_index);
-}
-
-static clib_error_t *
-dhcp6_addresses_show_command_function (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- dhcp6_client_cp_main_t *dm = &dhcp6_client_cp_main;
- clib_error_t *error = 0;
- address_info_t *address_info;
- f64 current_time = vlib_time_now (vm);
-
- /* *INDENT-OFF* */
- pool_foreach (address_info, dm->address_pool,
- ({
- vlib_cli_output (vm, "address: %U, "
- "preferred lifetime: %u, valid lifetime: %u "
- "(%f remaining)",
- format_ip6_address, &address_info->address,
- address_info->preferred_lt, address_info->valid_lt,
- address_info->due_time - current_time);
- }));
- /* *INDENT-ON* */
-
- return error;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp6_addresses_show_command, static) = {
- .path = "show dhcp6 addresses",
- .short_help = "show dhcp6 addresses",
- .function = dhcp6_addresses_show_command_function,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcp6_clients_show_command_function (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- clib_error_t *error = 0;
- client_state_t *cs;
- f64 current_time = vlib_time_now (vm);
- char buf1[256];
- char buf2[256];
- const char *rebinding;
- u32 i;
-
- for (i = 0; i < vec_len (rm->client_state_by_sw_if_index); i++)
- {
- cs = &rm->client_state_by_sw_if_index[i];
- if (cs->enabled)
- {
- if (cs->T1_due_time != DBL_MAX && cs->T1_due_time > current_time)
- {
- sprintf (buf1, "%u remaining",
- (u32) round (cs->T1_due_time - current_time));
- }
- else
- sprintf (buf1, "timeout");
- if (cs->T2_due_time != DBL_MAX && cs->T2_due_time > current_time)
- sprintf (buf2, "%u remaining",
- (u32) round (cs->T2_due_time - current_time));
- else
- sprintf (buf2, "timeout");
- if (cs->rebinding)
- rebinding = ", REBINDING";
- else
- rebinding = "";
- if (cs->T1)
- vlib_cli_output (vm,
- "sw_if_index: %u, T1: %u (%s), "
- "T2: %u (%s), server index: %d%s", i,
- cs->T1, buf1, cs->T2, buf2,
- cs->server_index, rebinding);
- else
- vlib_cli_output (vm, "sw_if_index: %u%s", i, rebinding);
- }
- }
-
- return error;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp6_clients_show_command, static) = {
- .path = "show dhcp6 clients",
- .short_help = "show dhcp6 clients",
- .function = dhcp6_clients_show_command_function,
-};
-/* *INDENT-ON* */
-
-static int
-dhcp6_client_enable_disable (u32 sw_if_index, u8 enable)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- vnet_main_t *vnm = rm->vnet_main;
- vlib_main_t *vm = rm->vlib_main;
- client_state_t *client_state;
- client_state_t empty_config = { 0 };
- address_info_t *address_info;
- clib_error_t *error;
-
- if (!vnet_sw_interface_is_api_valid (vnm, sw_if_index))
- {
- clib_warning ("Invalid sw_if_index");
- return 1;
- }
-
- vec_validate_init_empty (rm->client_state_by_sw_if_index, sw_if_index,
- empty_config);
- client_state = &rm->client_state_by_sw_if_index[sw_if_index];
-
- u8 old_enabled = client_state->enabled;
- if (enable)
- client_state->enabled = 1;
- client_state->server_index = ~0;
-
- if (!old_enabled && enable)
- {
- rm->n_clients++;
- if (rm->n_clients == 1)
- {
- enable_process ();
- dhcp6_clients_enable_disable (1);
- }
-
- ip6_enable (sw_if_index);
- send_client_message_start_stop (sw_if_index, ~0, DHCPV6_MSG_SOLICIT,
- 0, 1);
- }
- else if (old_enabled && !enable)
- {
- send_client_message_start_stop (sw_if_index, ~0, ~0, 0, 0);
-
- rm->n_clients--;
- if (rm->n_clients == 0)
- {
- dhcp6_clients_enable_disable (0);
- disable_process ();
- }
-
- /* *INDENT-OFF* */
- pool_foreach (address_info, rm->address_pool,
- ({
- if (address_info->sw_if_index == sw_if_index)
- {
- ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
- rm->client_state_by_sw_if_index[sw_if_index].enabled);
- client_state_t *client_state =
- &rm->client_state_by_sw_if_index[sw_if_index];
- send_client_message_start_stop (sw_if_index,
- client_state->server_index,
- DHCPV6_MSG_RELEASE, address_info,
- 1);
- error = ip6_add_del_interface_address (vm, sw_if_index,
- &address_info->address,
- 64, 1);
- if (error)
- clib_warning ("Failed to delete interface address");
- pool_put (rm->address_pool, address_info);
- }
- }));
- /* *INDENT-ON* */
- }
-
- if (!enable)
- client_state->enabled = 0;
-
- return 0;
-}
-
-static clib_error_t *
-dhcp6_client_enable_disable_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- vnet_main_t *vnm = rm->vnet_main;
- clib_error_t *error = 0;
- u32 sw_if_index = ~0;
- u8 enable = 1;
- unformat_input_t _line_input, *line_input = &_line_input;
-
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
- ;
- else if (unformat (line_input, "disable"))
- enable = 0;
- else
- {
- error = clib_error_return (0, "unexpected input `%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
- unformat_free (line_input);
-
- if (sw_if_index != ~0)
- {
- if (dhcp6_client_enable_disable (sw_if_index, enable) != 0)
- error = clib_error_return (0, "Invalid sw_if_index");
- }
- else
- error = clib_error_return (0, "Missing sw_if_index");
-
-done:
- return error;
-}
-
-/*?
- * This command is used to enable/disable DHCPv6 client
- * on particular interface.
- *
- * @cliexpar
- * @parblock
- * Example of how to enable DHCPv6 client:
- * @cliexcmd{dhcp6 client GigabitEthernet2/0/0}
- * Example of how to disable DHCPv6 client:
- * @cliexcmd{dhcp6 client GigabitEthernet2/0/0 disable}
- * @endparblock
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp6_client_enable_disable_command, static) = {
- .path = "dhcp6 client",
- .short_help = "dhcp6 client <interface> [disable]",
- .function = dhcp6_client_enable_disable_command_fn,
-};
-/* *INDENT-ON* */
-
-static void
- vl_api_dhcp6_client_enable_disable_t_handler
- (vl_api_dhcp6_client_enable_disable_t * mp)
-{
- vl_api_dhcp6_client_enable_disable_reply_t *rmp;
- u32 sw_if_index;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- sw_if_index = ntohl (mp->sw_if_index);
-
- rv = dhcp6_client_enable_disable (sw_if_index, mp->enable);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO (VL_API_SW_INTERFACE_SET_TABLE_REPLY);
-}
-
-#define vl_msg_name_crc_list
-#include <vnet/dhcp/dhcp6_ia_na_client_cp.api.h>
-#undef vl_msg_name_crc_list
-
-static void
-setup_message_id_table (api_main_t * am)
-{
-#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
- foreach_vl_msg_name_crc_dhcp6_ia_na_client_cp;
-#undef _
-}
-
-static clib_error_t *
-dhcp_client_cp_init (vlib_main_t * vm)
-{
- dhcp6_client_cp_main_t *rm = &dhcp6_client_cp_main;
- api_main_t *am = &api_main;
-
- rm->vlib_main = vm;
- rm->vnet_main = vnet_get_main ();
- rm->api_main = am;
- rm->node_index = dhcp6_client_cp_process_node.index;
-
-#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N, #n, \
- vl_api_##n##_t_handler, \
- vl_noop_handler, \
- vl_api_##n##_t_endian, \
- vl_api_##n##_t_print, \
- sizeof(vl_api_##n##_t), 0/* do NOT trace! */);
- foreach_dhcp6_client_cp_msg;
-#undef _
-
- /*
- * Set up the (msg_name, crc, message-id) table
- */
- setup_message_id_table (am);
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (dhcp_client_cp_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_ia_na_client_dp.c b/src/vnet/dhcp/dhcp6_ia_na_client_dp.c
deleted file mode 100644
index f49017b0236..00000000000
--- a/src/vnet/dhcp/dhcp6_ia_na_client_dp.c
+++ /dev/null
@@ -1,658 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vlib/vlib.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/mfib/mfib_table.h>
-#include <vnet/mfib/ip6_mfib.h>
-#include <vnet/fib/fib.h>
-#include <vnet/adj/adj_mcast.h>
-#include <vnet/ip/ip6_neighbor.h>
-#include <vlibapi/api_common.h>
-#include <vlibmemory/api.h>
-#include <vnet/dhcp/dhcp6_ia_na_client_dp.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-#include <vnet/ip/ip_types_api.h>
-
-#include <vnet/vnet_msg_enum.h>
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_endianfun
-
-/* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define vl_printfun
-#include <vnet/vnet_all_api_h.h>
-#undef vl_printfun
-
-#include <vlibapi/api_helper_macros.h>
-
-dhcp6_ia_na_client_main_t dhcp6_ia_na_client_main;
-dhcp6_ia_na_client_public_main_t dhcp6_ia_na_client_public_main;
-
-static void
-signal_report (address_report_t * r)
-{
- vlib_main_t *vm = vlib_get_main ();
- dhcp6_ia_na_client_main_t *cm = &dhcp6_ia_na_client_main;
- uword ni = cm->publisher_node;
- uword et = cm->publisher_et;
-
- if (ni == (uword) ~ 0)
- return;
- address_report_t *q =
- vlib_process_signal_event_data (vm, ni, et, 1, sizeof *q);
-
- *q = *r;
-}
-
-int
-dhcp6_publish_report (address_report_t * r)
-{
- void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
- vl_api_rpc_call_main_thread (signal_report, (u8 *) r, sizeof *r);
- return 0;
-}
-
-void
-dhcp6_set_publisher_node (uword node_index, uword event_type)
-{
- dhcp6_ia_na_client_main_t *cm = &dhcp6_ia_na_client_main;
- cm->publisher_node = node_index;
- cm->publisher_et = event_type;
-}
-
-static void
-stop_sending_client_message (vlib_main_t * vm,
- dhcp6_ia_na_client_state_t * client_state)
-{
- u32 bi0;
-
- client_state->keep_sending_client_message = 0;
- vec_free (client_state->params.addresses);
- if (client_state->buffer)
- {
- bi0 = vlib_get_buffer_index (vm, client_state->buffer);
- vlib_buffer_free (vm, &bi0, 1);
- client_state->buffer = 0;
- adj_unlock (client_state->adj_index);
- client_state->adj_index = ~0;
- }
-}
-
-static vlib_buffer_t *
-create_buffer_for_client_message (vlib_main_t * vm, u32 sw_if_index,
- dhcp6_ia_na_client_state_t * client_state,
- u32 type)
-{
- dhcp6_client_common_main_t *ccm = &dhcp6_client_common_main;
- vnet_main_t *vnm = vnet_get_main ();
-
- vlib_buffer_t *b;
- u32 bi;
- ip6_header_t *ip;
- udp_header_t *udp;
- dhcpv6_header_t *dhcp;
- ip6_address_t src_addr;
- u32 dhcp_opt_len = 0;
- client_state->transaction_start = vlib_time_now (vm);
- u32 n_addresses;
- u32 i;
-
- vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
- vnet_sw_interface_t *sup_sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
- vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
-
- /* Interface(s) down? */
- if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
- return NULL;
- if ((sup_sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
- return NULL;
- if ((sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
- return NULL;
-
- /* Get a link-local address */
- src_addr = ip6_neighbor_get_link_local_address (sw_if_index);
-
- if (src_addr.as_u8[0] != 0xfe)
- {
- clib_warning ("Could not find source address to send DHCPv6 packet");
- return NULL;
- }
-
- if (vlib_buffer_alloc (vm, &bi, 1) != 1)
- {
- clib_warning ("Buffer allocation failed");
- return NULL;
- }
-
- b = vlib_get_buffer (vm, bi);
- vnet_buffer (b)->sw_if_index[VLIB_RX] = sw_if_index;
- vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
- client_state->adj_index = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6,
- VNET_LINK_IP6,
- sw_if_index);
- vnet_buffer (b)->ip.adj_index[VLIB_TX] = client_state->adj_index;
- b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
-
- ip = (ip6_header_t *) vlib_buffer_get_current (b);
- udp = (udp_header_t *) (ip + 1);
- dhcp = (dhcpv6_header_t *) (udp + 1);
-
- ip->src_address = src_addr;
- ip->hop_limit = 255;
- ip->ip_version_traffic_class_and_flow_label =
- clib_host_to_net_u32 (0x6 << 28);
- ip->payload_length = 0;
- ip->protocol = IP_PROTOCOL_UDP;
-
- udp->src_port = clib_host_to_net_u16 (DHCPV6_CLIENT_PORT);
- udp->dst_port = clib_host_to_net_u16 (DHCPV6_SERVER_PORT);
- udp->checksum = 0;
- udp->length = 0;
-
- dhcp->msg_type = type;
- dhcp->xid[0] = (client_state->transaction_id & 0x00ff0000) >> 16;
- dhcp->xid[1] = (client_state->transaction_id & 0x0000ff00) >> 8;
- dhcp->xid[2] = (client_state->transaction_id & 0x000000ff) >> 0;
-
- void *d = (void *) dhcp->data;
- dhcpv6_option_t *duid;
- dhcpv6_elapsed_t *elapsed;
- dhcpv6_ia_header_t *ia_hdr;
- dhcpv6_ia_opt_addr_t *opt_addr;
- if (type == DHCPV6_MSG_SOLICIT || type == DHCPV6_MSG_REQUEST ||
- type == DHCPV6_MSG_RENEW || type == DHCPV6_MSG_REBIND ||
- type == DHCPV6_MSG_RELEASE)
- {
- duid = (dhcpv6_option_t *) d;
- duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_CLIENTID);
- duid->length = clib_host_to_net_u16 (CLIENT_DUID_LENGTH);
- clib_memcpy (duid + 1, client_duid.bin_string, CLIENT_DUID_LENGTH);
- d += sizeof (*duid) + CLIENT_DUID_LENGTH;
-
- if (client_state->params.server_index != ~0)
- {
- server_id_t *se =
- &ccm->server_ids[client_state->params.server_index];
-
- duid = (dhcpv6_option_t *) d;
- duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_SERVERID);
- duid->length = clib_host_to_net_u16 (se->len);
- clib_memcpy (duid + 1, se->data, se->len);
- d += sizeof (*duid) + se->len;
- }
-
- elapsed = (dhcpv6_elapsed_t *) d;
- elapsed->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_ELAPSED_TIME);
- elapsed->opt.length =
- clib_host_to_net_u16 (sizeof (*elapsed) - sizeof (elapsed->opt));
- elapsed->elapsed_10ms = 0;
- client_state->elapsed_pos =
- (char *) &elapsed->elapsed_10ms -
- (char *) vlib_buffer_get_current (b);
- d += sizeof (*elapsed);
-
- ia_hdr = (dhcpv6_ia_header_t *) d;
- ia_hdr->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IA_NA);
- ia_hdr->iaid = clib_host_to_net_u32 (DHCPV6_CLIENT_IAID);
- ia_hdr->t1 = clib_host_to_net_u32 (client_state->params.T1);
- ia_hdr->t2 = clib_host_to_net_u32 (client_state->params.T2);
- d += sizeof (*ia_hdr);
-
- n_addresses = vec_len (client_state->params.addresses);
-
- ia_hdr->opt.length =
- clib_host_to_net_u16 (sizeof (*ia_hdr) +
- n_addresses * sizeof (*opt_addr) -
- sizeof (ia_hdr->opt));
-
- for (i = 0; i < n_addresses; i++)
- {
- dhcp6_send_client_message_params_address_t *addr =
- &client_state->params.addresses[i];
- opt_addr = (dhcpv6_ia_opt_addr_t *) d;
- opt_addr->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IAADDR);
- opt_addr->opt.length =
- clib_host_to_net_u16 (sizeof (*opt_addr) -
- sizeof (opt_addr->opt));
- opt_addr->addr = addr->address;
- opt_addr->valid = clib_host_to_net_u32 (addr->valid_lt);
- opt_addr->preferred = clib_host_to_net_u32 (addr->preferred_lt);
- d += sizeof (*opt_addr);
- }
- }
- else
- {
- clib_warning ("State not implemented");
- }
-
- dhcp_opt_len = ((u8 *) d) - dhcp->data;
- udp->length =
- clib_host_to_net_u16 (sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len);
- ip->payload_length = udp->length;
- b->current_length =
- sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len;
-
- ip->dst_address = all_dhcp6_relay_agents_and_servers;
-
- return b;
-}
-
-static inline u8
-check_send_client_message (vlib_main_t * vm,
- dhcp6_ia_na_client_state_t * client_state,
- f64 current_time, f64 * due_time)
-{
- vlib_buffer_t *p0;
- vlib_frame_t *f;
- u32 *to_next;
- u32 next_index;
- vlib_buffer_t *c0;
- ip6_header_t *ip;
- udp_header_t *udp;
- u32 ci0;
- int bogus_length = 0;
-
- dhcp6_send_client_message_params_t *params;
-
- f64 now = vlib_time_now (vm);
-
- if (!client_state->keep_sending_client_message)
- return false;
-
- params = &client_state->params;
-
- if (client_state->due_time > current_time)
- {
- *due_time = client_state->due_time;
- return true;
- }
-
- p0 = client_state->buffer;
-
- next_index = ip6_rewrite_mcast_node.index;
-
- c0 = vlib_buffer_copy (vm, p0);
- ci0 = vlib_get_buffer_index (vm, c0);
-
- ip = (ip6_header_t *) vlib_buffer_get_current (c0);
- udp = (udp_header_t *) (ip + 1);
-
- u16 *elapsed_field = (u16 *) ((void *) ip + client_state->elapsed_pos);
- *elapsed_field =
- clib_host_to_net_u16 ((u16)
- ((now - client_state->transaction_start) * 100));
-
- udp->checksum = 0;
- udp->checksum =
- ip6_tcp_udp_icmp_compute_checksum (vm, 0, ip, &bogus_length);
-
- f = vlib_get_frame_to_node (vm, next_index);
- to_next = vlib_frame_vector_args (f);
- to_next[0] = ci0;
- f->n_vectors = 1;
- vlib_put_frame_to_node (vm, next_index, f);
-
- if (params->mrc != 0 && --client_state->n_left == 0)
- stop_sending_client_message (vm, client_state);
- else
- {
- client_state->sleep_interval =
- (2 + random_f64_from_to (-0.1, 0.1)) * client_state->sleep_interval;
- if (client_state->sleep_interval > params->mrt)
- client_state->sleep_interval =
- (1 + random_f64_from_to (-0.1, 0.1)) * params->mrt;
-
- client_state->due_time = current_time + client_state->sleep_interval;
-
- if (params->mrd != 0
- && current_time > client_state->start_time + params->mrd)
- stop_sending_client_message (vm, client_state);
- else
- *due_time = client_state->due_time;
- }
-
- return client_state->keep_sending_client_message;
-}
-
-static uword
-send_dhcp6_client_message_process (vlib_main_t * vm,
- vlib_node_runtime_t * rt,
- vlib_frame_t * f0)
-{
- dhcp6_ia_na_client_main_t *cm = &dhcp6_ia_na_client_main;
- dhcp6_ia_na_client_state_t *client_state;
- uword *event_data = 0;
- f64 sleep_time = 1e9;
- f64 current_time;
- f64 due_time;
- f64 dt = 0;
- int i;
-
- while (true)
- {
- vlib_process_wait_for_event_or_clock (vm, sleep_time);
- vlib_process_get_events (vm, &event_data);
- vec_reset_length (event_data);
-
- current_time = vlib_time_now (vm);
- do
- {
- due_time = current_time + 1e9;
- for (i = 0; i < vec_len (cm->client_state_by_sw_if_index); i++)
- {
- client_state = &cm->client_state_by_sw_if_index[i];
- if (!client_state->entry_valid)
- continue;
- if (check_send_client_message
- (vm, client_state, current_time, &dt) && (dt < due_time))
- due_time = dt;
- }
- current_time = vlib_time_now (vm);
- }
- while (due_time < current_time);
-
- sleep_time = due_time - current_time;
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (send_dhcp6_client_message_process_node, static) = {
- .function = send_dhcp6_client_message_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "send-dhcp6-client-message-process",
-};
-/* *INDENT-ON* */
-
-void
-dhcp6_send_client_message (vlib_main_t * vm, u32 sw_if_index, u8 stop,
- dhcp6_send_client_message_params_t * params)
-{
- dhcp6_ia_na_client_main_t *cm = &dhcp6_ia_na_client_main;
- dhcp6_ia_na_client_state_t *client_state = 0;
- dhcp6_ia_na_client_state_t empty_state = { 0, };
-
- ASSERT (~0 != sw_if_index);
-
- vec_validate_init_empty (cm->client_state_by_sw_if_index, sw_if_index,
- empty_state);
- client_state = &cm->client_state_by_sw_if_index[sw_if_index];
- if (!client_state->entry_valid)
- {
- client_state->entry_valid = 1;
- client_state->adj_index = ~0;
- }
-
- stop_sending_client_message (vm, client_state);
-
- if (!stop)
- {
- client_state->keep_sending_client_message = 1;
- vec_free (client_state->params.addresses);
- client_state->params = *params;
- client_state->params.addresses = vec_dup (params->addresses);
- client_state->n_left = params->mrc;
- client_state->start_time = vlib_time_now (vm);
- client_state->sleep_interval =
- (1 + random_f64_from_to (-0.1, 0.1)) * params->irt;
- client_state->due_time = 0; /* send first packet ASAP */
- client_state->transaction_id = random_u32 (&cm->seed) & 0x00ffffff;
- client_state->buffer =
- create_buffer_for_client_message (vm, sw_if_index, client_state,
- params->msg_type);
- if (!client_state->buffer)
- client_state->keep_sending_client_message = 0;
- else
- vlib_process_signal_event (vm,
- send_dhcp6_client_message_process_node.index,
- 1, 0);
- }
-}
-
-void
- vl_api_dhcp6_send_client_message_t_handler
- (vl_api_dhcp6_send_client_message_t * mp)
-{
- vl_api_dhcp6_send_client_message_reply_t *rmp;
- dhcp6_send_client_message_params_t params;
- vlib_main_t *vm = vlib_get_main ();
- u32 n_addresses;
- u32 i;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- BAD_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_DHCP6_SEND_CLIENT_MESSAGE_REPLY);
-
- if (rv != 0)
- return;
-
- params.sw_if_index = ntohl (mp->sw_if_index);
- params.server_index = ntohl (mp->server_index);
- params.irt = ntohl (mp->irt);
- params.mrt = ntohl (mp->mrt);
- params.mrc = ntohl (mp->mrc);
- params.mrd = ntohl (mp->mrd);
- params.msg_type = ntohl (mp->msg_type);
- params.T1 = ntohl (mp->T1);
- params.T2 = ntohl (mp->T2);
- n_addresses = ntohl (mp->n_addresses);
- params.addresses = 0;
- if (n_addresses > 0)
- vec_validate (params.addresses, n_addresses - 1);
- for (i = 0; i < n_addresses; i++)
- {
- vl_api_dhcp6_address_info_t *ai = &mp->addresses[i];
- dhcp6_send_client_message_params_address_t *addr = &params.addresses[i];
- addr->preferred_lt = ntohl (ai->preferred_time);
- addr->valid_lt = ntohl (ai->valid_time);
- ip6_address_decode (ai->address, &addr->address);
- }
-
- dhcp6_send_client_message (vm, ntohl (mp->sw_if_index), mp->stop, &params);
-}
-
-clib_error_t *
-call_dhcp6_reply_event_callbacks (void *data,
- _vnet_dhcp6_reply_event_function_list_elt_t
- * elt)
-{
- clib_error_t *error = 0;
-
- while (elt)
- {
- error = elt->fp (data);
- if (error)
- return error;
- elt = elt->next_dhcp6_reply_event_function;
- }
-
- return error;
-}
-
-static uword
-dhcp6_reply_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
- vlib_frame_t * f)
-{
- /* These cross the longjmp boundary (vlib_process_wait_for_event)
- * and need to be volatile - to prevent them from being optimized into
- * a register - which could change during suspension */
-
- while (1)
- {
- vlib_process_wait_for_event (vm);
- uword event_type = DHCP6_DP_REPLY_REPORT;
- void *event_data = vlib_process_get_event_data (vm, &event_type);
-
- int i;
- if (event_type == DHCP6_DP_REPLY_REPORT)
- {
- address_report_t *events = event_data;
- for (i = 0; i < vec_len (events); i++)
- {
- u32 event_size =
- sizeof (vl_api_dhcp6_reply_event_t) +
- vec_len (events[i].addresses) *
- sizeof (vl_api_dhcp6_address_info_t);
- vl_api_dhcp6_reply_event_t *event = clib_mem_alloc (event_size);
- clib_memset (event, 0, event_size);
-
- event->sw_if_index = htonl (events[i].body.sw_if_index);
- event->server_index = htonl (events[i].body.server_index);
- event->msg_type = events[i].body.msg_type;
- event->T1 = htonl (events[i].body.T1);
- event->T2 = htonl (events[i].body.T2);
- event->inner_status_code =
- htons (events[i].body.inner_status_code);
- event->status_code = htons (events[i].body.status_code);
- event->preference = events[i].body.preference;
-
- event->n_addresses = htonl (vec_len (events[i].addresses));
- vl_api_dhcp6_address_info_t *address =
- (typeof (address)) event->addresses;
- u32 j;
- for (j = 0; j < vec_len (events[i].addresses); j++)
- {
- dhcp6_address_info_t *info = &events[i].addresses[j];
- ip6_address_encode (&info->address, address->address);
- address->valid_time = htonl (info->valid_time);
- address->preferred_time = htonl (info->preferred_time);
- address++;
- }
- vec_free (events[i].addresses);
-
- dhcp6_ia_na_client_public_main_t *dcpm =
- &dhcp6_ia_na_client_public_main;
- call_dhcp6_reply_event_callbacks (event, dcpm->functions);
-
- vpe_client_registration_t *reg;
- /* *INDENT-OFF* */
- pool_foreach(reg, vpe_api_main.dhcp6_reply_events_registrations,
- ({
- vl_api_registration_t *vl_reg;
- vl_reg =
- vl_api_client_index_to_registration (reg->client_index);
- if (vl_reg && vl_api_can_send_msg (vl_reg))
- {
- vl_api_dhcp6_reply_event_t *msg =
- vl_msg_api_alloc (event_size);
- clib_memcpy (msg, event, event_size);
- msg->_vl_msg_id = htons (VL_API_DHCP6_REPLY_EVENT);
- msg->client_index = reg->client_index;
- msg->pid = reg->client_pid;
- vl_api_send_msg (vl_reg, (u8 *) msg);
- }
- }));
- /* *INDENT-ON* */
-
- clib_mem_free (event);
- }
- }
- vlib_process_put_event_data (vm, event_data);
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp6_reply_process_node) = {
- .function = dhcp6_reply_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dhcp6-reply-publisher-process",
-};
-/* *INDENT-ON* */
-
-void
- vl_api_want_dhcp6_reply_events_t_handler
- (vl_api_want_dhcp6_reply_events_t * mp)
-{
- vpe_api_main_t *am = &vpe_api_main;
- vl_api_want_dhcp6_reply_events_reply_t *rmp;
- int rv = 0;
-
- uword *p =
- hash_get (am->dhcp6_reply_events_registration_hash, mp->client_index);
- vpe_client_registration_t *rp;
- if (p)
- {
- if (mp->enable_disable)
- {
- clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto reply;
- }
- else
- {
- rp = pool_elt_at_index (am->dhcp6_reply_events_registrations, p[0]);
- pool_put (am->dhcp6_reply_events_registrations, rp);
- hash_unset (am->dhcp6_reply_events_registration_hash,
- mp->client_index);
- if (pool_elts (am->dhcp6_reply_events_registrations) == 0)
- dhcp6_set_publisher_node (~0, DHCP6_DP_REPORT_MAX);
- goto reply;
- }
- }
- if (mp->enable_disable == 0)
- {
- clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto reply;
- }
- pool_get (am->dhcp6_reply_events_registrations, rp);
- rp->client_index = mp->client_index;
- rp->client_pid = ntohl (mp->pid);
- hash_set (am->dhcp6_reply_events_registration_hash, rp->client_index,
- rp - am->dhcp6_reply_events_registrations);
- dhcp6_set_publisher_node (dhcp6_reply_process_node.index,
- DHCP6_DP_REPLY_REPORT);
-
-reply:
- REPLY_MACRO (VL_API_WANT_DHCP6_REPLY_EVENTS_REPLY);
-}
-
-static clib_error_t *
-dhcp6_client_init (vlib_main_t * vm)
-{
- dhcp6_ia_na_client_main_t *cm = &dhcp6_ia_na_client_main;
-
- cm->vlib_main = vm;
- cm->vnet_main = vnet_get_main ();
-
- cm->publisher_node = ~0;
-
- cm->seed = 0xdeaccabe;
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (dhcp6_client_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_ia_na_client_dp.h b/src/vnet/dhcp/dhcp6_ia_na_client_dp.h
deleted file mode 100644
index a866479fbaf..00000000000
--- a/src/vnet/dhcp/dhcp6_ia_na_client_dp.h
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef included_vnet_dhcp6_client_dp_h
-#define included_vnet_dhcp6_client_dp_h
-
-#include <vlib/vlib.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-
-typedef struct
-{
- u32 preferred_lt;
- u32 valid_lt;
- ip6_address_t address;
-} dhcp6_send_client_message_params_address_t;
-
-typedef struct
-{
- u32 sw_if_index;
- u32 server_index;
- u32 irt;
- u32 mrt;
- u32 mrc;
- u32 mrd;
- u8 msg_type;
- u32 T1;
- u32 T2;
- dhcp6_send_client_message_params_address_t *addresses;
-} dhcp6_send_client_message_params_t;
-
-typedef struct
-{
- u8 entry_valid;
- u8 keep_sending_client_message; /* when true then next fields are valid */
- dhcp6_send_client_message_params_t params;
- f64 transaction_start;
- f64 sleep_interval;
- f64 due_time;
- u32 n_left;
- f64 start_time;
- u32 transaction_id;
- vlib_buffer_t *buffer;
- u32 elapsed_pos;
- u32 adj_index;
-} dhcp6_ia_na_client_state_t;
-
-typedef struct
-{
- dhcp6_ia_na_client_state_t *client_state_by_sw_if_index;
-
- uword publisher_node;
- uword publisher_et;
-
- u32 seed;
-
- /* convenience */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
-} dhcp6_ia_na_client_main_t;
-
-extern dhcp6_ia_na_client_main_t dhcp6_ia_na_client_main;
-
-typedef struct
-{
- ip6_address_t address;
- u32 valid_time;
- u32 preferred_time;
- u16 status_code;
-} dhcp6_address_info_t;
-
-typedef struct
-{
- dhcp6_report_common_t body;
- u32 n_addresses;
- dhcp6_address_info_t *addresses;
-} address_report_t;
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-void dhcp6_send_client_message (vlib_main_t * vm, u32 sw_if_index, u8 stop,
- dhcp6_send_client_message_params_t * params);
-void dhcp6_set_publisher_node (uword node_index, uword event_type);
-int dhcp6_publish_report (address_report_t * r);
-
-
-void
- vl_api_want_dhcp6_reply_events_t_handler
- (vl_api_want_dhcp6_reply_events_t * mp);
-void
- vl_api_dhcp6_send_client_message_t_handler
- (vl_api_dhcp6_send_client_message_t * mp);
-void
- vl_api_dhcp6_clients_enable_disable_t_handler
- (vl_api_dhcp6_clients_enable_disable_t * mp);
-
-extern vlib_node_registration_t dhcp6_reply_process_node;
-
-enum
-{ DHCP6_DP_REPLY_REPORT, DHCP6_DP_REPORT_MAX };
-
-typedef struct _vnet_dhcp6_reply_function_list_elt
-{
- struct _vnet_dhcp6_reply_function_list_elt *next_dhcp6_reply_event_function;
- clib_error_t *(*fp) (vl_api_dhcp6_reply_event_t * mp);
-} _vnet_dhcp6_reply_event_function_list_elt_t;
-
-typedef struct
-{
- _vnet_dhcp6_reply_event_function_list_elt_t *functions;
-} dhcp6_ia_na_client_public_main_t;
-
-extern dhcp6_ia_na_client_public_main_t dhcp6_ia_na_client_public_main;
-
-#define VNET_DHCP6_REPLY_EVENT_FUNCTION(f) \
- \
-static void __vnet_dhcp6_reply_event_function_init_##f (void) \
- __attribute__((__constructor__)) ; \
- \
-static void __vnet_dhcp6_reply_event_function_init_##f (void) \
-{ \
- dhcp6_ia_na_client_public_main_t * nm = &dhcp6_ia_na_client_public_main; \
- static _vnet_dhcp6_reply_event_function_list_elt_t init_function; \
- init_function.next_dhcp6_reply_event_function = nm->functions; \
- nm->functions = &init_function; \
- init_function.fp = (void *) &f; \
-} \
- \
-static void __vnet_dhcp6_reply_event_function_deinit_##f (void) \
- __attribute__((__destructor__)) ; \
- \
-static void __vnet_dhcp6_reply_event_function_deinit_##f (void) \
-{ \
- dhcp6_ia_na_client_public_main_t * nm = &dhcp6_ia_na_client_public_main; \
- _vnet_dhcp6_reply_event_function_list_elt_t *next; \
- if (nm->functions->fp == (void *) &f) \
- { \
- nm->functions = \
- nm->functions->next_dhcp6_reply_event_function; \
- return; \
- } \
- next = nm->functions; \
- while (next->next_dhcp6_reply_event_function) \
- { \
- if (next->next_dhcp6_reply_event_function->fp == (void *) &f) \
- { \
- next->next_dhcp6_reply_event_function = \
- next->next_dhcp6_reply_event_function->next_dhcp6_reply_event_function; \
- return; \
- } \
- next = next->next_dhcp6_reply_event_function; \
- } \
-}
-
-#endif /* included_vnet_dhcp6_client_dp_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_packet.h b/src/vnet/dhcp/dhcp6_packet.h
deleted file mode 100644
index d5467952a64..00000000000
--- a/src/vnet/dhcp/dhcp6_packet.h
+++ /dev/null
@@ -1,271 +0,0 @@
-#ifndef included_vnet_dhcp6_packet_h
-#define included_vnet_dhcp6_packet_h
-
-/*
- * DHCP packet format
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-#include <vnet/ip/ip6_packet.h>
-
-// #define DHCP_VRF_NAME_MAX_LEN L3VM_MAX_NAME_STR_LEN
-// #define DHCPV6_MAX_VRF_NAME_LEN L3VM_MAX_NAME_STR_LEN
-#define DHCP_MAX_RELAY_ADDR 16
-#define PROTO_UDP 17
-#define DHCPV6_CLIENT_PORT 546
-#define DHCPV6_SERVER_PORT 547
-#define HOP_COUNT_LIMIT 32
-#define DHCPV6_CISCO_ENT_NUM 9
-
-/*
- * DHCPv6 message types
- */
-typedef enum dhcpv6_msg_type_
-{
- DHCPV6_MSG_SOLICIT = 1,
- DHCPV6_MSG_ADVERTISE = 2,
- DHCPV6_MSG_REQUEST = 3,
- DHCPV6_MSG_CONFIRM = 4,
- DHCPV6_MSG_RENEW = 5,
- DHCPV6_MSG_REBIND = 6,
- DHCPV6_MSG_REPLY = 7,
- DHCPV6_MSG_RELEASE = 8,
- DHCPV6_MSG_DECLINE = 9,
- DHCPV6_MSG_RECONFIGURE = 10,
- DHCPV6_MSG_INFORMATION_REQUEST = 11,
- DHCPV6_MSG_RELAY_FORW = 12,
- DHCPV6_MSG_RELAY_REPL = 13,
-} dhcpv6_msg_type_t;
-
-/* Name, code, min payload length */
-#define dhcpv6_foreach_option \
- _(CLIENTID , 1 , 4 ) \
- _(SERVERID , 2 , 4 ) \
- _(IA_NA , 3 , 12) \
- _(IA_TA , 4 , 4 ) \
- _(IAADDR , 5 , 24) \
- _(ORO , 6 , 0 ) \
- _(PREFERENCE , 7 , 1 ) \
- _(ELAPSED_TIME , 8 , 2 ) \
- _(RELAY_MSG , 9 , 0 ) \
- _(AUTH , 11 , 11) \
- _(UNICAST , 12 , 16) \
- _(STATUS_CODE , 13 , 2 ) \
- _(RAPID_COMMIT , 14 , 0 ) \
- _(USER_CLASS , 15 , 0 ) \
- _(VENDOR_CLASS , 16 , 4 ) \
- _(VENDOR_OPTS , 17 , 4 ) \
- _(INTERFACE_ID , 18 , 0 ) \
- _(RECONF_MSG , 19 , 1 ) \
- _(RECONF_ACCEPT , 20 , 0 ) \
- _(DNS_SEARCH , 24 , 0 ) \
- _(IA_PD , 25 , 12) \
- _(IAPREFIX , 26 , 25) \
- _(REMOTEID , 37 , 4 ) \
- _(VSS , 68 , 1 ) \
- _(CLIENT_LINK_LAYER_ADDRESS, 79 , 2 )
-
-/*
- * DHCPv6 options types
- */
-enum
-{
-#define _(a,b,c) DHCPV6_OPTION_##a = b,
- dhcpv6_foreach_option
-#undef _
- DHCPV6_OPTION_MAX
-};
-
-/*
-* DHCPv6 status codes
- */
-enum
-{
- DHCPV6_STATUS_SUCCESS = 0,
- DHCPV6_STATUS_UNSPEC_FAIL = 1,
- DHCPV6_STATUS_NOADDRS_AVAIL = 2,
- DHCPV6_STATUS_NO_BINDING = 3,
- DHCPV6_STATUS_NOT_ONLINK = 4,
- DHCPV6_STATUS_USE_MULTICAST = 5,
- DHCPV6_STATUS_NOPREFIX_AVAIL = 6,
-};
-
-/*
- * DHCPv6 DUID types
- */
-enum
-{
- DHCPV6_DUID_LLT = 1, /* DUID Based on Link-layer Address Plus Time */
- DHCPV6_DUID_EN = 2, /* DUID Based on Enterprise Number */
- DHCPV6_DUID_LL = 3, /* DUID Based on Link-layer Address */
-};
-
-//Structure for DHCPv6 payload from client
-typedef struct dhcpv6_hdr_
-{
- u8 msg_type; //DHCP msg type
- u8 xid[3]; //Transaction id
- u8 data[0];
-} dhcpv6_header_t;
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct dhcpv6_relay_ctx_ {
- dhcpv6_header_t *pkt;
- u32 pkt_len;
- u32 dhcpv6_len; //DHCPv6 payload load
-// if_ordinal iod;
- u32 if_index;
- u32 ctx_id;
- char ctx_name[32+1];
- u8 dhcp_msg_type;
-}) dhcpv6_relay_ctx_t;
-/* *INDENT-ON* */
-
-//Structure for DHCPv6 RELAY-FORWARD and DHCPv6 RELAY-REPLY pkts
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct dhcpv6_relay_hdr_ {
- u8 msg_type;
- u8 hop_count;
- ip6_address_t link_addr;
- ip6_address_t peer_addr;
- u8 data[0];
-}) dhcpv6_relay_hdr_t;
-/* *INDENT-ON* */
-
-typedef enum dhcp_stats_action_type_
-{
- DHCP_STATS_ACTION_FORWARDED = 1,
- DHCP_STATS_ACTION_RECEIVED,
- DHCP_STATS_ACTION_DROPPED
-} dhcp_stats_action_type_t;
-//Generic counters for a packet
-typedef struct dhcp_stats_counters_
-{
- u64 rx_pkts; //counter for received pkts
- u64 tx_pkts; //counter for forwarded pkts
- u64 drops; //counter for dropped pkts
-} dhcp_stats_counters_t;
-
-
-typedef enum dhcpv6_stats_drop_reason_
-{
- DHCPV6_RELAY_PKT_DROP_RELAYDISABLE = 1,
- DHCPV6_RELAY_PKT_DROP_MAX_HOPS,
- DHCPV6_RELAY_PKT_DROP_VALIDATION_FAIL,
- DHCPV6_RELAY_PKT_DROP_UNKNOWN_OP_INTF,
- DHCPV6_RELAY_PKT_DROP_BAD_CONTEXT,
- DHCPV6_RELAY_PKT_DROP_OPT_INSERT_FAIL,
- DHCPV6_RELAY_PKT_DROP_REPLY_FROM_CLIENT,
-} dhcpv6_stats_drop_reason_t;
-
-#define dhcpv6_optlen(opt) clib_net_to_host_u16((opt)->length)
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct {
- u16 option;
- u16 length;
- u8 data[0];
-}) dhcpv6_option_t;
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct {
- dhcpv6_option_t opt;
- u16 status_code;
-}) dhcpv6_status_code_t;
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct {
- dhcpv6_option_t opt;
- u32 int_idx;
-}) dhcpv6_int_id_t;
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct {
- dhcpv6_option_t opt;
- u8 vss_type;
- u8 data[0];
-}) dhcpv6_vss_t;
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct {
- dhcpv6_option_t opt;
- u32 ent_num;
- u32 rmt_id;
-}) dhcpv6_rmt_id_t;
-/* *INDENT-ON* */
-
-/* *INDENT-OFF* */
-typedef CLIB_PACKED (struct {
- dhcpv6_option_t opt;
- u16 link_type;
- u8 data[6]; // data[0]:data[5]: MAC address
-}) dhcpv6_client_mac_t;
-/* *INDENT-ON* */
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt; u32 iaid; u32 t1;
- u32 t2;
- u8 data[0];
- }) dhcpv6_ia_header_t;
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt; u32 preferred; u32 valid; u8 prefix;
- ip6_address_t addr;
- }) dhcpv6_ia_opt_pd_t;
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt; ip6_address_t addr; u32 preferred;
- u32 valid;
- }) dhcpv6_ia_opt_addr_t;
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt;
- u16 options[0];
- }) dhcpv6_oro_t;
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt; u16 elapsed_10ms;
- }) dhcpv6_elapsed_t;
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt; u16 duid_type;
- u16 hardware_type;
- }) dhcpv6_duid_t;
-
-typedef CLIB_PACKED (struct
- {
- dhcpv6_option_t opt; u16 status_code;
- u8 message[0];
- }) dhcpv6_status_t;
-
-
-#endif /* included_vnet_dhcp6_packet_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_pd_client_cp.api b/src/vnet/dhcp/dhcp6_pd_client_cp.api
deleted file mode 100644
index 43ed868e81e..00000000000
--- a/src/vnet/dhcp/dhcp6_pd_client_cp.api
+++ /dev/null
@@ -1,61 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-option version = "1.0.0";
-
-/** \brief Enable/disable DHCPv6 PD client on interface
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param sw_if_index - interface to enable/disable client on
- @param prefix_group - name of prefix group (relevant when 'enable' is 1)
- @param enable - 1 to enable, 0 to disable
-*/
-autoreply define dhcp6_pd_client_enable_disable
-{
- u32 client_index;
- u32 context;
- u32 sw_if_index;
- u8 prefix_group[64];
- u8 enable;
-};
-
-/** \brief Add/delete IPv6 address optionally using available prefix
- @param client_index - opaque cookie to identify the sender
- @param context - sender context, to match reply w/ request
- @param sw_if_index - software interface index of interface
- to add/delete address to/from
- @param prefix_group - name of prefix group,
- prefix_group[0] == '\0' means no prefix should be used
- @param address - address or suffix to be used with a prefix
- from selected group
- @param prefix_length - subnet prefix for the address
- @param is_add - 1 for add, 0 for remove
-*/
-autoreply define ip6_add_del_address_using_prefix
-{
- u32 client_index;
- u32 context;
- u32 sw_if_index;
- u8 prefix_group[64];
- u8 address[16];
- u8 prefix_length;
- u8 is_add;
-};
-
-/*
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_pd_client_cp.c b/src/vnet/dhcp/dhcp6_pd_client_cp.c
deleted file mode 100644
index cc538a78ab1..00000000000
--- a/src/vnet/dhcp/dhcp6_pd_client_cp.c
+++ /dev/null
@@ -1,1414 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vnet/vnet.h>
-#include <vlibmemory/api.h>
-#include <vnet/vnet_msg_enum.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/dhcp/dhcp6_pd_client_dp.h>
-#include <vnet/ip/ip.h>
-#include <vnet/ip/ip6.h>
-#include <float.h>
-#include <math.h>
-#include <string.h>
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_endianfun
-
-#include <vlibapi/api_helper_macros.h>
-
-#define foreach_dhcp6_pd_client_cp_msg \
-_(DHCP6_PD_CLIENT_ENABLE_DISABLE, dhcp6_pd_client_enable_disable) \
-_(IP6_ADD_DEL_ADDRESS_USING_PREFIX, ip6_add_del_address_using_prefix)
-
-#define vl_api_dhcp6_pd_client_enable_disable_t_print vl_noop_handler
-#define vl_api_ip6_add_del_address_using_prefix_t_print vl_noop_handler
-
-typedef struct
-{
- u32 prefix_group_index;
- uword opaque_data; // used by prefix publisher
- ip6_address_t prefix;
- u8 prefix_length;
- u32 preferred_lt;
- u32 valid_lt;
- f64 due_time;
-} prefix_info_t;
-
-typedef struct
-{
- u8 enabled;
- u32 prefix_group_index;
- u32 server_index;
- u32 T1;
- u32 T2;
- f64 T1_due_time;
- f64 T2_due_time;
- u32 prefix_count;
- u8 rebinding;
-} client_state_t;
-
-typedef struct
-{
- client_state_t *client_state_by_sw_if_index;
- clib_bitmap_t *prefix_ownership_bitmap;
- u32 n_clients;
- f64 max_valid_due_time;
-
- /* convenience */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
- api_main_t *api_main;
- u32 node_index;
-} dhcp6_pd_client_cp_main_t;
-
-static dhcp6_pd_client_cp_main_t dhcp6_pd_client_cp_main;
-
-typedef struct
-{
- prefix_info_t *prefix_pool;
- const u8 **prefix_group_name_by_index;
-} ip6_prefix_main_t;
-
-static ip6_prefix_main_t ip6_prefix_main;
-
-typedef struct
-{
- /* config */
- u32 sw_if_index;
- u32 prefix_group_index;
- ip6_address_t address;
- u8 prefix_length;
-
- /* state */
- u8 configured_in_data_plane;
-} ip6_address_info_t;
-
-typedef struct
-{
- ip6_address_info_t *addresses;
- u32 *active_prefix_index_by_prefix_group_index;
-} ip6_address_with_prefix_main_t;
-
-static ip6_address_with_prefix_main_t ip6_address_with_prefix_main;
-
-enum
-{
- DHCPV6_PD_EVENT_INTERRUPT,
- DHCPV6_PD_EVENT_DISABLE,
-};
-
-static_always_inline u32
-active_prefix_index_by_prefix_group_index_get (u32 prefix_group_index)
-{
- ip6_address_with_prefix_main_t *apm = &ip6_address_with_prefix_main;
-
- if (prefix_group_index >=
- vec_len (apm->active_prefix_index_by_prefix_group_index))
- return ~0;
-
- return apm->active_prefix_index_by_prefix_group_index[prefix_group_index];
-}
-
-static_always_inline void
-active_prefix_index_by_prefix_group_index_set (u32 prefix_group_index,
- u32 prefix_index)
-{
- ip6_address_with_prefix_main_t *apm = &ip6_address_with_prefix_main;
- static const u32 empty = ~0;
-
- ASSERT (prefix_group_index != ~0);
-
- if (prefix_index == ~0
- && prefix_group_index >=
- vec_len (apm->active_prefix_index_by_prefix_group_index))
- return;
-
- vec_validate_init_empty (apm->active_prefix_index_by_prefix_group_index,
- prefix_group_index, empty);
- apm->active_prefix_index_by_prefix_group_index[prefix_group_index] =
- prefix_index;
-}
-
-static_always_inline u8
-is_dhcpv6_pd_prefix (prefix_info_t * prefix_info)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- u32 prefix_index;
-
- prefix_index = prefix_info - pm->prefix_pool;
- return clib_bitmap_get (rm->prefix_ownership_bitmap, prefix_index);
-}
-
-static_always_inline void
-set_is_dhcpv6_pd_prefix (prefix_info_t * prefix_info, u8 value)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- u32 prefix_index;
-
- prefix_index = prefix_info - pm->prefix_pool;
- rm->prefix_ownership_bitmap =
- clib_bitmap_set (rm->prefix_ownership_bitmap, prefix_index, value);
-}
-
-static void
-cp_ip6_address_prefix_add_del_handler (u32 prefix_index, u8 is_add);
-
-static void
-notify_prefix_add_del (u32 prefix_index, u8 is_add)
-{
- // TODO: use registries
- cp_ip6_address_prefix_add_del_handler (prefix_index, is_add);
-}
-
-static void
-send_client_message_start_stop (u32 sw_if_index, u32 server_index,
- u8 msg_type, prefix_info_t * prefix_list,
- u8 start)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- dhcp6_pd_send_client_message_params_t params = { 0, };
- dhcp6_pd_send_client_message_params_prefix_t *prefixes = 0, *pref;
- u32 i;
-
- ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
- rm->client_state_by_sw_if_index[sw_if_index].enabled);
- client_state_t *client_state =
- &rm->client_state_by_sw_if_index[sw_if_index];
-
- params.sw_if_index = sw_if_index;
- params.server_index = server_index;
- params.msg_type = msg_type;
- if (start)
- {
- if (msg_type == DHCPV6_MSG_SOLICIT)
- {
- params.irt = 1;
- params.mrt = 120;
- }
- else if (msg_type == DHCPV6_MSG_REQUEST)
- {
- params.irt = 1;
- params.mrt = 30;
- params.mrc = 10;
- }
- else if (msg_type == DHCPV6_MSG_RENEW)
- {
- params.irt = 10;
- params.mrt = 600;
- f64 current_time = vlib_time_now (rm->vlib_main);
- i32 diff_time = client_state->T2 - current_time;
- if (diff_time < 0)
- diff_time = 0;
- params.mrd = diff_time;
- }
- else if (msg_type == DHCPV6_MSG_REBIND)
- {
- params.irt = 10;
- params.mrt = 600;
- f64 current_time = vlib_time_now (rm->vlib_main);
- i32 diff_time = rm->max_valid_due_time - current_time;
- if (diff_time < 0)
- diff_time = 0;
- params.mrd = diff_time;
- }
- else if (msg_type == DHCPV6_MSG_RELEASE)
- {
- params.mrc = 1;
- }
- }
-
- params.T1 = 0;
- params.T2 = 0;
- if (vec_len (prefix_list) != 0)
- vec_validate (prefixes, vec_len (prefix_list) - 1);
- for (i = 0; i < vec_len (prefix_list); i++)
- {
- prefix_info_t *prefix = &prefix_list[i];
- pref = &prefixes[i];
- pref->valid_lt = prefix->valid_lt;
- pref->preferred_lt = prefix->preferred_lt;
- pref->prefix = prefix->prefix;
- pref->prefix_length = prefix->prefix_length;
- }
- params.prefixes = prefixes;
-
- dhcp6_pd_send_client_message (rm->vlib_main, sw_if_index, !start, &params);
-
- vec_free (params.prefixes);
-}
-
-static void interrupt_process (void);
-
-static u32
-ip6_enable (u32 sw_if_index)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- clib_error_t *rv;
-
- rv = enable_ip6_interface (rm->vlib_main, sw_if_index);
-
- return rv != 0;
-}
-
-static u8
-ip6_prefixes_equal (ip6_address_t * prefix1, ip6_address_t * prefix2, u8 len)
-{
- if (len >= 64)
- {
- if (prefix1->as_u64[0] != prefix2->as_u64[0])
- return 0;
- if (len == 64)
- return 1;
- return clib_net_to_host_u64 (prefix1->as_u64[1]) >> (128 - len) ==
- clib_net_to_host_u64 (prefix2->as_u64[1]) >> (128 - len);
- }
- return clib_net_to_host_u64 (prefix1->as_u64[0]) >> (64 - len) ==
- clib_net_to_host_u64 (prefix2->as_u64[0]) >> (64 - len);
-}
-
-static clib_error_t *
-dhcp6_pd_reply_event_handler (vl_api_dhcp6_pd_reply_event_t * mp)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- vlib_main_t *vm = rm->vlib_main;
- client_state_t *client_state;
- ip6_address_t *prefix;
- u32 sw_if_index;
- u32 n_prefixes;
- vl_api_dhcp6_pd_prefix_info_t *api_prefix;
- u32 inner_status_code;
- u32 status_code;
- u32 server_index;
- f64 current_time;
- clib_error_t *error = 0;
- u32 i;
-
- current_time = vlib_time_now (vm);
-
- sw_if_index = ntohl (mp->sw_if_index);
-
- if (sw_if_index >= vec_len (rm->client_state_by_sw_if_index))
- return 0;
-
- client_state = &rm->client_state_by_sw_if_index[sw_if_index];
-
- if (!client_state->enabled)
- return 0;
-
- server_index = ntohl (mp->server_index);
-
- n_prefixes = ntohl (mp->n_prefixes);
-
- inner_status_code = ntohs (mp->inner_status_code);
- status_code = ntohs (mp->status_code);
-
- if (mp->msg_type == DHCPV6_MSG_API_ADVERTISE
- && client_state->server_index == ~0)
- {
- prefix_info_t *prefix_list = 0, *prefix_info;
- u8 prefix_length;
-
- if (inner_status_code == DHCPV6_STATUS_NOPREFIX_AVAIL)
- {
- clib_warning
- ("Advertise message arrived with NoPrefixAvail status code");
- return 0;
- }
-
- if (n_prefixes > 0)
- vec_validate (prefix_list, n_prefixes - 1);
- for (i = 0; i < n_prefixes; i++)
- {
- api_prefix = &mp->prefixes[i];
- prefix = (ip6_address_t *) api_prefix->prefix.address;
- prefix_length = api_prefix->prefix.len;
-
- prefix_info = &prefix_list[i];
- prefix_info->prefix = *prefix;
- prefix_info->prefix_length = prefix_length;
- prefix_info->preferred_lt = 0;
- prefix_info->valid_lt = 0;
- }
-
- client_state->server_index = server_index;
-
- send_client_message_start_stop (sw_if_index, server_index,
- DHCPV6_MSG_REQUEST, prefix_list, 1);
- vec_free (prefix_list);
- }
-
- if (mp->msg_type != DHCPV6_MSG_API_REPLY)
- return 0;
-
- if (!client_state->rebinding && client_state->server_index != server_index)
- {
- clib_warning ("Reply message arrived with Server ID different "
- "from that in Request or Renew message");
- return 0;
- }
-
- if (inner_status_code == DHCPV6_STATUS_NOPREFIX_AVAIL)
- {
- clib_warning ("Reply message arrived with NoPrefixAvail status code");
- if (n_prefixes > 0)
- {
- clib_warning
- ("Invalid Reply message arrived: It contains NoPrefixAvail "
- "status code but also contains prefixes");
- return 0;
- }
- }
-
- if (status_code == DHCPV6_STATUS_UNSPEC_FAIL)
- {
- clib_warning ("Reply message arrived with UnspecFail status code");
- return 0;
- }
-
- send_client_message_start_stop (sw_if_index, server_index,
- mp->msg_type, 0, 0);
-
- for (i = 0; i < n_prefixes; i++)
- {
- prefix_info_t *prefix_info = 0;
- u8 prefix_length;
- u32 valid_time;
- u32 preferred_time;
-
- api_prefix = &mp->prefixes[i];
-
- prefix = (ip6_address_t *) api_prefix->prefix.address;
- prefix_length = api_prefix->prefix.len;
-
- if (ip6_address_is_link_local_unicast (prefix))
- continue;
-
- valid_time = ntohl (api_prefix->valid_time);
- preferred_time = ntohl (api_prefix->preferred_time);
- prefix_length = api_prefix->prefix.len;
-
- if (preferred_time > valid_time)
- continue;
-
- u8 address_prefix_present = 0;
- /* *INDENT-OFF* */
- pool_foreach (prefix_info, pm->prefix_pool,
- ({
- if (is_dhcpv6_pd_prefix (prefix_info) &&
- prefix_info->opaque_data == sw_if_index &&
- prefix_info->prefix_length == prefix_length &&
- ip6_prefixes_equal (&prefix_info->prefix, prefix, prefix_length))
- {
- address_prefix_present = 1;
- goto prefix_pool_foreach_out;
- }
- }));
- /* *INDENT-ON* */
- prefix_pool_foreach_out:
-
- if (address_prefix_present)
- {
- prefix_info->preferred_lt = preferred_time;
- prefix_info->valid_lt = valid_time;
- prefix_info->due_time = current_time + valid_time;
- if (prefix_info->due_time > rm->max_valid_due_time)
- rm->max_valid_due_time = prefix_info->due_time;
- continue;
- }
-
- if (valid_time == 0)
- continue;
-
- pool_get (pm->prefix_pool, prefix_info);
- prefix_info->prefix_group_index = client_state->prefix_group_index;
- set_is_dhcpv6_pd_prefix (prefix_info, 1);
- prefix_info->opaque_data = sw_if_index;
- prefix_info->prefix_length = prefix_length;
- prefix_info->prefix = *prefix;
- prefix_info->preferred_lt = preferred_time;
- prefix_info->valid_lt = valid_time;
- prefix_info->due_time = current_time + valid_time;
- if (prefix_info->due_time > rm->max_valid_due_time)
- rm->max_valid_due_time = prefix_info->due_time;
- rm->client_state_by_sw_if_index[sw_if_index].prefix_count++;
-
- u32 prefix_index = prefix_info - pm->prefix_pool;
- notify_prefix_add_del (prefix_index, 1);
- }
-
- client_state->server_index = server_index;
- client_state->T1 = ntohl (mp->T1);
- client_state->T2 = ntohl (mp->T2);
- if (client_state->T1 != 0)
- client_state->T1_due_time = current_time + client_state->T1;
- if (client_state->T2 != 0)
- client_state->T2_due_time = current_time + client_state->T2;
- client_state->rebinding = 0;
-
- interrupt_process ();
-
- return error;
-}
-
-static prefix_info_t *
-create_prefix_list (u32 sw_if_index)
-{
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- prefix_info_t *prefix_info, *prefix_list = 0;;
-
- /* *INDENT-OFF* */
- pool_foreach (prefix_info, pm->prefix_pool,
- ({
- if (is_dhcpv6_pd_prefix (prefix_info) &&
- prefix_info->opaque_data == sw_if_index)
- {
- u32 pos = vec_len (prefix_list);
- vec_validate (prefix_list, pos);
- clib_memcpy (&prefix_list[pos], prefix_info, sizeof (*prefix_info));
- }
- }));
- /* *INDENT-ON* */
-
- return prefix_list;
-}
-
-VNET_DHCP6_PD_REPLY_EVENT_FUNCTION (dhcp6_pd_reply_event_handler);
-
-static uword
-dhcp6_pd_client_cp_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
- vlib_frame_t * f)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- prefix_info_t *prefix_info;
- client_state_t *client_state;
- f64 sleep_time = 1e9;
- f64 current_time;
- f64 due_time;
- uword event_type;
- uword *event_data = 0;
- int i;
-
- while (1)
- {
- vlib_process_wait_for_event_or_clock (vm, sleep_time);
- event_type = vlib_process_get_events (vm, &event_data);
- vec_reset_length (event_data);
-
- if (event_type == DHCPV6_PD_EVENT_DISABLE)
- {
- vlib_node_set_state (vm, rm->node_index, VLIB_NODE_STATE_DISABLED);
- sleep_time = 1e9;
- continue;
- }
-
- current_time = vlib_time_now (vm);
- do
- {
- due_time = current_time + 1e9;
- /* *INDENT-OFF* */
- pool_foreach (prefix_info, pm->prefix_pool,
- ({
- if (is_dhcpv6_pd_prefix (prefix_info))
- {
- if (prefix_info->due_time > current_time)
- {
- if (prefix_info->due_time < due_time)
- due_time = prefix_info->due_time;
- }
- else
- {
- u32 prefix_index = prefix_info - pm->prefix_pool;
- notify_prefix_add_del (prefix_index, 0);
- u32 sw_if_index = prefix_info->opaque_data;
- set_is_dhcpv6_pd_prefix (prefix_info, 0);
- pool_put (pm->prefix_pool, prefix_info);
- client_state = &rm->client_state_by_sw_if_index[sw_if_index];
- if (--client_state->prefix_count == 0)
- {
- client_state->rebinding = 0;
- client_state->server_index = ~0;
- send_client_message_start_stop (sw_if_index, ~0,
- DHCPV6_MSG_SOLICIT,
- 0, 1);
- }
- }
- }
- }));
- /* *INDENT-ON* */
- for (i = 0; i < vec_len (rm->client_state_by_sw_if_index); i++)
- {
- client_state_t *cs = &rm->client_state_by_sw_if_index[i];
- if (cs->enabled && cs->server_index != ~0)
- {
- if (cs->T2_due_time > current_time)
- {
- if (cs->T2_due_time < due_time)
- due_time = cs->T2_due_time;
- if (cs->T1_due_time > current_time)
- {
- if (cs->T1_due_time < due_time)
- due_time = cs->T1_due_time;
- }
- else
- {
- cs->T1_due_time = DBL_MAX;
- prefix_info_t *prefix_list;
- prefix_list = create_prefix_list (i);
- send_client_message_start_stop (i, cs->server_index,
- DHCPV6_MSG_RENEW,
- prefix_list, 1);
- vec_free (prefix_list);
- }
- }
- else
- {
- cs->T2_due_time = DBL_MAX;
- prefix_info_t *prefix_list;
- prefix_list = create_prefix_list (i);
- cs->rebinding = 1;
- send_client_message_start_stop (i, ~0,
- DHCPV6_MSG_REBIND,
- prefix_list, 1);
- vec_free (prefix_list);
- }
- }
- }
- current_time = vlib_time_now (vm);
- }
- while (due_time < current_time);
-
- sleep_time = due_time - current_time;
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp6_pd_client_cp_process_node) = {
- .function = dhcp6_pd_client_cp_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dhcp6-pd-client-cp-process",
-};
-/* *INDENT-ON* */
-
-static void
-interrupt_process (void)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
-
- vlib_process_signal_event (vm, dhcp6_pd_client_cp_process_node.index,
- DHCPV6_PD_EVENT_INTERRUPT, 0);
-}
-
-static void
-disable_process (void)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
-
- vlib_process_signal_event (vm, dhcp6_pd_client_cp_process_node.index,
- DHCPV6_PD_EVENT_DISABLE, 0);
-}
-
-static void
-enable_process (void)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- vlib_main_t *vm = rm->vlib_main;
- vlib_node_t *node;
-
- node = vec_elt (vm->node_main.nodes, rm->node_index);
-
- vlib_node_set_state (vm, rm->node_index, VLIB_NODE_STATE_POLLING);
- vlib_start_process (vm, node->runtime_index);
-}
-
-static u32
-cp_ip6_construct_address (ip6_address_info_t * address_info, u32 prefix_index,
- ip6_address_t * r_addr)
-{
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- prefix_info_t *prefix;
- u64 mask, addr0, pref;
-
- addr0 = clib_net_to_host_u64 (address_info->address.as_u64[0]);
- prefix = &pm->prefix_pool[prefix_index];
- if (prefix->prefix_length > 64)
- {
- clib_warning ("Prefix length is bigger that 64 bits");
- return 1;
- }
- mask = ((u64) 1 << (64 - prefix->prefix_length)) - 1;
- addr0 &= mask;
- pref = clib_host_to_net_u64 (prefix->prefix.as_u64[0]);
- pref &= ~mask;
- addr0 |= pref;
- r_addr->as_u64[0] = clib_host_to_net_u64 (addr0);
- r_addr->as_u64[1] = address_info->address.as_u64[1];
-
- return 0;
-}
-
-static void
-cp_ip6_address_add_del_now (ip6_address_info_t * address_info, u8 is_add)
-{
- vlib_main_t *vm = vlib_get_main ();
- u32 prefix_index;
- ip6_address_t addr;
- clib_error_t *error;
-
- if (address_info->prefix_group_index != ~0)
- prefix_index =
- active_prefix_index_by_prefix_group_index_get
- (address_info->prefix_group_index);
- else
- prefix_index = ~0;
-
- if (is_add && !address_info->configured_in_data_plane)
- {
- if (prefix_index != ~0)
- {
- if (cp_ip6_construct_address (address_info, prefix_index, &addr) !=
- 0)
- return;
- error =
- ip6_add_del_interface_address (vm, address_info->sw_if_index,
- &addr, address_info->prefix_length,
- 0 /* add */ );
- if (error)
- clib_warning ("Failed adding IPv6 address: %U",
- format_clib_error, error);
- else
- address_info->configured_in_data_plane = 1;
- }
- else
- {
- if (address_info->prefix_group_index == ~0)
- {
- error =
- ip6_add_del_interface_address (vm, address_info->sw_if_index,
- &address_info->address,
- address_info->prefix_length,
- 0 /* add */ );
- if (error)
- clib_warning ("Failed adding IPv6 address: %U",
- format_clib_error, error);
- else
- address_info->configured_in_data_plane = 1;
- }
- }
- }
- else if (!is_add && address_info->configured_in_data_plane)
- {
- if (prefix_index == ~0)
- {
- if (address_info->prefix_group_index == ~0)
- {
- error =
- ip6_add_del_interface_address (vm, address_info->sw_if_index,
- &address_info->address,
- address_info->prefix_length,
- 1 /* del */ );
- if (error)
- clib_warning ("Failed deleting IPv6 address: %U",
- format_clib_error, error);
- address_info->configured_in_data_plane = 0;
- }
- else
- clib_warning ("Deleting address with prefix "
- "but active prefix index is not set");
- }
- else
- {
- if (cp_ip6_construct_address (address_info, prefix_index, &addr) !=
- 0)
- return;
- error =
- ip6_add_del_interface_address (vm, address_info->sw_if_index,
- &addr, address_info->prefix_length,
- 1 /* del */ );
- if (error)
- clib_warning ("Failed deleting IPv6 address: %U",
- format_clib_error, error);
- address_info->configured_in_data_plane = 0;
- }
- }
-}
-
-static u32
-cp_ip6_address_find_new_active_prefix (u32 prefix_group_index,
- u32 ignore_prefix_index)
-{
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- prefix_info_t *prefix_info;
-
- /* *INDENT-OFF* */
- pool_foreach (prefix_info, pm->prefix_pool,
- ({
- if (prefix_info->prefix_group_index == prefix_group_index &&
- prefix_info - pm->prefix_pool != ignore_prefix_index)
- return prefix_info - pm->prefix_pool;
- }));
- /* *INDENT-ON* */
- return ~0;
-}
-
-static void
-cp_ip6_address_prefix_add_del_handler (u32 prefix_index, u8 is_add)
-{
- ip6_address_with_prefix_main_t *apm = &ip6_address_with_prefix_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- ip6_address_info_t *address_info;
- prefix_info_t *prefix;
- u32 new_prefix_index;
- u32 prefix_group_index;
- u32 i;
-
- prefix = &pm->prefix_pool[prefix_index];
- prefix_group_index = prefix->prefix_group_index;
-
- if (is_add)
- {
- if (active_prefix_index_by_prefix_group_index_get
- (prefix_group_index) == ~0)
- {
- active_prefix_index_by_prefix_group_index_set
- (prefix_group_index, prefix_index);
- for (i = 0; i < vec_len (apm->addresses); i++)
- {
- address_info = &apm->addresses[i];
- if (address_info->prefix_group_index == prefix_group_index)
- cp_ip6_address_add_del_now (address_info, 1 /* add */ );
- }
- }
- }
- else
- {
- if (active_prefix_index_by_prefix_group_index_get
- (prefix_group_index) == prefix_index)
- {
- for (i = 0; i < vec_len (apm->addresses); i++)
- {
- address_info = &apm->addresses[i];
- if (address_info->prefix_group_index == prefix_group_index)
- cp_ip6_address_add_del_now (address_info, 0 /* del */ );
- }
- active_prefix_index_by_prefix_group_index_set
- (prefix_group_index, ~0);
- new_prefix_index =
- cp_ip6_address_find_new_active_prefix (prefix_group_index,
- prefix_index);
- if (new_prefix_index != ~0)
- {
- active_prefix_index_by_prefix_group_index_set
- (prefix_group_index, new_prefix_index);
- for (i = 0; i < vec_len (apm->addresses); i++)
- {
- address_info = &apm->addresses[i];
- if (address_info->prefix_group_index == prefix_group_index)
- cp_ip6_address_add_del_now (address_info, 1 /* add */ );
- }
- }
- }
- }
-}
-
-static u32
-prefix_group_find_or_create (const u8 * name, u8 create)
-{
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- u32 free_index = ~0;
- u8 *name_dup;
- u32 i;
-
- for (i = 0; i < vec_len (pm->prefix_group_name_by_index); i++)
- {
- if (pm->prefix_group_name_by_index[i] == 0)
- free_index = i;
- else if (0 ==
- strcmp ((const char *) pm->prefix_group_name_by_index[i],
- (const char *) name))
- return i;
- }
- if (!create)
- return ~0;
- name_dup = (u8 *) strdup ((const char *) name);
- if (free_index != ~0)
- {
- pm->prefix_group_name_by_index[free_index] = name_dup;
- return free_index;
- }
- else
- {
- vec_add1 (pm->prefix_group_name_by_index, name_dup);
- return vec_len (pm->prefix_group_name_by_index) - 1;
- }
-}
-
-static int
-cp_ip6_address_add_del (u32 sw_if_index, const u8 * prefix_group,
- ip6_address_t address, u8 prefix_length, u8 is_add)
-{
-
- ip6_address_with_prefix_main_t *apm = &ip6_address_with_prefix_main;
- vnet_main_t *vnm = vnet_get_main ();
- ip6_address_info_t *address_info;
- u32 prefix_group_index;
- u32 n;
-
- if (!vnet_sw_interface_is_api_valid (vnm, sw_if_index))
- {
- clib_warning ("Invalid sw_if_index");
- return VNET_API_ERROR_INVALID_VALUE;
- }
-
- if (prefix_group != 0 && prefix_group[0] != '\0')
- {
- if (strnlen ((const char *) prefix_group, 64) == 64)
- return VNET_API_ERROR_INVALID_VALUE;
-
- prefix_group_index = prefix_group_find_or_create (prefix_group, 1);
- }
- else
- prefix_group_index = ~0;
-
- n = vec_len (apm->addresses);
-
- vec_foreach (address_info, apm->addresses)
- {
- if (address_info->sw_if_index == sw_if_index &&
- address_info->prefix_group_index == prefix_group_index &&
- address_info->prefix_length == prefix_length &&
- 0 == memcmp (&address_info->address, &address, 16))
- {
- if (is_add)
- return VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
- cp_ip6_address_add_del_now (address_info, 0 /* del */ );
- *address_info = apm->addresses[n - 1];
- _vec_len (apm->addresses) = n - 1;
- return 0;
- }
- }
-
- if (!is_add)
- return VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
-
- vec_validate (apm->addresses, n);
- address_info = &apm->addresses[n];
- address_info->sw_if_index = sw_if_index;
- address_info->prefix_group_index = prefix_group_index;
- address_info->address = address;
- address_info->prefix_length = prefix_length;
- cp_ip6_address_add_del_now (address_info, 1 /* add */ );
-
- return 0;
-}
-
-static void
- vl_api_ip6_add_del_address_using_prefix_t_handler
- (vl_api_ip6_add_del_address_using_prefix_t * mp)
-{
- vl_api_ip6_add_del_address_using_prefix_reply_t *rmp;
- u32 sw_if_index;
- ip6_address_t address;
- u8 prefix_length;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- sw_if_index = ntohl (mp->sw_if_index);
-
- memcpy (address.as_u8, mp->address, 16);
- prefix_length = mp->prefix_length;
-
- rv =
- cp_ip6_address_add_del (sw_if_index, mp->prefix_group, address,
- prefix_length, mp->is_add);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO (VL_API_IP6_ADD_DEL_ADDRESS_USING_PREFIX_REPLY);
-}
-
-static clib_error_t *
-cp_ip6_address_add_del_command_function (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- clib_error_t *error = 0;
- u32 sw_if_index = ~0;
- u8 *prefix_group = 0;
- ip6_address_t address;
- u32 prefix_length;
- u8 address_set = 0;
- u8 add = 1;
- unformat_input_t _line_input, *line_input = &_line_input;
-
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index));
- else if (unformat (line_input, "prefix group %s", &prefix_group));
- else
- if (unformat (line_input, "%U/%d", unformat_ip6_address,
- &address, &prefix_length))
- address_set = 1;
- else if (unformat (line_input, "del"))
- add = 0;
- else
- {
- error = clib_error_return (0, "unexpected input `%U'",
- format_unformat_error, line_input);
- unformat_free (line_input);
- goto done;
- }
- }
-
- unformat_free (line_input);
-
- if (sw_if_index == ~0)
- error = clib_error_return (0, "Missing sw_if_index");
- else if (address_set == 0)
- error = clib_error_return (0, "Missing address");
- else
- {
- if (cp_ip6_address_add_del
- (sw_if_index, prefix_group, address, prefix_length, add) != 0)
- error = clib_error_return (0, "Error adding or removing address");
- }
-
-done:
- return error;
-}
-
-/*?
- * This command is used to add/delete IPv6 address
- * potentially using available prefix from specified prefix group
- *
- * @cliexpar
- * @parblock
- * Example of how to add IPv6 address:
- * @cliexcmd{set ip6 address GigabitEthernet2/0/0
- * prefix group my-prefix-group ::7/64}
- * Example of how to delete IPv6 address:
- * @cliexcmd{set ip6 address GigabitEthernet2/0/0
- * prefix group my-prefix-group ::7/64 del}
- * @endparblock
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_address_add_del_command, static) = {
- .path = "set ip6 address",
- .short_help = "set ip6 address <interface> [prefix group <string>] "
- "<address> [del]",
- .function = cp_ip6_address_add_del_command_function,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-cp_ip6_addresses_show_command_function (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- ip6_address_with_prefix_main_t *apm = &ip6_address_with_prefix_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- ip6_address_info_t *address_info;
- const u8 *prefix_group;
- clib_error_t *error = 0;
- int i;
-
- for (i = 0; i < vec_len (apm->addresses); i++)
- {
- address_info = &apm->addresses[i];
- if (address_info->prefix_group_index == ~0)
- prefix_group = (const u8 *) "NONE";
- else
- prefix_group =
- pm->prefix_group_name_by_index[address_info->prefix_group_index];
- vlib_cli_output (vm,
- "sw_if_index: %u, prefix_group: %s, address: %U/%d",
- address_info->sw_if_index, prefix_group,
- format_ip6_address, &address_info->address,
- address_info->prefix_length);
- }
-
- return error;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_addresses_show_command, static) = {
- .path = "show ip6 addresses",
- .short_help = "show ip6 addresses",
- .function = cp_ip6_addresses_show_command_function,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-cp_ip6_prefixes_show_command_function (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- clib_error_t *error = 0;
- prefix_info_t *prefix_info;
- const u8 *prefix_group;
- f64 current_time = vlib_time_now (vm);
-
- /* *INDENT-OFF* */
- pool_foreach (prefix_info, pm->prefix_pool,
- ({
- prefix_group =
- pm->prefix_group_name_by_index[prefix_info->prefix_group_index];
- vlib_cli_output (vm, "opaque_data: %lu, prefix: %U/%d, prefix group: %s, "
- "preferred lifetime: %u, valid lifetime: %u "
- "(%f remaining)",
- prefix_info->opaque_data, format_ip6_address,
- &prefix_info->prefix, prefix_info->prefix_length,
- prefix_group,
- prefix_info->preferred_lt, prefix_info->valid_lt,
- prefix_info->due_time - current_time);
- }));
- /* *INDENT-ON* */
-
- return error;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_prefixes_show_command, static) = {
- .path = "show ip6 prefixes",
- .short_help = "show ip6 prefixes",
- .function = cp_ip6_prefixes_show_command_function,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-ip6_pd_clients_show_command_function (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- clib_error_t *error = 0;
- client_state_t *cs;
- f64 current_time = vlib_time_now (vm);
- const u8 *prefix_group;
- char buf1[256];
- char buf2[256];
- const char *rebinding;
- u32 i;
-
- for (i = 0; i < vec_len (rm->client_state_by_sw_if_index); i++)
- {
- cs = &rm->client_state_by_sw_if_index[i];
- if (cs->enabled)
- {
- if (cs->T1_due_time != DBL_MAX && cs->T1_due_time > current_time)
- {
- sprintf (buf1, "%u remaining",
- (u32) round (cs->T1_due_time - current_time));
- }
- else
- sprintf (buf1, "timeout");
- if (cs->T2_due_time != DBL_MAX && cs->T2_due_time > current_time)
- sprintf (buf2, "%u remaining",
- (u32) round (cs->T2_due_time - current_time));
- else
- sprintf (buf2, "timeout");
- if (cs->rebinding)
- rebinding = ", REBINDING";
- else
- rebinding = "";
- prefix_group =
- pm->prefix_group_name_by_index[cs->prefix_group_index];
- if (cs->T1)
- vlib_cli_output (vm,
- "sw_if_index: %u, prefix group: %s, T1: %u (%s), "
- "T2: %u (%s), server index: %d%s", i,
- prefix_group, cs->T1, buf1, cs->T2, buf2,
- cs->server_index, rebinding);
- else
- vlib_cli_output (vm, "sw_if_index: %u, prefix group: %s%s", i,
- prefix_group, rebinding);
- }
- }
-
- return error;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (ip6_pd_clients_show_command, static) = {
- .path = "show ip6 pd clients",
- .short_help = "show ip6 pd clients",
- .function = ip6_pd_clients_show_command_function,
-};
-/* *INDENT-ON* */
-
-static int
-dhcp6_pd_client_enable_disable (u32 sw_if_index, const u8 * prefix_group,
- u8 enable)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- ip6_prefix_main_t *pm = &ip6_prefix_main;
- vnet_main_t *vnm = rm->vnet_main;
- client_state_t *client_state;
- static client_state_t empty_config = {
- 0
- };
- prefix_info_t *prefix_info;
- prefix_info_t *prefix_list = 0;
- u32 prefix_group_index;
-
- if (!vnet_sw_interface_is_api_valid (vnm, sw_if_index))
- {
- clib_warning ("Invalid sw_if_index");
- return VNET_API_ERROR_INVALID_VALUE;
- }
-
- vec_validate_init_empty (rm->client_state_by_sw_if_index, sw_if_index,
- empty_config);
- client_state = &rm->client_state_by_sw_if_index[sw_if_index];
-
- u8 old_enabled = client_state->enabled;
-
- if (enable)
- {
- if (strnlen ((const char *) prefix_group, 64) == 64
- || prefix_group[0] == '\0')
- return VNET_API_ERROR_INVALID_VALUE;
- prefix_group_index =
- prefix_group_find_or_create (prefix_group, !old_enabled);
- if (old_enabled
- && prefix_group_index != client_state->prefix_group_index)
- return VNET_API_ERROR_INVALID_VALUE;
- }
-
- if (!old_enabled && enable)
- {
- client_state->enabled = 1;
- client_state->prefix_group_index = prefix_group_index;
- ASSERT (client_state->prefix_group_index != ~0);
- client_state->server_index = ~0;
-
- rm->n_clients++;
- if (rm->n_clients == 1)
- {
- enable_process ();
- dhcp6_clients_enable_disable (1);
- }
-
- ip6_enable (sw_if_index);
- send_client_message_start_stop (sw_if_index, ~0, DHCPV6_MSG_SOLICIT,
- 0, 1);
- }
- else if (old_enabled && !enable)
- {
- send_client_message_start_stop (sw_if_index, ~0, ~0, 0, 0);
-
- rm->n_clients--;
- if (rm->n_clients == 0)
- {
- dhcp6_clients_enable_disable (0);
- disable_process ();
- }
-
- vec_validate (prefix_list, 0);
-
- /* *INDENT-OFF* */
- pool_foreach (prefix_info, pm->prefix_pool,
- ({
- if (is_dhcpv6_pd_prefix (prefix_info) &&
- prefix_info->opaque_data == sw_if_index)
- {
- ASSERT (sw_if_index < vec_len (rm->client_state_by_sw_if_index) &&
- rm->client_state_by_sw_if_index[sw_if_index].enabled);
- client_state_t *client_state =
- &rm->client_state_by_sw_if_index[sw_if_index];
- prefix_list[0] = *prefix_info;
- send_client_message_start_stop (sw_if_index,
- client_state->server_index,
- DHCPV6_MSG_RELEASE, prefix_list,
- 1);
- u32 prefix_index = prefix_info - pm->prefix_pool;
- notify_prefix_add_del (prefix_index, 0);
- set_is_dhcpv6_pd_prefix (prefix_info, 0);
- pool_put (pm->prefix_pool, prefix_info);
- }
- }));
- /* *INDENT-ON* */
-
- vec_free (prefix_list);
-
- clib_memset (client_state, 0, sizeof (*client_state));
- }
-
- return 0;
-}
-
-static clib_error_t *
-dhcp6_pd_client_enable_disable_command_fn (vlib_main_t *
- vm,
- unformat_input_t
- * input, vlib_cli_command_t * cmd)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- vnet_main_t *vnm = rm->vnet_main;
- clib_error_t *error = 0;
- u8 *prefix_group = 0;
- u32 sw_if_index = ~0;
- u8 enable = 1;
- unformat_input_t _line_input, *line_input = &_line_input;
-
- if (!unformat_user (input, unformat_line_input, line_input))
- return 0;
-
- while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat
- (line_input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
- ;
- else if (unformat (line_input, "prefix group %s", &prefix_group));
- else if (unformat (line_input, "disable"))
- enable = 0;
- else
- {
- error = clib_error_return (0, "unexpected input `%U'",
- format_unformat_error, line_input);
- goto done;
- }
- }
-
- if (prefix_group == 0 && enable)
- error = clib_error_return (0, "Prefix group must be set when enabling");
- else if (sw_if_index != ~0)
- {
- if (dhcp6_pd_client_enable_disable (sw_if_index, prefix_group, enable)
- != 0)
- error = clib_error_return (0, "Invalid sw_if_index or prefix group");
- }
- else
- error = clib_error_return (0, "Missing sw_if_index");
-
-done:
- vec_free (prefix_group);
- unformat_free (line_input);
-
- return error;
-}
-
-/*?
- * This command is used to enable/disable DHCPv6 PD client
- * on particular interface.
- *
- * @cliexpar
- * @parblock
- * Example of how to enable DHCPv6 PD client:
- * @cliexcmd{dhcp6 pd client GigabitEthernet2/0/0 prefix group my-pd-group}
- * Example of how to disable DHCPv6 PD client:
- * @cliexcmd{dhcp6 pd client GigabitEthernet2/0/0 disable}
- * @endparblock
-?*/
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcp6_pd_client_enable_disable_command, static) = {
- .path = "dhcp6 pd client",
- .short_help = "dhcp6 pd client <interface> (prefix group <string> | disable)",
- .function = dhcp6_pd_client_enable_disable_command_fn,
-};
-/* *INDENT-ON* */
-
-static void
- vl_api_dhcp6_pd_client_enable_disable_t_handler
- (vl_api_dhcp6_pd_client_enable_disable_t * mp)
-{
- vl_api_dhcp6_pd_client_enable_disable_reply_t *rmp;
- u32 sw_if_index;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- sw_if_index = ntohl (mp->sw_if_index);
-
- rv =
- dhcp6_pd_client_enable_disable (sw_if_index, mp->prefix_group,
- mp->enable);
-
- BAD_SW_IF_INDEX_LABEL;
-
- REPLY_MACRO (VL_API_DHCP6_PD_CLIENT_ENABLE_DISABLE_REPLY);
-}
-
-#define vl_msg_name_crc_list
-#include <vnet/dhcp/dhcp6_pd_client_cp.api.h>
-#undef vl_msg_name_crc_list
-
-static void
-setup_message_id_table (api_main_t * am)
-{
-#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
- foreach_vl_msg_name_crc_dhcp6_pd_client_cp;
-#undef _
-}
-
-static clib_error_t *
-dhcp_pd_client_cp_init (vlib_main_t * vm)
-{
- dhcp6_pd_client_cp_main_t *rm = &dhcp6_pd_client_cp_main;
- api_main_t *am = &api_main;
-
- rm->vlib_main = vm;
- rm->vnet_main = vnet_get_main ();
- rm->api_main = am;
- rm->node_index = dhcp6_pd_client_cp_process_node.index;
-
-#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N, #n, \
- vl_api_##n##_t_handler, \
- vl_noop_handler, \
- vl_api_##n##_t_endian, \
- vl_api_##n##_t_print, \
- sizeof(vl_api_##n##_t), 0/* do NOT trace! */);
- foreach_dhcp6_pd_client_cp_msg;
-#undef _
-
- /*
- * Set up the (msg_name, crc, message-id) table
- */
- setup_message_id_table (am);
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (dhcp_pd_client_cp_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_pd_client_dp.c b/src/vnet/dhcp/dhcp6_pd_client_dp.c
deleted file mode 100644
index c665b17281a..00000000000
--- a/src/vnet/dhcp/dhcp6_pd_client_dp.c
+++ /dev/null
@@ -1,665 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vlib/vlib.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/mfib/mfib_table.h>
-#include <vnet/mfib/ip6_mfib.h>
-#include <vnet/fib/fib.h>
-#include <vnet/adj/adj_mcast.h>
-#include <vnet/ip/ip6_neighbor.h>
-#include <vlibapi/api_common.h>
-#include <vlibmemory/api.h>
-#include <vnet/dhcp/dhcp6_pd_client_dp.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-#include <vnet/ip/ip_types_api.h>
-
-#include <vnet/vnet_msg_enum.h>
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_endianfun
-
-/* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define vl_printfun
-#include <vnet/vnet_all_api_h.h>
-#undef vl_printfun
-
-#include <vlibapi/api_helper_macros.h>
-
-dhcp6_pd_client_main_t dhcp6_pd_client_main;
-dhcp6_pd_client_public_main_t dhcp6_pd_client_public_main;
-
-static void
-signal_report (prefix_report_t * r)
-{
- vlib_main_t *vm = vlib_get_main ();
- dhcp6_pd_client_main_t *cm = &dhcp6_pd_client_main;
- uword ni = cm->publisher_node;
- uword et = cm->publisher_et;
-
- if (ni == (uword) ~ 0)
- return;
- prefix_report_t *q =
- vlib_process_signal_event_data (vm, ni, et, 1, sizeof *q);
-
- *q = *r;
-}
-
-int
-dhcp6_pd_publish_report (prefix_report_t * r)
-{
- void vl_api_rpc_call_main_thread (void *fp, u8 * data, u32 data_length);
- vl_api_rpc_call_main_thread (signal_report, (u8 *) r, sizeof *r);
- return 0;
-}
-
-void
-dhcp6_pd_set_publisher_node (uword node_index, uword event_type)
-{
- dhcp6_pd_client_main_t *cm = &dhcp6_pd_client_main;
- cm->publisher_node = node_index;
- cm->publisher_et = event_type;
-}
-
-static void
-stop_sending_client_message (vlib_main_t * vm,
- dhcp6_pd_client_state_t * client_state)
-{
- u32 bi0;
-
- client_state->keep_sending_client_message = 0;
- vec_free (client_state->params.prefixes);
- if (client_state->buffer)
- {
- bi0 = vlib_get_buffer_index (vm, client_state->buffer);
- vlib_buffer_free (vm, &bi0, 1);
- client_state->buffer = 0;
- adj_unlock (client_state->adj_index);
- client_state->adj_index = ~0;
- }
-}
-
-static vlib_buffer_t *
-create_buffer_for_client_message (vlib_main_t * vm,
- u32 sw_if_index,
- dhcp6_pd_client_state_t
- * client_state, u32 type)
-{
- dhcp6_client_common_main_t *ccm = &dhcp6_client_common_main;
- vnet_main_t *vnm = vnet_get_main ();
-
- vlib_buffer_t *b;
- u32 bi;
- ip6_header_t *ip;
- udp_header_t *udp;
- dhcpv6_header_t *dhcp;
- ip6_address_t src_addr;
- u32 dhcp_opt_len = 0;
- client_state->transaction_start = vlib_time_now (vm);
- u32 n_prefixes;
- u32 i;
-
- vnet_hw_interface_t *hw = vnet_get_sup_hw_interface (vnm, sw_if_index);
- vnet_sw_interface_t *sup_sw = vnet_get_sup_sw_interface (vnm, sw_if_index);
- vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, sw_if_index);
-
- /* Interface(s) down? */
- if ((hw->flags & VNET_HW_INTERFACE_FLAG_LINK_UP) == 0)
- return NULL;
- if ((sup_sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
- return NULL;
- if ((sw->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) == 0)
- return NULL;
-
- /* Get a link-local address */
- src_addr = ip6_neighbor_get_link_local_address (sw_if_index);
-
- if (src_addr.as_u8[0] != 0xfe)
- {
- clib_warning ("Could not find source address to send DHCPv6 packet");
- return NULL;
- }
-
- if (vlib_buffer_alloc (vm, &bi, 1) != 1)
- {
- clib_warning ("Buffer allocation failed");
- return NULL;
- }
-
- b = vlib_get_buffer (vm, bi);
- vnet_buffer (b)->sw_if_index[VLIB_RX] = sw_if_index;
- vnet_buffer (b)->sw_if_index[VLIB_TX] = sw_if_index;
- client_state->adj_index = adj_mcast_add_or_lock (FIB_PROTOCOL_IP6,
- VNET_LINK_IP6,
- sw_if_index);
- vnet_buffer (b)->ip.adj_index[VLIB_TX] = client_state->adj_index;
- b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
-
- ip = (ip6_header_t *) vlib_buffer_get_current (b);
- udp = (udp_header_t *) (ip + 1);
- dhcp = (dhcpv6_header_t *) (udp + 1);
-
- ip->src_address = src_addr;
- ip->hop_limit = 255;
- ip->ip_version_traffic_class_and_flow_label =
- clib_host_to_net_u32 (0x6 << 28);
- ip->payload_length = 0;
- ip->protocol = IP_PROTOCOL_UDP;
-
- udp->src_port = clib_host_to_net_u16 (DHCPV6_CLIENT_PORT);
- udp->dst_port = clib_host_to_net_u16 (DHCPV6_SERVER_PORT);
- udp->checksum = 0;
- udp->length = 0;
-
- dhcp->msg_type = type;
- dhcp->xid[0] = (client_state->transaction_id & 0x00ff0000) >> 16;
- dhcp->xid[1] = (client_state->transaction_id & 0x0000ff00) >> 8;
- dhcp->xid[2] = (client_state->transaction_id & 0x000000ff) >> 0;
-
- void *d = (void *) dhcp->data;
- dhcpv6_option_t *duid;
- dhcpv6_elapsed_t *elapsed;
- dhcpv6_ia_header_t *ia_hdr;
- dhcpv6_ia_opt_pd_t *opt_pd;
- if (type == DHCPV6_MSG_SOLICIT || type == DHCPV6_MSG_REQUEST ||
- type == DHCPV6_MSG_RENEW || type == DHCPV6_MSG_REBIND ||
- type == DHCPV6_MSG_RELEASE)
- {
- duid = (dhcpv6_option_t *) d;
- duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_CLIENTID);
- duid->length = clib_host_to_net_u16 (CLIENT_DUID_LENGTH);
- clib_memcpy (duid + 1, client_duid.bin_string, CLIENT_DUID_LENGTH);
- d += sizeof (*duid) + CLIENT_DUID_LENGTH;
-
- if (client_state->params.server_index != ~0)
- {
- server_id_t *se =
- &ccm->server_ids[client_state->params.server_index];
-
- duid = (dhcpv6_option_t *) d;
- duid->option = clib_host_to_net_u16 (DHCPV6_OPTION_SERVERID);
- duid->length = clib_host_to_net_u16 (se->len);
- clib_memcpy (duid + 1, se->data, se->len);
- d += sizeof (*duid) + se->len;
- }
-
- elapsed = (dhcpv6_elapsed_t *) d;
- elapsed->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_ELAPSED_TIME);
- elapsed->opt.length =
- clib_host_to_net_u16 (sizeof (*elapsed) - sizeof (elapsed->opt));
- elapsed->elapsed_10ms = 0;
- client_state->elapsed_pos =
- (char *) &elapsed->elapsed_10ms -
- (char *) vlib_buffer_get_current (b);
- d += sizeof (*elapsed);
-
- ia_hdr = (dhcpv6_ia_header_t *) d;
- ia_hdr->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IA_PD);
- ia_hdr->iaid = clib_host_to_net_u32 (DHCPV6_CLIENT_IAID);
- ia_hdr->t1 = clib_host_to_net_u32 (client_state->params.T1);
- ia_hdr->t2 = clib_host_to_net_u32 (client_state->params.T2);
- d += sizeof (*ia_hdr);
-
- n_prefixes = vec_len (client_state->params.prefixes);
-
- ia_hdr->opt.length =
- clib_host_to_net_u16 (sizeof (*ia_hdr) +
- n_prefixes * sizeof (*opt_pd) -
- sizeof (ia_hdr->opt));
-
- for (i = 0; i < n_prefixes; i++)
- {
- dhcp6_pd_send_client_message_params_prefix_t *pref =
- &client_state->params.prefixes[i];
- opt_pd = (dhcpv6_ia_opt_pd_t *) d;
- opt_pd->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_IAPREFIX);
- opt_pd->opt.length =
- clib_host_to_net_u16 (sizeof (*opt_pd) - sizeof (opt_pd->opt));
- opt_pd->addr = pref->prefix;
- opt_pd->prefix = pref->prefix_length;
- opt_pd->valid = clib_host_to_net_u32 (pref->valid_lt);
- opt_pd->preferred = clib_host_to_net_u32 (pref->preferred_lt);
- d += sizeof (*opt_pd);
- }
- }
- else
- {
- clib_warning ("State not implemented");
- }
-
- dhcp_opt_len = ((u8 *) d) - dhcp->data;
- udp->length =
- clib_host_to_net_u16 (sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len);
- ip->payload_length = udp->length;
- b->current_length =
- sizeof (*ip) + sizeof (*udp) + sizeof (*dhcp) + dhcp_opt_len;
-
- ip->dst_address = all_dhcp6_relay_agents_and_servers;
-
- return b;
-}
-
-static inline u8
-check_pd_send_client_message (vlib_main_t * vm,
- dhcp6_pd_client_state_t * client_state,
- f64 current_time, f64 * due_time)
-{
- vlib_buffer_t *p0;
- vlib_frame_t *f;
- u32 *to_next;
- u32 next_index;
- vlib_buffer_t *c0;
- ip6_header_t *ip;
- udp_header_t *udp;
- u32 ci0;
- int bogus_length = 0;
-
- dhcp6_pd_send_client_message_params_t *params;
-
- f64 now = vlib_time_now (vm);
-
- if (!client_state->keep_sending_client_message)
- return false;
-
- params = &client_state->params;
-
- if (client_state->due_time > current_time)
- {
- *due_time = client_state->due_time;
- return true;
- }
-
- p0 = client_state->buffer;
-
- next_index = ip6_rewrite_mcast_node.index;
-
- c0 = vlib_buffer_copy (vm, p0);
- ci0 = vlib_get_buffer_index (vm, c0);
-
- ip = (ip6_header_t *) vlib_buffer_get_current (c0);
- udp = (udp_header_t *) (ip + 1);
-
- u16 *elapsed_field = (u16 *) ((void *) ip + client_state->elapsed_pos);
- *elapsed_field =
- clib_host_to_net_u16 ((u16)
- ((now - client_state->transaction_start) * 100));
-
- udp->checksum = 0;
- udp->checksum =
- ip6_tcp_udp_icmp_compute_checksum (vm, 0, ip, &bogus_length);
-
- f = vlib_get_frame_to_node (vm, next_index);
- to_next = vlib_frame_vector_args (f);
- to_next[0] = ci0;
- f->n_vectors = 1;
- vlib_put_frame_to_node (vm, next_index, f);
-
- if (params->mrc != 0 && --client_state->n_left == 0)
- stop_sending_client_message (vm, client_state);
- else
- {
- client_state->sleep_interval =
- (2 + random_f64_from_to (-0.1, 0.1)) * client_state->sleep_interval;
- if (client_state->sleep_interval > params->mrt)
- client_state->sleep_interval =
- (1 + random_f64_from_to (-0.1, 0.1)) * params->mrt;
-
- client_state->due_time = current_time + client_state->sleep_interval;
-
- if (params->mrd != 0
- && current_time > client_state->start_time + params->mrd)
- stop_sending_client_message (vm, client_state);
- else
- *due_time = client_state->due_time;
- }
-
- return client_state->keep_sending_client_message;
-}
-
-static uword
-send_dhcp6_pd_client_message_process (vlib_main_t * vm,
- vlib_node_runtime_t * rt,
- vlib_frame_t * f0)
-{
- dhcp6_pd_client_main_t *cm = &dhcp6_pd_client_main;
- dhcp6_pd_client_state_t *client_state;
- uword *event_data = 0;
- f64 sleep_time = 1e9;
- f64 current_time;
- f64 due_time;
- f64 dt = 0;
- int i;
-
- while (true)
- {
- vlib_process_wait_for_event_or_clock (vm, sleep_time);
- vlib_process_get_events (vm, &event_data);
- vec_reset_length (event_data);
-
- current_time = vlib_time_now (vm);
- do
- {
- due_time = current_time + 1e9;
- for (i = 0; i < vec_len (cm->client_state_by_sw_if_index); i++)
- {
- client_state = &cm->client_state_by_sw_if_index[i];
- if (!client_state->entry_valid)
- continue;
- if (check_pd_send_client_message
- (vm, client_state, current_time, &dt) && (dt < due_time))
- due_time = dt;
- }
- current_time = vlib_time_now (vm);
- }
- while (due_time < current_time);
-
- sleep_time = due_time - current_time;
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (send_dhcp6_pd_client_message_process_node, static) = {
- .function = send_dhcp6_pd_client_message_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "send-dhcp6-pd-client-message-process",
-};
-/* *INDENT-ON* */
-
-void
-dhcp6_pd_send_client_message (vlib_main_t * vm, u32 sw_if_index, u8 stop,
- dhcp6_pd_send_client_message_params_t * params)
-{
- dhcp6_pd_client_main_t *cm = &dhcp6_pd_client_main;
- dhcp6_pd_client_state_t *client_state = 0;
- dhcp6_pd_client_state_t empty_state = {
- 0,
- };
-
- ASSERT (~0 != sw_if_index);
-
- vec_validate_init_empty (cm->client_state_by_sw_if_index, sw_if_index,
- empty_state);
- client_state = &cm->client_state_by_sw_if_index[sw_if_index];
- if (!client_state->entry_valid)
- {
- client_state->entry_valid = 1;
- client_state->adj_index = ~0;
- }
-
- stop_sending_client_message (vm, client_state);
-
- if (!stop)
- {
- client_state->keep_sending_client_message = 1;
- vec_free (client_state->params.prefixes);
- client_state->params = *params;
- client_state->params.prefixes = vec_dup (params->prefixes);
- client_state->n_left = params->mrc;
- client_state->start_time = vlib_time_now (vm);
- client_state->sleep_interval =
- (1 + random_f64_from_to (-0.1, 0.1)) * params->irt;
- client_state->due_time = 0; /* send first packet ASAP */
- client_state->transaction_id = random_u32 (&cm->seed) & 0x00ffffff;
- client_state->buffer =
- create_buffer_for_client_message (vm, sw_if_index, client_state,
- params->msg_type);
- if (!client_state->buffer)
- client_state->keep_sending_client_message = 0;
- else
- vlib_process_signal_event (vm,
- send_dhcp6_pd_client_message_process_node.index,
- 1, 0);
- }
-}
-
-void
- vl_api_dhcp6_pd_send_client_message_t_handler
- (vl_api_dhcp6_pd_send_client_message_t * mp)
-{
- vl_api_dhcp6_pd_send_client_message_reply_t *rmp;
- dhcp6_pd_send_client_message_params_t params;
- vlib_main_t *vm = vlib_get_main ();
- u32 n_prefixes;
- u32 i;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (mp);
-
- BAD_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_DHCP6_PD_SEND_CLIENT_MESSAGE_REPLY);
-
- if (rv != 0)
- return;
-
- params.sw_if_index = ntohl (mp->sw_if_index);
- params.server_index = ntohl (mp->server_index);
- params.irt = ntohl (mp->irt);
- params.mrt = ntohl (mp->mrt);
- params.mrc = ntohl (mp->mrc);
- params.mrd = ntohl (mp->mrd);
- params.msg_type = ntohl (mp->msg_type);
- params.T1 = ntohl (mp->T1);
- params.T2 = ntohl (mp->T2);
- n_prefixes = ntohl (mp->n_prefixes);
- params.prefixes = 0;
- if (n_prefixes > 0)
- vec_validate (params.prefixes, n_prefixes - 1);
- for (i = 0; i < n_prefixes; i++)
- {
- vl_api_dhcp6_pd_prefix_info_t *pi = &mp->prefixes[i];
- dhcp6_pd_send_client_message_params_prefix_t *pref =
- &params.prefixes[i];
- pref->preferred_lt = ntohl (pi->preferred_time);
- pref->valid_lt = ntohl (pi->valid_time);
- ip6_address_decode (pi->prefix.address, &pref->prefix);
- pref->prefix_length = pi->prefix.len;
- }
-
- dhcp6_pd_send_client_message (vm, ntohl (mp->sw_if_index), mp->stop,
- &params);
-}
-
-static clib_error_t *
-call_dhcp6_pd_reply_event_callbacks (void *data,
- _vnet_dhcp6_pd_reply_event_function_list_elt_t
- * elt)
-{
- clib_error_t *error = 0;
-
- while (elt)
- {
- error = elt->fp (data);
- if (error)
- return error;
- elt = elt->next_dhcp6_pd_reply_event_function;
- }
-
- return error;
-}
-
-static uword
-dhcp6_pd_reply_process (vlib_main_t * vm, vlib_node_runtime_t * rt,
- vlib_frame_t * f)
-{
- /* These cross the longjmp boundary (vlib_process_wait_for_event)
- * and need to be volatile - to prevent them from being optimized into
- * a register - which could change during suspension */
-
- while (1)
- {
- vlib_process_wait_for_event (vm);
- uword event_type = DHCP6_PD_DP_REPLY_REPORT;
- void *event_data = vlib_process_get_event_data (vm, &event_type);
-
- int i;
- if (event_type == DHCP6_PD_DP_REPLY_REPORT)
- {
- prefix_report_t *events = event_data;
- for (i = 0; i < vec_len (events); i++)
- {
- u32 event_size =
- sizeof (vl_api_dhcp6_pd_reply_event_t) +
- vec_len (events[i].prefixes) *
- sizeof (vl_api_dhcp6_pd_prefix_info_t);
- vl_api_dhcp6_pd_reply_event_t *event =
- clib_mem_alloc (event_size);
- clib_memset (event, 0, event_size);
-
- event->sw_if_index = htonl (events[i].body.sw_if_index);
- event->server_index = htonl (events[i].body.server_index);
- event->msg_type = events[i].body.msg_type;
- event->T1 = htonl (events[i].body.T1);
- event->T2 = htonl (events[i].body.T2);
- event->inner_status_code =
- htons (events[i].body.inner_status_code);
- event->status_code = htons (events[i].body.status_code);
- event->preference = events[i].body.preference;
-
- event->n_prefixes = htonl (vec_len (events[i].prefixes));
- vl_api_dhcp6_pd_prefix_info_t *prefix =
- (typeof (prefix)) event->prefixes;
- u32 j;
- for (j = 0; j < vec_len (events[i].prefixes); j++)
- {
- dhcp6_prefix_info_t *info = &events[i].prefixes[j];
- ip6_address_encode (&info->prefix, prefix->prefix.address);
- prefix->prefix.len = info->prefix_length;
- prefix->valid_time = htonl (info->valid_time);
- prefix->preferred_time = htonl (info->preferred_time);
- prefix++;
- }
- vec_free (events[i].prefixes);
-
- dhcp6_pd_client_public_main_t *dpcpm =
- &dhcp6_pd_client_public_main;
- call_dhcp6_pd_reply_event_callbacks (event, dpcpm->functions);
-
- vpe_client_registration_t *reg;
- /* *INDENT-OFF* */
- pool_foreach(reg, vpe_api_main.dhcp6_pd_reply_events_registrations,
- ({
- vl_api_registration_t *vl_reg;
- vl_reg =
- vl_api_client_index_to_registration (reg->client_index);
- if (vl_reg && vl_api_can_send_msg (vl_reg))
- {
- vl_api_dhcp6_pd_reply_event_t *msg =
- vl_msg_api_alloc (event_size);
- clib_memcpy (msg, event, event_size);
- msg->_vl_msg_id = htons (VL_API_DHCP6_PD_REPLY_EVENT);
- msg->client_index = reg->client_index;
- msg->pid = reg->client_pid;
- vl_api_send_msg (vl_reg, (u8 *) msg);
- }
- }));
- /* *INDENT-ON* */
-
- clib_mem_free (event);
- }
- }
- vlib_process_put_event_data (vm, event_data);
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp6_pd_reply_process_node) = {
- .function = dhcp6_pd_reply_process,
- .type = VLIB_NODE_TYPE_PROCESS,
- .name = "dhcp6-pd-reply-publisher-process",
-};
-/* *INDENT-ON* */
-
-void
- vl_api_want_dhcp6_pd_reply_events_t_handler
- (vl_api_want_dhcp6_pd_reply_events_t * mp)
-{
- vpe_api_main_t *am = &vpe_api_main;
- vl_api_want_dhcp6_pd_reply_events_reply_t *rmp;
- int rv = 0;
-
- uword *p =
- hash_get (am->dhcp6_pd_reply_events_registration_hash, mp->client_index);
- vpe_client_registration_t *rp;
- if (p)
- {
- if (mp->enable_disable)
- {
- clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto reply;
- }
- else
- {
- rp =
- pool_elt_at_index (am->dhcp6_pd_reply_events_registrations, p[0]);
- pool_put (am->dhcp6_pd_reply_events_registrations, rp);
- hash_unset (am->dhcp6_pd_reply_events_registration_hash,
- mp->client_index);
- if (pool_elts (am->dhcp6_pd_reply_events_registrations) == 0)
- dhcp6_pd_set_publisher_node (~0, DHCP6_PD_DP_REPORT_MAX);
- goto reply;
- }
- }
- if (mp->enable_disable == 0)
- {
- clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
- rv = VNET_API_ERROR_INVALID_REGISTRATION;
- goto reply;
- }
- pool_get (am->dhcp6_pd_reply_events_registrations, rp);
- rp->client_index = mp->client_index;
- rp->client_pid = ntohl (mp->pid);
- hash_set (am->dhcp6_pd_reply_events_registration_hash, rp->client_index,
- rp - am->dhcp6_pd_reply_events_registrations);
- dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index,
- DHCP6_PD_DP_REPLY_REPORT);
-
-reply:
- REPLY_MACRO (VL_API_WANT_DHCP6_PD_REPLY_EVENTS_REPLY);
-}
-
-static clib_error_t *
-dhcp6_pd_client_init (vlib_main_t * vm)
-{
- dhcp6_pd_client_main_t *cm = &dhcp6_pd_client_main;
-
- cm->vlib_main = vm;
- cm->vnet_main = vnet_get_main ();
- cm->publisher_node = ~0;
- cm->seed = (u32) clib_cpu_time_now ();
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (dhcp6_pd_client_init);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_pd_client_dp.h b/src/vnet/dhcp/dhcp6_pd_client_dp.h
deleted file mode 100644
index 88c731c2e67..00000000000
--- a/src/vnet/dhcp/dhcp6_pd_client_dp.h
+++ /dev/null
@@ -1,179 +0,0 @@
-/*
- * Copyright (c) 2018 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef included_vnet_dhcp6_pd_client_dp_h
-#define included_vnet_dhcp6_pd_client_dp_h
-
-#include <vlib/vlib.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-
-typedef struct
-{
- u32 preferred_lt;
- u32 valid_lt;
- ip6_address_t prefix;
- u8 prefix_length;
-} dhcp6_pd_send_client_message_params_prefix_t;
-
-typedef struct
-{
- u32 sw_if_index;
- u32 server_index;
- u32 irt;
- u32 mrt;
- u32 mrc;
- u32 mrd;
- u8 msg_type;
- u32 T1;
- u32 T2;
- dhcp6_pd_send_client_message_params_prefix_t *prefixes;
-} dhcp6_pd_send_client_message_params_t;
-
-typedef struct
-{
- u8 entry_valid;
- u8 keep_sending_client_message; /* when true then next fields are valid */
- dhcp6_pd_send_client_message_params_t params;
- f64 transaction_start;
- f64 sleep_interval;
- f64 due_time;
- u32 n_left;
- f64 start_time;
- u32 transaction_id;
- vlib_buffer_t *buffer;
- u32 elapsed_pos;
- u32 adj_index;
-} dhcp6_pd_client_state_t;
-
-typedef struct
-{
- dhcp6_pd_client_state_t *client_state_by_sw_if_index;
-
- uword publisher_node;
- uword publisher_et;
-
- u32 seed;
-
- /* convenience */
- vlib_main_t *vlib_main;
- vnet_main_t *vnet_main;
-} dhcp6_pd_client_main_t;
-
-extern dhcp6_pd_client_main_t dhcp6_pd_client_main;
-
-typedef struct
-{
- ip6_address_t prefix;
- u8 prefix_length;
- u32 valid_time;
- u32 preferred_time;
- u16 status_code;
-} dhcp6_prefix_info_t;
-
-typedef struct
-{
- dhcp6_report_common_t body;
- u32 n_prefixes;
- dhcp6_prefix_info_t *prefixes;
-} prefix_report_t;
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-void dhcp6_pd_send_client_message (vlib_main_t * vm, u32 sw_if_index, u8 stop,
- dhcp6_pd_send_client_message_params_t *
- params);
-void dhcp6_pd_set_publisher_node (uword node_index, uword event_type);
-int dhcp6_pd_publish_report (prefix_report_t * r);
-
-void
- vl_api_want_dhcp6_pd_reply_events_t_handler
- (vl_api_want_dhcp6_pd_reply_events_t * mp);
-void
- vl_api_dhcp6_pd_send_client_message_t_handler
- (vl_api_dhcp6_pd_send_client_message_t * mp);
-void
- vl_api_dhcp6_clients_enable_disable_t_handler
- (vl_api_dhcp6_clients_enable_disable_t * mp);
-
-extern vlib_node_registration_t dhcp6_pd_reply_process_node;
-
-enum
-{ DHCP6_PD_DP_REPLY_REPORT, DHCP6_PD_DP_REPORT_MAX };
-
-typedef struct _vnet_dhcp6_pd_reply_function_list_elt
-{
- struct _vnet_dhcp6_pd_reply_function_list_elt
- *next_dhcp6_pd_reply_event_function;
- clib_error_t *(*fp) (vl_api_dhcp6_pd_reply_event_t * mp);
-} _vnet_dhcp6_pd_reply_event_function_list_elt_t;
-
-typedef struct
-{
- _vnet_dhcp6_pd_reply_event_function_list_elt_t *functions;
-} dhcp6_pd_client_public_main_t;
-
-extern dhcp6_pd_client_public_main_t dhcp6_pd_client_public_main;
-
-#define VNET_DHCP6_PD_REPLY_EVENT_FUNCTION(f) \
- \
-static void __vnet_dhcp6_pd_reply_event_function_init_##f (void) \
- __attribute__((__constructor__)) ; \
- \
-static void __vnet_dhcp6_pd_reply_event_function_init_##f (void) \
-{ \
- dhcp6_pd_client_public_main_t * nm = &dhcp6_pd_client_public_main; \
- static _vnet_dhcp6_pd_reply_event_function_list_elt_t init_function; \
- init_function.next_dhcp6_pd_reply_event_function = nm->functions; \
- nm->functions = &init_function; \
- init_function.fp = (void *) &f; \
-} \
- \
-static void __vnet_dhcp6_pd_reply_event_function_deinit_##f (void) \
- __attribute__((__destructor__)) ; \
- \
-static void __vnet_dhcp6_pd_reply_event_function_deinit_##f (void) \
-{ \
- dhcp6_pd_client_public_main_t * nm = &dhcp6_pd_client_public_main; \
- _vnet_dhcp6_pd_reply_event_function_list_elt_t *next; \
- if (nm->functions->fp == (void *) &f) \
- { \
- nm->functions = \
- nm->functions->next_dhcp6_pd_reply_event_function; \
- return; \
- } \
- next = nm->functions; \
- while (next->next_dhcp6_pd_reply_event_function) \
- { \
- if (next->next_dhcp6_pd_reply_event_function->fp == (void *) &f) \
- { \
- next->next_dhcp6_pd_reply_event_function = \
- next->next_dhcp6_pd_reply_event_function->next_dhcp6_pd_reply_event_function; \
- return; \
- } \
- next = next->next_dhcp6_pd_reply_event_function; \
- } \
-}
-
-#endif /* included_vnet_dhcp6_pd_client_dp_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp6_pd_doc.md b/src/vnet/dhcp/dhcp6_pd_doc.md
deleted file mode 100644
index 0d0e0865f1b..00000000000
--- a/src/vnet/dhcp/dhcp6_pd_doc.md
+++ /dev/null
@@ -1,86 +0,0 @@
-# DHCPv6 prefix delegation {#dhcp6_pd_doc}
-
-DHCPv6 prefix delegation client implementation is split between Control Plane and Data Plane.
-Data Plane can also be used alone by external application (external Control Plane) using Data Plane Binary API.
-
-Number of different IA\_PDs managed by VPP is currently limited to 1 (and corresponding IAID has value 1).
-Client ID is of type DUID-LLT (Link Layer address plus time) and is created on VPP startup from avaliable interfaces (or chosen at random for debugging purposes).
-Server ID is only visible to Data Plane. Control Plane identifies servers by a 32-bit handle (server\_index) mapped to Server ID by Data Plane.
-
-## Control Plane
-
-DHCPv6 PD clients are configured per interface.
-When configuring a PD client we have to choose a name of a prefix group for that client.
-Each prefix obtained through this client will be flagged as belonging to specified prefix group.
-The prefix groups are used as a filter by prefix consumers.
-
-To enable client on particular interface call Binary API function dhcp6\_pd\_client\_enable\_disable with param 'sw\_if\_index' set to that interface,
-'prefix\_group' set to prefix group name and 'enable' set to true.
-Format of corresponding Debug CLI command is: "dhcp6 pd client <interface> [disable]"
-
-To add/delete IPv6 address potentially using available prefix from specified prefix group call Binary API command ip6\_add\_del\_address\_using\_prefix with parameters:
-> sw\_if\_index - software interface index of interface to add/delete address to/from
-> prefix\_group - name of prefix group, prefix\_group[0] == '\0' means no prefix should be used
-> address - address or suffix to be used with a prefix from selected group
-> prefix\_length - subnet prefix for the address
-> is\_add - 1 for add, 0 for remove
-or Debug CLI command with format: "set ip6 addresses <interface> [prefix group <n>] <address> [del]"
-
-When no prefix is avaliable, no address is physically added, but is added once a prefix becomes avaliable.
-Address is removed when all available prefixes are removed.
-When a used prefix is removed and there is other available prefix, the address that used the prefix is reconfigured using the available prefix.
-
-There are three debug CLI commands (with no parameters) used to show the state of clients, prefixes and addresses:
- show ip6 pd clients
- show ip6 prefixes
- show ip6 addresses
-
-### Example configuration
-
-set int state GigabitEthernet0/8/0 up
-dhcp6 pd client GigabitEthernet0/8/0 prefix group my-dhcp6-pd-group
-set ip6 address GigabitEthernet0/8/0 prefix group my-dhcp6-pd-group ::7/64
-
-## Data Plane
-
-First API message to be called is dhcp6\_clients\_enable\_disable with enable parameter set to 1.
-It enables DHCPv6 client subsystem to receive UDP messages containing DHCPv6 client port (sets the router to DHCPv6 client mode).
-This is to ensure client subsystem gets the messages instead of DHCPv6 proxy subsystem.
-
-There is one common Binary API call for sending DHCPv6 client messages (dhcp6\_pd\_send\_client\_message) with these fields:
-> msg\_type - message type (e.g. Solicit)
-> sw\_if\_index - index of TX interface
-> server\_index - used to dentify DHCPv6 server,
- unique for each DHCPv6 server on the link,
- value obrtained from dhcp6\_pd\_reply\_event API message,
- use ~0 to send message to all DHCPv6 servers
-> param irt - initial retransmission time
-> param mrt - maximum retransmission time
-> param mrc - maximum retransmission count
-> param mrd - maximum retransmission duration for sending the message
-> stop - if non-zero then stop resending the message, otherwise start sending the message
-> T1 - value of T1 in IA\_PD option
-> T2 - value of T2 in IA\_PD option
-> prefixes - list of prefixes in IA\_PD option
-
-The message is automatically resent by Data Plane based on parameters 'irt', 'mrt', 'mrc' and 'mrd'.
-To stop the resending call the same function (same msg\_type is sufficient) with 'stop' set to 1.
-
-To subscribe for notifications of DHCPv6 messages from server call Binary API function
-want\_dhcp6\_pd\_reply\_events with enable\_disable set to 1
-Notification (dhcp6\_pd\_reply\_event) fileds are:
-> sw\_if\_index - index of RX interface
-> server\_index - used to dentify DHCPv6 server, unique for each DHCPv6 server on the link
-> msg\_type - message type
-> T1 - value of T1 in IA\_PD option
-> T2 - value of T2 in IA\_PD option
-> inner\_status\_code - value of status code inside IA\_PD option
-> status\_code - value of status code
-> preference - value of preference option in reply message
-> prefixes - list of prefixes in IA\_PD option
-
-Prefix is a struct with with these fields:
-> prefix - prefix bytes
-> prefix\_length - prefix length
-> valid\_time - valid lifetime
-> preferred\_time - preferred lifetime
diff --git a/src/vnet/dhcp/dhcp6_proxy_error.def b/src/vnet/dhcp/dhcp6_proxy_error.def
deleted file mode 100644
index 55fa731766c..00000000000
--- a/src/vnet/dhcp/dhcp6_proxy_error.def
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * dhcp_proxy_error.def: dhcp proxy errors
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-dhcpv6_proxy_error (NONE, "no error")
-dhcpv6_proxy_error (NO_SERVER, "no dhcpv6 server configured")
-dhcpv6_proxy_error (RELAY_TO_SERVER, "DHCPV6 packets relayed to the server")
-dhcpv6_proxy_error (RELAY_TO_CLIENT, "DHCPV6 packets relayed to clients")
-dhcpv6_proxy_error (NO_INTERFACE_ADDRESS, "DHCPV6 no interface address")
-dhcpv6_proxy_error (WRONG_MESSAGE_TYPE, "DHCPV6 wrong message type.")
-dhcpv6_proxy_error (NO_SRC_ADDRESS, "DHCPV6 no srouce IPv6 address configured.")
-dhcpv6_proxy_error (NO_CIRCUIT_ID_OPTION, "DHCPv6 reply packets without circuit ID option")
-dhcpv6_proxy_error (NO_RELAY_MESSAGE_OPTION, "DHCPv6 reply packets without relay message option")
-dhcpv6_proxy_error (BAD_SVR_FIB_OR_ADDRESS, "DHCPv6 packets not from DHCPv6 server or server FIB.")
-dhcpv6_proxy_error (PKT_TOO_BIG, "DHCPv6 packets which are too big.")
-dhcpv6_proxy_error (WRONG_INTERFACE_ID_OPTION, "DHCPv6 reply to invalid interface.")
diff --git a/src/vnet/dhcp/dhcp6_proxy_node.c b/src/vnet/dhcp/dhcp6_proxy_node.c
deleted file mode 100644
index 174548f24eb..00000000000
--- a/src/vnet/dhcp/dhcp6_proxy_node.c
+++ /dev/null
@@ -1,1186 +0,0 @@
-/*
- * dhcp6_proxy_node.c: dhcpv6 proxy node processing
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vlib/vlib.h>
-#include <vnet/pg/pg.h>
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/dhcp/dhcp6_packet.h>
-#include <vnet/mfib/mfib_table.h>
-#include <vnet/mfib/ip6_mfib.h>
-#include <vnet/fib/fib.h>
-
-static char *dhcpv6_proxy_error_strings[] = {
-#define dhcpv6_proxy_error(n,s) s,
-#include <vnet/dhcp/dhcp6_proxy_error.def>
-#undef dhcpv6_proxy_error
-};
-
-#define foreach_dhcpv6_proxy_to_server_input_next \
- _ (DROP, "error-drop") \
- _ (LOOKUP, "ip6-lookup") \
- _ (SEND_TO_CLIENT, "dhcpv6-proxy-to-client")
-
-
-typedef enum
-{
-#define _(s,n) DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_##s,
- foreach_dhcpv6_proxy_to_server_input_next
-#undef _
- DHCPV6_PROXY_TO_SERVER_INPUT_N_NEXT,
-} dhcpv6_proxy_to_server_input_next_t;
-
-typedef struct
-{
- /* 0 => to server, 1 => to client */
- int which;
- u8 packet_data[64];
- u32 error;
- u32 sw_if_index;
- u32 original_sw_if_index;
-} dhcpv6_proxy_trace_t;
-
-static vlib_node_registration_t dhcpv6_proxy_to_server_node;
-static vlib_node_registration_t dhcpv6_proxy_to_client_node;
-
-/* all DHCP servers address */
-static ip6_address_t all_dhcpv6_server_address;
-static ip6_address_t all_dhcpv6_server_relay_agent_address;
-
-static u8 *
-format_dhcpv6_proxy_trace (u8 * s, va_list * args)
-{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- dhcpv6_proxy_trace_t *t = va_arg (*args, dhcpv6_proxy_trace_t *);
-
- if (t->which == 0)
- s = format (s, "DHCPV6 proxy: sent to server %U",
- format_ip6_address, &t->packet_data, sizeof (ip6_address_t));
- else
- s = format (s, "DHCPV6 proxy: sent to client from %U",
- format_ip6_address, &t->packet_data, sizeof (ip6_address_t));
- if (t->error != (u32) ~ 0)
- s = format (s, " error: %s\n", dhcpv6_proxy_error_strings[t->error]);
-
- s = format (s, " original_sw_if_index: %d, sw_if_index: %d\n",
- t->original_sw_if_index, t->sw_if_index);
-
- return s;
-}
-
-static u8 *
-format_dhcpv6_proxy_header_with_length (u8 * s, va_list * args)
-{
- dhcpv6_header_t *h = va_arg (*args, dhcpv6_header_t *);
- u32 max_header_bytes = va_arg (*args, u32);
- u32 header_bytes;
-
- header_bytes = sizeof (h[0]);
- if (max_header_bytes != 0 && header_bytes > max_header_bytes)
- return format (s, "dhcpv6 header truncated");
-
- s = format (s, "DHCPV6 Proxy");
-
- return s;
-}
-
-/* get first interface address */
-static ip6_address_t *
-ip6_interface_first_global_or_site_address (ip6_main_t * im, u32 sw_if_index)
-{
- ip_lookup_main_t *lm = &im->lookup_main;
- ip_interface_address_t *ia = 0;
- ip6_address_t *result = 0;
-
- /* *INDENT-OFF* */
- foreach_ip_interface_address (lm, ia, sw_if_index,
- 1 /* honor unnumbered */,
- ({
- ip6_address_t * a = ip_interface_address_get_address (lm, ia);
- if ((a->as_u8[0] & 0xe0) == 0x20 ||
- (a->as_u8[0] & 0xfe) == 0xfc) {
- result = a;
- break;
- }
- }));
- /* *INDENT-ON* */
- return result;
-}
-
-static inline void
-copy_ip6_address (ip6_address_t * dst, ip6_address_t * src)
-{
- dst->as_u64[0] = src->as_u64[0];
- dst->as_u64[1] = src->as_u64[1];
-}
-
-static uword
-dhcpv6_proxy_to_server_input (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
-{
- u32 n_left_from, next_index, *from, *to_next;
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- from = vlib_frame_vector_args (from_frame);
- n_left_from = from_frame->n_vectors;
- u32 pkts_to_server = 0, pkts_to_client = 0, pkts_no_server = 0;
- u32 pkts_no_interface_address = 0, pkts_no_exceeding_max_hop = 0;
- u32 pkts_no_src_address = 0;
- u32 pkts_wrong_msg_type = 0;
- u32 pkts_too_big = 0;
- ip6_main_t *im = &ip6_main;
- ip6_address_t *src;
- int bogus_length;
- dhcp_proxy_t *proxy;
- dhcp_server_t *server;
- u32 rx_fib_idx = 0, server_fib_idx = 0;
-
- next_index = node->cached_next_index;
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- vnet_main_t *vnm = vnet_get_main ();
- u32 sw_if_index = 0;
- u32 rx_sw_if_index = 0;
- vnet_sw_interface_t *swif;
- u32 bi0;
- vlib_buffer_t *b0;
- udp_header_t *u0, *u1;
- dhcpv6_header_t *h0; // client msg hdr
- ip6_header_t *ip0, *ip1;
- ip6_address_t _ia0, *ia0 = &_ia0;
- u32 next0;
- u32 error0 = (u32) ~ 0;
- dhcpv6_option_t *fwd_opt;
- dhcpv6_relay_hdr_t *r1;
- u16 len;
- dhcpv6_int_id_t *id1;
- dhcpv6_vss_t *vss1;
- dhcpv6_client_mac_t *cmac; // client mac
- ethernet_header_t *e_h0;
- u8 client_src_mac[6];
- dhcp_vss_t *vss;
- u8 is_solicit = 0;
-
- bi0 = from[0];
- from += 1;
- n_left_from -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
-
- h0 = vlib_buffer_get_current (b0);
-
- /*
- * udp_local hands us the DHCPV6 header.
- */
- u0 = (void *) h0 - (sizeof (*u0));
- ip0 = (void *) u0 - (sizeof (*ip0));
- e_h0 = (void *) ip0 - ethernet_buffer_header_size (b0);
-
- clib_memcpy (client_src_mac, e_h0->src_address, 6);
-
- switch (h0->msg_type)
- {
- case DHCPV6_MSG_SOLICIT:
- case DHCPV6_MSG_REQUEST:
- case DHCPV6_MSG_CONFIRM:
- case DHCPV6_MSG_RENEW:
- case DHCPV6_MSG_REBIND:
- case DHCPV6_MSG_RELEASE:
- case DHCPV6_MSG_DECLINE:
- case DHCPV6_MSG_INFORMATION_REQUEST:
- case DHCPV6_MSG_RELAY_FORW:
- /* send to server */
- break;
- case DHCPV6_MSG_RELAY_REPL:
- /* send to client */
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_SEND_TO_CLIENT;
- error0 = 0;
- pkts_to_client++;
- goto do_enqueue;
- default:
- /* drop the packet */
- pkts_wrong_msg_type++;
- error0 = DHCPV6_PROXY_ERROR_WRONG_MESSAGE_TYPE;
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- goto do_trace;
-
- }
-
- /* Send to DHCPV6 server via the configured FIB */
- rx_sw_if_index = sw_if_index =
- vnet_buffer (b0)->sw_if_index[VLIB_RX];
- rx_fib_idx = im->mfib_index_by_sw_if_index[rx_sw_if_index];
- proxy = dhcp_get_proxy (dpm, rx_fib_idx, FIB_PROTOCOL_IP6);
-
- if (PREDICT_FALSE (NULL == proxy))
- {
- error0 = DHCPV6_PROXY_ERROR_NO_SERVER;
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_server++;
- goto do_trace;
- }
-
- server = &proxy->dhcp_servers[0];
- server_fib_idx = server->server_fib_index;
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = server_fib_idx;
-
-
- /* relay-option header pointer */
- vlib_buffer_advance (b0, -(sizeof (*fwd_opt)));
- fwd_opt = vlib_buffer_get_current (b0);
- /* relay message header pointer */
- vlib_buffer_advance (b0, -(sizeof (*r1)));
- r1 = vlib_buffer_get_current (b0);
-
- vlib_buffer_advance (b0, -(sizeof (*u1)));
- u1 = vlib_buffer_get_current (b0);
-
- vlib_buffer_advance (b0, -(sizeof (*ip1)));
- ip1 = vlib_buffer_get_current (b0);
-
- /* fill in all that rubbish... */
- len = clib_net_to_host_u16 (u0->length) - sizeof (udp_header_t);
- copy_ip6_address (&r1->peer_addr, &ip0->src_address);
-
- r1->msg_type = DHCPV6_MSG_RELAY_FORW;
- fwd_opt->length = clib_host_to_net_u16 (len);
- fwd_opt->option = clib_host_to_net_u16 (DHCPV6_OPTION_RELAY_MSG);
-
- r1->hop_count++;
- r1->hop_count =
- (h0->msg_type != DHCPV6_MSG_RELAY_FORW) ? 0 : r1->hop_count;
-
- if (PREDICT_FALSE (r1->hop_count >= HOP_COUNT_LIMIT))
- {
- error0 = DHCPV6_RELAY_PKT_DROP_MAX_HOPS;
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_exceeding_max_hop++;
- goto do_trace;
- }
-
-
- /* If relay-fwd and src address is site or global unicast address */
- if (h0->msg_type == DHCPV6_MSG_RELAY_FORW &&
- ((ip0->src_address.as_u8[0] & 0xe0) == 0x20 ||
- (ip0->src_address.as_u8[0] & 0xfe) == 0xfc))
- {
- /* Set link address to zero */
- r1->link_addr.as_u64[0] = 0;
- r1->link_addr.as_u64[1] = 0;
- goto link_address_set;
- }
-
- /* if receiving interface is unnumbered, use receiving interface
- * IP address as link address, otherwise use the loopback interface
- * IP address as link address.
- */
-
- swif = vnet_get_sw_interface (vnm, rx_sw_if_index);
- if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
- sw_if_index = swif->unnumbered_sw_if_index;
-
- ia0 =
- ip6_interface_first_global_or_site_address (&ip6_main,
- sw_if_index);
- if (ia0 == 0)
- {
- error0 = DHCPV6_PROXY_ERROR_NO_INTERFACE_ADDRESS;
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_interface_address++;
- goto do_trace;
- }
-
- copy_ip6_address (&r1->link_addr, ia0);
-
- link_address_set:
-
- if ((b0->current_length + sizeof (*id1) + sizeof (*vss1) +
- sizeof (*cmac)) > vlib_buffer_get_default_data_size (vm))
- {
- error0 = DHCPV6_PROXY_ERROR_PKT_TOO_BIG;
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_too_big++;
- goto do_trace;
- }
-
- id1 = (dhcpv6_int_id_t *) (((uword) ip1) + b0->current_length);
- b0->current_length += (sizeof (*id1));
-
- id1->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_INTERFACE_ID);
- id1->opt.length = clib_host_to_net_u16 (sizeof (rx_sw_if_index));
- id1->int_idx = clib_host_to_net_u32 (rx_sw_if_index);
-
- u1->length = 0;
- if (h0->msg_type != DHCPV6_MSG_RELAY_FORW)
- {
- cmac =
- (dhcpv6_client_mac_t *) (((uword) ip1) + b0->current_length);
- b0->current_length += (sizeof (*cmac));
- cmac->opt.length = clib_host_to_net_u16 (sizeof (*cmac) -
- sizeof (cmac->opt));
- cmac->opt.option =
- clib_host_to_net_u16
- (DHCPV6_OPTION_CLIENT_LINK_LAYER_ADDRESS);
- cmac->link_type = clib_host_to_net_u16 (1); /* ethernet */
- clib_memcpy (cmac->data, client_src_mac, 6);
- u1->length += sizeof (*cmac);
- }
-
- vss = dhcp_get_vss_info (dpm, rx_fib_idx, FIB_PROTOCOL_IP6);
-
- if (vss)
- {
- u16 id_len; /* length of VPN ID */
- u16 type_len = sizeof (vss1->vss_type);
-
- vss1 = (dhcpv6_vss_t *) (((uword) ip1) + b0->current_length);
- vss1->vss_type = vss->vss_type;
- if (vss->vss_type == VSS_TYPE_VPN_ID)
- {
- id_len = sizeof (vss->vpn_id); /* vpn_id is 7 bytes */
- memcpy (vss1->data, vss->vpn_id, id_len);
- }
- else if (vss->vss_type == VSS_TYPE_ASCII)
- {
- id_len = vec_len (vss->vpn_ascii_id);
- memcpy (vss1->data, vss->vpn_ascii_id, id_len);
- }
- else /* must be VSS_TYPE_DEFAULT, no VPN ID */
- id_len = 0;
-
- vss1->opt.option = clib_host_to_net_u16 (DHCPV6_OPTION_VSS);
- vss1->opt.length = clib_host_to_net_u16 (type_len + id_len);
- u1->length += type_len + id_len + sizeof (vss1->opt);
- b0->current_length += type_len + id_len + sizeof (vss1->opt);
- }
-
- pkts_to_server++;
- u1->checksum = 0;
- u1->src_port = clib_host_to_net_u16 (UDP_DST_PORT_dhcpv6_to_client);
- u1->dst_port = clib_host_to_net_u16 (UDP_DST_PORT_dhcpv6_to_server);
-
- u1->length =
- clib_host_to_net_u16 (clib_net_to_host_u16 (fwd_opt->length) +
- sizeof (*r1) + sizeof (*fwd_opt) +
- sizeof (*u1) + sizeof (*id1) + u1->length);
-
- clib_memset (ip1, 0, sizeof (*ip1));
- ip1->ip_version_traffic_class_and_flow_label = 0x60;
- ip1->payload_length = u1->length;
- ip1->protocol = PROTO_UDP;
- ip1->hop_limit = HOP_COUNT_LIMIT;
- src = ((server->dhcp_server.ip6.as_u64[0] ||
- server->dhcp_server.ip6.as_u64[1]) ?
- &server->dhcp_server.ip6 : &all_dhcpv6_server_address);
- copy_ip6_address (&ip1->dst_address, src);
-
-
- ia0 = ip6_interface_first_global_or_site_address
- (&ip6_main, vnet_buffer (b0)->sw_if_index[VLIB_RX]);
-
- src = (proxy->dhcp_src_address.ip6.as_u64[0] ||
- proxy->dhcp_src_address.ip6.as_u64[1]) ?
- &proxy->dhcp_src_address.ip6 : ia0;
- if (ia0 == 0)
- {
- error0 = DHCPV6_PROXY_ERROR_NO_SRC_ADDRESS;
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_src_address++;
- goto do_trace;
- }
-
- copy_ip6_address (&ip1->src_address, src);
-
-
- u1->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip1,
- &bogus_length);
- ASSERT (bogus_length == 0);
-
- next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP;
-
- is_solicit = (DHCPV6_MSG_SOLICIT == h0->msg_type);
-
- /*
- * If we have multiple servers configured and this is the
- * client's discover message, then send copies to each of
- * those servers
- */
- if (is_solicit && vec_len (proxy->dhcp_servers) > 1)
- {
- u32 ii;
-
- for (ii = 1; ii < vec_len (proxy->dhcp_servers); ii++)
- {
- vlib_buffer_t *c0;
- u32 ci0;
-
- c0 = vlib_buffer_copy (vm, b0);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (c0);
- ci0 = vlib_get_buffer_index (vm, c0);
- server = &proxy->dhcp_servers[ii];
-
- ip0 = vlib_buffer_get_current (c0);
-
- src = ((server->dhcp_server.ip6.as_u64[0] ||
- server->dhcp_server.ip6.as_u64[1]) ?
- &server->dhcp_server.ip6 :
- &all_dhcpv6_server_address);
- copy_ip6_address (&ip1->dst_address, src);
-
- to_next[0] = ci0;
- to_next += 1;
- n_left_to_next -= 1;
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- ci0, next0);
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcpv6_proxy_trace_t *tr;
-
- tr = vlib_add_trace (vm, node, c0, sizeof (*tr));
- tr->which = 0; /* to server */
- tr->error = error0;
- tr->original_sw_if_index = rx_sw_if_index;
- tr->sw_if_index = sw_if_index;
- if (next0 == DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
- copy_ip6_address ((ip6_address_t *) &
- tr->packet_data[0],
- &server->dhcp_server.ip6);
- }
-
- if (PREDICT_FALSE (0 == n_left_to_next))
- {
- vlib_put_next_frame (vm, node, next_index,
- n_left_to_next);
- vlib_get_next_frame (vm, node, next_index,
- to_next, n_left_to_next);
- }
- }
- }
-
- do_trace:
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcpv6_proxy_trace_t *tr = vlib_add_trace (vm, node,
- b0, sizeof (*tr));
- tr->which = 0; /* to server */
- tr->error = error0;
- tr->original_sw_if_index = rx_sw_if_index;
- tr->sw_if_index = sw_if_index;
- if (DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP == next0)
- copy_ip6_address ((ip6_address_t *) & tr->packet_data[0],
- &server->dhcp_server.ip6);
- }
-
- do_enqueue:
- to_next[0] = bi0;
- to_next += 1;
- n_left_to_next -= 1;
-
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_server_node.index,
- DHCPV6_PROXY_ERROR_RELAY_TO_CLIENT,
- pkts_to_client);
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_server_node.index,
- DHCPV6_PROXY_ERROR_RELAY_TO_SERVER,
- pkts_to_server);
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_server_node.index,
- DHCPV6_PROXY_ERROR_NO_INTERFACE_ADDRESS,
- pkts_no_interface_address);
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_server_node.index,
- DHCPV6_PROXY_ERROR_WRONG_MESSAGE_TYPE,
- pkts_wrong_msg_type);
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_server_node.index,
- DHCPV6_PROXY_ERROR_NO_SRC_ADDRESS,
- pkts_no_src_address);
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_server_node.index,
- DHCPV6_PROXY_ERROR_PKT_TOO_BIG, pkts_too_big);
- return from_frame->n_vectors;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcpv6_proxy_to_server_node, static) = {
- .function = dhcpv6_proxy_to_server_input,
- .name = "dhcpv6-proxy-to-server",
- /* Takes a vector of packets. */
- .vector_size = sizeof (u32),
-
- .n_errors = DHCPV6_PROXY_N_ERROR,
- .error_strings = dhcpv6_proxy_error_strings,
-
- .n_next_nodes = DHCPV6_PROXY_TO_SERVER_INPUT_N_NEXT,
- .next_nodes = {
-#define _(s,n) [DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_##s] = n,
- foreach_dhcpv6_proxy_to_server_input_next
-#undef _
- },
-
- .format_buffer = format_dhcpv6_proxy_header_with_length,
- .format_trace = format_dhcpv6_proxy_trace,
-#if 0
- .unformat_buffer = unformat_dhcpv6_proxy_header,
-#endif
-};
-/* *INDENT-ON* */
-
-static uword
-dhcpv6_proxy_to_client_input (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * from_frame)
-{
-
- u32 n_left_from, *from;
- ethernet_main_t *em = vnet_get_ethernet_main ();
- dhcp_proxy_main_t *dm = &dhcp_proxy_main;
- dhcp_proxy_t *proxy;
- dhcp_server_t *server;
- vnet_main_t *vnm = vnet_get_main ();
- int bogus_length;
-
- from = vlib_frame_vector_args (from_frame);
- n_left_from = from_frame->n_vectors;
-
- while (n_left_from > 0)
- {
- u32 bi0;
- vlib_buffer_t *b0;
- udp_header_t *u0, *u1 = 0;
- dhcpv6_relay_hdr_t *h0;
- ip6_header_t *ip1 = 0, *ip0;
- ip6_address_t _ia0, *ia0 = &_ia0;
- ip6_address_t client_address;
- ethernet_interface_t *ei0;
- ethernet_header_t *mac0;
- vnet_hw_interface_t *hi0;
- vlib_frame_t *f0;
- u32 *to_next0;
- u32 sw_if_index = ~0;
- u32 original_sw_if_index = ~0;
- vnet_sw_interface_t *si0;
- u32 error0 = (u32) ~ 0;
- vnet_sw_interface_t *swif;
- dhcpv6_option_t *r0 = 0, *o;
- u16 len = 0;
- u8 interface_opt_flag = 0;
- u8 relay_msg_opt_flag = 0;
- ip6_main_t *im = &ip6_main;
- u32 server_fib_idx, client_fib_idx;
-
- bi0 = from[0];
- from += 1;
- n_left_from -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- h0 = vlib_buffer_get_current (b0);
-
- if (DHCPV6_MSG_RELAY_REPL != h0->msg_type)
- {
- error0 = DHCPV6_PROXY_ERROR_WRONG_MESSAGE_TYPE;
-
- drop_packet:
- vlib_node_increment_counter (vm, dhcpv6_proxy_to_client_node.index,
- error0, 1);
-
- f0 = vlib_get_frame_to_node (vm, dm->error_drop_node_index);
- to_next0 = vlib_frame_vector_args (f0);
- to_next0[0] = bi0;
- f0->n_vectors = 1;
- vlib_put_frame_to_node (vm, dm->error_drop_node_index, f0);
- goto do_trace;
- }
- /* hop count seems not need to be checked */
- if (HOP_COUNT_LIMIT < h0->hop_count)
- {
- error0 = DHCPV6_RELAY_PKT_DROP_MAX_HOPS;
- goto drop_packet;
- }
- u0 = (void *) h0 - (sizeof (*u0));
- ip0 = (void *) u0 - (sizeof (*ip0));
-
- vlib_buffer_advance (b0, sizeof (*h0));
- o = vlib_buffer_get_current (b0);
-
- /* Parse through TLVs looking for option 18 (DHCPV6_OPTION_INTERFACE_ID)
- _and_ option 9 (DHCPV6_OPTION_RELAY_MSG) option which must be there.
- Currently assuming no other options need to be processed
- The interface-ID is the FIB number we need
- to track down the client-facing interface */
-
- while ((u8 *) o < (b0->data + b0->current_data + b0->current_length))
- {
- if (DHCPV6_OPTION_INTERFACE_ID == clib_net_to_host_u16 (o->option))
- {
- interface_opt_flag = 1;
- if (clib_net_to_host_u16 (o->length) == sizeof (sw_if_index))
- sw_if_index =
- clib_net_to_host_u32 (((dhcpv6_int_id_t *) o)->int_idx);
- if (sw_if_index >= vec_len (im->fib_index_by_sw_if_index))
- {
- error0 = DHCPV6_PROXY_ERROR_WRONG_INTERFACE_ID_OPTION;
- goto drop_packet;
- }
- }
- if (DHCPV6_OPTION_RELAY_MSG == clib_net_to_host_u16 (o->option))
- {
- relay_msg_opt_flag = 1;
- r0 = vlib_buffer_get_current (b0);
- }
- if ((relay_msg_opt_flag == 1) && (interface_opt_flag == 1))
- break;
- vlib_buffer_advance (b0,
- sizeof (*o) +
- clib_net_to_host_u16 (o->length));
- o =
- (dhcpv6_option_t *) (((uword) o) +
- clib_net_to_host_u16 (o->length) +
- sizeof (*o));
- }
-
- if ((relay_msg_opt_flag == 0) || (r0 == 0))
- {
- error0 = DHCPV6_PROXY_ERROR_NO_RELAY_MESSAGE_OPTION;
- goto drop_packet;
- }
-
- if ((u32) ~ 0 == sw_if_index)
- {
- error0 = DHCPV6_PROXY_ERROR_NO_CIRCUIT_ID_OPTION;
- goto drop_packet;
- }
-
- //Advance buffer to start of encapsulated DHCPv6 message
- vlib_buffer_advance (b0, sizeof (*r0));
-
- client_fib_idx = im->mfib_index_by_sw_if_index[sw_if_index];
- proxy = dhcp_get_proxy (dm, client_fib_idx, FIB_PROTOCOL_IP6);
-
- if (NULL == proxy)
- {
- error0 = DHCPV6_PROXY_ERROR_NO_SERVER;
- goto drop_packet;
- }
-
- server_fib_idx = im->fib_index_by_sw_if_index
- [vnet_buffer (b0)->sw_if_index[VLIB_RX]];
-
- vec_foreach (server, proxy->dhcp_servers)
- {
- if (server_fib_idx == server->server_fib_index &&
- ip0->src_address.as_u64[0] == server->dhcp_server.ip6.as_u64[0] &&
- ip0->src_address.as_u64[1] == server->dhcp_server.ip6.as_u64[1])
- {
- goto server_found;
- }
- }
-
- //drop packet if not from server with configured address or FIB
- error0 = DHCPV6_PROXY_ERROR_BAD_SVR_FIB_OR_ADDRESS;
- goto drop_packet;
-
- server_found:
- vnet_buffer (b0)->sw_if_index[VLIB_TX] = original_sw_if_index
- = sw_if_index;
-
- swif = vnet_get_sw_interface (vnm, original_sw_if_index);
- if (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED)
- sw_if_index = swif->unnumbered_sw_if_index;
-
-
- /*
- * udp_local hands us the DHCPV6 header, need udp hdr,
- * ip hdr to relay to client
- */
- vlib_buffer_advance (b0, -(sizeof (*u1)));
- u1 = vlib_buffer_get_current (b0);
-
- vlib_buffer_advance (b0, -(sizeof (*ip1)));
- ip1 = vlib_buffer_get_current (b0);
-
- copy_ip6_address (&client_address, &h0->peer_addr);
-
- ia0 = ip6_interface_first_address (&ip6_main, sw_if_index);
- if (ia0 == 0)
- {
- error0 = DHCPV6_PROXY_ERROR_NO_INTERFACE_ADDRESS;
- goto drop_packet;
- }
-
- len = clib_net_to_host_u16 (r0->length);
- clib_memset (ip1, 0, sizeof (*ip1));
- copy_ip6_address (&ip1->dst_address, &client_address);
- u1->checksum = 0;
- u1->src_port = clib_net_to_host_u16 (UDP_DST_PORT_dhcpv6_to_server);
- u1->dst_port = clib_net_to_host_u16 (UDP_DST_PORT_dhcpv6_to_client);
- u1->length = clib_host_to_net_u16 (len + sizeof (udp_header_t));
-
- ip1->ip_version_traffic_class_and_flow_label =
- ip0->ip_version_traffic_class_and_flow_label & 0x00000fff;
- ip1->payload_length = u1->length;
- ip1->protocol = PROTO_UDP;
- ip1->hop_limit = HOP_COUNT_LIMIT;
- copy_ip6_address (&ip1->src_address, ia0);
-
- u1->checksum = ip6_tcp_udp_icmp_compute_checksum (vm, b0, ip1,
- &bogus_length);
- ASSERT (bogus_length == 0);
-
- vlib_buffer_advance (b0, -(sizeof (ethernet_header_t)));
- si0 = vnet_get_sw_interface (vnm, original_sw_if_index);
- if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
- vlib_buffer_advance (b0, -4 /* space for VLAN tag */ );
-
- mac0 = vlib_buffer_get_current (b0);
-
- hi0 = vnet_get_sup_hw_interface (vnm, original_sw_if_index);
- ei0 = pool_elt_at_index (em->interfaces, hi0->hw_instance);
- clib_memcpy (mac0->src_address, ei0->address, sizeof (ei0->address));
- clib_memset (&mac0->dst_address, 0xff, sizeof (mac0->dst_address));
- mac0->type = (si0->type == VNET_SW_INTERFACE_TYPE_SUB) ?
- clib_net_to_host_u16 (0x8100) : clib_net_to_host_u16 (0x86dd);
-
- if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
- {
- u32 *vlan_tag = (u32 *) (mac0 + 1);
- u32 tmp;
- tmp = (si0->sub.id << 16) | 0x0800;
- *vlan_tag = clib_host_to_net_u32 (tmp);
- }
-
- /* $$$ consider adding a dynamic next to the graph node, for performance */
- f0 = vlib_get_frame_to_node (vm, hi0->output_node_index);
- to_next0 = vlib_frame_vector_args (f0);
- to_next0[0] = bi0;
- f0->n_vectors = 1;
- vlib_put_frame_to_node (vm, hi0->output_node_index, f0);
-
- do_trace:
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcpv6_proxy_trace_t *tr = vlib_add_trace (vm, node,
- b0, sizeof (*tr));
- tr->which = 1; /* to client */
- if (ia0)
- copy_ip6_address ((ip6_address_t *) tr->packet_data, ia0);
- tr->error = error0;
- tr->original_sw_if_index = original_sw_if_index;
- tr->sw_if_index = sw_if_index;
- }
- }
- return from_frame->n_vectors;
-
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcpv6_proxy_to_client_node, static) = {
- .function = dhcpv6_proxy_to_client_input,
- .name = "dhcpv6-proxy-to-client",
- /* Takes a vector of packets. */
- .vector_size = sizeof (u32),
-
- .n_errors = DHCPV6_PROXY_N_ERROR,
- .error_strings = dhcpv6_proxy_error_strings,
- .format_buffer = format_dhcpv6_proxy_header_with_length,
- .format_trace = format_dhcpv6_proxy_trace,
-#if 0
- .unformat_buffer = unformat_dhcpv6_proxy_header,
-#endif
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcp6_proxy_init (vlib_main_t * vm)
-{
- dhcp_proxy_main_t *dm = &dhcp_proxy_main;
- vlib_node_t *error_drop_node;
-
- error_drop_node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
- dm->error_drop_node_index = error_drop_node->index;
-
- /* RFC says this is the dhcpv6 server address */
- all_dhcpv6_server_address.as_u64[0] =
- clib_host_to_net_u64 (0xFF05000000000000);
- all_dhcpv6_server_address.as_u64[1] = clib_host_to_net_u64 (0x00010003);
-
- /* RFC says this is the server and agent address */
- all_dhcpv6_server_relay_agent_address.as_u64[0] =
- clib_host_to_net_u64 (0xFF02000000000000);
- all_dhcpv6_server_relay_agent_address.as_u64[1] =
- clib_host_to_net_u64 (0x00010002);
-
- return 0;
-}
-
-VLIB_INIT_FUNCTION (dhcp6_proxy_init);
-
-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)
-{
- vlib_main_t *vm = vlib_get_main ();
- u32 rx_fib_index = 0;
- int rc = 0;
-
- const mfib_prefix_t all_dhcp_servers = {
- .fp_len = 128,
- .fp_proto = FIB_PROTOCOL_IP6,
- .fp_grp_addr = {
- .ip6 = all_dhcpv6_server_relay_agent_address,
- }
- };
-
- if (ip46_address_is_zero (addr))
- return VNET_API_ERROR_INVALID_DST_ADDRESS;
-
- if (ip46_address_is_zero (src_addr))
- return VNET_API_ERROR_INVALID_SRC_ADDRESS;
-
- rx_fib_index = mfib_table_find_or_create_and_lock (FIB_PROTOCOL_IP6,
- rx_table_id,
- MFIB_SOURCE_DHCP);
-
- if (is_del)
- {
- if (dhcp_proxy_server_del (FIB_PROTOCOL_IP6, rx_fib_index,
- addr, server_table_id))
- {
- mfib_table_entry_delete (rx_fib_index,
- &all_dhcp_servers, MFIB_SOURCE_DHCP);
- mfib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP6,
- MFIB_SOURCE_DHCP);
-
- udp_unregister_dst_port (vm, UDP_DST_PORT_dhcpv6_to_client,
- 0 /* is_ip6 */ );
- udp_unregister_dst_port (vm, UDP_DST_PORT_dhcpv6_to_server,
- 0 /* is_ip6 */ );
- }
- }
- else
- {
- const fib_route_path_t path_for_us = {
- .frp_proto = DPO_PROTO_IP6,
- .frp_addr = zero_addr,
- .frp_sw_if_index = 0xffffffff,
- .frp_fib_index = ~0,
- .frp_weight = 1,
- .frp_flags = FIB_ROUTE_PATH_LOCAL,
- .frp_mitf_flags = MFIB_ITF_FLAG_FORWARD,
- };
- if (dhcp_proxy_server_add (FIB_PROTOCOL_IP6, addr, src_addr,
- rx_fib_index, server_table_id))
- {
- mfib_table_entry_path_update (rx_fib_index,
- &all_dhcp_servers,
- MFIB_SOURCE_DHCP, &path_for_us);
- /*
- * Each interface that is enabled in this table, needs to be added
- * as an accepting interface, but this is not easily doable in VPP.
- * So we cheat. Add a flag to the entry that indicates accept form
- * any interface.
- * We will still only accept on v6 enabled interfaces, since the
- * input feature ensures this.
- */
- mfib_table_entry_update (rx_fib_index,
- &all_dhcp_servers,
- MFIB_SOURCE_DHCP,
- MFIB_RPF_ID_NONE,
- MFIB_ENTRY_FLAG_ACCEPT_ALL_ITF);
- mfib_table_lock (rx_fib_index, FIB_PROTOCOL_IP6, MFIB_SOURCE_DHCP);
-
- udp_register_dst_port (vm, UDP_DST_PORT_dhcpv6_to_client,
- dhcpv6_proxy_to_client_node.index,
- 0 /* is_ip6 */ );
- udp_register_dst_port (vm, UDP_DST_PORT_dhcpv6_to_server,
- dhcpv6_proxy_to_server_node.index,
- 0 /* is_ip6 */ );
- }
- }
-
- mfib_table_unlock (rx_fib_index, FIB_PROTOCOL_IP6, MFIB_SOURCE_DHCP);
-
- return (rc);
-}
-
-static clib_error_t *
-dhcpv6_proxy_set_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- ip46_address_t addr, src_addr;
- int set_server = 0, set_src_address = 0;
- u32 rx_table_id = 0, server_table_id = 0;
- int is_del = 0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "server %U", unformat_ip6_address, &addr.ip6))
- set_server = 1;
- else if (unformat (input, "src-address %U",
- unformat_ip6_address, &src_addr.ip6))
- set_src_address = 1;
- else if (unformat (input, "server-fib-id %d", &server_table_id))
- ;
- else if (unformat (input, "rx-fib-id %d", &rx_table_id))
- ;
- else if (unformat (input, "delete") || unformat (input, "del"))
- is_del = 1;
- else
- break;
- }
-
- if (is_del || (set_server && set_src_address))
- {
- int rv;
-
- rv = dhcp6_proxy_set_server (&addr, &src_addr, rx_table_id,
- server_table_id, is_del);
-
- //TODO: Complete the errors
- switch (rv)
- {
- case 0:
- return 0;
-
- case VNET_API_ERROR_INVALID_DST_ADDRESS:
- return clib_error_return (0, "Invalid server address");
-
- case VNET_API_ERROR_INVALID_SRC_ADDRESS:
- return clib_error_return (0, "Invalid src address");
-
- case VNET_API_ERROR_NO_SUCH_ENTRY:
- return clib_error_return
- (0, "Fib id %d: no per-fib DHCP server configured", rx_table_id);
-
- default:
- return clib_error_return (0, "BUG: rv %d", rv);
- }
- }
- else
- return clib_error_return (0, "parse error`%U'",
- format_unformat_error, input);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcpv6_proxy_set_command, static) = {
- .path = "set dhcpv6 proxy",
- .short_help = "set dhcpv6 proxy [del] server <ipv6-addr> src-address <ipv6-addr> "
- "[server-fib-id <fib-id>] [rx-fib-id <fib-id>] ",
- .function = dhcpv6_proxy_set_command_fn,
-};
-/* *INDENT-ON* */
-
-static u8 *
-format_dhcp6_proxy_server (u8 * s, va_list * args)
-{
- dhcp_proxy_t *proxy = va_arg (*args, dhcp_proxy_t *);
- fib_table_t *server_fib;
- dhcp_server_t *server;
- ip6_mfib_t *rx_fib;
-
- if (proxy == 0)
- {
- s = format (s, "%=14s%=16s%s", "RX FIB", "Src Address",
- "Servers FIB,Address");
- return s;
- }
-
- rx_fib = ip6_mfib_get (proxy->rx_fib_index);
-
- s = format (s, "%=14u%=16U",
- rx_fib->table_id,
- format_ip46_address, &proxy->dhcp_src_address, IP46_TYPE_ANY);
-
- vec_foreach (server, proxy->dhcp_servers)
- {
- server_fib = fib_table_get (server->server_fib_index, FIB_PROTOCOL_IP6);
- s = format (s, "%u,%U ",
- server_fib->ft_table_id,
- format_ip46_address, &server->dhcp_server, IP46_TYPE_ANY);
- }
-
- return s;
-}
-
-static int
-dhcp6_proxy_show_walk (dhcp_proxy_t * proxy, void *ctx)
-{
- vlib_main_t *vm = ctx;
-
- vlib_cli_output (vm, "%U", format_dhcp6_proxy_server, proxy);
-
- return (1);
-}
-
-static clib_error_t *
-dhcpv6_proxy_show_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- vlib_cli_output (vm, "%U", format_dhcp6_proxy_server,
- NULL /* header line */ );
-
- dhcp_proxy_walk (FIB_PROTOCOL_IP6, dhcp6_proxy_show_walk, vm);
-
- return (NULL);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcpv6_proxy_show_command, static) = {
- .path = "show dhcpv6 proxy",
- .short_help = "Display dhcpv6 proxy info",
- .function = dhcpv6_proxy_show_command_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcpv6_vss_command_fn (vlib_main_t * vm,
- unformat_input_t * input, vlib_cli_command_t * cmd)
-{
- u8 is_del = 0, vss_type = VSS_TYPE_DEFAULT;
- u8 *vpn_ascii_id = 0;
- u32 oui = 0, fib_id = 0, tbl_id = ~0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
- if (unformat (input, "table %d", &tbl_id))
- ;
- else if (unformat (input, "oui %d", &oui))
- vss_type = VSS_TYPE_VPN_ID;
- else if (unformat (input, "vpn-id %d", &fib_id))
- vss_type = VSS_TYPE_VPN_ID;
- else if (unformat (input, "vpn-ascii-id %s", &vpn_ascii_id))
- vss_type = VSS_TYPE_ASCII;
- else if (unformat (input, "delete") || unformat (input, "del"))
- is_del = 1;
- else
- break;
- }
-
- if (tbl_id == ~0)
- return clib_error_return (0, "no table ID specified.");
-
- int rv = dhcp_proxy_set_vss (FIB_PROTOCOL_IP6, tbl_id, vss_type,
- vpn_ascii_id, oui, fib_id, is_del);
- switch (rv)
- {
- case 0:
- return 0;
- case VNET_API_ERROR_NO_SUCH_ENTRY:
- return clib_error_return (0, "vss for table %d not found in pool.",
- tbl_id);
- default:
- return clib_error_return (0, "BUG: rv %d", rv);
- }
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcpv6_proxy_vss_command, static) = {
- .path = "set dhcpv6 vss",
- .short_help = "set dhcpv6 vss table <table-id> [oui <n> vpn-id <n> | vpn-ascii-id <text>]",
- .function = dhcpv6_vss_command_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcpv6_vss_show_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- dhcp_vss_walk (FIB_PROTOCOL_IP6, dhcp_vss_show_walk, vm);
-
- return (NULL);
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcpv6_proxy_vss_show_command, static) = {
- .path = "show dhcpv6 vss",
- .short_help = "show dhcpv6 VSS",
- .function = dhcpv6_vss_show_command_fn,
-};
-/* *INDENT-ON* */
-
-static clib_error_t *
-dhcpv6_link_address_show_command_fn (vlib_main_t * vm,
- unformat_input_t * input,
- vlib_cli_command_t * cmd)
-{
- vnet_main_t *vnm = vnet_get_main ();
- u32 sw_if_index0 = 0, sw_if_index;
- vnet_sw_interface_t *swif;
- ip6_address_t *ia0;
-
- while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
- {
-
- if (unformat (input, "%U",
- unformat_vnet_sw_interface, vnm, &sw_if_index0))
- {
- swif = vnet_get_sw_interface (vnm, sw_if_index0);
- sw_if_index = (swif->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED) ?
- swif->unnumbered_sw_if_index : sw_if_index0;
- ia0 = ip6_interface_first_address (&ip6_main, sw_if_index);
- if (ia0)
- {
- vlib_cli_output (vm, "%=20s%=48s", "interface", "link-address");
-
- vlib_cli_output (vm, "%=20U%=48U",
- format_vnet_sw_if_index_name, vnm,
- sw_if_index0, format_ip6_address, ia0);
- }
- else
- vlib_cli_output (vm, "%=34s%=20U",
- "No IPv6 address configured on",
- format_vnet_sw_if_index_name, vnm, sw_if_index);
- }
- else
- break;
- }
-
- return 0;
-}
-
-/* *INDENT-OFF* */
-VLIB_CLI_COMMAND (dhcpv6_proxy_address_show_command, static) = {
- .path = "show dhcpv6 link-address interface",
- .short_help = "show dhcpv6 link-address interface <interface>",
- .function = dhcpv6_link_address_show_command_fn,
-};
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp_api.c b/src/vnet/dhcp/dhcp_api.c
deleted file mode 100644
index 252f2df7d6b..00000000000
--- a/src/vnet/dhcp/dhcp_api.c
+++ /dev/null
@@ -1,420 +0,0 @@
-/*
- *------------------------------------------------------------------
- * dhcp_api.c - dhcp api
- *
- * Copyright (c) 2016 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *------------------------------------------------------------------
- */
-
-#include <vnet/vnet.h>
-#include <vlibmemory/api.h>
-
-#include <vnet/interface.h>
-#include <vnet/api_errno.h>
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/dhcp/client.h>
-#include <vnet/dhcp/dhcp6_pd_client_dp.h>
-#include <vnet/dhcp/dhcp6_ia_na_client_dp.h>
-#include <vnet/dhcp/dhcp6_client_common_dp.h>
-#include <vnet/fib/fib_table.h>
-#include <vnet/ip/ip_types_api.h>
-
-#include <vnet/vnet_msg_enum.h>
-
-#define vl_typedefs /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_typedefs
-
-#define vl_endianfun /* define message structures */
-#include <vnet/vnet_all_api_h.h>
-#undef vl_endianfun
-
-/* instantiate all the print functions we know about */
-#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
-#define vl_printfun
-#include <vnet/vnet_all_api_h.h>
-#undef vl_printfun
-
-#include <vlibapi/api_helper_macros.h>
-
-#define foreach_vpe_api_msg \
-_(DHCP_PROXY_CONFIG,dhcp_proxy_config) \
-_(DHCP_PROXY_DUMP,dhcp_proxy_dump) \
-_(DHCP_PROXY_SET_VSS,dhcp_proxy_set_vss) \
-_(DHCP_CLIENT_CONFIG, dhcp_client_config) \
-_(DHCP_CLIENT_DUMP, dhcp_client_dump) \
-_(WANT_DHCP6_PD_REPLY_EVENTS, want_dhcp6_pd_reply_events) \
-_(DHCP6_PD_SEND_CLIENT_MESSAGE, dhcp6_pd_send_client_message) \
-_(WANT_DHCP6_REPLY_EVENTS, want_dhcp6_reply_events) \
-_(DHCP6_SEND_CLIENT_MESSAGE, dhcp6_send_client_message) \
-_(DHCP6_CLIENTS_ENABLE_DISABLE, dhcp6_clients_enable_disable) \
-_(DHCP6_DUID_LL_SET, dhcp6_duid_ll_set)
-
-
-static void
-vl_api_dhcp_proxy_set_vss_t_handler (vl_api_dhcp_proxy_set_vss_t * mp)
-{
- vl_api_dhcp_proxy_set_vss_reply_t *rmp;
- u8 *vpn_ascii_id;
- int rv;
-
- mp->vpn_ascii_id[sizeof (mp->vpn_ascii_id) - 1] = 0;
- vpn_ascii_id = format (0, "%s", mp->vpn_ascii_id);
- rv =
- dhcp_proxy_set_vss ((mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4),
- ntohl (mp->tbl_id), ntohl (mp->vss_type),
- vpn_ascii_id, ntohl (mp->oui), ntohl (mp->vpn_index),
- mp->is_add == 0);
-
- REPLY_MACRO (VL_API_DHCP_PROXY_SET_VSS_REPLY);
-}
-
-
-static void vl_api_dhcp_proxy_config_t_handler
- (vl_api_dhcp_proxy_config_t * mp)
-{
- vl_api_dhcp_proxy_set_vss_reply_t *rmp;
- ip46_address_t src, server;
- int rv = -1;
-
- if (mp->dhcp_src_address.af != mp->dhcp_server.af)
- {
- rv = VNET_API_ERROR_INVALID_ARGUMENT;
- goto reply;
- }
-
- ip_address_decode (&mp->dhcp_src_address, &src);
- ip_address_decode (&mp->dhcp_server, &server);
-
- if (mp->dhcp_src_address.af == ADDRESS_IP4)
- {
- rv = dhcp4_proxy_set_server (&server,
- &src,
- (u32) ntohl (mp->rx_vrf_id),
- (u32) ntohl (mp->server_vrf_id),
- (int) (mp->is_add == 0));
- }
- else
- {
- rv = dhcp6_proxy_set_server (&server,
- &src,
- (u32) ntohl (mp->rx_vrf_id),
- (u32) ntohl (mp->server_vrf_id),
- (int) (mp->is_add == 0));
- }
-
-reply:
- REPLY_MACRO (VL_API_DHCP_PROXY_CONFIG_REPLY);
-}
-
-static void
-vl_api_dhcp_proxy_dump_t_handler (vl_api_dhcp_proxy_dump_t * mp)
-{
- vl_api_registration_t *reg;
-
- reg = vl_api_client_index_to_registration (mp->client_index);
- if (!reg)
- return;;
-
- dhcp_proxy_dump ((mp->is_ip6 == 1 ?
- FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4), reg, mp->context);
-}
-
-void
-dhcp_send_details (fib_protocol_t proto,
- void *opaque, u32 context, dhcp_proxy_t * proxy)
-{
- vl_api_dhcp_proxy_details_t *mp;
- vl_api_registration_t *reg = opaque;
- vl_api_dhcp_server_t *v_server;
- dhcp_server_t *server;
- fib_table_t *s_fib;
- dhcp_vss_t *vss;
- u32 count;
- size_t n;
-
- count = vec_len (proxy->dhcp_servers);
- n = sizeof (*mp) + (count * sizeof (vl_api_dhcp_server_t));
- mp = vl_msg_api_alloc (n);
- if (!mp)
- return;
- clib_memset (mp, 0, n);
- mp->_vl_msg_id = ntohs (VL_API_DHCP_PROXY_DETAILS);
- mp->context = context;
- mp->count = count;
-
- mp->is_ipv6 = (proto == FIB_PROTOCOL_IP6);
- mp->rx_vrf_id =
- htonl (dhcp_proxy_rx_table_get_table_id (proto, proxy->rx_fib_index));
-
- vss = dhcp_get_vss_info (&dhcp_proxy_main, proxy->rx_fib_index, proto);
-
- if (vss)
- {
- mp->vss_type = ntohl (vss->vss_type);
- if (vss->vss_type == VSS_TYPE_ASCII)
- {
- u32 id_len = vec_len (vss->vpn_ascii_id);
- clib_memcpy (mp->vss_vpn_ascii_id, vss->vpn_ascii_id, id_len);
- }
- else if (vss->vss_type == VSS_TYPE_VPN_ID)
- {
- u32 oui = ((u32) vss->vpn_id[0] << 16) + ((u32) vss->vpn_id[1] << 8)
- + ((u32) vss->vpn_id[2]);
- u32 fib_id = ((u32) vss->vpn_id[3] << 24) +
- ((u32) vss->vpn_id[4] << 16) + ((u32) vss->vpn_id[5] << 8) +
- ((u32) vss->vpn_id[6]);
- mp->vss_oui = htonl (oui);
- mp->vss_fib_id = htonl (fib_id);
- }
- }
- else
- mp->vss_type = VSS_TYPE_INVALID;
-
- vec_foreach_index (count, proxy->dhcp_servers)
- {
- server = &proxy->dhcp_servers[count];
- v_server = &mp->servers[count];
-
- s_fib = fib_table_get (server->server_fib_index, proto);
-
- v_server->server_vrf_id = htonl (s_fib->ft_table_id);
-
- if (mp->is_ipv6)
- {
- memcpy (&v_server->dhcp_server.un, &server->dhcp_server.ip6, 16);
- }
- else
- {
- /* put the address in the first bytes */
- memcpy (&v_server->dhcp_server.un, &server->dhcp_server.ip4, 4);
- }
- }
-
- if (mp->is_ipv6)
- {
- memcpy (&mp->dhcp_src_address.un, &proxy->dhcp_src_address.ip6, 16);
- }
- else
- {
- /* put the address in the first bytes */
- memcpy (&mp->dhcp_src_address.un, &proxy->dhcp_src_address.ip4, 4);
- }
- vl_api_send_msg (reg, (u8 *) mp);
-}
-
-static void
-dhcp_client_lease_encode (vl_api_dhcp_lease_t * lease,
- const dhcp_client_t * client)
-{
- size_t len;
- u8 i;
-
- lease->is_ipv6 = 0; // only support IPv6 clients
- lease->sw_if_index = ntohl (client->sw_if_index);
- lease->state = ntohl (client->state);
- len = clib_min (sizeof (lease->hostname) - 1, vec_len (client->hostname));
- clib_memcpy (&lease->hostname, client->hostname, len);
- lease->hostname[len] = 0;
-
- lease->mask_width = client->subnet_mask_width;
- clib_memcpy (&lease->host_address.un, (u8 *) & client->leased_address,
- sizeof (ip4_address_t));
- clib_memcpy (&lease->router_address.un, (u8 *) & client->router_address,
- sizeof (ip4_address_t));
-
- lease->count = vec_len (client->domain_server_address);
- for (i = 0; i < lease->count; i++)
- clib_memcpy (&lease->domain_server[i].address,
- (u8 *) & client->domain_server_address[i],
- sizeof (ip4_address_t));
-
- clib_memcpy (&lease->host_mac[0], client->client_hardware_address, 6);
-}
-
-static void
-dhcp_client_data_encode (vl_api_dhcp_client_t * vclient,
- const dhcp_client_t * client)
-{
- size_t len;
-
- vclient->sw_if_index = ntohl (client->sw_if_index);
- len = clib_min (sizeof (vclient->hostname) - 1, vec_len (client->hostname));
- clib_memcpy (&vclient->hostname, client->hostname, len);
- vclient->hostname[len] = 0;
-
- len = clib_min (sizeof (vclient->id) - 1,
- vec_len (client->client_identifier));
- clib_memcpy (&vclient->id, client->client_identifier, len);
- vclient->id[len] = 0;
-
- if (NULL != client->event_callback)
- vclient->want_dhcp_event = 1;
- else
- vclient->want_dhcp_event = 0;
- vclient->set_broadcast_flag = client->set_broadcast_flag;
- vclient->dscp = ip_dscp_encode (client->dscp);
- vclient->pid = client->pid;
-}
-
-static void
-dhcp_compl_event_callback (u32 client_index, const dhcp_client_t * client)
-{
- vl_api_registration_t *reg;
- vl_api_dhcp_compl_event_t *mp;
-
- reg = vl_api_client_index_to_registration (client_index);
- if (!reg)
- return;
-
- mp = vl_msg_api_alloc (sizeof (*mp));
- mp->client_index = client_index;
- mp->pid = client->pid;
- dhcp_client_lease_encode (&mp->lease, client);
-
- mp->_vl_msg_id = ntohs (VL_API_DHCP_COMPL_EVENT);
-
- vl_api_send_msg (reg, (u8 *) mp);
-}
-
-static void vl_api_dhcp_client_config_t_handler
- (vl_api_dhcp_client_config_t * mp)
-{
- vlib_main_t *vm = vlib_get_main ();
- vl_api_dhcp_client_config_reply_t *rmp;
- u32 sw_if_index;
- ip_dscp_t dscp;
- int rv = 0;
-
- VALIDATE_SW_IF_INDEX (&(mp->client));
-
- sw_if_index = ntohl (mp->client.sw_if_index);
- dscp = ip_dscp_decode (mp->client.dscp);
-
- rv = dhcp_client_config (mp->is_add,
- mp->client_index,
- vm,
- sw_if_index,
- mp->client.hostname,
- mp->client.id,
- (mp->client.want_dhcp_event ?
- dhcp_compl_event_callback :
- NULL),
- mp->client.set_broadcast_flag,
- dscp, mp->client.pid);
-
- BAD_SW_IF_INDEX_LABEL;
- REPLY_MACRO (VL_API_DHCP_CLIENT_CONFIG_REPLY);
-}
-
-typedef struct dhcp_client_send_walk_ctx_t_
-{
- vl_api_registration_t *reg;
- u32 context;
-} dhcp_client_send_walk_ctx_t;
-
-static int
-send_dhcp_client_entry (const dhcp_client_t * client, void *arg)
-{
- dhcp_client_send_walk_ctx_t *ctx;
- vl_api_dhcp_client_details_t *mp;
-
- ctx = arg;
-
- mp = vl_msg_api_alloc (sizeof (*mp));
- clib_memset (mp, 0, sizeof (*mp));
-
- mp->_vl_msg_id = ntohs (VL_API_DHCP_CLIENT_DETAILS);
- mp->context = ctx->context;
-
- dhcp_client_data_encode (&mp->client, client);
- dhcp_client_lease_encode (&mp->lease, client);
-
- vl_api_send_msg (ctx->reg, (u8 *) mp);
-
- return (1);
-}
-
-static void
-vl_api_dhcp_client_dump_t_handler (vl_api_dhcp_client_dump_t * mp)
-{
- vl_api_registration_t *reg;
-
- reg = vl_api_client_index_to_registration (mp->client_index);
- if (!reg)
- return;
-
- dhcp_client_send_walk_ctx_t ctx = {
- .reg = reg,
- .context = mp->context,
- };
- dhcp_client_walk (send_dhcp_client_entry, &ctx);
-}
-
-/*
- * dhcp_api_hookup
- * Add vpe's API message handlers to the table.
- * vlib has already mapped shared memory and
- * added the client registration handlers.
- * See .../vlib-api/vlibmemory/memclnt_vlib.c:memclnt_process()
- */
-#define vl_msg_name_crc_list
-#include <vnet/vnet_all_api_h.h>
-#undef vl_msg_name_crc_list
-
-static void
-setup_message_id_table (api_main_t * am)
-{
-#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
- foreach_vl_msg_name_crc_dhcp;
-#undef _
-}
-
-static clib_error_t *
-dhcp_api_hookup (vlib_main_t * vm)
-{
- api_main_t *am = &api_main;
-
-#define _(N,n) \
- vl_msg_api_set_handlers(VL_API_##N, #n, \
- vl_api_##n##_t_handler, \
- vl_noop_handler, \
- vl_api_##n##_t_endian, \
- vl_api_##n##_t_print, \
- sizeof(vl_api_##n##_t), 1);
- foreach_vpe_api_msg;
-#undef _
-
- /*
- * Set up the (msg_name, crc, message-id) table
- */
- setup_message_id_table (am);
-
- dhcp6_pd_set_publisher_node (dhcp6_pd_reply_process_node.index,
- DHCP6_PD_DP_REPLY_REPORT);
- dhcp6_set_publisher_node (dhcp6_reply_process_node.index,
- DHCP6_DP_REPLY_REPORT);
-
- return 0;
-}
-
-VLIB_API_INIT_FUNCTION (dhcp_api_hookup);
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp_client_detect.c b/src/vnet/dhcp/dhcp_client_detect.c
deleted file mode 100644
index c79970d1456..00000000000
--- a/src/vnet/dhcp/dhcp_client_detect.c
+++ /dev/null
@@ -1,324 +0,0 @@
-/*
- * DHCP feature; applied as an input feature to select DHCP packets
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vnet/dhcp/client.h>
-#include <vnet/udp/udp.h>
-
-#define foreach_dhcp_client_detect \
- _(EXTRACT, "Extract")
-
-typedef enum
-{
-#define _(sym,str) DHCP_CLIENT_DETECT_ERROR_##sym,
- foreach_dhcp_client_detect
-#undef _
- DHCP_CLIENT_DETECT_N_ERROR,
-} dhcp_client_detect_error_t;
-
-static char *dhcp_client_detect_error_strings[] = {
-#define _(sym,string) string,
- foreach_dhcp_client_detect
-#undef _
-};
-
-typedef enum
-{
-#define _(sym,str) DHCP_CLIENT_DETECT_NEXT_##sym,
- foreach_dhcp_client_detect
-#undef _
- DHCP_CLIENT_DETECT_N_NEXT,
-} dhcp_client_detect_next_t;
-
-/**
- * per-packet trace data
- */
-typedef struct dhcp_client_detect_trace_t_
-{
- /* per-pkt trace data */
- u8 extracted;
-} dhcp_client_detect_trace_t;
-
-VLIB_NODE_FN (dhcp_client_detect_node) (vlib_main_t * vm,
- vlib_node_runtime_t * node,
- vlib_frame_t * frame)
-{
- dhcp_client_detect_next_t next_index;
- u16 dhcp_client_port_network_order;
- u32 n_left_from, *from, *to_next;
- u32 extractions;
-
- dhcp_client_port_network_order =
- clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_client);
- next_index = 0;
- extractions = 0;
- n_left_from = frame->n_vectors;
- from = vlib_frame_vector_args (frame);
-
- while (n_left_from > 0)
- {
- u32 n_left_to_next;
-
- vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
-
- /*
- * This loop is optimised not so we can really quickly process DHCp
- * offers... but so we can quickly sift them out when the interface
- * is also receiving 'normal' packets
- */
- while (n_left_from >= 8 && n_left_to_next >= 4)
- {
- udp_header_t *udp0, *udp1, *udp2, *udp3;
- ip4_header_t *ip0, *ip1, *ip2, *ip3;
- vlib_buffer_t *b0, *b1, *b2, *b3;
- u32 next0, next1, next2, next3;
- u32 bi0, bi1, bi2, bi3;
-
- next0 = next1 = next2 = next3 = ~0;
- bi0 = to_next[0] = from[0];
- bi1 = to_next[1] = from[1];
- bi2 = to_next[2] = from[2];
- bi3 = to_next[3] = from[3];
-
- /* Prefetch next iteration. */
- {
- vlib_buffer_t *p2, *p3, *p4, *p5;
-
- p2 = vlib_get_buffer (vm, from[2]);
- p3 = vlib_get_buffer (vm, from[3]);
- p4 = vlib_get_buffer (vm, from[4]);
- p5 = vlib_get_buffer (vm, from[5]);
-
- vlib_prefetch_buffer_header (p2, STORE);
- vlib_prefetch_buffer_header (p3, STORE);
- vlib_prefetch_buffer_header (p4, STORE);
- vlib_prefetch_buffer_header (p5, STORE);
-
- CLIB_PREFETCH (p2->data, sizeof (ip0[0]) + sizeof (udp0[0]),
- STORE);
- CLIB_PREFETCH (p3->data, sizeof (ip0[0]) + sizeof (udp0[0]),
- STORE);
- CLIB_PREFETCH (p4->data, sizeof (ip0[0]) + sizeof (udp0[0]),
- STORE);
- CLIB_PREFETCH (p5->data, sizeof (ip0[0]) + sizeof (udp0[0]),
- STORE);
- }
-
- from += 4;
- to_next += 4;
- n_left_from -= 4;
- n_left_to_next -= 4;
-
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
- b2 = vlib_get_buffer (vm, bi2);
- b3 = vlib_get_buffer (vm, bi3);
- ip0 = vlib_buffer_get_current (b0);
- ip1 = vlib_buffer_get_current (b1);
- ip2 = vlib_buffer_get_current (b2);
- ip3 = vlib_buffer_get_current (b2);
-
- vnet_feature_next (&next0, b0);
- vnet_feature_next (&next1, b1);
- vnet_feature_next (&next2, b2);
- vnet_feature_next (&next3, b3);
-
- if (ip0->protocol == IP_PROTOCOL_UDP)
- {
- udp0 = (udp_header_t *) (ip0 + 1);
-
- if (dhcp_client_port_network_order == udp0->dst_port)
- {
- next0 = DHCP_CLIENT_DETECT_NEXT_EXTRACT;
- extractions++;
- }
- }
- if (ip1->protocol == IP_PROTOCOL_UDP)
- {
- udp1 = (udp_header_t *) (ip1 + 1);
-
- if (dhcp_client_port_network_order == udp1->dst_port)
- {
- next1 = DHCP_CLIENT_DETECT_NEXT_EXTRACT;
- extractions++;
- }
- }
- if (ip2->protocol == IP_PROTOCOL_UDP)
- {
- udp2 = (udp_header_t *) (ip2 + 1);
-
- if (dhcp_client_port_network_order == udp2->dst_port)
- {
- next2 = DHCP_CLIENT_DETECT_NEXT_EXTRACT;
- extractions++;
- }
- }
- if (ip3->protocol == IP_PROTOCOL_UDP)
- {
- udp3 = (udp_header_t *) (ip3 + 1);
-
- if (dhcp_client_port_network_order == udp3->dst_port)
- {
- next3 = DHCP_CLIENT_DETECT_NEXT_EXTRACT;
- extractions++;
- }
- }
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_client_detect_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->extracted = (next0 == DHCP_CLIENT_DETECT_NEXT_EXTRACT);
- }
- if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_client_detect_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- t->extracted = (next1 == DHCP_CLIENT_DETECT_NEXT_EXTRACT);
- }
- if (PREDICT_FALSE (b2->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_client_detect_trace_t *t =
- vlib_add_trace (vm, node, b2, sizeof (*t));
- t->extracted = (next2 == DHCP_CLIENT_DETECT_NEXT_EXTRACT);
- }
- if (PREDICT_FALSE (b3->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_client_detect_trace_t *t =
- vlib_add_trace (vm, node, b3, sizeof (*t));
- t->extracted = (next3 == DHCP_CLIENT_DETECT_NEXT_EXTRACT);
- }
-
- /* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x4 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, bi1, bi2, bi3,
- next0, next1, next2, next3);
- }
-
- while (n_left_from > 0 && n_left_to_next > 0)
- {
- udp_header_t *udp0;
- vlib_buffer_t *b0;
- ip4_header_t *ip0;
- u32 next0 = ~0;
- u32 bi0;
-
- bi0 = from[0];
- to_next[0] = bi0;
- from += 1;
- to_next += 1;
- n_left_from -= 1;
- n_left_to_next -= 1;
-
- b0 = vlib_get_buffer (vm, bi0);
- ip0 = vlib_buffer_get_current (b0);
-
- /*
- * when this feature is applied on an interface that is already
- * accepting packets (because e.g. the interface has other addresses
- * assigned) we are looking for the preverbial needle in the haystack
- * so assume the packet is not the one we are looking for.
- */
- vnet_feature_next (&next0, b0);
-
- /*
- * all we are looking for here is DHCP/BOOTP packet-to-client
- * UDO port.
- */
- if (ip0->protocol == IP_PROTOCOL_UDP)
- {
- udp0 = (udp_header_t *) (ip0 + 1);
-
- if (dhcp_client_port_network_order == udp0->dst_port)
- {
- next0 = DHCP_CLIENT_DETECT_NEXT_EXTRACT;
- extractions++;
- }
- }
-
- if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
- {
- dhcp_client_detect_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->extracted = (next0 == DHCP_CLIENT_DETECT_NEXT_EXTRACT);
- }
-
- /* verify speculative enqueue, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, next0);
- }
-
- vlib_put_next_frame (vm, node, next_index, n_left_to_next);
- }
-
- vlib_node_increment_counter (vm, node->node_index,
- DHCP_CLIENT_DETECT_ERROR_EXTRACT, extractions);
-
- return frame->n_vectors;
-}
-
-/* packet trace format function */
-static u8 *
-format_dhcp_client_detect_trace (u8 * s, va_list * args)
-{
- CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
- CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
- dhcp_client_detect_trace_t *t =
- va_arg (*args, dhcp_client_detect_trace_t *);
-
- s = format (s, "dhcp-client-detect: %s", (t->extracted ? "yes" : "no"));
-
- return s;
-}
-
-/* *INDENT-OFF* */
-VLIB_REGISTER_NODE (dhcp_client_detect_node) = {
- .name = "ip4-dhcp-client-detect",
- .vector_size = sizeof (u32),
- .format_trace = format_dhcp_client_detect_trace,
- .type = VLIB_NODE_TYPE_INTERNAL,
-
- .n_errors = ARRAY_LEN(dhcp_client_detect_error_strings),
- .error_strings = dhcp_client_detect_error_strings,
-
- .n_next_nodes = DHCP_CLIENT_DETECT_N_NEXT,
- .next_nodes = {
- /*
- * Jump straight to the UDP dispatch node thus avoiding
- * the RPF checks in ip4-local that will fail
- */
- [DHCP_CLIENT_DETECT_NEXT_EXTRACT] = "ip4-udp-lookup",
- },
-};
-
-VNET_FEATURE_INIT (ip4_dvr_reinject_feat_node, static) =
-{
- .arc_name = "ip4-unicast",
- .node_name = "ip4-dhcp-client-detect",
- .runs_before = VNET_FEATURES ("ip4-not-enabled"),
-};
-
-/* *INDENT-ON* */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp_proxy.c b/src/vnet/dhcp/dhcp_proxy.c
deleted file mode 100644
index 9a69041bc1d..00000000000
--- a/src/vnet/dhcp/dhcp_proxy.c
+++ /dev/null
@@ -1,375 +0,0 @@
-/*
- * proxy_node.c: common dhcp v4 and v6 proxy node processing
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <vnet/dhcp/dhcp_proxy.h>
-#include <vnet/fib/fib_table.h>
-#include <vnet/mfib/mfib_table.h>
-
-/**
- * @brief Shard 4/6 instance of DHCP main
- */
-dhcp_proxy_main_t dhcp_proxy_main;
-
-static void
-dhcp_proxy_rx_table_lock (fib_protocol_t proto, u32 fib_index)
-{
- if (FIB_PROTOCOL_IP4 == proto)
- fib_table_lock (fib_index, proto, FIB_SOURCE_DHCP);
- else
- mfib_table_lock (fib_index, proto, MFIB_SOURCE_DHCP);
-}
-
-static void
-dhcp_proxy_rx_table_unlock (fib_protocol_t proto, u32 fib_index)
-{
- if (FIB_PROTOCOL_IP4 == proto)
- fib_table_unlock (fib_index, proto, FIB_SOURCE_DHCP);
- else
- mfib_table_unlock (fib_index, proto, MFIB_SOURCE_DHCP);
-}
-
-u32
-dhcp_proxy_rx_table_get_table_id (fib_protocol_t proto, u32 fib_index)
-{
- if (FIB_PROTOCOL_IP4 == proto)
- {
- fib_table_t *fib;
-
- fib = fib_table_get (fib_index, proto);
-
- return (fib->ft_table_id);
- }
- else
- {
- mfib_table_t *mfib;
-
- mfib = mfib_table_get (fib_index, proto);
-
- return (mfib->mft_table_id);
- }
-}
-
-void
-dhcp_proxy_walk (fib_protocol_t proto, dhcp_proxy_walk_fn_t fn, void *ctx)
-{
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- dhcp_proxy_t *server;
- u32 server_index, i;
-
- vec_foreach_index (i, dpm->dhcp_server_index_by_rx_fib_index[proto])
- {
- server_index = dpm->dhcp_server_index_by_rx_fib_index[proto][i];
- if (~0 == server_index)
- continue;
-
- server = pool_elt_at_index (dpm->dhcp_servers[proto], server_index);
-
- if (!fn (server, ctx))
- break;
- }
-}
-
-void
-dhcp_vss_walk (fib_protocol_t proto, dhcp_vss_walk_fn_t fn, void *ctx)
-{
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- mfib_table_t *mfib;
- dhcp_vss_t *vss;
- u32 vss_index, i;
- fib_table_t *fib;
-
- vec_foreach_index (i, dpm->vss_index_by_rx_fib_index[proto])
- {
- vss_index = dpm->vss_index_by_rx_fib_index[proto][i];
- if (~0 == vss_index)
- continue;
-
- vss = pool_elt_at_index (dpm->vss[proto], vss_index);
-
- if (FIB_PROTOCOL_IP4 == proto)
- {
- fib = fib_table_get (i, proto);
-
- if (!fn (vss, fib->ft_table_id, ctx))
- break;
- }
- else
- {
- mfib = mfib_table_get (i, proto);
-
- if (!fn (vss, mfib->mft_table_id, ctx))
- break;
- }
- }
-}
-
-static u32
-dhcp_proxy_server_find (dhcp_proxy_t * proxy,
- fib_protocol_t proto,
- ip46_address_t * addr, u32 server_table_id)
-{
- dhcp_server_t *server;
- u32 ii, fib_index;
-
- vec_foreach_index (ii, proxy->dhcp_servers)
- {
- server = &proxy->dhcp_servers[ii];
- fib_index = fib_table_find (proto, server_table_id);
-
- if (ip46_address_is_equal (&server->dhcp_server,
- addr) &&
- (server->server_fib_index == fib_index))
- {
- return (ii);
- }
- }
- return (~0);
-}
-
-int
-dhcp_proxy_server_del (fib_protocol_t proto,
- u32 rx_fib_index,
- ip46_address_t * addr, u32 server_table_id)
-{
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- dhcp_proxy_t *proxy = 0;
-
- proxy = dhcp_get_proxy (dpm, rx_fib_index, proto);
-
- if (NULL != proxy)
- {
- dhcp_server_t *server;
- u32 index;
-
- index = dhcp_proxy_server_find (proxy, proto, addr, server_table_id);
-
- if (~0 != index)
- {
- server = &proxy->dhcp_servers[index];
- fib_table_unlock (server->server_fib_index, proto, FIB_SOURCE_DHCP);
-
- vec_del1 (proxy->dhcp_servers, index);
-
- if (0 == vec_len (proxy->dhcp_servers))
- {
- /* no servers left, delete the proxy config */
- dpm->dhcp_server_index_by_rx_fib_index[proto][rx_fib_index] =
- ~0;
- vec_free (proxy->dhcp_servers);
- pool_put (dpm->dhcp_servers[proto], proxy);
- return (1);
- }
- }
- }
-
- /* the proxy still exists */
- return (0);
-}
-
-int
-dhcp_proxy_server_add (fib_protocol_t proto,
- ip46_address_t * addr,
- ip46_address_t * src_address,
- u32 rx_fib_index, u32 server_table_id)
-{
- dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
- dhcp_proxy_t *proxy = 0;
- int new = 0;
-
- proxy = dhcp_get_proxy (dpm, rx_fib_index, proto);
-
- if (NULL == proxy)
- {
- vec_validate_init_empty (dpm->dhcp_server_index_by_rx_fib_index[proto],
- rx_fib_index, ~0);
-
- pool_get (dpm->dhcp_servers[proto], proxy);
- clib_memset (proxy, 0, sizeof (*proxy));
- new = 1;
-
- dpm->dhcp_server_index_by_rx_fib_index[proto][rx_fib_index] =
- proxy - dpm->dhcp_servers[proto];
-
- proxy->dhcp_src_address = *src_address;
- proxy->rx_fib_index = rx_fib_index;
- }
- else
- {
- if (~0 != dhcp_proxy_server_find (proxy, proto, addr, server_table_id))
- {
- return (new);
- }
- }
-
- dhcp_server_t server = {
- .dhcp_server = *addr,
- .server_fib_index = fib_table_find_or_create_and_lock (proto,
- server_table_id,
- FIB_SOURCE_DHCP),
- };
-
- vec_add1 (proxy->dhcp_servers, server);
-
- return (new);
-}
-
-typedef struct dhcp4_proxy_dump_walk_ctx_t_
-{
- fib_protocol_t proto;
- void *opaque;
- u32 context;
-} dhcp_proxy_dump_walk_cxt_t;
-
-static int
-dhcp_proxy_dump_walk (dhcp_proxy_t * proxy, void *arg)
-{
- dhcp_proxy_dump_walk_cxt_t *ctx = arg;
-
- dhcp_send_details (ctx->proto, ctx->opaque, ctx->context, proxy);
-
- return (1);
-}
-
-void
-dhcp_proxy_dump (fib_protocol_t proto, void *opaque, u32 context)
-{
- dhcp_proxy_dump_walk_cxt_t ctx = {
- .proto = proto,
- .opaque = opaque,
- .context = context,
- };
- dhcp_proxy_walk (proto, dhcp_proxy_dump_walk, &ctx);
-}
-
-int
-dhcp_vss_show_walk (dhcp_vss_t * vss, u32 rx_table_id, void *ctx)
-{
- vlib_main_t *vm = ctx;
-
- if (vss->vss_type == VSS_TYPE_VPN_ID)
- {
- u32 oui = ((u32) vss->vpn_id[0] << 16) + ((u32) vss->vpn_id[1] << 8)
- + ((u32) vss->vpn_id[2]);
- u32 fib_id = ((u32) vss->vpn_id[3] << 24) + ((u32) vss->vpn_id[4] << 16)
- + ((u32) vss->vpn_id[5] << 8) + ((u32) vss->vpn_id[6]);
- vlib_cli_output (vm, " fib_table: %d oui: %d vpn_index: %d",
- rx_table_id, oui, fib_id);
- }
- else if (vss->vss_type == VSS_TYPE_ASCII)
- vlib_cli_output (vm, " fib_table: %d vpn_id: %s",
- rx_table_id, vss->vpn_ascii_id);
- else
- vlib_cli_output (vm, " fib_table: %d default global vpn", rx_table_id);
-
- return (1);
-}
-
-void
-update_vss (dhcp_vss_t * v,
- u8 vss_type, u8 * vpn_ascii_id, u32 oui, u32 vpn_index)
-{
- v->vss_type = vss_type;
- if (v->vpn_ascii_id)
- {
- if (v->vpn_ascii_id == (u8 *) ~ 0)
- v->vpn_ascii_id = 0;
- else
- vec_free (v->vpn_ascii_id);
- }
-
- if (vss_type == VSS_TYPE_ASCII)
- v->vpn_ascii_id = vpn_ascii_id;
- else if (vss_type == VSS_TYPE_VPN_ID)
- {
- v->vpn_id[0] = (oui >> 16) & 0xff;
- v->vpn_id[1] = (oui >> 8) & 0xff;
- v->vpn_id[2] = (oui >> 0) & 0xff;
- v->vpn_id[3] = (vpn_index >> 24) & 0xff;
- v->vpn_id[4] = (vpn_index >> 16) & 0xff;
- v->vpn_id[5] = (vpn_index >> 8) & 0xff;
- v->vpn_id[6] = (vpn_index >> 0) & 0xff;
- }
-}
-
-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)
-{
- dhcp_proxy_main_t *dm = &dhcp_proxy_main;
- dhcp_vss_t *v = NULL;
- u32 rx_fib_index;
- int rc = 0;
-
- if (proto == FIB_PROTOCOL_IP4)
- rx_fib_index = fib_table_find_or_create_and_lock (proto, tbl_id,
- FIB_SOURCE_DHCP);
- else
- rx_fib_index = mfib_table_find_or_create_and_lock (proto, tbl_id,
- MFIB_SOURCE_DHCP);
- v = dhcp_get_vss_info (dm, rx_fib_index, proto);
-
- if (NULL != v)
- {
- if (is_del)
- {
- /* release the lock held on the table when the VSS
- * info was created */
- dhcp_proxy_rx_table_unlock (proto, rx_fib_index);
-
- vec_free (v->vpn_ascii_id);
- pool_put (dm->vss[proto], v);
- dm->vss_index_by_rx_fib_index[proto][rx_fib_index] = ~0;
- }
- else
- {
- update_vss (v, vss_type, vpn_ascii_id, oui, vpn_index);
- }
- }
- else
- {
- if (is_del)
- rc = VNET_API_ERROR_NO_SUCH_ENTRY;
- else
- {
- /* create a new entry */
- vec_validate_init_empty (dm->vss_index_by_rx_fib_index[proto],
- rx_fib_index, ~0);
-
- /* hold a lock on the table whilst the VSS info exist */
- pool_get (dm->vss[proto], v);
- update_vss (v, vss_type, vpn_ascii_id, oui, vpn_index);
- dm->vss_index_by_rx_fib_index[proto][rx_fib_index] =
- v - dm->vss[proto];
- dhcp_proxy_rx_table_lock (proto, rx_fib_index);
- }
- }
-
- /* Release the lock taken during the create_or_lock at the start */
- dhcp_proxy_rx_table_unlock (proto, rx_fib_index);
-
- return (rc);
-}
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/dhcp/dhcp_proxy.h b/src/vnet/dhcp/dhcp_proxy.h
deleted file mode 100644
index 60c4eb838c8..00000000000
--- a/src/vnet/dhcp/dhcp_proxy.h
+++ /dev/null
@@ -1,306 +0,0 @@
-/*
- * dhcp_proxy.h: DHCP v4 & v6 proxy common functions/types
- *
- * Copyright (c) 2013 Cisco and/or its affiliates.
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at:
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef included_dhcp_proxy_h
-#define included_dhcp_proxy_h
-
-#include <vnet/vnet.h>
-#include <vnet/dhcp/dhcp4_packet.h>
-#include <vnet/ethernet/ethernet.h>
-#include <vnet/ip/ip.h>
-#include <vnet/ip/ip4.h>
-#include <vnet/ip/ip4_packet.h>
-#include <vnet/pg/pg.h>
-#include <vnet/ip/format.h>
-#include <vnet/udp/udp.h>
-
-typedef enum
-{
-#define dhcp_proxy_error(n,s) DHCP_PROXY_ERROR_##n,
-#include <vnet/dhcp/dhcp4_proxy_error.def>
-#undef dhcp_proxy_error
- DHCP_PROXY_N_ERROR,
-} dhcp_proxy_error_t;
-
-typedef enum
-{
-#define dhcpv6_proxy_error(n,s) DHCPV6_PROXY_ERROR_##n,
-#include <vnet/dhcp/dhcp6_proxy_error.def>
-#undef dhcpv6_proxy_error
- DHCPV6_PROXY_N_ERROR,
-} dhcpv6_proxy_error_t;
-
-/* flags to indicate which DHCP ports should be or have been registered */
-typedef enum
-{
- DHCP_PORT_REG_CLIENT = 0x1,
- DHCP_PORT_REG_SERVER = 0x2,
-} dhcp_port_reg_flags_t;
-
-/**
- * @brief The Virtual Sub-net Selection information for a given RX FIB
- */
-typedef struct dhcp_vss_t_
-{
- /**
- * @brief VSS type as defined in RFC 6607:
- * 0 for NVT ASCII VPN Identifier
- * 1 for RFC 2685 VPN-ID of 7 octects - 3 bytes OUI & 4 bytes VPN index
- * 255 for global default VPN
- */
- u8 vss_type;
-#define VSS_TYPE_ASCII 0
-#define VSS_TYPE_VPN_ID 1
-#define VSS_TYPE_INVALID 123
-#define VSS_TYPE_DEFAULT 255
- /**
- * @brief Type 1 VPN-ID
- */
- u8 vpn_id[7];
- /**
- * @brief Type 0 ASCII VPN Identifier
- */
- u8 *vpn_ascii_id;
-} dhcp_vss_t;
-
-/**
- * @brief A representation of a single DHCP Server within a given VRF config
- */
-typedef struct dhcp_server_t_
-{
- /**
- * @brief The address of the DHCP server to which to relay the client's
- * messages
- */
- ip46_address_t dhcp_server;
-
- /**
- * @brief The FIB index (not the external Table-ID) in which the server
- * is reachable.
- */
- u32 server_fib_index;
-} dhcp_server_t;
-
-/**
- * @brief A DHCP proxy representation fpr per-client VRF config
- */
-typedef struct dhcp_proxy_t_
-{
- /**
- * @brief The set of DHCP servers to which messages are relayed.
- * If multiple servers are configured then discover/solict messages
- * are relayed to each. A cookie is maintained for the relay, and only
- * one message is replayed to the client, based on the presence of the
- * cookie.
- * The expectation is there are only 1 or 2 servers, hence no fancy DB.
- */
- dhcp_server_t *dhcp_servers;
-
- /**
- * @brief Hash table of pending requets key'd on the clients MAC address
- */
- uword *dhcp_pending;
-
- /**
- * @brief A lock for the pending request DB.
- */
- int lock;
-
- /**
- * @brief The source address to use in relayed messaes
- */
- ip46_address_t dhcp_src_address;
-
- /**
- * @brief The FIB index (not the external Table-ID) in which the client
- * is resides.
- */
- u32 rx_fib_index;
-} dhcp_proxy_t;
-
-#define DHCP_N_PROTOS (FIB_PROTOCOL_IP6 + 1)
-
-/**
- * @brief Collection of global DHCP proxy data
- */
-typedef struct
-{
- /* Pool of DHCP servers */
- dhcp_proxy_t *dhcp_servers[DHCP_N_PROTOS];
-
- /* Pool of selected DHCP server. Zero is the default server */
- u32 *dhcp_server_index_by_rx_fib_index[DHCP_N_PROTOS];
-
- /* to drop pkts in server-to-client direction */
- u32 error_drop_node_index;
-
- dhcp_vss_t *vss[DHCP_N_PROTOS];
-
- /* hash lookup specific vrf_id -> option 82 vss suboption */
- u32 *vss_index_by_rx_fib_index[DHCP_N_PROTOS];
-
- /* flags to indicate which udp ports have been registered */
- int udp_ports_registered;
-
- /* convenience */
- vlib_main_t *vlib_main;
-
-} dhcp_proxy_main_t;
-
-extern dhcp_proxy_main_t dhcp_proxy_main;
-
-/**
- * @brief Register the dhcp client and/or server ports, if not already done
- */
-void dhcp_maybe_register_udp_ports (dhcp_port_reg_flags_t ports);
-
-/**
- * @brief Send the details of a proxy session to the API client during a dump
- */
-void dhcp_send_details (fib_protocol_t proto,
- void *opaque, u32 context, dhcp_proxy_t * proxy);
-
-/**
- * @brief Show (on CLI) a VSS config during a show walk
- */
-int dhcp_vss_show_walk (dhcp_vss_t * vss, u32 rx_table_id, void *ctx);
-
-/**
- * @brief Configure/set a new VSS info
- */
-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);
-
-/**
- * @brief Dump the proxy configs to the API
- */
-void dhcp_proxy_dump (fib_protocol_t proto, void *opaque, u32 context);
-
-/**
- * @brief Add a new DHCP proxy server configuration.
- * @return 1 is the config is new,
- * 0 otherwise (implying a modify of an existing)
- */
-int dhcp_proxy_server_add (fib_protocol_t proto,
- ip46_address_t * addr,
- ip46_address_t * src_address,
- u32 rx_fib_iindex, u32 server_table_id);
-
-/**
- * @brief Delete a DHCP proxy config
- * @return 1 if the proxy is deleted, 0 otherwise
- */
-int dhcp_proxy_server_del (fib_protocol_t proto,
- u32 rx_fib_index,
- ip46_address_t * addr, u32 server_table_id);
-
-u32 dhcp_proxy_rx_table_get_table_id (fib_protocol_t proto, u32 fib_index);
-
-/**
- * @brief Callback function invoked for each DHCP proxy entry
- * return 0 to break the walk, non-zero otherwise.
- */
-typedef int (*dhcp_proxy_walk_fn_t) (dhcp_proxy_t * server, void *ctx);
-
-/**
- * @brief Walk/Visit each DHCP proxy server
- */
-void dhcp_proxy_walk (fib_protocol_t proto,
- dhcp_proxy_walk_fn_t fn, void *ctx);
-
-/**
- * @brief Callback function invoked for each DHCP VSS entry
- * return 0 to break the walk, non-zero otherwise.
- */
-typedef int (*dhcp_vss_walk_fn_t) (dhcp_vss_t * server,
- u32 rx_table_id, void *ctx);
-
-/**
- * @brief Walk/Visit each DHCP proxy VSS
- */
-void dhcp_vss_walk (fib_protocol_t proto, dhcp_vss_walk_fn_t fn, void *ctx);
-
-/**
- * @brief Lock a proxy object to prevent simultaneous access of its
- * pending store
- */
-void dhcp_proxy_lock (dhcp_proxy_t * server);
-
-/**
- * @brief Lock a proxy object to prevent simultaneous access of its
- * pending store
- */
-void dhcp_proxy_unlock (dhcp_proxy_t * server);
-
-/**
- * @brief Get the VSS data for the FIB index
- */
-static inline dhcp_vss_t *
-dhcp_get_vss_info (dhcp_proxy_main_t * dm,
- u32 rx_fib_index, fib_protocol_t proto)
-{
- dhcp_vss_t *v = NULL;
-
- if (vec_len (dm->vss_index_by_rx_fib_index[proto]) > rx_fib_index &&
- dm->vss_index_by_rx_fib_index[proto][rx_fib_index] != ~0)
- {
- v = pool_elt_at_index (dm->vss[proto],
- dm->vss_index_by_rx_fib_index[proto]
- [rx_fib_index]);
- }
-
- return (v);
-}
-
-/**
- * @brief Get the DHCP proxy server data for the FIB index
- */
-static inline dhcp_proxy_t *
-dhcp_get_proxy (dhcp_proxy_main_t * dm,
- u32 rx_fib_index, fib_protocol_t proto)
-{
- dhcp_proxy_t *s = NULL;
-
- if (vec_len (dm->dhcp_server_index_by_rx_fib_index[proto]) > rx_fib_index &&
- dm->dhcp_server_index_by_rx_fib_index[proto][rx_fib_index] != ~0)
- {
- s = pool_elt_at_index (dm->dhcp_servers[proto],
- dm->dhcp_server_index_by_rx_fib_index[proto]
- [rx_fib_index]);
- }
-
- return (s);
-}
-
-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);
-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);
-
-#endif /* included_dhcp_proxy_h */
-
-/*
- * fd.io coding-style-patch-verification: ON
- *
- * Local Variables:
- * eval: (c-set-style "gnu")
- * End:
- */
diff --git a/src/vnet/vnet_all_api_h.h b/src/vnet/vnet_all_api_h.h
index 3b5140e1ed2..519f5219042 100644
--- a/src/vnet/vnet_all_api_h.h
+++ b/src/vnet/vnet_all_api_h.h
@@ -60,7 +60,6 @@
#include <vnet/srmpls/sr_mpls.api.h>
#include <vnet/classify/classify.api.h>
#include <vnet/ipfix-export/ipfix_export.api.h>
-#include <vnet/dhcp/dhcp.api.h>
#include <vnet/cop/cop.api.h>
#include <vnet/policer/policer.api.h>
#include <vnet/ethernet/p2p_ethernet.api.h>
@@ -71,8 +70,6 @@
#include <vnet/pg/pg.api.h>
#include <vnet/feature/feature.api.h>
#include <vnet/qos/qos.api.h>
-#include <vnet/dhcp/dhcp6_pd_client_cp.api.h>
-#include <vnet/dhcp/dhcp6_ia_na_client_cp.api.h>
#include <vnet/devices/pipe/pipe.api.h>
#include <vnet/vxlan-gbp/vxlan_gbp.api.h>
#include <vnet/syslog/syslog.api.h>