00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include <netlink/cli/utils.h>
00020 #include <netlink/cli/route.h>
00021
00022 struct rtnl_route *nl_cli_route_alloc(void)
00023 {
00024 struct rtnl_route *route;
00025
00026 route = rtnl_route_alloc();
00027 if (!route)
00028 nl_cli_fatal(ENOMEM, "Unable to allocate route object");
00029
00030 return route;
00031 }
00032
00033 struct nl_cache *nl_cli_route_alloc_cache(struct nl_sock *sk, int flags)
00034 {
00035 struct nl_cache *cache;
00036 int err;
00037
00038 if ((err = rtnl_route_alloc_cache(sk, AF_UNSPEC, flags, &cache)) < 0)
00039 nl_cli_fatal(err, "Unable to allocate route cache: %s\n",
00040 nl_geterror(err));
00041
00042 nl_cache_mngt_provide(cache);
00043
00044 return cache;
00045 }
00046
00047 void nl_cli_route_parse_family(struct rtnl_route *route, char *arg)
00048 {
00049 int family;
00050
00051 if ((family = nl_str2af(arg)) != AF_UNSPEC)
00052 rtnl_route_set_family(route, family);
00053 }
00054
00055 void nl_cli_route_parse_dst(struct rtnl_route *route, char *arg)
00056 {
00057 struct nl_addr *addr;
00058 int err;
00059
00060 addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route));
00061 if ((err = rtnl_route_set_dst(route, addr)) < 0)
00062 nl_cli_fatal(err, "Unable to set destination address: %s",
00063 nl_geterror(err));
00064
00065 nl_addr_put(addr);
00066 }
00067
00068 void nl_cli_route_parse_src(struct rtnl_route *route, char *arg)
00069 {
00070 struct nl_addr *addr;
00071 int err;
00072
00073 addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route));
00074 if ((err = rtnl_route_set_src(route, addr)) < 0)
00075 nl_cli_fatal(err, "Unable to set source address: %s",
00076 nl_geterror(err));
00077
00078 nl_addr_put(addr);
00079 }
00080
00081 void nl_cli_route_parse_pref_src(struct rtnl_route *route, char *arg)
00082 {
00083 struct nl_addr *addr;
00084 int err;
00085
00086 addr = nl_cli_addr_parse(arg, rtnl_route_get_family(route));
00087 if ((err = rtnl_route_set_pref_src(route, addr)) < 0)
00088 nl_cli_fatal(err, "Unable to set preferred source address: %s",
00089 nl_geterror(err));
00090
00091 nl_addr_put(addr);
00092 }
00093
00094 void nl_cli_route_parse_metric(struct rtnl_route *route, char *subopts)
00095 {
00096
00097 static char *const tokens[] = {
00098 "unspec",
00099 "lock",
00100 "mtu",
00101 "window",
00102 "rtt",
00103 "rttvar",
00104 "sstresh",
00105 "cwnd",
00106 "advmss",
00107 "reordering",
00108 "hoplimit",
00109 "initcwnd",
00110 "features",
00111 NULL,
00112 };
00113 unsigned long lval;
00114 char *arg, *endptr;
00115
00116 while (*subopts != '\0') {
00117 int ret = getsubopt(&subopts, tokens, &arg);
00118 if (ret == -1)
00119 nl_cli_fatal(EINVAL, "Unknown metric token \"%s\"", arg);
00120
00121 if (ret == 0)
00122 nl_cli_fatal(EINVAL, "Invalid metric \"%s\"", tokens[ret]);
00123
00124 if (arg == NULL)
00125 nl_cli_fatal(EINVAL, "Metric \"%s\", no value given", tokens[ret]);
00126
00127 lval = strtoul(arg, &endptr, 0);
00128 if (endptr == arg)
00129 nl_cli_fatal(EINVAL, "Metric \"%s\", value not numeric", tokens[ret]);
00130
00131 if ((ret = rtnl_route_set_metric(route, ret, lval)) < 0)
00132 nl_cli_fatal(ret, "Unable to set metric: %s",
00133 nl_geterror(ret));
00134 }
00135 }
00136
00137 void nl_cli_route_parse_nexthop(struct rtnl_route *route, char *subopts,
00138 struct nl_cache *link_cache)
00139 {
00140 enum {
00141 NH_DEV,
00142 NH_VIA,
00143 NH_WEIGHT,
00144 };
00145 static char *const tokens[] = {
00146 "dev",
00147 "via",
00148 "weight",
00149 NULL,
00150 };
00151 struct rtnl_nexthop *nh;
00152 unsigned long lval;
00153 struct nl_addr *addr;
00154 int ival;
00155 char *arg, *endptr;
00156
00157 if (!(nh = rtnl_route_nh_alloc()))
00158 nl_cli_fatal(ENOMEM, "Out of memory");
00159
00160 while (*subopts != '\0') {
00161 int ret = getsubopt(&subopts, tokens, &arg);
00162 if (ret == -1)
00163 nl_cli_fatal(EINVAL, "Unknown nexthop token \"%s\"", arg);
00164
00165 if (arg == NULL)
00166 nl_cli_fatal(EINVAL, "Missing argument to option \"%s\"\n",
00167 tokens[ret]);
00168
00169 switch (ret) {
00170 case NH_DEV:
00171 if (!(ival = rtnl_link_name2i(link_cache, arg)))
00172 nl_cli_fatal(ENOENT,"Link \"%s\" does not exist", arg);
00173
00174 rtnl_route_nh_set_ifindex(nh, ival);
00175 break;
00176
00177 case NH_VIA:
00178 addr = nl_cli_addr_parse(arg,rtnl_route_get_family(route));
00179 rtnl_route_nh_set_gateway(nh, addr);
00180 nl_addr_put(addr);
00181 break;
00182
00183 case NH_WEIGHT:
00184 lval = strtoul(arg, &endptr, 0);
00185 if (endptr == arg)
00186 nl_cli_fatal(EINVAL,
00187 "Invalid weight \"%s\", not numeric",
00188 arg);
00189 rtnl_route_nh_set_weight(nh, lval);
00190 break;
00191 }
00192 }
00193
00194 rtnl_route_add_nexthop(route, nh);
00195 }
00196
00197 void nl_cli_route_parse_table(struct rtnl_route *route, char *arg)
00198 {
00199 unsigned long lval;
00200 char *endptr;
00201
00202 lval = strtoul(arg, &endptr, 0);
00203 if (endptr == arg) {
00204 if ((lval = rtnl_route_str2table(arg)) < 0)
00205 nl_cli_fatal(EINVAL, "Unknown table name \"%s\"", arg);
00206 }
00207
00208 rtnl_route_set_table(route, lval);
00209 }
00210
00211 void nl_cli_route_parse_prio(struct rtnl_route *route, char *arg)
00212 {
00213 unsigned long lval;
00214 char *endptr;
00215
00216 lval = strtoul(arg, &endptr, 0);
00217 if (endptr == arg)
00218 nl_cli_fatal(EINVAL, "Invalid priority value, not numeric");
00219 rtnl_route_set_priority(route, lval);
00220 }
00221
00222 void nl_cli_route_parse_scope(struct rtnl_route *route, char *arg)
00223 {
00224 int ival;
00225
00226 if ((ival = rtnl_str2scope(arg)) < 0)
00227 nl_cli_fatal(EINVAL, "Unknown routing scope \"%s\"", arg);
00228
00229 rtnl_route_set_scope(route, ival);
00230 }
00231
00232 void nl_cli_route_parse_protocol(struct rtnl_route *route, char *arg)
00233 {
00234 unsigned long lval;
00235 char *endptr;
00236
00237 lval = strtoul(arg, &endptr, 0);
00238 if (endptr == arg) {
00239 if ((lval = rtnl_route_str2proto(arg)) < 0)
00240 nl_cli_fatal(EINVAL,
00241 "Unknown routing protocol name \"%s\"",
00242 arg);
00243 }
00244
00245 rtnl_route_set_protocol(route, lval);
00246 }
00247
00248 void nl_cli_route_parse_type(struct rtnl_route *route, char *arg)
00249 {
00250 int ival;
00251
00252 if ((ival = nl_str2rtntype(arg)) < 0)
00253 nl_cli_fatal(EINVAL, "Unknown routing type \"%s\"", arg);
00254
00255 if ((ival = rtnl_route_set_type(route, ival)) < 0)
00256 nl_cli_fatal(ival, "Unable to set routing type: %s",
00257 nl_geterror(ival));
00258 }
00259
00260 void nl_cli_route_parse_iif(struct rtnl_route *route, char *arg, struct nl_cache *link_cache)
00261 {
00262 int ival;
00263
00264 if (!(ival = rtnl_link_name2i(link_cache, arg)))
00265 nl_cli_fatal(ENOENT, "Link \"%s\" does not exist", arg);
00266
00267 rtnl_route_set_iif(route, ival);
00268 }
00269
00270