hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/sched/sch_mqprio.c
....@@ -130,6 +130,97 @@
130130 return 0;
131131 }
132132
133
+static int mqprio_parse_nlattr(struct Qdisc *sch, struct tc_mqprio_qopt *qopt,
134
+ struct nlattr *opt,
135
+ struct netlink_ext_ack *extack)
136
+{
137
+ struct mqprio_sched *priv = qdisc_priv(sch);
138
+ struct nlattr *tb[TCA_MQPRIO_MAX + 1];
139
+ struct nlattr *attr;
140
+ int i, rem, err;
141
+
142
+ err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
143
+ sizeof(*qopt));
144
+ if (err < 0)
145
+ return err;
146
+
147
+ if (!qopt->hw) {
148
+ NL_SET_ERR_MSG(extack,
149
+ "mqprio TCA_OPTIONS can only contain netlink attributes in hardware mode");
150
+ return -EINVAL;
151
+ }
152
+
153
+ if (tb[TCA_MQPRIO_MODE]) {
154
+ priv->flags |= TC_MQPRIO_F_MODE;
155
+ priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
156
+ }
157
+
158
+ if (tb[TCA_MQPRIO_SHAPER]) {
159
+ priv->flags |= TC_MQPRIO_F_SHAPER;
160
+ priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
161
+ }
162
+
163
+ if (tb[TCA_MQPRIO_MIN_RATE64]) {
164
+ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
165
+ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MIN_RATE64],
166
+ "min_rate accepted only when shaper is in bw_rlimit mode");
167
+ return -EINVAL;
168
+ }
169
+ i = 0;
170
+ nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
171
+ rem) {
172
+ if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64) {
173
+ NL_SET_ERR_MSG_ATTR(extack, attr,
174
+ "Attribute type expected to be TCA_MQPRIO_MIN_RATE64");
175
+ return -EINVAL;
176
+ }
177
+
178
+ if (nla_len(attr) != sizeof(u64)) {
179
+ NL_SET_ERR_MSG_ATTR(extack, attr,
180
+ "Attribute TCA_MQPRIO_MIN_RATE64 expected to have 8 bytes length");
181
+ return -EINVAL;
182
+ }
183
+
184
+ if (i >= qopt->num_tc)
185
+ break;
186
+ priv->min_rate[i] = *(u64 *)nla_data(attr);
187
+ i++;
188
+ }
189
+ priv->flags |= TC_MQPRIO_F_MIN_RATE;
190
+ }
191
+
192
+ if (tb[TCA_MQPRIO_MAX_RATE64]) {
193
+ if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE) {
194
+ NL_SET_ERR_MSG_ATTR(extack, tb[TCA_MQPRIO_MAX_RATE64],
195
+ "max_rate accepted only when shaper is in bw_rlimit mode");
196
+ return -EINVAL;
197
+ }
198
+ i = 0;
199
+ nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
200
+ rem) {
201
+ if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64) {
202
+ NL_SET_ERR_MSG_ATTR(extack, attr,
203
+ "Attribute type expected to be TCA_MQPRIO_MAX_RATE64");
204
+ return -EINVAL;
205
+ }
206
+
207
+ if (nla_len(attr) != sizeof(u64)) {
208
+ NL_SET_ERR_MSG_ATTR(extack, attr,
209
+ "Attribute TCA_MQPRIO_MAX_RATE64 expected to have 8 bytes length");
210
+ return -EINVAL;
211
+ }
212
+
213
+ if (i >= qopt->num_tc)
214
+ break;
215
+ priv->max_rate[i] = *(u64 *)nla_data(attr);
216
+ i++;
217
+ }
218
+ priv->flags |= TC_MQPRIO_F_MAX_RATE;
219
+ }
220
+
221
+ return 0;
222
+}
223
+
133224 static int mqprio_init(struct Qdisc *sch, struct nlattr *opt,
134225 struct netlink_ext_ack *extack)
135226 {
....@@ -139,9 +230,6 @@
139230 struct Qdisc *qdisc;
140231 int i, err = -EOPNOTSUPP;
141232 struct tc_mqprio_qopt *qopt = NULL;
142
- struct nlattr *tb[TCA_MQPRIO_MAX + 1];
143
- struct nlattr *attr;
144
- int rem;
145233 int len;
146234
147235 BUILD_BUG_ON(TC_MAX_QUEUE != TC_QOPT_MAX_QUEUE);
....@@ -166,55 +254,9 @@
166254
167255 len = nla_len(opt) - NLA_ALIGN(sizeof(*qopt));
168256 if (len > 0) {
169
- err = parse_attr(tb, TCA_MQPRIO_MAX, opt, mqprio_policy,
170
- sizeof(*qopt));
171
- if (err < 0)
257
+ err = mqprio_parse_nlattr(sch, qopt, opt, extack);
258
+ if (err)
172259 return err;
173
-
174
- if (!qopt->hw)
175
- return -EINVAL;
176
-
177
- if (tb[TCA_MQPRIO_MODE]) {
178
- priv->flags |= TC_MQPRIO_F_MODE;
179
- priv->mode = *(u16 *)nla_data(tb[TCA_MQPRIO_MODE]);
180
- }
181
-
182
- if (tb[TCA_MQPRIO_SHAPER]) {
183
- priv->flags |= TC_MQPRIO_F_SHAPER;
184
- priv->shaper = *(u16 *)nla_data(tb[TCA_MQPRIO_SHAPER]);
185
- }
186
-
187
- if (tb[TCA_MQPRIO_MIN_RATE64]) {
188
- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
189
- return -EINVAL;
190
- i = 0;
191
- nla_for_each_nested(attr, tb[TCA_MQPRIO_MIN_RATE64],
192
- rem) {
193
- if (nla_type(attr) != TCA_MQPRIO_MIN_RATE64)
194
- return -EINVAL;
195
- if (i >= qopt->num_tc)
196
- break;
197
- priv->min_rate[i] = *(u64 *)nla_data(attr);
198
- i++;
199
- }
200
- priv->flags |= TC_MQPRIO_F_MIN_RATE;
201
- }
202
-
203
- if (tb[TCA_MQPRIO_MAX_RATE64]) {
204
- if (priv->shaper != TC_MQPRIO_SHAPER_BW_RATE)
205
- return -EINVAL;
206
- i = 0;
207
- nla_for_each_nested(attr, tb[TCA_MQPRIO_MAX_RATE64],
208
- rem) {
209
- if (nla_type(attr) != TCA_MQPRIO_MAX_RATE64)
210
- return -EINVAL;
211
- if (i >= qopt->num_tc)
212
- break;
213
- priv->max_rate[i] = *(u64 *)nla_data(attr);
214
- i++;
215
- }
216
- priv->flags |= TC_MQPRIO_F_MAX_RATE;
217
- }
218260 }
219261
220262 /* pre-allocate qdisc, attachment can't fail */