I’ve added a new feature that I would like to share.
The pf_ring feature allows packets sampling of packets that belong to a sw
filtered session.
In other words, if a sw filter is applied, you will be able not to block
100% of the packets (till filtering rule removal). Some packets will be
allowed to “pass” the filter.
The use case is keeping the advantage of improved performance by filtering
most (e.g. 90%) of the traffic, while being able to get some (e.g. 10%) of
the traffic for analysis purposes. This will allow the application not be
100% blind.
This feature is not good for applications that are sensitive to
out-of-sequence packets.
Technical code details:
1. New pf_ring param “filtering_sampling_segment_size” is set to 100
by default.
2. New pf_ring userspace API int
pfring_set_sw_filtering_sampling_rate(pfring *ring, u_int32_t rate /* 0 =
no sampling */) was added.
This API should be used right after adding a new SW hash filtering rule,
with a “rate” parameter.
A rate=10 means that the 10 first packets of every segment of 100 filtered
packets of the session, will be forwarded.
If the API is not called, then the default rate=0, thus no change in
current behavior (i.e. 100% of the packets are filtered, since 0 filtered
packets are forwarded).
3. I’ve had to add a new member variable to struct pf_ring_socket
which is ‘sw_filtering_hash_filtered’ that counts the actual filtered
packets.
Current ‘sw_filtering_hash_match’ is not good enough anymore for this
purpose since it counts the matches before excluding the forwarded packets,
but it has a great help
in calculating the sampled filtered packets.
Technical build/test details:
1. Functionality was tested based on pf_ring version 6.6.0 (on CentOS
7)
2. Attached patch was created based on latest pf_ring code-base
(Sep-7, 2017), and tested for compilation only. Not functionality.
If this feature will ever make it to the main code, it would be great.
Any comments are welcome.
Amir
diff -Naur PF_RING-dev.20170907/kernel/linux/pf_ring.h
PF_RING-dev.20170907.sampling/kernel/linux/pf_ring.h
--- PF_RING-dev.20170907/kernel/linux/pf_ring.h 2017-09-07 13:02:53.000000000
+0300
+++ PF_RING-dev.20170907.sampling/kernel/linux/pf_ring.h 2017-09-07
13:35:43.508272000 +0300
@@ -65,6 +65,7 @@
#define SO_SET_POLL_WATERMARK 117
#define SO_SET_VIRTUAL_FILTERING_DEVICE 118
#define SO_REHASH_RSS_PACKET 119
+#define SO_SET_SW_FILTERING_SAMPLING_RATE 120
#define SO_SHUTDOWN_RING 124
#define SO_PURGE_IDLE_RULES 125 /* inactivity (sec) */
#define SO_SET_SOCKET_MODE 126
@@ -1078,6 +1079,7 @@
sw_filtering_hash_bucket **sw_filtering_hash;
u_int64_t sw_filtering_hash_match;
u_int64_t sw_filtering_hash_miss;
+ u_int64_t sw_filtering_hash_filtered;
u_int32_t num_sw_filtering_hash;
/* Sw Filtering Rules - wildcard */
@@ -1087,6 +1089,8 @@
/* Hw Filtering Rules */
u_int16_t num_hw_filtering_rules;
struct list_head hw_filtering_rules;
+ /* Sw Filtering - sampling rate */
+ u_int32_t sw_filtering_sampling_rate;
/* Locks */
atomic_t num_ring_users;
diff -Naur PF_RING-dev.20170907/kernel/pf_ring.c
PF_RING-dev.20170907.sampling/kernel/pf_ring.c
--- PF_RING-dev.20170907/kernel/pf_ring.c 2017-09-07 13:02:53.000000000
+0300
+++ PF_RING-dev.20170907.sampling/kernel/pf_ring.c 2017-09-07
13:54:45.102938000 +0300
@@ -365,6 +365,7 @@
static unsigned int force_ring_lock = 0;
static unsigned int enable_debug = 0;
static unsigned int transparent_mode = 0;
+static unsigned int filtering_sampling_segment_size = 100;
static atomic_t ring_id_serial = ATOMIC_INIT(0);
#if defined(RHEL_RELEASE_CODE)
@@ -382,6 +383,7 @@
module_param(force_ring_lock, uint, 0644);
module_param(enable_debug, uint, 0644);
module_param(transparent_mode, uint, 0644);
+module_param(filtering_sampling_segment_size, uint, 0644);
MODULE_PARM_DESC(min_num_slots, "Min number of ring slots");
MODULE_PARM_DESC(perfect_rules_hash_size, "Perfect rules hash size");
@@ -397,6 +399,7 @@
MODULE_PARM_DESC(enable_debug, "Set to 1 to enable PF_RING debug tracing into
the syslog, 2 for more verbosity");
MODULE_PARM_DESC(transparent_mode,
"(deprecated)");
+MODULE_PARM_DESC(filtering_sampling_segment_size, "Size of filtered packets
segment for sampling (currently, for sw hash filters only)");
/* ********************************** */
@@ -1360,20 +1363,21 @@
if(m->private == NULL) {
/* /proc/net/pf_ring/info */
- seq_printf(m, "PF_RING Version : %s (%s)\n", RING_VERSION,
GIT_REV);
- seq_printf(m, "Total rings : %d\n",
atomic_read(&ring_table_size));
+ seq_printf(m, "PF_RING Version : %s (%s)\n", RING_VERSION,
GIT_REV);
+ seq_printf(m, "Total rings : %d\n",
atomic_read(&ring_table_size));
seq_printf(m, "\nStandard (non ZC) Options\n");
- seq_printf(m, "Ring slots : %d\n", min_num_slots);
- seq_printf(m, "Slot version : %d\n", RING_FLOWSLOT_VERSION);
- seq_printf(m, "Capture TX : %s\n", enable_tx_capture ? "Yes
[RX+TX]" : "No [RX only]");
- seq_printf(m, "IP Defragment : %s\n", enable_ip_defrag ? "Yes"
: "No");
- seq_printf(m, "Socket Mode : %s\n", quick_mode ? "Quick" :
"Standard");
+ seq_printf(m, "Ring slots : %d\n", min_num_slots);
+ seq_printf(m, "Slot version : %d\n",
RING_FLOWSLOT_VERSION);
+ seq_printf(m, "Capture TX : %s\n", enable_tx_capture
? "Yes [RX+TX]" : "No [RX only]");
+ seq_printf(m, "IP Defragment : %s\n", enable_ip_defrag ?
"Yes" : "No");
+ seq_printf(m, "Socket Mode : %s\n", quick_mode ?
"Quick" : "Standard");
if(enable_frag_coherence) {
purge_idle_fragment_cache();
- seq_printf(m, "Cluster Fragment Queue : %u\n", num_cluster_fragments);
- seq_printf(m, "Cluster Fragment Discard : %u\n",
num_cluster_discarded_fragments);
+ seq_printf(m, "Cluster Fragment Queue : %u\n",
num_cluster_fragments);
+ seq_printf(m, "Cluster Fragment Discard : %u\n",
num_cluster_discarded_fragments);
}
+ seq_printf(m, "Filtering sampling segment size : %d\n",
filtering_sampling_segment_size);
} else {
/* Detailed statistics about a PF_RING */
struct pf_ring_socket *pfr = (struct pf_ring_socket *)m->private;
@@ -1383,7 +1387,7 @@
struct list_head *ptr, *tmp_ptr;
fsi = pfr->slots_info;
- seq_printf(m, "Bound Device(s) : ");
+ seq_printf(m, "Bound Device(s) : ");
if(pfr->custom_bound_device_name[0] != '\0') {
seq_printf(m, pfr->custom_bound_device_name);
@@ -1400,59 +1404,61 @@
seq_printf(m, "\n");
- seq_printf(m, "Active : %d\n", pfr->ring_active);
- seq_printf(m, "Breed : %s\n", (pfr->zc_device_entry !=
NULL) ? "ZC" : "Standard");
- seq_printf(m, "Appl. Name : %s\n", pfr->appl_name ?
pfr->appl_name : "<unknown>");
- seq_printf(m, "Socket Mode : %s\n", sockmode2string(pfr->mode));
+ seq_printf(m, "Active : %d\n", pfr->ring_active);
+ seq_printf(m, "Breed : %s\n", (pfr->zc_device_entry !=
NULL) ? "ZC" : "Standard");
+ seq_printf(m, "Appl. Name : %s\n", pfr->appl_name ?
pfr->appl_name : "<unknown>");
+ seq_printf(m, "Socket Mode : %s\n",
sockmode2string(pfr->mode));
if (pfr->mode != send_only_mode) {
- seq_printf(m, "Capture Direction : %s\n",
direction2string(pfr->direction));
+ seq_printf(m, "Capture Direction : %s\n",
direction2string(pfr->direction));
if (pfr->zc_device_entry == NULL) {
- seq_printf(m, "Sampling Rate : %d\n", pfr->sample_rate);
- seq_printf(m, "IP Defragment : %s\n", enable_ip_defrag ? "Yes"
: "No");
- seq_printf(m, "BPF Filtering : %s\n", pfr->bpfFilter ?
"Enabled" : "Disabled");
- seq_printf(m, "Sw Filt Hash Rules : %d\n",
pfr->num_sw_filtering_hash);
- seq_printf(m, "Sw Filt WC Rules : %d\n",
pfr->num_sw_filtering_rules);
- seq_printf(m, "Sw Filt Hash Match : %llu\n",
pfr->sw_filtering_hash_match);
- seq_printf(m, "Sw Filt Hash Miss : %llu\n",
pfr->sw_filtering_hash_miss);
+ seq_printf(m, "Sampling Rate : %d\n", pfr->sample_rate);
+ seq_printf(m, "IP Defragment : %s\n", enable_ip_defrag ?
"Yes" : "No");
+ seq_printf(m, "BPF Filtering : %s\n", pfr->bpfFilter ?
"Enabled" : "Disabled");
+ seq_printf(m, "Sw Filt Hash Rules : %d\n",
pfr->num_sw_filtering_hash);
+ seq_printf(m, "Sw Filt WC Rules : %d\n",
pfr->num_sw_filtering_rules);
+ seq_printf(m, "Sw Filt Hash Match : %llu\n",
pfr->sw_filtering_hash_match);
+ seq_printf(m, "Sw Filt Hash Miss : %llu\n",
pfr->sw_filtering_hash_miss);
+ seq_printf(m, "Sw Filt Hash Filtered : %llu\n",
pfr->sw_filtering_hash_filtered);
+ seq_printf(m, "Sw Filt Sampling Rate : %u\n",
pfr->sw_filtering_sampling_rate);
}
- seq_printf(m, "Hw Filt Rules : %d\n",
pfr->num_hw_filtering_rules);
- seq_printf(m, "Poll Pkt Watermark : %d\n",
pfr->poll_num_pkts_watermark);
- seq_printf(m, "Num Poll Calls : %u\n", pfr->num_poll_calls);
+ seq_printf(m, "Hw Filt Rules : %d\n",
pfr->num_hw_filtering_rules);
+ seq_printf(m, "Poll Pkt Watermark : %d\n",
pfr->poll_num_pkts_watermark);
+ seq_printf(m, "Num Poll Calls : %u\n", pfr->num_poll_calls);
}
if(pfr->zc_device_entry != NULL) {
/* ZC */
- seq_printf(m, "Channel Id : %d\n",
pfr->zc_device_entry->zc_dev.channel_id);
+ seq_printf(m, "Channel Id : %d\n",
pfr->zc_device_entry->zc_dev.channel_id);
if (pfr->mode != send_only_mode)
- seq_printf(m, "Num RX Slots : %d\n",
pfr->zc_device_entry->zc_dev.mem_info.rx.packet_memory_num_slots);
+ seq_printf(m, "Num RX Slots : %d\n",
pfr->zc_device_entry->zc_dev.mem_info.rx.packet_memory_num_slots);
if (pfr->mode != recv_only_mode)
- seq_printf(m, "Num TX Slots : %d\n",
pfr->zc_device_entry->zc_dev.mem_info.tx.packet_memory_num_slots);
+ seq_printf(m, "Num TX Slots : %d\n",
pfr->zc_device_entry->zc_dev.mem_info.tx.packet_memory_num_slots);
} else if(fsi != NULL) {
/* Standard PF_RING */
- seq_printf(m, "Channel Id Mask : 0x%016llX\n", pfr->channel_id_mask);
+ seq_printf(m, "Channel Id Mask : 0x%016llX\n",
pfr->channel_id_mask);
if (pfr->cluster_id != 0)
- seq_printf(m, "Cluster Id : %d\n", pfr->cluster_id);
- seq_printf(m, "Slot Version : %d [%s]\n", fsi->version,
RING_VERSION);
- seq_printf(m, "Min Num Slots : %d\n", fsi->min_num_slots);
- seq_printf(m, "Bucket Len : %d\n", fsi->data_len);
- seq_printf(m, "Slot Len : %d [bucket+header]\n",
fsi->slot_len);
- seq_printf(m, "Tot Memory : %llu\n", fsi->tot_mem);
+ seq_printf(m, "Cluster Id : %d\n", pfr->cluster_id);
+ seq_printf(m, "Slot Version : %d [%s]\n", fsi->version,
RING_VERSION);
+ seq_printf(m, "Min Num Slots : %d\n", fsi->min_num_slots);
+ seq_printf(m, "Bucket Len : %d\n", fsi->data_len);
+ seq_printf(m, "Slot Len : %d [bucket+header]\n",
fsi->slot_len);
+ seq_printf(m, "Tot Memory : %llu\n", fsi->tot_mem);
if (pfr->mode != send_only_mode) {
- seq_printf(m, "Tot Packets : %lu\n", (unsigned
long)fsi->tot_pkts);
- seq_printf(m, "Tot Pkt Lost : %lu\n", (unsigned
long)fsi->tot_lost);
- seq_printf(m, "Tot Insert : %lu\n", (unsigned
long)fsi->tot_insert);
- seq_printf(m, "Tot Read : %lu\n", (unsigned
long)fsi->tot_read);
- seq_printf(m, "Insert Offset : %lu\n", (unsigned
long)fsi->insert_off);
- seq_printf(m, "Remove Offset : %lu\n", (unsigned
long)fsi->remove_off);
- seq_printf(m, "Num Free Slots : %lu\n", (unsigned
long)get_num_ring_free_slots(pfr));
+ seq_printf(m, "Tot Packets : %lu\n", (unsigned
long)fsi->tot_pkts);
+ seq_printf(m, "Tot Pkt Lost : %lu\n", (unsigned
long)fsi->tot_lost);
+ seq_printf(m, "Tot Insert : %lu\n", (unsigned
long)fsi->tot_insert);
+ seq_printf(m, "Tot Read : %lu\n", (unsigned
long)fsi->tot_read);
+ seq_printf(m, "Insert Offset : %lu\n", (unsigned
long)fsi->insert_off);
+ seq_printf(m, "Remove Offset : %lu\n", (unsigned
long)fsi->remove_off);
+ seq_printf(m, "Num Free Slots : %lu\n", (unsigned
long)get_num_ring_free_slots(pfr));
}
if (pfr->mode != recv_only_mode) {
- seq_printf(m, "TX: Send Ok : %lu\n", (unsigned
long)fsi->good_pkt_sent);
- seq_printf(m, "TX: Send Errors : %lu\n", (unsigned
long)fsi->pkt_send_error);
+ seq_printf(m, "TX: Send Ok : %lu\n", (unsigned
long)fsi->good_pkt_sent);
+ seq_printf(m, "TX: Send Errors : %lu\n", (unsigned
long)fsi->pkt_send_error);
}
if (pfr->mode != send_only_mode) {
- seq_printf(m, "Reflect: Fwd Ok : %lu\n", (unsigned
long)fsi->tot_fwd_ok);
- seq_printf(m, "Reflect: Fwd Errors: %lu\n", (unsigned
long)fsi->tot_fwd_notok);
+ seq_printf(m, "Reflect: Fwd Ok : %lu\n", (unsigned
long)fsi->tot_fwd_ok);
+ seq_printf(m, "Reflect: Fwd Errors : %lu\n", (unsigned
long)fsi->tot_fwd_notok);
}
}
} else
@@ -3467,8 +3473,17 @@
/* [2.1] Search the hash */
if(pfr->sw_filtering_hash != NULL) {
hash_found = check_perfect_rules(skb, pfr, hdr, &fwd_pkt, displ);
- if (hash_found)
+ if (hash_found) {
pfr->sw_filtering_hash_match++;
+ /* If there is a filter for the session, let the first
'sw_filtering_sampling_rate' (e.g. 10) packets
+ * of every 'filtering_sampling_segment_size' (e.g. 100) filtered
packets, to pass the filter
+ */
+ if ( pfr->sw_filtering_sampling_rate && fwd_pkt==0 &&
((pfr->sw_filtering_hash_match % filtering_sampling_segment_size) <
pfr->sw_filtering_sampling_rate) ) {
+ fwd_pkt=1;
+ } else {
+ pfr->sw_filtering_hash_filtered++;
+ }
+ }
else
pfr->sw_filtering_hash_miss++;
}
@@ -4097,6 +4112,7 @@
pfr->master_ring = NULL;
pfr->ring_dev = &none_device_element; /* Unbound socket */
pfr->sample_rate = 1; /* No sampling */
+ pfr->sw_filtering_sampling_rate = 0; /* No filtering sampling */
sk->sk_family = PF_RING;
sk->sk_destruct = ring_sock_destruct;
pfr->ring_id = atomic_inc_return(&ring_id_serial);
@@ -6509,6 +6525,13 @@
return(-EFAULT);
break;
+ case SO_SET_SW_FILTERING_SAMPLING_RATE:
+ if(optlen != sizeof(pfr->sw_filtering_sampling_rate))
+ return(-EINVAL);
+ if(copy_from_user(&pfr->sw_filtering_sampling_rate, optval,
sizeof(pfr->sw_filtering_sampling_rate)))
+ return(-EFAULT);
+ break;
+
case SO_ACTIVATE_RING:
debug_printk(2, "* SO_ACTIVATE_RING *\n");
@@ -8006,13 +8029,14 @@
if(transparent_mode != 0)
printk("[PF_RING] Warning: transparent_mode is deprecated!\n");
- printk("[PF_RING] Min # ring slots %d\n", min_num_slots);
- printk("[PF_RING] Slot version %d\n",
+ printk("[PF_RING] Min # ring slots %d\n", min_num_slots);
+ printk("[PF_RING] Slot version %d\n",
RING_FLOWSLOT_VERSION);
- printk("[PF_RING] Capture TX %s\n",
+ printk("[PF_RING] Capture TX %s\n",
enable_tx_capture ? "Yes [RX+TX]" : "No [RX only]");
- printk("[PF_RING] IP Defragment %s\n",
+ printk("[PF_RING] IP Defragment %s\n",
enable_ip_defrag ? "Yes" : "No");
+ printk("[PF_RING] Filtering sampling segment size %d\n",
filtering_sampling_segment_size);
if((rc = proto_register(&ring_proto, 0)) != 0)
return(rc);
diff -Naur PF_RING-dev.20170907/userland/c++/PFring.h
PF_RING-dev.20170907.sampling/userland/c++/PFring.h
--- PF_RING-dev.20170907/userland/c++/PFring.h 2017-09-07 13:02:53.000000000
+0300
+++ PF_RING-dev.20170907.sampling/userland/c++/PFring.h 2017-09-07
13:56:31.888988000 +0300
@@ -79,6 +79,8 @@
inline int enable_ring() { return pfring_enable_ring(ring); };
inline int set_sampling_rate(u_int32_t rate /* 1 = no sampling */)
{ return pfring_set_sampling_rate(ring, rate); };
+ inline int set_sw_filtering_sampling_rate(u_int32_t rate /* 0 = no sampling
*/)
+ { return pfring_set_sw_filtering_sampling_rate(ring, rate); };
inline int get_version(u_int32_t *version)
{ return pfring_version(ring, version); };
inline int get_socket_id() { return ring->fd; };
diff -Naur PF_RING-dev.20170907/userland/lib/notused/pfring_mod_multi.c
PF_RING-dev.20170907.sampling/userland/lib/notused/pfring_mod_multi.c
--- PF_RING-dev.20170907/userland/lib/notused/pfring_mod_multi.c
2017-09-07 13:02:53.000000000 +0300
+++ PF_RING-dev.20170907.sampling/userland/lib/notused/pfring_mod_multi.c
2017-09-07 13:57:21.413025000 +0300
@@ -161,6 +161,18 @@
/* ******************************* */
+int pfring_mod_multi_set_sw_filtering_sampling_rate(pfring *ring, u_int32_t
rate /* 0 = no sampling */) {
+ struct ring_list_element *elem = (struct ring_list_element *)
ring->priv_data;
+ while(elem != NULL) {
+ if(pfring_set_sw_filtering_sampling_rate(elem->ring, rate)<0)
+ return -1;
+ elem = elem->next;
+ }
+ return 0;
+}
+
+/* ******************************* */
+
int pfring_mod_multi_set_direction(pfring *ring, packet_direction direction) {
struct ring_list_element *elem = (struct ring_list_element *)
ring->priv_data;
while(elem != NULL) {
diff -Naur PF_RING-dev.20170907/userland/lib/pfring.c
PF_RING-dev.20170907.sampling/userland/lib/pfring.c
--- PF_RING-dev.20170907/userland/lib/pfring.c 2017-09-07 13:02:53.000000000
+0300
+++ PF_RING-dev.20170907.sampling/userland/lib/pfring.c 2017-09-07
13:58:19.247064000 +0300
@@ -757,6 +757,23 @@
/* **************************************************** */
+int pfring_set_sw_filtering_sampling_rate(pfring *ring, u_int32_t rate /* 0 =
no sampling */) {
+ if(ring && ring->set_sw_filtering_sampling_rate) {
+ int rc;
+
+ rc = ring->set_sw_filtering_sampling_rate(ring, rate);
+
+ if (rc == 0)
+ ring->sw_filtering_sampling_rate = rate;
+
+ return(rc);
+ }
+
+ return(PF_RING_ERROR_NOT_SUPPORTED);
+}
+
+/* **************************************************** */
+
int pfring_set_packet_slicing(pfring *ring, packet_slicing_level level,
u_int32_t additional_bytes) {
if (ring && ring->set_packet_slicing) {
int rc;
diff -Naur PF_RING-dev.20170907/userland/lib/pfring.h
PF_RING-dev.20170907.sampling/userland/lib/pfring.h
--- PF_RING-dev.20170907/userland/lib/pfring.h 2017-09-07 13:02:53.000000000
+0300
+++ PF_RING-dev.20170907.sampling/userland/lib/pfring.h 2017-09-07
14:00:23.512178000 +0300
@@ -244,6 +244,7 @@
u_int8_t (*get_num_rx_channels) (pfring *);
int (*get_card_settings) (pfring *, pfring_card_settings *);
int (*set_sampling_rate) (pfring *, u_int32_t);
+ int (*set_sw_filtering_sampling_rate)(pfring *, u_int32_t);
int (*set_packet_slicing) (pfring *, packet_slicing_level,
u_int32_t);
int (*get_selectable_fd) (pfring *);
int (*set_direction) (pfring *, packet_direction);
@@ -306,6 +307,7 @@
u_int32_t caplen;
u_int16_t slot_header_len, mtu_len /* 0 = unknown */;
u_int32_t sampling_rate, sampling_counter;
+ u_int32_t sw_filtering_sampling_rate;
packet_slicing_level slicing_level;
u_int32_t slicing_additional_bytes;
u_int8_t is_shutting_down, socket_default_accept_policy;
@@ -750,6 +752,15 @@
int pfring_remove_filtering_rule(pfring *ring, u_int16_t rule_id);
/**
+ * Implement packet sampling during sw filtering directly into the kernel.
Note that this solution is much more efficient than implementing it in
user-space.
+ * Sampled packets during filtering are only those that already has been
filtered (if any).
+ * @param ring The PF_RING handle on which sampling is applied.
+ * @param rate The sampling rate. Rate of X means that first X packets out of
'filtering_sampling_segment_size' are forwarded. This means that a sampling
rate of 0 disables sampling.
+ * @return 0 on success, a negative value otherwise.
+ */
+int pfring_set_sw_filtering_sampling_rate(pfring *ring, u_int32_t rate /* 0 =
no sampling */);
+
+/**
* Remove hash filtering rules inactive for the specified number of seconds.
* @param ring The PF_RING handle on which the rules will be removed.
* @param inactivity_sec The inactivity threshold.
diff -Naur PF_RING-dev.20170907/userland/lib/pfring_mod.c
PF_RING-dev.20170907.sampling/userland/lib/pfring_mod.c
--- PF_RING-dev.20170907/userland/lib/pfring_mod.c 2017-09-07
13:02:53.000000000 +0300
+++ PF_RING-dev.20170907.sampling/userland/lib/pfring_mod.c 2017-09-07
14:01:59.409271000 +0300
@@ -204,6 +204,7 @@
ring->send = pfring_mod_send;
ring->get_num_rx_channels = pfring_mod_get_num_rx_channels;
ring->set_sampling_rate = pfring_mod_set_sampling_rate;
+ ring->set_sw_filtering_sampling_rate =
pfring_mod_set_sw_filtering_sampling_rate;
ring->get_selectable_fd = pfring_mod_get_selectable_fd;
ring->set_direction = pfring_mod_set_direction;
ring->set_socket_mode = pfring_mod_set_socket_mode;
@@ -417,6 +418,12 @@
return(setsockopt(ring->fd, 0, SO_SET_SAMPLING_RATE, &rate, sizeof(rate)));
}
+/* **************************************************** */
+
+int pfring_mod_set_sw_filtering_sampling_rate(pfring *ring, u_int32_t rate /*
0 = no sampling */) {
+ return(setsockopt(ring->fd, 0, SO_SET_SW_FILTERING_SAMPLING_RATE, &rate,
sizeof(rate)));
+}
+
/* ******************************* */
int pfring_mod_stats(pfring *ring, pfring_stat *stats) {
diff -Naur PF_RING-dev.20170907/userland/lib/pfring_mod.h
PF_RING-dev.20170907.sampling/userland/lib/pfring_mod.h
--- PF_RING-dev.20170907/userland/lib/pfring_mod.h 2017-09-07
13:02:53.000000000 +0300
+++ PF_RING-dev.20170907.sampling/userland/lib/pfring_mod.h 2017-09-07
14:02:24.792303000 +0300
@@ -35,6 +35,7 @@
int pfring_mod_send(pfring *ring, char *pkt, u_int pkt_len, u_int8_t
flush_packet);
u_int8_t pfring_mod_get_num_rx_channels(pfring *ring);
int pfring_mod_set_sampling_rate(pfring *ring, u_int32_t rate);
+int pfring_mod_set_sw_filtering_sampling_rate(pfring *ring, u_int32_t rate);
int pfring_mod_get_selectable_fd(pfring *ring);
int pfring_mod_set_direction(pfring *ring, packet_direction direction);
int pfring_mod_set_socket_mode(pfring *ring, socket_mode mode);
_______________________________________________
Ntop-misc mailing list
[email protected]
http://listgateway.unipi.it/mailman/listinfo/ntop-misc