libnl  3.2.3
/build/buildd/libnl3-3.2.3/src/lib/route.c
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 /** @} */