nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * src/nl-qdisc-dump.c Dump qdisc attributes |
||
3 | * |
||
4 | * This library is free software; you can redistribute it and/or |
||
5 | * modify it under the terms of the GNU Lesser General Public |
||
6 | * License as published by the Free Software Foundation version 2.1 |
||
7 | * of the License. |
||
8 | * |
||
9 | * Copyright (c) 2003-2006 Thomas Graf <tgraf@suug.ch> |
||
10 | */ |
||
11 | |||
12 | #include "utils.h" |
||
13 | #include <netlink/route/sch/fifo.h> |
||
14 | #include <netlink/route/sch/prio.h> |
||
15 | |||
16 | static void print_usage(void) |
||
17 | { |
||
18 | printf( |
||
19 | "Usage: nl-qdisc-add <ifindex> <handle> <parent> <kind>\n"); |
||
20 | exit(1); |
||
21 | } |
||
22 | |||
23 | static int parse_blackhole_opts(struct rtnl_qdisc *qdisc, char *argv[], |
||
24 | int argc) |
||
25 | { |
||
26 | return 0; |
||
27 | } |
||
28 | |||
29 | static int parse_pfifo_opts(struct rtnl_qdisc *qdisc, char *argv[], int argc) |
||
30 | { |
||
31 | int err, limit; |
||
32 | |||
33 | if (argc > 0) { |
||
34 | if (argc != 2 || strcasecmp(argv[0], "limit")) { |
||
35 | fprintf(stderr, "Usage: ... pfifo limit <limit>\n"); |
||
36 | return -1; |
||
37 | } |
||
38 | |||
39 | limit = strtoul(argv[1], NULL, 0); |
||
40 | err = rtnl_qdisc_fifo_set_limit(qdisc, limit); |
||
41 | if (err < 0) { |
||
42 | fprintf(stderr, "%s\n", nl_geterror()); |
||
43 | return -1; |
||
44 | } |
||
45 | } |
||
46 | |||
47 | return 0; |
||
48 | } |
||
49 | |||
50 | static int parse_bfifo_opts(struct rtnl_qdisc *qdisc, char *argv[], int argc) |
||
51 | { |
||
52 | int err, limit; |
||
53 | |||
54 | if (argc > 0) { |
||
55 | if (argc != 2 || strcasecmp(argv[0], "limit")) { |
||
56 | fprintf(stderr, "Usage: ... bfifo limit <limit>\n"); |
||
57 | return -1; |
||
58 | } |
||
59 | |||
60 | limit = nl_size2int(argv[1]); |
||
61 | if (limit < 0) { |
||
62 | fprintf(stderr, "Invalid value for limit.\n"); |
||
63 | return -1; |
||
64 | } |
||
65 | |||
66 | err = rtnl_qdisc_fifo_set_limit(qdisc, limit); |
||
67 | if (err < 0) { |
||
68 | fprintf(stderr, "%s\n", nl_geterror()); |
||
69 | return -1; |
||
70 | } |
||
71 | } |
||
72 | |||
73 | return 0; |
||
74 | } |
||
75 | |||
76 | static int parse_prio_opts(struct rtnl_qdisc *qdisc, char *argv[], int argc) |
||
77 | { |
||
78 | int i, err, bands; |
||
79 | uint8_t map[] = QDISC_PRIO_DEFAULT_PRIOMAP; |
||
80 | |||
81 | if (argc > 0) { |
||
82 | if (argc < 2 || strcasecmp(argv[0], "bands")) |
||
83 | goto usage; |
||
84 | |||
85 | bands = strtoul(argv[1], NULL, 0); |
||
86 | err = rtnl_qdisc_prio_set_bands(qdisc, bands); |
||
87 | if (err < 0) { |
||
88 | fprintf(stderr, "%s\n", nl_geterror()); |
||
89 | return -1; |
||
90 | } |
||
91 | } |
||
92 | |||
93 | if (argc > 2) { |
||
94 | if (argc < 5 || strcasecmp(argv[2], "map")) |
||
95 | goto usage; |
||
96 | |||
97 | for (i = 3; i < (argc & ~1U); i += 2) { |
||
98 | int prio, band; |
||
99 | |||
100 | prio = rtnl_str2prio(argv[i]); |
||
101 | if (prio < 0 || prio > sizeof(map)/sizeof(map[0])) { |
||
102 | fprintf(stderr, "Invalid priority \"%s\"\n", |
||
103 | argv[i]); |
||
104 | return -1; |
||
105 | } |
||
106 | |||
107 | band = strtoul(argv[i+1], NULL, 0); |
||
108 | |||
109 | map[prio] = band; |
||
110 | } |
||
111 | } |
||
112 | |||
113 | err = rtnl_qdisc_prio_set_priomap(qdisc, map, sizeof(map)); |
||
114 | if (err < 0) { |
||
115 | fprintf(stderr, "%s\n", nl_geterror()); |
||
116 | return -1; |
||
117 | } |
||
118 | |||
119 | return 0; |
||
120 | usage: |
||
121 | fprintf(stderr, "Usage: ... prio bands <nbands> map MAP\n" |
||
122 | "MAP := <prio> <band>\n"); |
||
123 | return -1; |
||
124 | } |
||
125 | |||
126 | int main(int argc, char *argv[]) |
||
127 | { |
||
128 | struct nl_sock *nlh; |
||
129 | struct rtnl_qdisc *qdisc; |
||
130 | uint32_t handle, parent; |
||
131 | int err = 1; |
||
132 | |||
133 | if (nltool_init(argc, argv) < 0) |
||
134 | return -1; |
||
135 | |||
136 | if (argc < 5 || !strcmp(argv[1], "-h")) |
||
137 | print_usage(); |
||
138 | |||
139 | nlh = nltool_alloc_handle(); |
||
140 | if (!nlh) |
||
141 | goto errout; |
||
142 | |||
143 | qdisc = rtnl_qdisc_alloc(); |
||
144 | if (!qdisc) |
||
145 | goto errout_free_handle; |
||
146 | |||
147 | rtnl_qdisc_set_ifindex(qdisc, strtoul(argv[1], NULL, 0)); |
||
148 | |||
149 | if (rtnl_tc_str2handle(argv[2], &handle) < 0) { |
||
150 | fprintf(stderr, "%s\n", nl_geterror()); |
||
151 | goto errout_free_qdisc; |
||
152 | } |
||
153 | |||
154 | if (rtnl_tc_str2handle(argv[3], &parent) < 0) { |
||
155 | fprintf(stderr, "%s\n", nl_geterror()); |
||
156 | goto errout_free_qdisc; |
||
157 | } |
||
158 | |||
159 | rtnl_qdisc_set_handle(qdisc, handle); |
||
160 | rtnl_qdisc_set_parent(qdisc, parent); |
||
161 | rtnl_qdisc_set_kind(qdisc, argv[4]); |
||
162 | |||
163 | if (!strcasecmp(argv[4], "blackhole")) |
||
164 | err = parse_blackhole_opts(qdisc, &argv[5], argc-5); |
||
165 | else if (!strcasecmp(argv[4], "pfifo")) |
||
166 | err = parse_pfifo_opts(qdisc, &argv[5], argc-5); |
||
167 | else if (!strcasecmp(argv[4], "bfifo")) |
||
168 | err = parse_bfifo_opts(qdisc, &argv[5], argc-5); |
||
169 | else if (!strcasecmp(argv[4], "prio")) |
||
170 | err = parse_prio_opts(qdisc, &argv[5], argc-5); |
||
171 | else { |
||
172 | fprintf(stderr, "Unknown qdisc \"%s\"\n", argv[4]); |
||
173 | goto errout_free_qdisc; |
||
174 | } |
||
175 | |||
176 | if (err < 0) |
||
177 | goto errout_free_qdisc; |
||
178 | |||
179 | if (nltool_connect(nlh, NETLINK_ROUTE) < 0) |
||
180 | goto errout_free_qdisc; |
||
181 | |||
182 | if (rtnl_qdisc_add(nlh, qdisc, NLM_F_REPLACE) < 0) { |
||
183 | fprintf(stderr, "Unable to add Qdisc: %s\n", nl_geterror()); |
||
184 | goto errout_close; |
||
185 | } |
||
186 | |||
187 | err = 0; |
||
188 | errout_close: |
||
189 | nl_close(nlh); |
||
190 | errout_free_qdisc: |
||
191 | rtnl_qdisc_put(qdisc); |
||
192 | errout_free_handle: |
||
193 | nl_handle_destroy(nlh); |
||
194 | errout: |
||
195 | return err; |
||
196 | } |