aboutsummaryrefslogtreecommitdiffstats
path: root/net/sched/cls_flower.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/sched/cls_flower.c')
-rw-r--r--net/sched/cls_flower.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c
index dad04e710493..12ca9d13db83 100644
--- a/net/sched/cls_flower.c
+++ b/net/sched/cls_flower.c
@@ -1290,17 +1290,23 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
1290 struct cls_fl_head *head = rtnl_dereference(tp->root); 1290 struct cls_fl_head *head = rtnl_dereference(tp->root);
1291 struct cls_fl_filter *fold = *arg; 1291 struct cls_fl_filter *fold = *arg;
1292 struct cls_fl_filter *fnew; 1292 struct cls_fl_filter *fnew;
1293 struct fl_flow_mask *mask;
1293 struct nlattr **tb; 1294 struct nlattr **tb;
1294 struct fl_flow_mask mask = {};
1295 int err; 1295 int err;
1296 1296
1297 if (!tca[TCA_OPTIONS]) 1297 if (!tca[TCA_OPTIONS])
1298 return -EINVAL; 1298 return -EINVAL;
1299 1299
1300 tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL); 1300 mask = kzalloc(sizeof(struct fl_flow_mask), GFP_KERNEL);
1301 if (!tb) 1301 if (!mask)
1302 return -ENOBUFS; 1302 return -ENOBUFS;
1303 1303
1304 tb = kcalloc(TCA_FLOWER_MAX + 1, sizeof(struct nlattr *), GFP_KERNEL);
1305 if (!tb) {
1306 err = -ENOBUFS;
1307 goto errout_mask_alloc;
1308 }
1309
1304 err = nla_parse_nested(tb, TCA_FLOWER_MAX, tca[TCA_OPTIONS], 1310 err = nla_parse_nested(tb, TCA_FLOWER_MAX, tca[TCA_OPTIONS],
1305 fl_policy, NULL); 1311 fl_policy, NULL);
1306 if (err < 0) 1312 if (err < 0)
@@ -1343,12 +1349,12 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
1343 } 1349 }
1344 } 1350 }
1345 1351
1346 err = fl_set_parms(net, tp, fnew, &mask, base, tb, tca[TCA_RATE], ovr, 1352 err = fl_set_parms(net, tp, fnew, mask, base, tb, tca[TCA_RATE], ovr,
1347 tp->chain->tmplt_priv, extack); 1353 tp->chain->tmplt_priv, extack);
1348 if (err) 1354 if (err)
1349 goto errout_idr; 1355 goto errout_idr;
1350 1356
1351 err = fl_check_assign_mask(head, fnew, fold, &mask); 1357 err = fl_check_assign_mask(head, fnew, fold, mask);
1352 if (err) 1358 if (err)
1353 goto errout_idr; 1359 goto errout_idr;
1354 1360
@@ -1365,7 +1371,7 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
1365 if (!tc_skip_hw(fnew->flags)) { 1371 if (!tc_skip_hw(fnew->flags)) {
1366 err = fl_hw_replace_filter(tp, fnew, extack); 1372 err = fl_hw_replace_filter(tp, fnew, extack);
1367 if (err) 1373 if (err)
1368 goto errout_mask; 1374 goto errout_mask_ht;
1369 } 1375 }
1370 1376
1371 if (!tc_in_hw(fnew->flags)) 1377 if (!tc_in_hw(fnew->flags))
@@ -1392,8 +1398,13 @@ static int fl_change(struct net *net, struct sk_buff *in_skb,
1392 } 1398 }
1393 1399
1394 kfree(tb); 1400 kfree(tb);
1401 kfree(mask);
1395 return 0; 1402 return 0;
1396 1403
1404errout_mask_ht:
1405 rhashtable_remove_fast(&fnew->mask->ht, &fnew->ht_node,
1406 fnew->mask->filter_ht_params);
1407
1397errout_mask: 1408errout_mask:
1398 fl_mask_put(head, fnew->mask, false); 1409 fl_mask_put(head, fnew->mask, false);
1399 1410
@@ -1405,6 +1416,8 @@ errout:
1405 kfree(fnew); 1416 kfree(fnew);
1406errout_tb: 1417errout_tb:
1407 kfree(tb); 1418 kfree(tb);
1419errout_mask_alloc:
1420 kfree(mask);
1408 return err; 1421 return err;
1409} 1422}
1410 1423