summaryrefslogtreecommitdiff
path: root/lib/zclient.c
diff options
context:
space:
mode:
authorSiger Yang <siger.yang@outlook.com>2022-09-06 15:13:23 +0800
committerSiger Yang <siger.yang@outlook.com>2022-11-22 22:35:35 +0800
commitdfacea4ae7001346ea5e21fce485db5255e809f6 (patch)
tree161f876506910bd56ea76be2e843f6766d97a31b /lib/zclient.c
parentc317d3f246769e8261df0f9d1eb787bea7b5da06 (diff)
zebra: traffic control ZAPI
This commit adds ZAPI encoders & decoders for traffic control operations, which include tc_qdisc, tc_class and tc_filter. Signed-off-by: Siger Yang <siger.yang@outlook.com>
Diffstat (limited to 'lib/zclient.c')
-rw-r--r--lib/zclient.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/lib/zclient.c b/lib/zclient.c
index fd6eb7db0d..07c7e5aea8 100644
--- a/lib/zclient.c
+++ b/lib/zclient.c
@@ -37,6 +37,7 @@
#include "mpls.h"
#include "sockopt.h"
#include "pbr.h"
+#include "tc.h"
#include "nexthop_group.h"
#include "lib_errors.h"
#include "srte.h"
@@ -1649,6 +1650,96 @@ int zapi_pbr_rule_encode(uint8_t cmd, struct stream *s, struct pbr_rule *zrule)
return 0;
}
+int zapi_tc_qdisc_encode(uint8_t cmd, struct stream *s, struct tc_qdisc *qdisc)
+{
+ stream_reset(s);
+ zclient_create_header(s, cmd, VRF_DEFAULT);
+
+
+ stream_putl(s, 1);
+
+ stream_putl(s, qdisc->ifindex);
+ stream_putl(s, qdisc->kind);
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return 0;
+}
+
+int zapi_tc_class_encode(uint8_t cmd, struct stream *s, struct tc_class *class)
+{
+ stream_reset(s);
+ zclient_create_header(s, cmd, VRF_DEFAULT);
+
+ stream_putl(s, 1);
+
+ stream_putl(s, class->ifindex);
+ stream_putl(s, class->handle);
+ stream_putl(s, class->kind);
+
+ switch (class->kind) {
+ case TC_QDISC_HTB:
+ stream_putq(s, class->u.htb.rate);
+ stream_putq(s, class->u.htb.ceil);
+ break;
+ default:
+ /* not implemented */
+ break;
+ }
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return 0;
+}
+
+int zapi_tc_filter_encode(uint8_t cmd, struct stream *s,
+ struct tc_filter *filter)
+{
+ stream_reset(s);
+ zclient_create_header(s, cmd, VRF_DEFAULT);
+
+ stream_putl(s, 1);
+
+ stream_putl(s, filter->ifindex);
+ stream_putl(s, filter->handle);
+ stream_putl(s, filter->priority);
+ stream_putl(s, filter->protocol);
+ stream_putl(s, filter->kind);
+
+ switch (filter->kind) {
+ case TC_FILTER_FLOWER:
+ stream_putl(s, filter->u.flower.filter_bm);
+ if (filter->u.flower.filter_bm & TC_FLOWER_IP_PROTOCOL)
+ stream_putc(s, filter->u.flower.ip_proto);
+ if (filter->u.flower.filter_bm & TC_FLOWER_SRC_IP)
+ zapi_encode_prefix(s, &filter->u.flower.src_ip,
+ filter->u.flower.src_ip.family);
+ if (filter->u.flower.filter_bm & TC_FLOWER_SRC_PORT) {
+ stream_putw(s, filter->u.flower.src_port_min);
+ stream_putw(s, filter->u.flower.src_port_max);
+ }
+ if (filter->u.flower.filter_bm & TC_FLOWER_DST_IP)
+ zapi_encode_prefix(s, &filter->u.flower.dst_ip,
+ filter->u.flower.dst_ip.family);
+ if (filter->u.flower.filter_bm & TC_FLOWER_DST_PORT) {
+ stream_putw(s, filter->u.flower.dst_port_min);
+ stream_putw(s, filter->u.flower.dst_port_max);
+ }
+ if (filter->u.flower.filter_bm & TC_FLOWER_DSFIELD) {
+ stream_putc(s, filter->u.flower.dsfield);
+ stream_putc(s, filter->u.flower.dsfield_mask);
+ }
+ stream_putl(s, filter->u.flower.classid);
+ break;
+ default:
+ /* not implemented */
+ break;
+ }
+
+ stream_putw_at(s, 0, stream_get_endp(s));
+
+ return 0;
+}
+
bool zapi_nhg_notify_decode(struct stream *s, uint32_t *id,
enum zapi_nhg_notify_owner *note)
{