9362 /**
9363 * unregister_netdev - remove device from the kernel
9364 * @dev: device
9365 *
9366 * This function shuts down a device interface and removes it
9367 * from the kernel tables.
9368 *
9369 * This is just a wrapper for unregister_netdevice that takes
9370 * the rtnl semaphore. In general you want to use this and not
9371 * unregister_netdevice.
9372 */
9373 void unregister_netdev(struct net_device *dev)
9374 {
9375 rtnl_lock();
9376 unregister_netdevice(dev);
9377 rtnl_unlock();
9378 }
9379 EXPORT_SYMBOL(unregister_netdev);
2665 static inline void unregister_netdevice(struct net_device *dev)
2666 {
2667 unregister_netdevice_queue(dev, NULL);
2668 }
9315 /**
9316 * unregister_netdevice_queue - remove device from the kernel
9317 * @dev: device
9318 * @head: list
9319 *
9320 * This function shuts down a device interface and removes it
9321 * from the kernel tables.
9322 * If head not NULL, device is queued to be unregistered later.
9323 *
9324 * Callers must hold the rtnl semaphore. You may want
9325 * unregister_netdev() instead of this.
9326 */
9327
9328 void unregister_netdevice_queue(struct net_device *dev, struct list_head *head)
9329 {
9330 ASSERT_RTNL();
9331
9332 if (head) {
9333 list_move_tail(&dev->unreg_list, head);
9334 } else {
9335 rollback_registered(dev);
9336 /* Finish processing unregister after unlock */
9337 net_set_todo(dev);
9338 }
9339 }
8259 static void rollback_registered(struct net_device *dev)
8260 {
8261 LIST_HEAD(single);
8262
8263 list_add(&dev->unreg_list, &single);
8264 rollback_registered_many(&single);
8265 list_del(&single);
8266 }
8171 static void rollback_registered_many(struct list_head *head)
8172 {
8173 struct net_device *dev, *tmp;
8174 LIST_HEAD(close_head);
8175
8176 BUG_ON(dev_boot_phase);
8177 ASSERT_RTNL();
8178
8179 list_for_each_entry_safe(dev, tmp, head, unreg_list) {
8180 /* Some devices call without registering
8181 * for initialization unwind. Remove those
8182 * devices and proceed with the remaining.
8183 */
8184 if (dev->reg_state == NETREG_UNINITIALIZED) {
8185 pr_debug("unregister_netdevice: device %s/%p never was registered\n",
8186 dev->name, dev);
8187
8188 WARN_ON(1);
8189 list_del(&dev->unreg_list);
8190 continue;
8191 }
8192 dev->dismantle = true;
8193 BUG_ON(dev->reg_state != NETREG_REGISTERED);
8194 }
8195
8196 /* If device is running, close it first. */
8197 list_for_each_entry(dev, head, unreg_list)
8198 list_add_tail(&dev->close_list, &close_head);
8199 dev_close_many(&close_head, true);
8200
8201 list_for_each_entry(dev, head, unreg_list) {
8202 /* And unlink it from device chain. */
8203 unlist_netdevice(dev);
8204
8205 dev->reg_state = NETREG_UNREGISTERING;
8206 }
8207 flush_all_backlogs();
8208
8209 synchronize_net();
8210
8211 list_for_each_entry(dev, head, unreg_list) {
8212 struct sk_buff *skb = NULL;
8213
8214 /* Shutdown queueing discipline. */
8215 dev_shutdown(dev);
8216
8217 dev_xdp_uninstall(dev);
8218
8219 /* Notify protocols, that we are about to destroy
8220 * this device. They should clean all the things.
8221 */
8222 call_netdevice_notifiers(NETDEV_UNREGISTER, dev<
JJJ:unregister_netdev
于 2024-04-09 00:34:15 首次发布
本文介绍了Linux内核中的两个关键函数unregister_netdev和unregister_netdevice_queue,用于从内核表中移除网络设备,包括关闭接口、移除队列、清理相关数据和协议栈的通知。文章还涉及设备状态管理、工作队列操作和数据包处理流程。

最低0.47元/天 解锁文章
632

被折叠的 条评论
为什么被折叠?



