SNAT: IPFIX logging (VPP-445)
Change-Id: I8450217dd43a1cd9f510e40dfb22274ffc33a4c6 Signed-off-by: Matus Fabian <matfabia@cisco.com>
This commit is contained in:
committed by
Damjan Marion
parent
2d0b6e380b
commit
eea28d78a3
+2
-1
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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
@@ -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
@@ -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__ */
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user