+ if (NULL != server)
+ {
+ /* modify of an existing entry */
+ ip6_fib_t *fib;
+
+ fib = ip6_fib_get(server->server_fib6_index);
+
+ if (fib->table_id != server_fib_id)
+ {
+ /* swap tables */
+ fib_table_unlock(server->server_fib6_index, FIB_PROTOCOL_IP6);
+ server->server_fib6_index =
+ ip6_fib_table_find_or_create_and_lock(server_fib_id);
+ }
+ }
+ else
+ {
+ /* Allocate a new server */
+ pool_get (dm->dhcp6_servers, server);
+
+ vec_validate_init_empty (dm->dhcp6_server_index_by_rx_fib_index,
+ rx_fib_index, ~0);
+ dm->dhcp6_server_index_by_rx_fib_index[rx_fib_index] =
+ server - dm->dhcp6_servers;
+
+ server->server_fib6_index =
+ ip6_fib_table_find_or_create_and_lock(server_fib_id);
+ mfib_table_lock(rx_fib_index, FIB_PROTOCOL_IP6);
+
+ const mfib_prefix_t all_dhcp_servers = {
+ .fp_len = 128,
+ .fp_proto = FIB_PROTOCOL_IP6,
+ .fp_grp_addr = {
+ .ip6 = dm->all_dhcpv6_server_relay_agent_address,
+ }
+ };
+ const fib_route_path_t path_for_us = {
+ .frp_proto = FIB_PROTOCOL_IP6,
+ .frp_addr = zero_addr,
+ .frp_sw_if_index = 0xffffffff,
+ .frp_fib_index = ~0,
+ .frp_weight = 0,
+ .frp_flags = FIB_ROUTE_PATH_LOCAL,
+ };
+ mfib_table_entry_path_update(rx_fib_index,
+ &all_dhcp_servers,
+ MFIB_SOURCE_DHCP,
+ &path_for_us,
+ MFIB_ITF_FLAG_FORWARD);
+ /*
+ * 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_ENTRY_FLAG_ACCEPT_ALL_ITF);
+ }
+ copy_ip6_address(&server->dhcp6_server, addr);
+ copy_ip6_address(&server->dhcp6_src_address, src_address);
+ }
+
+out:
+ mfib_table_unlock(rx_fib_index, FIB_PROTOCOL_IP6);
+
+ return (rc);