Skip to content

Commit 499aa9e

Browse files
vladimirolteandavem330
authored andcommitted
net: dsa: install the primary unicast MAC address as standalone port host FDB
To be able to safely turn off CPU flooding for standalone ports, we need to ensure that the dev_addr of each DSA slave interface is installed as a standalone host FDB entry for compatible switches. Signed-off-by: Vladimir Oltean <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 5e8a1e0 commit 499aa9e

File tree

1 file changed

+33
-2
lines changed

1 file changed

+33
-2
lines changed

net/dsa/slave.c

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -175,6 +175,7 @@ static int dsa_slave_open(struct net_device *dev)
175175
{
176176
struct net_device *master = dsa_slave_to_master(dev);
177177
struct dsa_port *dp = dsa_slave_to_port(dev);
178+
struct dsa_switch *ds = dp->ds;
178179
int err;
179180

180181
err = dev_open(master, NULL);
@@ -183,10 +184,16 @@ static int dsa_slave_open(struct net_device *dev)
183184
goto out;
184185
}
185186

187+
if (dsa_switch_supports_uc_filtering(ds)) {
188+
err = dsa_port_standalone_host_fdb_add(dp, dev->dev_addr, 0);
189+
if (err)
190+
goto out;
191+
}
192+
186193
if (!ether_addr_equal(dev->dev_addr, master->dev_addr)) {
187194
err = dev_uc_add(master, dev->dev_addr);
188195
if (err < 0)
189-
goto out;
196+
goto del_host_addr;
190197
}
191198

192199
err = dsa_port_enable_rt(dp, dev->phydev);
@@ -198,6 +205,9 @@ static int dsa_slave_open(struct net_device *dev)
198205
del_unicast:
199206
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
200207
dev_uc_del(master, dev->dev_addr);
208+
del_host_addr:
209+
if (dsa_switch_supports_uc_filtering(ds))
210+
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);
201211
out:
202212
return err;
203213
}
@@ -206,12 +216,16 @@ static int dsa_slave_close(struct net_device *dev)
206216
{
207217
struct net_device *master = dsa_slave_to_master(dev);
208218
struct dsa_port *dp = dsa_slave_to_port(dev);
219+
struct dsa_switch *ds = dp->ds;
209220

210221
dsa_port_disable_rt(dp);
211222

212223
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
213224
dev_uc_del(master, dev->dev_addr);
214225

226+
if (dsa_switch_supports_uc_filtering(ds))
227+
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);
228+
215229
return 0;
216230
}
217231

@@ -244,24 +258,41 @@ static void dsa_slave_set_rx_mode(struct net_device *dev)
244258
static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
245259
{
246260
struct net_device *master = dsa_slave_to_master(dev);
261+
struct dsa_port *dp = dsa_slave_to_port(dev);
262+
struct dsa_switch *ds = dp->ds;
247263
struct sockaddr *addr = a;
248264
int err;
249265

250266
if (!is_valid_ether_addr(addr->sa_data))
251267
return -EADDRNOTAVAIL;
252268

269+
if (dsa_switch_supports_uc_filtering(ds)) {
270+
err = dsa_port_standalone_host_fdb_add(dp, addr->sa_data, 0);
271+
if (err)
272+
return err;
273+
}
274+
253275
if (!ether_addr_equal(addr->sa_data, master->dev_addr)) {
254276
err = dev_uc_add(master, addr->sa_data);
255277
if (err < 0)
256-
return err;
278+
goto del_unicast;
257279
}
258280

259281
if (!ether_addr_equal(dev->dev_addr, master->dev_addr))
260282
dev_uc_del(master, dev->dev_addr);
261283

284+
if (dsa_switch_supports_uc_filtering(ds))
285+
dsa_port_standalone_host_fdb_del(dp, dev->dev_addr, 0);
286+
262287
eth_hw_addr_set(dev, addr->sa_data);
263288

264289
return 0;
290+
291+
del_unicast:
292+
if (dsa_switch_supports_uc_filtering(ds))
293+
dsa_port_standalone_host_fdb_del(dp, addr->sa_data, 0);
294+
295+
return err;
265296
}
266297

267298
struct dsa_slave_dump_ctx {

0 commit comments

Comments
 (0)