aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@vyatta.com>2008-11-20 00:32:24 -0500
committerDavid S. Miller <davem@davemloft.net>2008-11-20 00:32:24 -0500
commitd314774cf2cd5dfeb39a00d37deee65d4c627927 (patch)
tree1c7778b509cea814aa2b7115949667941037d07c /net/core
parent6b41e7dd90c6a628ab5fb8d781302d60a243b2ce (diff)
netdev: network device operations infrastructure
This patch changes the network device internal API to move adminstrative operations out of the network device structure and into a separate structure. This patch involves some hackery to maintain compatablity between the new and old model, so all 300+ drivers don't have to be changed at once. For drivers that aren't converted yet, the netdevice_ops virt function list still resides in the net_device structure. For old protocols, the new net_device_ops are copied out to the old net_device pointers. After the transistion is completed the nag message can be changed to an WARN_ON, and the compatiablity code can be made configurable. Some function pointers aren't moved: * destructor can't be in net_device_ops because it may need to be referenced after the module is unloaded. * neighbor setup is manipulated in a couple of places that need special consideration * hard_start_xmit is in the fast path for transmit. Signed-off-by: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c109
-rw-r--r--net/core/netpoll.c7
-rw-r--r--net/core/rtnetlink.c9
3 files changed, 86 insertions, 39 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index e08c0fcd603b..ca14ab407b33 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1059,6 +1059,7 @@ void dev_load(struct net *net, const char *name)
1059 */ 1059 */
1060int dev_open(struct net_device *dev) 1060int dev_open(struct net_device *dev)
1061{ 1061{
1062 const struct net_device_ops *ops = dev->netdev_ops;
1062 int ret = 0; 1063 int ret = 0;
1063 1064
1064 ASSERT_RTNL(); 1065 ASSERT_RTNL();
@@ -1081,11 +1082,11 @@ int dev_open(struct net_device *dev)
1081 */ 1082 */
1082 set_bit(__LINK_STATE_START, &dev->state); 1083 set_bit(__LINK_STATE_START, &dev->state);
1083 1084
1084 if (dev->validate_addr) 1085 if (ops->ndo_validate_addr)
1085 ret = dev->validate_addr(dev); 1086 ret = ops->ndo_validate_addr(dev);
1086 1087
1087 if (!ret && dev->open) 1088 if (!ret && ops->ndo_open)
1088 ret = dev->open(dev); 1089 ret = ops->ndo_open(dev);
1089 1090
1090 /* 1091 /*
1091 * If it went open OK then: 1092 * If it went open OK then:
@@ -1129,6 +1130,7 @@ int dev_open(struct net_device *dev)
1129 */ 1130 */
1130int dev_close(struct net_device *dev) 1131int dev_close(struct net_device *dev)
1131{ 1132{
1133 const struct net_device_ops *ops = dev->netdev_ops;
1132 ASSERT_RTNL(); 1134 ASSERT_RTNL();
1133 1135
1134 might_sleep(); 1136 might_sleep();
@@ -1161,8 +1163,8 @@ int dev_close(struct net_device *dev)
1161 * We allow it to be called even after a DETACH hot-plug 1163 * We allow it to be called even after a DETACH hot-plug
1162 * event. 1164 * event.
1163 */ 1165 */
1164 if (dev->stop) 1166 if (ops->ndo_stop)
1165 dev->stop(dev); 1167 ops->ndo_stop(dev);
1166 1168
1167 /* 1169 /*
1168 * Device is now down. 1170 * Device is now down.
@@ -2930,8 +2932,10 @@ int netdev_set_master(struct net_device *slave, struct net_device *master)
2930 2932
2931static void dev_change_rx_flags(struct net_device *dev, int flags) 2933static void dev_change_rx_flags(struct net_device *dev, int flags)
2932{ 2934{
2933 if (dev->flags & IFF_UP && dev->change_rx_flags) 2935 const struct net_device_ops *ops = dev->netdev_ops;
2934 dev->change_rx_flags(dev, flags); 2936
2937 if ((dev->flags & IFF_UP) && ops->ndo_change_rx_flags)
2938 ops->ndo_change_rx_flags(dev, flags);
2935} 2939}
2936 2940
2937static int __dev_set_promiscuity(struct net_device *dev, int inc) 2941static int __dev_set_promiscuity(struct net_device *dev, int inc)
@@ -3051,6 +3055,8 @@ int dev_set_allmulti(struct net_device *dev, int inc)
3051 */ 3055 */
3052void __dev_set_rx_mode(struct net_device *dev) 3056void __dev_set_rx_mode(struct net_device *dev)
3053{ 3057{
3058 const struct net_device_ops *ops = dev->netdev_ops;
3059
3054 /* dev_open will call this function so the list will stay sane. */ 3060 /* dev_open will call this function so the list will stay sane. */
3055 if (!(dev->flags&IFF_UP)) 3061 if (!(dev->flags&IFF_UP))
3056 return; 3062 return;
@@ -3058,8 +3064,8 @@ void __dev_set_rx_mode(struct net_device *dev)
3058 if (!netif_device_present(dev)) 3064 if (!netif_device_present(dev))
3059 return; 3065 return;
3060 3066
3061 if (dev->set_rx_mode) 3067 if (ops->ndo_set_rx_mode)
3062 dev->set_rx_mode(dev); 3068 ops->ndo_set_rx_mode(dev);
3063 else { 3069 else {
3064 /* Unicast addresses changes may only happen under the rtnl, 3070 /* Unicast addresses changes may only happen under the rtnl,
3065 * therefore calling __dev_set_promiscuity here is safe. 3071 * therefore calling __dev_set_promiscuity here is safe.
@@ -3072,8 +3078,8 @@ void __dev_set_rx_mode(struct net_device *dev)
3072 dev->uc_promisc = 0; 3078 dev->uc_promisc = 0;
3073 } 3079 }
3074 3080
3075 if (dev->set_multicast_list) 3081 if (ops->ndo_set_multicast_list)
3076 dev->set_multicast_list(dev); 3082 ops->ndo_set_multicast_list(dev);
3077 } 3083 }
3078} 3084}
3079 3085
@@ -3432,6 +3438,7 @@ int dev_change_flags(struct net_device *dev, unsigned flags)
3432 */ 3438 */
3433int dev_set_mtu(struct net_device *dev, int new_mtu) 3439int dev_set_mtu(struct net_device *dev, int new_mtu)
3434{ 3440{
3441 const struct net_device_ops *ops = dev->netdev_ops;
3435 int err; 3442 int err;
3436 3443
3437 if (new_mtu == dev->mtu) 3444 if (new_mtu == dev->mtu)
@@ -3445,10 +3452,11 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
3445 return -ENODEV; 3452 return -ENODEV;
3446 3453
3447 err = 0; 3454 err = 0;
3448 if (dev->change_mtu) 3455 if (ops->ndo_change_mtu)
3449 err = dev->change_mtu(dev, new_mtu); 3456 err = ops->ndo_change_mtu(dev, new_mtu);
3450 else 3457 else
3451 dev->mtu = new_mtu; 3458 dev->mtu = new_mtu;
3459
3452 if (!err && dev->flags & IFF_UP) 3460 if (!err && dev->flags & IFF_UP)
3453 call_netdevice_notifiers(NETDEV_CHANGEMTU, dev); 3461 call_netdevice_notifiers(NETDEV_CHANGEMTU, dev);
3454 return err; 3462 return err;
@@ -3463,15 +3471,16 @@ int dev_set_mtu(struct net_device *dev, int new_mtu)
3463 */ 3471 */
3464int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa) 3472int dev_set_mac_address(struct net_device *dev, struct sockaddr *sa)
3465{ 3473{
3474 const struct net_device_ops *ops = dev->netdev_ops;
3466 int err; 3475 int err;
3467 3476
3468 if (!dev->set_mac_address) 3477 if (!ops->ndo_set_mac_address)
3469 return -EOPNOTSUPP; 3478 return -EOPNOTSUPP;
3470 if (sa->sa_family != dev->type) 3479 if (sa->sa_family != dev->type)
3471 return -EINVAL; 3480 return -EINVAL;
3472 if (!netif_device_present(dev)) 3481 if (!netif_device_present(dev))
3473 return -ENODEV; 3482 return -ENODEV;
3474 err = dev->set_mac_address(dev, sa); 3483 err = ops->ndo_set_mac_address(dev, sa);
3475 if (!err) 3484 if (!err)
3476 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); 3485 call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
3477 return err; 3486 return err;
@@ -3551,6 +3560,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
3551{ 3560{
3552 int err; 3561 int err;
3553 struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name); 3562 struct net_device *dev = __dev_get_by_name(net, ifr->ifr_name);
3563 const struct net_device_ops *ops = dev->netdev_ops;
3554 3564
3555 if (!dev) 3565 if (!dev)
3556 return -ENODEV; 3566 return -ENODEV;
@@ -3578,15 +3588,15 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
3578 return 0; 3588 return 0;
3579 3589
3580 case SIOCSIFMAP: 3590 case SIOCSIFMAP:
3581 if (dev->set_config) { 3591 if (ops->ndo_set_config) {
3582 if (!netif_device_present(dev)) 3592 if (!netif_device_present(dev))
3583 return -ENODEV; 3593 return -ENODEV;
3584 return dev->set_config(dev, &ifr->ifr_map); 3594 return ops->ndo_set_config(dev, &ifr->ifr_map);
3585 } 3595 }
3586 return -EOPNOTSUPP; 3596 return -EOPNOTSUPP;
3587 3597
3588 case SIOCADDMULTI: 3598 case SIOCADDMULTI:
3589 if ((!dev->set_multicast_list && !dev->set_rx_mode) || 3599 if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
3590 ifr->ifr_hwaddr.sa_family != AF_UNSPEC) 3600 ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
3591 return -EINVAL; 3601 return -EINVAL;
3592 if (!netif_device_present(dev)) 3602 if (!netif_device_present(dev))
@@ -3595,7 +3605,7 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
3595 dev->addr_len, 1); 3605 dev->addr_len, 1);
3596 3606
3597 case SIOCDELMULTI: 3607 case SIOCDELMULTI:
3598 if ((!dev->set_multicast_list && !dev->set_rx_mode) || 3608 if ((!ops->ndo_set_multicast_list && !ops->ndo_set_rx_mode) ||
3599 ifr->ifr_hwaddr.sa_family != AF_UNSPEC) 3609 ifr->ifr_hwaddr.sa_family != AF_UNSPEC)
3600 return -EINVAL; 3610 return -EINVAL;
3601 if (!netif_device_present(dev)) 3611 if (!netif_device_present(dev))
@@ -3633,10 +3643,9 @@ static int dev_ifsioc(struct net *net, struct ifreq *ifr, unsigned int cmd)
3633 cmd == SIOCBRDELIF || 3643 cmd == SIOCBRDELIF ||
3634 cmd == SIOCWANDEV) { 3644 cmd == SIOCWANDEV) {
3635 err = -EOPNOTSUPP; 3645 err = -EOPNOTSUPP;
3636 if (dev->do_ioctl) { 3646 if (ops->ndo_do_ioctl) {
3637 if (netif_device_present(dev)) 3647 if (netif_device_present(dev))
3638 err = dev->do_ioctl(dev, ifr, 3648 err = ops->ndo_do_ioctl(dev, ifr, cmd);
3639 cmd);
3640 else 3649 else
3641 err = -ENODEV; 3650 err = -ENODEV;
3642 } 3651 }
@@ -3897,8 +3906,8 @@ static void rollback_registered(struct net_device *dev)
3897 */ 3906 */
3898 dev_addr_discard(dev); 3907 dev_addr_discard(dev);
3899 3908
3900 if (dev->uninit) 3909 if (dev->netdev_ops->ndo_uninit)
3901 dev->uninit(dev); 3910 dev->netdev_ops->ndo_uninit(dev);
3902 3911
3903 /* Notifier chain MUST detach us from master device. */ 3912 /* Notifier chain MUST detach us from master device. */
3904 WARN_ON(dev->master); 3913 WARN_ON(dev->master);
@@ -3988,7 +3997,7 @@ int register_netdevice(struct net_device *dev)
3988 struct hlist_head *head; 3997 struct hlist_head *head;
3989 struct hlist_node *p; 3998 struct hlist_node *p;
3990 int ret; 3999 int ret;
3991 struct net *net; 4000 struct net *net = dev_net(dev);
3992 4001
3993 BUG_ON(dev_boot_phase); 4002 BUG_ON(dev_boot_phase);
3994 ASSERT_RTNL(); 4003 ASSERT_RTNL();
@@ -3997,8 +4006,7 @@ int register_netdevice(struct net_device *dev)
3997 4006
3998 /* When net_device's are persistent, this will be fatal. */ 4007 /* When net_device's are persistent, this will be fatal. */
3999 BUG_ON(dev->reg_state != NETREG_UNINITIALIZED); 4008 BUG_ON(dev->reg_state != NETREG_UNINITIALIZED);
4000 BUG_ON(!dev_net(dev)); 4009 BUG_ON(!net);
4001 net = dev_net(dev);
4002 4010
4003 spin_lock_init(&dev->addr_list_lock); 4011 spin_lock_init(&dev->addr_list_lock);
4004 netdev_set_addr_lockdep_class(dev); 4012 netdev_set_addr_lockdep_class(dev);
@@ -4006,9 +4014,46 @@ int register_netdevice(struct net_device *dev)
4006 4014
4007 dev->iflink = -1; 4015 dev->iflink = -1;
4008 4016
4017#ifdef CONFIG_COMPAT_NET_DEV_OPS
4018 /* Netdevice_ops API compatiability support.
4019 * This is temporary until all network devices are converted.
4020 */
4021 if (dev->netdev_ops) {
4022 const struct net_device_ops *ops = dev->netdev_ops;
4023
4024 dev->init = ops->ndo_init;
4025 dev->uninit = ops->ndo_uninit;
4026 dev->open = ops->ndo_open;
4027 dev->change_rx_flags = ops->ndo_change_rx_flags;
4028 dev->set_rx_mode = ops->ndo_set_rx_mode;
4029 dev->set_multicast_list = ops->ndo_set_multicast_list;
4030 dev->set_mac_address = ops->ndo_set_mac_address;
4031 dev->validate_addr = ops->ndo_validate_addr;
4032 dev->do_ioctl = ops->ndo_do_ioctl;
4033 dev->set_config = ops->ndo_set_config;
4034 dev->change_mtu = ops->ndo_change_mtu;
4035 dev->tx_timeout = ops->ndo_tx_timeout;
4036 dev->get_stats = ops->ndo_get_stats;
4037 dev->vlan_rx_register = ops->ndo_vlan_rx_register;
4038 dev->vlan_rx_add_vid = ops->ndo_vlan_rx_add_vid;
4039 dev->vlan_rx_kill_vid = ops->ndo_vlan_rx_kill_vid;
4040#ifdef CONFIG_NET_POLL_CONTROLLER
4041 dev->poll_controller = ops->ndo_poll_controller;
4042#endif
4043 } else {
4044 char drivername[64];
4045 pr_info("%s (%s): not using net_device_ops yet\n",
4046 dev->name, netdev_drivername(dev, drivername, 64));
4047
4048 /* This works only because net_device_ops and the
4049 compatiablity structure are the same. */
4050 dev->netdev_ops = (void *) &(dev->init);
4051 }
4052#endif
4053
4009 /* Init, if this function is available */ 4054 /* Init, if this function is available */
4010 if (dev->init) { 4055 if (dev->netdev_ops->ndo_init) {
4011 ret = dev->init(dev); 4056 ret = dev->netdev_ops->ndo_init(dev);
4012 if (ret) { 4057 if (ret) {
4013 if (ret > 0) 4058 if (ret > 0)
4014 ret = -EIO; 4059 ret = -EIO;
@@ -4086,8 +4131,8 @@ out:
4086 return ret; 4131 return ret;
4087 4132
4088err_uninit: 4133err_uninit:
4089 if (dev->uninit) 4134 if (dev->netdev_ops->ndo_uninit)
4090 dev->uninit(dev); 4135 dev->netdev_ops->ndo_uninit(dev);
4091 goto out; 4136 goto out;
4092} 4137}
4093 4138
diff --git a/net/core/netpoll.c b/net/core/netpoll.c
index fc4e28e23b89..630df6034444 100644
--- a/net/core/netpoll.c
+++ b/net/core/netpoll.c
@@ -172,12 +172,13 @@ static void service_arp_queue(struct netpoll_info *npi)
172void netpoll_poll(struct netpoll *np) 172void netpoll_poll(struct netpoll *np)
173{ 173{
174 struct net_device *dev = np->dev; 174 struct net_device *dev = np->dev;
175 const struct net_device_ops *ops = dev->netdev_ops;
175 176
176 if (!dev || !netif_running(dev) || !dev->poll_controller) 177 if (!dev || !netif_running(dev) || !ops->ndo_poll_controller)
177 return; 178 return;
178 179
179 /* Process pending work on NIC */ 180 /* Process pending work on NIC */
180 dev->poll_controller(dev); 181 ops->ndo_poll_controller(dev);
181 182
182 poll_napi(dev); 183 poll_napi(dev);
183 184
@@ -694,7 +695,7 @@ int netpoll_setup(struct netpoll *np)
694 atomic_inc(&npinfo->refcnt); 695 atomic_inc(&npinfo->refcnt);
695 } 696 }
696 697
697 if (!ndev->poll_controller) { 698 if (!ndev->netdev_ops->ndo_poll_controller) {
698 printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n", 699 printk(KERN_ERR "%s: %s doesn't support polling, aborting.\n",
699 np->name, np->dev_name); 700 np->name, np->dev_name);
700 err = -ENOTSUPP; 701 err = -ENOTSUPP;
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 4dfb6b4d4559..6f8e0778e565 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -762,6 +762,7 @@ static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[])
762static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, 762static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
763 struct nlattr **tb, char *ifname, int modified) 763 struct nlattr **tb, char *ifname, int modified)
764{ 764{
765 const struct net_device_ops *ops = dev->netdev_ops;
765 int send_addr_notify = 0; 766 int send_addr_notify = 0;
766 int err; 767 int err;
767 768
@@ -783,7 +784,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
783 struct rtnl_link_ifmap *u_map; 784 struct rtnl_link_ifmap *u_map;
784 struct ifmap k_map; 785 struct ifmap k_map;
785 786
786 if (!dev->set_config) { 787 if (!ops->ndo_set_config) {
787 err = -EOPNOTSUPP; 788 err = -EOPNOTSUPP;
788 goto errout; 789 goto errout;
789 } 790 }
@@ -801,7 +802,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
801 k_map.dma = (unsigned char) u_map->dma; 802 k_map.dma = (unsigned char) u_map->dma;
802 k_map.port = (unsigned char) u_map->port; 803 k_map.port = (unsigned char) u_map->port;
803 804
804 err = dev->set_config(dev, &k_map); 805 err = ops->ndo_set_config(dev, &k_map);
805 if (err < 0) 806 if (err < 0)
806 goto errout; 807 goto errout;
807 808
@@ -812,7 +813,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
812 struct sockaddr *sa; 813 struct sockaddr *sa;
813 int len; 814 int len;
814 815
815 if (!dev->set_mac_address) { 816 if (!ops->ndo_set_mac_address) {
816 err = -EOPNOTSUPP; 817 err = -EOPNOTSUPP;
817 goto errout; 818 goto errout;
818 } 819 }
@@ -831,7 +832,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
831 sa->sa_family = dev->type; 832 sa->sa_family = dev->type;
832 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]), 833 memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
833 dev->addr_len); 834 dev->addr_len);
834 err = dev->set_mac_address(dev, sa); 835 err = ops->ndo_set_mac_address(dev, sa);
835 kfree(sa); 836 kfree(sa);
836 if (err) 837 if (err)
837 goto errout; 838 goto errout;