Skip to content

Commit 402dae9

Browse files
Veaceslav Falicodavem330
authored andcommitted
net: add netdev_adjacent->private and allow to use it
Currently, even though we can access any linked device, we can't attach anything to it, which is vital to properly manage them. To fix this, add a new void *private to netdev_adjacent and functions setting/getting it (per link), so that we can save, per example, bonding's slave structures there, per slave device. netdev_master_upper_dev_link_private(dev, upper_dev, private) links dev to upper dev and populates the neighbour link only with private. netdev_lower_dev_get_private{,_rcu}() returns the private, if found. CC: "David S. Miller" <[email protected]> CC: Eric Dumazet <[email protected]> CC: Jiri Pirko <[email protected]> CC: Alexander Duyck <[email protected]> Signed-off-by: Veaceslav Falico <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5249dec commit 402dae9

File tree

2 files changed

+64
-11
lines changed

2 files changed

+64
-11
lines changed

include/linux/netdevice.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2839,8 +2839,15 @@ extern int netdev_upper_dev_link(struct net_device *dev,
28392839
struct net_device *upper_dev);
28402840
extern int netdev_master_upper_dev_link(struct net_device *dev,
28412841
struct net_device *upper_dev);
2842+
extern int netdev_master_upper_dev_link_private(struct net_device *dev,
2843+
struct net_device *upper_dev,
2844+
void *private);
28422845
extern void netdev_upper_dev_unlink(struct net_device *dev,
28432846
struct net_device *upper_dev);
2847+
extern void *netdev_lower_dev_get_private_rcu(struct net_device *dev,
2848+
struct net_device *lower_dev);
2849+
extern void *netdev_lower_dev_get_private(struct net_device *dev,
2850+
struct net_device *lower_dev);
28442851
extern int skb_checksum_help(struct sk_buff *skb);
28452852
extern struct sk_buff *__skb_gso_segment(struct sk_buff *skb,
28462853
netdev_features_t features, bool tx_path);

