Skip to content

Commit

Permalink
* uacctd: configurable read Netlink buffer (snaplen) via setsockopt()…
Browse files Browse the repository at this point in the history
… call

  and internal Netlink buffer (uacctd_nl_size) for better performances at
  higher pps rates. Many thanks go to A.O. Prokofiev, author of the patch.
* Documentation updated
  • Loading branch information
paololucente authored and paolo committed Oct 19, 2009
1 parent 5a2669f commit 650780d
Show file tree
Hide file tree
Showing 7 changed files with 47 additions and 22 deletions.
22 changes: 16 additions & 6 deletions CONFIG-KEYS
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,10 @@ DESC: specifies the maximum number of bytes to capture for each packet. This di
resources. The right value need to be traded-off. In case classification is enabled,
values under 200 bytes are often meaningless. 500-750 bytes are enough even for text
based protocols. Default snaplen values are ok if classification is disabled.
For uacctd daemon, this option doesn't apply to packet snapshot length but rather to
the Netlink socket read buffer size. This should be reasonably large - at least 4KB,
which is the default value. For large uacctd_nl_size values snaplen could be further
increased.

KEY: plugins (-P)
VALUES: [ memory | print | mysql | pgsql | sqlite3 | nfprobe | sfprobe ]
Expand Down Expand Up @@ -700,7 +704,7 @@ DESC: enables packet sampling. It expects a number which is the mean ratio of p
methods). Finally, note that this 'sampling_rate' directive can be renormalized by using the
'usrf' action of the 'sql_preprocess' layer. (default: no sampling)

KEY: pmacctd_force_frag_handling [GLOBAL, NO_NFACCTD]
KEY: [ pmacctd_force_frag_handling | uacctd_force_frag_handling ] [GLOBAL, NO_NFACCTD]
VALUES: [true|false]
DESC: forces 'pmacctd' to join together IPv4/IPv6 fragments: 'pmacctd' does this only whether any of
the port primitives are selected (src_port, dst_port, sum_port); in fact, when not dealing with
Expand All @@ -709,25 +713,25 @@ DESC: forces 'pmacctd' to join together IPv4/IPv6 fragments: 'pmacctd' does thi
whether they need to match TCP/UDP ports. So, this directive aims to support such scenarios.
(default: false)

KEY: pmacctd_frag_buffer_size [GLOBAL, NO_NFACCTD]
KEY: [ pmacctd_frag_buffer_size | uacctd_frag_buffer_size ] [GLOBAL, NO_NFACCTD]
DESC: defines the maximum size of the fragment buffer. The value is expeced in bytes (default: 4 Mb).

KEY: pmacctd_flow_buffer_size [GLOBAL, NO_NFACCTD]
KEY: [ pmacctd_flow_buffer_size | uacctd_flow_buffer_size ] [GLOBAL, NO_NFACCTD]
DESC: defines the maximum size of the flow buffer. This is an upper limit to avoid unlimited growth
of the memory structure. This value has to scale accordingly to the link traffic rate. It is
expected in bytes (default: 16 Mb).

KEY: pmacctd_flow_buffer_buckets [GLOBAL, NO_NFACCTD]
KEY: [ pmacctd_flow_buffer_buckets | uacctd_flow_buffer_buckets ] [GLOBAL, NO_NFACCTD]
DESC: defines the number of buckets of the flow buffer - which is organized as a chained hash table.
To exploit better performances, the table should be reasonably flat. This value has to scale to
higher power of 2 accordingly to the link traffic rate. For example, it has been reported that
a value of 65536 works just fine under full 100Mbit load (default: 256).

KEY: pmacctd_conntrack_buffer_size [GLOBAL, NO_NFACCTD]
KEY: [ pmacctd_conntrack_buffer_size | uacctd_conntrack_buffer_size ] [GLOBAL, NO_NFACCTD]
DESC: defines the maximum size of the connection tracking buffer. The value is expected in bytes
(default: 8 Mb).

KEY: pmacctd_flow_lifetime [GLOBAL, NO_NFACCTD]
KEY: [ pmacctd_flow_lifetime | uacctd_flow_lifetime ] [GLOBAL, NO_NFACCTD]
DESC: defines how long a flow could remain inactive (ie. no packets belonging to such flow are received)
before considering it expired. The value is expected in seconds. (default: 60 secs)

Expand Down Expand Up @@ -950,3 +954,9 @@ DESC: writes a list of the BGP neighbors in the established state to the specif
KEY: uacctd_group
DESC: Sets the Linux Netlink ULOG multicast group to be joined. (default: 1)

KEY: uacctd_nl_size
DESC: Sets ULOG Netlink internal buffer size (specified in bytes). It is 4KB by default, but to
safely record bursts of high-speed traffic, it could be further increased. For high loads,
values as large as 2MB are recommended. When modifying this value, it is also recommended
to reflect the change to the 'snaplen' option. (default: 4096)

1 change: 1 addition & 0 deletions src/cfg.h
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ struct configuration {
char *sfprobe_agentip;
int sfprobe_agentsubid;
int uacctd_group;
int uacctd_nl_size;
};

struct plugin_type_entry {
Expand Down
11 changes: 11 additions & 0 deletions src/cfg_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -2322,3 +2322,14 @@ int cfg_key_uacctd_group(char *filename, char *name, char *value_ptr)
for (; list; list = list->next, changes++) list->cfg.uacctd_group = (1 << (value-1));
return changes;
}

