1919#include <net/switchdev.h>
2020#include <linux/if_bridge.h>
2121#include <linux/netpoll.h>
22+ #include <linux/if_vlan.h>
2223#include "dsa_priv.h"
2324
2425/* slave mii_bus handling ***************************************************/
@@ -200,105 +201,6 @@ static int dsa_slave_set_mac_address(struct net_device *dev, void *a)
200201 return 0 ;
201202}
202203
203- static int dsa_slave_fdb_add (struct ndmsg * ndm , struct nlattr * tb [],
204- struct net_device * dev ,
205- const unsigned char * addr , u16 vid , u16 nlm_flags )
206- {
207- struct dsa_slave_priv * p = netdev_priv (dev );
208- struct dsa_switch * ds = p -> parent ;
209- int ret = - EOPNOTSUPP ;
210-
211- if (ds -> drv -> fdb_add )
212- ret = ds -> drv -> fdb_add (ds , p -> port , addr , vid );
213-
214- return ret ;
215- }
216-
217- static int dsa_slave_fdb_del (struct ndmsg * ndm , struct nlattr * tb [],
218- struct net_device * dev ,
219- const unsigned char * addr , u16 vid )
220- {
221- struct dsa_slave_priv * p = netdev_priv (dev );
222- struct dsa_switch * ds = p -> parent ;
223- int ret = - EOPNOTSUPP ;
224-
225- if (ds -> drv -> fdb_del )
226- ret = ds -> drv -> fdb_del (ds , p -> port , addr , vid );
227-
228- return ret ;
229- }
230-
231- static int dsa_slave_fill_info (struct net_device * dev , struct sk_buff * skb ,
232- const unsigned char * addr , u16 vid ,
233- bool is_static ,
234- u32 portid , u32 seq , int type ,
235- unsigned int flags )
236- {
237- struct nlmsghdr * nlh ;
238- struct ndmsg * ndm ;
239-
240- nlh = nlmsg_put (skb , portid , seq , type , sizeof (* ndm ), flags );
241- if (!nlh )
242- return - EMSGSIZE ;
243-
244- ndm = nlmsg_data (nlh );
245- ndm -> ndm_family = AF_BRIDGE ;
246- ndm -> ndm_pad1 = 0 ;
247- ndm -> ndm_pad2 = 0 ;
248- ndm -> ndm_flags = NTF_EXT_LEARNED ;
249- ndm -> ndm_type = 0 ;
250- ndm -> ndm_ifindex = dev -> ifindex ;
251- ndm -> ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE ;
252-
253- if (nla_put (skb , NDA_LLADDR , ETH_ALEN , addr ))
254- goto nla_put_failure ;
255-
256- if (vid && nla_put_u16 (skb , NDA_VLAN , vid ))
257- goto nla_put_failure ;
258-
259- nlmsg_end (skb , nlh );
260- return 0 ;
261-
262- nla_put_failure :
263- nlmsg_cancel (skb , nlh );
264- return - EMSGSIZE ;
265- }
266-
267- /* Dump information about entries, in response to GETNEIGH */
268- static int dsa_slave_fdb_dump (struct sk_buff * skb , struct netlink_callback * cb ,
269- struct net_device * dev ,
270- struct net_device * filter_dev , int idx )
271- {
272- struct dsa_slave_priv * p = netdev_priv (dev );
273- struct dsa_switch * ds = p -> parent ;
274- unsigned char addr [ETH_ALEN ] = { 0 };
275- int ret ;
276-
277- if (!ds -> drv -> fdb_getnext )
278- return - EOPNOTSUPP ;
279-
280- for (; ; idx ++ ) {
281- bool is_static ;
282-
283- ret = ds -> drv -> fdb_getnext (ds , p -> port , addr , & is_static );
284- if (ret < 0 )
285- break ;
286-
287- if (idx < cb -> args [0 ])
288- continue ;
289-
290- ret = dsa_slave_fill_info (dev , skb , addr , 0 ,
291- is_static ,
292- NETLINK_CB (cb -> skb ).portid ,
293- cb -> nlh -> nlmsg_seq ,
294- RTM_NEWNEIGH , NLM_F_MULTI );
295- if (ret < 0 )
296- break ;
297- }
298-
299- return idx ;
300- }
301-
302204static int dsa_slave_ioctl (struct net_device * dev , struct ifreq * ifr , int cmd )
303205{
304206 struct dsa_slave_priv * p = netdev_priv (dev );
@@ -364,6 +266,115 @@ static int dsa_slave_port_attr_set(struct net_device *dev,
364266 return ret ;
365267}
366268
269+ static int dsa_slave_port_fdb_add (struct net_device * dev ,
270+ struct switchdev_obj * obj )
271+ {
272+ struct switchdev_obj_fdb * fdb = & obj -> u .fdb ;
273+ struct dsa_slave_priv * p = netdev_priv (dev );
274+ struct dsa_switch * ds = p -> parent ;
275+ int err ;
276+
277+ if (obj -> trans == SWITCHDEV_TRANS_PREPARE )
278+ err = ds -> drv -> port_fdb_add ? 0 : - EOPNOTSUPP ;
279+ else if (obj -> trans == SWITCHDEV_TRANS_COMMIT )
280+ err = ds -> drv -> port_fdb_add (ds , p -> port , fdb -> vid , fdb -> addr );
281+ else
282+ err = - EOPNOTSUPP ;
283+
284+ return err ;
285+ }
286+
287+ static int dsa_slave_port_fdb_del (struct net_device * dev ,
288+ struct switchdev_obj * obj )
289+ {
290+ struct switchdev_obj_fdb * fdb = & obj -> u .fdb ;
291+ struct dsa_slave_priv * p = netdev_priv (dev );
292+ struct dsa_switch * ds = p -> parent ;
293+
294+ if (!ds -> drv -> port_fdb_del )
295+ return - EOPNOTSUPP ;
296+
297+ return ds -> drv -> port_fdb_del (ds , p -> port , fdb -> vid , fdb -> addr );
298+ }
299+
300+ static int dsa_slave_port_fdb_dump (struct net_device * dev ,
301+ struct switchdev_obj * obj )
302+ {
303+ struct switchdev_obj_fdb * fdb = & obj -> u .fdb ;
304+ struct dsa_slave_priv * p = netdev_priv (dev );
305+ struct dsa_switch * ds = p -> parent ;
306+ int err ;
307+
308+ if (!ds -> drv -> port_fdb_getnext )
309+ return - EOPNOTSUPP ;
310+
311+ memset (fdb , 0 , sizeof (* fdb ));
312+
313+ for (;;) {
314+ err = ds -> drv -> port_fdb_getnext (ds , p -> port , & fdb -> vid ,
315+ fdb -> addr , & fdb -> is_static );
316+ if (err )
317+ break ;
318+
319+ err = obj -> cb (dev , obj );
320+ if (err )
321+ break ;
322+ }
323+
324+ return err == - ENOENT ? 0 : err ;
325+ }
326+
327+ static int dsa_slave_port_obj_add (struct net_device * dev ,
328+ struct switchdev_obj * obj )
329+ {
330+ int err ;
331+
332+ switch (obj -> id ) {
333+ case SWITCHDEV_OBJ_PORT_FDB :
334+ err = dsa_slave_port_fdb_add (dev , obj );
335+ break ;
336+ default :
337+ err = - EOPNOTSUPP ;
338+ break ;
339+ }
340+
341+ return err ;
342+ }
343+
344+ static int dsa_slave_port_obj_del (struct net_device * dev ,
345+ struct switchdev_obj * obj )
346+ {
347+ int err ;
348+
349+ switch (obj -> id ) {
350+ case SWITCHDEV_OBJ_PORT_FDB :
351+ err = dsa_slave_port_fdb_del (dev , obj );
352+ break ;
353+ default :
354+ err = - EOPNOTSUPP ;
355+ break ;
356+ }
357+
358+ return err ;
359+ }
360+
361+ static int dsa_slave_port_obj_dump (struct net_device * dev ,
362+ struct switchdev_obj * obj )
363+ {
364+ int err ;
365+
366+ switch (obj -> id ) {
367+ case SWITCHDEV_OBJ_PORT_FDB :
368+ err = dsa_slave_port_fdb_dump (dev , obj );
369+ break ;
370+ default :
371+ err = - EOPNOTSUPP ;
372+ break ;
373+ }
374+
375+ return err ;
376+ }
377+
367378static int dsa_slave_bridge_port_join (struct net_device * dev ,
368379 struct net_device * br )
369380{
@@ -765,9 +776,9 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
765776 .ndo_change_rx_flags = dsa_slave_change_rx_flags ,
766777 .ndo_set_rx_mode = dsa_slave_set_rx_mode ,
767778 .ndo_set_mac_address = dsa_slave_set_mac_address ,
768- .ndo_fdb_add = dsa_slave_fdb_add ,
769- .ndo_fdb_del = dsa_slave_fdb_del ,
770- .ndo_fdb_dump = dsa_slave_fdb_dump ,
779+ .ndo_fdb_add = switchdev_port_fdb_add ,
780+ .ndo_fdb_del = switchdev_port_fdb_del ,
781+ .ndo_fdb_dump = switchdev_port_fdb_dump ,
771782 .ndo_do_ioctl = dsa_slave_ioctl ,
772783 .ndo_get_iflink = dsa_slave_get_iflink ,
773784#ifdef CONFIG_NET_POLL_CONTROLLER
@@ -780,6 +791,9 @@ static const struct net_device_ops dsa_slave_netdev_ops = {
780791static const struct switchdev_ops dsa_slave_switchdev_ops = {
781792 .switchdev_port_attr_get = dsa_slave_port_attr_get ,
782793 .switchdev_port_attr_set = dsa_slave_port_attr_set ,
794+ .switchdev_port_obj_add = dsa_slave_port_obj_add ,
795+ .switchdev_port_obj_del = dsa_slave_port_obj_del ,
796+ .switchdev_port_obj_dump = dsa_slave_port_obj_dump ,
783797};
784798
785799static void dsa_slave_adjust_link (struct net_device * dev )
0 commit comments