Page MenuHomeFreeBSD

D806.id.diff
No OneTemporary

D806.id.diff

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

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)

Event Timeline