summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Borkmann <dborkman@redhat.com>2013-06-03 22:49:19 +0200
committerDaniel Borkmann <dborkman@redhat.com>2013-06-03 22:52:33 +0200
commitdc5f7a04f2b446b5224be356c2fc79e88a5d3e8f (patch)
tree1bde4c8eea045e789ea797117e7ab3b84aac7117
parent0bc86fe938e8f6d12aca41a283491f51729d5c62 (diff)
irq: break out from xutils and save + restore
Break out IRQ functionality from xutils, simplify it, and save + restore IRQ affinity list. Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
-rw-r--r--irq.c129
-rw-r--r--irq.h10
-rw-r--r--netsniff-ng.c3
-rw-r--r--netsniff-ng/Makefile1
-rw-r--r--trafgen.c2
-rw-r--r--trafgen/Makefile1
-rw-r--r--xutils.c108
-rw-r--r--xutils.h3
8 files changed, 145 insertions, 112 deletions
diff --git a/irq.c b/irq.c
new file mode 100644
index 0000000..fbd1cbc
--- /dev/null
+++ b/irq.c
@@ -0,0 +1,129 @@
+/*
+ * netsniff-ng - the packet sniffing beast
+ * Copyright 2009 - 2013 Daniel Borkmann.
+ * Copyright 2009, 2010 Emmanuel Roullit.
+ * Subject to the GPL, version 2.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#include "irq.h"
+#include "die.h"
+#include "xutils.h"
+
+int device_irq_number(const char *ifname)
+{
+ int irq = 0;
+ char buff[128], sysname[128];
+ FILE *fp;
+
+ if (!strncmp("lo", ifname, strlen("lo")))
+ return 0;
+
+ slprintf(sysname, sizeof(sysname),
+ "/sys/class/net/%s/device/irq",
+ ifname);
+
+ fp = fopen(sysname, "r");
+ if (!fp)
+ return -ENOENT;
+
+ memset(buff, 0, sizeof(buff));
+
+ if (fgets(buff, sizeof(buff), fp) != NULL) {
+ buff[sizeof(buff) - 1] = 0;
+ irq = atoi(buff);
+ }
+
+ fclose(fp);
+ return irq;
+}
+
+static char nic_irq_affinity_list[128];
+static bool nic_irq_stored = false;
+static int nic_irq = -1;
+
+static void device_save_irq_affinity_list(void)
+{
+ int ret, fd;
+ char file[128];
+
+ bug_on(nic_irq_stored);
+
+ slprintf(file, sizeof(file),
+ "/proc/irq/%d/smp_affinity_list", nic_irq);
+
+ fd = open(file, O_RDONLY);
+ if (fd < 0)
+ return;
+
+ memset(nic_irq_affinity_list, 0, sizeof(nic_irq_affinity_list));
+
+ ret = read(fd, nic_irq_affinity_list,
+ sizeof(nic_irq_affinity_list));
+ if (ret < 0)
+ panic("Cannot store NIC IRQ affinity!\n");
+
+ close(fd);
+
+ nic_irq_stored = true;
+}
+
+void device_restore_irq_affinity_list(void)
+{
+ int ret, fd;
+ char file[128];
+
+ if (!nic_irq_stored)
+ return;
+
+ bug_on(nic_irq == -1);
+
+ slprintf(file, sizeof(file),
+ "/proc/irq/%d/smp_affinity_list", nic_irq);
+
+ fd = open(file, O_WRONLY);
+ if (fd < 0)
+ return;
+
+ ret = write(fd, nic_irq_affinity_list,
+ sizeof(nic_irq_affinity_list));
+ if (ret < 0)
+ panic("Cannot restore NIC IRQ affinity!\n");
+
+ close(fd);
+}
+
+int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
+{
+ int ret, fd;
+ char file[128], list[64];
+
+ if (!nic_irq_stored) {
+ nic_irq = irq;
+ device_save_irq_affinity_list();
+ }
+
+ slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
+ slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
+
+ fd = open(file, O_WRONLY);
+ if (fd < 0)
+ return -ENOENT;
+
+ ret = write(fd, list, strlen(list));
+
+ close(fd);
+ return ret;
+}
+
+int device_bind_irq_to_cpu(int irq, int cpu)
+{
+ return device_set_irq_affinity_list(irq, cpu, cpu);
+}
diff --git a/irq.h b/irq.h
new file mode 100644
index 0000000..6c1c850
--- /dev/null
+++ b/irq.h
@@ -0,0 +1,10 @@
+#ifndef IRQ_H
+#define IRQ_H
+
+extern int device_irq_number(const char *ifname);
+extern int device_bind_irq_to_cpu(int irq, int cpu);
+extern void device_restore_irq_affinity_list(void);
+extern int device_set_irq_affinity_list(int irq, unsigned long from,
+ unsigned long to);
+
+#endif /* IRQ_H */
diff --git a/netsniff-ng.c b/netsniff-ng.c
index 4d9abc8..899a148 100644
--- a/netsniff-ng.c
+++ b/netsniff-ng.c
@@ -32,6 +32,7 @@
#include "bpf.h"
#include "xio.h"
#include "die.h"
+#include "irq.h"
#include "geoip.h"
#include "tprintf.h"
#include "dissector.h"
@@ -1398,7 +1399,7 @@ int main(int argc, char **argv)
if (setsockmem)
reset_system_socket_memory(vals, array_size(vals));
destroy_geoip();
-
+ device_restore_irq_affinity_list();
tprintf_cleanup();
free(ctx.device_in);
diff --git a/netsniff-ng/Makefile b/netsniff-ng/Makefile
index 211c726..7d5f89c 100644
--- a/netsniff-ng/Makefile
+++ b/netsniff-ng/Makefile
@@ -32,6 +32,7 @@ netsniff-ng-objs = dissector.o \
proto_vlan_q_in_q.o \
proto_mpls_unicast.o \
proto_80211_mac_hdr.o \
+ irq.o \
xio.o \
xutils.o \
xmalloc.o \
diff --git a/trafgen.c b/trafgen.c
index bbce64c..d493614 100644
--- a/trafgen.c
+++ b/trafgen.c
@@ -37,6 +37,7 @@
#include "mac80211.h"
#include "xutils.h"
#include "xio.h"
+#include "irq.h"
#include "built_in.h"
#include "trafgen_conf.h"
#include "tprintf.h"
@@ -1083,6 +1084,7 @@ int main(int argc, char **argv)
thread_out:
xunlockme();
destroy_shared_var(stats, ctx.cpus);
+ device_restore_irq_affinity_list();
free(ctx.device);
free(ctx.device_trans);
diff --git a/trafgen/Makefile b/trafgen/Makefile
index 8257ad1..914b61c 100644
--- a/trafgen/Makefile
+++ b/trafgen/Makefile
@@ -5,6 +5,7 @@ trafgen-libs = $(shell pkg-config --libs libnl-3.0) \
trafgen-objs = xmalloc.o \
xio.o \
xutils.o \
+ irq.o \
mac80211.o \
ring_tx.o \
ring.o \
diff --git a/xutils.c b/xutils.c
index 5421d7d..a5fbb3c 100644
--- a/xutils.c
+++ b/xutils.c
@@ -608,114 +608,6 @@ void device_set_flags(const char *ifname, const short flags)
close(sock);
}
-int device_irq_number(const char *ifname)
-{
- /*
- * Since fetching IRQ numbers from SIOCGIFMAP is deprecated and not
- * supported anymore, we need to grab them from procfs
- */
- int irq = 0;
- char *buffp;
- char buff[512];
- char sysname[512];
- FILE *fp;
-
- if (!strncmp("lo", ifname, strlen("lo")))
- return 0;
-
- fp = fopen("/proc/interrupts", "r");
- if (!fp)
- panic("Cannot open /proc/interrupts!\n");
-
- memset(buff, 0, sizeof(buff));
- while (fgets(buff, sizeof(buff), fp) != NULL) {
- buff[sizeof(buff) - 1] = 0;
-
- if (strstr(buff, ifname) == NULL)
- continue;
-
- buffp = buff;
- while (*buffp != ':')
- buffp++;
- *buffp = 0;
- irq = atoi(buff);
-
- memset(buff, 0, sizeof(buff));
- }
-
- fclose(fp);
-
- if (irq != 0)
- return irq;
- /*
- * Try sysfs as fallback. Probably wireless devices will be found
- * here. We return silently if it fails ...
- */
- slprintf(sysname, sizeof(sysname), "/sys/class/net/%s/device/irq",
- ifname);
-
- fp = fopen(sysname, "r");
- if (!fp)
- return -ENOENT;
-
- memset(buff, 0, sizeof(buff));
- if(fgets(buff, sizeof(buff), fp) != NULL) {
- buff[sizeof(buff) - 1] = 0;
- irq = atoi(buff);
- }
-
- fclose(fp);
-
- return irq;
-}
-
-int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to)
-{
- int ret, fd;
- char file[256], list[64];
-
- slprintf(file, sizeof(file), "/proc/irq/%d/smp_affinity_list", irq);
- slprintf(list, sizeof(list), "%lu-%lu\n", from, to);
-
- fd = open(file, O_WRONLY);
- if (fd < 0)
- return -ENOENT;
-
- ret = write(fd, list, strlen(list));
-
- close(fd);
- return ret;
-}
-
-int device_bind_irq_to_cpu(int irq, int cpu)
-{
- int ret;
- char buff[256];
- char file[256];
- FILE *fp;
-
- /* Note: first CPU begins with CPU 0 */
- if (irq < 0 || cpu < 0)
- return -EINVAL;
-
- memset(file, 0, sizeof(file));
- memset(buff, 0, sizeof(buff));
-
- /* smp_affinity starts counting with CPU 1, 2, ... */
- cpu = cpu + 1;
- sprintf(file, "/proc/irq/%d/smp_affinity", irq);
-
- fp = fopen(file, "w");
- if (!fp)
- return -ENOENT;
-
- sprintf(buff, "%d", cpu);
- ret = fwrite(buff, sizeof(buff), 1, fp);
-
- fclose(fp);
- return (ret > 0 ? 0 : ret);
-}
-
void sock_print_net_stats(int sock)
{
int ret;
diff --git a/xutils.h b/xutils.h
index 6e72b5c..28a307b 100644
--- a/xutils.h
+++ b/xutils.h
@@ -36,9 +36,6 @@ extern int ethtool_drvinf(const char *ifname, struct ethtool_drvinfo *drvinf);
extern int ethtool_link(const char *ifname);
extern int device_mtu(const char *ifname);
extern int device_address(const char *ifname, int af, struct sockaddr_storage *ss);
-extern int device_irq_number(const char *ifname);
-extern int device_set_irq_affinity_list(int irq, unsigned long from, unsigned long to);
-extern int device_bind_irq_to_cpu(int irq, int cpu);
extern void sock_print_net_stats(int sock);
extern int device_ifindex(const char *ifname);
extern short device_get_flags(const char *ifname);