net/core/dev.c

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4376,6 +4376,9 @@ struct netdev_adjacent {
43764376
/* counter for the number of times this device was added to us */
43774377
u16 ref_nr;
43784378

4379+
/* private field for the users */
4380+
void *private;
4381+
43794382
struct list_head list;
43804383
struct rcu_head rcu;
43814384
};
@@ -4510,7 +4513,7 @@ EXPORT_SYMBOL(netdev_master_upper_dev_get_rcu);
45104513
static int __netdev_adjacent_dev_insert(struct net_device *dev,
45114514
struct net_device *adj_dev,
45124515
struct list_head *dev_list,
4513-
bool master)
4516+
void *private, bool master)
45144517
{
45154518
struct netdev_adjacent *adj;
45164519

@@ -4528,6 +4531,7 @@ static int __netdev_adjacent_dev_insert(struct net_device *dev,
45284531
adj->dev = adj_dev;
45294532
adj->master = master;
45304533
adj->ref_nr = 1;
4534+
adj->private = private;
45314535
dev_hold(adj_dev);
45324536

45334537
pr_debug("dev_hold for %s, because of link added from %s to %s\n",
@@ -4574,15 +4578,17 @@ int __netdev_adjacent_dev_link_lists(struct net_device *dev,
45744578
struct net_device *upper_dev,
45754579
struct list_head *up_list,
45764580
struct list_head *down_list,
4577-
bool master)
4581+
void *private, bool master)
45784582
{
45794583
int ret;
45804584

4581-
ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, master);
4585+
ret = __netdev_adjacent_dev_insert(dev, upper_dev, up_list, private,
4586+
master);
45824587
if (ret)
45834588
return ret;
45844589

4585-
ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, false);
4590+
ret = __netdev_adjacent_dev_insert(upper_dev, dev, down_list, private,
4591+
false);
45864592
if (ret) {
45874593
__netdev_adjacent_dev_remove(dev, upper_dev, up_list);
45884594
return ret;
@@ -4597,7 +4603,7 @@ int __netdev_adjacent_dev_link(struct net_device *dev,
45974603
return __netdev_adjacent_dev_link_lists(dev, upper_dev,
45984604
&dev->all_adj_list.upper,
45994605
&upper_dev->all_adj_list.lower,
4600-
false);
4606+
NULL, false);
46014607
}
46024608

46034609
void __netdev_adjacent_dev_unlink_lists(struct net_device *dev,
@@ -4619,7 +4625,7 @@ void __netdev_adjacent_dev_unlink(struct net_device *dev,
46194625

46204626
int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
46214627
struct net_device *upper_dev,
4622-
bool master)
4628+
void *private, bool master)
46234629
{
46244630
int ret = __netdev_adjacent_dev_link(dev, upper_dev);
46254631

@@ -4629,7 +4635,7 @@ int __netdev_adjacent_dev_link_neighbour(struct net_device *dev,
46294635
ret = __netdev_adjacent_dev_link_lists(dev, upper_dev,
46304636
&dev->adj_list.upper,
46314637
&upper_dev->adj_list.lower,
4632-
master);
4638+
private, master);
46334639
if (ret) {
46344640
__netdev_adjacent_dev_unlink(dev, upper_dev);
46354641
return ret;
@@ -4648,7 +4654,8 @@ void __netdev_adjacent_dev_unlink_neighbour(struct net_device *dev,
46484654
}
46494655

46504656
static int __netdev_upper_dev_link(struct net_device *dev,
4651-
struct net_device *upper_dev, bool master)
4657+
struct net_device *upper_dev, bool master,
4658+
void *private)
46524659
{
46534660
struct netdev_adjacent *i, *j, *to_i, *to_j;
46544661
int ret = 0;
@@ -4668,7 +4675,8 @@ static int __netdev_upper_dev_link(struct net_device *dev,
46684675
if (master && netdev_master_upper_dev_get(dev))
46694676
return -EBUSY;
46704677

4671-
ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, master);
4678+
ret = __netdev_adjacent_dev_link_neighbour(dev, upper_dev, private,
4679+
master);
46724680
if (ret)
46734681
return ret;
46744682

@@ -4759,7 +4767,7 @@ static int __netdev_upper_dev_link(struct net_device *dev,
47594767
int netdev_upper_dev_link(struct net_device *dev,
47604768
struct net_device *upper_dev)
47614769
{
4762-
return __netdev_upper_dev_link(dev, upper_dev, false);
4770+
return __netdev_upper_dev_link(dev, upper_dev, false, NULL);
47634771
}
47644772
EXPORT_SYMBOL(netdev_upper_dev_link);
47654773

@@ -4777,10 +4785,18 @@ EXPORT_SYMBOL(netdev_upper_dev_link);
47774785
int netdev_master_upper_dev_link(struct net_device *dev,
47784786
struct net_device *upper_dev)
47794787
{
4780-
return __netdev_upper_dev_link(dev, upper_dev, true);
4788+
return __netdev_upper_dev_link(dev, upper_dev, true, NULL);
47814789
}
47824790
EXPORT_SYMBOL(netdev_master_upper_dev_link);
47834791

4792+
int netdev_master_upper_dev_link_private(struct net_device *dev,
4793+
struct net_device *upper_dev,
4794+
void *private)
4795+
{
4796+
return __netdev_upper_dev_link(dev, upper_dev, true, private);
4797+
}
4798+
EXPORT_SYMBOL(netdev_master_upper_dev_link_private);
4799+
47844800
/**
47854801
* netdev_upper_dev_unlink - Removes a link to upper device
47864802
* @dev: device
@@ -4818,6 +4834,36 @@ void netdev_upper_dev_unlink(struct net_device *dev,
48184834
}
48194835
EXPORT_SYMBOL(netdev_upper_dev_unlink);
48204836

4837+
void *netdev_lower_dev_get_private_rcu(struct net_device *dev,
4838+
struct net_device *lower_dev)
4839+
{
4840+
struct netdev_adjacent *lower;
4841+
4842+
if (!lower_dev)
4843+
return NULL;
4844+
lower = __netdev_find_adj_rcu(dev, lower_dev, &dev->adj_list.lower);
4845+
if (!lower)
4846+
return NULL;
4847+
4848+
return lower->private;
4849+
}
4850+
EXPORT_SYMBOL(netdev_lower_dev_get_private_rcu);
4851+
4852+
void *netdev_lower_dev_get_private(struct net_device *dev,
4853+
struct net_device *lower_dev)
4854+
{
4855+
struct netdev_adjacent *lower;
4856+
4857+
if (!lower_dev)
4858+
return NULL;
4859+
lower = __netdev_find_adj(dev, lower_dev, &dev->adj_list.lower);
4860+
if (!lower)
4861+
return NULL;
4862+
4863+
return lower->private;
4864+
}
4865+
EXPORT_SYMBOL(netdev_lower_dev_get_private);
4866+
48214867
static void dev_change_rx_flags(struct net_device *dev, int flags)
48224868
{
48234869
const struct net_device_ops *ops = dev->netdev_ops;

0 commit comments

Comments
 (0)