2 * proxy_node.c: common dhcp v4 and v6 proxy node processing
4 * Copyright (c) 2013 Cisco and/or its affiliates.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 #include <vnet/dhcp/dhcp_proxy.h>
19 #include <vnet/fib/fib_table.h>
22 * @brief Shard 4/6 instance of DHCP main
24 dhcp_proxy_main_t dhcp_proxy_main;
27 dhcp_proxy_walk (fib_protocol_t proto,
28 dhcp_proxy_walk_fn_t fn,
31 dhcp_proxy_main_t * dpm = &dhcp_proxy_main;
32 dhcp_server_t * server;
35 vec_foreach_index (i, dpm->dhcp_server_index_by_rx_fib_index[proto])
37 server_index = dpm->dhcp_server_index_by_rx_fib_index[proto][i];
38 if (~0 == server_index)
41 server = pool_elt_at_index (dpm->dhcp_servers[proto], server_index);
49 dhcp_vss_walk (fib_protocol_t proto,
50 dhcp_vss_walk_fn_t fn,
53 dhcp_proxy_main_t * dpm = &dhcp_proxy_main;
59 vec_foreach_index (i, dpm->vss_index_by_rx_fib_index[proto])
61 vss_index = dpm->vss_index_by_rx_fib_index[proto][i];
65 vss = pool_elt_at_index (dpm->vss[proto], vss_index);
67 fib = fib_table_get(i, proto);
69 if (!fn(vss, fib->ft_table_id, ctx))
75 dhcp_proxy_server_del (fib_protocol_t proto,
78 dhcp_proxy_main_t * dpm = &dhcp_proxy_main;
79 dhcp_server_t * server = 0;
82 server = dhcp_get_server(dpm, rx_fib_index, proto);
86 rc = VNET_API_ERROR_NO_SUCH_ENTRY;
90 /* Use the default server again. */
91 dpm->dhcp_server_index_by_rx_fib_index[proto][rx_fib_index] = ~0;
93 fib_table_unlock (server->server_fib_index, proto);
95 pool_put (dpm->dhcp_servers[proto], server);
102 dhcp_proxy_server_add (fib_protocol_t proto,
103 ip46_address_t *addr,
104 ip46_address_t *src_address,
108 dhcp_proxy_main_t * dpm = &dhcp_proxy_main;
109 dhcp_server_t * server = 0;
112 server = dhcp_get_server(dpm, rx_fib_index, proto);
116 vec_validate_init_empty(dpm->dhcp_server_index_by_rx_fib_index[proto],
120 pool_get (dpm->dhcp_servers[proto], server);
121 memset (server, 0, sizeof (*server));
124 dpm->dhcp_server_index_by_rx_fib_index[proto][rx_fib_index] =
125 server - dpm->dhcp_servers[proto];
127 server->rx_fib_index = rx_fib_index;
128 server->server_fib_index =
129 fib_table_find_or_create_and_lock(proto, server_table_id);
133 /* modify, may need to swap server FIBs */
136 tmp_index = fib_table_find(proto, server_table_id);
138 if (tmp_index != server->server_fib_index)
140 tmp_index = server->server_fib_index;
142 /* certainly swapping if the fib doesn't exist */
143 server->server_fib_index =
144 fib_table_find_or_create_and_lock(proto, server_table_id);
145 fib_table_unlock (tmp_index, proto);
149 server->dhcp_server = *addr;
150 server->dhcp_src_address = *src_address;
155 typedef struct dhcp4_proxy_dump_walk_ctx_t_
157 fib_protocol_t proto;
160 } dhcp_proxy_dump_walk_cxt_t;
163 dhcp_proxy_dump_walk (dhcp_server_t *server,
166 dhcp_proxy_dump_walk_cxt_t *ctx = arg;
167 fib_table_t *s_fib, *r_fib;
170 v = dhcp_get_vss_info(&dhcp_proxy_main,
171 server->rx_fib_index,
174 s_fib = fib_table_get(server->server_fib_index, ctx->proto);
175 r_fib = fib_table_get(server->rx_fib_index, ctx->proto);
177 dhcp_send_details(ctx->proto,
180 &server->dhcp_server,
181 &server->dhcp_src_address,
191 dhcp_proxy_dump (fib_protocol_t proto,
195 dhcp_proxy_dump_walk_cxt_t ctx = {
200 dhcp_proxy_walk(proto, dhcp_proxy_dump_walk, &ctx);
204 dhcp_vss_show_walk (dhcp_vss_t *vss,
208 vlib_main_t * vm = ctx;
210 vlib_cli_output (vm, "%=6d%=6d%=12d",
218 int dhcp_proxy_set_vss (fib_protocol_t proto,
224 dhcp_proxy_main_t *dm = &dhcp_proxy_main;
225 dhcp_vss_t *v = NULL;
229 rx_fib_index = fib_table_find_or_create_and_lock(proto, tbl_id);
230 v = dhcp_get_vss_info(dm, rx_fib_index, proto);
236 /* release the lock held on the table when the VSS
237 * info was created */
238 fib_table_unlock (rx_fib_index, proto);
240 pool_put (dm->vss[proto], v);
241 dm->vss_index_by_rx_fib_index[proto][rx_fib_index] = ~0;
245 /* this is a modify */
253 rc = VNET_API_ERROR_NO_SUCH_ENTRY;
256 /* create a new entry */
257 vec_validate_init_empty(dm->vss_index_by_rx_fib_index[proto],
260 /* hold a lock on the table whilst the VSS info exist */
261 fib_table_lock (rx_fib_index, proto);
263 pool_get (dm->vss[proto], v);
266 dm->vss_index_by_rx_fib_index[proto][rx_fib_index] =
271 /* Release the lock taken during the create_or_lock at the start */
272 fib_table_unlock (rx_fib_index, proto);