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

net: bridge: move bridge ioctls out of .ndo_do_ioctl

Working towards obsoleting the .ndo_do_ioctl operation entirely,
stop passing the SIOCBRADDIF/SIOCBRDELIF device ioctl commands
into this callback.

My first attempt was to add another ndo_siocbr() callback, but
as there is only a single driver that takes these commands and
there is already a hook mechanism to call directly into this
driver, extend this hook instead, and use it for both the
deviceless and the device specific ioctl commands.

Cc: Roopa Prabhu <roopa@nvidia.com>
Cc: Nikolay Aleksandrov <nikolay@nvidia.com>
Cc: bridge@lists.linux-foundation.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
ad2f99ae 88fc023f

+43 -31
+6 -1
include/linux/if_bridge.h
··· 61 61 62 62 #define BR_DEFAULT_AGEING_TIME (300 * HZ) 63 63 64 - extern void brioctl_set(int (*ioctl_hook)(struct net *, unsigned int, void __user *)); 64 + struct net_bridge; 65 + void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, 66 + unsigned int cmd, struct ifreq *ifr, 67 + void __user *uarg)); 68 + int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, 69 + struct ifreq *ifr, void __user *uarg); 65 70 66 71 #if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING) 67 72 int br_multicast_list_adjacent(struct net_device *dev,
+1 -1
net/bridge/br.c
··· 359 359 if (err) 360 360 goto err_out5; 361 361 362 - brioctl_set(br_ioctl_deviceless_stub); 362 + brioctl_set(br_ioctl_stub); 363 363 364 364 #if IS_ENABLED(CONFIG_ATM_LANE) 365 365 br_fdb_test_addr_hook = br_fdb_test_addr;
-1
net/bridge/br_device.c
··· 454 454 .ndo_set_rx_mode = br_dev_set_multicast_list, 455 455 .ndo_change_rx_flags = br_dev_change_rx_flags, 456 456 .ndo_change_mtu = br_change_mtu, 457 - .ndo_do_ioctl = br_dev_ioctl, 458 457 .ndo_siocdevprivate = br_dev_siocdevprivate, 459 458 #ifdef CONFIG_NET_POLL_CONTROLLER 460 459 .ndo_netpoll_setup = br_netpoll_setup,
+3 -12
net/bridge/br_ioctl.c
··· 366 366 return -EOPNOTSUPP; 367 367 } 368 368 369 - int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, void __user *uarg) 369 + int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd, 370 + struct ifreq *ifr, void __user *uarg) 370 371 { 371 372 switch (cmd) { 372 373 case SIOCGIFBR: ··· 391 390 392 391 return br_del_bridge(net, buf); 393 392 } 394 - } 395 - return -EOPNOTSUPP; 396 - } 397 393 398 - int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) 399 - { 400 - struct net_bridge *br = netdev_priv(dev); 401 - 402 - switch (cmd) { 403 394 case SIOCBRADDIF: 404 395 case SIOCBRDELIF: 405 - return add_del_if(br, rq->ifr_ifindex, cmd == SIOCBRADDIF); 396 + return add_del_if(br, ifr->ifr_ifindex, cmd == SIOCBRADDIF); 406 397 407 398 } 408 - 409 - br_debug(br, "Bridge does not support ioctl 0x%x\n", cmd); 410 399 return -EOPNOTSUPP; 411 400 }
+2 -3
net/bridge/br_private.h
··· 851 851 } 852 852 853 853 /* br_ioctl.c */ 854 - int br_dev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); 855 854 int br_dev_siocdevprivate(struct net_device *dev, struct ifreq *rq, 856 855 void __user *data, int cmd); 857 - int br_ioctl_deviceless_stub(struct net *net, unsigned int cmd, 858 - void __user *arg); 856 + int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd, 857 + struct ifreq *ifr, void __user *uarg); 859 858 860 859 /* br_multicast.c */ 861 860 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
+8 -3
net/core/dev_ioctl.c
··· 6 6 #include <linux/rtnetlink.h> 7 7 #include <linux/net_tstamp.h> 8 8 #include <linux/wireless.h> 9 + #include <linux/if_bridge.h> 9 10 #include <net/dsa.h> 10 11 #include <net/wext.h> 11 12 ··· 375 374 case SIOCWANDEV: 376 375 return dev_siocwandev(dev, &ifr->ifr_settings); 377 376 377 + case SIOCBRADDIF: 378 + case SIOCBRDELIF: 379 + if (!netif_device_present(dev)) 380 + return -ENODEV; 381 + return br_ioctl_call(net, netdev_priv(dev), cmd, ifr, NULL); 382 + 378 383 case SIOCSHWTSTAMP: 379 384 err = net_hwtstamp_validate(ifr); 380 385 if (err) ··· 406 399 cmd == SIOCBONDSETHWADDR || 407 400 cmd == SIOCBONDSLAVEINFOQUERY || 408 401 cmd == SIOCBONDINFOQUERY || 409 - cmd == SIOCBONDCHANGEACTIVE || 410 - cmd == SIOCBRADDIF || 411 - cmd == SIOCBRDELIF) { 402 + cmd == SIOCBONDCHANGEACTIVE) { 412 403 err = dev_do_ioctl(dev, ifr, cmd); 413 404 } else 414 405 err = -EINVAL;
+23 -10
net/socket.c
··· 1064 1064 */ 1065 1065 1066 1066 static DEFINE_MUTEX(br_ioctl_mutex); 1067 - static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg); 1067 + static int (*br_ioctl_hook)(struct net *net, struct net_bridge *br, 1068 + unsigned int cmd, struct ifreq *ifr, 1069 + void __user *uarg); 1068 1070 1069 - void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) 1071 + void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br, 1072 + unsigned int cmd, struct ifreq *ifr, 1073 + void __user *uarg)) 1070 1074 { 1071 1075 mutex_lock(&br_ioctl_mutex); 1072 1076 br_ioctl_hook = hook; 1073 1077 mutex_unlock(&br_ioctl_mutex); 1074 1078 } 1075 1079 EXPORT_SYMBOL(brioctl_set); 1080 + 1081 + int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd, 1082 + struct ifreq *ifr, void __user *uarg) 1083 + { 1084 + int err = -ENOPKG; 1085 + 1086 + if (!br_ioctl_hook) 1087 + request_module("bridge"); 1088 + 1089 + mutex_lock(&br_ioctl_mutex); 1090 + if (br_ioctl_hook) 1091 + err = br_ioctl_hook(net, br, cmd, ifr, uarg); 1092 + mutex_unlock(&br_ioctl_mutex); 1093 + 1094 + return err; 1095 + } 1076 1096 1077 1097 static DEFINE_MUTEX(vlan_ioctl_mutex); 1078 1098 static int (*vlan_ioctl_hook) (struct net *, void __user *arg); ··· 1182 1162 case SIOCSIFBR: 1183 1163 case SIOCBRADDBR: 1184 1164 case SIOCBRDELBR: 1185 - err = -ENOPKG; 1186 - if (!br_ioctl_hook) 1187 - request_module("bridge"); 1188 - 1189 - mutex_lock(&br_ioctl_mutex); 1190 - if (br_ioctl_hook) 1191 - err = br_ioctl_hook(net, cmd, argp); 1192 - mutex_unlock(&br_ioctl_mutex); 1165 + err = br_ioctl_call(net, NULL, cmd, NULL, argp); 1193 1166 break; 1194 1167 case SIOCGIFVLAN: 1195 1168 case SIOCSIFVLAN: