}
 
 static int rocker_port_obj_add(struct net_device *dev,
-                              enum switchdev_obj_id id, const void *obj,
+                              enum switchdev_obj_id id,
+                              const struct switchdev_obj *obj,
                               struct switchdev_trans *trans)
 {
        struct rocker_port *rocker_port = netdev_priv(dev);
 
        switch (id) {
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
-               err = rocker_port_vlans_add(rocker_port, trans, obj);
+               err = rocker_port_vlans_add(rocker_port, trans,
+                                           SWITCHDEV_OBJ_PORT_VLAN(obj));
                break;
        case SWITCHDEV_OBJ_ID_IPV4_FIB:
-               fib4 = obj;
+               fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
                err = rocker_port_fib_ipv4(rocker_port, trans,
                                           htonl(fib4->dst), fib4->dst_len,
                                           fib4->fi, fib4->tb_id, 0);
                break;
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = rocker_port_fdb_add(rocker_port, trans, obj);
+               err = rocker_port_fdb_add(rocker_port, trans,
+                                         SWITCHDEV_OBJ_PORT_FDB(obj));
                break;
        default:
                err = -EOPNOTSUPP;
 }
 
 static int rocker_port_obj_del(struct net_device *dev,
-                              enum switchdev_obj_id id, const void *obj)
+                              enum switchdev_obj_id id,
+                              const struct switchdev_obj *obj)
 {
        struct rocker_port *rocker_port = netdev_priv(dev);
        const struct switchdev_obj_ipv4_fib *fib4;
 
        switch (id) {
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
-               err = rocker_port_vlans_del(rocker_port, obj);
+               err = rocker_port_vlans_del(rocker_port,
+                                           SWITCHDEV_OBJ_PORT_VLAN(obj));
                break;
        case SWITCHDEV_OBJ_ID_IPV4_FIB:
-               fib4 = obj;
+               fib4 = SWITCHDEV_OBJ_IPV4_FIB(obj);
                err = rocker_port_fib_ipv4(rocker_port, NULL,
                                           htonl(fib4->dst), fib4->dst_len,
                                           fib4->fi, fib4->tb_id,
                                           ROCKER_OP_FLAG_REMOVE);
                break;
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = rocker_port_fdb_del(rocker_port, NULL, obj);
+               err = rocker_port_fdb_del(rocker_port, NULL,
+                                         SWITCHDEV_OBJ_PORT_FDB(obj));
                break;
        default:
                err = -EOPNOTSUPP;
 
 static int rocker_port_fdb_dump(const struct rocker_port *rocker_port,
                                struct switchdev_obj_port_fdb *fdb,
-                               int (*cb)(void *obj))
+                               switchdev_obj_dump_cb_t *cb)
 {
        struct rocker *rocker = rocker_port->rocker;
        struct rocker_fdb_tbl_entry *found;
                fdb->ndm_state = NUD_REACHABLE;
                fdb->vid = rocker_port_vlan_to_vid(rocker_port,
                                                   found->key.vlan_id);
-               err = cb(fdb);
+               err = cb(&fdb->obj);
                if (err)
                        break;
        }
 
 static int rocker_port_vlan_dump(const struct rocker_port *rocker_port,
                                 struct switchdev_obj_port_vlan *vlan,
-                               int (*cb)(void *obj))
+                                switchdev_obj_dump_cb_t *cb)
 {
        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 = cb(vlan);
+               err = cb(&vlan->obj);
                if (err)
                        break;
        }
 }
 
 static int rocker_port_obj_dump(struct net_device *dev,
-                               enum switchdev_obj_id id, void *obj,
-                               int (*cb)(void *obj))
+                               enum switchdev_obj_id id,
+                               struct switchdev_obj *obj,
+                               switchdev_obj_dump_cb_t *cb)
 {
        const struct rocker_port *rocker_port = netdev_priv(dev);
        int err = 0;
 
        switch (id) {
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = rocker_port_fdb_dump(rocker_port, obj, cb);
+               err = rocker_port_fdb_dump(rocker_port,
+                                          SWITCHDEV_OBJ_PORT_FDB(obj), cb);
                break;
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
-               err = rocker_port_vlan_dump(rocker_port, obj, cb);
+               err = rocker_port_vlan_dump(rocker_port,
+                                           SWITCHDEV_OBJ_PORT_VLAN(obj), cb);
                break;
        default:
                err = -EOPNOTSUPP;
 
        SWITCHDEV_OBJ_ID_PORT_FDB,
 };
 
+struct switchdev_obj {
+};
+
 /* SWITCHDEV_OBJ_ID_PORT_VLAN */
 struct switchdev_obj_port_vlan {
+       struct switchdev_obj obj;
        u16 flags;
        u16 vid_begin;
        u16 vid_end;
 };
 
+#define SWITCHDEV_OBJ_PORT_VLAN(obj) \
+       container_of(obj, struct switchdev_obj_port_vlan, obj)
+
 /* SWITCHDEV_OBJ_ID_IPV4_FIB */
 struct switchdev_obj_ipv4_fib {
+       struct switchdev_obj obj;
        u32 dst;
        int dst_len;
        struct fib_info *fi;
        u32 tb_id;
 };
 
+#define SWITCHDEV_OBJ_IPV4_FIB(obj) \
+       container_of(obj, struct switchdev_obj_ipv4_fib, obj)
+
 /* SWITCHDEV_OBJ_ID_PORT_FDB */
 struct switchdev_obj_port_fdb {
+       struct switchdev_obj obj;
        const unsigned char *addr;
        u16 vid;
        u16 ndm_state;
 };
 
+#define SWITCHDEV_OBJ_PORT_FDB(obj) \
+       container_of(obj, struct switchdev_obj_port_fdb, obj)
+
 void switchdev_trans_item_enqueue(struct switchdev_trans *trans,
                                  void *data, void (*destructor)(void const *),
                                  struct switchdev_trans_item *tritem);
 void *switchdev_trans_item_dequeue(struct switchdev_trans *trans);
 
+typedef int switchdev_obj_dump_cb_t(struct switchdev_obj *obj);
+
 /**
  * struct switchdev_ops - switchdev operations
  *
                                           struct switchdev_trans *trans);
        int     (*switchdev_port_obj_add)(struct net_device *dev,
                                          enum switchdev_obj_id id,
-                                         const void *obj,
+                                         const struct switchdev_obj *obj,
                                          struct switchdev_trans *trans);
        int     (*switchdev_port_obj_del)(struct net_device *dev,
                                          enum switchdev_obj_id id,
-                                         const void *obj);
+                                         const struct switchdev_obj *obj);
        int     (*switchdev_port_obj_dump)(struct net_device *dev,
-                                          enum switchdev_obj_id id, void *obj,
-                                          int (*cb)(void *obj));
+                                          enum switchdev_obj_id id,
+                                          struct switchdev_obj *obj,
+                                          switchdev_obj_dump_cb_t *cb);
 };
 
 enum switchdev_notifier_type {
 int switchdev_port_attr_set(struct net_device *dev,
                            struct switchdev_attr *attr);
 int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id,
-                          const void *obj);
+                          const struct switchdev_obj *obj);
 int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id,
-                          const void *obj);
+                          const struct switchdev_obj *obj);
 int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id,
-                           void *obj, int (*cb)(void *obj));
+                           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,
 
 static inline int switchdev_port_obj_add(struct net_device *dev,
                                         enum switchdev_obj_id id,
-                                        const void *obj)
+                                        const struct switchdev_obj *obj)
 {
        return -EOPNOTSUPP;
 }
 
 static inline int switchdev_port_obj_del(struct net_device *dev,
                                         enum switchdev_obj_id id,
-                                        const void *obj)
+                                        const struct switchdev_obj *obj)
 {
        return -EOPNOTSUPP;
 }
 
 static inline int switchdev_port_obj_dump(struct net_device *dev,
-                                         enum switchdev_obj_id id, void *obj,
-                                         int (*cb)(void *obj))
+                                         enum switchdev_obj_id id,
+                                         const struct switchdev_obj *obj,
+                                         switchdev_obj_dump_cb_t *cb)
 {
        return -EOPNOTSUPP;
 }
 
                .vid = f->vlan_id,
        };
 
-       switchdev_port_obj_del(f->dst->dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb);
+       switchdev_port_obj_del(f->dst->dev, SWITCHDEV_OBJ_ID_PORT_FDB,
+                              &fdb.obj);
 }
 
 static void fdb_delete(struct net_bridge *br, struct net_bridge_fdb_entry *f)
 
                };
 
                err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_VLAN,
-                                            &v);
+                                            &v.obj);
                if (err == -EOPNOTSUPP)
                        err = 0;
        }
                };
 
                err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_VLAN,
-                                            &v);
+                                            &v.obj);
                if (err == -EOPNOTSUPP)
                        err = 0;
        }
 
 
 static int dsa_slave_port_vlan_dump(struct net_device *dev,
                                    struct switchdev_obj_port_vlan *vlan,
-                                   int (*cb)(void *obj))
+                                   switchdev_obj_dump_cb_t *cb)
 {
        struct dsa_slave_priv *p = netdev_priv(dev);
        struct dsa_switch *ds = p->parent;
                if (test_bit(p->port, untagged))
                        vlan->flags |= BRIDGE_VLAN_INFO_UNTAGGED;
 
-               err = cb(vlan);
+               err = cb(&vlan->obj);
                if (err)
                        break;
        }
 
 static int dsa_slave_port_fdb_dump(struct net_device *dev,
                                   struct switchdev_obj_port_fdb *fdb,
-                                  int (*cb)(void *obj))
+                                  switchdev_obj_dump_cb_t *cb)
 {
        struct dsa_slave_priv *p = netdev_priv(dev);
        struct dsa_switch *ds = p->parent;
                fdb->vid = vid;
                fdb->ndm_state = is_static ? NUD_NOARP : NUD_REACHABLE;
 
-               ret = cb(fdb);
+               ret = cb(&fdb->obj);
                if (ret < 0)
                        break;
        }
 }
 
 static int dsa_slave_port_obj_add(struct net_device *dev,
-                                 enum switchdev_obj_id id, const void *obj,
+                                 enum switchdev_obj_id id,
+                                 const struct switchdev_obj *obj,
                                  struct switchdev_trans *trans)
 {
        int err;
 
        switch (id) {
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = dsa_slave_port_fdb_add(dev, obj, trans);
+               err = dsa_slave_port_fdb_add(dev,
+                                            SWITCHDEV_OBJ_PORT_FDB(obj),
+                                            trans);
                break;
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
-               err = dsa_slave_port_vlan_add(dev, obj, trans);
+               err = dsa_slave_port_vlan_add(dev,
+                                             SWITCHDEV_OBJ_PORT_VLAN(obj),
+                                             trans);
                break;
        default:
                err = -EOPNOTSUPP;
 }
 
 static int dsa_slave_port_obj_del(struct net_device *dev,
-                                 enum switchdev_obj_id id, const void *obj)
+                                 enum switchdev_obj_id id,
+                                 const struct switchdev_obj *obj)
 {
        int err;
 
        switch (id) {
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = dsa_slave_port_fdb_del(dev, obj);
+               err = dsa_slave_port_fdb_del(dev,
+                                            SWITCHDEV_OBJ_PORT_FDB(obj));
                break;
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
-               err = dsa_slave_port_vlan_del(dev, obj);
+               err = dsa_slave_port_vlan_del(dev,
+                                             SWITCHDEV_OBJ_PORT_VLAN(obj));
                break;
        default:
                err = -EOPNOTSUPP;
 }
 
 static int dsa_slave_port_obj_dump(struct net_device *dev,
-                                  enum switchdev_obj_id id, void *obj,
-                                  int (*cb)(void *obj))
+                                  enum switchdev_obj_id id,
+                                  struct switchdev_obj *obj,
+                                  switchdev_obj_dump_cb_t *cb)
 {
        int err;
 
        switch (id) {
        case SWITCHDEV_OBJ_ID_PORT_FDB:
-               err = dsa_slave_port_fdb_dump(dev, obj, cb);
+               err = dsa_slave_port_fdb_dump(dev,
+                                             SWITCHDEV_OBJ_PORT_FDB(obj),
+                                             cb);
                break;
        case SWITCHDEV_OBJ_ID_PORT_VLAN:
-               err = dsa_slave_port_vlan_dump(dev, obj, cb);
+               err = dsa_slave_port_vlan_dump(dev,
+                                              SWITCHDEV_OBJ_PORT_VLAN(obj),
+                                              cb);
                break;
        default:
                err = -EOPNOTSUPP;
 
 EXPORT_SYMBOL_GPL(switchdev_port_attr_set);
 
 static int __switchdev_port_obj_add(struct net_device *dev,
-                                   enum switchdev_obj_id id, const void *obj,
+                                   enum switchdev_obj_id id,
+                                   const struct switchdev_obj *obj,
                                    struct switchdev_trans *trans)
 {
        const struct switchdev_ops *ops = dev->switchdev_ops;
  *     rtnl_lock must be held.
  */
 int switchdev_port_obj_add(struct net_device *dev, enum switchdev_obj_id id,
-                          const void *obj)
+                          const struct switchdev_obj *obj)
 {
        struct switchdev_trans trans;
        int err;
  *     @obj: object to delete
  */
 int switchdev_port_obj_del(struct net_device *dev, enum switchdev_obj_id id,
-                          const void *obj)
+                          const struct switchdev_obj *obj)
 {
        const struct switchdev_ops *ops = dev->switchdev_ops;
        struct net_device *lower_dev;
  *     @cb: function to call with a filled object
  */
 int switchdev_port_obj_dump(struct net_device *dev, enum switchdev_obj_id id,
-                           void *obj, int (*cb)(void *obj))
+                           struct switchdev_obj *obj,
+                           switchdev_obj_dump_cb_t *cb)
 {
        const struct switchdev_ops *ops = dev->switchdev_ops;
        struct net_device *lower_dev;
        return 0;
 }
 
