Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 203246
b: refs/heads/master
c: a5b6ee2
h: refs/heads/master
v: v3
  • Loading branch information
Ben Hutchings authored and David S. Miller committed Jun 30, 2010
1 parent d26dd4f commit 6d92a6a
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: cbf2d604a1cd77944a795bb8dbe844eaa38b44c8
refs/heads/master: a5b6ee291e39e285e021cf251dbcf770c83cd74e
15 changes: 15 additions & 0 deletions trunk/include/linux/ethtool.h
Original file line number Diff line number Diff line change
Expand Up @@ -384,6 +384,15 @@ struct ethtool_rxnfc {
__u32 rule_locs[0];
};

struct ethtool_rxfh_indir {
__u32 cmd;
/* On entry, this is the array size of the user buffer. On
* return from ETHTOOL_GRXFHINDIR, this is the array size of
* the hardware indirection table. */
__u32 size;
__u32 ring_index[0]; /* ring/queue index for each hash value */
};

struct ethtool_rx_ntuple_flow_spec {
__u32 flow_type;
union {
Expand Down Expand Up @@ -576,6 +585,10 @@ struct ethtool_ops {
int (*set_rx_ntuple)(struct net_device *,
struct ethtool_rx_ntuple *);
int (*get_rx_ntuple)(struct net_device *, u32 stringset, void *);
int (*get_rxfh_indir)(struct net_device *,
struct ethtool_rxfh_indir *);
int (*set_rxfh_indir)(struct net_device *,
const struct ethtool_rxfh_indir *);
};
#endif /* __KERNEL__ */

Expand Down Expand Up @@ -637,6 +650,8 @@ struct ethtool_ops {
#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
#define ETHTOOL_GSSET_INFO 0x00000037 /* Get string set info */
#define ETHTOOL_GRXFHINDIR 0x00000038 /* Get RX flow hash indir'n table */
#define ETHTOOL_SRXFHINDIR 0x00000039 /* Set RX flow hash indir'n table */

/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
Expand Down
80 changes: 80 additions & 0 deletions trunk/net/core/ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,80 @@ static noinline_for_stack int ethtool_get_rxnfc(struct net_device *dev,
return ret;
}

static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
void __user *useraddr)
{
struct ethtool_rxfh_indir *indir;
u32 table_size;
size_t full_size;
int ret;

if (!dev->ethtool_ops->get_rxfh_indir)
return -EOPNOTSUPP;

if (copy_from_user(&table_size,
useraddr + offsetof(struct ethtool_rxfh_indir, size),
sizeof(table_size)))
return -EFAULT;

if (table_size >
(KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index))
return -ENOMEM;
full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size;
indir = kmalloc(full_size, GFP_USER);
if (!indir)
return -ENOMEM;

indir->cmd = ETHTOOL_GRXFHINDIR;
indir->size = table_size;
ret = dev->ethtool_ops->get_rxfh_indir(dev, indir);
if (ret)
goto out;

if (copy_to_user(useraddr, indir, full_size))
ret = -EFAULT;

out:
kfree(indir);
return ret;
}

static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
void __user *useraddr)
{
struct ethtool_rxfh_indir *indir;
u32 table_size;
size_t full_size;
int ret;

if (!dev->ethtool_ops->set_rxfh_indir)
return -EOPNOTSUPP;

if (copy_from_user(&table_size,
useraddr + offsetof(struct ethtool_rxfh_indir, size),
sizeof(table_size)))
return -EFAULT;

if (table_size >
(KMALLOC_MAX_SIZE - sizeof(*indir)) / sizeof(*indir->ring_index))
return -ENOMEM;
full_size = sizeof(*indir) + sizeof(*indir->ring_index) * table_size;
indir = kmalloc(full_size, GFP_USER);
if (!indir)
return -ENOMEM;

if (copy_from_user(indir, useraddr, full_size)) {
ret = -EFAULT;
goto out;
}

ret = dev->ethtool_ops->set_rxfh_indir(dev, indir);

out:
kfree(indir);
return ret;
}

static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
struct ethtool_rx_ntuple_flow_spec *spec,
struct ethtool_rx_ntuple_flow_spec_container *fsc)
Expand Down Expand Up @@ -1526,6 +1600,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GSSET_INFO:
rc = ethtool_get_sset_info(dev, useraddr);
break;
case ETHTOOL_GRXFHINDIR:
rc = ethtool_get_rxfh_indir(dev, useraddr);
break;
case ETHTOOL_SRXFHINDIR:
rc = ethtool_set_rxfh_indir(dev, useraddr);
break;
default:
rc = -EOPNOTSUPP;
}
Expand Down

0 comments on commit 6d92a6a

Please sign in to comment.