Date: Mon, 30 Sep 2013 06:43:02 +0900 From: Takuya ASADA <syuu@dokukino.com> To: hiren panchasara <hiren.panchasara@gmail.com> Cc: "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>, Adrian Chadd <adrian@freebsd.org> Subject: Re: Adding Flow Director sysctls to ixgbe(4) (was: netmap: traffic distribution) Message-ID: <CALG4x-Xf27oEOA9K5j%2BRRndFe1VbDowpTti8a8qwu1mRaB4BkQ@mail.gmail.com> In-Reply-To: <CALCpEUHoVJgmYptMp6Q%2BY%2BDgbxgujN8e7TcANUi1De_fnkOZ_w@mail.gmail.com> References: <CALCpEUHcpoJoo_gqjyDzosE1bJ_J=o3uqUuyYJA8dWZdjMrNTA@mail.gmail.com> <CAJ-VmompkSY-tU2SysaEf6p1uJPmcMeXKJ6_EZ_DJiYTQXbUzw@mail.gmail.com> <CALG4x-XowXNze82jvFX84X0=d7MRucpJbUeExug9y7XsaZXkSw@mail.gmail.com> <CALCpEUHoVJgmYptMp6Q%2BY%2BDgbxgujN8e7TcANUi1De_fnkOZ_w@mail.gmail.com>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --] Hi, I just implemented device specific ioctl with device specific configuration tool. It still doesn't support some important features such as: - FDIR enable / disable via sysctl or tunable params - ATR enable / disable via sysctl or tunable params - IPv6 support on signature filter - signature filter list - support perfect filter But, at least it can configure signature filter manually. Usage is as follows: Usage: ixgbetool <ifname> [operation] add_sig_filter <proto> <src_ip> <src_port> <dst_ip> <dst_port> <que_index> del_sig_filter <proto> <src_ip> <src_port> <dst_ip> <dst_port> 2013/9/28 hiren panchasara <hiren.panchasara@gmail.com> > > > > On Fri, Sep 27, 2013 at 1:58 AM, Takuya ASADA <syuu@dokukino.com> wrote: > >> 2013/9/27 Adrian Chadd <adrian@freebsd.org> >> >>> On 27 September 2013 00:43, hiren panchasara <hiren.panchasara@gmail.com >>> > wrote: >>> >>> >>>> Takuya, >>>> >>>> I see a lot of responses/comments on proposed changes. Was anything >>>> decided >>>> at the end of it? As far as I can tell, its still not committed to the >>>> tree. >>>> >>> >>> I'd rather see an ioctl API for that chipset and then have a separate >>> tool program it for now. >>> >> >> Ah, like cxgbetool and cxgbe? (it has device specific tool and ioctls) >> http://svnweb.freebsd.org/base/head/tools/tools/cxgbetool/ >> > > Something like this for ixgbe would be nice to start with, imo. > > Cheers, > Hiren > >> http://svnweb.freebsd.org/base/head/sys/dev/cxgb/ >> >> >>> So, how bout we hack that up? :) >>> >> >> Sound's interesting ;-) >> Could you tell me more detail about your idea? >> >> > [-- Attachment #2 --] diff --git a/sys/dev/ixgbe/ixgbe.c b/sys/dev/ixgbe/ixgbe.c index b65df72..beb3366 100644 --- a/sys/dev/ixgbe/ixgbe.c +++ b/sys/dev/ixgbe/ixgbe.c @@ -35,7 +35,9 @@ #include "opt_inet.h" #include "opt_inet6.h" + #include "ixgbe.h" +#include "ixgbe_ioctl.h" /********************************************************************* * Set this to one to display debug statistics @@ -200,7 +202,9 @@ static void ixgbe_handle_msf(void *, int); 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 @@ -224,6 +228,19 @@ static driver_t ixgbe_driver = { "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); @@ -317,6 +334,7 @@ static bool ixgbe_rsc_enable = FALSE; static int ixgbe_total_ports; #ifdef IXGBE_FDIR +#ifdef IXGBE_FDIR_ATR /* ** For Flow Director: this is the ** number of TX packets we sample @@ -327,6 +345,7 @@ static int ixgbe_total_ports; ** setting this to 0. */ static int atr_sample_rate = 20; +#endif /* ** Flow Director actually 'steals' ** part of the packet buffer as its @@ -401,6 +420,20 @@ ixgbe_probe(device_t dev) 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 * @@ -604,6 +637,11 @@ ixgbe_attach(device_t dev) #ifdef DEV_NETMAP ixgbe_netmap_attach(adapter); #endif /* DEV_NETMAP */ + + error = ixgbe_makedev(adapter); + if (error) + goto err_late; + INIT_DEBUGOUT("ixgbe_attach: end"); return (0); err_late: @@ -1812,7 +1850,7 @@ retry: return (error); } -#ifdef IXGBE_FDIR +#ifdef IXGBE_FDIR_ATR /* Do the flow director magic */ if ((txr->atr_sample) && (!adapter->fdir_reinit)) { ++txr->atr_count; @@ -3059,7 +3097,7 @@ ixgbe_setup_transmit_ring(struct tx_ring *txr) 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; @@ -3479,7 +3517,7 @@ ixgbe_tso_setup(struct tx_ring *txr, struct mbuf *mp, 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 @@ -5270,13 +5308,33 @@ ixgbe_update_stats_counters(struct adapter *adapter) 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 */ @@ -5642,6 +5700,32 @@ ixgbe_add_hw_stats(struct adapter *adapter) 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, + ""); } /* @@ -5803,3 +5887,83 @@ ixgbe_disable_rx_drop(struct adapter *adapter) IXGBE_WRITE_REG(hw, IXGBE_SRRCTL(i), srrctl); } } + +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 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; + + if (priv_check(td, PRIV_DRIVER)) { + return (EPERM); + } + + switch (cmd) { + case IXGBE_ADD_SIGFILTER: { + struct ix_filter *filter = (struct ix_filter *)data; + 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: + return (EINVAL); + } + 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; + + ixgbe_fdir_add_signature_filter_82599(&adapter->hw, + input, common, filter->que_index); + break; + } + case IXGBE_CLR_SIGFILTER: { + struct ix_filter *filter = (struct ix_filter *)data; + 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: + return (EINVAL); + } + 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; + + ixgbe_fdir_erase_signature_filter_82599(&adapter->hw, + input, common); + break; + } + default: + return (EOPNOTSUPP); + break; + } + + return (0); +} + diff --git a/sys/dev/ixgbe/ixgbe.h b/sys/dev/ixgbe/ixgbe.h index 77b72ed..49c41f2 100644 --- a/sys/dev/ixgbe/ixgbe.h +++ b/sys/dev/ixgbe/ixgbe.h @@ -88,6 +88,8 @@ #include <sys/pcpu.h> #include <sys/smp.h> #include <machine/smp.h> +#include <sys/conf.h> +#include <sys/priv.h> #include "ixgbe_api.h" @@ -468,6 +470,8 @@ struct adapter { unsigned long link_irq; struct ixgbe_hw_stats stats; + + struct cdev *cdev; }; diff --git a/sys/dev/ixgbe/ixgbe_82599.c b/sys/dev/ixgbe/ixgbe_82599.c index 3cc8cd7..72ea5ea 100644 --- a/sys/dev/ixgbe/ixgbe_82599.c +++ b/sys/dev/ixgbe/ixgbe_82599.c @@ -1482,7 +1482,8 @@ s32 ixgbe_init_fdir_signature_82599(struct ixgbe_hw *hw, u32 fdirctrl) * 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 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, 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); \ diff --git a/sys/dev/ixgbe/ixgbe_api.h b/sys/dev/ixgbe/ixgbe_api.h index 91023ae..77c6427 100644 --- a/sys/dev/ixgbe/ixgbe_api.h +++ b/sys/dev/ixgbe/ixgbe_api.h @@ -144,6 +144,9 @@ s32 ixgbe_fdir_add_signature_filter_82599(struct ixgbe_hw *hw, 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, diff --git a/sys/dev/ixgbe/ixgbe_ioctl.h b/sys/dev/ixgbe/ixgbe_ioctl.h new file mode 100644 index 0000000..f7113d3 --- /dev/null +++ b/sys/dev/ixgbe/ixgbe_ioctl.h @@ -0,0 +1,58 @@ +/************************************************************************** + +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_CLR_SIGFILTER +}; + +enum { + IXGBE_FILTER_PROTO_TCPV4, + IXGBE_FILTER_PROTO_UDPV4 +}; + +struct ix_filter { + 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_CLR_SIGFILTER _IOW('i', IX_CLR_SIGFILTER, struct ix_filter) + +#endif + diff --git a/sys/dev/ixgbe/ixgbe_type.h b/sys/dev/ixgbe/ixgbe_type.h index 49f5bc0..c5f29bb 100644 --- a/sys/dev/ixgbe/ixgbe_type.h +++ b/sys/dev/ixgbe/ixgbe_type.h @@ -2997,6 +2997,8 @@ struct ixgbe_hw_stats { u64 qbtc[16]; u64 qprdc[16]; u64 pxon2offc[8]; + u64 fdirfree_free; + u64 fdirfree_coll; u64 fdirustat_add; u64 fdirustat_remove; u64 fdirfstat_fadd; diff --git a/tools/tools/ixgbetool/Makefile b/tools/tools/ixgbetool/Makefile new file mode 100644 index 0000000..0695e93 --- /dev/null +++ b/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> diff --git a/tools/tools/ixgbetool/ixgbetool.c b/tools/tools/ixgbetool/ixgbetool.c new file mode 100644 index 0000000..d1911a5 --- /dev/null +++ b/tools/tools/ixgbetool/ixgbetool.c @@ -0,0 +1,174 @@ +/************************************************************************** + +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, "\tdel_sig_filter <proto> <src_ip> <src_port> <dst_ip> <dst_port>\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 int +del_sig_filter(int argc, char *argv[], char *ifname) +{ + struct ix_filter filter; + int error; + + if (argc != 8) + 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; + + error = doit(ifname, IXGBE_CLR_SIGFILTER, (void *)&filter); + 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], "del_sig_filter")) + ret = del_sig_filter(argc, argv, ifname); + else + ret = -1; + + if (ret) + usage(); + + return (ret); +} +
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CALG4x-Xf27oEOA9K5j%2BRRndFe1VbDowpTti8a8qwu1mRaB4BkQ>