-static int switchdev_port_vlan_dump_cb(void *obj)
+static int switchdev_port_vlan_dump_cb(struct switchdev_obj *obj)
 {
-       struct switchdev_obj_port_vlan *vlan = 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 ((filter_mask & RTEXT_FILTER_BRVLAN) ||
            (filter_mask & RTEXT_FILTER_BRVLAN_COMPRESSED)) {
                err = switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_VLAN,
-                                             &dump.vlan,
+                                             &dump.vlan.obj,
                                              switchdev_port_vlan_dump_cb);
                if (err)
                        goto err_out;
                                    struct nlattr *afspec,
                                    int (*f)(struct net_device *dev,
                                             enum switchdev_obj_id id,
-                                            const void *obj))
+                                            const struct switchdev_obj *obj))
 {
        struct nlattr *attr;
        struct bridge_vlan_info *vinfo;
-       struct switchdev_obj_port_vlan vlan = { 0 };
+       struct switchdev_obj_port_vlan vlan = { {}, 0 };
        int rem;
        int err;
 
                        vlan.vid_end = vinfo->vid;
                        if (vlan.vid_end <= vlan.vid_begin)
                                return -EINVAL;
-                       err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan);
+                       err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan.obj);
                        if (err)
                                return err;
                        memset(&vlan, 0, sizeof(vlan));
                                return -EINVAL;
                        vlan.vid_begin = vinfo->vid;
                        vlan.vid_end = vinfo->vid;
