diff options
Diffstat (limited to 'net/core')
-rw-r--r-- | net/core/dev.c | 35 |
1 files changed, 34 insertions, 1 deletions
diff --git a/net/core/dev.c b/net/core/dev.c index de443ee1b046..25ab6fe80da2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -4584,6 +4584,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, | |||
4584 | void *private, bool master) | 4584 | void *private, bool master) |
4585 | { | 4585 | { |
4586 | struct netdev_adjacent *adj; | 4586 | struct netdev_adjacent *adj; |
4587 | char linkname[IFNAMSIZ+7]; | ||
4587 | int ret; | 4588 | int ret; |
4588 | 4589 | ||
4589 | adj = __netdev_find_adj(dev, adj_dev, dev_list); | 4590 | adj = __netdev_find_adj(dev, adj_dev, dev_list); |
@@ -4606,12 +4607,26 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, | |||
4606 | pr_debug("dev_hold for %s, because of link added from %s to %s\n", | 4607 | pr_debug("dev_hold for %s, because of link added from %s to %s\n", |
4607 | adj_dev->name, dev->name, adj_dev->name); | 4608 | adj_dev->name, dev->name, adj_dev->name); |
4608 | 4609 | ||
4610 | if (dev_list == &dev->adj_list.lower) { | ||
4611 | sprintf(linkname, "lower_%s", adj_dev->name); | ||
4612 | ret = sysfs_create_link(&(dev->dev.kobj), | ||
4613 | &(adj_dev->dev.kobj), linkname); | ||
4614 | if (ret) | ||
4615 | goto free_adj; | ||
4616 | } else if (dev_list == &dev->adj_list.upper) { | ||
4617 | sprintf(linkname, "upper_%s", adj_dev->name); | ||
4618 | ret = sysfs_create_link(&(dev->dev.kobj), | ||
4619 | &(adj_dev->dev.kobj), linkname); | ||
4620 | if (ret) | ||
4621 | goto free_adj; | ||
4622 | } | ||
4623 | |||
4609 | /* Ensure that master link is always the first item in list. */ | 4624 | /* Ensure that master link is always the first item in list. */ |
4610 | if (master) { | 4625 | if (master) { |
4611 | ret = sysfs_create_link(&(dev->dev.kobj), | 4626 | ret = sysfs_create_link(&(dev->dev.kobj), |
4612 | &(adj_dev->dev.kobj), "master"); | 4627 | &(adj_dev->dev.kobj), "master"); |
4613 | if (ret) | 4628 | if (ret) |
4614 | goto free_adj; | 4629 | goto remove_symlinks; |
4615 | 4630 | ||
4616 | list_add_rcu(&adj->list, dev_list); | 4631 | list_add_rcu(&adj->list, dev_list); |
4617 | } else { | 4632 | } else { |
@@ -4620,6 +4635,15 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev, | |||
4620 | 4635 | ||
4621 | return 0; | 4636 | return 0; |
4622 | 4637 | ||
4638 | remove_symlinks: | ||
4639 | if (dev_list == &dev->adj_list.lower) { | ||
4640 | sprintf(linkname, "lower_%s", adj_dev->name); | ||
4641 | sysfs_remove_link(&(dev->dev.kobj), linkname); | ||
4642 | } else if (dev_list == &dev->adj_list.upper) { | ||
4643 | sprintf(linkname, "upper_%s", adj_dev->name); | ||
4644 | sysfs_remove_link(&(dev->dev.kobj), linkname); | ||
4645 | } | ||
4646 | |||
4623 | free_adj: | 4647 | free_adj: |
4624 | kfree(adj); | 4648 | kfree(adj); |
4625 | 4649 | ||
@@ -4631,6 +4655,7 @@ void __netdev_adjacent_dev_remove(struct net_device *dev, | |||
4631 | struct list_head *dev_list) | 4655 | struct list_head *dev_list) |
4632 | { | 4656 | { |
4633 | struct netdev_adjacent *adj; | 4657 | struct netdev_adjacent *adj; |
4658 | char linkname[IFNAMSIZ+7]; | ||
4634 | 4659 | ||
4635 | adj = __netdev_find_adj(dev, adj_dev, dev_list); | 4660 | adj = __netdev_find_adj(dev, adj_dev, dev_list); |
4636 | 4661 | ||
@@ -4650,6 +4675,14 @@ void __netdev_adjacent_dev_remove(struct net_device *dev, | |||
4650 | if (adj->master) | 4675 | if (adj->master) |
4651 | sysfs_remove_link(&(dev->dev.kobj), "master"); | 4676 | sysfs_remove_link(&(dev->dev.kobj), "master"); |
4652 | 4677 | ||
4678 | if (dev_list == &dev->adj_list.lower) { | ||
4679 | sprintf(linkname, "lower_%s", adj_dev->name); | ||
4680 | sysfs_remove_link(&(dev->dev.kobj), linkname); | ||
4681 | } else if (dev_list == &dev->adj_list.upper) { | ||
4682 | sprintf(linkname, "upper_%s", adj_dev->name); | ||
4683 | sysfs_remove_link(&(dev->dev.kobj), linkname); | ||
4684 | } | ||
4685 | |||
4653 | list_del_rcu(&adj->list); | 4686 | list_del_rcu(&adj->list); |
4654 | pr_debug("dev_put for %s, because link removed from %s to %s\n", | 4687 | pr_debug("dev_put for %s, because link removed from %s to %s\n", |
4655 | adj_dev->name, dev->name, adj_dev->name); | 4688 | adj_dev->name, dev->name, adj_dev->name); |