SNAT: IPFIX logging (VPP-445)

Change-Id: I8450217dd43a1cd9f510e40dfb22274ffc33a4c6
Signed-off-by: Matus Fabian <matfabia@cisco.com>
This commit is contained in:
Matus Fabian
2017-01-13 04:15:54 -08:00
committed by Damjan Marion
parent 2d0b6e380b
commit eea28d78a3
11 changed files with 1608 additions and 11 deletions
+2 -1
View File
@@ -18,7 +18,8 @@ vppplugins_LTLIBRARIES += snat_plugin.la
snat_plugin_la_SOURCES = snat/snat.c \
snat/in2out.c \
snat/out2in.c \
snat/snat_plugin.api.h
snat/snat_plugin.api.h \
snat/snat_ipfix_logging.c
API_FILES += snat/snat.api
+17
View File
@@ -22,6 +22,7 @@
#include <vnet/ethernet/ethernet.h>
#include <vnet/fib/ip4_fib.h>
#include <snat/snat.h>
#include <snat/snat_ipfix_logging.h>
#include <vppinfra/hash.h>
#include <vppinfra/error.h>
@@ -213,6 +214,14 @@ static u32 slow_path (snat_main_t *sm, vlib_buffer_t *b0,
if (clib_bihash_add_del_8_8 (&sm->out2in, &kv0, 0 /* is_add */))
clib_warning ("out2in key delete failed");
/* log NAT event */
snat_ipfix_logging_nat44_ses_delete(s->in2out.addr.as_u32,
s->out2in.addr.as_u32,
s->in2out.protocol,
s->in2out.port,
s->out2in.port,
s->in2out.fib_index);
snat_free_outside_address_and_port
(sm, &s->out2in, s->outside_address_index);
s->outside_address_index = ~0;
@@ -302,6 +311,14 @@ static u32 slow_path (snat_main_t *sm, vlib_buffer_t *b0,
kv0.key = worker_by_out_key.as_u64;
kv0.value = cpu_index;
clib_bihash_add_del_8_8 (&sm->worker_by_out, &kv0, 1);
/* log NAT event */
snat_ipfix_logging_nat44_ses_create(s->in2out.addr.as_u32,
s->out2in.addr.as_u32,
s->in2out.protocol,
s->in2out.port,
s->out2in.port,
s->in2out.fib_index);
return next0;
}
+9 -1
View File
@@ -22,6 +22,7 @@
#include <vnet/ethernet/ethernet.h>
#include <vnet/fib/ip4_fib.h>
#include <snat/snat.h>
#include <snat/snat_ipfix_logging.h>
#include <vppinfra/hash.h>
#include <vppinfra/error.h>
@@ -210,7 +211,14 @@ create_session_for_static_mapping (snat_main_t *sm,
if (clib_bihash_add_del_8_8 (&sm->out2in, &kv0, 1 /* is_add */))
clib_warning ("out2in key add failed");
return s;
/* log NAT event */
snat_ipfix_logging_nat44_ses_create(s->in2out.addr.as_u32,
s->out2in.addr.as_u32,
s->in2out.protocol,
s->in2out.port,
s->out2in.port,
s->in2out.fib_index);
return s;
}
static inline u32 icmp_out2in_slow_path (snat_main_t *sm,
+24
View File
@@ -318,3 +318,27 @@ define snat_interface_addr_details {
u32 context;
u32 sw_if_index;
};
/** \brief Enable/disable S-NAT IPFIX logging
@param client_index - opaque cookie to identify the sender
@param context - sender context, to match reply w/ request
@param domain_id - observation domain ID
@param src_port - source port number
@param enable - 1 if enable, 0 if disable
*/
define snat_ipfix_enable_disable {
u32 client_index;
u32 context;
u32 domain_id;
u16 src_port;
u8 enable;
};
/** \brief Enable/disable S-NAT IPFIX logging reply
@param context - sender context, to match reply w/ request
@param retval - return code
*/
define snat_ipfix_enable_disable_reply {
u32 context;
i32 retval;
};
+108 -4
View File
@@ -21,6 +21,7 @@
#include <vnet/plugin/plugin.h>
#include <vlibapi/api.h>
#include <snat/snat.h>
#include <snat/snat_ipfix_logging.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
@@ -278,6 +279,13 @@ int snat_del_address (snat_main_t *sm, ip4_address_t addr)
pool_foreach (ses, tsm->sessions, ({
if (ses->out2in.addr.as_u32 == addr.as_u32)
{
/* log NAT event */
snat_ipfix_logging_nat44_ses_delete(ses->in2out.addr.as_u32,
ses->out2in.addr.as_u32,
ses->in2out.protocol,
ses->in2out.port,
ses->out2in.port,
ses->in2out.fib_index);
vec_add1 (ses_to_be_removed, ses - tsm->sessions);
kv.key = ses->in2out.as_u64;
clib_bihash_add_del_8_8 (&sm->in2out, &kv, 0);
@@ -550,6 +558,14 @@ int snat_add_static_mapping(ip4_address_t l_addr, ip4_address_t e_addr,
continue;
}
/* log NAT event */
snat_ipfix_logging_nat44_ses_delete(s->in2out.addr.as_u32,
s->out2in.addr.as_u32,
s->in2out.protocol,
s->in2out.port,
s->out2in.port,
s->in2out.fib_index);
value.key = s->in2out.as_u64;
clib_bihash_add_del_8_8 (&sm->in2out, &value, 0);
value.key = s->out2in.as_u64;
@@ -1172,6 +1188,37 @@ static void *vl_api_snat_interface_addr_dump_t_print
FINISH;
}
static void
vl_api_snat_ipfix_enable_disable_t_handler
(vl_api_snat_ipfix_enable_disable_t * mp)
{
snat_main_t * sm = &snat_main;
vl_api_snat_ipfix_enable_disable_reply_t * rmp;
int rv = 0;
rv = snat_ipfix_logging_enable_disable(mp->enable,
clib_host_to_net_u32 (mp->domain_id),
clib_host_to_net_u16 (mp->src_port));
REPLY_MACRO (VL_API_SNAT_IPFIX_ENABLE_DISABLE_REPLY);
}
static void *vl_api_snat_ipfix_enable_disable_t_print
(vl_api_snat_ipfix_enable_disable_t *mp, void * handle)
{
u8 * s;
s = format (0, "SCRIPT: snat_ipfix_enable_disable ");
if (mp->domain_id)
s = format (s, "domain %d ", clib_net_to_host_u32 (mp->domain_id));
if (mp->src_port)
s = format (s, "src_port %d ", clib_net_to_host_u16 (mp->src_port));
if (!mp->enable)
s = format (s, "disable ");
FINISH;
}
/* List of message types that this plugin understands */
#define foreach_snat_plugin_api_msg \
_(SNAT_ADD_ADDRESS_RANGE, snat_add_address_range) \
@@ -1185,7 +1232,8 @@ _(SNAT_INTERFACE_DUMP, snat_interface_dump) \
_(SNAT_SET_WORKERS, snat_set_workers) \
_(SNAT_WORKER_DUMP, snat_worker_dump) \
_(SNAT_ADD_DEL_INTERFACE_ADDR, snat_add_del_interface_addr) \
_(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump)
_(SNAT_INTERFACE_ADDR_DUMP, snat_interface_addr_dump) \
_(SNAT_IPFIX_ENABLE_DISABLE, snat_ipfix_enable_disable)
/* Set up the API message handling tables */
static clib_error_t *
@@ -1303,6 +1351,9 @@ static clib_error_t * snat_init (vlib_main_t * vm)
vec_add1 (im->add_del_interface_address_callbacks, cb4);
/* Init IPFIX logging */
snat_ipfix_logging_init(vm);
return error;
}
@@ -1420,6 +1471,7 @@ int snat_alloc_outside_address_and_port (snat_main_t * sm,
}
}
/* Totally out of translations to use... */
snat_ipfix_logging_addresses_exhausted(0);
return 1;
}
@@ -1719,6 +1771,58 @@ VLIB_CLI_COMMAND (set_workers_command, static) = {
"set snat workers <workers-list>",
};
static clib_error_t *
snat_ipfix_logging_enable_disable_command_fn (vlib_main_t * vm,
unformat_input_t * input,
vlib_cli_command_t * cmd)
{
unformat_input_t _line_input, *line_input = &_line_input;
u32 domain_id = 0;
u32 src_port = 0;
u8 enable = 1;
int rv = 0;
/* Get a line of input. */
if (!unformat_user (input, unformat_line_input, line_input))
return 0;
while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
{
if (unformat (line_input, "domain %d", &domain_id))
;
else if (unformat (line_input, "src-port %d", &src_port))
;
else if (unformat (line_input, "disable"))
enable = 0;
else
return clib_error_return (0, "unknown input '%U'",
format_unformat_error, input);
}
unformat_free (line_input);
rv = snat_ipfix_logging_enable_disable (enable, domain_id, (u16) src_port);
if (rv)
return clib_error_return (0, "ipfix logging enable failed");
return 0;
}
/*?
* @cliexpar
* @cliexstart{snat ipfix logging}
* To enable SNAT IPFIX logging use:
* vpp# snat ipfix logging
* To set IPFIX exporter use:
* vpp# set ipfix exporter collector 10.10.10.3 src 10.10.10.1
* @cliexend
?*/
VLIB_CLI_COMMAND (snat_ipfix_logging_enable_disable_command, static) = {
.path = "snat ipfix logging",
.function = snat_ipfix_logging_enable_disable_command_fn,
.short_help = "snat ipfix logging [domain <domain-id>] [src-port <port>] [disable]",
};
static clib_error_t *
snat_config (vlib_main_t * vm, unformat_input_t * input)
{
@@ -1968,7 +2072,7 @@ show_snat_command_fn (vlib_main_t * vm,
({
s = format (s, " %d", j);
}));
vlib_cli_output (vm, " %d busy ports:%v", ap->busy_ports, s);
vlib_cli_output (vm, " %d busy ports:%s", ap->busy_ports, s);
}
}
@@ -1981,7 +2085,7 @@ show_snat_command_fn (vlib_main_t * vm,
{
vlib_worker_thread_t *w =
vlib_worker_threads + *worker + sm->first_worker_index;
vlib_cli_output (vm, " %v", w->name);
vlib_cli_output (vm, " %s", w->name);
}
}
}
@@ -2032,7 +2136,7 @@ show_snat_command_fn (vlib_main_t * vm,
continue;
vlib_worker_thread_t *w = vlib_worker_threads + j;
vlib_cli_output (vm, "Thread %d (%v at lcore %u):", j, w->name,
vlib_cli_output (vm, "Thread %d (%s at lcore %u):", j, w->name,
w->lcore_id);
vlib_cli_output (vm, " %d list pool elements",
pool_elts (tsm->list_pool));
File diff suppressed because it is too large Load Diff
+68
View File
@@ -0,0 +1,68 @@
/*
* snat_ipfix_logging.h - NAT Events IPFIX logging
*
* Copyright (c) 2016 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef __included_snat_ipfix_logging_h__
#define __included_snat_ipfix_logging_h__
typedef enum {
NAT_ADDRESSES_EXHAUTED = 3,
NAT44_SESSION_CREATE = 4,
NAT44_SESSION_DELETE = 5,
NAT_PORTS_EXHAUSTED = 12,
} nat_event_t;
typedef struct {
/** S-NAT IPFIX logging enabled */
u8 enabled;
/** ipfix buffers under construction */
vlib_buffer_t *nat44_session_buffer;
vlib_buffer_t *addr_exhausted_buffer;
/** frames containing ipfix buffers */
vlib_frame_t *nat44_session_frame;
vlib_frame_t *addr_exhausted_frame;
/** next record offset */
u32 nat44_session_next_record_offset;
u32 addr_exhausted_next_record_offset;
/** Time reference pair */
u64 milisecond_time_0;
f64 vlib_time_0;
/** template IDs */
u16 nat44_session_template_id;
u16 addr_exhausted_template_id;
/** stream index */
u32 stream_index;
} snat_ipfix_logging_main_t;
extern snat_ipfix_logging_main_t snat_ipfix_logging_main;
void snat_ipfix_logging_init (vlib_main_t * vm);
int snat_ipfix_logging_enable_disable (int enable, u32 domain_id, u16 src_port);
void snat_ipfix_logging_nat44_ses_create (u32 src_ip, u32 nat_src_ip,
snat_protocol_t snat_proto,
u16 src_port, u16 nat_src_port,
u32 vrf_id);
void snat_ipfix_logging_nat44_ses_delete (u32 src_ip, u32 nat_src_ip,
snat_protocol_t snat_proto,
u16 src_port, u16 nat_src_port,
u32 vrf_id);
void snat_ipfix_logging_addresses_exhausted(u32 pool_id);
#endif /* __included_snat_ipfix_logging_h__ */
+44 -4
View File
@@ -62,7 +62,8 @@ _(snat_add_address_range_reply) \
_(snat_interface_add_del_feature_reply) \
_(snat_add_static_mapping_reply) \
_(snat_set_workers_reply) \
_(snat_add_del_interface_addr_reply)
_(snat_add_del_interface_addr_reply) \
_(snat_ipfix_enable_disable_reply)
#define _(n) \
static void vl_api_##n##_t_handler \
@@ -98,7 +99,9 @@ _(SNAT_SET_WORKERS_REPLY, snat_set_workers_reply) \
_(SNAT_WORKER_DETAILS, snat_worker_details) \
_(SNAT_ADD_DEL_INTERFACE_ADDR_REPLY, \
snat_add_del_interface_addr_reply) \
_(SNAT_INTERFACE_ADDR_DETAILS, snat_interface_addr_details)
_(SNAT_INTERFACE_ADDR_DETAILS, snat_interface_addr_details) \
_(SNAT_IPFIX_ENABLE_DISABLE_REPLY, \
snat_ipfix_enable_disable_reply)
/* M: construct, but don't yet send a message */
#define M(T,t) \
@@ -543,7 +546,7 @@ static int api_snat_worker_dump(vat_main_t * vam)
return 0;
}
static int api_snat_add_del_interface_addr (vat_main_t * vam)
static int api_snat_ipfix_enable_disable (vat_main_t * vam)
{
snat_test_main_t * sm = &snat_test_main;
unformat_input_t * i = vam->input;
@@ -617,6 +620,41 @@ static int api_snat_interface_addr_dump(vat_main_t * vam)
return 0;
}
static int api_snat_add_del_interface_addr (vat_main_t * vam)
{
snat_test_main_t * sm = &snat_test_main;
unformat_input_t * i = vam->input;
f64 timeout;
vl_api_snat_ipfix_enable_disable_t * mp;
u32 domain_id = 0;
u32 src_port = 0;
u8 enable = 1;
while (unformat_check_input (i) != UNFORMAT_END_OF_INPUT)
{
if (unformat (i, "domain %d", &domain_id))
;
else if (unformat (i, "src_port %d", &src_port))
;
else if (unformat (i, "disable"))
enable = 0;
else
{
clib_warning("unknown input '%U'", format_unformat_error, i);
return -99;
}
}
M(SNAT_IPFIX_ENABLE_DISABLE, snat_ipfix_enable_disable);
mp->domain_id = htonl(domain_id);
mp->src_port = htons((u16) src_port);
mp->enable = enable;
S; W;
/* NOTREACHED */
return 0;
}
/*
* List of messages that the api test plugin sends,
* and that the data plane plugin processes
@@ -635,7 +673,9 @@ _(snat_interface_dump, "") \
_(snat_worker_dump, "") \
_(snat_add_del_interface_addr, \
"<intfc> | sw_if_index <id> [del]") \
_(snat_interface_addr_dump, "")
_(snat_interface_addr_dump, "") \
_(snat_ipfix_enable_disable, "[domain <id>] [src_port <n>] " \
"[disable]")
void vat_api_hookup (vat_main_t *vam)
{