aboutsummaryrefslogtreecommitdiffstats
path: root/vpp
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2016-04-30 10:25:32 -0400
committerKeith Burns (alagalah) <alagalah@gmail.com>2016-08-01 18:16:24 -0700
commit6f9bca21945b171035a2a00663f1cd2185027f8b (patch)
tree7ed04ce7ed88233f1900941b1b41cd78c890d3ee /vpp
parentf7643fd9e1915e703d9a696c97be685328e9c388 (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.c126
-rw-r--r--vpp/vpp-api/custom_dump.c50
-rw-r--r--vpp/vpp-api/vpe.api57
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;
+};