diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/core/ethtool.c | 34 |
1 files changed, 34 insertions, 0 deletions
diff --git a/net/core/ethtool.c b/net/core/ethtool.c index 248c25c3e820..91ffce20c36b 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c | |||
@@ -485,6 +485,38 @@ static void __rx_ntuple_filter_add(struct ethtool_rx_ntuple_list *list, | |||
485 | list->count++; | 485 | list->count++; |
486 | } | 486 | } |
487 | 487 | ||
488 | /* | ||
489 | * ethtool does not (or did not) set masks for flow parameters that are | ||
490 | * not specified, so if both value and mask are 0 then this must be | ||
491 | * treated as equivalent to a mask with all bits set. Implement that | ||
492 | * here rather than in drivers. | ||
493 | */ | ||
494 | static void rx_ntuple_fix_masks(struct ethtool_rx_ntuple_flow_spec *fs) | ||
495 | { | ||
496 | struct ethtool_tcpip4_spec *entry = &fs->h_u.tcp_ip4_spec; | ||
497 | struct ethtool_tcpip4_spec *mask = &fs->m_u.tcp_ip4_spec; | ||
498 | |||
499 | if (fs->flow_type != TCP_V4_FLOW && | ||
500 | fs->flow_type != UDP_V4_FLOW && | ||
501 | fs->flow_type != SCTP_V4_FLOW) | ||
502 | return; | ||
503 | |||
504 | if (!(entry->ip4src | mask->ip4src)) | ||
505 | mask->ip4src = htonl(0xffffffff); | ||
506 | if (!(entry->ip4dst | mask->ip4dst)) | ||
507 | mask->ip4dst = htonl(0xffffffff); | ||
508 | if (!(entry->psrc | mask->psrc)) | ||
509 | mask->psrc = htons(0xffff); | ||
510 | if (!(entry->pdst | mask->pdst)) | ||
511 | mask->pdst = htons(0xffff); | ||
512 | if (!(entry->tos | mask->tos)) | ||
513 | mask->tos = 0xff; | ||
514 | if (!(fs->vlan_tag | fs->vlan_tag_mask)) | ||
515 | fs->vlan_tag_mask = 0xffff; | ||
516 | if (!(fs->data | fs->data_mask)) | ||
517 | fs->data_mask = 0xffffffffffffffffULL; | ||
518 | } | ||
519 | |||
488 | static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, | 520 | static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, |
489 | void __user *useraddr) | 521 | void __user *useraddr) |
490 | { | 522 | { |
@@ -499,6 +531,8 @@ static noinline_for_stack int ethtool_set_rx_ntuple(struct net_device *dev, | |||
499 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) | 531 | if (copy_from_user(&cmd, useraddr, sizeof(cmd))) |
500 | return -EFAULT; | 532 | return -EFAULT; |
501 | 533 | ||
534 | rx_ntuple_fix_masks(&cmd.fs); | ||
535 | |||
502 | /* | 536 | /* |
503 | * Cache filter in dev struct for GET operation only if | 537 | * Cache filter in dev struct for GET operation only if |
504 | * the underlying driver doesn't have its own GET operation, and | 538 | * the underlying driver doesn't have its own GET operation, and |