diff options
author | Dave Barach <dave@barachs.net> | 2016-04-30 10:25:32 -0400 |
---|---|---|
committer | Keith Burns (alagalah) <alagalah@gmail.com> | 2016-08-01 18:16:24 -0700 |
commit | 6f9bca21945b171035a2a00663f1cd2185027f8b (patch) | |
tree | 7ed04ce7ed88233f1900941b1b41cd78c890d3ee /vpp | |
parent | f7643fd9e1915e703d9a696c97be685328e9c388 (diff) |
VPP-226 IPv4 src-address + port range checker
Change-Id: Ia251e9d7d53e894a5666109f69e9626d27ea74cb
Signed-off-by: Dave Barach <dave@barachs.net>
Signed-off-by: Keith Burns (alagalah) <alagalah@gmail.com>
Diffstat (limited to 'vpp')
-rw-r--r-- | vpp/vpp-api/api.c | 126 | ||||
-rw-r--r-- | vpp/vpp-api/custom_dump.c | 50 | ||||
-rw-r--r-- | vpp/vpp-api/vpe.api | 57 |
3 files changed, 231 insertions, 2 deletions
diff --git a/vpp/vpp-api/api.c b/vpp/vpp-api/api.c index dcaedac3..3f48a7ef 100644 --- a/vpp/vpp-api/api.c +++ b/vpp/vpp-api/api.c @@ -77,6 +77,7 @@ #include <vnet/map/map.h> #include <vnet/cop/cop.h> #include <vnet/ip/ip6_hop_by_hop.h> +#include <vnet/ip/ip_source_and_port_range_check.h> #include <vnet/devices/af_packet/af_packet.h> #include <vnet/policer/policer.h> #include <vnet/devices/netmap/netmap.h> @@ -377,7 +378,11 @@ _(IPFIX_DUMP,ipfix_dump) \ _(GET_NEXT_INDEX, get_next_index) \ _(PG_CREATE_INTERFACE, pg_create_interface) \ _(PG_CAPTURE, pg_capture) \ -_(PG_ENABLE_DISABLE, pg_enable_disable) +_(PG_ENABLE_DISABLE, pg_enable_disable) \ +_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \ + ip_source_and_port_range_check_add_del) \ +_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \ + ip_source_and_port_range_check_interface_add_del) #define QUOTE_(x) #x #define QUOTE(x) QUOTE_(x) @@ -7455,6 +7460,125 @@ static void vl_api_pg_enable_disable_t_handler (vl_api_pg_enable_disable_t *mp) REPLY_MACRO(VL_API_PG_ENABLE_DISABLE_REPLY); } +static void vl_api_ip_source_and_port_range_check_add_del_t_handler ( + vl_api_ip_source_and_port_range_check_add_del_t *mp) +{ + vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp; + int rv = 0; + + u8 is_ipv6 = mp->is_ipv6; + u8 is_add = mp->is_add; + u8 mask_length = mp->mask_length; + ip4_address_t ip4_addr; + //ip6_address_t ip6_addr; + u16 * low_ports = 0 ; + u16 * high_ports = 0 ; + u16 tmp_low, tmp_high; + u8 num_ranges ; + int i; + u32 vrf_id; + + // Validate port range + num_ranges = mp->number_of_ranges; + if (num_ranges > 32) { // This is size of array in VPE.API + rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY; + goto reply; + } + + vec_reset_length (low_ports); + vec_reset_length (high_ports); + + for (i = 0; i < num_ranges; i++) { + tmp_low = mp->low_ports[i]; + tmp_high = mp->high_ports[i]; + // If tmp_low <= tmp_high then only need to check tmp_low = 0 + // If tmp_low <= tmp_high then only need to check tmp_high > 65535 + if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535) { + rv = VNET_API_ERROR_INVALID_VALUE; + goto reply; + } + vec_add1 (low_ports, tmp_low ); + vec_add1 (high_ports, tmp_high+1 ); + } + + // Validate mask_length + if (mask_length < 0 || + ( is_ipv6 && mask_length > 128) || + ( !is_ipv6 && mask_length > 32)) { + rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH; + goto reply; + } + + vrf_id = ntohl (mp->vrf_id); + + if ( vrf_id < 1 ) { + rv = VNET_API_ERROR_INVALID_VALUE; + goto reply; + } + //ip6 + if (is_ipv6) { + /* clib_memcpy (ip6_addr.as_u8, mp->address, */ + /* sizeof (ip6_addr.as_u8)); */ + /* rv = ip6_source_and_port_range_check_add_del (ip6_addr, */ + /* mask_length, */ + /* vrf_id, */ + /* low_ports, */ + /* high_ports, */ + /* is_add); */ + + //ip4 + } else { + clib_memcpy (ip4_addr.data, mp->address, + sizeof (ip4_addr)); + rv = ip4_source_and_port_range_check_add_del (&ip4_addr, + mask_length, + vrf_id, + low_ports, + high_ports, + is_add); + } + + reply: + vec_free (low_ports); + vec_free (high_ports); + + REPLY_MACRO(VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY); +} + +static void +vl_api_ip_source_and_port_range_check_interface_add_del_t_handler +(vl_api_ip_source_and_port_range_check_interface_add_del_t * mp) +{ + vlib_main_t *vm = vlib_get_main(); + vl_api_ip_source_and_port_range_check_interface_add_del_reply_t * rmp; + ip4_main_t * im = &ip4_main; + int rv; + u32 sw_if_index, fib_index, vrf_id; + uword * p = 0; + + vrf_id = ntohl(mp->vrf_id); + + p = hash_get (im->fib_index_by_table_id, vrf_id); + + if (p == 0) { + rv = VNET_API_ERROR_INVALID_VALUE; + goto reply; + } + + fib_index = p[0]; + + sw_if_index = ntohl(mp->sw_if_index); + + VALIDATE_SW_IF_INDEX(mp); + + rv = set_ip_source_and_port_range_check (vm, fib_index, sw_if_index, mp->is_add); + + BAD_SW_IF_INDEX_LABEL; + reply: + + REPLY_MACRO(VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY); +} + #define BOUNCE_HANDLER(nn) \ static void vl_api_##nn##_t_handler ( \ vl_api_##nn##_t *mp) \ diff --git a/vpp/vpp-api/custom_dump.c b/vpp/vpp-api/custom_dump.c index a6898eb8..51bf81d9 100644 --- a/vpp/vpp-api/custom_dump.c +++ b/vpp/vpp-api/custom_dump.c @@ -2084,6 +2084,49 @@ static void *vl_api_pg_enable_disable_t_print FINISH; } +static void *vl_api_ip_source_and_port_range_check_add_del_t_print +(vl_api_ip_source_and_port_range_check_add_del_t * mp, void *handle) +{ + u8 * s; + int i; + + s = format (0, "SCRIPT: ip_source_and_port_range_check_add_del "); + if (mp->is_ipv6) + s = format (s, "%U/%d ", format_ip6_address, mp->address, + mp->mask_length); + else + s = format (s, "%U/%d ", format_ip4_address, mp->address, + mp->mask_length); + + for (i = 0; i < mp->number_of_ranges; i++) { + s = format (s, "range %d - %d", mp->low_ports[i], mp->high_ports[i]); + } + + s = format (s, "vrf %d ", ntohl(mp->vrf_id)); + + if (mp->is_add == 0) + s = format (s, "del "); + + FINISH; +} + +static void *vl_api_ip_source_and_port_range_check_interface_add_del_t_print +(vl_api_ip_source_and_port_range_check_interface_add_del_t * mp, void *handle) +{ + u8 * s; + + s = format (0, "SCRIPT: ip_source_and_port_range_check_interface_add_del "); + + s = format (s, "%d ", ntohl(mp->sw_if_index)); + + s = format (s, "vrf %d ", ntohl(mp->vrf_id)); + + if (mp->is_add == 0) + s = format (s, "del "); + + FINISH; +} + #define foreach_custom_print_function \ _(CREATE_LOOPBACK, create_loopback) \ _(SW_INTERFACE_SET_FLAGS, sw_interface_set_flags) \ @@ -2189,7 +2232,12 @@ _(PG_ENABLE_DISABLE, pg_enable_disable) \ _(POLICER_ADD_DEL, policer_add_del) \ _(POLICER_DUMP, policer_dump) \ _(POLICER_CLASSIFY_SET_INTERFACE, policer_classify_set_interface) \ -_(POLICER_CLASSIFY_DUMP, policer_classify_dump) +_(POLICER_CLASSIFY_DUMP, policer_classify_dump) \ +_(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \ + ip_source_and_port_range_check_add_del) \ +_(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \ + ip_source_and_port_range_check_interface_add_del) + void vl_msg_api_custom_dump_configure (api_main_t *am) { diff --git a/vpp/vpp-api/vpe.api b/vpp/vpp-api/vpe.api index ebadda85..ba7572bc 100644 --- a/vpp/vpp-api/vpe.api +++ b/vpp/vpp-api/vpe.api @@ -4343,3 +4343,60 @@ define pg_enable_disable_reply { u32 context; i32 retval; }; + +/** \brief Configure IP source and L4 port-range check + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param is_ip6 - 1 if source address type is IPv6 + @param is_add - 1 if add, 0 if delete + @param mask_length - mask length for address entry + @param address - array of address bytes + @param low_ports[32] - up to 32 low end of port range entries (must have corresponding high_ports entry) + @param high_ports[32] - up to 32 high end of port range entries (must have corresponding low_ports entry) + @param vrf_id - fib table/vrf id to associate the source and port-range check with + @note To specify a single port set low_port and high_port entry the same +*/ +define ip_source_and_port_range_check_add_del { + u32 client_index; + u32 context; + u8 is_ipv6; + u8 is_add; + u8 mask_length; + u8 address[16]; + u8 number_of_ranges; + u16 low_ports[32]; + u16 high_ports[32]; + u32 vrf_id; +}; + +/** \brief Configure IP source and L4 port-range check reply + @param context - returned sender context, to match reply w/ request + @param retval - return code +*/ +define ip_source_and_port_range_check_add_del_reply { + u32 context; + i32 retval; +}; + +/** \brief Set interface source and L4 port-range request + @param client_index - opaque cookie to identify the sender + @param context - sender context, to match reply w/ request + @param interface_id - interface index + @param vrf_id - VRF associated with source and L4 port-range check +*/ +define ip_source_and_port_range_check_interface_add_del { + u32 client_index; + u32 context; + u8 is_add; + u32 sw_if_index; + u32 vrf_id; +}; + +/** \brief Set interface source and L4 port-range response + @param context - sender context, to match reply w/ request + @param retval - return value for request +*/ +define ip_source_and_port_range_check_interface_add_del_reply { + u32 context; + i32 retval; +}; |