int cfg_key_uacctd_nl_size(char *filename, char *name, char *value_ptr)
{
struct plugins_list_entry *list = plugins_list;
int value, changes = 0;

value = atoi(value_ptr);

for (; list; list = list->next, changes++) list->cfg.uacctd_nl_size = value;
return changes;
}
1 change: 1 addition & 0 deletions src/cfg_handlers.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ EXT int cfg_key_nfacctd_bgp_to_agent_map(char *, char *, char *);
EXT int cfg_key_nfacctd_bgp_follow_default(char *, char *, char *);
EXT int cfg_key_nfacctd_bgp_neighbors_file(char *, char *, char *);
EXT int cfg_key_uacctd_group(char *, char *, char *);
EXT int cfg_key_uacctd_nl_size(char *, char *, char *);

EXT void parse_time(char *, char *, int *, int *);
#undef EXT
1 change: 1 addition & 0 deletions src/pmacct-data.h
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,7 @@ static const struct _dictionary_line dictionary[] = {
{"bgp_follow_default", cfg_key_nfacctd_bgp_follow_default},
{"bgp_neighbors_file", cfg_key_nfacctd_bgp_neighbors_file},
{"uacctd_group", cfg_key_uacctd_group},
{"uacctd_nl_size", cfg_key_uacctd_nl_size},
{"", NULL},
};

Expand Down
2 changes: 1 addition & 1 deletion src/pmacct-defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
#define ARGS_NFACCTD "n:dDhP:b:f:F:c:m:p:r:s:S:L:l:v:o:R"
#define ARGS_SFACCTD "n:dDhP:b:f:F:c:m:p:r:s:S:L:l:v:o:R"
#define ARGS_PMACCTD "n:NdDhP:b:f:F:c:i:I:m:p:r:s:S:v:o:wWL:R"
#define ARGS_UACCTD "n:NdDhP:b:f:F:c:m:p:r:s:S:v:o:Rg:"
#define ARGS_UACCTD "n:NdDhP:b:f:F:c:m:p:r:s:S:v:o:Rg:L:"
#define ARGS_PMACCT "Ssc:Cetm:p:P:M:arN:n:lT:"
#define N_PRIMITIVES 21
#define N_FUNCS 10
Expand Down
31 changes: 16 additions & 15 deletions src/uacctd.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ void usage_daemon(char *prog_name)
printf(" -F \tWrite Core Process PID into the specified file\n");
printf(" -R \tRenormalize sampled data\n");
printf(" -g \tNetlink ULOG group\n");
printf(" -L \tNetlink socket read buffer size\n");
printf("\nMemory Plugin (-P memory) options:\n");
printf(" -p \tSocket for client-server communication (DEFAULT: /tmp/collect.pipe)\n");
printf(" -b \tNumber of buckets\n");
Expand Down Expand Up @@ -237,6 +238,11 @@ int main(int argc,char **argv, char **envp)
strncat(cfg_cmdline[rows], optarg, CFG_LINE_LEN(cfg_cmdline[rows]));
rows++;
break;
case 'L':
strlcpy(cfg_cmdline[rows], "snaplen: ", SRVBUFLEN);
strncat(cfg_cmdline[rows], optarg, CFG_LINE_LEN(cfg_cmdline[rows]));
rows++;
break;
case 'R':
strlcpy(cfg_cmdline[rows], "sfacctd_renormalize: true", SRVBUFLEN);
rows++;
Expand Down Expand Up @@ -274,7 +280,8 @@ int main(int argc,char **argv, char **envp)

if (config.files_umask) umask(config.files_umask);

config.snaplen = psize;
if (!config.snaplen) config.snaplen = psize;
if (!config.uacctd_nl_size) config.uacctd_nl_size = psize;

/* Let's check whether we need superuser privileges */
if (getuid() != 0) {
Expand Down Expand Up @@ -458,20 +465,6 @@ int main(int argc,char **argv, char **envp)
if (config.handle_flows) init_ip_flow_handler();
load_networks(config.networks_file, &nt, &nc);

/*
// XXX: applicable afterwards to ULOG socket?
//
if (config.pipe_size) {
int slen = sizeof(config.pipe_size), x;
#if defined (PCAP_TYPE_linux) || (PCAP_TYPE_snoop)
Setsocksize(pcap_fileno(device.dev_desc), SOL_SOCKET, SO_RCVBUF, &config.pipe_size, slen);
getsockopt(pcap_fileno(device.dev_desc), SOL_SOCKET, SO_RCVBUF, &x, &slen);
Log(LOG_DEBUG, "DEBUG ( default/core ): PCAP buffer: obtained %d / %d bytes.\n", x, config.pipe_size);
#endif
}
*/

device.link_type = DLT_RAW;
for (index = 0; _devices[index].link_type != -1; index++) {
if (device.link_type == _devices[index].link_type)
Expand All @@ -496,6 +489,14 @@ int main(int argc,char **argv, char **envp)

Log(LOG_INFO, "INFO ( default/core ): Successfully connected Netlink ULOG socket\n");

if (config.uacctd_nl_size > ULOG_BUFLEN) {
/* If configured buffer size is larger than default 4KB */
if (setsockopt(ulog_fd, SOL_SOCKET, SO_RCVBUF, &config.uacctd_nl_size, sizeof(config.uacctd_nl_size)))
Log(LOG_ERR, "ERROR ( default/core ): Failed to set Netlink receive buffer size\n");
else
Log(LOG_INFO, "INFO ( default/core ): Netlink receive buffer size set to %u\n", config.uacctd_nl_size);
}

ulog_buffer = malloc(config.snaplen);
if (ulog_buffer == NULL) {
Log(LOG_ERR, "ERROR ( default/core ): ULOG buffer malloc() failed\n");
Expand Down

0 comments on commit 650780d

Please sign in to comment.