1 /* SPDX-License-Identifier: LGPL-2.1-or-later
2  * Copyright © 2020 VMware, Inc. */
3 
4 #include <linux/pkt_sched.h>
5 
6 #include "alloc-util.h"
7 #include "conf-parser.h"
8 #include "hhf.h"
9 #include "netlink-util.h"
10 #include "parse-util.h"
11 #include "string-util.h"
12 #include "util.h"
13 
heavy_hitter_filter_fill_message(Link * link,QDisc * qdisc,sd_netlink_message * req)14 static int heavy_hitter_filter_fill_message(Link *link, QDisc *qdisc, sd_netlink_message *req) {
15         HeavyHitterFilter *hhf;
16         int r;
17 
18         assert(link);
19         assert(qdisc);
20         assert(req);
21 
22         assert_se(hhf = HHF(qdisc));
23 
24         r = sd_netlink_message_open_container_union(req, TCA_OPTIONS, "hhf");
25         if (r < 0)
26                 return r;
27 
28         if (hhf->packet_limit > 0) {
29                 r = sd_netlink_message_append_u32(req, TCA_HHF_BACKLOG_LIMIT, hhf->packet_limit);
30                 if (r < 0)
31                         return r;
32         }
33 
34        r = sd_netlink_message_close_container(req);
35         if (r < 0)
36                 return r;
37 
38         return 0;
39 }
40 
config_parse_heavy_hitter_filter_packet_limit(const char * unit,const char * filename,unsigned line,const char * section,unsigned section_line,const char * lvalue,int ltype,const char * rvalue,void * data,void * userdata)41 int config_parse_heavy_hitter_filter_packet_limit(
42                 const char *unit,
43                 const char *filename,
44                 unsigned line,
45                 const char *section,
46                 unsigned section_line,
47                 const char *lvalue,
48                 int ltype,
49                 const char *rvalue,
50                 void *data,
51                 void *userdata) {
52 
53         _cleanup_(qdisc_free_or_set_invalidp) QDisc *qdisc = NULL;
54         HeavyHitterFilter *hhf;
55         Network *network = data;
56         int r;
57 
58         assert(filename);
59         assert(lvalue);
60         assert(rvalue);
61         assert(data);
62 
63         r = qdisc_new_static(QDISC_KIND_HHF, network, filename, section_line, &qdisc);
64         if (r == -ENOMEM)
65                 return log_oom();
66         if (r < 0) {
67                 log_syntax(unit, LOG_WARNING, filename, line, r,
68                            "More than one kind of queueing discipline, ignoring assignment: %m");
69                 return 0;
70         }
71 
72         hhf = HHF(qdisc);
73 
74         if (isempty(rvalue)) {
75                 hhf->packet_limit = 0;
76 
77                 TAKE_PTR(qdisc);
78                 return 0;
79         }
80 
81         r = safe_atou32(rvalue, &hhf->packet_limit);
82         if (r < 0) {
83                 log_syntax(unit, LOG_WARNING, filename, line, r,
84                            "Failed to parse '%s=', ignoring assignment: %s",
85                            lvalue, rvalue);
86                 return 0;
87         }
88 
89         TAKE_PTR(qdisc);
90 
91         return 0;
92 }
93 
94 const QDiscVTable hhf_vtable = {
95         .object_size = sizeof(HeavyHitterFilter),
96         .tca_kind = "hhf",
97         .fill_message = heavy_hitter_filter_fill_message,
98 };
99