diff options
| -rw-r--r-- | include/linux/mroute.h | 1 | ||||
| -rw-r--r-- | include/net/sock.h | 2 | ||||
| -rw-r--r-- | net/ipv4/af_inet.c | 16 | ||||
| -rw-r--r-- | net/ipv4/ipmr.c | 46 | ||||
| -rw-r--r-- | net/ipv4/raw.c | 19 |
5 files changed, 84 insertions, 0 deletions
diff --git a/include/linux/mroute.h b/include/linux/mroute.h index 0fa7a3a874c8..b21d567692b2 100644 --- a/include/linux/mroute.h +++ b/include/linux/mroute.h | |||
| @@ -150,6 +150,7 @@ static inline int ip_mroute_opt(int opt) | |||
| 150 | extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int); | 150 | extern int ip_mroute_setsockopt(struct sock *, int, char __user *, unsigned int); |
| 151 | extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *); | 151 | extern int ip_mroute_getsockopt(struct sock *, int, char __user *, int __user *); |
| 152 | extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); | 152 | extern int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg); |
| 153 | extern int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg); | ||
| 153 | extern int ip_mr_init(void); | 154 | extern int ip_mr_init(void); |
| 154 | #else | 155 | #else |
| 155 | static inline | 156 | static inline |
diff --git a/include/net/sock.h b/include/net/sock.h index d884d268c704..bc1cf7d88ccb 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
| @@ -753,6 +753,8 @@ struct proto { | |||
| 753 | int level, | 753 | int level, |
| 754 | int optname, char __user *optval, | 754 | int optname, char __user *optval, |
| 755 | int __user *option); | 755 | int __user *option); |
| 756 | int (*compat_ioctl)(struct sock *sk, | ||
| 757 | unsigned int cmd, unsigned long arg); | ||
| 756 | #endif | 758 | #endif |
| 757 | int (*sendmsg)(struct kiocb *iocb, struct sock *sk, | 759 | int (*sendmsg)(struct kiocb *iocb, struct sock *sk, |
| 758 | struct msghdr *msg, size_t len); | 760 | struct msghdr *msg, size_t len); |
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index f2b61107df6c..45b89d7bda5a 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c | |||
| @@ -880,6 +880,19 @@ int inet_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | |||
| 880 | } | 880 | } |
| 881 | EXPORT_SYMBOL(inet_ioctl); | 881 | EXPORT_SYMBOL(inet_ioctl); |
| 882 | 882 | ||
| 883 | #ifdef CONFIG_COMPAT | ||
| 884 | int inet_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) | ||
| 885 | { | ||
| 886 | struct sock *sk = sock->sk; | ||
| 887 | int err = -ENOIOCTLCMD; | ||
| 888 | |||
| 889 | if (sk->sk_prot->compat_ioctl) | ||
| 890 | err = sk->sk_prot->compat_ioctl(sk, cmd, arg); | ||
| 891 | |||
| 892 | return err; | ||
| 893 | } | ||
| 894 | #endif | ||
| 895 | |||
| 883 | const struct proto_ops inet_stream_ops = { | 896 | const struct proto_ops inet_stream_ops = { |
| 884 | .family = PF_INET, | 897 | .family = PF_INET, |
| 885 | .owner = THIS_MODULE, | 898 | .owner = THIS_MODULE, |
| @@ -903,6 +916,7 @@ const struct proto_ops inet_stream_ops = { | |||
| 903 | #ifdef CONFIG_COMPAT | 916 | #ifdef CONFIG_COMPAT |
| 904 | .compat_setsockopt = compat_sock_common_setsockopt, | 917 | .compat_setsockopt = compat_sock_common_setsockopt, |
| 905 | .compat_getsockopt = compat_sock_common_getsockopt, | 918 | .compat_getsockopt = compat_sock_common_getsockopt, |
| 919 | .compat_ioctl = inet_compat_ioctl, | ||
| 906 | #endif | 920 | #endif |
| 907 | }; | 921 | }; |
| 908 | EXPORT_SYMBOL(inet_stream_ops); | 922 | EXPORT_SYMBOL(inet_stream_ops); |
| @@ -929,6 +943,7 @@ const struct proto_ops inet_dgram_ops = { | |||
| 929 | #ifdef CONFIG_COMPAT | 943 | #ifdef CONFIG_COMPAT |
| 930 | .compat_setsockopt = compat_sock_common_setsockopt, | 944 | .compat_setsockopt = compat_sock_common_setsockopt, |
| 931 | .compat_getsockopt = compat_sock_common_getsockopt, | 945 | .compat_getsockopt = compat_sock_common_getsockopt, |
| 946 | .compat_ioctl = inet_compat_ioctl, | ||
| 932 | #endif | 947 | #endif |
| 933 | }; | 948 | }; |
| 934 | EXPORT_SYMBOL(inet_dgram_ops); | 949 | EXPORT_SYMBOL(inet_dgram_ops); |
| @@ -959,6 +974,7 @@ static const struct proto_ops inet_sockraw_ops = { | |||
| 959 | #ifdef CONFIG_COMPAT | 974 | #ifdef CONFIG_COMPAT |
| 960 | .compat_setsockopt = compat_sock_common_setsockopt, | 975 | .compat_setsockopt = compat_sock_common_setsockopt, |
| 961 | .compat_getsockopt = compat_sock_common_getsockopt, | 976 | .compat_getsockopt = compat_sock_common_getsockopt, |
| 977 | .compat_ioctl = inet_compat_ioctl, | ||
| 962 | #endif | 978 | #endif |
| 963 | }; | 979 | }; |
| 964 | 980 | ||
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 3f3a9afd73e0..7e41ac0b9260 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c | |||
| @@ -60,6 +60,7 @@ | |||
| 60 | #include <linux/notifier.h> | 60 | #include <linux/notifier.h> |
| 61 | #include <linux/if_arp.h> | 61 | #include <linux/if_arp.h> |
| 62 | #include <linux/netfilter_ipv4.h> | 62 | #include <linux/netfilter_ipv4.h> |
| 63 | #include <linux/compat.h> | ||
| 63 | #include <net/ipip.h> | 64 | #include <net/ipip.h> |
| 64 | #include <net/checksum.h> | 65 | #include <net/checksum.h> |
| 65 | #include <net/netlink.h> | 66 | #include <net/netlink.h> |
| @@ -1434,6 +1435,51 @@ int ipmr_ioctl(struct sock *sk, int cmd, void __user *arg) | |||
| 1434 | } | 1435 | } |
| 1435 | } | 1436 | } |
| 1436 | 1437 | ||
| 1438 | #ifdef CONFIG_COMPAT | ||
| 1439 | struct compat_sioc_sg_req { | ||
| 1440 | struct in_addr src; | ||
| 1441 | struct in_addr grp; | ||
| 1442 | compat_ulong_t pktcnt; | ||
| 1443 | compat_ulong_t bytecnt; | ||
| 1444 | compat_ulong_t wrong_if; | ||
| 1445 | }; | ||
| 1446 | |||
| 1447 | int ipmr_compat_ioctl(struct sock *sk, unsigned int cmd, void __user *arg) | ||
| 1448 | { | ||
| 1449 | struct sioc_sg_req sr; | ||
| 1450 | struct mfc_cache *c; | ||
| 1451 | struct net *net = sock_net(sk); | ||
| 1452 | struct mr_table *mrt; | ||
| 1453 | |||
| 1454 | mrt = ipmr_get_table(net, raw_sk(sk)->ipmr_table ? : RT_TABLE_DEFAULT); | ||
| 1455 | if (mrt == NULL) | ||
| 1456 | return -ENOENT; | ||
| 1457 | |||
| 1458 | switch (cmd) { | ||
| 1459 | case SIOCGETSGCNT: | ||
| 1460 | if (copy_from_user(&sr, arg, sizeof(sr))) | ||
| 1461 | return -EFAULT; | ||
| 1462 | |||
| 1463 | rcu_read_lock(); | ||
| 1464 | c = ipmr_cache_find(mrt, sr.src.s_addr, sr.grp.s_addr); | ||
| 1465 | if (c) { | ||
| 1466 | sr.pktcnt = c->mfc_un.res.pkt; | ||
| 1467 | sr.bytecnt = c->mfc_un.res.bytes; | ||
| 1468 | sr.wrong_if = c->mfc_un.res.wrong_if; | ||
| 1469 | rcu_read_unlock(); | ||
| 1470 | |||
| 1471 | if (copy_to_user(arg, &sr, sizeof(sr))) | ||
| 1472 | return -EFAULT; | ||
| 1473 | return 0; | ||
| 1474 | } | ||
| 1475 | rcu_read_unlock(); | ||
| 1476 | return -EADDRNOTAVAIL; | ||
| 1477 | default: | ||
| 1478 | return -ENOIOCTLCMD; | ||
| 1479 | } | ||
| 1480 | } | ||
| 1481 | #endif | ||
| 1482 | |||
| 1437 | 1483 | ||
| 1438 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) | 1484 | static int ipmr_device_event(struct notifier_block *this, unsigned long event, void *ptr) |
| 1439 | { | 1485 | { |
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c index a3d5ab786e81..6390ba299b3d 100644 --- a/net/ipv4/raw.c +++ b/net/ipv4/raw.c | |||
| @@ -76,6 +76,7 @@ | |||
| 76 | #include <linux/seq_file.h> | 76 | #include <linux/seq_file.h> |
| 77 | #include <linux/netfilter.h> | 77 | #include <linux/netfilter.h> |
| 78 | #include <linux/netfilter_ipv4.h> | 78 | #include <linux/netfilter_ipv4.h> |
| 79 | #include <linux/compat.h> | ||
| 79 | 80 | ||
| 80 | static struct raw_hashinfo raw_v4_hashinfo = { | 81 | static struct raw_hashinfo raw_v4_hashinfo = { |
| 81 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), | 82 | .lock = __RW_LOCK_UNLOCKED(raw_v4_hashinfo.lock), |
| @@ -838,6 +839,23 @@ static int raw_ioctl(struct sock *sk, int cmd, unsigned long arg) | |||
| 838 | } | 839 | } |
| 839 | } | 840 | } |
| 840 | 841 | ||
| 842 | #ifdef CONFIG_COMPAT | ||
| 843 | static int compat_raw_ioctl(struct sock *sk, unsigned int cmd, unsigned long arg) | ||
| 844 | { | ||
| 845 | switch (cmd) { | ||
| 846 | case SIOCOUTQ: | ||
| 847 | case SIOCINQ: | ||
| 848 | return -ENOIOCTLCMD; | ||
| 849 | default: | ||
| 850 | #ifdef CONFIG_IP_MROUTE | ||
| 851 | return ipmr_compat_ioctl(sk, cmd, compat_ptr(arg)); | ||
| 852 | #else | ||
| 853 | return -ENOIOCTLCMD; | ||
| 854 | #endif | ||
| 855 | } | ||
| 856 | } | ||
| 857 | #endif | ||
| 858 | |||
| 841 | struct proto raw_prot = { | 859 | struct proto raw_prot = { |
| 842 | .name = "RAW", | 860 | .name = "RAW", |
| 843 | .owner = THIS_MODULE, | 861 | .owner = THIS_MODULE, |
| @@ -860,6 +878,7 @@ struct proto raw_prot = { | |||
| 860 | #ifdef CONFIG_COMPAT | 878 | #ifdef CONFIG_COMPAT |
| 861 | .compat_setsockopt = compat_raw_setsockopt, | 879 | .compat_setsockopt = compat_raw_setsockopt, |
| 862 | .compat_getsockopt = compat_raw_getsockopt, | 880 | .compat_getsockopt = compat_raw_getsockopt, |
| 881 | .compat_ioctl = compat_raw_ioctl, | ||
| 863 | #endif | 882 | #endif |
| 864 | }; | 883 | }; |
| 865 | 884 | ||
