* TCA_OPTIONS, which are appended right after struct tc_mqprio_qopt.
  */
 static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
-                              struct nlattr *opt)
+                              struct nlattr *opt,
+                              struct netlink_ext_ack *extack)
 {
        struct nlattr *nlattr_opt = nla_data(opt) + NLA_ALIGN(sizeof(*qopt));
        int nlattr_opt_len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
                        return err;
        }
 
-       if (!qopt->hw)
+       if (!qopt->hw) {
+               NL_SET_ERR_MSG(extack,
+                              "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode");
                return -EINVAL;
+       }
 
        if (tb[TCA_MQPRIO_MODE]) {
                priv->flags |= TC_MQPRIO_F_MODE;
        }
 
        if (tb[TCA_MQPRIO_MIN_RATE64]) {
-               if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
+               if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
+                       NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64],
+                                           "min_rate accepted only when shaper is in bw_rlimit mode");
                        return -EINVAL;
+               }
                i = 0;
                nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
                                    rem) {
-                       if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
+                       if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) {
+                               NL_SET_ERR_MSG_ATTR(extack, attr,
+                                                   "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
                                return -EINVAL;
+                       }
                        if (i >= qopt->num_tc)
                                break;
                        priv->min_rate[i] = nla_get_u64(attr);
        }
 
        if (tb[TCA_MQPRIO_MAX_RATE64]) {
-               if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
+               if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
+                       NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64],
+                                           "max_rate accepted only when shaper is in bw_rlimit mode");
                        return -EINVAL;
+               }
                i = 0;
                nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
                                    rem) {
-                       if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
+                       if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) {
+                               NL_SET_ERR_MSG_ATTR(extack, attr,
+                                                   "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
                                return -EINVAL;
+                       }
                        if (i >= qopt->num_tc)
                                break;
                        priv->max_rate[i] = nla_get_u64(attr);
 
        len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
        if (len > 0) {
-               err = mqprio_parse_nlattr(sch, qopt, opt);
+               err = mqprio_parse_nlattr(sch, qopt, opt, extack);
                if (err)
                        return err;
        }