Skip to content

Commit e0a4b99

Browse files
TaeheeYoodavem330
authored andcommitted
hsr: use upper/lower device infrastructure
netdev_upper_dev_link() is useful to manage lower/upper interfaces. And this function internally validates looping, maximum depth. All or most virtual interfaces that could have a real interface (e.g. macsec, macvlan, ipvlan etc.) use lower/upper infrastructure. Signed-off-by: Taehee Yoo <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 81390d0 commit e0a4b99

File tree

3 files changed

+40
-30
lines changed

3 files changed

+40
-30
lines changed

net/hsr/hsr_device.c

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -341,22 +341,33 @@ static void hsr_announce(struct timer_list *t)
341341
rcu_read_unlock();
342342
}
343343

344+
static void hsr_del_ports(struct hsr_priv *hsr)
345+
{
346+
struct hsr_port *port;
347+
348+
port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_A);
349+
if (port)
350+
hsr_del_port(port);
351+
352+
port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
353+
if (port)
354+
hsr_del_port(port);
355+
356+
port = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
357+
if (port)
358+
hsr_del_port(port);
359+
}
360+
344361
/* This has to be called after all the readers are gone.
345362
* Otherwise we would have to check the return value of
346363
* hsr_port_get_hsr().
347364
*/
348365
static void hsr_dev_destroy(struct net_device *hsr_dev)
349366
{
350-
struct hsr_priv *hsr;
351-
struct hsr_port *port;
352-
struct hsr_port *tmp;
353-
354-
hsr = netdev_priv(hsr_dev);
367+
struct hsr_priv *hsr = netdev_priv(hsr_dev);
355368

356369
hsr_debugfs_term(hsr);
357-
358-
list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
359-
hsr_del_port(port);
370+
hsr_del_ports(hsr);
360371

361372
del_timer_sync(&hsr->prune_timer);
362373
del_timer_sync(&hsr->announce_timer);
@@ -426,8 +437,6 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
426437
struct netlink_ext_ack *extack)
427438
{
428439
struct hsr_priv *hsr;
429-
struct hsr_port *port;
430-
struct hsr_port *tmp;
431440
int res;
432441

433442
hsr = netdev_priv(hsr_dev);
@@ -494,8 +503,7 @@ int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
494503
err_add_slaves:
495504
unregister_netdevice(hsr_dev);
496505
err_unregister:
497-
list_for_each_entry_safe(port, tmp, &hsr->ports, port_list)
498-
hsr_del_port(port);
506+
hsr_del_ports(hsr);
499507
err_add_master:
500508
hsr_del_self_node(hsr);
501509

net/hsr/hsr_main.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,8 @@ static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
8585
master->dev->mtu = mtu_max;
8686
break;
8787
case NETDEV_UNREGISTER:
88-
hsr_del_port(port);
88+
if (!is_hsr_master(dev))
89+
hsr_del_port(port);
8990
break;
9091
case NETDEV_PRE_TYPE_CHANGE:
9192
/* HSR works only on Ethernet devices. Refuse slave to change

net/hsr/hsr_slave.c

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -97,19 +97,25 @@ static int hsr_check_dev_ok(struct net_device *dev,
9797
}
9898

9999
/* Setup device to be added to the HSR bridge. */
100-
static int hsr_portdev_setup(struct net_device *dev, struct hsr_port *port)
100+
static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
101+
struct hsr_port *port,
102+
struct netlink_ext_ack *extack)
103+
101104
{
105+
struct net_device *hsr_dev;
106+
struct hsr_port *master;
102107
int res;
103108

104-
dev_hold(dev);
105109
res = dev_set_promiscuity(dev, 1);
106110
if (res)
107111
goto fail_promiscuity;
108112

109-
/* FIXME:
110-
* What does net device "adjacency" mean? Should we do
111-
* res = netdev_master_upper_dev_link(port->dev, port->hsr->dev); ?
112-
*/
113+
master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
114+
hsr_dev = master->dev;
115+
116+
res = netdev_upper_dev_link(dev, hsr_dev, extack);
117+
if (res)
118+
goto fail_upper_dev_link;
113119

114120
res = netdev_rx_handler_register(dev, hsr_handle_frame, port);
115121
if (res)
@@ -119,6 +125,8 @@ static int hsr_portdev_setup(struct net_device *dev, struct hsr_port *port)
119125
return 0;
120126

121127
fail_rx_handler:
128+
netdev_upper_dev_unlink(dev, hsr_dev);
129+
fail_upper_dev_link:
122130
dev_set_promiscuity(dev, -1);
123131
fail_promiscuity:
124132
dev_put(dev);
@@ -147,7 +155,7 @@ int hsr_add_port(struct hsr_priv *hsr, struct net_device *dev,
147155
return -ENOMEM;
148156

149157
if (type != HSR_PT_MASTER) {
150-
res = hsr_portdev_setup(dev, port);
158+
res = hsr_portdev_setup(hsr, dev, port, extack);
151159
if (res)
152160
goto fail_dev_setup;
153161
}
@@ -180,21 +188,14 @@ void hsr_del_port(struct hsr_port *port)
180188
list_del_rcu(&port->port_list);
181189

182190
if (port != master) {
183-
if (master) {
184-
netdev_update_features(master->dev);
185-
dev_set_mtu(master->dev, hsr_get_max_mtu(hsr));
186-
}
191+
netdev_update_features(master->dev);
192+
dev_set_mtu(master->dev, hsr_get_max_mtu(hsr));
187193
netdev_rx_handler_unregister(port->dev);
188194
dev_set_promiscuity(port->dev, -1);
195+
netdev_upper_dev_unlink(port->dev, master->dev);
189196
}
190197

191-
/* FIXME?
192-
* netdev_upper_dev_unlink(port->dev, port->hsr->dev);
193-
*/
194-
195198
synchronize_rcu();
196199

197-
if (port != master)
198-
dev_put(port->dev);
199200
kfree(port);
200201
}

0 commit comments

Comments
 (0)