nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* |
2 | * src/lib/route.c CLI Route Helpers |
||
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) 2008-2009 Thomas Graf <tgraf@suug.ch> |
||
10 | */ |
||
11 | |||
12 | /** |
||
13 | * @ingroup cli |
||
14 | * @defgroup cli_route Routing |
||
15 | * |
||
16 | * @{ |
||
17 | */ |
||
18 | |||
19 | #include <netlink/cli/utils.h> |
||
20 | #include <netlink/cli/route.h> |
||
21 | |||
22 | struct rtnl_route *nl_cli_route_alloc(void) |
||
23 | { |
||
24 | struct rtnl_route *route; |
||
25 | |||
26 | route = rtnl_route_alloc(); |
||
27 | if (!route) |
||
28 | nl_cli_fatal(ENOMEM, "Unable to allocate route object"); |
||
29 | |||
30 | return route; |
||
31 | } |
||
32 | |||
33 | struct nl_cache *nl_cli_route_alloc_cache(struct nl_sock *sk, int flags) |
||
34 | { |
||
35 | struct nl_cache *cache; |
||
36 | int err; |
||
37 | |||
38 | if ((err = rtnl_route_alloc_cache(sk, AF_UNSPEC, flags, &cache)) < 0) |
||
39 | nl_cli_fatal(err, "Unable to allocate route cache: %s\n", |
||
40 | nl_geterror(err)); |
||
41 | |||
42 | nl_cache_mngt_provide(cache); |
||
43 | |||
44 | return cache; |
||
45 | } |
||
46 | |||
47 | void nl_cli_route_parse_family(struct rtnl_route *route, char *arg) |
||
48 | { |
||
49 | int family; |
||
50 | |||
51 | if ((family = nl_str2af(arg)) != AF_UNSPEC) |
||
52 | rtnl_route_set_family(route, family); |
||
53 | } |
||
54 | |||
55 | void nl_cli_route_parse_dst(struct rtnl_route *route, char *arg) |
||
56 | { |
||
57 | struct nl_addr *addr; |
||
58 | int err; |
||
59 | |||
60 | addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route)); |
||
61 | if ((err = rtnl_route_set_dst(route, addr)) < 0) |
||
62 | nl_cli_fatal(err, "Unable to set destination address: %s", |
||
63 | nl_geterror(err)); |
||
64 | |||
65 | nl_addr_put(addr); |
||
66 | } |
||
67 | |||
68 | void nl_cli_route_parse_src(struct rtnl_route *route, char *arg) |
||
69 | { |
||
70 | struct nl_addr *addr; |
||
71 | int err; |
||
72 | |||
73 | addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route)); |
||
74 | if ((err = rtnl_route_set_src(route, addr)) < 0) |
||
75 | nl_cli_fatal(err, "Unable to set source address: %s", |
||
76 | nl_geterror(err)); |
||
77 | |||
78 | nl_addr_put(addr); |
||
79 | } |
||
80 | |||
81 | void nl_cli_route_parse_pref_src(struct rtnl_route *route, char *arg) |
||
82 | { |
||
83 | struct nl_addr *addr; |
||
84 | int err; |
||
85 | |||
86 | addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route)); |
||
87 | if ((err = rtnl_route_set_pref_src(route, addr)) < 0) |
||
88 | nl_cli_fatal(err, "Unable to set preferred source address: %s", |
||
89 | nl_geterror(err)); |
||
90 | |||
91 | nl_addr_put(addr); |
||
92 | } |
||
93 | |||
94 | void nl_cli_route_parse_metric(struct rtnl_route *route, char *subopts) |
||
95 | { |
||
96 | /* strict equal order to RTAX_* */ |
||
97 | static char *const tokens[] = { |
||
98 | "unspec", |
||
99 | "lock", |
||
100 | "mtu", |
||
101 | "window", |
||
102 | "rtt", |
||
103 | "rttvar", |
||
104 | "sstresh", |
||
105 | "cwnd", |
||
106 | "advmss", |
||
107 | "reordering", |
||
108 | "hoplimit", |
||
109 | "initcwnd", |
||
110 | "features", |
||
111 | NULL, |
||
112 | }; |
||
113 | unsigned long lval; |
||
114 | char *arg, *endptr; |
||
115 | |||
116 | while (*subopts != '\0') { |
||
117 | int ret = getsubopt(&subopts, tokens, &arg); |
||
118 | if (ret == -1) |
||
119 | nl_cli_fatal(EINVAL, "Unknown metric token \"%s\"", arg); |
||
120 | |||
121 | if (ret == 0) |
||
122 | nl_cli_fatal(EINVAL, "Invalid metric \"%s\"", tokens[ret]); |
||
123 | |||
124 | if (arg == NULL) |
||
125 | nl_cli_fatal(EINVAL, "Metric \"%s\", no value given", tokens[ret]); |
||
126 | |||
127 | lval = strtoul(arg, &endptr, 0); |
||
128 | if (endptr == arg) |
||
129 | nl_cli_fatal(EINVAL, "Metric \"%s\", value not numeric", tokens[ret]); |
||
130 | |||
131 | if ((ret = rtnl_route_set_metric(route, ret, lval)) < 0) |
||
132 | nl_cli_fatal(ret, "Unable to set metric: %s", |
||
133 | nl_geterror(ret)); |
||
134 | } |
||
135 | } |
||
136 | |||
137 | void nl_cli_route_parse_nexthop(struct rtnl_route *route, char *subopts, |
||
138 | struct nl_cache *link_cache) |
||
139 | { |
||
140 | enum { |
||
141 | NH_DEV, |
||
142 | NH_VIA, |
||
143 | NH_WEIGHT, |
||
144 | }; |
||
145 | static char *const tokens[] = { |
||
146 | "dev", |
||
147 | "via", |
||
148 | "weight", |
||
149 | NULL, |
||
150 | }; |
||
151 | struct rtnl_nexthop *nh; |
||
152 | unsigned long lval; |
||
153 | struct nl_addr *addr; |
||
154 | int ival; |
||
155 | char *arg, *endptr; |
||
156 | |||
157 | if (!(nh = rtnl_route_nh_alloc())) |
||
158 | nl_cli_fatal(ENOMEM, "Out of memory"); |
||
159 | |||
160 | while (*subopts != '\0') { |
||
161 | int ret = getsubopt(&subopts, tokens, &arg); |
||
162 | if (ret == -1) |
||
163 | nl_cli_fatal(EINVAL, "Unknown nexthop token \"%s\"", arg); |
||
164 | |||
165 | if (arg == NULL) |
||
166 | nl_cli_fatal(EINVAL, "Missing argument to option \"%s\"\n", |
||
167 | tokens[ret]); |
||
168 | |||
169 | switch (ret) { |
||
170 | case NH_DEV: |
||
171 | if (!(ival = rtnl_link_name2i(link_cache, arg))) |
||
172 | nl_cli_fatal(ENOENT,"Link \"%s\" does not exist", arg); |
||
173 | |||
174 | rtnl_route_nh_set_ifindex(nh, ival); |
||
175 | break; |
||
176 | |||
177 | case NH_VIA: |
||
178 | addr = nl_cli_addr_parse(arg,rtnl_route_get_family(route)); |
||
179 | rtnl_route_nh_set_gateway(nh, addr); |
||
180 | nl_addr_put(addr); |
||
181 | break; |
||
182 | |||
183 | case NH_WEIGHT: |
||
184 | lval = strtoul(arg, &endptr, 0); |
||
185 | if (endptr == arg) |
||
186 | nl_cli_fatal(EINVAL, |
||
187 | "Invalid weight \"%s\", not numeric", |
||
188 | arg); |
||
189 | rtnl_route_nh_set_weight(nh, lval); |
||
190 | break; |
||
191 | } |
||
192 | } |
||
193 | |||
194 | rtnl_route_add_nexthop(route, nh); |
||
195 | } |
||
196 | |||
197 | void nl_cli_route_parse_table(struct rtnl_route *route, char *arg) |
||
198 | { |
||
199 | unsigned long lval; |
||
200 | char *endptr; |
||
201 | |||
202 | lval = strtoul(arg, &endptr, 0); |
||
203 | if (endptr == arg) { |
||
204 | if ((lval = rtnl_route_str2table(arg)) < 0) |
||
205 | nl_cli_fatal(EINVAL, "Unknown table name \"%s\"", arg); |
||
206 | } |
||
207 | |||
208 | rtnl_route_set_table(route, lval); |
||
209 | } |
||
210 | |||
211 | void nl_cli_route_parse_prio(struct rtnl_route *route, char *arg) |
||
212 | { |
||
213 | unsigned long lval; |
||
214 | char *endptr; |
||
215 | |||
216 | lval = strtoul(arg, &endptr, 0); |
||
217 | if (endptr == arg) |
||
218 | nl_cli_fatal(EINVAL, "Invalid priority value, not numeric"); |
||
219 | rtnl_route_set_priority(route, lval); |
||
220 | } |
||
221 | |||
222 | void nl_cli_route_parse_scope(struct rtnl_route *route, char *arg) |
||
223 | { |
||
224 | int ival; |
||
225 | |||
226 | if ((ival = rtnl_str2scope(arg)) < 0) |
||
227 | nl_cli_fatal(EINVAL, "Unknown routing scope \"%s\"", arg); |
||
228 | |||
229 | rtnl_route_set_scope(route, ival); |
||
230 | } |
||
231 | |||
232 | void nl_cli_route_parse_protocol(struct rtnl_route *route, char *arg) |
||
233 | { |
||
234 | unsigned long lval; |
||
235 | char *endptr; |
||
236 | |||
237 | lval = strtoul(arg, &endptr, 0); |
||
238 | if (endptr == arg) { |
||
239 | if ((lval = rtnl_route_str2proto(arg)) < 0) |
||
240 | nl_cli_fatal(EINVAL, |
||
241 | "Unknown routing protocol name \"%s\"", |
||
242 | arg); |
||
243 | } |
||
244 | |||
245 | rtnl_route_set_protocol(route, lval); |
||
246 | } |
||
247 | |||
248 | void nl_cli_route_parse_type(struct rtnl_route *route, char *arg) |
||
249 | { |
||
250 | int ival; |
||
251 | |||
252 | if ((ival = nl_str2rtntype(arg)) < 0) |
||
253 | nl_cli_fatal(EINVAL, "Unknown routing type \"%s\"", arg); |
||
254 | |||
255 | if ((ival = rtnl_route_set_type(route, ival)) < 0) |
||
256 | nl_cli_fatal(ival, "Unable to set routing type: %s", |
||
257 | nl_geterror(ival)); |
||
258 | } |
||
259 | |||
260 | void nl_cli_route_parse_iif(struct rtnl_route *route, char *arg, struct nl_cache *link_cache) |
||
261 | { |
||
262 | int ival; |
||
263 | |||
264 | if (!(ival = rtnl_link_name2i(link_cache, arg))) |
||
265 | nl_cli_fatal(ENOENT, "Link \"%s\" does not exist", arg); |
||
266 | |||
267 | rtnl_route_set_iif(route, ival); |
||
268 | } |
||
269 | |||
270 | /** @} */ |