aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/ethtool.h50
-rw-r--r--include/linux/netdevice.h3
-rw-r--r--net/core/dev.c5
-rw-r--r--net/core/ethtool.c329
4 files changed, 386 insertions, 1 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index ef4a2d84d922..a3cac53a0766 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -14,6 +14,7 @@
14#define _LINUX_ETHTOOL_H 14#define _LINUX_ETHTOOL_H
15 15
16#include <linux/types.h> 16#include <linux/types.h>
17#include <linux/rculist.h>
17 18
18/* This should work for both 32 and 64 bit userland. */ 19/* This should work for both 32 and 64 bit userland. */
19struct ethtool_cmd { 20struct ethtool_cmd {
@@ -242,6 +243,7 @@ enum ethtool_stringset {
242 ETH_SS_TEST = 0, 243 ETH_SS_TEST = 0,
243 ETH_SS_STATS, 244 ETH_SS_STATS,
244 ETH_SS_PRIV_FLAGS, 245 ETH_SS_PRIV_FLAGS,
246 ETH_SS_NTUPLE_FILTERS,
245}; 247};
246 248
247/* for passing string sets for data tagging */ 249/* for passing string sets for data tagging */
@@ -290,6 +292,7 @@ struct ethtool_perm_addr {
290 */ 292 */
291enum ethtool_flags { 293enum ethtool_flags {
292 ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */ 294 ETH_FLAG_LRO = (1 << 15), /* LRO is enabled */
295 ETH_FLAG_NTUPLE = (1 << 27), /* N-tuple filters enabled */
293}; 296};
294 297
295/* The following structures are for supporting RX network flow 298/* The following structures are for supporting RX network flow
@@ -363,6 +366,35 @@ struct ethtool_rxnfc {
363 __u32 rule_locs[0]; 366 __u32 rule_locs[0];
364}; 367};
365 368
369struct ethtool_rx_ntuple_flow_spec {
370 __u32 flow_type;
371 union {
372 struct ethtool_tcpip4_spec tcp_ip4_spec;
373 struct ethtool_tcpip4_spec udp_ip4_spec;
374 struct ethtool_tcpip4_spec sctp_ip4_spec;
375 struct ethtool_ah_espip4_spec ah_ip4_spec;
376 struct ethtool_ah_espip4_spec esp_ip4_spec;
377 struct ethtool_rawip4_spec raw_ip4_spec;
378 struct ethtool_ether_spec ether_spec;
379 struct ethtool_usrip4_spec usr_ip4_spec;
380 __u8 hdata[64];
381 } h_u, m_u; /* entry, mask */
382
383 __u16 vlan_tag;
384 __u16 vlan_tag_mask;
385 __u64 data; /* user-defined flow spec data */
386 __u64 data_mask; /* user-defined flow spec mask */
387
388 /* signed to distinguish between queue and actions (DROP) */
389 __s32 action;
390#define ETHTOOL_RXNTUPLE_ACTION_DROP -1
391};
392
393struct ethtool_rx_ntuple {
394 __u32 cmd;
395 struct ethtool_rx_ntuple_flow_spec fs;
396};
397
366#define ETHTOOL_FLASH_MAX_FILENAME 128 398#define ETHTOOL_FLASH_MAX_FILENAME 128
367enum ethtool_flash_op_type { 399enum ethtool_flash_op_type {
368 ETHTOOL_FLASH_ALL_REGIONS = 0, 400 ETHTOOL_FLASH_ALL_REGIONS = 0,
@@ -377,6 +409,18 @@ struct ethtool_flash {
377 409
378#ifdef __KERNEL__ 410#ifdef __KERNEL__
379 411
412struct ethtool_rx_ntuple_flow_spec_container {
413 struct ethtool_rx_ntuple_flow_spec fs;
414 struct list_head list;
415};
416
417struct ethtool_rx_ntuple_list {
418#define ETHTOOL_MAX_NTUPLE_LIST_ENTRY 1024
419#define ETHTOOL_MAX_NTUPLE_STRING_PER_ENTRY 14
420 struct list_head list;
421 unsigned int count;
422};
423
380struct net_device; 424struct net_device;
381 425
382/* Some generic methods drivers may use in their ethtool_ops */ 426/* Some generic methods drivers may use in their ethtool_ops */
@@ -394,6 +438,7 @@ u32 ethtool_op_get_ufo(struct net_device *dev);
394int ethtool_op_set_ufo(struct net_device *dev, u32 data); 438int ethtool_op_set_ufo(struct net_device *dev, u32 data);
395u32 ethtool_op_get_flags(struct net_device *dev); 439u32 ethtool_op_get_flags(struct net_device *dev);
396int ethtool_op_set_flags(struct net_device *dev, u32 data); 440int ethtool_op_set_flags(struct net_device *dev, u32 data);
441void ethtool_ntuple_flush(struct net_device *dev);
397 442
398/** 443/**
399 * &ethtool_ops - Alter and report network device settings 444 * &ethtool_ops - Alter and report network device settings
@@ -500,6 +545,8 @@ struct ethtool_ops {
500 int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *); 545 int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
501 int (*flash_device)(struct net_device *, struct ethtool_flash *); 546 int (*flash_device)(struct net_device *, struct ethtool_flash *);
502 int (*reset)(struct net_device *, u32 *); 547 int (*reset)(struct net_device *, u32 *);
548 int (*set_rx_ntuple)(struct net_device *, struct ethtool_rx_ntuple *);
549 int (*get_rx_ntuple)(struct net_device *, u32 stringset, void *);
503}; 550};
504#endif /* __KERNEL__ */ 551#endif /* __KERNEL__ */
505 552
@@ -559,6 +606,9 @@ struct ethtool_ops {
559#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */ 606#define ETHTOOL_FLASHDEV 0x00000033 /* Flash firmware to device */
560#define ETHTOOL_RESET 0x00000034 /* Reset hardware */ 607#define ETHTOOL_RESET 0x00000034 /* Reset hardware */
561 608
609#define ETHTOOL_SRXNTUPLE 0x00000035 /* Add an n-tuple filter to device */
610#define ETHTOOL_GRXNTUPLE 0x00000036 /* Get n-tuple filters from device */
611
562/* compatibility with older code */ 612/* compatibility with older code */
563#define SPARC_ETH_GSET ETHTOOL_GSET 613#define SPARC_ETH_GSET ETHTOOL_GSET
564#define SPARC_ETH_SSET ETHTOOL_SSET 614#define SPARC_ETH_SSET ETHTOOL_SSET
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index e535700a3b72..cdf53a8d9ff5 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -746,6 +746,7 @@ struct net_device {
746#define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */ 746#define NETIF_F_FCOE_CRC (1 << 24) /* FCoE CRC32 */
747#define NETIF_F_SCTP_CSUM (1 << 25) /* SCTP checksum offload */ 747#define NETIF_F_SCTP_CSUM (1 << 25) /* SCTP checksum offload */
748#define NETIF_F_FCOE_MTU (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/ 748#define NETIF_F_FCOE_MTU (1 << 26) /* Supports max FCoE MTU, 2158 bytes*/
749#define NETIF_F_NTUPLE (1 << 27) /* N-tuple filters supported */
749 750
750 /* Segmentation offload features */ 751 /* Segmentation offload features */
751#define NETIF_F_GSO_SHIFT 16 752#define NETIF_F_GSO_SHIFT 16
@@ -954,6 +955,8 @@ struct net_device {
954 /* max exchange id for FCoE LRO by ddp */ 955 /* max exchange id for FCoE LRO by ddp */
955 unsigned int fcoe_ddp_xid; 956 unsigned int fcoe_ddp_xid;
956#endif 957#endif
958 /* n-tuple filter list attached to this device */
959 struct ethtool_rx_ntuple_list ethtool_ntuple_list;
957}; 960};
958#define to_net_dev(d) container_of(d, struct net_device, dev) 961#define to_net_dev(d) container_of(d, struct net_device, dev)
959 962
diff --git a/net/core/dev.c b/net/core/dev.c
index 94c1eeed25e5..ae75f25ac0a5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5419,6 +5419,8 @@ struct net_device *alloc_netdev_mq(int sizeof_priv, const char *name,
5419 5419
5420 netdev_init_queues(dev); 5420 netdev_init_queues(dev);
5421 5421
5422 INIT_LIST_HEAD(&dev->ethtool_ntuple_list.list);
5423 dev->ethtool_ntuple_list.count = 0;
5422 INIT_LIST_HEAD(&dev->napi_list); 5424 INIT_LIST_HEAD(&dev->napi_list);
5423 INIT_LIST_HEAD(&dev->unreg_list); 5425 INIT_LIST_HEAD(&dev->unreg_list);
5424 INIT_LIST_HEAD(&dev->link_watch_list); 5426 INIT_LIST_HEAD(&dev->link_watch_list);
@@ -5455,6 +5457,9 @@ void free_netdev(struct net_device *dev)
5455 /* Flush device addresses */ 5457 /* Flush device addresses */
5456 dev_addr_flush(dev); 5458 dev_addr_flush(dev);
5457 5459
5460 /* Clear ethtool n-tuple list */
5461 ethtool_ntuple_flush(dev);
5462
5458 list_for_each_entry_safe(p, n, &dev->napi_list, dev_list) 5463 list_for_each_entry_safe(p, n, &dev->napi_list, dev_list)
5459 netif_napi_del(p); 5464 netif_napi_del(p);
5460 5465
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index d8aee584e8d1..6ec73d3983a3 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -120,7 +120,7 @@ int ethtool_op_set_ufo(struct net_device *dev, u32 data)
120 * NETIF_F_xxx values in include/linux/netdevice.h 120 * NETIF_F_xxx values in include/linux/netdevice.h
121 */ 121 */
122static const u32 flags_dup_features = 122static const u32 flags_dup_features =
123 ETH_FLAG_LRO; 123 (ETH_FLAG_LRO | ETH_FLAG_NTUPLE);
124 124
125u32 ethtool_op_get_flags(struct net_device *dev) 125u32 ethtool_op_get_flags(struct net_device *dev)
126{ 126{
@@ -139,9 +139,26 @@ int ethtool_op_set_flags(struct net_device *dev, u32 data)
139 else 139 else
140 dev->features &= ~NETIF_F_LRO; 140 dev->features &= ~NETIF_F_LRO;
141 141
142 if (data & ETH_FLAG_NTUPLE)
143 dev->features |= NETIF_F_NTUPLE;
144 else
145 dev->features &= ~NETIF_F_NTUPLE;
146
142 return 0; 147 return 0;
143} 148}
144 149
150void ethtool_ntuple_flush(struct net_device *dev)
151{
152 struct ethtool_rx_ntuple_flow_spec_container *fsc, *f;
153
154 list_for_each_entry_safe(fsc, f, &dev->ethtool_ntuple_list.list, list) {
155 list_del(&fsc->list);
156 kfree(fsc);
157 }
158 dev->ethtool_ntuple_list.count = 0;
159}
160EXPORT_SYMBOL(ethtool_ntuple_flush);
161
145/* Handlers for each ethtool command */ 162/* Handlers for each ethtool command */
146 163
147static int ethtool_get_settings(struct net_device *dev, void __user *useraddr) 164static int ethtool_get_settings(struct net_device *dev, void __user *useraddr)
@@ -266,6 +283,307 @@ err_out:
266 return ret; 283 return ret;
267} 284}
268 285
286static int __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list,
287 struct ethtool_rx_ntuple_flow_spec *spec)
288{
289 struct ethtool_rx_ntuple_flow_spec_container *fsc;
290
291 /* don't add filters forever */
292 if (list->count >= ETHTOOL_MAX_NTUPLE_LIST_ENTRY)
293 return 0;
294
295 fsc = kmalloc(sizeof(*fsc), GFP_ATOMIC);
296 if (!fsc)
297 return -ENOMEM;
298
299 /* Copy the whole filter over */
300 fsc->fs.flow_type = spec->flow_type;
301 memcpy(&fsc->fs.h_u, &spec->h_u, sizeof(spec->h_u));
302 memcpy(&fsc->fs.m_u, &spec->m_u, sizeof(spec->m_u));
303
304 fsc->fs.vlan_tag = spec->vlan_tag;
305 fsc->fs.vlan_tag_mask = spec->vlan_tag_mask;
306 fsc->fs.data = spec->data;
307 fsc->fs.data_mask = spec->data_mask;
308 fsc->fs.action = spec->action;
309
310 /* add to the list */
311 list_add_tail_rcu(&fsc->list, &list->list);
312 list->count++;
313
314 return 0;
315}
316
317static int ethtool_set_rx_ntuple(struct net_device *dev, void __user *useraddr)
318{
319 struct ethtool_rx_ntuple cmd;
320 const struct ethtool_ops *ops = dev->ethtool_ops;
321 int ret;
322
323 if (!ops->set_rx_ntuple)
324 return -EOPNOTSUPP;
325
326 if (!(dev->features & NETIF_F_NTUPLE))
327 return -EINVAL;
328
329 if (copy_from_user(&cmd, useraddr, sizeof(cmd)))
330 return -EFAULT;
331
332 ret = ops->set_rx_ntuple(dev, &cmd);
333
334 /*
335 * Cache filter in dev struct for GET operation only if
336 * the underlying driver doesn't have its own GET operation, and
337 * only if the filter was added successfully.
338 */
339 if (!ops->get_rx_ntuple && !ret)
340 if (__rx_ntuple_filter_add(&dev->ethtool_ntuple_list, &cmd.fs))
341 return -ENOMEM;
342
343 return ret;
344}
345
346static int ethtool_get_rx_ntuple(struct net_device *dev, void __user *useraddr)
347{
348 struct ethtool_gstrings gstrings;
349 const struct ethtool_ops *ops = dev->ethtool_ops;
350 struct ethtool_rx_ntuple_flow_spec_container *fsc;
351 u8 *data;
352 char *p;
353 int ret, i, num_strings = 0;
354
355 if (!ops->get_sset_count)
356 return -EOPNOTSUPP;
357
358 if (copy_from_user(&gstrings, useraddr, sizeof(gstrings)))
359 return -EFAULT;
360
361 ret = ops->get_sset_count(dev, gstrings.string_set);
362 if (ret < 0)
363 return ret;
364
365 gstrings.len = ret;
366
367 data = kmalloc(gstrings.len * ETH_GSTRING_LEN, GFP_USER);
368 if (!data)
369 return -ENOMEM;
370
371 if (ops->get_rx_ntuple) {
372 /* driver-specific filter grab */
373 ret = ops->get_rx_ntuple(dev, gstrings.string_set, data);
374 goto copy;
375 }
376
377 /* default ethtool filter grab */
378 i = 0;
379 p = (char *)data;
380 list_for_each_entry(fsc, &dev->ethtool_ntuple_list.list, list) {
381 sprintf(p, "Filter %d:\n", i);
382 p += ETH_GSTRING_LEN;
383 num_strings++;
384
385 switch (fsc->fs.flow_type) {
386 case TCP_V4_FLOW:
387 sprintf(p, "\tFlow Type: TCP\n");
388 p += ETH_GSTRING_LEN;
389 num_strings++;
390 break;
391 case UDP_V4_FLOW:
392 sprintf(p, "\tFlow Type: UDP\n");
393 p += ETH_GSTRING_LEN;
394 num_strings++;
395 break;
396 case SCTP_V4_FLOW:
397 sprintf(p, "\tFlow Type: SCTP\n");
398 p += ETH_GSTRING_LEN;
399 num_strings++;
400 break;
401 case AH_ESP_V4_FLOW:
402 sprintf(p, "\tFlow Type: AH ESP\n");
403 p += ETH_GSTRING_LEN;
404 num_strings++;
405 break;
406 case ESP_V4_FLOW:
407 sprintf(p, "\tFlow Type: ESP\n");
408 p += ETH_GSTRING_LEN;
409 num_strings++;
410 break;
411 case IP_USER_FLOW:
412 sprintf(p, "\tFlow Type: Raw IP\n");
413 p += ETH_GSTRING_LEN;
414 num_strings++;
415 break;
416 case IPV4_FLOW:
417 sprintf(p, "\tFlow Type: IPv4\n");
418 p += ETH_GSTRING_LEN;
419 num_strings++;
420 break;
421 default:
422 sprintf(p, "\tFlow Type: Unknown\n");
423 p += ETH_GSTRING_LEN;
424 num_strings++;
425 goto unknown_filter;
426 };
427
428 /* now the rest of the filters */
429 switch (fsc->fs.flow_type) {
430 case TCP_V4_FLOW:
431 case UDP_V4_FLOW:
432 case SCTP_V4_FLOW:
433 sprintf(p, "\tSrc IP addr: 0x%x\n",
434 fsc->fs.h_u.tcp_ip4_spec.ip4src);
435 p += ETH_GSTRING_LEN;
436 num_strings++;
437 sprintf(p, "\tSrc IP mask: 0x%x\n",
438 fsc->fs.m_u.tcp_ip4_spec.ip4src);
439 p += ETH_GSTRING_LEN;
440 num_strings++;
441 sprintf(p, "\tDest IP addr: 0x%x\n",
442 fsc->fs.h_u.tcp_ip4_spec.ip4dst);
443 p += ETH_GSTRING_LEN;
444 num_strings++;
445 sprintf(p, "\tDest IP mask: 0x%x\n",
446 fsc->fs.m_u.tcp_ip4_spec.ip4dst);
447 p += ETH_GSTRING_LEN;
448 num_strings++;
449 sprintf(p, "\tSrc Port: %d, mask: 0x%x\n",
450 fsc->fs.h_u.tcp_ip4_spec.psrc,
451 fsc->fs.m_u.tcp_ip4_spec.psrc);
452 p += ETH_GSTRING_LEN;
453 num_strings++;
454 sprintf(p, "\tDest Port: %d, mask: 0x%x\n",
455 fsc->fs.h_u.tcp_ip4_spec.pdst,
456 fsc->fs.m_u.tcp_ip4_spec.pdst);
457 p += ETH_GSTRING_LEN;
458 num_strings++;
459 sprintf(p, "\tTOS: %d, mask: 0x%x\n",
460 fsc->fs.h_u.tcp_ip4_spec.tos,
461 fsc->fs.m_u.tcp_ip4_spec.tos);
462 p += ETH_GSTRING_LEN;
463 num_strings++;
464 break;
465 case AH_ESP_V4_FLOW:
466 case ESP_V4_FLOW:
467 sprintf(p, "\tSrc IP addr: 0x%x\n",
468 fsc->fs.h_u.ah_ip4_spec.ip4src);
469 p += ETH_GSTRING_LEN;
470 num_strings++;
471 sprintf(p, "\tSrc IP mask: 0x%x\n",
472 fsc->fs.m_u.ah_ip4_spec.ip4src);
473 p += ETH_GSTRING_LEN;
474 num_strings++;
475 sprintf(p, "\tDest IP addr: 0x%x\n",
476 fsc->fs.h_u.ah_ip4_spec.ip4dst);
477 p += ETH_GSTRING_LEN;
478 num_strings++;
479 sprintf(p, "\tDest IP mask: 0x%x\n",
480 fsc->fs.m_u.ah_ip4_spec.ip4dst);
481 p += ETH_GSTRING_LEN;
482 num_strings++;
483 sprintf(p, "\tSPI: %d, mask: 0x%x\n",
484 fsc->fs.h_u.ah_ip4_spec.spi,
485 fsc->fs.m_u.ah_ip4_spec.spi);
486 p += ETH_GSTRING_LEN;
487 num_strings++;
488 sprintf(p, "\tTOS: %d, mask: 0x%x\n",
489 fsc->fs.h_u.ah_ip4_spec.tos,
490 fsc->fs.m_u.ah_ip4_spec.tos);
491 p += ETH_GSTRING_LEN;
492 num_strings++;
493 break;
494 case IP_USER_FLOW:
495 sprintf(p, "\tSrc IP addr: 0x%x\n",
496 fsc->fs.h_u.raw_ip4_spec.ip4src);
497 p += ETH_GSTRING_LEN;
498 num_strings++;
499 sprintf(p, "\tSrc IP mask: 0x%x\n",
500 fsc->fs.m_u.raw_ip4_spec.ip4src);
501 p += ETH_GSTRING_LEN;
502 num_strings++;
503 sprintf(p, "\tDest IP addr: 0x%x\n",
504 fsc->fs.h_u.raw_ip4_spec.ip4dst);
505 p += ETH_GSTRING_LEN;
506 num_strings++;
507 sprintf(p, "\tDest IP mask: 0x%x\n",
508 fsc->fs.m_u.raw_ip4_spec.ip4dst);
509 p += ETH_GSTRING_LEN;
510 num_strings++;
511 break;
512 case IPV4_FLOW:
513 sprintf(p, "\tSrc IP addr: 0x%x\n",
514 fsc->fs.h_u.usr_ip4_spec.ip4src);
515 p += ETH_GSTRING_LEN;
516 num_strings++;
517 sprintf(p, "\tSrc IP mask: 0x%x\n",
518 fsc->fs.m_u.usr_ip4_spec.ip4src);
519 p += ETH_GSTRING_LEN;
520 num_strings++;
521 sprintf(p, "\tDest IP addr: 0x%x\n",
522 fsc->fs.h_u.usr_ip4_spec.ip4dst);
523 p += ETH_GSTRING_LEN;
524 num_strings++;
525 sprintf(p, "\tDest IP mask: 0x%x\n",
526 fsc->fs.m_u.usr_ip4_spec.ip4dst);
527 p += ETH_GSTRING_LEN;
528 num_strings++;
529 sprintf(p, "\tL4 bytes: 0x%x, mask: 0x%x\n",
530 fsc->fs.h_u.usr_ip4_spec.l4_4_bytes,
531 fsc->fs.m_u.usr_ip4_spec.l4_4_bytes);
532 p += ETH_GSTRING_LEN;
533 num_strings++;
534 sprintf(p, "\tTOS: %d, mask: 0x%x\n",
535 fsc->fs.h_u.usr_ip4_spec.tos,
536 fsc->fs.m_u.usr_ip4_spec.tos);
537 p += ETH_GSTRING_LEN;
538 num_strings++;
539 sprintf(p, "\tIP Version: %d, mask: 0x%x\n",
540 fsc->fs.h_u.usr_ip4_spec.ip_ver,
541 fsc->fs.m_u.usr_ip4_spec.ip_ver);
542 p += ETH_GSTRING_LEN;
543 num_strings++;
544 sprintf(p, "\tProtocol: %d, mask: 0x%x\n",
545 fsc->fs.h_u.usr_ip4_spec.proto,
546 fsc->fs.m_u.usr_ip4_spec.proto);
547 p += ETH_GSTRING_LEN;
548 num_strings++;
549 break;
550 };
551 sprintf(p, "\tVLAN: %d, mask: 0x%x\n",
552 fsc->fs.vlan_tag, fsc->fs.vlan_tag_mask);
553 p += ETH_GSTRING_LEN;
554 num_strings++;
555 sprintf(p, "\tUser-defined: 0x%Lx\n", fsc->fs.data);
556 p += ETH_GSTRING_LEN;
557 num_strings++;
558 sprintf(p, "\tUser-defined mask: 0x%Lx\n", fsc->fs.data_mask);
559 p += ETH_GSTRING_LEN;
560 num_strings++;
561 if (fsc->fs.action == ETHTOOL_RXNTUPLE_ACTION_DROP)
562 sprintf(p, "\tAction: Drop\n");
563 else
564 sprintf(p, "\tAction: Direct to queue %d\n",
565 fsc->fs.action);
566 p += ETH_GSTRING_LEN;
567 num_strings++;
568unknown_filter:
569 i++;
570 }
571copy:
572 /* indicate to userspace how many strings we actually have */
573 gstrings.len = num_strings;
574 ret = -EFAULT;
575 if (copy_to_user(useraddr, &gstrings, sizeof(gstrings)))
576 goto out;
577 useraddr += sizeof(gstrings);
578 if (copy_to_user(useraddr, data, gstrings.len * ETH_GSTRING_LEN))
579 goto out;
580 ret = 0;
581
582out:
583 kfree(data);
584 return ret;
585}
586
269static int ethtool_get_regs(struct net_device *dev, char __user *useraddr) 587static int ethtool_get_regs(struct net_device *dev, char __user *useraddr)
270{ 588{
271 struct ethtool_regs regs; 589 struct ethtool_regs regs;
@@ -313,6 +631,9 @@ static int ethtool_reset(struct net_device *dev, char __user *useraddr)
313 if (copy_from_user(&reset, useraddr, sizeof(reset))) 631 if (copy_from_user(&reset, useraddr, sizeof(reset)))
314 return -EFAULT; 632 return -EFAULT;
315 633
634 /* Clear ethtool n-tuple list */
635 ethtool_ntuple_flush(dev);
636
316 ret = dev->ethtool_ops->reset(dev, &reset.data); 637 ret = dev->ethtool_ops->reset(dev, &reset.data);
317 if (ret) 638 if (ret)
318 return ret; 639 return ret;
@@ -1112,6 +1433,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
1112 case ETHTOOL_RESET: 1433 case ETHTOOL_RESET:
1113 rc = ethtool_reset(dev, useraddr); 1434 rc = ethtool_reset(dev, useraddr);
1114 break; 1435 break;
1436 case ETHTOOL_SRXNTUPLE:
1437 rc = ethtool_set_rx_ntuple(dev, useraddr);
1438 break;
1439 case ETHTOOL_GRXNTUPLE:
1440 rc = ethtool_get_rx_ntuple(dev, useraddr);
1441 break;
1115 default: 1442 default:
1116 rc = -EOPNOTSUPP; 1443 rc = -EOPNOTSUPP;
1117 } 1444 }