On 6.8.2017 15:15, Arkadi Sharshevsky wrote:
> Currently the bridge port flags, vlans, FDBs and MDBs can be offloaded
> through the bridge code, making the switchdev's SELF bridge bypass
> implementation to be redundant. This implies several changes:
> - No need for dump infra in switchdev, DSA's special case is handled
>   privately.
> - Remove obj_dump from switchdev_ops.
> - FDBs are removed from obj_add/del routines, due to the fact that they
>   are offloaded through the bridge notification chain.
> - The switchdev_port_bridge_xx() and switchdev_port_fdb_xx() functions
>   can be removed.
> 
> Signed-off-by: Arkadi Sharshevsky <arka...@mellanox.com>
> Reviewed-by: Vivien Didelot <vivien.dide...@savoirfairelinux.com>
> ---
> v1->v2
> - Fix typo in commit message.
> ---
>  include/net/switchdev.h   |  75 --------
>  net/switchdev/switchdev.c | 435 
> ----------------------------------------------
>  2 files changed, 510 deletions(-)
> 
> diff --git a/include/net/switchdev.h b/include/net/switchdev.h
> index d2637a6..d767b79 100644
> --- a/include/net/switchdev.h
> +++ b/include/net/switchdev.h
> @@ -74,7 +74,6 @@ struct switchdev_attr {
>  enum switchdev_obj_id {
>       SWITCHDEV_OBJ_ID_UNDEFINED,
>       SWITCHDEV_OBJ_ID_PORT_VLAN,
> -     SWITCHDEV_OBJ_ID_PORT_FDB,
>       SWITCHDEV_OBJ_ID_PORT_MDB,
>  };
>  
> @@ -97,17 +96,6 @@ struct switchdev_obj_port_vlan {
>  #define SWITCHDEV_OBJ_PORT_VLAN(obj) \
>       container_of(obj, struct switchdev_obj_port_vlan, obj)
>  
> -/* SWITCHDEV_OBJ_ID_PORT_FDB */
> -struct switchdev_obj_port_fdb {
> -     struct switchdev_obj obj;
> -     unsigned char addr[ETH_ALEN];
> -     u16 vid;
> -     u16 ndm_state;
> -};
> -
> -#define SWITCHDEV_OBJ_PORT_FDB(obj) \
> -     container_of(obj, struct switchdev_obj_port_fdb, obj)
> -
>  /* SWITCHDEV_OBJ_ID_PORT_MDB */
>  struct switchdev_obj_port_mdb {
>       struct switchdev_obj obj;
> @@ -135,8 +123,6 @@ typedef int switchdev_obj_dump_cb_t(struct switchdev_obj 
> *obj);
>   * @switchdev_port_obj_add: Add an object to port (see switchdev_obj_*).
>   *
>   * @switchdev_port_obj_del: Delete an object from port (see switchdev_obj_*).
> - *
> - * @switchdev_port_obj_dump: Dump port objects (see switchdev_obj_*).
>   */
>  struct switchdev_ops {
>       int     (*switchdev_port_attr_get)(struct net_device *dev,
> @@ -149,9 +135,6 @@ struct switchdev_ops {
>                                         struct switchdev_trans *trans);
>       int     (*switchdev_port_obj_del)(struct net_device *dev,
>                                         const struct switchdev_obj *obj);
> -     int     (*switchdev_port_obj_dump)(struct net_device *dev,
> -                                        struct switchdev_obj *obj,
> -                                        switchdev_obj_dump_cb_t *cb);
>  };
>  
>  enum switchdev_notifier_type {
> @@ -189,25 +172,10 @@ int switchdev_port_obj_add(struct net_device *dev,
>                          const struct switchdev_obj *obj);
>  int switchdev_port_obj_del(struct net_device *dev,
>                          const struct switchdev_obj *obj);
> -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj 
> *obj,
> -                         switchdev_obj_dump_cb_t *cb);
>  int register_switchdev_notifier(struct notifier_block *nb);
>  int unregister_switchdev_notifier(struct notifier_block *nb);
>  int call_switchdev_notifiers(unsigned long val, struct net_device *dev,
>                            struct switchdev_notifier_info *info);
> -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
> -                               struct net_device *dev, u32 filter_mask,
> -                               int nlflags);
> -int switchdev_port_bridge_setlink(struct net_device *dev,
> -                               struct nlmsghdr *nlh, u16 flags);
> -int switchdev_port_bridge_dellink(struct net_device *dev,
> -                               struct nlmsghdr *nlh, u16 flags);
> -int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
> -                        struct net_device *dev, const unsigned char *addr,
> -                        u16 vid, u16 nlm_flags);
> -int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
> -                        struct net_device *dev, const unsigned char *addr,
> -                        u16 vid);
>  void switchdev_port_fwd_mark_set(struct net_device *dev,
>                                struct net_device *group_dev,
>                                bool joining);
> @@ -246,13 +214,6 @@ static inline int switchdev_port_obj_del(struct 
> net_device *dev,
>       return -EOPNOTSUPP;
>  }
>  
> -static inline int switchdev_port_obj_dump(struct net_device *dev,
> -                                       const struct switchdev_obj *obj,
> -                                       switchdev_obj_dump_cb_t *cb)
> -{
> -     return -EOPNOTSUPP;
> -}
> -
>  static inline int register_switchdev_notifier(struct notifier_block *nb)
>  {
>       return 0;
> @@ -270,42 +231,6 @@ static inline int call_switchdev_notifiers(unsigned long 
> val,
>       return NOTIFY_DONE;
>  }
>  
> -static inline int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid,
> -                                         u32 seq, struct net_device *dev,
> -                                         u32 filter_mask, int nlflags)
> -{
> -     return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_bridge_setlink(struct net_device *dev,
> -                                             struct nlmsghdr *nlh,
> -                                             u16 flags)
> -{
> -     return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_bridge_dellink(struct net_device *dev,
> -                                             struct nlmsghdr *nlh,
> -                                             u16 flags)
> -{
> -     return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr 
> *tb[],
> -                                      struct net_device *dev,
> -                                      const unsigned char *addr,
> -                                      u16 vid, u16 nlm_flags)
> -{
> -     return -EOPNOTSUPP;
> -}
> -
> -static inline int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr 
> *tb[],
> -                                      struct net_device *dev,
> -                                      const unsigned char *addr, u16 vid)
> -{
> -     return -EOPNOTSUPP;
> -}
> -
>  static inline bool switchdev_port_same_parent_id(struct net_device *a,
>                                                struct net_device *b)
>  {
> diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
> index 3d32981..0531b41 100644
> --- a/net/switchdev/switchdev.c
> +++ b/net/switchdev/switchdev.c
> @@ -343,8 +343,6 @@ static size_t switchdev_obj_size(const struct 
> switchdev_obj *obj)
>       switch (obj->id) {
>       case SWITCHDEV_OBJ_ID_PORT_VLAN:
>               return sizeof(struct switchdev_obj_port_vlan);
> -     case SWITCHDEV_OBJ_ID_PORT_FDB:
> -             return sizeof(struct switchdev_obj_port_fdb);
>       case SWITCHDEV_OBJ_ID_PORT_MDB:
>               return sizeof(struct switchdev_obj_port_mdb);
>       default:
> @@ -534,43 +532,6 @@ int switchdev_port_obj_del(struct net_device *dev,
>  }
>  EXPORT_SYMBOL_GPL(switchdev_port_obj_del);
>  
> -/**
> - *   switchdev_port_obj_dump - Dump port objects
> - *
> - *   @dev: port device
> - *   @id: object ID
> - *   @obj: object to dump
> - *   @cb: function to call with a filled object
> - *
> - *   rtnl_lock must be held.
> - */
> -int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj 
> *obj,
> -                         switchdev_obj_dump_cb_t *cb)
> -{
> -     const struct switchdev_ops *ops = dev->switchdev_ops;
> -     struct net_device *lower_dev;
> -     struct list_head *iter;
> -     int err = -EOPNOTSUPP;
> -
> -     ASSERT_RTNL();
> -
> -     if (ops && ops->switchdev_port_obj_dump)
> -             return ops->switchdev_port_obj_dump(dev, obj, cb);
> -
> -     /* Switch device port(s) may be stacked under
> -      * bond/team/vlan dev, so recurse down to dump objects on
> -      * first port at bottom of stack.
> -      */
> -
> -     netdev_for_each_lower_dev(dev, lower_dev, iter) {
> -             err = switchdev_port_obj_dump(lower_dev, obj, cb);
> -             break;
> -     }
> -
> -     return err;
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_obj_dump);
> -
>  static ATOMIC_NOTIFIER_HEAD(switchdev_notif_chain);
>  
>  /**
> @@ -613,402 +574,6 @@ int call_switchdev_notifiers(unsigned long val, struct 
> net_device *dev,
>  }
>  EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
>  
> -struct switchdev_vlan_dump {
> -     struct switchdev_obj_port_vlan vlan;
> -     struct sk_buff *skb;
> -     u32 filter_mask;
> -     u16 flags;
> -     u16 begin;
> -     u16 end;
> -};
> -
> -static int switchdev_port_vlan_dump_put(struct switchdev_vlan_dump *dump)
> -{
> -     struct bridge_vlan_info vinfo;
> -
> -     vinfo.flags = dump->flags;
> -
> -     if (dump->begin == 0 && dump->end == 0) {
> -             return 0;
> -     } else if (dump->begin == dump->end) {
> -             vinfo.vid = dump->begin;
> -             if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
> -                         sizeof(vinfo), &vinfo))
> -                     return -EMSGSIZE;
> -     } else {
> -             vinfo.vid = dump->begin;
> -             vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_BEGIN;
> -             if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
> -                         sizeof(vinfo), &vinfo))
> -                     return -EMSGSIZE;
> -             vinfo.vid = dump->end;
> -             vinfo.flags &= ~BRIDGE_VLAN_INFO_RANGE_BEGIN;
> -             vinfo.flags |= BRIDGE_VLAN_INFO_RANGE_END;
> -             if (nla_put(dump->skb, IFLA_BRIDGE_VLAN_INFO,
> -                         sizeof(vinfo), &vinfo))
> -                     return -EMSGSIZE;
> -     }
> -
> -     return 0;
> -}
> -
> -static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj)
> -{
> -     struct switchdev_obj_port_vlan *vlan = SWITCHDEV_OBJ_PORT_VLAN(obj);
> -     struct switchdev_vlan_dump *dump =
> -             container_of(vlan, struct switchdev_vlan_dump, vlan);
> -     int err = 0;
> -
> -     if (vlan->vid_begin > vlan->vid_end)
> -             return -EINVAL;
> -
> -     if (dump->filter_mask & RTEXT_FILTER_BRVLAN) {
> -             dump->flags = vlan->flags;
> -             for (dump->begin = dump->end = vlan->vid_begin;
> -                  dump->begin <= vlan->vid_end;
> -                  dump->begin++, dump->end++) {
> -                     err = switchdev_port_vlan_dump_put(dump);
> -                     if (err)
> -                             return err;
> -             }
> -     } else if (dump->filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED) {
> -             if (dump->begin > vlan->vid_begin &&
> -                 dump->begin >= vlan->vid_end) {
> -                     if ((dump->begin - 1) == vlan->vid_end &&
> -                         dump->flags == vlan->flags) {
> -                             /* prepend */
> -                             dump->begin = vlan->vid_begin;
> -                     } else {
> -                             err = switchdev_port_vlan_dump_put(dump);
> -                             dump->flags = vlan->flags;
> -                             dump->begin = vlan->vid_begin;
> -                             dump->end = vlan->vid_end;
> -                     }
> -             } else if (dump->end <= vlan->vid_begin &&
> -                        dump->end < vlan->vid_end) {
> -                     if ((dump->end  + 1) == vlan->vid_begin &&
> -                         dump->flags == vlan->flags) {
> -                             /* append */
> -                             dump->end = vlan->vid_end;
> -                     } else {
> -                             err = switchdev_port_vlan_dump_put(dump);
> -                             dump->flags = vlan->flags;
> -                             dump->begin = vlan->vid_begin;
> -                             dump->end = vlan->vid_end;
> -                     }
> -             } else {
> -                     err = -EINVAL;
> -             }
> -     }
> -
> -     return err;
> -}
> -
> -static int switchdev_port_vlan_fill(struct sk_buff *skb, struct net_device 
> *dev,
> -                                 u32 filter_mask)
> -{
> -     struct switchdev_vlan_dump dump = {
> -             .vlan.obj.orig_dev = dev,
> -             .vlan.obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
> -             .skb = skb,
> -             .filter_mask = filter_mask,
> -     };
> -     int err = 0;
> -
> -     if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
> -         (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
> -             err = switchdev_port_obj_dump(dev, &dump.vlan.obj,
> -                                           switchdev_port_vlan_dump_cb);
> -             if (err)
> -                     goto err_out;
> -             if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
> -                     /* last one */
> -                     err = switchdev_port_vlan_dump_put(&dump);
> -     }
> -
> -err_out:
> -     return err == -EOPNOTSUPP ? 0 : err;
> -}
> -
> -/**
> - *   switchdev_port_bridge_getlink - Get bridge port attributes
> - *
> - *   @dev: port device
> - *
> - *   Called for SELF on rtnl_bridge_getlink to get bridge port
> - *   attributes.
> - */
> -int switchdev_port_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
> -                               struct net_device *dev, u32 filter_mask,
> -                               int nlflags)
> -{
> -     struct switchdev_attr attr = {
> -             .orig_dev = dev,
> -             .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
> -     };
> -     u16 mode = BRIDGE_MODE_UNDEF;
> -     u32 mask = BR_LEARNING | BR_LEARNING_SYNC | BR_FLOOD;
> -     int err;
> -
> -     if (!netif_is_bridge_port(dev))
> -             return -EOPNOTSUPP;
> -
> -     err = switchdev_port_attr_get(dev, &attr);
> -     if (err && err != -EOPNOTSUPP)
> -             return err;
> -
> -     return ndo_dflt_bridge_getlink(skb, pid, seq, dev, mode,
> -                                    attr.u.brport_flags, mask, nlflags,
> -                                    filter_mask, switchdev_port_vlan_fill);
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_bridge_getlink);
> -
> -static int switchdev_port_br_setflag(struct net_device *dev,
> -                                  struct nlattr *nlattr,
> -                                  unsigned long brport_flag)
> -{
> -     struct switchdev_attr attr = {
> -             .orig_dev = dev,
> -             .id = SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS,
> -     };
> -     u8 flag = nla_get_u8(nlattr);
> -     int err;
> -
> -     err = switchdev_port_attr_get(dev, &attr);
> -     if (err)
> -             return err;
> -
> -     if (flag)
> -             attr.u.brport_flags |= brport_flag;
> -     else
> -             attr.u.brport_flags &= ~brport_flag;
> -
> -     return switchdev_port_attr_set(dev, &attr);
> -}
> -
> -static const struct nla_policy
> -switchdev_port_bridge_policy[IFLA_BRPORT_MAX + 1] = {
> -     [IFLA_BRPORT_STATE]             = { .type = NLA_U8 },
> -     [IFLA_BRPORT_COST]              = { .type = NLA_U32 },
> -     [IFLA_BRPORT_PRIORITY]          = { .type = NLA_U16 },
> -     [IFLA_BRPORT_MODE]              = { .type = NLA_U8 },
> -     [IFLA_BRPORT_GUARD]             = { .type = NLA_U8 },
> -     [IFLA_BRPORT_PROTECT]           = { .type = NLA_U8 },
> -     [IFLA_BRPORT_FAST_LEAVE]        = { .type = NLA_U8 },
> -     [IFLA_BRPORT_LEARNING]          = { .type = NLA_U8 },
> -     [IFLA_BRPORT_LEARNING_SYNC]     = { .type = NLA_U8 },
> -     [IFLA_BRPORT_UNICAST_FLOOD]     = { .type = NLA_U8 },
> -};
> -
> -static int switchdev_port_br_setlink_protinfo(struct net_device *dev,
> -                                           struct nlattr *protinfo)
> -{
> -     struct nlattr *attr;
> -     int rem;
> -     int err;
> -
> -     err = nla_validate_nested(protinfo, IFLA_BRPORT_MAX,
> -                               switchdev_port_bridge_policy, NULL);
> -     if (err)
> -             return err;
> -
> -     nla_for_each_nested(attr, protinfo, rem) {
> -             switch (nla_type(attr)) {
> -             case IFLA_BRPORT_LEARNING:
> -                     err = switchdev_port_br_setflag(dev, attr,
> -                                                     BR_LEARNING);
> -                     break;
> -             case IFLA_BRPORT_LEARNING_SYNC:
> -                     err = switchdev_port_br_setflag(dev, attr,
> -                                                     BR_LEARNING_SYNC);
> -                     break;
> -             case IFLA_BRPORT_UNICAST_FLOOD:
> -                     err = switchdev_port_br_setflag(dev, attr, BR_FLOOD);
> -                     break;
> -             default:
> -                     err = -EOPNOTSUPP;
> -                     break;
> -             }
> -             if (err)
> -                     return err;
> -     }
> -
> -     return 0;
> -}
> -
> -static int switchdev_port_br_afspec(struct net_device *dev,
> -                                 struct nlattr *afspec,
> -                                 int (*f)(struct net_device *dev,
> -                                          const struct switchdev_obj *obj))
> -{
> -     struct nlattr *attr;
> -     struct bridge_vlan_info *vinfo;
> -     struct switchdev_obj_port_vlan vlan = {
> -             .obj.orig_dev = dev,
> -             .obj.id = SWITCHDEV_OBJ_ID_PORT_VLAN,
> -     };
> -     int rem;
> -     int err;
> -
> -     nla_for_each_nested(attr, afspec, rem) {
> -             if (nla_type(attr) != IFLA_BRIDGE_VLAN_INFO)
> -                     continue;
> -             if (nla_len(attr) != sizeof(struct bridge_vlan_info))
> -                     return -EINVAL;
> -             vinfo = nla_data(attr);
> -             if (!vinfo->vid || vinfo->vid >= VLAN_VID_MASK)
> -                     return -EINVAL;
> -             vlan.flags = vinfo->flags;
> -             if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_BEGIN) {
> -                     if (vlan.vid_begin)
> -                             return -EINVAL;
> -                     vlan.vid_begin = vinfo->vid;
> -                     /* don't allow range of pvids */
> -                     if (vlan.flags & BRIDGE_VLAN_INFO_PVID)
> -                             return -EINVAL;
> -             } else if (vinfo->flags & BRIDGE_VLAN_INFO_RANGE_END) {
> -                     if (!vlan.vid_begin)
> -                             return -EINVAL;
> -                     vlan.vid_end = vinfo->vid;
> -                     if (vlan.vid_end <= vlan.vid_begin)
> -                             return -EINVAL;
> -                     err = f(dev, &vlan.obj);
> -                     if (err)
> -                             return err;
> -                     vlan.vid_begin = 0;
> -             } else {
> -                     if (vlan.vid_begin)
> -                             return -EINVAL;
> -                     vlan.vid_begin = vinfo->vid;
> -                     vlan.vid_end = vinfo->vid;
> -                     err = f(dev, &vlan.obj);
> -                     if (err)
> -                             return err;
> -                     vlan.vid_begin = 0;
> -             }
> -     }
> -
> -     return 0;
> -}
> -
> -/**
> - *   switchdev_port_bridge_setlink - Set bridge port attributes
> - *
> - *   @dev: port device
> - *   @nlh: netlink header
> - *   @flags: netlink flags
> - *
> - *   Called for SELF on rtnl_bridge_setlink to set bridge port
> - *   attributes.
> - */
> -int switchdev_port_bridge_setlink(struct net_device *dev,
> -                               struct nlmsghdr *nlh, u16 flags)
> -{
> -     struct nlattr *protinfo;
> -     struct nlattr *afspec;
> -     int err = 0;
> -
> -     if (!netif_is_bridge_port(dev))
> -             return -EOPNOTSUPP;
> -
> -     protinfo = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
> -                                IFLA_PROTINFO);
> -     if (protinfo) {
> -             err = switchdev_port_br_setlink_protinfo(dev, protinfo);
> -             if (err)
> -                     return err;
> -     }
> -
> -     afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
> -                              IFLA_AF_SPEC);
> -     if (afspec)
> -             err = switchdev_port_br_afspec(dev, afspec,
> -                                            switchdev_port_obj_add);
> -
> -     return err;
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_bridge_setlink);
> -
> -/**
> - *   switchdev_port_bridge_dellink - Set bridge port attributes
> - *
> - *   @dev: port device
> - *   @nlh: netlink header
> - *   @flags: netlink flags
> - *
> - *   Called for SELF on rtnl_bridge_dellink to set bridge port
> - *   attributes.
> - */
> -int switchdev_port_bridge_dellink(struct net_device *dev,
> -                               struct nlmsghdr *nlh, u16 flags)
> -{
> -     struct nlattr *afspec;
> -
> -     if (!netif_is_bridge_port(dev))
> -             return -EOPNOTSUPP;
> -
> -     afspec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg),
> -                              IFLA_AF_SPEC);
> -     if (afspec)
> -             return switchdev_port_br_afspec(dev, afspec,
> -                                             switchdev_port_obj_del);
> -
> -     return 0;
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_bridge_dellink);
> -
> -/**
> - *   switchdev_port_fdb_add - Add FDB (MAC/VLAN) entry to port
> - *
> - *   @ndmsg: netlink hdr
> - *   @nlattr: netlink attributes
> - *   @dev: port device
> - *   @addr: MAC address to add
> - *   @vid: VLAN to add
> - *
> - *   Add FDB entry to switch device.
> - */
> -int switchdev_port_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
> -                        struct net_device *dev, const unsigned char *addr,
> -                        u16 vid, u16 nlm_flags)
> -{
> -     struct switchdev_obj_port_fdb fdb = {
> -             .obj.orig_dev = dev,
> -             .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
> -             .vid = vid,
> -     };
> -
> -     ether_addr_copy(fdb.addr, addr);
> -     return switchdev_port_obj_add(dev, &fdb.obj);
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_fdb_add);
> -
> -/**
> - *   switchdev_port_fdb_del - Delete FDB (MAC/VLAN) entry from port
> - *
> - *   @ndmsg: netlink hdr
> - *   @nlattr: netlink attributes
> - *   @dev: port device
> - *   @addr: MAC address to delete
> - *   @vid: VLAN to delete
> - *
> - *   Delete FDB entry from switch device.
> - */
> -int switchdev_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
> -                        struct net_device *dev, const unsigned char *addr,
> -                        u16 vid)
> -{
> -     struct switchdev_obj_port_fdb fdb = {
> -             .obj.orig_dev = dev,
> -             .obj.id = SWITCHDEV_OBJ_ID_PORT_FDB,
> -             .vid = vid,
> -     };
> -
> -     ether_addr_copy(fdb.addr, addr);
> -     return switchdev_port_obj_del(dev, &fdb.obj);
> -}
> -EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
> -
>  bool switchdev_port_same_parent_id(struct net_device *a,
>                                  struct net_device *b)
>  {
> 

Reviewed-by: Ivan Vecera <ivec...@redhat.com>

Reply via email to