-                       err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan);
+                       err = f(dev, SWITCHDEV_OBJ_ID_PORT_VLAN, &vlan.obj);
                        if (err)
                                return err;
                        memset(&vlan, 0, sizeof(vlan));
                .vid = vid,
        };
 
-       return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb);
+       return switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb.obj);
 }
 EXPORT_SYMBOL_GPL(switchdev_port_fdb_add);
 
                .vid = vid,
        };
 
-       return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb);
+       return switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &fdb.obj);
 }
 EXPORT_SYMBOL_GPL(switchdev_port_fdb_del);
 
        int idx;
 };
 
-static int switchdev_port_fdb_dump_cb(void *obj)
+static int switchdev_port_fdb_dump_cb(struct switchdev_obj *obj)
 {
-       struct switchdev_obj_port_fdb *fdb = obj;
+       struct switchdev_obj_port_fdb *fdb = SWITCHDEV_OBJ_PORT_FDB(obj);
        struct switchdev_fdb_dump *dump =
                container_of(fdb, struct switchdev_fdb_dump, fdb);
        u32 portid = NETLINK_CB(dump->cb->skb).portid;
                .idx = idx,
        };
 
-       switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &dump.fdb,
+       switchdev_port_obj_dump(dev, SWITCHDEV_OBJ_ID_PORT_FDB, &dump.fdb.obj,
                                switchdev_port_fdb_dump_cb);
        return dump.idx;
 }
        if (!dev)
                return 0;
 
-       err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, &ipv4_fib);
+       err = switchdev_port_obj_add(dev, SWITCHDEV_OBJ_ID_IPV4_FIB,
+                                    &ipv4_fib.obj);
        if (!err)
                fi->fib_flags |= RTNH_F_OFFLOAD;
 
        if (!dev)
                return 0;
 
-       err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_IPV4_FIB, &ipv4_fib);
+       err = switchdev_port_obj_del(dev, SWITCHDEV_OBJ_ID_IPV4_FIB,
+                                    &ipv4_fib.obj);
        if (!err)
                fi->fib_flags &= ~RTNH_F_OFFLOAD;