Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F109915040
D806.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
26 KB
Referenced Files
None
Subscribers
None
D806.id.diff
View Options
Index: sys/dev/ixgbe/ixgbe.h
===================================================================
--- sys/dev/ixgbe/ixgbe.h
+++ sys/dev/ixgbe/ixgbe.h
@@ -90,8 +90,11 @@
#include <sys/pcpu.h>
#include <sys/smp.h>
#include <machine/smp.h>
+#include <sys/conf.h>
+#include <sys/priv.h>
#include "ixgbe_api.h"
+#include "ixgbe_ioctl.h"
/* Tunables */
@@ -457,8 +460,17 @@
unsigned long link_irq;
struct ixgbe_hw_stats stats;
+
+ struct cdev *cdev;
+ TAILQ_HEAD(, ix_filter_entry) filter_list;
+ struct mtx filter_mtx;
+ unsigned next_filter_id;
};
+struct ix_filter_entry {
+ TAILQ_ENTRY(ix_filter_entry) link;
+ struct ix_filter filter;
+};
/* Precision Time Sync (IEEE 1588) defines */
#define ETHERTYPE_IEEE1588 0x88F7
Index: sys/dev/ixgbe/ixgbe.c
===================================================================
--- sys/dev/ixgbe/ixgbe.c
+++ sys/dev/ixgbe/ixgbe.c
@@ -205,7 +205,9 @@
static void ixgbe_handle_mod(void *, int);
#ifdef IXGBE_FDIR
+#ifdef IXGBE_FDIR_ATR
static void ixgbe_atr(struct tx_ring *, struct mbuf *);
+#endif
static void ixgbe_reinit_fdir(void *, int);
#endif
@@ -229,6 +231,19 @@
"ix", ixgbe_methods, sizeof(struct adapter),
};
+static d_ioctl_t ixgbe_extension_ioctl;
+static d_open_t ixgbe_extension_open;
+static d_close_t ixgbe_extension_close;
+
+static struct cdevsw ixgbe_cdevsw = {
+ .d_version = D_VERSION,
+ .d_flags = 0,
+ .d_open = ixgbe_extension_open,
+ .d_close = ixgbe_extension_close,
+ .d_ioctl = ixgbe_extension_ioctl,
+ .d_name = "ixgbe",
+};
+
devclass_t ixgbe_devclass;
DRIVER_MODULE(ixgbe, pci, ixgbe_driver, ixgbe_devclass, 0, 0);
@@ -337,6 +352,7 @@
static int ixgbe_total_ports;
#ifdef IXGBE_FDIR
+#ifdef IXGBE_FDIR_ATR
/*
** For Flow Director: this is the
** number of TX packets we sample
@@ -347,6 +363,7 @@
** setting this to 0.
*/
static int atr_sample_rate = 20;
+#endif
/*
** Flow Director actually 'steals'
** part of the packet buffer as its
@@ -421,6 +438,20 @@
return (ENXIO);
}
+static int
+ixgbe_makedev(struct adapter *adapter)
+{
+ adapter->cdev = make_dev(&ixgbe_cdevsw, adapter->ifp->if_dunit,
+ UID_ROOT, GID_WHEEL, 0600, "%s", if_name(adapter->ifp));
+
+ if (adapter->cdev == NULL)
+ return (ENOMEM);
+
+ adapter->cdev->si_drv1 = (void *)adapter;
+
+ return (0);
+}
+
/*********************************************************************
* Device initialization routine
*
@@ -624,6 +655,14 @@
#ifdef DEV_NETMAP
ixgbe_netmap_attach(adapter);
#endif /* DEV_NETMAP */
+
+ error = ixgbe_makedev(adapter);
+ if (error)
+ goto err_late;
+
+ mtx_init(&adapter->filter_mtx, "filter_mtx", NULL, MTX_DEF);
+ TAILQ_INIT(&adapter->filter_list);
+
INIT_DEBUGOUT("ixgbe_attach: end");
return (0);
err_late:
@@ -1860,7 +1899,7 @@
return (error);
}
-#ifdef IXGBE_FDIR
+#ifdef IXGBE_FDIR_ATR
/* Do the flow director magic */
if ((txr->atr_sample) && (!adapter->fdir_reinit)) {
++txr->atr_count;
@@ -3169,7 +3208,7 @@
txbuf->eop = NULL;
}
-#ifdef IXGBE_FDIR
+#ifdef IXGBE_FDIR_ATR
/* Set the rate at which we sample packets */
if (adapter->hw.mac.type != ixgbe_mac_82598EB)
txr->atr_sample = atr_sample_rate;
@@ -3589,7 +3628,7 @@
return (0);
}
-#ifdef IXGBE_FDIR
+#ifdef IXGBE_FDIR_ATR
/*
** This routine parses packet headers so that Flow
** Director can make a hashed filter table entry
@@ -5489,13 +5528,33 @@
adapter->stats.xec += IXGBE_READ_REG(hw, IXGBE_XEC);
adapter->stats.fccrc += IXGBE_READ_REG(hw, IXGBE_FCCRC);
adapter->stats.fclast += IXGBE_READ_REG(hw, IXGBE_FCLAST);
- /* Only read FCOE on 82599 */
+ /* Only read FCOE/FDIR on 82599 */
if (hw->mac.type != ixgbe_mac_82598EB) {
adapter->stats.fcoerpdc += IXGBE_READ_REG(hw, IXGBE_FCOERPDC);
adapter->stats.fcoeprc += IXGBE_READ_REG(hw, IXGBE_FCOEPRC);
adapter->stats.fcoeptc += IXGBE_READ_REG(hw, IXGBE_FCOEPTC);
adapter->stats.fcoedwrc += IXGBE_READ_REG(hw, IXGBE_FCOEDWRC);
adapter->stats.fcoedwtc += IXGBE_READ_REG(hw, IXGBE_FCOEDWTC);
+ adapter->stats.fdirfree_free =
+ (IXGBE_READ_REG(hw, IXGBE_FDIRFREE) & IXGBE_FDIRFREE_FREE_MASK)
+ >> IXGBE_FDIRFREE_FREE_SHIFT;
+ adapter->stats.fdirfree_coll =
+ (IXGBE_READ_REG(hw, IXGBE_FDIRFREE) & IXGBE_FDIRFREE_COLL_MASK)
+ >> IXGBE_FDIRFREE_COLL_SHIFT;
+ adapter->stats.fdirustat_add +=
+ (IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT) & IXGBE_FDIRUSTAT_ADD_MASK)
+ >> IXGBE_FDIRUSTAT_ADD_SHIFT;
+ adapter->stats.fdirustat_remove +=
+ (IXGBE_READ_REG(hw, IXGBE_FDIRUSTAT) & IXGBE_FDIRUSTAT_REMOVE_MASK)
+ >> IXGBE_FDIRUSTAT_REMOVE_SHIFT;
+ adapter->stats.fdirfstat_fadd +=
+ (IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT) & IXGBE_FDIRFSTAT_FADD_MASK)
+ >> IXGBE_FDIRFSTAT_FADD_SHIFT;
+ adapter->stats.fdirfstat_fremove +=
+ (IXGBE_READ_REG(hw, IXGBE_FDIRFSTAT) & IXGBE_FDIRFSTAT_FREMOVE_MASK)
+ >> IXGBE_FDIRFSTAT_FREMOVE_SHIFT;
+ adapter->stats.fdirmatch += IXGBE_READ_REG(hw, IXGBE_FDIRMATCH);
+ adapter->stats.fdirmiss += IXGBE_READ_REG(hw, IXGBE_FDIRMISS);
}
/* Fill out the OS statistics structure */
@@ -5861,6 +5920,32 @@
SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "tx_frames_1024_1522",
CTLFLAG_RD, &stats->ptc1522,
"1024-1522 byte frames transmitted");
+
+ /* fdir stats */
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirfree_free",
+ CTLFLAG_RD, &stats->fdirfree_free,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirfree_coll",
+ CTLFLAG_RD, &stats->fdirfree_coll,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirustat_add",
+ CTLFLAG_RD, &stats->fdirustat_add,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirustat_remove",
+ CTLFLAG_RD, &stats->fdirustat_remove,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirfstat_fadd",
+ CTLFLAG_RD, &stats->fdirfstat_fadd,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirfstat_fremove",
+ CTLFLAG_RD, &stats->fdirfstat_fremove,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirmatch",
+ CTLFLAG_RD, &stats->fdirmatch,
+ "");
+ SYSCTL_ADD_UQUAD(ctx, stat_list, OID_AUTO, "fdirmiss",
+ CTLFLAG_RD, &stats->fdirmiss,
+ "");
}
/*
@@ -6011,6 +6096,140 @@
}
}
+static int
+ixgbe_extension_open(struct cdev *dev, int flags, int fmp, struct thread *td)
+{
+ return (0);
+}
+
+static int
+ixgbe_extension_close(struct cdev *dev, int flags, int fmt, struct thread *td)
+{
+ return (0);
+}
+
+static struct ix_filter_entry *
+ixgbe_find_filter(struct adapter *adapter, unsigned id)
+{
+ struct ix_filter_entry *entry;
+
+ TAILQ_FOREACH(entry, &adapter->filter_list, link)
+ if (entry->filter.id == id)
+ return entry;
+ return NULL;
+}
+
+static int
+ixgbe_extension_ioctl(struct cdev *dev, unsigned long cmd, caddr_t data,
+ int fflag, struct thread *td)
+{
+ struct adapter *adapter = (struct adapter *)dev->si_drv1;
+ int error = 0;
+
+ if (priv_check(td, PRIV_DRIVER)) {
+ return (EPERM);
+ }
+
+ mtx_lock(&adapter->filter_mtx);
+ switch (cmd) {
+ case IXGBE_ADD_SIGFILTER: {
+ struct ix_filter *filter = (struct ix_filter *)data;
+ struct ix_filter_entry *entry;
+ union ixgbe_atr_hash_dword input = {.dword = 0};
+ union ixgbe_atr_hash_dword common = {.dword = 0};
+
+ switch (filter->proto) {
+ case IXGBE_FILTER_PROTO_TCPV4:
+ input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_TCPV4;
+ break;
+ case IXGBE_FILTER_PROTO_UDPV4:
+ input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_UDPV4;
+ break;
+ default:
+ error = EINVAL;
+ goto out;
+ }
+ common.port.src ^= htons(filter->src_port);
+ common.port.dst ^= htons(filter->dst_port);
+ common.flex_bytes ^= htons(ETHERTYPE_IP);
+ common.ip ^= filter->src_ip.s_addr ^ filter->dst_ip.s_addr;
+
+ entry = malloc(sizeof(*entry), M_DEVBUF, M_NOWAIT | M_ZERO);
+ if (!entry) {
+ error = ENOMEM;
+ goto out;
+ }
+ memcpy(&entry->filter, filter, sizeof(entry->filter));
+ entry->filter.id = adapter->next_filter_id++;
+ TAILQ_INSERT_TAIL(&adapter->filter_list, entry, link);
+
+ ixgbe_fdir_add_signature_filter_82599(&adapter->hw,
+ input, common, filter->que_index);
+ break;
+ }
+ case IXGBE_GET_SIGFILTER: {
+ struct ix_filter *filter = (struct ix_filter *)data;
+ struct ix_filter_entry *entry;
+
+ entry = ixgbe_find_filter(adapter, filter->id);
+ if (entry)
+ memcpy(filter, &entry->filter, sizeof(*filter));
+ else
+ error = ENOENT;
+ break;
+ };
+ case IXGBE_CLR_SIGFILTER: {
+ unsigned *id = (unsigned *)data;
+ struct ix_filter_entry *entry;
+ union ixgbe_atr_hash_dword input = {.dword = 0};
+ union ixgbe_atr_hash_dword common = {.dword = 0};
+
+ entry = ixgbe_find_filter(adapter, *id);
+ if (!entry) {
+ error = ENOENT;
+ goto out;
+ }
+
+ switch (entry->filter.proto) {
+ case IXGBE_FILTER_PROTO_TCPV4:
+ input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_TCPV4;
+ break;
+ case IXGBE_FILTER_PROTO_UDPV4:
+ input.formatted.flow_type ^= IXGBE_ATR_FLOW_TYPE_UDPV4;
+ break;
+ default:
+ error = EINVAL;
+ goto out;
+ }
+ common.port.src ^= htons(entry->filter.src_port);
+ common.port.dst ^= htons(entry->filter.dst_port);
+ common.flex_bytes ^= htons(ETHERTYPE_IP);
+ common.ip ^= entry->filter.src_ip.s_addr
+ ^ entry->filter.dst_ip.s_addr;
+
+ ixgbe_fdir_erase_signature_filter_82599(&adapter->hw,
+ input, common);
+
+ TAILQ_REMOVE(&adapter->filter_list, entry, link);
+ break;
+ }
+ case IXGBE_GET_SIGFILTER_LEN: {
+ unsigned *id = (unsigned *)data;
+
+ *id = adapter->next_filter_id;
+ break;
+ }
+ default:
+ error = EOPNOTSUPP;
+ break;
+ }
+
+out:
+ mtx_unlock(&adapter->filter_mtx);
+ return (error);
+}
+
+
static void
ixgbe_disable_rx_drop(struct adapter *adapter)
{
Index: sys/dev/ixgbe/ixgbe_82599.c
===================================================================
--- sys/dev/ixgbe/ixgbe_82599.c
+++ sys/dev/ixgbe/ixgbe_82599.c
@@ -1482,7 +1482,8 @@
* Set the maximum length per hash bucket to 0xA filters
* Send interrupt when 64 filters are left
*/
- fdirctrl |= (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
+ fdirctrl |= IXGBE_FDIRCTRL_REPORT_STATUS |
+ (0x6 << IXGBE_FDIRCTRL_FLEX_SHIFT) |
(0xA << IXGBE_FDIRCTRL_MAX_LENGTH_SHIFT) |
(4 << IXGBE_FDIRCTRL_FULL_THRESH_SHIFT);
@@ -1667,6 +1668,56 @@
return IXGBE_SUCCESS;
}
+/**
+ * ixgbe_fdir_erase_signature_filter_82599 - Adds a signature hash filter
+ * @hw: pointer to hardware structure
+ * @stream: input bitstream
+ * @queue: queue index to direct traffic to
+ **/
+s32 ixgbe_fdir_erase_signature_filter_82599(struct ixgbe_hw *hw,
+ union ixgbe_atr_hash_dword input,
+ union ixgbe_atr_hash_dword common)
+{
+ u64 fdirhashcmd;
+ u32 fdircmd;
+
+ DEBUGFUNC("ixgbe_fdir_clear_signature_filter_82599");
+
+ /*
+ * Get the flow_type in order to program FDIRCMD properly
+ * lowest 2 bits are FDIRCMD.L4TYPE, third lowest bit is FDIRCMD.IPV6
+ */
+ switch (input.formatted.flow_type) {
+ case IXGBE_ATR_FLOW_TYPE_TCPV4:
+ case IXGBE_ATR_FLOW_TYPE_UDPV4:
+ case IXGBE_ATR_FLOW_TYPE_SCTPV4:
+ case IXGBE_ATR_FLOW_TYPE_TCPV6:
+ case IXGBE_ATR_FLOW_TYPE_UDPV6:
+ case IXGBE_ATR_FLOW_TYPE_SCTPV6:
+ break;
+ default:
+ DEBUGOUT(" Error on flow type input\n");
+ return IXGBE_ERR_CONFIG;
+ }
+
+ /* configure FDIRCMD register */
+ fdircmd = IXGBE_FDIRCMD_CMD_REMOVE_FLOW |
+ IXGBE_FDIRCMD_LAST | IXGBE_FDIRCMD_QUEUE_EN;
+ fdircmd |= input.formatted.flow_type << IXGBE_FDIRCMD_FLOW_TYPE_SHIFT;
+
+ /*
+ * The lower 32-bits of fdirhashcmd is for FDIRHASH, the upper 32-bits
+ * is for FDIRCMD. Then do a 64-bit register write from FDIRHASH.
+ */
+ fdirhashcmd = (u64)fdircmd << 32;
+ fdirhashcmd |= ixgbe_atr_compute_sig_hash_82599(input, common);
+ IXGBE_WRITE_REG64(hw, IXGBE_FDIRHASH, fdirhashcmd);
+
+ DEBUGOUT1("Tx hash=%x\n", (u32)fdirhashcmd);
+
+ return IXGBE_SUCCESS;
+}
+
#define IXGBE_COMPUTE_BKT_HASH_ITERATION(_n) \
do { \
u32 n = (_n); \
Index: sys/dev/ixgbe/ixgbe_api.h
===================================================================
--- sys/dev/ixgbe/ixgbe_api.h
+++ sys/dev/ixgbe/ixgbe_api.h
@@ -144,6 +144,9 @@
union ixgbe_atr_hash_dword input,
union ixgbe_atr_hash_dword common,
u8 queue);
+s32 ixgbe_fdir_erase_signature_filter_82599(struct ixgbe_hw *hw,
+ union ixgbe_atr_hash_dword input,
+ union ixgbe_atr_hash_dword common);
s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
union ixgbe_atr_input *input_mask);
s32 ixgbe_fdir_write_perfect_filter_82599(struct ixgbe_hw *hw,
Index: sys/dev/ixgbe/ixgbe_ioctl.h
===================================================================
--- /dev/null
+++ sys/dev/ixgbe/ixgbe_ioctl.h
@@ -0,0 +1,63 @@
+/**************************************************************************
+
+Copyright (c) 2013 Takuya ASADA
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Neither the name of the Chelsio Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+$FreeBSD$
+
+***************************************************************************/
+
+#ifndef __IXGBEIOCTL_H__
+#define __IXGBEIOCTL_H__
+
+enum {
+ IX_ADD_SIGFILTER = 0x0,
+ IX_GET_SIGFILTER,
+ IX_CLR_SIGFILTER,
+ IX_GET_SIGFILTER_LEN
+};
+
+enum {
+ IXGBE_FILTER_PROTO_TCPV4,
+ IXGBE_FILTER_PROTO_UDPV4
+};
+
+struct ix_filter {
+ unsigned id;
+ int proto;
+ struct in_addr src_ip;
+ int src_port;
+ struct in_addr dst_ip;
+ int dst_port;
+ int que_index;
+};
+
+#define IXGBE_ADD_SIGFILTER _IOW('i', IX_ADD_SIGFILTER, struct ix_filter)
+#define IXGBE_GET_SIGFILTER _IOWR('i', IX_GET_SIGFILTER, struct ix_filter)
+#define IXGBE_CLR_SIGFILTER _IOW('i', IX_CLR_SIGFILTER, unsigned)
+#define IXGBE_GET_SIGFILTER_LEN _IOR('i', IX_GET_SIGFILTER_LEN, unsigned)
+
+#endif
+
Index: sys/dev/ixgbe/ixgbe_type.h
===================================================================
--- sys/dev/ixgbe/ixgbe_type.h
+++ sys/dev/ixgbe/ixgbe_type.h
@@ -2997,6 +2997,8 @@
u64 qbtc[16];
u64 qprdc[16];
u64 pxon2offc[8];
+ u64 fdirfree_free;
+ u64 fdirfree_coll;
u64 fdirustat_add;
u64 fdirustat_remove;
u64 fdirfstat_fadd;
Index: tools/tools/ixgbetool/Makefile
===================================================================
--- /dev/null
+++ tools/tools/ixgbetool/Makefile
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG= ixgbetool
+SRCS= ixgbetool.c
+NO_MAN=
+CFLAGS+= -I${.CURDIR}/../../../sys/dev/ixgbe -I.
+BINDIR?= /usr/sbin
+
+.include <bsd.prog.mk>
@@ -0,0 +1,9 @@
+# $FreeBSD$
+
+PROG= ixgbetool
+SRCS= ixgbetool.c
+NO_MAN=
+CFLAGS+= -I${.CURDIR}/../../../sys/dev/ixgbe -I.
+BINDIR?= /usr/sbin
+
+.include <bsd.prog.mk>
Index: tools/tools/ixgbetool/ixgbetool.c
===================================================================
--- /dev/null
+++ tools/tools/ixgbetool/ixgbetool.c
@@ -0,0 +1,210 @@
+/**************************************************************************
+
+Copyright (c) 2013, Takuya ASADA.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Chelsio Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+***************************************************************************/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <ixgbe_ioctl.h>
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: ixgbetool <ifname> [operation]\n");
+ fprintf(stderr, "\tadd_sig_filter <proto> <src_ip> <src_port> <dst_ip> <dst_port> <que_index>\n");
+ fprintf(stderr, "\tshow_sig_filter\n");
+ fprintf(stderr, "\tdel_sig_filter <id>\n");
+}
+
+static int
+doit(const char *iff_name, unsigned long cmd, void *data)
+{
+ int fd = 0;
+ int err;
+ char buf[64];
+
+ snprintf(buf, 64, "/dev/%s", iff_name);
+ if ((fd = open(buf, O_RDWR)) < 0)
+ return -1;
+
+ err = ioctl(fd, cmd, data) < 0 ? -1 : 0;
+ close(fd);
+ return err;
+}
+
+static int
+add_sig_filter(int argc, char *argv[], char *ifname)
+{
+ struct ix_filter filter;
+ int error;
+
+ if (argc != 9)
+ return -1;
+
+ if (!strcmp(argv[3], "tcpv4"))
+ filter.proto = IXGBE_FILTER_PROTO_TCPV4;
+ else if (!strcmp(argv[3], "udpv4"))
+ filter.proto = IXGBE_FILTER_PROTO_UDPV4;
+ else
+ return -1;
+ error = inet_aton(argv[4], &filter.src_ip);
+ if (error != 1)
+ return error;
+ errno = 0;
+ filter.src_port = strtol(argv[5], NULL, 0);
+ if (errno)
+ return errno;
+ error = inet_aton(argv[6], &filter.dst_ip);
+ if (error != 1)
+ return error;
+ errno = 0;
+ filter.dst_port = strtol(argv[7], NULL, 0);
+ if (errno)
+ return errno;
+ errno = 0;
+ filter.que_index = strtol(argv[8], NULL, 0);
+ if (errno)
+ return errno;
+
+ error = doit(ifname, IXGBE_ADD_SIGFILTER, (void *)&filter);
+ if (error)
+ perror("ioctl");
+ return 0;
+}
+
+static inline const char *
+filter_proto_str(int proto)
+{
+ const char *str;
+
+ switch (proto) {
+ case IXGBE_FILTER_PROTO_TCPV4:
+ str = "tcpv4";
+ break;
+ case IXGBE_FILTER_PROTO_UDPV4:
+ str = "udpv4";
+ break;
+ default:
+ str = "(inval)";
+ }
+ return str;
+}
+
+static int
+show_sig_filter(int argc, char *argv[], char *ifname)
+{
+ unsigned i;
+ unsigned len;
+ int error;
+
+ if (argc != 3)
+ return -1;
+
+ error = doit(ifname, IXGBE_GET_SIGFILTER_LEN, (void *)&len);
+ if (error)
+ perror("ioctl");
+
+ for (i = 0; i < len; i++) {
+ struct ix_filter filter;
+ filter.id = i;
+ error = doit(ifname, IXGBE_GET_SIGFILTER, (void *)&filter);
+ if (error)
+ continue;
+ printf("id: %u\n", filter.id);
+ printf("proto: %s\n", filter_proto_str(filter.proto));
+ printf("src_ip: %s\n", inet_ntoa(filter.src_ip));
+ printf("src_port: %d\n", filter.src_port);
+ printf("dst_ip: %s\n", inet_ntoa(filter.dst_ip));
+ printf("dst_port: %d\n", filter.dst_port);
+ printf("que_index: %d\n", filter.que_index);
+ printf("\n");
+ }
+ return 0;
+}
+
+static int
+del_sig_filter(int argc, char *argv[], char *ifname)
+{
+ unsigned id;
+ int error;
+
+ if (argc != 4)
+ return -1;
+
+ errno = 0;
+ id = strtoul(argv[3], NULL, 0);
+ if (errno)
+ return errno;
+
+ error = doit(ifname, IXGBE_CLR_SIGFILTER, (void *)&id);
+ if (error)
+ perror("ioctl");
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ char *ifname;
+
+ if (argc < 3) {
+ usage();
+ exit(1);
+ }
+ ifname = argv[1];
+ if (!strcmp(argv[2], "add_sig_filter"))
+ ret = add_sig_filter(argc, argv, ifname);
+ else if (!strcmp(argv[2], "show_sig_filter"))
+ ret = show_sig_filter(argc, argv, ifname);
+ else if (!strcmp(argv[2], "del_sig_filter"))
+ ret = del_sig_filter(argc, argv, ifname);
+ else
+ ret = -1;
+
+ if (ret)
+ usage();
+
+ return (ret);
+}
@@ -0,0 +1,210 @@
+/**************************************************************************
+
+Copyright (c) 2013, Takuya ASADA.
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ 3. Neither the name of the Chelsio Corporation nor the names of its
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+
+***************************************************************************/
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <stdio.h>
+#include <string.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <sys/ioctl.h>
+#include <ixgbe_ioctl.h>
+
+static void
+usage(void)
+{
+ fprintf(stderr, "Usage: ixgbetool <ifname> [operation]\n");
+ fprintf(stderr, "\tadd_sig_filter <proto> <src_ip> <src_port> <dst_ip> <dst_port> <que_index>\n");
+ fprintf(stderr, "\tshow_sig_filter\n");
+ fprintf(stderr, "\tdel_sig_filter <id>\n");
+}
+
+static int
+doit(const char *iff_name, unsigned long cmd, void *data)
+{
+ int fd = 0;
+ int err;
+ char buf[64];
+
+ snprintf(buf, 64, "/dev/%s", iff_name);
+ if ((fd = open(buf, O_RDWR)) < 0)
+ return -1;
+
+ err = ioctl(fd, cmd, data) < 0 ? -1 : 0;
+ close(fd);
+ return err;
+}
+
+static int
+add_sig_filter(int argc, char *argv[], char *ifname)
+{
+ struct ix_filter filter;
+ int error;
+
+ if (argc != 9)
+ return -1;
+
+ if (!strcmp(argv[3], "tcpv4"))
+ filter.proto = IXGBE_FILTER_PROTO_TCPV4;
+ else if (!strcmp(argv[3], "udpv4"))
+ filter.proto = IXGBE_FILTER_PROTO_UDPV4;
+ else
+ return -1;
+ error = inet_aton(argv[4], &filter.src_ip);
+ if (error != 1)
+ return error;
+ errno = 0;
+ filter.src_port = strtol(argv[5], NULL, 0);
+ if (errno)
+ return errno;
+ error = inet_aton(argv[6], &filter.dst_ip);
+ if (error != 1)
+ return error;
+ errno = 0;
+ filter.dst_port = strtol(argv[7], NULL, 0);
+ if (errno)
+ return errno;
+ errno = 0;
+ filter.que_index = strtol(argv[8], NULL, 0);
+ if (errno)
+ return errno;
+
+ error = doit(ifname, IXGBE_ADD_SIGFILTER, (void *)&filter);
+ if (error)
+ perror("ioctl");
+ return 0;
+}
+
+static inline const char *
+filter_proto_str(int proto)
+{
+ const char *str;
+
+ switch (proto) {
+ case IXGBE_FILTER_PROTO_TCPV4:
+ str = "tcpv4";
+ break;
+ case IXGBE_FILTER_PROTO_UDPV4:
+ str = "udpv4";
+ break;
+ default:
+ str = "(inval)";
+ }
+ return str;
+}
+
+static int
+show_sig_filter(int argc, char *argv[], char *ifname)
+{
+ unsigned i;
+ unsigned len;
+ int error;
+
+ if (argc != 3)
+ return -1;
+
+ error = doit(ifname, IXGBE_GET_SIGFILTER_LEN, (void *)&len);
+ if (error)
+ perror("ioctl");
+
+ for (i = 0; i < len; i++) {
+ struct ix_filter filter;
+ filter.id = i;
+ error = doit(ifname, IXGBE_GET_SIGFILTER, (void *)&filter);
+ if (error)
+ continue;
+ printf("id: %u\n", filter.id);
+ printf("proto: %s\n", filter_proto_str(filter.proto));
+ printf("src_ip: %s\n", inet_ntoa(filter.src_ip));
+ printf("src_port: %d\n", filter.src_port);
+ printf("dst_ip: %s\n", inet_ntoa(filter.dst_ip));
+ printf("dst_port: %d\n", filter.dst_port);
+ printf("que_index: %d\n", filter.que_index);
+ printf("\n");
+ }
+ return 0;
+}
+
+static int
+del_sig_filter(int argc, char *argv[], char *ifname)
+{
+ unsigned id;
+ int error;
+
+ if (argc != 4)
+ return -1;
+
+ errno = 0;
+ id = strtoul(argv[3], NULL, 0);
+ if (errno)
+ return errno;
+
+ error = doit(ifname, IXGBE_CLR_SIGFILTER, (void *)&id);
+ if (error)
+ perror("ioctl");
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ int ret;
+ char *ifname;
+
+ if (argc < 3) {
+ usage();
+ exit(1);
+ }
+ ifname = argv[1];
+ if (!strcmp(argv[2], "add_sig_filter"))
+ ret = add_sig_filter(argc, argv, ifname);
+ else if (!strcmp(argv[2], "show_sig_filter"))
+ ret = show_sig_filter(argc, argv, ifname);
+ else if (!strcmp(argv[2], "del_sig_filter"))
+ ret = del_sig_filter(argc, argv, ifname);
+ else
+ ret = -1;
+
+ if (ret)
+ usage();
+
+ return (ret);
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Feb 12, 4:05 AM (8 h, 56 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
16605680
Default Alt Text
D806.id.diff (26 KB)
Attached To
Mode
D806: dev/ixgbe: implement flowdirector
Attached
Detach File
Event Timeline
Log In to Comment