Loading include/linux/ethtool.h +83 −6 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ * Portions Copyright 2002 Intel (eli.kupermann@intel.com, * christopher.leech@intel.com, * scott.feldman@intel.com) * Portions Copyright (C) Sun Microsystems 2008 */ #ifndef _LINUX_ETHTOOL_H Loading Loading @@ -287,10 +288,75 @@ enum ethtool_flags { ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ }; /* The following structures are for supporting RX network flow * classification configuration. Note, all multibyte fields, e.g., * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network * byte order. */ struct ethtool_tcpip4_spec { __be32 ip4src; __be32 ip4dst; __be16 psrc; __be16 pdst; __u8 tos; }; struct ethtool_ah_espip4_spec { __be32 ip4src; __be32 ip4dst; __be32 spi; __u8 tos; }; struct ethtool_rawip4_spec { __be32 ip4src; __be32 ip4dst; __u8 hdata[64]; }; struct ethtool_ether_spec { __be16 ether_type; __u8 frame_size; __u8 eframe[16]; }; #define ETH_RX_NFC_IP4 1 #define ETH_RX_NFC_IP6 2 struct ethtool_usrip4_spec { __be32 ip4src; __be32 ip4dst; __be32 l4_4_bytes; __u8 tos; __u8 ip_ver; __u8 proto; }; struct ethtool_rx_flow_spec { __u32 flow_type; union { struct ethtool_tcpip4_spec tcp_ip4_spec; struct ethtool_tcpip4_spec udp_ip4_spec; struct ethtool_tcpip4_spec sctp_ip4_spec; struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; struct ethtool_rawip4_spec raw_ip4_spec; struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; __u8 hdata[64]; } h_u, m_u; /* entry, mask */ __u64 ring_cookie; __u32 location; }; struct ethtool_rxnfc { __u32 cmd; __u32 flow_type; /* The rx flow hash value or the rule DB size */ __u64 data; struct ethtool_rx_flow_spec fs; __u32 rule_cnt; __u32 rule_locs[0]; }; #ifdef __KERNEL__ Loading Loading @@ -417,8 +483,8 @@ struct ethtool_ops { /* the following hooks are obsolete */ int (*self_test_count)(struct net_device *);/* use get_sset_count */ int (*get_stats_count)(struct net_device *);/* use get_sset_count */ int (*get_rxhash)(struct net_device *, struct ethtool_rxnfc *); int (*set_rxhash)(struct net_device *, struct ethtool_rxnfc *); int (*get_rxnfc)(struct net_device *, struct ethtool_rxnfc *, void *); int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *); }; #endif /* __KERNEL__ */ Loading Loading @@ -469,6 +535,12 @@ struct ethtool_ops { #define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */ #define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */ #define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */ #define ETHTOOL_GRXRINGS 0x0000002d /* Get RX rings available for LB */ #define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */ #define ETHTOOL_GRXCLSRULE 0x0000002f /* Get RX classification rule */ #define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */ #define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */ #define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET Loading Loading @@ -565,9 +637,13 @@ struct ethtool_ops { #define UDP_V6_FLOW 0x06 #define SCTP_V6_FLOW 0x07 #define AH_ESP_V6_FLOW 0x08 #define AH_V4_FLOW 0x09 #define ESP_V4_FLOW 0x0a #define AH_V6_FLOW 0x0b #define ESP_V6_FLOW 0x0c #define IP_USER_FLOW 0x0d /* L3-L4 network traffic flow hash options */ #define RXH_DEV_PORT (1 << 0) #define RXH_L2DA (1 << 1) #define RXH_VLAN (1 << 2) #define RXH_L3_PROTO (1 << 3) Loading @@ -577,5 +653,6 @@ struct ethtool_ops { #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ #define RXH_DISCARD (1 << 31) #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL #endif /* _LINUX_ETHTOOL_H */ net/core/ethtool.c +48 −10 Original line number Diff line number Diff line Loading @@ -209,34 +209,62 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) return 0; } static int ethtool_set_rxhash(struct net_device *dev, void __user *useraddr) static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc cmd; if (!dev->ethtool_ops->set_rxhash) if (!dev->ethtool_ops->set_rxnfc) return -EOPNOTSUPP; if (copy_from_user(&cmd, useraddr, sizeof(cmd))) return -EFAULT; return dev->ethtool_ops->set_rxhash(dev, &cmd); return dev->ethtool_ops->set_rxnfc(dev, &cmd); } static int ethtool_get_rxhash(struct net_device *dev, void __user *useraddr) static int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc info; const struct ethtool_ops *ops = dev->ethtool_ops; int ret; void *rule_buf = NULL; if (!dev->ethtool_ops->get_rxhash) if (!ops->get_rxnfc) return -EOPNOTSUPP; if (copy_from_user(&info, useraddr, sizeof(info))) return -EFAULT; dev->ethtool_ops->get_rxhash(dev, &info); if (info.cmd == ETHTOOL_GRXCLSRLALL) { if (info.rule_cnt > 0) { rule_buf = kmalloc(info.rule_cnt * sizeof(u32), GFP_USER); if (!rule_buf) return -ENOMEM; } } ret = ops->get_rxnfc(dev, &info, rule_buf); if (ret < 0) goto err_out; ret = -EFAULT; if (copy_to_user(useraddr, &info, sizeof(info))) return -EFAULT; return 0; goto err_out; if (rule_buf) { useraddr += offsetof(struct ethtool_rxnfc, rule_locs); if (copy_to_user(useraddr, rule_buf, info.rule_cnt * sizeof(u32))) goto err_out; } ret = 0; err_out: if (rule_buf) kfree(rule_buf); return ret; } static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) Loading Loading @@ -901,6 +929,10 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GFLAGS: case ETHTOOL_GPFLAGS: case ETHTOOL_GRXFH: case ETHTOOL_GRXRINGS: case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRULE: case ETHTOOL_GRXCLSRLALL: break; default: if (!capable(CAP_NET_ADMIN)) Loading Loading @@ -1052,10 +1084,16 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) dev->ethtool_ops->set_priv_flags); break; case ETHTOOL_GRXFH: rc = ethtool_get_rxhash(dev, useraddr); case ETHTOOL_GRXRINGS: case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRULE: case ETHTOOL_GRXCLSRLALL: rc = ethtool_get_rxnfc(dev, useraddr); break; case ETHTOOL_SRXFH: rc = ethtool_set_rxhash(dev, useraddr); case ETHTOOL_SRXCLSRLDEL: case ETHTOOL_SRXCLSRLINS: rc = ethtool_set_rxnfc(dev, useraddr); break; case ETHTOOL_GGRO: rc = ethtool_get_gro(dev, useraddr); Loading Loading
include/linux/ethtool.h +83 −6 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ * Portions Copyright 2002 Intel (eli.kupermann@intel.com, * christopher.leech@intel.com, * scott.feldman@intel.com) * Portions Copyright (C) Sun Microsystems 2008 */ #ifndef _LINUX_ETHTOOL_H Loading Loading @@ -287,10 +288,75 @@ enum ethtool_flags { ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ }; /* The following structures are for supporting RX network flow * classification configuration. Note, all multibyte fields, e.g., * ip4src, ip4dst, psrc, pdst, spi, etc. are expected to be in network * byte order. */ struct ethtool_tcpip4_spec { __be32 ip4src; __be32 ip4dst; __be16 psrc; __be16 pdst; __u8 tos; }; struct ethtool_ah_espip4_spec { __be32 ip4src; __be32 ip4dst; __be32 spi; __u8 tos; }; struct ethtool_rawip4_spec { __be32 ip4src; __be32 ip4dst; __u8 hdata[64]; }; struct ethtool_ether_spec { __be16 ether_type; __u8 frame_size; __u8 eframe[16]; }; #define ETH_RX_NFC_IP4 1 #define ETH_RX_NFC_IP6 2 struct ethtool_usrip4_spec { __be32 ip4src; __be32 ip4dst; __be32 l4_4_bytes; __u8 tos; __u8 ip_ver; __u8 proto; }; struct ethtool_rx_flow_spec { __u32 flow_type; union { struct ethtool_tcpip4_spec tcp_ip4_spec; struct ethtool_tcpip4_spec udp_ip4_spec; struct ethtool_tcpip4_spec sctp_ip4_spec; struct ethtool_ah_espip4_spec ah_ip4_spec; struct ethtool_ah_espip4_spec esp_ip4_spec; struct ethtool_rawip4_spec raw_ip4_spec; struct ethtool_ether_spec ether_spec; struct ethtool_usrip4_spec usr_ip4_spec; __u8 hdata[64]; } h_u, m_u; /* entry, mask */ __u64 ring_cookie; __u32 location; }; struct ethtool_rxnfc { __u32 cmd; __u32 flow_type; /* The rx flow hash value or the rule DB size */ __u64 data; struct ethtool_rx_flow_spec fs; __u32 rule_cnt; __u32 rule_locs[0]; }; #ifdef __KERNEL__ Loading Loading @@ -417,8 +483,8 @@ struct ethtool_ops { /* the following hooks are obsolete */ int (*self_test_count)(struct net_device *);/* use get_sset_count */ int (*get_stats_count)(struct net_device *);/* use get_sset_count */ int (*get_rxhash)(struct net_device *, struct ethtool_rxnfc *); int (*set_rxhash)(struct net_device *, struct ethtool_rxnfc *); int (*get_rxnfc)(struct net_device *, struct ethtool_rxnfc *, void *); int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *); }; #endif /* __KERNEL__ */ Loading Loading @@ -469,6 +535,12 @@ struct ethtool_ops { #define ETHTOOL_SRXFH 0x0000002a /* Set RX flow hash configuration */ #define ETHTOOL_GGRO 0x0000002b /* Get GRO enable (ethtool_value) */ #define ETHTOOL_SGRO 0x0000002c /* Set GRO enable (ethtool_value) */ #define ETHTOOL_GRXRINGS 0x0000002d /* Get RX rings available for LB */ #define ETHTOOL_GRXCLSRLCNT 0x0000002e /* Get RX class rule count */ #define ETHTOOL_GRXCLSRULE 0x0000002f /* Get RX classification rule */ #define ETHTOOL_GRXCLSRLALL 0x00000030 /* Get all RX classification rule */ #define ETHTOOL_SRXCLSRLDEL 0x00000031 /* Delete RX classification rule */ #define ETHTOOL_SRXCLSRLINS 0x00000032 /* Insert RX classification rule */ /* compatibility with older code */ #define SPARC_ETH_GSET ETHTOOL_GSET Loading Loading @@ -565,9 +637,13 @@ struct ethtool_ops { #define UDP_V6_FLOW 0x06 #define SCTP_V6_FLOW 0x07 #define AH_ESP_V6_FLOW 0x08 #define AH_V4_FLOW 0x09 #define ESP_V4_FLOW 0x0a #define AH_V6_FLOW 0x0b #define ESP_V6_FLOW 0x0c #define IP_USER_FLOW 0x0d /* L3-L4 network traffic flow hash options */ #define RXH_DEV_PORT (1 << 0) #define RXH_L2DA (1 << 1) #define RXH_VLAN (1 << 2) #define RXH_L3_PROTO (1 << 3) Loading @@ -577,5 +653,6 @@ struct ethtool_ops { #define RXH_L4_B_2_3 (1 << 7) /* dst port in case of TCP/UDP/SCTP */ #define RXH_DISCARD (1 << 31) #define RX_CLS_FLOW_DISC 0xffffffffffffffffULL #endif /* _LINUX_ETHTOOL_H */
net/core/ethtool.c +48 −10 Original line number Diff line number Diff line Loading @@ -209,34 +209,62 @@ static int ethtool_get_drvinfo(struct net_device *dev, void __user *useraddr) return 0; } static int ethtool_set_rxhash(struct net_device *dev, void __user *useraddr) static int ethtool_set_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc cmd; if (!dev->ethtool_ops->set_rxhash) if (!dev->ethtool_ops->set_rxnfc) return -EOPNOTSUPP; if (copy_from_user(&cmd, useraddr, sizeof(cmd))) return -EFAULT; return dev->ethtool_ops->set_rxhash(dev, &cmd); return dev->ethtool_ops->set_rxnfc(dev, &cmd); } static int ethtool_get_rxhash(struct net_device *dev, void __user *useraddr) static int ethtool_get_rxnfc(struct net_device *dev, void __user *useraddr) { struct ethtool_rxnfc info; const struct ethtool_ops *ops = dev->ethtool_ops; int ret; void *rule_buf = NULL; if (!dev->ethtool_ops->get_rxhash) if (!ops->get_rxnfc) return -EOPNOTSUPP; if (copy_from_user(&info, useraddr, sizeof(info))) return -EFAULT; dev->ethtool_ops->get_rxhash(dev, &info); if (info.cmd == ETHTOOL_GRXCLSRLALL) { if (info.rule_cnt > 0) { rule_buf = kmalloc(info.rule_cnt * sizeof(u32), GFP_USER); if (!rule_buf) return -ENOMEM; } } ret = ops->get_rxnfc(dev, &info, rule_buf); if (ret < 0) goto err_out; ret = -EFAULT; if (copy_to_user(useraddr, &info, sizeof(info))) return -EFAULT; return 0; goto err_out; if (rule_buf) { useraddr += offsetof(struct ethtool_rxnfc, rule_locs); if (copy_to_user(useraddr, rule_buf, info.rule_cnt * sizeof(u32))) goto err_out; } ret = 0; err_out: if (rule_buf) kfree(rule_buf); return ret; } static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) Loading Loading @@ -901,6 +929,10 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) case ETHTOOL_GFLAGS: case ETHTOOL_GPFLAGS: case ETHTOOL_GRXFH: case ETHTOOL_GRXRINGS: case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRULE: case ETHTOOL_GRXCLSRLALL: break; default: if (!capable(CAP_NET_ADMIN)) Loading Loading @@ -1052,10 +1084,16 @@ int dev_ethtool(struct net *net, struct ifreq *ifr) dev->ethtool_ops->set_priv_flags); break; case ETHTOOL_GRXFH: rc = ethtool_get_rxhash(dev, useraddr); case ETHTOOL_GRXRINGS: case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRULE: case ETHTOOL_GRXCLSRLALL: rc = ethtool_get_rxnfc(dev, useraddr); break; case ETHTOOL_SRXFH: rc = ethtool_set_rxhash(dev, useraddr); case ETHTOOL_SRXCLSRLDEL: case ETHTOOL_SRXCLSRLINS: rc = ethtool_set_rxnfc(dev, useraddr); break; case ETHTOOL_GGRO: rc = ethtool_get_gro(dev, useraddr); Loading