}
 
 static int rocker_port_fdb_dump(const struct rocker_port *rocker_port,
-                               struct switchdev_obj *obj)
+                               struct switchdev_obj_fdb *fdb,
+                               int (*cb)(void *obj))
 {
        struct rocker *rocker = rocker_port->rocker;
-       struct switchdev_obj_fdb *fdb = &obj->u.fdb;
        struct rocker_fdb_tbl_entry *found;
        struct hlist_node *tmp;
        unsigned long lock_flags;
                fdb->ndm_state = NUD_REACHABLE;
                fdb->vid = rocker_port_vlan_to_vid(rocker_port,
                                                   found->key.vlan_id);
-               err = obj->cb(obj);
+               err = cb(fdb);
                if (err)
                        break;
        }
 }
 
 static int rocker_port_vlan_dump(const struct rocker_port *rocker_port,
-                                struct switchdev_obj *obj)
+                                struct switchdev_obj_vlan *vlan,
+                               int (*cb)(void *obj))
 {
-       struct switchdev_obj_vlan *vlan = &obj->u.vlan;
        u16 vid;
        int err = 0;
 
                if (rocker_vlan_id_is_internal(htons(vid)))
                        vlan->flags |= BRIDGE_VLAN_INFO_PVID;
                vlan->vid_begin = vlan->vid_end = vid;
-               err = obj->cb(obj);
+               err = cb(vlan);
                if (err)
                        break;
        }
 }
 
 static int rocker_port_obj_dump(struct net_device *dev,
-                               struct switchdev_obj *obj)
+                               enum switchdev_obj_id id, void *obj,
+                               int (*cb)(void *obj))
 {
        const struct rocker_port *rocker_port = netdev_priv(dev);
        int err = 0;
 
-       switch (obj->id) {
+       switch (id) {
        case SWITCHDEV_OBJ_PORT_FDB:
-               err = rocker_port_fdb_dump(rocker_port, obj);
+               err = rocker_port_fdb_dump(rocker_port, obj, cb);
                break;
        case SWITCHDEV_OBJ_PORT_VLAN:
-               err = rocker_port_vlan_dump(rocker_port, obj);
+               err = rocker_port_vlan_dump(rocker_port, obj, cb);
                break;
        default:
                err = -EOPNOTSUPP;
 
        int     (*switchdev_port_obj_del)(struct net_device *dev,
                                          struct switchdev_obj *obj);
        int     (*switchdev_port_obj_dump)(struct net_device *dev,
-                                         struct switchdev_obj *obj);
+                                          enum switchdev_obj_id id, void *obj,
+                                          int (*cb)(void *obj));
 };
 
 enum switchdev_notifier_type {
                            struct switchdev_attr *attr);
 int switchdev_port_obj_add(struct net_device *dev, struct switchdev_obj *obj);
 int switchdev_port_obj_del(struct net_device *dev, struct switchdev_obj *obj);
-int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj);
+int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id,
+                           void *obj, int (*cb)(void *obj));
 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,
 }
 
 static inline int switchdev_port_obj_dump(struct net_device *dev,
-                                         struct switchdev_obj *obj)
+                                         enum switchdev_obj_id id, void *obj,
+                                         int (*cb)(void *obj))
 {
        return -EOPNOTSUPP;
 }
 
 }
 
 static int dsa_slave_port_vlan_dump(struct net_device *dev,
-                                   struct switchdev_obj *obj)
+                                   struct switchdev_obj_vlan *vlan,
+                                   int (*cb)(void *obj))
 {
-       struct switchdev_obj_vlan *vlan = &obj->u.vlan;
        struct dsa_slave_priv *p = netdev_priv(dev);
        struct dsa_switch *ds = p->parent;
        DECLARE_BITMAP(members, DSA_MAX_PORTS);
                if (test_bit(p->port, untagged))
                        vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;
 
-               err = obj->cb(obj);
+               err = cb(vlan);
                if (err)
                        break;
        }
 }
 
 static int dsa_slave_port_fdb_dump(struct net_device *dev,
-                                  struct switchdev_obj *obj)
+                                  struct switchdev_obj_fdb *fdb,
+                                  int (*cb)(void *obj))
 {
        struct dsa_slave_priv *p = netdev_priv(dev);
        struct dsa_switch *ds = p->parent;
                if (ret < 0)
                        break;
 
-               obj->u.fdb.addr = addr;
-               obj->u.fdb.vid = vid;
-               obj->u.fdb.ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
+               fdb->addr = addr;
+               fdb->vid = vid;
+               fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
 
-               ret = obj->cb(obj);
+               ret = cb(fdb);
                if (ret < 0)
                        break;
        }
 }
 
 static int dsa_slave_port_obj_dump(struct net_device *dev,
-                                  struct switchdev_obj *obj)
+                                  enum switchdev_obj_id id, void *obj,
+                                  int (*cb)(void *obj))
 {
        int err;
 
-       switch (obj->id) {
+       switch (id) {
        case SWITCHDEV_OBJ_PORT_FDB:
-               err = dsa_slave_port_fdb_dump(dev, obj);
+               err = dsa_slave_port_fdb_dump(dev, obj, cb);
                break;
        case SWITCHDEV_OBJ_PORT_VLAN:
-               err = dsa_slave_port_vlan_dump(dev, obj);
+               err = dsa_slave_port_vlan_dump(dev, obj, cb);
                break;
        default:
                err = -EOPNOTSUPP;
 
  *     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
  */
-int switchdev_port_obj_dump(struct net_device *dev, struct switchdev_obj *obj)
+int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id,
+                           void *obj, int (*cb)(void *obj))
 {
        const struct switchdev_ops *ops = dev->switchdev_ops;
        struct net_device *lower_dev;
        int err = -EOPNOTSUPP;
 
        if (ops && ops->switchdev_port_obj_dump)
-               return ops->switchdev_port_obj_dump(dev, obj);
+               return ops->switchdev_port_obj_dump(dev, id, obj, cb);
 
        /* Switch device port(s) may be stacked under
         * bond/team/vlan dev, so recurse down to dump objects on
         */
 
        netdev_for_each_lower_dev(dev, lower_dev, iter) {
-               err = switchdev_port_obj_dump(lower_dev, obj);
+               err = switchdev_port_obj_dump(lower_dev, id, obj, cb);
                break;
        }
 
 EXPORT_SYMBOL_GPL(call_switchdev_notifiers);
 
 struct switchdev_vlan_dump {
-       struct switchdev_obj obj;
+       struct switchdev_obj_vlan vlan;
        struct sk_buff *skb;
        u32 filter_mask;
        u16 flags;
        return 0;
 }
 
-static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj)
+static int switchdev_port_vlan_dump_cb(void *obj)
 {
+       struct switchdev_obj_vlan *vlan = obj;
        struct switchdev_vlan_dump *dump =
-               container_of(obj, struct switchdev_vlan_dump, obj);
-       struct switchdev_obj_vlan *vlan = &dump->obj.u.vlan;
+               container_of(vlan, struct switchdev_vlan_dump, vlan);
        int err = 0;
 
        if (vlan->vid_begin > vlan->vid_end)
                                    u32 filter_mask)
 {
        struct switchdev_vlan_dump dump = {
-               .obj = {
-                       .id = SWITCHDEV_OBJ_PORT_VLAN,
-                       .cb = switchdev_port_vlan_dump_cb,
-               },
                .skb = skb,
                .filter_mask = filter_mask,
        };
 
        if ((filter_mask & RTEXT_FILTER_BRVLAN) ||
            (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
-               err = switchdev_port_obj_dump(dev, &dump.obj);
+               err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_VLAN,
+                                             &dump.vlan,
+                                             switchdev_port_vlan_dump_cb);
                if (err)
                        goto err_out;
                if (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)
 EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
 
 struct switchdev_fdb_dump {
-       struct switchdev_obj obj;
+       struct switchdev_obj_fdb fdb;
        struct net_device *dev;
        struct sk_buff *skb;
        struct netlink_callback *cb;
        int idx;
 };
 
-static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj)
+static int switchdev_port_fdb_dump_cb(void *obj)
 {
+       struct switchdev_obj_fdb *fdb = obj;
        struct switchdev_fdb_dump *dump =
-               container_of(obj, struct switchdev_fdb_dump, obj);
+               container_of(fdb, struct switchdev_fdb_dump, fdb);
        u32 portid = NETLINK_CB(dump->cb->skb).portid;
        u32 seq = dump->cb->nlh->nlmsg_seq;
        struct nlmsghdr *nlh;
        ndm->ndm_flags   = NTF_SELF;
        ndm->ndm_type    = 0;
        ndm->ndm_ifindex = dump->dev->ifindex;
-       ndm->ndm_state   = obj->u.fdb.ndm_state;
+       ndm->ndm_state   = fdb->ndm_state;
 
-       if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, obj->u.fdb.addr))
+       if (nla_put(dump->skb, NDA_LLADDR, ETH_ALEN, fdb->addr))
                goto nla_put_failure;
 
-       if (obj->u.fdb.vid && nla_put_u16(dump->skb, NDA_VLAN, obj->u.fdb.vid))
+       if (fdb->vid && nla_put_u16(dump->skb, NDA_VLAN, fdb->vid))
                goto nla_put_failure;
 
        nlmsg_end(dump->skb, nlh);
                            struct net_device *filter_dev, int idx)
 {
        struct switchdev_fdb_dump dump = {
-               .obj = {
-                       .id = SWITCHDEV_OBJ_PORT_FDB,
-                       .cb = switchdev_port_fdb_dump_cb,
-               },
                .dev = dev,
                .skb = skb,
                .cb = cb,
                .idx = idx,
        };
 
-       switchdev_port_obj_dump(dev, &dump.obj);
+       switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_PORT_FDB, &dump.fdb,
+                               switchdev_port_fdb_dump_cb);
        return dump.idx;
 }
 EXPORT_SYMBOL_GPL(switchdev_port_fdb_dump);