libnl
3.2.3
|
00001 /* 00002 * src/lib/route.c CLI Route Helpers 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation version 2.1 00007 * of the License. 00008 * 00009 * Copyright (c) 2008-2009 Thomas Graf <tgraf@suug.ch> 00010 */ 00011 00012 /** 00013 * @ingroup cli 00014 * @defgroup cli_route Routing 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 /* strict equal order to RTAX_* */ 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 /** @} */