@@ -210,17 +210,17 @@
/* ********************************** */
-#if 1
-
static rwlock_t ring_mgmt_lock;
-inline void init_ring_readers(void) { ring_mgmt_lock =
+inline void init_ring_readers(void) {
+ ring_mgmt_lock =
#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,39))
- RW_LOCK_UNLOCKED
+ RW_LOCK_UNLOCKED
#else
- __RW_LOCK_UNLOCKED(ring_mgmt_lock)
+ __RW_LOCK_UNLOCKED(ring_mgmt_lock)
#endif
-; }
+ ;
+}
inline void ring_write_lock(void) { write_lock_bh(&ring_mgmt_lock); }
inline void ring_write_unlock(void) { write_unlock_bh(&ring_mgmt_lock); }
/* use ring_read_lock/ring_read_unlock in process context (a bottom half may use write_lock) */
@@ -230,38 +230,6 @@
inline void ring_read_lock_inbh(void) { read_lock(&ring_mgmt_lock); }
inline void ring_read_unlock_inbh(void) { read_unlock(&ring_mgmt_lock); }
-#else
-
-static atomic_t num_ring_readers, ring_stop;
-
-/* Do NOT call schedule() as this might cause crash when exiting */
-
-inline void init_ring_readers(void) {
- atomic_set(&num_ring_readers, 0);
- atomic_set(&ring_stop, 0);
-}
-
-inline void ring_write_lock(void) {
- atomic_set(&ring_stop, 1);
-
- while(atomic_read(&num_ring_readers) > 0) { /* schedule() */; }
-}
-
-inline void ring_write_unlock(void) {
- atomic_set(&ring_stop, 0);
-}
-
-inline void ring_read_lock(void) {
- while(atomic_read(&ring_stop) == 1) { /* schedule() */; }
- atomic_inc(&num_ring_readers);
-}
-
-inline void ring_read_unlock(void) {
- atomic_dec(&num_ring_readers);
-}
-
-#endif
-
/* ********************************** */
/*
@@ -473,7 +441,7 @@
return(((u_int32_t) - 1) + tot_insert - tot_read);
}
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
printk("[PF_RING] -> [tot_insert=%d][tot_read=%d]\n",
tot_insert, tot_read);
}
@@ -572,7 +540,7 @@
skb_queue_purge(&sk->sk_receive_queue);
if(!sock_flag(sk, SOCK_DEAD)) {
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
printk("[PF_RING] Attempt to release alive ring socket: %p\n", sk);
}
return;
@@ -598,7 +566,7 @@
ring_proc_dir,
ring_proc_get_info, pfr);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Added /proc/net/pf_ring/%s\n", pfr->sock_proc_name);
ring_table_size++;
@@ -611,12 +579,12 @@
{
if((ring_proc_dir != NULL)
&& (pfr->sock_proc_name[0] != '\0')) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Removing /proc/net/pf_ring/%s\n", pfr->sock_proc_name);
remove_proc_entry(pfr->sock_proc_name, ring_proc_dir);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Removed /proc/net/pf_ring/%s\n", pfr->sock_proc_name);
pfr->sock_proc_name[0] = '\0';
@@ -663,6 +631,10 @@
rlen = sprintf(buf, "Name: %s\n", dev->name);
rlen += sprintf(buf+rlen, "Index: %d\n", dev->ifindex);
+ rlen += sprintf(buf+rlen, "Address: %02X:%02X:%02X:%02X:%02X:%02X\n",
+ dev->perm_addr[0], dev->perm_addr[1], dev->perm_addr[2],
+ dev->perm_addr[3], dev->perm_addr[4], dev->perm_addr[5]);
+
rlen += sprintf(buf+rlen, "Polling Mode: %s\n", dev_ptr->is_dna_device ? "DNA" : "NAPI/TNAPI");
switch(dev->type) {
@@ -676,7 +648,7 @@
if(!dev_ptr->is_dna_device) {
if(dev->ifindex < MAX_NUM_IFIDX) {
- rlen += sprintf(buf+rlen, "# bound sockets: %d\n",
+ rlen += sprintf(buf+rlen, "# Bound Sockets: %d\n",
num_rings_per_device[dev->ifindex]);
}
}
@@ -704,7 +676,7 @@
if((dev->ethtool_ops == NULL) || (dev->ethtool_ops->set_eeprom == NULL)) return(-1);
- if(enable_debug) printk("[PF_RING] hw_filtering_rule[%s][request=%d][%p]\n",
+ if(unlikely(enable_debug)) printk("[PF_RING] hw_filtering_rule[%s][request=%d][%p]\n",
dev->name, request, dev->ethtool_ops->set_eeprom);
eeprom.len = 1 /* add/remove (no check) */,
@@ -845,7 +817,7 @@
if(copy_from_user(buf, buffer, count)) return(-EFAULT);
buf[sizeof(buf)-1] = '\0', buf[count] = '\0';
- if(enable_debug) printk("[PF_RING] ring_proc_dev_rule_write(%s)\n", buf);
+ if(unlikely(enable_debug)) printk("[PF_RING] ring_proc_dev_rule_write(%s)\n", buf);
num = sscanf(buf, "%c(%d,%d,%d,%c%c%c,%d.%d.%d.%d/%d,%d,%d.%d.%d.%d/%d,%d)",
&add, &rule_id, &queue_id, &vlan,
@@ -853,7 +825,7 @@
&s_a, &s_b, &s_c, &s_d, &s_mask, &s_port,
&d_a, &d_b, &d_c, &d_d, &d_mask, &d_port);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_proc_dev_rule_write(%s): num=%d (1)\n", buf, num);
if(num == 19) {
@@ -878,7 +850,7 @@
&s_a, &s_b, &s_c, &s_d, &s_port,
&d_a, &d_b, &d_c, &d_d, &d_port);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_proc_dev_rule_write(%s): num=%d (2)\n", buf, num);
if(num == 16) {
@@ -977,23 +949,37 @@
rlen += sprintf(buf + rlen, "BPF Filtering : %s\n", pfr->bpfFilter ? "Enabled" : "Disabled");
rlen += sprintf(buf + rlen, "# Sw Filt. Rules : %d\n", pfr->num_sw_filtering_rules);
rlen += sprintf(buf + rlen, "# Hw Filt. Rules : %d\n", pfr->num_hw_filtering_rules);
- rlen += sprintf(buf + rlen, "Cluster Id : %d\n", pfr->cluster_id);
- rlen += sprintf(buf + rlen, "Channel Id : %d\n", pfr->channel_id);
- rlen += sprintf(buf + rlen, "Min Num Slots : %d\n", fsi->min_num_slots);
rlen += sprintf(buf + rlen, "Poll Pkt Watermark : %d\n", pfr->poll_num_pkts_watermark);
- rlen += sprintf(buf + rlen, "Bucket Len : %d\n", fsi->data_len);
- rlen += sprintf(buf + rlen, "Slot Len : %d [bucket+header]\n", fsi->slot_len);
- rlen += sprintf(buf + rlen, "Tot Memory : %d\n", fsi->tot_mem);
rlen += sprintf(buf + rlen, "Num Poll Calls : %u\n", pfr->num_poll_calls);
- rlen += sprintf(buf + rlen, "Tot Packets : %lu\n", (unsigned long)fsi->tot_pkts);
- rlen += sprintf(buf + rlen, "Tot Pkt Lost : %lu\n", (unsigned long)fsi->tot_lost);
- rlen += sprintf(buf + rlen, "Tot Insert : %lu\n", (unsigned long)fsi->tot_insert);
- rlen += sprintf(buf + rlen, "Tot Read : %lu\n", (unsigned long)fsi->tot_read);
- rlen += sprintf(buf + rlen, "Insert Offset : %lu\n", (unsigned long)fsi->insert_off);
- rlen += sprintf(buf + rlen, "Remove Offset : %lu\n", (unsigned long)fsi->remove_off);
- rlen += sprintf(buf + rlen, "Tot Fwd Ok : %lu\n", (unsigned long)fsi->tot_fwd_ok);
- rlen += sprintf(buf + rlen, "Tot Fwd Errors : %lu\n", (unsigned long)fsi->tot_fwd_notok);
- rlen += sprintf(buf + rlen, "Num Free Slots : %u\n", get_num_ring_free_slots(pfr));
+
+ if (pfr->dna_device_entry != NULL) {
+ /* DNA */
+ rlen += sprintf(buf + rlen, "Channel Id : %d\n", pfr->dna_device_entry->dev.channel_id);
+ rlen += sprintf(buf + rlen, "Num Slots : %d\n", pfr->dna_device_entry->dev.mem_info.packet_memory_num_slots);
+ rlen += sprintf(buf + rlen, "Tot Memory : %u bytes\n",
+ pfr->dna_device_entry->dev.mem_info.packet_memory_tot_len *
+ (pfr->dna_device_entry->dev.num_rx_pages + pfr->dna_device_entry->dev.num_tx_pages)
+ +
+ (pfr->dna_device_entry->dev.mem_info.packet_memory_num_slots *
+ pfr->dna_device_entry->dev.mem_info.descr_packet_memory_slot_len));
+ } else {
+ rlen += sprintf(buf + rlen, "Channel Id : %d\n", pfr->channel_id);
+ rlen += sprintf(buf + rlen, "Cluster Id : %d\n", pfr->cluster_id);
+ rlen += sprintf(buf + rlen, "Min Num Slots : %d\n", fsi->min_num_slots);
+ rlen += sprintf(buf + rlen, "Bucket Len : %d\n", fsi->data_len);
+ rlen += sprintf(buf + rlen, "Slot Len : %d [bucket+header]\n", fsi->slot_len);
+ rlen += sprintf(buf + rlen, "Tot Memory : %d\n", fsi->tot_mem);
+ rlen += sprintf(buf + rlen, "Tot Packets : %lu\n", (unsigned long)fsi->tot_pkts);
+ rlen += sprintf(buf + rlen, "Tot Pkt Lost : %lu\n", (unsigned long)fsi->tot_lost);
+ rlen += sprintf(buf + rlen, "Tot Insert : %lu\n", (unsigned long)fsi->tot_insert);
+ rlen += sprintf(buf + rlen, "Tot Read : %lu\n", (unsigned long)fsi->tot_read);
+ rlen += sprintf(buf + rlen, "Insert Offset : %lu\n", (unsigned long)fsi->insert_off);
+ rlen += sprintf(buf + rlen, "Remove Offset : %lu\n", (unsigned long)fsi->remove_off);
+ rlen += sprintf(buf + rlen, "Tot Fwd Ok : %lu\n", (unsigned long)fsi->tot_fwd_ok);
+ rlen += sprintf(buf + rlen, "Tot Fwd Errors : %lu\n", (unsigned long)fsi->tot_fwd_notok);
+ rlen += sprintf(buf + rlen, "Num Free Slots : %u\n", get_num_ring_free_slots(pfr));
+ }
+
} else {
rlen = sprintf(buf, "WARNING ring not active (fsi == NULL)\n");
}
@@ -1075,10 +1061,10 @@
{
if(ring_proc != NULL) {
remove_proc_entry(PROC_INFO, ring_proc_dir);
- if(enable_debug) printk("[PF_RING] removed /proc/net/pf_ring/%s\n", PROC_INFO);
+ if(unlikely(enable_debug)) printk("[PF_RING] removed /proc/net/pf_ring/%s\n", PROC_INFO);
remove_proc_entry(PROC_PLUGINS_INFO, ring_proc_dir);
- if(enable_debug) printk("[PF_RING] removed /proc/net/pf_ring/%s\n", PROC_PLUGINS_INFO);
+ if(unlikely(enable_debug)) printk("[PF_RING] removed /proc/net/pf_ring/%s\n", PROC_PLUGINS_INFO);
remove_proc_entry(PROC_DEV, ring_proc_dir);
@@ -1088,7 +1074,7 @@
init_net.
#endif
proc_net);
- if(enable_debug) printk("[PF_RING] deregistered /proc/net/pf_ring\n");
+ if(unlikely(enable_debug)) printk("[PF_RING] deregistered /proc/net/pf_ring\n");
}
}
}
@@ -1108,7 +1094,7 @@
/* Check if the memory has been already allocated */
if(pfr->ring_memory != NULL) return(0);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_alloc_mem(bucket_len=%d)\n", pfr->bucket_len);
/* **********************************************
@@ -1154,7 +1140,7 @@
pfr->ring_memory = vmalloc_user(tot_mem);
if(pfr->ring_memory != NULL) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] successfully allocated %lu bytes at 0x%08lx\n",
(unsigned long)tot_mem, (unsigned long)pfr->ring_memory);
} else {
@@ -1172,7 +1158,7 @@
pfr->slots_info->tot_mem = tot_mem;
pfr->slots_info->sample_rate = 1;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] allocated %d slots [slot_len=%d][tot_mem=%u]\n",
pfr->slots_info->min_num_slots, pfr->slots_info->slot_len,
pfr->slots_info->tot_mem);
@@ -1197,7 +1183,7 @@
struct ring_element *next;
struct pf_ring_socket *pfr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_insert()\n");
next = kmalloc(sizeof(struct ring_element), GFP_ATOMIC);
@@ -1234,7 +1220,7 @@
struct pf_ring_socket *pfr_to_delete = ring_sk(sk);
u_int8_t master_found = 0, socket_found = 0;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_remove()\n");
list_for_each_safe(ptr, tmp_ptr, &ring_table) {
@@ -1244,12 +1230,12 @@
pfr = ring_sk(entry->sk);
if(pfr->master_ring == pfr_to_delete) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Removing master ring\n");
pfr->master_ring = NULL, master_found = 1;
} else if(entry->sk == sk) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Found socket to remove\n");
list_del(ptr);
@@ -1262,7 +1248,7 @@
if(to_delete) kfree(to_delete);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] leaving ring_remove()\n");
}
@@ -1554,7 +1540,7 @@
inline int hash_bucket_match_rule(sw_filtering_hash_bucket * hash_bucket,
hash_filtering_rule * rule)
{
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] (%u,%d,%d.%d.%d.%d:%u,%d.%d.%d.%d:%u) "
"(%u,%d,%d.%d.%d.%d:%u,%d.%d.%d.%d:%u)\n",
hash_bucket->rule.vlan_id, hash_bucket->rule.proto,
@@ -1600,7 +1586,7 @@
inline int hash_filtering_rule_match(hash_filtering_rule * a,
hash_filtering_rule * b)
{
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] (%u,%d,%d.%d.%d.%d:%u,%d.%d.%d.%d:%u) "
"(%u,%d,%d.%d.%d.%d:%u,%d.%d.%d.%d:%u)\n",
a->vlan_id, a->proto,
@@ -1655,7 +1641,7 @@
{
u_int8_t empty_mac[ETH_ALEN] = { 0 }; /* NULL MAC address */
- if(enable_debug) printk("[PF_RING] match_filtering_rule()\n");
+ if(unlikely(enable_debug)) printk("[PF_RING] match_filtering_rule()\n");
*behaviour = forward_packet_and_stop_rule_evaluation; /* Default */
@@ -1709,7 +1695,7 @@
#ifdef CONFIG_TEXTSEARCH
if(rule->pattern[0] != NULL) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] pattern\n");
if((hdr->extended_hdr.parsed_pkt.offset.payload_offset > 0)
@@ -1722,7 +1708,7 @@
int i;
struct ts_state state;
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
printk("[PF_RING] Trying to match pattern [caplen=%d][len=%d][displ=%d][payload_offset=%d][",
hdr->caplen, payload_len, displ,
hdr->extended_hdr.parsed_pkt.offset.payload_offset);
@@ -1734,11 +1720,11 @@
payload[payload_len] = '\0';
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Attempt to match [%s]\n", payload);
for(i = 0; (i < MAX_NUM_PATTERN) && (rule->pattern[i] != NULL); i++) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Attempt to match pattern %d\n", i);
rc = (textsearch_find_continuous
(rule->pattern[i], &state,
@@ -1747,7 +1733,7 @@
break;
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Match returned: %d [payload_len=%d][%s]\n",
rc, payload_len, payload);
@@ -1768,7 +1754,7 @@
) {
int rc;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] rule->plugin_id [rule_id=%d]"
"[filter_plugin_id=%d][plugin_action=%d][ptr=%p]\n",
rule->rule.rule_id,
@@ -1789,7 +1775,7 @@
hdr->extended_hdr.parsed_pkt.last_matched_plugin_id =
rule->rule.extended_fields.filter_plugin_id;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] [last_matched_plugin = %d][buffer=%p][len=%d]\n",
*last_matched_plugin,
parse_memory_buffer[rule->rule.extended_fields.filter_plugin_id],
@@ -1807,14 +1793,14 @@
) {
int rc;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Calling pfring_plugin_handle_skb(pluginId=%d)\n",
rule->rule.plugin_action.plugin_id);
rc = plugin_registration[rule->rule.plugin_action.plugin_id]
->pfring_plugin_handle_skb(pfr, rule, NULL, hdr, skb, displ,
rule->rule.extended_fields.filter_plugin_id,
- &parse_memory_buffer[rule->rule.extended_fields.filter_plugin_id],
+ &parse_memory_buffer[rule->rule.plugin_action.plugin_id],
behaviour);
if(rc <= 0)
return(0); /* No match */
@@ -1825,17 +1811,17 @@
if(parse_memory_buffer[rule->rule.plugin_action.plugin_id])
*free_parse_mem = 1;
} else {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Skipping pfring_plugin_handle_skb(plugin_action=%d)\n",
rule->rule.plugin_action.plugin_id);
*behaviour = rule->rule.rule_action;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Rule %d behaviour: %d\n",
rule->rule.rule_id, rule->rule.rule_action);
}
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
printk("[PF_RING] MATCH: match_filtering_rule(vlan=%u, proto=%u, sip=%u, sport=%u, dip=%u, dport=%u)\n",
hdr->extended_hdr.parsed_pkt.vlan_id, hdr->extended_hdr.parsed_pkt.l3_proto,
hdr->extended_hdr.parsed_pkt.ipv4_src, hdr->extended_hdr.parsed_pkt.l4_src_port,
@@ -1857,6 +1843,42 @@
/* ********************************** */
+static inline void set_skb_time(struct sk_buff *skb, struct pfring_pkthdr *hdr) {
+ /* BD - API changed for time keeping */
+#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
+ if(skb->stamp.tv_sec == 0)
+ do_gettimeofday(&skb->stamp); /* If timestamp is missing add it */
+ hdr->ts.tv_sec = skb->stamp.tv_sec, hdr->ts.tv_usec = skb->stamp.tv_usec;
+ hdr->extended_hdr.timestamp_ns = 0; /* No nsec for old kernels */
+#elif(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
+ if(skb->tstamp.off_sec == 0)
+ __net_timestamp(skb); /* If timestamp is missing add it */
+ hdr->ts.tv_sec = skb->tstamp.off_sec, hdr->ts.tv_usec = skb->tstamp.off_usec;
+ hdr->extended_hdr.timestamp_ns = 0; /* No nsec for old kernels */
+#else /* 2.6.22 and above */
+ if(skb->tstamp.tv64 == 0)
+ __net_timestamp(skb); /* If timestamp is missing add it */
+
+ hdr->ts = ktime_to_timeval(skb->tstamp);
+
+#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
+ {
+ /* Use hardware timestamps when present. If not, just use software timestamps */
+ hdr->extended_hdr.timestamp_ns = ktime_to_ns(skb_hwtstamps(skb)->hwtstamp);
+
+ if(unlikely(enable_debug))
+ printk("[PF_RING] hwts=%llu/dev=%s\n",
+ hdr->extended_hdr.timestamp_ns,
+ skb->dev ? skb->dev->name : "???");
+ }
+#endif
+ if(hdr->extended_hdr.timestamp_ns == 0)
+ hdr->extended_hdr.timestamp_ns = ktime_to_ns(skb->tstamp);
+#endif
+}
+
+/* ********************************** */
+
/*
Generic function for copying either a skb or a raw
memory block to the ring buffer
@@ -1880,6 +1902,9 @@
/* We need to lock as two ksoftirqd might put data onto the same ring */
+ if(hdr->ts.tv_sec == 0)
+ set_skb_time(skb, hdr);
+
if(do_lock) write_lock(&pfr->ring_index_lock);
// smp_rmb();
@@ -1890,7 +1915,7 @@
/* No room left */
pfr->slots_info->tot_lost++;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ==> slot(off=%d) is full [insert_off=%u][remove_off=%u][slot_len=%u][num_queued_pkts=%u]\n",
off, pfr->slots_info->insert_off, pfr->slots_info->remove_off, pfr->slots_info->slot_len, num_queued_pkts(pfr));
@@ -1909,7 +1934,7 @@
}
if(hdr->caplen > 0) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> [caplen=%d][len=%d][displ=%d][extended_hdr.parsed_header_len=%d][bucket_len=%d][sizeof=%d]\n",
hdr->caplen, hdr->len, displ, hdr->extended_hdr.parsed_header_len, pfr->bucket_len,
pfr->slot_header_len);
@@ -1938,7 +1963,7 @@
pfr->slots_info->insert_off = get_next_slot_offset(pfr, off, &taken);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ==> insert_off=%d\n", pfr->slots_info->insert_off);
/*
@@ -1982,7 +2007,7 @@
struct pf_ring_socket *pfr = (_pfr->master_ring != NULL) ? _pfr->master_ring : _pfr;
u_int32_t the_bit = 1 << channel_id;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> add_pkt_to_ring(len=%d) [pfr->channel_id=%d][channel_id=%d]\n",
hdr->len, pfr->channel_id, channel_id);
@@ -2070,7 +2095,7 @@
int displ,
rule_action_behaviour behaviour)
{
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] reflect_packet called\n");
if((reflector_dev != NULL)
@@ -2219,7 +2244,7 @@
{
struct list_head *ptr, *tmp_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Entered check_wildcard_rules()\n");
list_for_each_safe(ptr, tmp_ptr, &pfr->sw_filtering_rules) {
@@ -2231,7 +2256,7 @@
if(match_filtering_rule(pfr, entry, hdr, skb, displ,
parse_memory_buffer, free_parse_mem,
last_matched_plugin, &behaviour)) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] behaviour=%d\n", behaviour);
hdr->extended_hdr.parsed_pkt.last_matched_rule_id = entry->rule.rule_id;
@@ -2253,7 +2278,7 @@
&& plugin_registration[*last_matched_plugin] != NULL
&& plugin_registration[*last_matched_plugin]->pfring_plugin_add_rule != NULL
&& (plugin_registration[*last_matched_plugin]->pfring_plugin_add_rule(entry, hdr, hash_bucket) == 0) ) {
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
printk("pfring_plugin_add_rule(entry, hdr, hash_bucket) done!\n");
}
} else {
@@ -2283,7 +2308,7 @@
write_unlock(&pfr->ring_rules_lock);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Added rule: [%d.%d.%d.%d:%d <-> %d.%d.%d.%d:%d][tot_rules=%d]\n",
((hash_bucket->rule.host4_peer_a >> 24) & 0xff), ((hash_bucket->rule.host4_peer_a >> 16) & 0xff),
((hash_bucket->rule.host4_peer_a >> 8) & 0xff), ((hash_bucket->rule.host4_peer_a >> 0) & 0xff),
@@ -2370,7 +2395,7 @@
if(res == 0) {
/* Filter failed */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] add_skb_to_ring(skb): Filter failed [len=%d][tot=%llu]"
"[insert_off=%d][pkt_type=%d][cloned=%d]\n",
(int)skb->len, pfr->slots_info->tot_pkts,
@@ -2419,26 +2444,14 @@
that will then be freed when the packet has been handled
*/
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> add_skb_to_ring(len=%d) [channel_id=%d/%d][active=%d][%s]\n",
hdr->len, channel_id, num_rx_channels,
pfr->ring_active, pfr->ring_netdev->dev->name);
- {
- static int once = 0;
-
- while(once < 25) {
- printk("[PF_RING] add_skb_to_ring on device index %d [active=%d]\n",
- skb->dev->ifindex, pfr->ring_active);
- once++;
- }
- }
-
if((!pfring_enabled) || ((!pfr->ring_active) && (pfr->master_ring == NULL)))
return(-1);
-
-
pfr->num_rx_channels = num_rx_channels; /* Constantly updated */
hdr->extended_hdr.parsed_pkt.last_matched_rule_id = (u_int16_t)-1;
@@ -2452,7 +2465,7 @@
}
}
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
printk("[PF_RING] add_skb_to_ring: [%s][displ=%d][len=%d][caplen=%d]"
"[is_ip_pkt=%d][%d -> %d][%p/%p]\n",
(skb->dev->name != NULL) ? skb->dev->name : "<NULL>",
@@ -2475,7 +2488,7 @@
hash_found = check_perfect_rules(skb, pfr, hdr, &fwd_pkt, &free_parse_mem,
parse_memory_buffer, displ, &last_matched_plugin);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] check_perfect_rules() returned %d\n", hash_found);
/* [2.2] Search rules list */
@@ -2484,13 +2497,13 @@
parse_memory_buffer, displ, &last_matched_plugin) != 0)
fwd_pkt = 0;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] check_wildcard_rules() completed: fwd_pkt=%d\n", fwd_pkt);
}
if(fwd_pkt) {
/* We accept the packet: it needs to be queued */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Forwarding packet to userland\n");
/* [3] Packet sampling */
@@ -2503,7 +2516,7 @@
} else {
pfr->pktToSample--;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] add_skb_to_ring(skb): sampled packet [len=%d]"
"[tot=%llu][insert_off=%d][pkt_type=%d][cloned=%d]\n",
(int)skb->len, pfr->slots_info->tot_pkts,
@@ -2533,7 +2546,7 @@
hdr->extended_hdr.parsed_pkt.last_matched_plugin_id = last_matched_plugin;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> [last_matched_plugin = %d][extended_hdr.parsed_header_len=%d]\n",
last_matched_plugin, hdr->extended_hdr.parsed_header_len);
@@ -2548,7 +2561,7 @@
}
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] [pfr->slots_info->insert_off=%d]\n",
pfr->slots_info->insert_off);
@@ -2584,7 +2597,7 @@
if(reg == NULL)
return(-1);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> register_plugin(%d)\n", reg->plugin_id);
if((reg->plugin_id >= MAX_PLUGIN_ID) || (reg->plugin_id == 0))
@@ -2791,42 +2804,6 @@
/* ********************************** */
-static inline void set_skb_time(struct sk_buff *skb, struct pfring_pkthdr *hdr) {
- /* BD - API changed for time keeping */
-#if(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
- if(skb->stamp.tv_sec == 0)
- do_gettimeofday(&skb->stamp); /* If timestamp is missing add it */
- hdr->ts.tv_sec = skb->stamp.tv_sec, hdr->ts.tv_usec = skb->stamp.tv_usec;
- hdr->extended_hdr.timestamp_ns = 0; /* No nsec for old kernels */
-#elif(LINUX_VERSION_CODE < KERNEL_VERSION(2,6,22))
- if(skb->tstamp.off_sec == 0)
- __net_timestamp(skb); /* If timestamp is missing add it */
- hdr->ts.tv_sec = skb->tstamp.off_sec, hdr->ts.tv_usec = skb->tstamp.off_usec;
- hdr->extended_hdr.timestamp_ns = 0; /* No nsec for old kernels */
-#else /* 2.6.22 and above */
- if(skb->tstamp.tv64 == 0)
- __net_timestamp(skb); /* If timestamp is missing add it */
-
- hdr->ts = ktime_to_timeval(skb->tstamp);
-
-#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,30))
- {
- /* Use hardware timestamps when present. If not, just use software timestamps */
- hdr->extended_hdr.timestamp_ns = ktime_to_ns(skb_hwtstamps(skb)->hwtstamp);
-
- if(enable_debug)
- printk("[PF_RING] hwts=%llu/dev=%s\n",
- hdr->extended_hdr.timestamp_ns,
- skb->dev ? skb->dev->name : "???");
- }
-#endif
- if(hdr->extended_hdr.timestamp_ns == 0)
- hdr->extended_hdr.timestamp_ns = ktime_to_ns(skb->tstamp);
-#endif
-}
-
-/* ********************************** */
-
/*
PF_RING main entry point
@@ -2838,14 +2815,14 @@
*/
static int skb_ring_handler(struct sk_buff *skb,
- u_char recv_packet,
- u_char real_skb /* 1=real skb, 0=faked skb */ ,
+ u_int8_t recv_packet,
+ u_int8_t real_skb /* 1=real skb, 0=faked skb */ ,
u_int32_t channel_id,
u_int32_t num_rx_channels)
{
struct sock *skElement;
int rc = 0, is_ip_pkt = 0, room_available = 0;
- struct list_head *ptr;
+ struct list_head *ptr, *tmp_ptr;
struct pfring_pkthdr hdr;
int displ;
int defragmented_skb = 0;
@@ -2867,21 +2844,12 @@
} else
displ = 0;
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
if(skb->dev && (skb->dev->ifindex < MAX_NUM_IFIDX))
printk("[PF_RING] --> skb_ring_handler(%s): %d rings [num_any_rings=%d]\n",
skb->dev->name, num_rings_per_device[skb->dev->ifindex], num_any_rings);
}
- if(skb->dev->ifindex != 10) {
- static int once = 0;
-
- while(once < 25) {
- printk("[PF_RING] Received pkt on device index %d\n", skb->dev->ifindex);
- once++;
- }
- }
-
if((num_any_rings == 0)
&& (skb->dev
&& (skb->dev->ifindex < MAX_NUM_IFIDX)
@@ -2908,7 +2876,7 @@
return(0);
}
- if(enable_debug) {
+ if(unlikely(enable_debug)) {
struct timeval tv;
skb_get_timestamp(skb, &tv);
@@ -2924,9 +2892,12 @@
memset(&hdr, 0, sizeof(hdr));
- set_skb_time(skb, &hdr);
-
- hdr.len = hdr.caplen = skb->len + displ;
+ hdr.ts.tv_sec = 0;
+ /*
+ The min() below is not really necessary but we have observed that sometimes
+ skb->len > MTU thus it's better to be on the safe side
+ */
+ hdr.len = hdr.caplen = min(skb->len + displ, skb->dev->mtu);
if(quick_mode) {
struct pf_ring_socket *pfr = device_rings[skb->dev->ifindex][channel_id];
@@ -2939,14 +2910,14 @@
channel_id = hash_pkt_header(&hdr, 0, 0) % get_num_rx_queues(skb->dev);
}
- if(enable_debug) printk("[PF_RING] Expecting channel %d [%p]\n", channel_id, pfr);
+ if(unlikely(enable_debug)) printk("[PF_RING] Expecting channel %d [%p]\n", channel_id, pfr);
if((pfr != NULL)
&& is_valid_skb_direction(pfr->direction, recv_packet)
) {
/* printk("==>>> [%d][%d]\n", skb->dev->ifindex, channel_id); */
- rc = 1, hdr.len = skb->len, hdr.caplen = min_val(hdr.caplen, pfr->bucket_len);
+ rc = 1, hdr.caplen = min_val(hdr.caplen, pfr->bucket_len);
room_available |= copy_data_to_ring(skb, pfr, &hdr, displ, 0, NULL, NULL, 0);
}
} else {
@@ -2968,12 +2939,13 @@
else
hdr.extended_hdr.if_index = UNKNOWN_INTERFACE;
+ hdr.extended_hdr.rx_direction = recv_packet;
/* Avoid the ring to be manipulated while playing with it */
ring_read_lock();
/* [1] Check unclustered sockets */
- list_for_each(ptr, &ring_table) {
+ list_for_each_safe(ptr, tmp_ptr, &ring_table) {
struct pf_ring_socket *pfr;
struct ring_element *entry;
@@ -3043,6 +3015,11 @@
displ, channel_id, num_rx_channels);
rc = 1; /* Ring found: we've done our job */
break;
+
+ } else if((cluster_ptr->cluster.hashing_mode != cluster_round_robin)
+ /* We're the last element of the cluster so no further cluster element to check */
+ || ((num_iterations + 1) > cluster_ptr->cluster.num_cluster_elements)) {
+ pfr->slots_info->tot_pkts++, pfr->slots_info->tot_lost++;
}
}
}
@@ -3072,7 +3049,7 @@
rc = 0;
else {
if(recv_packet && real_skb) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] kfree_skb()\n");
kfree_skb(orig_skb); /* Free memory */
@@ -3084,7 +3061,7 @@
rdt2 = _rdtsc() - rdt2;
rdt = _rdtsc() - rdt;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] # cycles: %d [lock costed %d %d%%][free costed %d %d%%]\n",
(int)rdt, rdt - rdt1,
(int)((float)((rdt - rdt1) * 100) / (float)rdt), rdt2,
@@ -3105,7 +3082,7 @@
static int buffer_ring_handler(struct net_device *dev, char *data, int len)
{
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] buffer_ring_handler: [dev=%s][len=%d]\n",
dev->name == NULL ? "<NULL>" : dev->name, len);
@@ -3179,7 +3156,7 @@
% DEFAULT_RING_HASH_SIZE;
int rc = -1;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket(vlan=%u, proto=%u, "
"sip=%d.%d.%d.%d, sport=%u, dip=%d.%d.%d.%d, dport=%u, "
"hash_value=%u, add_rule=%d) called\n", rule->rule.vlan_id,
@@ -3200,13 +3177,13 @@
kcalloc(DEFAULT_RING_HASH_SIZE, sizeof(sw_filtering_hash_bucket *), GFP_ATOMIC);
if(pfr->sw_filtering_hash == NULL) {
/* kfree(rule); */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket() returned %d [0]\n", -EFAULT);
return(-EFAULT);
}
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket() allocated memory\n");
if(pfr->sw_filtering_hash == NULL) {
@@ -3218,7 +3195,7 @@
if(add_rule)
pfr->sw_filtering_hash[hash_value] = rule, rule->next = NULL, rc = 0;
else {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket() returned %d [1]\n", -1);
return(-1); /* Unable to find the specified rule */
}
@@ -3228,14 +3205,14 @@
while(bucket != NULL) {
if(hash_filtering_rule_match(&bucket->rule, &rule->rule)) {
if(add_rule) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Duplicate found while adding rule: discarded\n");
/* kfree(rule); */
return(-EEXIST);
} else {
/* We've found the bucket to delete */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket()"
" found a bucket to delete: removing it\n");
if(prev == NULL)
@@ -3245,7 +3222,7 @@
free_sw_filtering_hash_bucket(bucket);
kfree(bucket);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket() returned %d [2]\n", 0);
return(0);
}
@@ -3258,7 +3235,7 @@
if(add_rule) {
/* If the flow arrived until here, then this rule is unique */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket() "
"no duplicate rule found: adding the rule\n");
@@ -3275,7 +3252,7 @@
}
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] handle_sw_filtering_hash_bucket() returned %d [3]\n",
rc);
@@ -3333,7 +3310,7 @@
struct net *net,
#endif
struct socket *sock, int protocol
-#if(LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33))
+#if((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)) || ((LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)) && defined(REDHAT_PATCHED_KERNEL)))
, int kern
#endif
)
@@ -3342,7 +3319,7 @@
struct pf_ring_socket *pfr;
int err = -ENOMEM;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_create()\n");
/* Are you root, superuser or so ? */
@@ -3410,7 +3387,7 @@
ring_proc_add(pfr);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_create(): created\n");
return(0);
@@ -3450,7 +3427,7 @@
virtual_filtering_device_element *elem;
struct list_head *ptr, *tmp_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> add_virtual_filtering_device(%s)\n", info->device_name);
if(info == NULL)
@@ -3495,7 +3472,7 @@
{
struct list_head *ptr, *tmp_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> remove_virtual_filtering_device(%s)\n", device_name);
write_lock(&virtual_filtering_lock);
@@ -3546,7 +3523,7 @@
schedule();
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] called ring_release(%s)\n", pfr->ring_netdev->dev->name);
if(pfr->kernel_consumer_options) kfree(pfr->kernel_consumer_options);
@@ -3611,7 +3588,7 @@
/* Custom free function */
plugin_registration[rule->rule.plugin_action.plugin_id]->pfring_plugin_free_ring_mem(rule);
} else {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> default_free [rule->rule.plugin_action.plugin_id=%d]\n",
rule->rule.plugin_action.plugin_id);
if(rule->plugin_data_ptr != NULL) {
@@ -3703,7 +3680,7 @@
kfree(pfr);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_release: done\n");
return 0;
@@ -3740,7 +3717,7 @@
/* printk("[PF_RING] DeviceId: %u\n", dev->dev->ifindex); */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] packet_ring_bind(%s, bucket_len=%d) called\n",
dev->dev->name, pfr->bucket_len);
@@ -3791,7 +3768,7 @@
{
struct sock *sk = sock->sk;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_bind() called\n");
/*
@@ -3807,7 +3784,7 @@
/* Safety check: add trailing zero if missing */
sa->sa_data[sizeof(sa->sa_data) - 1] = '\0';
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] searching device %s\n", sa->sa_data);
#if 0
@@ -3820,7 +3797,7 @@
#endif
sa->sa_data)) == NULL) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] search failed\n");
return(-EINVAL);
}
@@ -3859,7 +3836,7 @@
start = vma->vm_start;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] do_memory_mmap(mode=%d, size=%lu, ptr=%p)\n", mode, size, ptr);
while(size > 0) {
@@ -3879,7 +3856,7 @@
}
if(rc) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] remap_pfn_range() failed\n");
return(-EAGAIN);
@@ -3908,7 +3885,7 @@
unsigned long mem_id = 0;
unsigned long size = (unsigned long)(vma->vm_end - vma->vm_start);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_mmap() called\n");
if(ring_alloc_mem(sk) != 0) {
@@ -3917,13 +3894,13 @@
}
if(size % PAGE_SIZE) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_mmap() failed: len is not multiple of PAGE_SIZE\n");
return(-EINVAL);
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_mmap() called, size: %ld bytes [bucket_len=%d]\n",
size, pfr->bucket_len);
@@ -3933,27 +3910,48 @@
if( (mem_id == 0 && pfr->ring_memory == NULL) ||
(mem_id > 0 && pfr->dna_device == NULL)) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_mmap() failed: "
"mapping area to an unbound socket\n");
return -EINVAL;
}
+ /* Tricks for DNA */
+ if((mem_id >= 100) && (mem_id < 1124)) {
+ /* DNA; RX packet memory */
+
+ mem_id -= 100;
+ if(mem_id >= MAX_NUM_DNA_PAGES) return -EINVAL;
+
+ if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->rx_packet_memory[mem_id], VM_LOCKED, 1)) < 0)
+ return(rc);
+
+ return(0);
+ } else if((mem_id >= 1124) && (mem_id < 2148)) {
+ mem_id -= 1124;
+ if(mem_id >= MAX_NUM_DNA_PAGES) return -EINVAL;
+
+ /* DNA: TX packet memory */
+ if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->tx_packet_memory[mem_id], VM_LOCKED, 1)) < 0)
+ return(rc);
+
+ return(0);
+ }
+
switch(mem_id) {
/* RING */
case 0:
-
- /* if userspace tries to mmap beyond end of our buffer, fail */
+ /* If userspace tries to mmap beyond end of our buffer, then fail */
if(size > pfr->slots_info->tot_mem) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_mmap() failed: "
"area too large [%ld > %d]\n",
size, pfr->slots_info->tot_mem);
return(-EINVAL);
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] mmap [slot_len=%d]"
"[tot_slots=%d] for ring on device %s\n",
pfr->slots_info->slot_len, pfr->slots_info->min_num_slots,
@@ -3963,31 +3961,18 @@
return(rc);
break;
- /* DNA Device */
case 1:
- /* DNA: RX packet memory */
- if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->rx_packet_memory, VM_LOCKED, 1)) < 0)
- return(rc);
- break;
-
- case 2:
/* DNA: RX packet descriptors */
if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->rx_descr_packet_memory, VM_LOCKED, 1)) < 0)
return(rc);
break;
- case 3:
+ case 2:
if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->phys_card_memory, (VM_RESERVED | VM_IO), 2)) < 0)
return(rc);
break;
- case 4:
- /* DNA: TX packet memory */
- if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->tx_packet_memory, VM_LOCKED, 1)) < 0)
- return(rc);
- break;
-
- case 5:
+ case 3:
/* DNA: TX packet descriptors */
if((rc = do_memory_mmap(vma, size, (void *)pfr->dna_device->tx_descr_packet_memory, VM_LOCKED, 1)) < 0)
return(rc);
@@ -3997,7 +3982,7 @@
return(-EAGAIN);
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_mmap succeeded\n");
return 0;
@@ -4011,7 +3996,7 @@
struct pf_ring_socket *pfr = ring_sk(sock->sk);
u_int32_t queued_pkts, num_loops = 0;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_recvmsg called\n");
pfr->ring_active = 1;
@@ -4019,7 +4004,7 @@
while((queued_pkts = num_queued_pkts(pfr)) < MIN_QUEUED_PKTS) {
wait_event_interruptible(pfr->ring_slots_waitqueue, 1);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] -> ring_recvmsg "
"[queued_pkts=%d][num_loops=%d]\n",
queued_pkts, num_loops);
@@ -4157,7 +4142,7 @@
struct pf_ring_socket *pfr = ring_sk(sock->sk);
int rc, mask = 0;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] -- poll called\n");
pfr->num_poll_calls++;
@@ -4165,7 +4150,7 @@
if(pfr->dna_device == NULL) {
/* PF_RING mode (No DNA) */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] poll called (non DNA device)\n");
pfr->ring_active = 1;
@@ -4184,12 +4169,12 @@
/* DNA mode */
/* enable_debug = 1; */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] poll called on DNA device [%d]\n",
*pfr->dna_device->interrupt_received);
if(pfr->dna_device->wait_packet_function_ptr == NULL) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] wait_packet_function_ptr is NULL: returning to caller\n");
return(0);
@@ -4197,25 +4182,25 @@
rc = pfr->dna_device->wait_packet_function_ptr(pfr->dna_device->adapter_ptr, 1);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] wait_packet_function_ptr(1) returned %d\n", rc);
if(rc == 0) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] calling poll_wait()\n");
/* No packet arrived yet */
poll_wait(file, pfr->dna_device->packet_waitqueue, wait);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] poll_wait() just returned\n");
} else
rc = pfr->dna_device->wait_packet_function_ptr(pfr->dna_device->adapter_ptr, 0);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] wait_packet_function_ptr(0) returned %d\n", rc);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] poll %s return [%d]\n",
pfr->ring_netdev->dev->name,
*pfr->dna_device->interrupt_received);
@@ -4274,7 +4259,7 @@
{
struct list_head *ptr, *tmp_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> remove_from_cluster(%d)\n", pfr->cluster_id);
if(pfr->cluster_id == 0 /* 0 = No Cluster */ )
@@ -4300,9 +4285,9 @@
u_int32_t master_socket_id)
{
int rc = -1;
- struct list_head *ptr;
+ struct list_head *ptr, *tmp_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] set_master_ring(%s=%d)\n",
pfr->ring_netdev->dev ? pfr->ring_netdev->dev->name : "none",
master_socket_id);
@@ -4310,7 +4295,7 @@
/* Avoid the ring to be manipulated while playing with it */
ring_read_lock();
- list_for_each(ptr, &ring_table) {
+ list_for_each_safe(ptr, tmp_ptr, &ring_table) {
struct pf_ring_socket *sk_pfr;
struct ring_element *entry;
struct sock *skElement;
@@ -4323,7 +4308,7 @@
if((sk_pfr != NULL) && (sk_pfr->ring_id == master_socket_id)) {
pfr->master_ring = sk_pfr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Found set_master_ring(%s) -> %s\n",
sk_pfr->ring_netdev->dev ? sk_pfr->ring_netdev->dev->name : "none",
pfr->master_ring->ring_netdev->dev->name);
@@ -4331,7 +4316,7 @@
rc = 0;
break;
} else {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Skipping socket(%s)=%d\n",
sk_pfr->ring_netdev->dev ? sk_pfr->ring_netdev->dev->name : "none",
sk_pfr->ring_id);
@@ -4340,7 +4325,7 @@
ring_read_unlock();
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] set_master_ring(%s, socket_id=%d) = %d\n",
pfr->ring_netdev->dev ? pfr->ring_netdev->dev->name : "none",
master_socket_id, rc);
@@ -4357,7 +4342,7 @@
struct list_head *ptr, *tmp_ptr;
ring_cluster_element *cluster_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> add_sock_to_cluster(%d)\n", cluster->clusterId);
if(cluster->clusterId == 0 /* 0 = No Cluster */ )
@@ -4399,9 +4384,8 @@
dna_device_mapping *mapping)
{
struct list_head *ptr, *tmp_ptr;
- dna_device_list *entry;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_map_dna_device(%s@%d): %s\n",
mapping->device_name,
mapping->channel_id,
@@ -4412,63 +4396,80 @@
u8 found = 0;
list_for_each_safe(ptr, tmp_ptr, &ring_dna_devices_list) {
- entry = list_entry(ptr, dna_device_list, list);
+ dna_device_list *entry = list_entry(ptr, dna_device_list, list);
if((!strcmp(entry->dev.netdev->name, mapping->device_name))
&& (entry->dev.channel_id == mapping->channel_id)
- && entry->in_use) {
- if(entry->sock_a == pfr) entry->sock_a = NULL;
- else if(entry->sock_b == pfr) entry->sock_b = NULL;
- else if(entry->sock_c == pfr) entry->sock_c = NULL;
- else {
- printk("[PF_RING] ring_map_dna_device(%s, %u): something got wrong 1\n",
- mapping->device_name, mapping->channel_id);
+ && entry->num_bound_sockets) {
+ int i;
+
+ for(i=0; i<MAX_NUM_DNA_BOUND_SOCKETS; i++)
+ if(entry->bound_sockets[i] == pfr) {
+ entry->bound_sockets[i] = NULL;
+ found = 1;
+ break;
+ }
+
+ if(!found) {
+ if(unlikely(enable_debug))
+ printk("[PF_RING] ring_map_dna_device(remove_device_mapping, %s, %u): something got wrong\n",
+ mapping->device_name, mapping->channel_id);
return(-1); /* Something got wrong */
}
+
+ entry->num_bound_sockets--;
- entry->in_use--, found = 1;
- break;
+ if(pfr->dna_device != NULL) {
+ if(unlikely(enable_debug))
+ printk("[PF_RING] ring_map_dna_device(%s): removed mapping [num_bound_sockets=%u]\n",
+ mapping->device_name, entry->num_bound_sockets);
+ pfr->dna_device->usage_notification(pfr->dna_device->adapter_ptr, 0 /* unlock */);
+ // pfr->dna_device = NULL;
+ }
+ /* Continue for all devices: no break */
}
}
- if(pfr->dna_device != NULL)
- pfr->dna_device->usage_notification(pfr->dna_device->adapter_ptr, 0 /* unlock */);
-
- pfr->dna_device = NULL;
- if(enable_debug)
- printk("[PF_RING] ring_map_dna_device(%s): removed mapping\n",
- mapping->device_name);
+ if(unlikely(enable_debug))
+ printk("[PF_RING] ring_map_dna_device(%s): removed mapping\n", mapping->device_name);
- if(!found) return(-1); else return(0);
+ return(0);
} else {
ring_proc_remove(pfr);
list_for_each_safe(ptr, tmp_ptr, &ring_dna_devices_list) {
- entry = list_entry(ptr, dna_device_list, list);
+ dna_device_list *entry = list_entry(ptr, dna_device_list, list);
if((!strcmp(entry->dev.netdev->name, mapping->device_name))
&& (entry->dev.channel_id == mapping->channel_id)) {
+ int i, found = 0;
- if(enable_debug)
- printk("[PF_RING] ==>> %s@%d [in_use=%d][%p]\n",
- entry->dev.netdev->name,
- mapping->channel_id,
- entry->in_use, entry);
-
- if(entry->sock_a == NULL) entry->sock_a = pfr;
- else if(entry->sock_b == NULL) entry->sock_b = pfr;
- else if(entry->sock_c == NULL) entry->sock_c = pfr;
- else {
- printk("[PF_RING] ring_map_dna_device(%s, %u, %s): something got wrong (too many DNA devices open)\n",
- mapping->device_name, mapping->channel_id, direction2string(pfr->direction));
+ if(unlikely(enable_debug))
+ printk("[PF_RING] ==>> %s@%d [num_bound_sockets=%d][%p]\n",
+ entry->dev.netdev->name, mapping->channel_id,
+ entry->num_bound_sockets, entry);
+
+ for(i=0; i<MAX_NUM_DNA_BOUND_SOCKETS; i++)
+ if(entry->bound_sockets[i] == NULL) {
+ entry->bound_sockets[i] = pfr;
+ found = 1;
+ break;
+ }
+
+ if(!found) {
+ if(unlikely(enable_debug))
+ printk("[PF_RING] ring_map_dna_device(add_device_mapping, %s, %u, %s): "
+ "something got wrong (too many DNA devices open)\n",
+ mapping->device_name, mapping->channel_id, direction2string(pfr->direction));
+
return(-1); /* Something got wrong: too many mappings */
}
- entry->in_use++, pfr->dna_device_entry = entry;
+ entry->num_bound_sockets++, pfr->dna_device_entry = entry;
pfr->dna_device = &entry->dev, pfr->ring_netdev->dev = entry->dev.netdev /* Default */;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_map_dna_device(%s, %u): added mapping\n",
mapping->device_name, mapping->channel_id);
@@ -4477,7 +4478,7 @@
ring_device_element *dev_ptr = list_entry(ptr, ring_device_element, device_list);
if(!strcmp(dev_ptr->dev->name, mapping->device_name)) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ==>> %s [%p]\n", dev_ptr->dev->name, dev_ptr);
pfr->ring_netdev = dev_ptr;
break;
@@ -4485,14 +4486,18 @@
}
/* Lock driver */
+ if(unlikely(enable_debug))
+ printk("[PF_RING] ===> ring_map_dna_device(%s): added mapping [num_bound_sockets=%u]\n",
+ mapping->device_name, entry->num_bound_sockets);
pfr->dna_device->usage_notification(pfr->dna_device->adapter_ptr, 1 /* lock */);
+
ring_proc_add(pfr);
return(0);
}
}
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ring_map_dna_device(%s, %u): mapping failed or not a dna device\n",
mapping->device_name, mapping->channel_id);
@@ -4508,7 +4513,7 @@
unsigned long expire_jiffies =
jiffies - msecs_to_jiffies(1000 * rule_inactivity);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] purge_idle_hash_rules(rule_inactivity=%d)\n",
rule_inactivity);
@@ -4524,7 +4529,7 @@
if(scan->rule.internals.jiffies_last_match < expire_jiffies) {
/* Expired rule: free it */
- if(enable_debug)
+ if(unlikely(enable_debug))
printk ("[PF_RING] Purging hash rule "
/* "[last_match=%u][expire_jiffies=%u]" */
"[%d.%d.%d.%d:%d <-> %d.%d.%d.%d:%d][purged=%d][tot_rules=%d]\n",
@@ -4565,7 +4570,7 @@
}
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Purged %d hash rules [tot_rules=%d]\n",
num_purged_rules, pfr->num_sw_filtering_rules);
}
@@ -4598,7 +4603,7 @@
kfree(entry->plugin_data_ptr);
free_filtering_rule(&entry->rule);
kfree(entry);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_REMOVE_FILTERING_RULE: rule %d has been removed\n", rule_id);
rule_found = 1;
break;
@@ -4629,7 +4634,7 @@
ret = -EFAULT;
if(ret != 0) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Invalid filtering plugin [id=%d]\n",
rule->rule.extended_fields.filter_plugin_id);
kfree(rule);
@@ -4646,7 +4651,7 @@
ret = -EFAULT;
if(ret != 0) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Invalid action plugin [id=%d]\n",
rule->rule.plugin_action.plugin_id);
kfree(rule);
@@ -4657,7 +4662,7 @@
if(rule->rule.reflector_device_name[0] != '\0') {
if((pfr->ring_netdev->dev != NULL)
&& (strcmp(rule->rule.reflector_device_name, pfr->ring_netdev->dev->name) == 0)) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] You cannot use as reflection device the same device on which this ring is bound\n");
kfree(rule);
return(-EFAULT);
@@ -4713,7 +4718,7 @@
#endif
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_ADD_FILTERING_RULE: About to add rule %d\n",
rule->rule.rule_id);
@@ -4721,7 +4726,7 @@
list_for_each_safe(ptr, tmp_ptr, &pfr->sw_filtering_rules) {
entry = list_entry(ptr, sw_filtering_rule_element, list);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_ADD_FILTERING_RULE: [current rule %d][rule to add %d]\n",
entry->rule.rule_id,
rule->rule.rule_id);
@@ -4730,13 +4735,13 @@
if(prev == NULL) {
list_add(&rule->list, &pfr->sw_filtering_rules); /* Add as first entry */
pfr->num_sw_filtering_rules++;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_ADD_FILTERING_RULE: added rule %d as head rule\n",
rule->rule.rule_id);
} else {
list_add(&rule->list, prev);
pfr->num_sw_filtering_rules++;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_ADD_FILTERING_RULE: added rule %d\n",
rule->rule.rule_id);
}
@@ -4751,13 +4756,13 @@
if(prev == NULL) {
list_add(&rule->list, &pfr->sw_filtering_rules); /* Add as first entry */
pfr->num_sw_filtering_rules++;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_ADD_FILTERING_RULE: added rule %d as first rule\n",
rule->rule.rule_id);
} else {
list_add_tail(&rule->list, &pfr->sw_filtering_rules); /* Add as first entry */
pfr->num_sw_filtering_rules++;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_ADD_FILTERING_RULE: added rule %d as last rule\n",
rule->rule.rule_id);
}
@@ -4784,7 +4789,7 @@
if(rule->rule.reflector_device_name[0] != '\0') {
if((pfr->ring_netdev->dev != NULL)
&& (strcmp(rule->rule.reflector_device_name, pfr->ring_netdev->dev->name) == 0)) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] You cannot use as reflection device the same device on "
"which this ring is bound\n");
kfree(rule);
@@ -4858,7 +4863,7 @@
case SO_ATTACH_FILTER:
ret = -EINVAL;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] BPF filter (%d)\n", 0);
if(optlen == sizeof(struct sock_fprog)) {
@@ -4868,7 +4873,7 @@
ret = -EFAULT;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] BPF filter (%d)\n", 1);
/*
@@ -4909,7 +4914,7 @@
write_unlock(&pfr->ring_rules_lock);
ret = 0;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] BPF filter attached successfully [len=%d]\n",
filter->len);
}
@@ -4975,7 +4980,7 @@
u_int32_t the_bit = 1 << i;
if((channel_id & the_bit) == the_bit) {
- if(enable_debug) printk("[PF_RING] Setting channel %d\n", i);
+ if(unlikely(enable_debug)) printk("[PF_RING] Setting channel %d\n", i);
device_rings[pfr->ring_netdev->dev->ifindex][i] = pfr;
pfr->num_channels_per_ring++;
@@ -4984,7 +4989,7 @@
}
pfr->channel_id = channel_id;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] [pfr->channel_id=%d][channel_id=%d]\n",
pfr->channel_id, channel_id);
@@ -5018,7 +5023,7 @@
return -EFAULT;
pfr->direction = direction;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_SET_PACKET_DIRECTION [pfr->direction=%s][direction=%s]\n",
direction2string(pfr->direction), direction2string(direction));
@@ -5054,7 +5059,7 @@
pfr->sw_filtering_rules_default_accept_policy = new_policy;
write_unlock(&pfr->ring_rules_lock);
/*
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_TOGGLE_FILTER_POLICY: default policy is %s\n",
pfr->sw_filtering_rules_default_accept_policy ? "accept" : "drop");
*/
@@ -5062,7 +5067,7 @@
break;
case SO_ADD_FILTERING_RULE:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] +++ SO_ADD_FILTERING_RULE(len=%d)(len=%u)\n",
optlen, (unsigned int)sizeof(ip_addr));
@@ -5074,7 +5079,7 @@
sw_filtering_rule_element *rule;
struct list_head *ptr, *tmp_ptr;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Allocating memory [filtering_rule]\n");
rule =(sw_filtering_rule_element *)
@@ -5137,7 +5142,7 @@
return -EFAULT;
if(remove_sw_filtering_rule_element(pfr, rule_id) == 0) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_REMOVE_FILTERING_RULE: rule %d does not exist\n", rule_id);
return -EFAULT; /* Rule not found */
}
@@ -5172,37 +5177,31 @@
break;
case SO_ACTIVATE_RING:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] * SO_ACTIVATE_RING *\n");
if(pfr->dna_device_entry != NULL) {
- struct pf_ring_socket *other1 = NULL, *other2 = NULL;
-
- /* This is a DNA ring */
- other1=pfr->dna_device_entry->sock_b;
- other2=pfr->dna_device_entry->sock_c;
- if(pfr->dna_device_entry->sock_b == pfr)
- other1 = pfr->dna_device_entry->sock_a;
- else if(pfr->dna_device_entry->sock_c == pfr)
- other2 = pfr->dna_device_entry->sock_a;
-
- /* We need to check if the other socket is not using our direction */
- if((other1 && other1->ring_active && (other1->direction == pfr->direction || other1->direction == rx_and_tx_direction)) ||
- ((other1 = other2) && other2->ring_active && (other2->direction == pfr->direction || other2->direction == rx_and_tx_direction))){
- printk("[PF_RING] Unable to activate two DNA sockets on the same interface %s (direction_a=%s, direction_b=%s)\n",
- pfr->ring_netdev->dev->name,
- direction2string(pfr->direction),
- direction2string(other1->direction));
-
- return -EFAULT; /* No way: we can't have two sockets that are doing the same thing with DNA */
- }
+ int i;
+
+ for(i=0; i<MAX_NUM_DNA_BOUND_SOCKETS; i++) {
+ if((pfr->dna_device_entry->bound_sockets[i] != NULL)
+ && pfr->dna_device_entry->bound_sockets[i]->ring_active) {
+ if((pfr->dna_device_entry->bound_sockets[i]->direction == pfr->direction)
+ || (pfr->dna_device_entry->bound_sockets[i]->direction == rx_and_tx_direction)) {
+ printk("[PF_RING] Unable to activate two or more DNA sockets on the same interface %s/direction\n",
+ pfr->ring_netdev->dev->name);
+
+ return -EFAULT; /* No way: we can't have two sockets that are doing the same thing with DNA */
+ }
+ } /* if */
+ } /* for */
}
found = 1, pfr->ring_active = 1;
break;
case SO_DEACTIVATE_RING:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] * SO_DEACTIVATE_RING *\n");
found = 1, pfr->ring_active = 0;
break;
@@ -5222,7 +5221,7 @@
if(pfr->poll_num_pkts_watermark == 0)
pfr->poll_num_pkts_watermark = 1;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> SO_SET_POLL_WATERMARK=%d\n", pfr->poll_num_pkts_watermark);
}
break;
@@ -5234,7 +5233,7 @@
if(copy_from_user(&pfr->bucket_len, optval, optlen))
return -EFAULT;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> SO_RING_BUCKET_LEN=%d\n", pfr->bucket_len);
}
break;
@@ -5383,7 +5382,7 @@
/* Notify the consumer that we're ready to start */
if(pfr->kernel_consumer_plugin_id
&& (plugin_registration[pfr->kernel_consumer_plugin_id] == NULL)) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] Plugin %d is unknown\n", pfr->kernel_consumer_plugin_id);
pfr->kernel_consumer_plugin_id = 0;
@@ -5419,7 +5418,7 @@
break;
case SO_REHASH_RSS_PACKET:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] * SO_REHASH_RSS_PACKET *\n");
found = 1, pfr->rehash_rss = 1;
@@ -5483,7 +5482,7 @@
if(len < 0)
return -EINVAL;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> getsockopt(%d)\n", optname);
switch (optname) {
@@ -5531,7 +5530,7 @@
return -EFAULT;
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] so_get_hash_filtering_rule_stats"
"(vlan=%u, proto=%u, sip=%u, sport=%u, dip=%u, dport=%u)\n",
rule.vlan_id, rule.proto,
@@ -5549,7 +5548,7 @@
read_lock(&pfr->ring_rules_lock);
bucket = pfr->sw_filtering_hash[hash_idx];
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] so_get_hash_filtering_rule_stats(): bucket=%p\n",
bucket);
@@ -5585,7 +5584,7 @@
read_unlock(&pfr->ring_rules_lock);
} else {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] so_get_hash_filtering_rule_stats(): entry not found [hash_idx=%d]\n",
hash_idx);
}
@@ -5608,7 +5607,7 @@
if(copy_from_user(&rule_id, optval, sizeof(rule_id)))
return -EFAULT;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] SO_GET_FILTERING_RULE_STATS: rule_id=%d\n",
rule_id);
@@ -5678,7 +5677,7 @@
num_rx_channels = max_val(pfr->num_rx_channels, get_num_rx_queues(pfr->ring_netdev->dev));
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> SO_GET_NUM_RX_CHANNELS[%s]=%d [dna=%d/dns_rx_channels=%d][%p]\n",
pfr->ring_netdev->dev->name, num_rx_channels,
pfr->ring_netdev->is_dna_device,
@@ -5694,7 +5693,7 @@
if(len < sizeof(pfr->ring_id))
return -EINVAL;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> SO_GET_RING_ID=%d\n", pfr->ring_id);
if(copy_to_user(optval, &pfr->ring_id, sizeof(pfr->ring_id)))
@@ -5705,7 +5704,7 @@
if(len < sizeof(pfr->kernel_consumer_plugin_id))
return -EINVAL;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] --> SO_GET_PACKET_CONSUMER_MODE=%d\n",
pfr->kernel_consumer_plugin_id);
@@ -5715,15 +5714,43 @@
break;
case SO_GET_BOUND_DEVICE_ADDRESS:
- if(len < 6) return -EINVAL;
+ if(len < ETH_ALEN) return -EINVAL;
if(pfr->dna_device != NULL) {
if(copy_to_user(optval, pfr->dna_device->device_address, 6))
return -EFAULT;
} else if((pfr->ring_netdev != NULL)
&& (pfr->ring_netdev->dev != NULL)) {
- if(copy_to_user(optval, pfr->ring_netdev->dev->dev_addr, 6))
+ char lowest_if_mac[ETH_ALEN] = { 0 };
+ char magic_if_mac[ETH_ALEN];
+ memset(magic_if_mac, RING_MAGIC_VALUE, sizeof(magic_if_mac));
+
+ /* Read input buffer */
+ if(copy_from_user(&lowest_if_mac, optval, ETH_ALEN))
return -EFAULT;
+
+ if(!memcmp(lowest_if_mac, magic_if_mac, ETH_ALEN)) {
+ struct list_head *ptr, *tmp_ptr;
+ long lowest_id = -1;
+
+ /* Return the MAC address of the lowest X of ethX */
+
+ list_for_each_safe(ptr, tmp_ptr, &ring_aware_device_list) {
+ ring_device_element *entry = list_entry(ptr, ring_device_element, device_list);
+ char *eptr;
+ long id = simple_strtol(&entry->dev->name[3], &eptr, 10);
+
+ if((lowest_id == -1) || (id < lowest_id)) {
+ lowest_id = id, memcpy(lowest_if_mac, entry->dev->perm_addr, ETH_ALEN);
+ }
+ }
+
+ if(copy_to_user(optval, lowest_if_mac, ETH_ALEN))
+ return -EFAULT;
+ } else {
+ if(copy_to_user(optval, pfr->ring_netdev->dev->dev_addr, ETH_ALEN))
+ return -EFAULT;
+ }
} else
return -EFAULT;
break;
@@ -5788,15 +5815,17 @@
/* ************************************* */
void dna_device_handler(dna_device_operation operation,
- unsigned long rx_packet_memory,
+ u_int num_rx_pages,
+ unsigned long rx_packet_memory[MAX_NUM_DNA_PAGES],
u_int packet_memory_num_slots,
u_int packet_memory_slot_len,
u_int packet_memory_tot_len,
- void *descr_packet_memory,
+ void *rx_descr_packet_memory,
u_int descr_packet_memory_num_slots,
u_int descr_packet_memory_slot_len,
u_int descr_packet_memory_tot_len,
- unsigned long tx_packet_memory,
+ u_int num_tx_pages,
+ unsigned long tx_packet_memory[MAX_NUM_DNA_PAGES],
void *tx_descr_packet_memory,
u_int channel_id,
void *phys_card_memory,
@@ -5810,10 +5839,12 @@
dna_wait_packet wait_packet_function_ptr,
dna_device_notify dev_notify_function_ptr)
{
- if(enable_debug)
+ if(unlikely(enable_debug)) {
printk("[PF_RING] dna_device_handler(%s@%u [operation=%s])\n",
netdev->name, channel_id,
operation == add_device_mapping ? "add_device_mapping" : "remove_device_mapping");
+ printk("[PF_RING] RX=%u/TX=%u\n", num_rx_pages, num_tx_pages);
+ }
if(operation == add_device_mapping) {
dna_device_list *next;
@@ -5822,20 +5853,25 @@
if(next != NULL) {
memset(next, 0, sizeof(dna_device_list));
- next->in_use = 0;
- next->dev.rx_packet_memory = rx_packet_memory;
+ next->num_bound_sockets = 0;
+ memcpy(&next->dev.rx_packet_memory, rx_packet_memory, sizeof(next->dev.rx_packet_memory));
+
+ /* Number of mapped pages */
+ next->dev.num_rx_pages = num_rx_pages, next->dev.num_tx_pages = num_tx_pages;
+
next->dev.mem_info.packet_memory_num_slots = packet_memory_num_slots;
next->dev.mem_info.packet_memory_slot_len = packet_memory_slot_len;
next->dev.mem_info.packet_memory_tot_len = packet_memory_tot_len;
next->dev.mem_info.device_model = device_model;
- next->dev.rx_descr_packet_memory = descr_packet_memory;
+ next->dev.rx_descr_packet_memory = rx_descr_packet_memory;
next->dev.mem_info.descr_packet_memory_num_slots = descr_packet_memory_num_slots;
next->dev.mem_info.descr_packet_memory_slot_len = descr_packet_memory_slot_len;
next->dev.mem_info.descr_packet_memory_tot_len = descr_packet_memory_tot_len;
next->dev.phys_card_memory = phys_card_memory;
next->dev.mem_info.phys_card_memory_len = phys_card_memory_len;
/* TX */
- next->dev.tx_packet_memory = tx_packet_memory;
+ if(tx_packet_memory != NULL)
+ memcpy(&next->dev.tx_packet_memory, tx_packet_memory, sizeof(next->dev.rx_packet_memory));
next->dev.tx_descr_packet_memory = tx_descr_packet_memory;
next->dev.channel_id = channel_id;
next->dev.netdev = netdev;
@@ -5862,7 +5898,7 @@
dev_ptr->num_dna_rx_queues = max_val(dev_ptr->num_dna_rx_queues, channel_id+1);
dev_ptr->is_dna_device = 1, dev_ptr->dna_device_model = device_model;
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ==>> Updating DNA %s [num_dna_rx_queues=%d][%p]\n",
dev_ptr->dev->name, dev_ptr->num_dna_rx_queues, dev_ptr);
break;
@@ -5891,7 +5927,7 @@
}
}
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] dna_device_handler(%s): [dna_devices_list_size=%d]\n",
netdev->name, dna_devices_list_size);
}
@@ -6056,7 +6092,7 @@
rc = dev_ptr->dev->ethtool_ops->set_eeprom(dev_ptr->dev, &eeprom, (u8*)NULL);
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] set_eeprom returned %d\n", rc);
if(rc == RING_MAGIC_VALUE) {
@@ -6073,16 +6109,16 @@
ring_proc_dev_rule_read, dev_ptr);
if(entry) {
entry->write_proc = ring_proc_dev_rule_write;
- if(enable_debug) printk("[PF_RING] Device %s (Intel 82599) DOES support hardware packet filtering\n", dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] Device %s (Intel 82599) DOES support hardware packet filtering\n", dev->name);
} else {
- if(enable_debug) printk("[PF_RING] Error while creating /proc entry 'rules' for device %s\n", dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] Error while creating /proc entry 'rules' for device %s\n", dev->name);
}
#endif
} else {
- if(enable_debug) printk("[PF_RING] Device %s does NOT support hardware packet filtering [1]\n", dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] Device %s does NOT support hardware packet filtering [1]\n", dev->name);
}
} else {
- if(enable_debug) printk("[PF_RING] Device %s does NOT support hardware packet filtering [2]\n", dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] Device %s does NOT support hardware packet filtering [2]\n", dev->name);
}
#endif
@@ -6106,11 +6142,11 @@
struct pfring_hooks *hook;
if(dev != NULL) {
- if(enable_debug) printk("[PF_RING] packet_notifier(%lu)\n", msg);
+ if(unlikely(enable_debug)) printk("[PF_RING] packet_notifier(%lu)\n", msg);
/* Skip non ethernet interfaces */
if(strncmp(dev->name, "eth", 3) && strncmp(dev->name, "lan", 3)) {
- if(enable_debug) printk("[PF_RING] packet_notifier(%s): skipping non ethernet device\n", dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] packet_notifier(%s): skipping non ethernet device\n", dev->name);
return NOTIFY_DONE;
}
@@ -6120,7 +6156,7 @@
case NETDEV_DOWN:
break;
case NETDEV_REGISTER:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] packet_notifier(%s) [REGISTER][pfring_ptr=%p][hook=%p]\n",
dev->name, dev->pfring_ptr, &ring_hooks);
@@ -6133,7 +6169,7 @@
break;
case NETDEV_UNREGISTER:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] packet_notifier(%s) [UNREGISTER][pfring_ptr=%p]\n",
dev->name, dev->pfring_ptr);
@@ -6156,13 +6192,13 @@
{
struct list_head *ptr, *tmp_ptr;
- if(enable_debug) printk("[PF_RING] Device change name %s\n", dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] Device change name %s\n", dev->name);
list_for_each_safe(ptr, tmp_ptr, &ring_aware_device_list) {
ring_device_element *dev_ptr = list_entry(ptr, ring_device_element, device_list);
if(dev_ptr->dev == dev) {
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] ==>> FOUND device change name %s -> %s\n",
dev_ptr->proc_entry->name, dev->name);
@@ -6204,7 +6240,7 @@
break;
default:
- if(enable_debug)
+ if(unlikely(enable_debug))
printk("[PF_RING] packet_notifier(%s): unhandled message [msg=%lu][pfring_ptr=%p]\n",
dev->name, msg, dev->pfring_ptr);
break;
@@ -6255,7 +6291,7 @@
remove_proc_entry(dev_ptr->dev->name, ring_proc_dev_dir);
if(hook->magic == PF_RING) {
- if(enable_debug) printk("[PF_RING] Unregister hook for %s\n", dev_ptr->dev->name);
+ if(unlikely(enable_debug)) printk("[PF_RING] Unregister hook for %s\n", dev_ptr->dev->name);
dev_ptr->dev->pfring_ptr = NULL; /* Unhook PF_RING */
}
|