[MDBE_ATTR_RTPROT] = NLA_POLICY_MIN(NLA_U8, RTPROT_STATIC),
 };
 
-static bool is_valid_mdb_entry(struct br_mdb_entry *entry,
-                              struct netlink_ext_ack *extack)
+static int validate_mdb_entry(const struct nlattr *attr,
+                             struct netlink_ext_ack *extack)
 {
+       struct br_mdb_entry *entry = nla_data(attr);
+
+       if (nla_len(attr) != sizeof(struct br_mdb_entry)) {
+               NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
+               return -EINVAL;
+       }
+
        if (entry->ifindex == 0) {
                NL_SET_ERR_MSG_MOD(extack, "Zero entry ifindex is not allowed");
-               return false;
+               return -EINVAL;
        }
 
        if (entry->addr.proto == htons(ETH_P_IP)) {
                if (!ipv4_is_multicast(entry->addr.u.ip4)) {
                        NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is not multicast");
-                       return false;
+                       return -EINVAL;
                }
                if (ipv4_is_local_multicast(entry->addr.u.ip4)) {
                        NL_SET_ERR_MSG_MOD(extack, "IPv4 entry group address is local multicast");
-                       return false;
+                       return -EINVAL;
                }
 #if IS_ENABLED(CONFIG_IPV6)
        } else if (entry->addr.proto == htons(ETH_P_IPV6)) {
                if (ipv6_addr_is_ll_all_nodes(&entry->addr.u.ip6)) {
                        NL_SET_ERR_MSG_MOD(extack, "IPv6 entry group address is link-local all nodes");
-                       return false;
+                       return -EINVAL;
                }
 #endif
        } else if (entry->addr.proto == 0) {
                /* L2 mdb */
                if (!is_multicast_ether_addr(entry->addr.u.mac_addr)) {
                        NL_SET_ERR_MSG_MOD(extack, "L2 entry group is not multicast");
-                       return false;
+                       return -EINVAL;
                }
        } else {
                NL_SET_ERR_MSG_MOD(extack, "Unknown entry protocol");
-               return false;
+               return -EINVAL;
        }
 
        if (entry->state != MDB_PERMANENT && entry->state != MDB_TEMPORARY) {
                NL_SET_ERR_MSG_MOD(extack, "Unknown entry state");
-               return false;
+               return -EINVAL;
        }
        if (entry->vid >= VLAN_VID_MASK) {
                NL_SET_ERR_MSG_MOD(extack, "Invalid entry VLAN id");
-               return false;
+               return -EINVAL;
        }
 
-       return true;
+       return 0;
 }
 
 static bool is_valid_mdb_source(struct nlattr *attr, __be16 proto,
        return 0;
 }
 
+static const struct nla_policy mdba_policy[MDBA_SET_ENTRY_MAX + 1] = {
+       [MDBA_SET_ENTRY_UNSPEC] = { .strict_start_type = MDBA_SET_ENTRY_ATTRS + 1 },
+       [MDBA_SET_ENTRY] = NLA_POLICY_VALIDATE_FN(NLA_BINARY,
+                                                 validate_mdb_entry,
+                                                 sizeof(struct br_mdb_entry)),
+       [MDBA_SET_ENTRY_ATTRS] = { .type = NLA_NESTED },
+};
+
 static int br_mdb_config_init(struct net *net, const struct nlmsghdr *nlh,
                              struct br_mdb_config *cfg,
                              struct netlink_ext_ack *extack)
        int err;
 
        err = nlmsg_parse_deprecated(nlh, sizeof(*bpm), tb,
-                                    MDBA_SET_ENTRY_MAX, NULL, extack);
+                                    MDBA_SET_ENTRY_MAX, mdba_policy, extack);
        if (err)
                return err;
 
                NL_SET_ERR_MSG_MOD(extack, "Missing MDBA_SET_ENTRY attribute");
                return -EINVAL;
        }
-       if (nla_len(tb[MDBA_SET_ENTRY]) != sizeof(struct br_mdb_entry)) {
-               NL_SET_ERR_MSG_MOD(extack, "Invalid MDBA_SET_ENTRY attribute length");
-               return -EINVAL;
-       }
 
        cfg->entry = nla_data(tb[MDBA_SET_ENTRY]);
-       if (!is_valid_mdb_entry(cfg->entry, extack))
-               return -EINVAL;
 
        if (cfg->entry->ifindex != cfg->br->dev->ifindex) {
                struct net_device *pdev;