aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/dhcp/dhcp4_proxy_node.c
diff options
context:
space:
mode:
authorJohn Lo <loj@cisco.com>2017-11-14 13:19:26 -0500
committerDave Barach <openvpp@barachs.net>2017-11-16 11:25:51 +0000
commit70bfcaf47779340951c1e6f169b1cedcabe708d1 (patch)
treeb6e1378942f278e914b7139d1210562d943cb680 /src/vnet/dhcp/dhcp4_proxy_node.c
parent9d72120a6986e642c5b16c8650ad266188adf142 (diff)
Add Support of DHCP VSS Type 0 where VPN-ID is ASCII
Enhence support of DHCP VSS (Virtual Subnet Selection) to include VSS type 0 where VSS info is a NVT (Network Virtual Terminal) ASCII VPN ID where the ASCII string MUST NOT be terminated with a zero byte. Existing code already support VSS type 1, where VSS information is a RFC 2685 VPN-ID of 7 bytes with 3 bytes OUI and 4 bytes VPN index, and VSS type 255 indicating global VPN. Change-Id: I54edbc447c89a2aacd1cc9fc72bd5ba386037608 Signed-off-by: John Lo <loj@cisco.com>
Diffstat (limited to 'src/vnet/dhcp/dhcp4_proxy_node.c')
-rw-r--r--src/vnet/dhcp/dhcp4_proxy_node.c161
1 files changed, 72 insertions, 89 deletions
diff --git a/src/vnet/dhcp/dhcp4_proxy_node.c b/src/vnet/dhcp/dhcp4_proxy_node.c
index 339a78858a7..cd52be83f71 100644
--- a/src/vnet/dhcp/dhcp4_proxy_node.c
+++ b/src/vnet/dhcp/dhcp4_proxy_node.c
@@ -229,19 +229,19 @@ dhcp_proxy_to_server_input (vlib_main_t * vm,
}
}
o = (dhcp_option_t *) (((uword) o) + (o->length + 2));
- }
+ }
fl = vlib_buffer_get_free_list (vm, vlib_buffer_get_free_list_index (b0));
// start write at (option*)o, some packets have padding
if (((u8 *)o - (u8 *)b0->data + VPP_DHCP_OPTION82_SIZE) > fl->n_data_bytes)
- {
+ {
next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
pkts_too_big++;
goto do_trace;
- }
+ }
if ((o->option == 0xFF) && ((u8 *)o <= end))
- {
+ {
vnet_main_t *vnm = vnet_get_main();
u16 old_l0, new_l0;
ip4_address_t _ia0, * ia0 = &_ia0;
@@ -264,65 +264,53 @@ dhcp_proxy_to_server_input (vlib_main_t * vm,
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 */
- o->data[2] = (original_sw_if_index >> 24) & 0xFF;
- o->data[3] = (original_sw_if_index >> 16) & 0xFF;
- o->data[4] = (original_sw_if_index >> 8) & 0xFF;
- o->data[5] = (original_sw_if_index >> 0) & 0xFF;
+ 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 */
- o->data[8] = ia0->as_u8[0];
- o->data[9] = ia0->as_u8[1];
- o->data[10] = ia0->as_u8[2];
- o->data[11] = ia0->as_u8[3];
+ u32 *o_addr = (u32 *) &o->data[8];
+ *o_addr = ia0->as_u32;
o->data[12] = 0xFF;
vss = dhcp_get_vss_info (dpm, fib_index, FIB_PROTOCOL_IP4);
- if (NULL != vss)
- {
- u32 opt82_fib_id=0, opt82_oui=0;
-
- opt82_oui = vss->oui;
- opt82_fib_id = vss->fib_id;
-
- o->data[12] = 151; /* vss suboption */
- if (255 == opt82_fib_id) {
- o->data[13] = 1; /* length */
- o->data[14] = 255; /* vss option type */
- o->data[15] = 152; /* vss control suboption */
- o->data[16] = 0; /* length */
- /* and a new "end-of-options" option (0xff) */
- o->data[17] = 0xFF;
- o->length += 5;
- } else {
- o->data[13] = 8; /* length */
- o->data[14] = 1; /* vss option type */
- o->data[15] = (opt82_oui >> 16) & 0xff;
- o->data[16] = (opt82_oui >> 8) & 0xff;
- o->data[17] = (opt82_oui ) & 0xff;
- o->data[18] = (opt82_fib_id >> 24) & 0xff;
- o->data[19] = (opt82_fib_id >> 16) & 0xff;
- o->data[20] = (opt82_fib_id >> 8) & 0xff;
- o->data[21] = (opt82_fib_id) & 0xff;
- o->data[22] = 152; /* vss control suboption */
- o->data[23] = 0; /* length */
-
- /* and a new "end-of-options" option (0xff) */
- o->data[24] = 0xFF;
- o->length += 12;
- }
- }
+ 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] = 0xFF; /* "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;
@@ -341,11 +329,13 @@ dhcp_proxy_to_server_input (vlib_main_t * vm,
new_l0 = clib_net_to_host_u16 (u0->length);
new_l0 += len;
u0->length = clib_host_to_net_u16 (new_l0);
- } else {
+ }
+ 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;
@@ -355,11 +345,11 @@ dhcp_proxy_to_server_input (vlib_main_t * vm,
* 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;
@@ -387,7 +377,7 @@ dhcp_proxy_to_server_input (vlib_main_t * vm,
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));
@@ -397,15 +387,15 @@ dhcp_proxy_to_server_input (vlib_main_t * vm,
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:
@@ -949,54 +939,47 @@ dhcp_option_82_vss_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
- int is_del = 0, got_new_vpn_id=0;
- u32 oui=0, fib_id=0, tbl_id=~0;
+ 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, "delete") || unformat(input, "del"))
- is_del = 1;
+ if (unformat (input, "table %d", &tbl_id))
+ ;
else if (unformat (input, "oui %d", &oui))
- got_new_vpn_id = 1;
+ vss_type = VSS_TYPE_VPN_ID;
else if (unformat (input, "vpn-id %d", &fib_id))
- got_new_vpn_id = 1;
- else if (unformat (input, "table %d", &tbl_id))
- got_new_vpn_id = 1;
+ 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;
- }
+ break;
+ }
+
if (tbl_id == ~0)
return clib_error_return (0, "no table ID specified.");
- if (is_del || got_new_vpn_id)
+ int rv = dhcp_proxy_set_vss (FIB_PROTOCOL_IP4, tbl_id, vss_type,
+ vpn_ascii_id, oui, fib_id, is_del);
+ switch (rv)
{
- int rv;
- rv = dhcp_proxy_set_vss(FIB_PROTOCOL_IP4, tbl_id, oui, fib_id, is_del);
- switch (rv)
- {
- case 0:
- return 0;
-
- case VNET_API_ERROR_NO_SUCH_FIB:
- return clib_error_return (0, "option 82 vss(oui:%d, vpn-id:%d) not found in table %d",
- oui, fib_id, tbl_id);
-
- 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);
- }
+ 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);
+
}
- else
- return clib_error_return (0, "parse error`%U'",
- format_unformat_error, input);
}
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 <oui> vpn-id <vpn-id>",
+ .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,
};