diff options
Diffstat (limited to 'net/core/dev.c')
-rw-r--r-- | net/core/dev.c | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index 09aef266d4d1..40d439524f49 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -136,6 +136,7 @@ | |||
136 | #include <linux/if_tunnel.h> | 136 | #include <linux/if_tunnel.h> |
137 | #include <linux/if_pppox.h> | 137 | #include <linux/if_pppox.h> |
138 | #include <linux/ppp_defs.h> | 138 | #include <linux/ppp_defs.h> |
139 | #include <linux/net_tstamp.h> | ||
139 | 140 | ||
140 | #include "net-sysfs.h" | 141 | #include "net-sysfs.h" |
141 | 142 | ||
@@ -1477,6 +1478,57 @@ static inline void net_timestamp_check(struct sk_buff *skb) | |||
1477 | __net_timestamp(skb); | 1478 | __net_timestamp(skb); |
1478 | } | 1479 | } |
1479 | 1480 | ||
1481 | static int net_hwtstamp_validate(struct ifreq *ifr) | ||
1482 | { | ||
1483 | struct hwtstamp_config cfg; | ||
1484 | enum hwtstamp_tx_types tx_type; | ||
1485 | enum hwtstamp_rx_filters rx_filter; | ||
1486 | int tx_type_valid = 0; | ||
1487 | int rx_filter_valid = 0; | ||
1488 | |||
1489 | if (copy_from_user(&cfg, ifr->ifr_data, sizeof(cfg))) | ||
1490 | return -EFAULT; | ||
1491 | |||
1492 | if (cfg.flags) /* reserved for future extensions */ | ||
1493 | return -EINVAL; | ||
1494 | |||
1495 | tx_type = cfg.tx_type; | ||
1496 | rx_filter = cfg.rx_filter; | ||
1497 | |||
1498 | switch (tx_type) { | ||
1499 | case HWTSTAMP_TX_OFF: | ||
1500 | case HWTSTAMP_TX_ON: | ||
1501 | case HWTSTAMP_TX_ONESTEP_SYNC: | ||
1502 | tx_type_valid = 1; | ||
1503 | break; | ||
1504 | } | ||
1505 | |||
1506 | switch (rx_filter) { | ||
1507 | case HWTSTAMP_FILTER_NONE: | ||
1508 | case HWTSTAMP_FILTER_ALL: | ||
1509 | case HWTSTAMP_FILTER_SOME: | ||
1510 | case HWTSTAMP_FILTER_PTP_V1_L4_EVENT: | ||
1511 | case HWTSTAMP_FILTER_PTP_V1_L4_SYNC: | ||
1512 | case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ: | ||
1513 | case HWTSTAMP_FILTER_PTP_V2_L4_EVENT: | ||
1514 | case HWTSTAMP_FILTER_PTP_V2_L4_SYNC: | ||
1515 | case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ: | ||
1516 | case HWTSTAMP_FILTER_PTP_V2_L2_EVENT: | ||
1517 | case HWTSTAMP_FILTER_PTP_V2_L2_SYNC: | ||
1518 | case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ: | ||
1519 | case HWTSTAMP_FILTER_PTP_V2_EVENT: | ||
1520 | case HWTSTAMP_FILTER_PTP_V2_SYNC: | ||
1521 | case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ: | ||
1522 | rx_filter_valid = 1; | ||
1523 | break; | ||
1524 | } | ||
1525 | |||
1526 | if (!tx_type_valid || !rx_filter_valid) | ||
1527 | return -ERANGE; | ||
1528 | |||
1529 | return 0; | ||
1530 | } | ||
1531 | |||
1480 | static inline bool is_skb_forwardable(struct net_device *dev, | 1532 | static inline bool is_skb_forwardable(struct net_device *dev, |
1481 | struct sk_buff *skb) | 1533 | struct sk_buff *skb) |
1482 | { | 1534 | { |
@@ -4921,6 +4973,12 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd) | |||
4921 | ifr->ifr_newname[IFNAMSIZ-1] = '\0'; | 4973 | ifr->ifr_newname[IFNAMSIZ-1] = '\0'; |
4922 | return dev_change_name(dev, ifr->ifr_newname); | 4974 | return dev_change_name(dev, ifr->ifr_newname); |
4923 | 4975 | ||
4976 | case SIOCSHWTSTAMP: | ||
4977 | err = net_hwtstamp_validate(ifr); | ||
4978 | if (err) | ||
4979 | return err; | ||
4980 | /* fall through */ | ||
4981 | |||
4924 | /* | 4982 | /* |
4925 | * Unknown or private ioctl | 4983 | * Unknown or private ioctl |
4926 | */ | 4984 | */ |