diff options
| -rw-r--r-- | include/linux/ethtool.h | 53 | ||||
| -rw-r--r-- | net/socket.c | 14 |
2 files changed, 39 insertions, 28 deletions
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index c04d1316d221..c7eff13d2f34 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h | |||
| @@ -380,27 +380,42 @@ struct ethtool_usrip4_spec { | |||
| 380 | __u8 proto; | 380 | __u8 proto; |
| 381 | }; | 381 | }; |
| 382 | 382 | ||
| 383 | union ethtool_flow_union { | ||
| 384 | struct ethtool_tcpip4_spec tcp_ip4_spec; | ||
| 385 | struct ethtool_tcpip4_spec udp_ip4_spec; | ||
| 386 | struct ethtool_tcpip4_spec sctp_ip4_spec; | ||
| 387 | struct ethtool_ah_espip4_spec ah_ip4_spec; | ||
| 388 | struct ethtool_ah_espip4_spec esp_ip4_spec; | ||
| 389 | struct ethtool_usrip4_spec usr_ip4_spec; | ||
| 390 | struct ethhdr ether_spec; | ||
| 391 | __u8 hdata[60]; | ||
| 392 | }; | ||
| 393 | |||
| 394 | struct ethtool_flow_ext { | ||
| 395 | __be16 vlan_etype; | ||
| 396 | __be16 vlan_tci; | ||
| 397 | __be32 data[2]; | ||
| 398 | }; | ||
| 399 | |||
| 383 | /** | 400 | /** |
| 384 | * struct ethtool_rx_flow_spec - specification for RX flow filter | 401 | * struct ethtool_rx_flow_spec - specification for RX flow filter |
| 385 | * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW | 402 | * @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW |
| 386 | * @h_u: Flow fields to match (dependent on @flow_type) | 403 | * @h_u: Flow fields to match (dependent on @flow_type) |
| 387 | * @m_u: Masks for flow field bits to be ignored | 404 | * @h_ext: Additional fields to match |
| 405 | * @m_u: Masks for flow field bits to be matched | ||
| 406 | * @m_ext: Masks for additional field bits to be matched | ||
| 407 | * Note, all additional fields must be ignored unless @flow_type | ||
| 408 | * includes the %FLOW_EXT flag. | ||
| 388 | * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC | 409 | * @ring_cookie: RX ring/queue index to deliver to, or %RX_CLS_FLOW_DISC |
| 389 | * if packets should be discarded | 410 | * if packets should be discarded |
| 390 | * @location: Index of filter in hardware table | 411 | * @location: Index of filter in hardware table |
| 391 | */ | 412 | */ |
| 392 | struct ethtool_rx_flow_spec { | 413 | struct ethtool_rx_flow_spec { |
| 393 | __u32 flow_type; | 414 | __u32 flow_type; |
| 394 | union { | 415 | union ethtool_flow_union h_u; |
| 395 | struct ethtool_tcpip4_spec tcp_ip4_spec; | 416 | struct ethtool_flow_ext h_ext; |
| 396 | struct ethtool_tcpip4_spec udp_ip4_spec; | 417 | union ethtool_flow_union m_u; |
| 397 | struct ethtool_tcpip4_spec sctp_ip4_spec; | 418 | struct ethtool_flow_ext m_ext; |
| 398 | struct ethtool_ah_espip4_spec ah_ip4_spec; | ||
| 399 | struct ethtool_ah_espip4_spec esp_ip4_spec; | ||
| 400 | struct ethtool_usrip4_spec usr_ip4_spec; | ||
| 401 | struct ethhdr ether_spec; | ||
| 402 | __u8 hdata[72]; | ||
| 403 | } h_u, m_u; | ||
| 404 | __u64 ring_cookie; | 419 | __u64 ring_cookie; |
| 405 | __u32 location; | 420 | __u32 location; |
| 406 | }; | 421 | }; |
| @@ -458,16 +473,10 @@ struct ethtool_rxnfc { | |||
| 458 | 473 | ||
| 459 | struct compat_ethtool_rx_flow_spec { | 474 | struct compat_ethtool_rx_flow_spec { |
| 460 | u32 flow_type; | 475 | u32 flow_type; |
| 461 | union { | 476 | union ethtool_flow_union h_u; |
| 462 | struct ethtool_tcpip4_spec tcp_ip4_spec; | 477 | struct ethtool_flow_ext h_ext; |
| 463 | struct ethtool_tcpip4_spec udp_ip4_spec; | 478 | union ethtool_flow_union m_u; |
| 464 | struct ethtool_tcpip4_spec sctp_ip4_spec; | 479 | struct ethtool_flow_ext m_ext; |
| 465 | struct ethtool_ah_espip4_spec ah_ip4_spec; | ||
| 466 | struct ethtool_ah_espip4_spec esp_ip4_spec; | ||
| 467 | struct ethtool_usrip4_spec usr_ip4_spec; | ||
| 468 | struct ethhdr ether_spec; | ||
| 469 | u8 hdata[72]; | ||
| 470 | } h_u, m_u; | ||
| 471 | compat_u64 ring_cookie; | 480 | compat_u64 ring_cookie; |
| 472 | u32 location; | 481 | u32 location; |
| 473 | }; | 482 | }; |
| @@ -1072,6 +1081,8 @@ struct ethtool_ops { | |||
| 1072 | #define IPV4_FLOW 0x10 /* hash only */ | 1081 | #define IPV4_FLOW 0x10 /* hash only */ |
| 1073 | #define IPV6_FLOW 0x11 /* hash only */ | 1082 | #define IPV6_FLOW 0x11 /* hash only */ |
| 1074 | #define ETHER_FLOW 0x12 /* spec only (ether_spec) */ | 1083 | #define ETHER_FLOW 0x12 /* spec only (ether_spec) */ |
| 1084 | /* Flag to enable additional fields in struct ethtool_rx_flow_spec */ | ||
| 1085 | #define FLOW_EXT 0x80000000 | ||
| 1075 | 1086 | ||
| 1076 | /* L3-L4 network traffic flow hash options */ | 1087 | /* L3-L4 network traffic flow hash options */ |
| 1077 | #define RXH_L2DA (1 << 1) | 1088 | #define RXH_L2DA (1 << 1) |
diff --git a/net/socket.c b/net/socket.c index 5212447c86e7..575c84f2af19 100644 --- a/net/socket.c +++ b/net/socket.c | |||
| @@ -2643,13 +2643,13 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) | |||
| 2643 | return -EFAULT; | 2643 | return -EFAULT; |
| 2644 | 2644 | ||
| 2645 | if (convert_in) { | 2645 | if (convert_in) { |
| 2646 | /* We expect there to be holes between fs.m_u and | 2646 | /* We expect there to be holes between fs.m_ext and |
| 2647 | * fs.ring_cookie and at the end of fs, but nowhere else. | 2647 | * fs.ring_cookie and at the end of fs, but nowhere else. |
| 2648 | */ | 2648 | */ |
| 2649 | BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_u) + | 2649 | BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + |
| 2650 | sizeof(compat_rxnfc->fs.m_u) != | 2650 | sizeof(compat_rxnfc->fs.m_ext) != |
| 2651 | offsetof(struct ethtool_rxnfc, fs.m_u) + | 2651 | offsetof(struct ethtool_rxnfc, fs.m_ext) + |
| 2652 | sizeof(rxnfc->fs.m_u)); | 2652 | sizeof(rxnfc->fs.m_ext)); |
| 2653 | BUILD_BUG_ON( | 2653 | BUILD_BUG_ON( |
| 2654 | offsetof(struct compat_ethtool_rxnfc, fs.location) - | 2654 | offsetof(struct compat_ethtool_rxnfc, fs.location) - |
| 2655 | offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != | 2655 | offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != |
| @@ -2657,7 +2657,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) | |||
| 2657 | offsetof(struct ethtool_rxnfc, fs.ring_cookie)); | 2657 | offsetof(struct ethtool_rxnfc, fs.ring_cookie)); |
| 2658 | 2658 | ||
| 2659 | if (copy_in_user(rxnfc, compat_rxnfc, | 2659 | if (copy_in_user(rxnfc, compat_rxnfc, |
| 2660 | (void *)(&rxnfc->fs.m_u + 1) - | 2660 | (void *)(&rxnfc->fs.m_ext + 1) - |
| 2661 | (void *)rxnfc) || | 2661 | (void *)rxnfc) || |
| 2662 | copy_in_user(&rxnfc->fs.ring_cookie, | 2662 | copy_in_user(&rxnfc->fs.ring_cookie, |
| 2663 | &compat_rxnfc->fs.ring_cookie, | 2663 | &compat_rxnfc->fs.ring_cookie, |
| @@ -2674,7 +2674,7 @@ static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) | |||
| 2674 | 2674 | ||
| 2675 | if (convert_out) { | 2675 | if (convert_out) { |
| 2676 | if (copy_in_user(compat_rxnfc, rxnfc, | 2676 | if (copy_in_user(compat_rxnfc, rxnfc, |
| 2677 | (const void *)(&rxnfc->fs.m_u + 1) - | 2677 | (const void *)(&rxnfc->fs.m_ext + 1) - |
| 2678 | (const void *)rxnfc) || | 2678 | (const void *)rxnfc) || |
| 2679 | copy_in_user(&compat_rxnfc->fs.ring_cookie, | 2679 | copy_in_user(&compat_rxnfc->fs.ring_cookie, |
| 2680 | &rxnfc->fs.ring_cookie, | 2680 | &rxnfc->fs.ring_cookie, |
