xref: /aosp_15_r20/external/libnl/src/lib/tc.c (revision 4dc78e53d49367fa8e61b07018507c90983a077d)
1 /* SPDX-License-Identifier: LGPL-2.1-only */
2 /*
3  * Copyright (c) 2010 Thomas Graf <[email protected]>
4  */
5 
6 #include "nl-default.h"
7 
8 #include <netlink/cli/utils.h>
9 #include <netlink/cli/tc.h>
10 
11 #include "nl-priv-dynamic-route/nl-priv-dynamic-route.h"
12 
13 /**
14  * @ingroup cli
15  * @defgroup cli_tc Traffic Control
16  * @{
17  */
nl_cli_tc_parse_dev(struct rtnl_tc * tc,struct nl_cache * link_cache,char * name)18 void nl_cli_tc_parse_dev(struct rtnl_tc *tc, struct nl_cache *link_cache, char *name)
19 {
20 	struct rtnl_link *link;
21 
22 	link = rtnl_link_get_by_name(link_cache, name);
23 	if (!link)
24 		nl_cli_fatal(ENOENT, "Link \"%s\" does not exist.", name);
25 
26 	rtnl_tc_set_link(tc, link);
27 	rtnl_link_put(link);
28 }
29 
nl_cli_tc_parse_parent(struct rtnl_tc * tc,char * arg)30 void nl_cli_tc_parse_parent(struct rtnl_tc *tc, char *arg)
31 {
32 	uint32_t parent;
33 	int err;
34 
35 	if ((err = rtnl_tc_str2handle(arg, &parent)) < 0)
36 		nl_cli_fatal(err, "Unable to parse handle \"%s\": %s",
37 		      arg, nl_geterror(err));
38 
39 	rtnl_tc_set_parent(tc, parent);
40 }
41 
nl_cli_tc_parse_handle(struct rtnl_tc * tc,char * arg,int create)42 void nl_cli_tc_parse_handle(struct rtnl_tc *tc, char *arg, int create)
43 {
44 	uint32_t handle, parent;
45 	int err;
46 
47 	parent = rtnl_tc_get_parent(tc);
48 
49 	if ((err = rtnl_tc_str2handle(arg, &handle)) < 0) {
50 		if (err == -NLE_OBJ_NOTFOUND && create)
51 			err = rtnl_classid_generate(arg, &handle, parent);
52 
53 		if (err < 0)
54 			nl_cli_fatal(err, "Unable to parse handle \"%s\": %s",
55 				     arg, nl_geterror(err));
56 	}
57 
58 	rtnl_tc_set_handle(tc, handle);
59 }
60 
nl_cli_tc_parse_mtu(struct rtnl_tc * tc,char * arg)61 void nl_cli_tc_parse_mtu(struct rtnl_tc *tc, char *arg)
62 {
63 	rtnl_tc_set_mtu(tc, nl_cli_parse_u32(arg));
64 }
65 
nl_cli_tc_parse_mpu(struct rtnl_tc * tc,char * arg)66 void nl_cli_tc_parse_mpu(struct rtnl_tc *tc, char *arg)
67 {
68 	rtnl_tc_set_mpu(tc, nl_cli_parse_u32(arg));
69 }
70 
nl_cli_tc_parse_overhead(struct rtnl_tc * tc,char * arg)71 void nl_cli_tc_parse_overhead(struct rtnl_tc *tc, char *arg)
72 {
73 	rtnl_tc_set_overhead(tc, nl_cli_parse_u32(arg));
74 }
75 
nl_cli_tc_parse_kind(struct rtnl_tc * tc,char * arg)76 void nl_cli_tc_parse_kind(struct rtnl_tc *tc, char *arg)
77 {
78 	rtnl_tc_set_kind(tc, arg);
79 }
80 
nl_cli_tc_parse_linktype(struct rtnl_tc * tc,char * arg)81 void nl_cli_tc_parse_linktype(struct rtnl_tc *tc, char *arg)
82 {
83 	int type;
84 
85 	if ((type = nl_str2llproto(arg)) < 0)
86 		nl_cli_fatal(type, "Unable to parse linktype \"%s\": %s",
87 			arg, nl_geterror(type));
88 
89 	rtnl_tc_set_linktype(tc, type);
90 }
91 
92 static NL_LIST_HEAD(tc_modules);
93 
__nl_cli_tc_lookup(struct rtnl_tc_ops * ops)94 static struct nl_cli_tc_module *__nl_cli_tc_lookup(struct rtnl_tc_ops *ops)
95 {
96 	struct nl_cli_tc_module *tm;
97 
98 	nl_list_for_each_entry(tm, &tc_modules, tm_list)
99 		if (tm->tm_ops == ops)
100 			return tm;
101 
102 	return NULL;
103 }
104 
nl_cli_tc_lookup(struct rtnl_tc_ops * ops)105 struct nl_cli_tc_module *nl_cli_tc_lookup(struct rtnl_tc_ops *ops)
106 {
107 	struct nl_cli_tc_module *tm;
108 
109 	if ((tm = __nl_cli_tc_lookup(ops)))
110 		return tm;
111 
112 	switch (ops->to_type) {
113 	case RTNL_TC_TYPE_QDISC:
114 	case RTNL_TC_TYPE_CLASS:
115 		nl_cli_load_module("cli/qdisc", ops->to_kind);
116 		break;
117 
118 	case RTNL_TC_TYPE_CLS:
119 		nl_cli_load_module("cli/cls", ops->to_kind);
120 		break;
121 
122 	default:
123 		nl_cli_fatal(EINVAL, "BUG: unhandled TC object type %d",
124 				ops->to_type);
125 	}
126 
127 	if (!(tm = __nl_cli_tc_lookup(ops)))  {
128 		nl_cli_fatal(EINVAL, "Application bug: The shared library for "
129 			"the tc object \"%s\" was successfully loaded but it "
130 			"seems that module did not register itself",
131 			ops->to_kind);
132 	}
133 
134 	return tm;
135 }
136 
nl_cli_tc_register(struct nl_cli_tc_module * tm)137 void nl_cli_tc_register(struct nl_cli_tc_module *tm)
138 {
139 	struct rtnl_tc_ops *ops;
140 
141 	if (!(ops = rtnl_tc_lookup_ops(tm->tm_type, tm->tm_name))) {
142 		nl_cli_fatal(ENOENT, "Unable to register CLI TC module "
143 		"\"%s\": No matching libnl TC module found.", tm->tm_name);
144 	}
145 
146 	if (__nl_cli_tc_lookup(ops)) {
147 		nl_cli_fatal(EEXIST, "Unable to register CLI TC module "
148 		"\"%s\": Module already registered.", tm->tm_name);
149 	}
150 
151 	tm->tm_ops = ops;
152 
153 	nl_list_add_tail(&tm->tm_list, &tc_modules);
154 }
155 
nl_cli_tc_unregister(struct nl_cli_tc_module * tm)156 void nl_cli_tc_unregister(struct nl_cli_tc_module *tm)
157 {
158 	nl_list_del(&tm->tm_list);
159 }
160 
161 
162 /** @} */
163