Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net: split out ndo_siowandev ioctl

In order to further reduce the scope of ndo_do_ioctl(), move
out the SIOCWANDEV handling into a new network device operation
function.

Adjust the prototype to only pass the if_settings sub-structure
in place of the ifreq, and remove the redundant 'cmd' argument
in the process.

Cc: Krzysztof Halasa <khc@pm.waw.pl>
Cc: "Jan \"Yenya\" Kasprzak" <kas@fi.muni.cz>
Cc: Kevin Curtis <kevin.curtis@farsite.co.uk>
Cc: Zhao Qiang <qiang.zhao@nxp.com>
Cc: Martin Schiller <ms@dev.tdt.de>
Cc: Jiri Slaby <jirislaby@kernel.org>
Cc: linux-x25@vger.kernel.org
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Arnd Bergmann and committed by
David S. Miller
ad7eab2a a7605370

+210 -257
+7
Documentation/networking/netdevices.rst
··· 222 222 Synchronization: rtnl_lock() semaphore. 223 223 Context: process 224 224 225 + ndo_siocwandev: 226 + Synchronization: rtnl_lock() semaphore. 227 + Context: process 228 + 229 + Used by the drivers/net/wan framework to handle 230 + the SIOCWANDEV ioctl with the if_settings structure. 231 + 225 232 ndo_siocdevprivate: 226 233 Synchronization: rtnl_lock() semaphore. 227 234 Context: process
+8 -11
drivers/net/wan/c101.c
··· 228 228 return -EOPNOTSUPP; 229 229 } 230 230 231 - static int c101_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 231 + static int c101_ioctl(struct net_device *dev, struct if_settings *ifs) 232 232 { 233 233 const size_t size = sizeof(sync_serial_settings); 234 234 sync_serial_settings new_line; 235 - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; 235 + sync_serial_settings __user *line = ifs->ifs_ifsu.sync; 236 236 port_t *port = dev_to_port(dev); 237 237 238 - if (cmd != SIOCWANDEV) 239 - return hdlc_ioctl(dev, ifr, cmd); 240 - 241 - switch (ifr->ifr_settings.type) { 238 + switch (ifs->type) { 242 239 case IF_GET_IFACE: 243 - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; 244 - if (ifr->ifr_settings.size < size) { 245 - ifr->ifr_settings.size = size; /* data size wanted */ 240 + ifs->type = IF_IFACE_SYNC_SERIAL; 241 + if (ifs->size < size) { 242 + ifs->size = size; /* data size wanted */ 246 243 return -ENOBUFS; 247 244 } 248 245 if (copy_to_user(line, &port->settings, size)) ··· 267 270 return 0; 268 271 269 272 default: 270 - return hdlc_ioctl(dev, ifr, cmd); 273 + return hdlc_ioctl(dev, ifs); 271 274 } 272 275 } 273 276 ··· 292 295 .ndo_open = c101_open, 293 296 .ndo_stop = c101_close, 294 297 .ndo_start_xmit = hdlc_start_xmit, 295 - .ndo_do_ioctl = c101_ioctl, 298 + .ndo_siocwandev = c101_ioctl, 296 299 .ndo_siocdevprivate = c101_siocdevprivate, 297 300 }; 298 301
+1 -1
drivers/net/wan/cosa.c
··· 414 414 .ndo_open = cosa_net_open, 415 415 .ndo_stop = cosa_net_close, 416 416 .ndo_start_xmit = hdlc_start_xmit, 417 - .ndo_do_ioctl = hdlc_ioctl, 417 + .ndo_siocwandev = hdlc_ioctl, 418 418 .ndo_tx_timeout = cosa_net_timeout, 419 419 }; 420 420
+41 -49
drivers/net/wan/farsync.c
··· 1784 1784 1785 1785 static int 1786 1786 fst_set_iface(struct fst_card_info *card, struct fst_port_info *port, 1787 - struct ifreq *ifr) 1787 + struct if_settings *ifs) 1788 1788 { 1789 1789 sync_serial_settings sync; 1790 1790 int i; 1791 1791 1792 - if (ifr->ifr_settings.size != sizeof(sync)) 1792 + if (ifs->size != sizeof(sync)) 1793 1793 return -ENOMEM; 1794 1794 1795 - if (copy_from_user 1796 - (&sync, ifr->ifr_settings.ifs_ifsu.sync, sizeof(sync))) 1795 + if (copy_from_user(&sync, ifs->ifs_ifsu.sync, sizeof(sync))) 1797 1796 return -EFAULT; 1798 1797 1799 1798 if (sync.loopback) ··· 1800 1801 1801 1802 i = port->index; 1802 1803 1803 - switch (ifr->ifr_settings.type) { 1804 + switch (ifs->type) { 1804 1805 case IF_IFACE_V35: 1805 1806 FST_WRW(card, portConfig[i].lineInterface, V35); 1806 1807 port->hwif = V35; ··· 1856 1857 1857 1858 static int 1858 1859 fst_get_iface(struct fst_card_info *card, struct fst_port_info *port, 1859 - struct ifreq *ifr) 1860 + struct if_settings *ifs) 1860 1861 { 1861 1862 sync_serial_settings sync; 1862 1863 int i; ··· 1867 1868 */ 1868 1869 switch (port->hwif) { 1869 1870 case E1: 1870 - ifr->ifr_settings.type = IF_IFACE_E1; 1871 + ifs->type = IF_IFACE_E1; 1871 1872 break; 1872 1873 case T1: 1873 - ifr->ifr_settings.type = IF_IFACE_T1; 1874 + ifs->type = IF_IFACE_T1; 1874 1875 break; 1875 1876 case V35: 1876 - ifr->ifr_settings.type = IF_IFACE_V35; 1877 + ifs->type = IF_IFACE_V35; 1877 1878 break; 1878 1879 case V24: 1879 - ifr->ifr_settings.type = IF_IFACE_V24; 1880 + ifs->type = IF_IFACE_V24; 1880 1881 break; 1881 1882 case X21D: 1882 - ifr->ifr_settings.type = IF_IFACE_X21D; 1883 + ifs->type = IF_IFACE_X21D; 1883 1884 break; 1884 1885 case X21: 1885 1886 default: 1886 - ifr->ifr_settings.type = IF_IFACE_X21; 1887 + ifs->type = IF_IFACE_X21; 1887 1888 break; 1888 1889 } 1889 - if (ifr->ifr_settings.size == 0) 1890 + if (!ifs->size) 1890 1891 return 0; /* only type requested */ 1891 1892 1892 - if (ifr->ifr_settings.size < sizeof(sync)) 1893 + if (ifs->size < sizeof(sync)) 1893 1894 return -ENOMEM; 1894 1895 1895 1896 i = port->index; ··· 1900 1901 INTCLK ? CLOCK_INT : CLOCK_EXT; 1901 1902 sync.loopback = 0; 1902 1903 1903 - if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &sync, sizeof(sync))) 1904 + if (copy_to_user(ifs->ifs_ifsu.sync, &sync, sizeof(sync))) 1904 1905 return -EFAULT; 1905 1906 1906 - ifr->ifr_settings.size = sizeof(sync); 1907 + ifs->size = sizeof(sync); 1907 1908 return 0; 1908 1909 } 1909 1910 ··· 2019 2020 } 2020 2021 2021 2022 static int 2022 - fst_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 2023 + fst_ioctl(struct net_device *dev, struct if_settings *ifs) 2023 2024 { 2024 2025 struct fst_card_info *card; 2025 2026 struct fst_port_info *port; 2026 2027 2027 - dbg(DBG_IOCTL, "ioctl: %x, %x\n", cmd, ifr->ifr_settings.type); 2028 + dbg(DBG_IOCTL, "SIOCDEVPRIVATE, %x\n", ifs->type); 2028 2029 2029 2030 port = dev_to_port(dev); 2030 2031 card = port->card; ··· 2032 2033 if (!capable(CAP_NET_ADMIN)) 2033 2034 return -EPERM; 2034 2035 2035 - switch (cmd) { 2036 - case SIOCWANDEV: 2037 - switch (ifr->ifr_settings.type) { 2038 - case IF_GET_IFACE: 2039 - return fst_get_iface(card, port, ifr); 2036 + switch (ifs->type) { 2037 + case IF_GET_IFACE: 2038 + return fst_get_iface(card, port, ifs); 2040 2039 2041 - case IF_IFACE_SYNC_SERIAL: 2042 - case IF_IFACE_V35: 2043 - case IF_IFACE_V24: 2044 - case IF_IFACE_X21: 2045 - case IF_IFACE_X21D: 2046 - case IF_IFACE_T1: 2047 - case IF_IFACE_E1: 2048 - return fst_set_iface(card, port, ifr); 2040 + case IF_IFACE_SYNC_SERIAL: 2041 + case IF_IFACE_V35: 2042 + case IF_IFACE_V24: 2043 + case IF_IFACE_X21: 2044 + case IF_IFACE_X21D: 2045 + case IF_IFACE_T1: 2046 + case IF_IFACE_E1: 2047 + return fst_set_iface(card, port, ifs); 2049 2048 2050 - case IF_PROTO_RAW: 2051 - port->mode = FST_RAW; 2049 + case IF_PROTO_RAW: 2050 + port->mode = FST_RAW; 2051 + return 0; 2052 + 2053 + case IF_GET_PROTO: 2054 + if (port->mode == FST_RAW) { 2055 + ifs->type = IF_PROTO_RAW; 2052 2056 return 0; 2053 - 2054 - case IF_GET_PROTO: 2055 - if (port->mode == FST_RAW) { 2056 - ifr->ifr_settings.type = IF_PROTO_RAW; 2057 - return 0; 2058 - } 2059 - return hdlc_ioctl(dev, ifr, cmd); 2060 - 2061 - default: 2062 - port->mode = FST_GEN_HDLC; 2063 - dbg(DBG_IOCTL, "Passing this type to hdlc %x\n", 2064 - ifr->ifr_settings.type); 2065 - return hdlc_ioctl(dev, ifr, cmd); 2066 2057 } 2058 + return hdlc_ioctl(dev, ifs); 2067 2059 2068 2060 default: 2069 - /* Not one of ours. Pass through to HDLC package */ 2070 - return hdlc_ioctl(dev, ifr, cmd); 2061 + port->mode = FST_GEN_HDLC; 2062 + dbg(DBG_IOCTL, "Passing this type to hdlc %x\n", 2063 + ifs->type); 2064 + return hdlc_ioctl(dev, ifs); 2071 2065 } 2072 2066 } 2073 2067 ··· 2320 2328 .ndo_open = fst_open, 2321 2329 .ndo_stop = fst_close, 2322 2330 .ndo_start_xmit = hdlc_start_xmit, 2323 - .ndo_do_ioctl = fst_ioctl, 2331 + .ndo_siocwandev = fst_ioctl, 2324 2332 .ndo_siocdevprivate = fst_siocdevprivate, 2325 2333 .ndo_tx_timeout = fst_tx_timeout, 2326 2334 };
+8 -11
drivers/net/wan/fsl_ucc_hdlc.c
··· 674 674 return IRQ_HANDLED; 675 675 } 676 676 677 - static int uhdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 677 + static int uhdlc_ioctl(struct net_device *dev, struct if_settings *ifs) 678 678 { 679 679 const size_t size = sizeof(te1_settings); 680 680 te1_settings line; 681 681 struct ucc_hdlc_private *priv = netdev_priv(dev); 682 682 683 - if (cmd != SIOCWANDEV) 684 - return hdlc_ioctl(dev, ifr, cmd); 685 - 686 - switch (ifr->ifr_settings.type) { 683 + switch (ifs->type) { 687 684 case IF_GET_IFACE: 688 - ifr->ifr_settings.type = IF_IFACE_E1; 689 - if (ifr->ifr_settings.size < size) { 690 - ifr->ifr_settings.size = size; /* data size wanted */ 685 + ifs->type = IF_IFACE_E1; 686 + if (ifs->size < size) { 687 + ifs->size = size; /* data size wanted */ 691 688 return -ENOBUFS; 692 689 } 693 690 memset(&line, 0, sizeof(line)); 694 691 line.clock_type = priv->clocking; 695 692 696 - if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size)) 693 + if (copy_to_user(ifs->ifs_ifsu.sync, &line, size)) 697 694 return -EFAULT; 698 695 return 0; 699 696 700 697 default: 701 - return hdlc_ioctl(dev, ifr, cmd); 698 + return hdlc_ioctl(dev, ifs); 702 699 } 703 700 } 704 701 ··· 1050 1053 .ndo_open = uhdlc_open, 1051 1054 .ndo_stop = uhdlc_close, 1052 1055 .ndo_start_xmit = hdlc_start_xmit, 1053 - .ndo_do_ioctl = uhdlc_ioctl, 1056 + .ndo_siocwandev = uhdlc_ioctl, 1054 1057 .ndo_tx_timeout = uhdlc_tx_timeout, 1055 1058 }; 1056 1059
+3 -6
drivers/net/wan/hdlc.c
··· 196 196 } 197 197 EXPORT_SYMBOL(hdlc_close); 198 198 199 - int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 199 + int hdlc_ioctl(struct net_device *dev, struct if_settings *ifs) 200 200 { 201 201 struct hdlc_proto *proto = first_proto; 202 202 int result; 203 203 204 - if (cmd != SIOCWANDEV) 205 - return -EINVAL; 206 - 207 204 if (dev_to_hdlc(dev)->proto) { 208 - result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr); 205 + result = dev_to_hdlc(dev)->proto->ioctl(dev, ifs); 209 206 if (result != -EINVAL) 210 207 return result; 211 208 } ··· 210 213 /* Not handled by currently attached protocol (if any) */ 211 214 212 215 while (proto) { 213 - result = proto->ioctl(dev, ifr); 216 + result = proto->ioctl(dev, ifs); 214 217 if (result != -EINVAL) 215 218 return result; 216 219 proto = proto->next;
+7 -7
drivers/net/wan/hdlc_cisco.c
··· 56 56 u32 rxseq; /* RX sequence number */ 57 57 }; 58 58 59 - static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr); 59 + static int cisco_ioctl(struct net_device *dev, struct if_settings *ifs); 60 60 61 61 static inline struct cisco_state *state(hdlc_device *hdlc) 62 62 { ··· 306 306 .create = cisco_hard_header, 307 307 }; 308 308 309 - static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 309 + static int cisco_ioctl(struct net_device *dev, struct if_settings *ifs) 310 310 { 311 - cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 311 + cisco_proto __user *cisco_s = ifs->ifs_ifsu.cisco; 312 312 const size_t size = sizeof(cisco_proto); 313 313 cisco_proto new_settings; 314 314 hdlc_device *hdlc = dev_to_hdlc(dev); 315 315 int result; 316 316 317 - switch (ifr->ifr_settings.type) { 317 + switch (ifs->type) { 318 318 case IF_GET_PROTO: 319 319 if (dev_to_hdlc(dev)->proto != &proto) 320 320 return -EINVAL; 321 - ifr->ifr_settings.type = IF_PROTO_CISCO; 322 - if (ifr->ifr_settings.size < size) { 323 - ifr->ifr_settings.size = size; /* data size wanted */ 321 + ifs->type = IF_PROTO_CISCO; 322 + if (ifs->size < size) { 323 + ifs->size = size; /* data size wanted */ 324 324 return -ENOBUFS; 325 325 } 326 326 if (copy_to_user(cisco_s, &state(hdlc)->settings, size))
+20 -23
drivers/net/wan/hdlc_fr.c
··· 146 146 u8 rxseq; /* RX sequence number */ 147 147 }; 148 148 149 - static int fr_ioctl(struct net_device *dev, struct ifreq *ifr); 149 + static int fr_ioctl(struct net_device *dev, struct if_settings *ifs); 150 150 151 151 static inline u16 q922_to_dlci(u8 *hdr) 152 152 { ··· 357 357 return 0; 358 358 } 359 359 360 - static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 360 + static int pvc_ioctl(struct net_device *dev, struct if_settings *ifs) 361 361 { 362 362 struct pvc_device *pvc = dev->ml_priv; 363 363 fr_proto_pvc_info info; 364 364 365 - if (cmd != SIOCWANDEV) 366 - return -EOPNOTSUPP; 367 - 368 - if (ifr->ifr_settings.type == IF_GET_PROTO) { 365 + if (ifs->type == IF_GET_PROTO) { 369 366 if (dev->type == ARPHRD_ETHER) 370 - ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC; 367 + ifs->type = IF_PROTO_FR_ETH_PVC; 371 368 else 372 - ifr->ifr_settings.type = IF_PROTO_FR_PVC; 369 + ifs->type = IF_PROTO_FR_PVC; 373 370 374 - if (ifr->ifr_settings.size < sizeof(info)) { 371 + if (ifs->size < sizeof(info)) { 375 372 /* data size wanted */ 376 - ifr->ifr_settings.size = sizeof(info); 373 + ifs->size = sizeof(info); 377 374 return -ENOBUFS; 378 375 } 379 376 380 377 info.dlci = pvc->dlci; 381 378 memcpy(info.master, pvc->frad->name, IFNAMSIZ); 382 - if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, 379 + if (copy_to_user(ifs->ifs_ifsu.fr_pvc_info, 383 380 &info, sizeof(info))) 384 381 return -EFAULT; 385 382 return 0; ··· 1056 1059 .ndo_open = pvc_open, 1057 1060 .ndo_stop = pvc_close, 1058 1061 .ndo_start_xmit = pvc_xmit, 1059 - .ndo_do_ioctl = pvc_ioctl, 1062 + .ndo_siocwandev = pvc_ioctl, 1060 1063 }; 1061 1064 1062 1065 static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type) ··· 1179 1182 .module = THIS_MODULE, 1180 1183 }; 1181 1184 1182 - static int fr_ioctl(struct net_device *dev, struct ifreq *ifr) 1185 + static int fr_ioctl(struct net_device *dev, struct if_settings *ifs) 1183 1186 { 1184 - fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; 1187 + fr_proto __user *fr_s = ifs->ifs_ifsu.fr; 1185 1188 const size_t size = sizeof(fr_proto); 1186 1189 fr_proto new_settings; 1187 1190 hdlc_device *hdlc = dev_to_hdlc(dev); 1188 1191 fr_proto_pvc pvc; 1189 1192 int result; 1190 1193 1191 - switch (ifr->ifr_settings.type) { 1194 + switch (ifs->type) { 1192 1195 case IF_GET_PROTO: 1193 1196 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */ 1194 1197 return -EINVAL; 1195 - ifr->ifr_settings.type = IF_PROTO_FR; 1196 - if (ifr->ifr_settings.size < size) { 1197 - ifr->ifr_settings.size = size; /* data size wanted */ 1198 + ifs->type = IF_PROTO_FR; 1199 + if (ifs->size < size) { 1200 + ifs->size = size; /* data size wanted */ 1198 1201 return -ENOBUFS; 1199 1202 } 1200 1203 if (copy_to_user(fr_s, &state(hdlc)->settings, size)) ··· 1256 1259 if (!capable(CAP_NET_ADMIN)) 1257 1260 return -EPERM; 1258 1261 1259 - if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc, 1262 + if (copy_from_user(&pvc, ifs->ifs_ifsu.fr_pvc, 1260 1263 sizeof(fr_proto_pvc))) 1261 1264 return -EFAULT; 1262 1265 1263 1266 if (pvc.dlci <= 0 || pvc.dlci >= 1024) 1264 1267 return -EINVAL; /* Only 10 bits, DLCI 0 reserved */ 1265 1268 1266 - if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC || 1267 - ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC) 1269 + if (ifs->type == IF_PROTO_FR_ADD_ETH_PVC || 1270 + ifs->type == IF_PROTO_FR_DEL_ETH_PVC) 1268 1271 result = ARPHRD_ETHER; /* bridged Ethernet device */ 1269 1272 else 1270 1273 result = ARPHRD_DLCI; 1271 1274 1272 - if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC || 1273 - ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC) 1275 + if (ifs->type == IF_PROTO_FR_ADD_PVC || 1276 + ifs->type == IF_PROTO_FR_ADD_ETH_PVC) 1274 1277 return fr_add_pvc(dev, pvc.dlci, result); 1275 1278 else 1276 1279 return fr_del_pvc(hdlc, pvc.dlci, result);
+4 -4
drivers/net/wan/hdlc_ppp.c
··· 100 100 101 101 static struct sk_buff_head tx_queue; /* used when holding the spin lock */ 102 102 103 - static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr); 103 + static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs); 104 104 105 105 static inline struct ppp *get_ppp(struct net_device *dev) 106 106 { ··· 655 655 .create = ppp_hard_header, 656 656 }; 657 657 658 - static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr) 658 + static int ppp_ioctl(struct net_device *dev, struct if_settings *ifs) 659 659 { 660 660 hdlc_device *hdlc = dev_to_hdlc(dev); 661 661 struct ppp *ppp; 662 662 int result; 663 663 664 - switch (ifr->ifr_settings.type) { 664 + switch (ifs->type) { 665 665 case IF_GET_PROTO: 666 666 if (dev_to_hdlc(dev)->proto != &proto) 667 667 return -EINVAL; 668 - ifr->ifr_settings.type = IF_PROTO_PPP; 668 + ifs->type = IF_PROTO_PPP; 669 669 return 0; /* return protocol only, no settable parameters */ 670 670 671 671 case IF_PROTO_PPP:
+7 -7
drivers/net/wan/hdlc_raw.c
··· 19 19 #include <linux/skbuff.h> 20 20 21 21 22 - static int raw_ioctl(struct net_device *dev, struct ifreq *ifr); 22 + static int raw_ioctl(struct net_device *dev, struct if_settings *ifs); 23 23 24 24 static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) 25 25 { ··· 33 33 }; 34 34 35 35 36 - static int raw_ioctl(struct net_device *dev, struct ifreq *ifr) 36 + static int raw_ioctl(struct net_device *dev, struct if_settings *ifs) 37 37 { 38 - raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 38 + raw_hdlc_proto __user *raw_s = ifs->ifs_ifsu.raw_hdlc; 39 39 const size_t size = sizeof(raw_hdlc_proto); 40 40 raw_hdlc_proto new_settings; 41 41 hdlc_device *hdlc = dev_to_hdlc(dev); 42 42 int result; 43 43 44 - switch (ifr->ifr_settings.type) { 44 + switch (ifs->type) { 45 45 case IF_GET_PROTO: 46 46 if (dev_to_hdlc(dev)->proto != &proto) 47 47 return -EINVAL; 48 - ifr->ifr_settings.type = IF_PROTO_HDLC; 49 - if (ifr->ifr_settings.size < size) { 50 - ifr->ifr_settings.size = size; /* data size wanted */ 48 + ifs->type = IF_PROTO_HDLC; 49 + if (ifs->size < size) { 50 + ifs->size = size; /* data size wanted */ 51 51 return -ENOBUFS; 52 52 } 53 53 if (copy_to_user(raw_s, hdlc->state, size))
+7 -7
drivers/net/wan/hdlc_raw_eth.c
··· 20 20 #include <linux/rtnetlink.h> 21 21 #include <linux/skbuff.h> 22 22 23 - static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr); 23 + static int raw_eth_ioctl(struct net_device *dev, struct if_settings *ifs); 24 24 25 25 static netdev_tx_t eth_tx(struct sk_buff *skb, struct net_device *dev) 26 26 { ··· 48 48 }; 49 49 50 50 51 - static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) 51 + static int raw_eth_ioctl(struct net_device *dev, struct if_settings *ifs) 52 52 { 53 - raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 53 + raw_hdlc_proto __user *raw_s = ifs->ifs_ifsu.raw_hdlc; 54 54 const size_t size = sizeof(raw_hdlc_proto); 55 55 raw_hdlc_proto new_settings; 56 56 hdlc_device *hdlc = dev_to_hdlc(dev); 57 57 unsigned int old_qlen; 58 58 int result; 59 59 60 - switch (ifr->ifr_settings.type) { 60 + switch (ifs->type) { 61 61 case IF_GET_PROTO: 62 62 if (dev_to_hdlc(dev)->proto != &proto) 63 63 return -EINVAL; 64 - ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; 65 - if (ifr->ifr_settings.size < size) { 66 - ifr->ifr_settings.size = size; /* data size wanted */ 64 + ifs->type = IF_PROTO_HDLC_ETH; 65 + if (ifs->size < size) { 66 + ifs->size = size; /* data size wanted */ 67 67 return -ENOBUFS; 68 68 } 69 69 if (copy_to_user(raw_s, hdlc->state, size))
+8 -8
drivers/net/wan/hdlc_x25.c
··· 29 29 struct tasklet_struct rx_tasklet; 30 30 }; 31 31 32 - static int x25_ioctl(struct net_device *dev, struct ifreq *ifr); 32 + static int x25_ioctl(struct net_device *dev, struct if_settings *ifs); 33 33 34 34 static struct x25_state *state(hdlc_device *hdlc) 35 35 { ··· 274 274 .module = THIS_MODULE, 275 275 }; 276 276 277 - static int x25_ioctl(struct net_device *dev, struct ifreq *ifr) 277 + static int x25_ioctl(struct net_device *dev, struct if_settings *ifs) 278 278 { 279 - x25_hdlc_proto __user *x25_s = ifr->ifr_settings.ifs_ifsu.x25; 279 + x25_hdlc_proto __user *x25_s = ifs->ifs_ifsu.x25; 280 280 const size_t size = sizeof(x25_hdlc_proto); 281 281 hdlc_device *hdlc = dev_to_hdlc(dev); 282 282 x25_hdlc_proto new_settings; 283 283 int result; 284 284 285 - switch (ifr->ifr_settings.type) { 285 + switch (ifs->type) { 286 286 case IF_GET_PROTO: 287 287 if (dev_to_hdlc(dev)->proto != &proto) 288 288 return -EINVAL; 289 - ifr->ifr_settings.type = IF_PROTO_X25; 290 - if (ifr->ifr_settings.size < size) { 291 - ifr->ifr_settings.size = size; /* data size wanted */ 289 + ifs->type = IF_PROTO_X25; 290 + if (ifs->size < size) { 291 + ifs->size = size; /* data size wanted */ 292 292 return -ENOBUFS; 293 293 } 294 294 if (copy_to_user(x25_s, &state(hdlc)->settings, size)) ··· 303 303 return -EBUSY; 304 304 305 305 /* backward compatibility */ 306 - if (ifr->ifr_settings.size == 0) { 306 + if (ifs->size == 0) { 307 307 new_settings.dce = 0; 308 308 new_settings.modulo = 8; 309 309 new_settings.window = 7;
+1 -6
drivers/net/wan/hostess_sv11.c
··· 142 142 return 0; 143 143 } 144 144 145 - static int hostess_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) 146 - { 147 - return hdlc_ioctl(d, ifr, cmd); 148 - } 149 - 150 145 /* Passed network frames, fire them downwind. 151 146 */ 152 147 ··· 166 171 .ndo_open = hostess_open, 167 172 .ndo_stop = hostess_close, 168 173 .ndo_start_xmit = hdlc_start_xmit, 169 - .ndo_do_ioctl = hostess_ioctl, 174 + .ndo_siocwandev = hdlc_ioctl, 170 175 }; 171 176 172 177 static struct z8530_dev *sv11_init(int iobase, int irq)
+8 -11
drivers/net/wan/ixp4xx_hss.c
··· 1254 1254 } 1255 1255 } 1256 1256 1257 - static int hss_hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 1257 + static int hss_hdlc_ioctl(struct net_device *dev, struct if_settings *ifs) 1258 1258 { 1259 1259 const size_t size = sizeof(sync_serial_settings); 1260 1260 sync_serial_settings new_line; 1261 - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; 1261 + sync_serial_settings __user *line = ifs->ifs_ifsu.sync; 1262 1262 struct port *port = dev_to_port(dev); 1263 1263 unsigned long flags; 1264 1264 int clk; 1265 1265 1266 - if (cmd != SIOCWANDEV) 1267 - return hdlc_ioctl(dev, ifr, cmd); 1268 - 1269 - switch (ifr->ifr_settings.type) { 1266 + switch (ifs->type) { 1270 1267 case IF_GET_IFACE: 1271 - ifr->ifr_settings.type = IF_IFACE_V35; 1272 - if (ifr->ifr_settings.size < size) { 1273 - ifr->ifr_settings.size = size; /* data size wanted */ 1268 + ifs->type = IF_IFACE_V35; 1269 + if (ifs->size < size) { 1270 + ifs->size = size; /* data size wanted */ 1274 1271 return -ENOBUFS; 1275 1272 } 1276 1273 memset(&new_line, 0, sizeof(new_line)); ··· 1320 1323 return 0; 1321 1324 1322 1325 default: 1323 - return hdlc_ioctl(dev, ifr, cmd); 1326 + return hdlc_ioctl(dev, ifs); 1324 1327 } 1325 1328 } 1326 1329 ··· 1332 1335 .ndo_open = hss_hdlc_open, 1333 1336 .ndo_stop = hss_hdlc_close, 1334 1337 .ndo_start_xmit = hdlc_start_xmit, 1335 - .ndo_do_ioctl = hss_hdlc_ioctl, 1338 + .ndo_siocwandev = hss_hdlc_ioctl, 1336 1339 }; 1337 1340 1338 1341 static int hss_init_one(struct platform_device *pdev)
+1 -1
drivers/net/wan/lmc/lmc.h
··· 19 19 void lmc_gpio_mkinput(lmc_softc_t * const sc, u32 bits); 20 20 void lmc_gpio_mkoutput(lmc_softc_t * const sc, u32 bits); 21 21 22 - int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 22 + int lmc_ioctl(struct net_device *dev, struct if_settings *ifs); 23 23 24 24 extern lmc_media_t lmc_ds3_media; 25 25 extern lmc_media_t lmc_ssi_media;
+1 -9
drivers/net/wan/lmc/lmc_main.c
··· 616 616 return ret; 617 617 } 618 618 619 - int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 620 - { 621 - if (cmd != SIOCWANDEV) 622 - return -EOPNOTSUPP; 623 - 624 - return lmc_proto_ioctl(dev_to_sc(dev), ifr, cmd); 625 - } 626 - 627 619 628 620 /* the watchdog process that cruises around */ 629 621 static void lmc_watchdog(struct timer_list *t) /*fold00*/ ··· 786 794 .ndo_open = lmc_open, 787 795 .ndo_stop = lmc_close, 788 796 .ndo_start_xmit = hdlc_start_xmit, 789 - .ndo_do_ioctl = lmc_ioctl, 797 + .ndo_siocwandev = hdlc_ioctl, 790 798 .ndo_siocdevprivate = lmc_siocdevprivate, 791 799 .ndo_tx_timeout = lmc_driver_timeout, 792 800 .ndo_get_stats = lmc_get_stats,
-7
drivers/net/wan/lmc/lmc_proto.c
··· 58 58 } 59 59 } 60 60 61 - int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd) 62 - { 63 - if (sc->if_type == LMC_PPP) 64 - return hdlc_ioctl(sc->lmc_device, ifr, cmd); 65 - return -EOPNOTSUPP; 66 - } 67 - 68 61 int lmc_proto_open(lmc_softc_t *sc) 69 62 { 70 63 int ret = 0;
-1
drivers/net/wan/lmc/lmc_proto.h
··· 5 5 #include <linux/hdlc.h> 6 6 7 7 void lmc_proto_attach(lmc_softc_t *sc); 8 - int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd); 9 8 int lmc_proto_open(lmc_softc_t *sc); 10 9 void lmc_proto_close(lmc_softc_t *sc); 11 10 __be16 lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
+8 -11
drivers/net/wan/n2.c
··· 239 239 return -EOPNOTSUPP; 240 240 } 241 241 242 - static int n2_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 242 + static int n2_ioctl(struct net_device *dev, struct if_settings *ifs) 243 243 { 244 244 const size_t size = sizeof(sync_serial_settings); 245 245 sync_serial_settings new_line; 246 - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; 246 + sync_serial_settings __user *line = ifs->ifs_ifsu.sync; 247 247 port_t *port = dev_to_port(dev); 248 248 249 - if (cmd != SIOCWANDEV) 250 - return hdlc_ioctl(dev, ifr, cmd); 251 - 252 - switch (ifr->ifr_settings.type) { 249 + switch (ifs->type) { 253 250 case IF_GET_IFACE: 254 - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; 255 - if (ifr->ifr_settings.size < size) { 256 - ifr->ifr_settings.size = size; /* data size wanted */ 251 + ifs->type = IF_IFACE_SYNC_SERIAL; 252 + if (ifs->size < size) { 253 + ifs->size = size; /* data size wanted */ 257 254 return -ENOBUFS; 258 255 } 259 256 if (copy_to_user(line, &port->settings, size)) ··· 278 281 return 0; 279 282 280 283 default: 281 - return hdlc_ioctl(dev, ifr, cmd); 284 + return hdlc_ioctl(dev, ifs); 282 285 } 283 286 } 284 287 ··· 314 317 .ndo_open = n2_open, 315 318 .ndo_stop = n2_close, 316 319 .ndo_start_xmit = hdlc_start_xmit, 317 - .ndo_do_ioctl = n2_ioctl, 320 + .ndo_siocwandev = n2_ioctl, 318 321 .ndo_siocdevprivate = n2_siocdevprivate, 319 322 }; 320 323
+13 -16
drivers/net/wan/pc300too.c
··· 186 186 return -EOPNOTSUPP; 187 187 } 188 188 189 - static int pc300_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 189 + static int pc300_ioctl(struct net_device *dev, struct if_settings *ifs) 190 190 { 191 191 const size_t size = sizeof(sync_serial_settings); 192 192 sync_serial_settings new_line; 193 - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; 193 + sync_serial_settings __user *line = ifs->ifs_ifsu.sync; 194 194 int new_type; 195 195 port_t *port = dev_to_port(dev); 196 196 197 - if (cmd != SIOCWANDEV) 198 - return hdlc_ioctl(dev, ifr, cmd); 199 - 200 - if (ifr->ifr_settings.type == IF_GET_IFACE) { 201 - ifr->ifr_settings.type = port->iface; 202 - if (ifr->ifr_settings.size < size) { 203 - ifr->ifr_settings.size = size; /* data size wanted */ 197 + if (ifs->type == IF_GET_IFACE) { 198 + ifs->type = port->iface; 199 + if (ifs->size < size) { 200 + ifs->size = size; /* data size wanted */ 204 201 return -ENOBUFS; 205 202 } 206 203 if (copy_to_user(line, &port->settings, size)) ··· 206 209 } 207 210 208 211 if (port->card->type == PC300_X21 && 209 - (ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL || 210 - ifr->ifr_settings.type == IF_IFACE_X21)) 212 + (ifs->type == IF_IFACE_SYNC_SERIAL || 213 + ifs->type == IF_IFACE_X21)) 211 214 new_type = IF_IFACE_X21; 212 215 213 216 else if (port->card->type == PC300_RSV && 214 - (ifr->ifr_settings.type == IF_IFACE_SYNC_SERIAL || 215 - ifr->ifr_settings.type == IF_IFACE_V35)) 217 + (ifs->type == IF_IFACE_SYNC_SERIAL || 218 + ifs->type == IF_IFACE_V35)) 216 219 new_type = IF_IFACE_V35; 217 220 218 221 else if (port->card->type == PC300_RSV && 219 - ifr->ifr_settings.type == IF_IFACE_V24) 222 + ifs->type == IF_IFACE_V24) 220 223 new_type = IF_IFACE_V24; 221 224 222 225 else 223 - return hdlc_ioctl(dev, ifr, cmd); 226 + return hdlc_ioctl(dev, ifs); 224 227 225 228 if (!capable(CAP_NET_ADMIN)) 226 229 return -EPERM; ··· 275 278 .ndo_open = pc300_open, 276 279 .ndo_stop = pc300_close, 277 280 .ndo_start_xmit = hdlc_start_xmit, 278 - .ndo_do_ioctl = pc300_ioctl, 281 + .ndo_siocwandev = pc300_ioctl, 279 282 .ndo_siocdevprivate = pc300_siocdevprivate, 280 283 }; 281 284
+8 -11
drivers/net/wan/pci200syn.c
··· 179 179 return -EOPNOTSUPP; 180 180 } 181 181 182 - static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 182 + static int pci200_ioctl(struct net_device *dev, struct if_settings *ifs) 183 183 { 184 184 const size_t size = sizeof(sync_serial_settings); 185 185 sync_serial_settings new_line; 186 - sync_serial_settings __user *line = ifr->ifr_settings.ifs_ifsu.sync; 186 + sync_serial_settings __user *line = ifs->ifs_ifsu.sync; 187 187 port_t *port = dev_to_port(dev); 188 188 189 - if (cmd != SIOCWANDEV) 190 - return hdlc_ioctl(dev, ifr, cmd); 191 - 192 - switch (ifr->ifr_settings.type) { 189 + switch (ifs->type) { 193 190 case IF_GET_IFACE: 194 - ifr->ifr_settings.type = IF_IFACE_V35; 195 - if (ifr->ifr_settings.size < size) { 196 - ifr->ifr_settings.size = size; /* data size wanted */ 191 + ifs->type = IF_IFACE_V35; 192 + if (ifs->size < size) { 193 + ifs->size = size; /* data size wanted */ 197 194 return -ENOBUFS; 198 195 } 199 196 if (copy_to_user(line, &port->settings, size)) ··· 220 223 return 0; 221 224 222 225 default: 223 - return hdlc_ioctl(dev, ifr, cmd); 226 + return hdlc_ioctl(dev, ifs); 224 227 } 225 228 } 226 229 ··· 256 259 .ndo_open = pci200_open, 257 260 .ndo_stop = pci200_close, 258 261 .ndo_start_xmit = hdlc_start_xmit, 259 - .ndo_do_ioctl = pci200_ioctl, 262 + .ndo_siocwandev = pci200_ioctl, 260 263 .ndo_siocdevprivate = pci200_siocdevprivate, 261 264 }; 262 265
+1 -9
drivers/net/wan/sealevel.c
··· 124 124 return 0; 125 125 } 126 126 127 - static int sealevel_ioctl(struct net_device *d, struct ifreq *ifr, int cmd) 128 - { 129 - /* struct slvl_device *slvl=dev_to_chan(d); 130 - * z8530_ioctl(d,&slvl->sync.chanA,ifr,cmd) 131 - */ 132 - return hdlc_ioctl(d, ifr, cmd); 133 - } 134 - 135 127 /* Passed network frames, fire them downwind. */ 136 128 137 129 static netdev_tx_t sealevel_queue_xmit(struct sk_buff *skb, ··· 144 152 .ndo_open = sealevel_open, 145 153 .ndo_stop = sealevel_close, 146 154 .ndo_start_xmit = hdlc_start_xmit, 147 - .ndo_do_ioctl = sealevel_ioctl, 155 + .ndo_siocwandev = hdlc_ioctl, 148 156 }; 149 157 150 158 static int slvl_setup(struct slvl_device *sv, int iobase, int irq)
+9 -12
drivers/net/wan/wanxl.c
··· 343 343 return 0; 344 344 } 345 345 346 - static int wanxl_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 346 + static int wanxl_ioctl(struct net_device *dev, struct if_settings *ifs) 347 347 { 348 348 const size_t size = sizeof(sync_serial_settings); 349 349 sync_serial_settings line; 350 350 struct port *port = dev_to_port(dev); 351 351 352 - if (cmd != SIOCWANDEV) 353 - return hdlc_ioctl(dev, ifr, cmd); 354 - 355 - switch (ifr->ifr_settings.type) { 352 + switch (ifs->type) { 356 353 case IF_GET_IFACE: 357 - ifr->ifr_settings.type = IF_IFACE_SYNC_SERIAL; 358 - if (ifr->ifr_settings.size < size) { 359 - ifr->ifr_settings.size = size; /* data size wanted */ 354 + ifs->type = IF_IFACE_SYNC_SERIAL; 355 + if (ifs->size < size) { 356 + ifs->size = size; /* data size wanted */ 360 357 return -ENOBUFS; 361 358 } 362 359 memset(&line, 0, sizeof(line)); ··· 361 364 line.clock_rate = 0; 362 365 line.loopback = 0; 363 366 364 - if (copy_to_user(ifr->ifr_settings.ifs_ifsu.sync, &line, size)) 367 + if (copy_to_user(ifs->ifs_ifsu.sync, &line, size)) 365 368 return -EFAULT; 366 369 return 0; 367 370 ··· 371 374 if (dev->flags & IFF_UP) 372 375 return -EBUSY; 373 376 374 - if (copy_from_user(&line, ifr->ifr_settings.ifs_ifsu.sync, 377 + if (copy_from_user(&line, ifs->ifs_ifsu.sync, 375 378 size)) 376 379 return -EFAULT; 377 380 ··· 386 389 return 0; 387 390 388 391 default: 389 - return hdlc_ioctl(dev, ifr, cmd); 392 + return hdlc_ioctl(dev, ifs); 390 393 } 391 394 } 392 395 ··· 542 545 .ndo_open = wanxl_open, 543 546 .ndo_stop = wanxl_close, 544 547 .ndo_start_xmit = hdlc_start_xmit, 545 - .ndo_do_ioctl = wanxl_ioctl, 548 + .ndo_siocwandev = wanxl_ioctl, 546 549 .ndo_get_stats = wanxl_get_stats, 547 550 }; 548 551
+2 -2
include/linux/hdlc.h
··· 22 22 void (*start)(struct net_device *dev); /* if open & DCD */ 23 23 void (*stop)(struct net_device *dev); /* if open & !DCD */ 24 24 void (*detach)(struct net_device *dev); 25 - int (*ioctl)(struct net_device *dev, struct ifreq *ifr); 25 + int (*ioctl)(struct net_device *dev, struct if_settings *ifs); 26 26 __be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev); 27 27 int (*netif_rx)(struct sk_buff *skb); 28 28 netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev); ··· 54 54 /* Exported from hdlc module */ 55 55 56 56 /* Called by hardware driver when a user requests HDLC service */ 57 - int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 57 + int hdlc_ioctl(struct net_device *dev, struct if_settings *ifs); 58 58 59 59 /* Must be used by hardware driver on module startup/exit */ 60 60 #define register_hdlc_device(dev) register_netdev(dev)
+2
include/linux/netdevice.h
··· 1367 1367 struct ifreq *ifr, int cmd); 1368 1368 int (*ndo_eth_ioctl)(struct net_device *dev, 1369 1369 struct ifreq *ifr, int cmd); 1370 + int (*ndo_siocwandev)(struct net_device *dev, 1371 + struct if_settings *ifs); 1370 1372 int (*ndo_siocdevprivate)(struct net_device *dev, 1371 1373 struct ifreq *ifr, 1372 1374 void __user *data, int cmd);
+18 -2
net/core/dev_ioctl.c
··· 291 291 return dev_do_ioctl(dev, ifr, cmd); 292 292 } 293 293 294 + static int dev_siocwandev(struct net_device *dev, struct if_settings *ifs) 295 + { 296 + const struct net_device_ops *ops = dev->netdev_ops; 297 + 298 + if (ops->ndo_siocwandev) { 299 + if (netif_device_present(dev)) 300 + return ops->ndo_siocwandev(dev, ifs); 301 + else 302 + return -ENODEV; 303 + } 304 + 305 + return -EOPNOTSUPP; 306 + } 307 + 294 308 /* 295 309 * Perform the SIOCxIFxxx calls, inside rtnl_lock() 296 310 */ ··· 373 359 ifr->ifr_newname[IFNAMSIZ-1] = '\0'; 374 360 return dev_change_name(dev, ifr->ifr_newname); 375 361 362 + case SIOCWANDEV: 363 + return dev_siocwandev(dev, &ifr->ifr_settings); 364 + 376 365 case SIOCSHWTSTAMP: 377 366 err = net_hwtstamp_validate(ifr); 378 367 if (err) ··· 403 386 cmd == SIOCBONDINFOQUERY || 404 387 cmd == SIOCBONDCHANGEACTIVE || 405 388 cmd == SIOCBRADDIF || 406 - cmd == SIOCBRDELIF || 407 - cmd == SIOCWANDEV) { 389 + cmd == SIOCBRDELIF) { 408 390 err = dev_do_ioctl(dev, ifr, cmd); 409 391 } else 410 392 err = -EINVAL;