00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifdef HAVE_CONFIG_H
00018 # include <dtn-config.h>
00019 #endif
00020
00021 #include <oasys/util/StringBuffer.h>
00022 #include <oasys/serialize/XMLSerialize.h>
00023
00024 #include "RouteCommand.h"
00025 #include "CompletionNotifier.h"
00026
00027 #include "contacts/Link.h"
00028 #include "contacts/ContactManager.h"
00029
00030 #include "bundling/BundleEvent.h"
00031 #include "bundling/BundleDaemon.h"
00032
00033 #include "routing/BundleRouter.h"
00034 #include "routing/RouteEntry.h"
00035 #include "routing/ExternalRouter.h"
00036 #include "routing/DTLSRConfig.h"
00037
00038 namespace dtn {
00039
00040 RouteCommand::RouteCommand()
00041 : TclCommand("route")
00042 {
00043 bind_var(new oasys::StringOpt("type", &BundleRouter::config_.type_,
00044 "type", "Which routing algorithm to use."));
00045
00046 bind_var(new oasys::BoolOpt("add_nexthop_routes",
00047 &BundleRouter::config_.add_nexthop_routes_,
00048 "Whether or not to automatically add routes "
00049 "for next hop links"));
00050
00051 bind_var(new oasys::BoolOpt("open_discovered_links",
00052 &BundleRouter::config_.open_discovered_links_,
00053 "Whether or not to automatically open "
00054 "discovered opportunistic links"));
00055
00056 bind_var(new oasys::IntOpt("default_priority",
00057 &BundleRouter::config_.default_priority_,
00058 "priority",
00059 "Default priority for new routes "
00060 "(initially zero)"));
00061
00062 bind_var(new oasys::IntOpt("max_route_to_chain",
00063 &BundleRouter::config_.max_route_to_chain_,
00064 "length",
00065 "Maximum number of route_to links to follow"));
00066
00067 bind_var(new oasys::UIntOpt("subscription_timeout",
00068 &BundleRouter::config_.subscription_timeout_,
00069 "timeout",
00070 "Default timeout for upstream subscription"));
00071
00072 bind_var(new oasys::StringOpt("dtlsr_area",
00073 &DTLSRConfig::instance()->area_,
00074 "area", "Administrative area for the local node"));
00075
00076 bind_var(new oasys::EnumOpt("dtlsr_weight_fn",
00077 DTLSRConfig::instance()->weight_opts_,
00078 (int*)&DTLSRConfig::instance()->weight_fn_,
00079 "fn", "Weight function for the graph"));
00080
00081 bind_var(new oasys::UIntOpt("dtlsr_weight_shift",
00082 &DTLSRConfig::instance()->weight_shift_,
00083 "shift", "Scale the weight on down links"));
00084
00085 bind_var(new oasys::DoubleOpt("dtlsr_uptime_factor",
00086 &DTLSRConfig::instance()->uptime_factor_,
00087 "pct", "Aging pct for cost of down links"));
00088
00089 bind_var(new oasys::BoolOpt("dtlsr_keep_down_links",
00090 &DTLSRConfig::instance()->keep_down_links_,
00091 "Whether or not to retain down links in the graph"));
00092
00093 bind_var(new oasys::UIntOpt("dtlsr_recompute_delay",
00094 &DTLSRConfig::instance()->recompute_delay_,
00095 "seconds",
00096 "Delay to compute routes after LSA arrives"));
00097
00098 bind_var(new oasys::UIntOpt("dtlsr_aging_delay",
00099 &DTLSRConfig::instance()->aging_interval_,
00100 "seconds",
00101 "Interval to locally recompute routes"));
00102
00103 bind_var(new oasys::UIntOpt("dtlsr_lsa_interval",
00104 &DTLSRConfig::instance()->lsa_interval_,
00105 "seconds",
00106 "Interval to periodically send LSAs"));
00107
00108 bind_var(new oasys::UIntOpt("dtlsr_lsa_lifetime",
00109 &DTLSRConfig::instance()->lsa_lifetime_,
00110 "seconds",
00111 "Lifetime of LSA bundles"));
00112
00113 add_to_help("add <dest> <link/endpoint> [opts]", "add a route");
00114 add_to_help("del <dest> <link/endpoint>", "delete a route");
00115 add_to_help("dump", "dump all of the static routes");
00116
00117 #if defined(XERCES_C_ENABLED) && defined(EXTERNAL_DP_ENABLED)
00118 bind_var(new oasys::UInt16Opt("server_port",
00119 &ExternalRouter::server_port,
00120 "port",
00121 "UDP port for IPC with external router(s)"));
00122
00123 bind_var(new oasys::UInt16Opt("hello_interval",
00124 &ExternalRouter::hello_interval,
00125 "interval",
00126 "seconds between hello messages"));
00127
00128 bind_var(new oasys::StringOpt("schema", &ExternalRouter::schema,
00129 "file",
00130 "The external router interface "
00131 "message schema."));
00132
00133 bind_var(new oasys::BoolOpt("xml_server_validation",
00134 &ExternalRouter::server_validation,
00135 "Perform xml validation on plug-in "
00136 "interface messages (default is true)"));
00137
00138 bind_var(new oasys::BoolOpt("xml_client_validation",
00139 &ExternalRouter::client_validation,
00140 "Include meta-info in xml messages "
00141 "so plug-in routers"
00142 "can perform validation (default is false)"));
00143 #endif
00144 }
00145
00146 int
00147 RouteCommand::exec(int argc, const char** argv, Tcl_Interp* interp)
00148 {
00149 (void)interp;
00150
00151 if (argc < 2) {
00152 resultf("need a route subcommand");
00153 return TCL_ERROR;
00154 }
00155
00156 const char* cmd = argv[1];
00157
00158 if (strcmp(cmd, "add") == 0) {
00159
00160 if (argc < 4) {
00161 wrong_num_args(argc, argv, 2, 4, INT_MAX);
00162 return TCL_ERROR;
00163 }
00164
00165 const char* dest_str = argv[2];
00166
00167 EndpointIDPattern dest(dest_str);
00168 if (!dest.valid()) {
00169 resultf("invalid destination eid %s", dest_str);
00170 return TCL_ERROR;
00171 }
00172
00173 const char* next_hop = argv[3];
00174
00175 RouteEntry* entry;
00176 LinkRef link;
00177 EndpointIDPattern route_to;
00178
00179 link = BundleDaemon::instance()->contactmgr()->find_link(next_hop);
00180 if (link != NULL) {
00181 entry = new RouteEntry(dest, link);
00182 } else if (route_to.assign(next_hop)) {
00183 entry = new RouteEntry(dest, route_to);
00184 } else {
00185 resultf("next hop %s is not a valid link or endpoint id",
00186 next_hop);
00187 return TCL_ERROR;
00188 }
00189
00190
00191
00192 argc -= 4;
00193 argv += 4;
00194 if (argc != 0 && (entry->parse_options(argc, argv) != argc))
00195 {
00196 resultf("invalid argument '%s'", argv[0]);
00197 return TCL_ERROR;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 if (BundleDaemon::instance()->started()) {
00207 BundleDaemon::post_and_wait(new RouteAddEvent(entry),
00208 CompletionNotifier::notifier());
00209 } else {
00210 BundleDaemon::post(new RouteAddEvent(entry));
00211 }
00212
00213 return TCL_OK;
00214 }
00215
00216 else if (strcmp(cmd, "del") == 0) {
00217
00218 if (argc != 3) {
00219 wrong_num_args(argc, argv, 2, 3, 3);
00220 return TCL_ERROR;
00221 }
00222
00223 EndpointIDPattern pat(argv[2]);
00224 if (!pat.valid()) {
00225 resultf("invalid endpoint id pattern '%s'", argv[2]);
00226 return TCL_ERROR;
00227 }
00228
00229 if (BundleDaemon::instance()->started()) {
00230 BundleDaemon::post_and_wait(new RouteDelEvent(pat),
00231 CompletionNotifier::notifier());
00232 } else {
00233 BundleDaemon::post(new RouteDelEvent(pat));
00234 }
00235
00236 return TCL_OK;
00237 }
00238
00239 else if (strcmp(cmd, "dump") == 0) {
00240 oasys::StringBuffer buf;
00241 BundleDaemon::instance()->get_routing_state(&buf);
00242 set_result(buf.c_str());
00243 return TCL_OK;
00244 }
00245
00246 else if (strcmp(cmd, "dump_tcl") == 0) {
00247
00248 oasys::StringBuffer buf;
00249 BundleDaemon::instance()->router()->tcl_dump_state(&buf);
00250 set_result(buf.c_str());
00251 return TCL_OK;
00252 }
00253
00254 else if (strcmp(cmd, "recompute_routes") == 0) {
00255 oasys::Time t = oasys::Time::now();
00256 BundleDaemon::instance()->router()->recompute_routes();
00257 resultf("%u", t.elapsed_ms());
00258 return TCL_OK;
00259 }
00260
00261 else if (strcmp(cmd, "local_eid") == 0) {
00262 if (argc == 2) {
00263
00264 set_result(BundleDaemon::instance()->local_eid().c_str());
00265 return TCL_OK;
00266
00267 } else if (argc == 3) {
00268
00269 BundleDaemon::instance()->set_local_eid(argv[2]);
00270 if (! BundleDaemon::instance()->local_eid().valid()) {
00271 resultf("invalid eid '%s'", argv[2]);
00272 return TCL_ERROR;
00273 }
00274 if (! BundleDaemon::instance()->local_eid().known_scheme()) {
00275 resultf("local eid '%s' has unknown scheme", argv[2]);
00276 return TCL_ERROR;
00277 }
00278 } else {
00279 wrong_num_args(argc, argv, 2, 2, 3);
00280 return TCL_ERROR;
00281 }
00282 }
00283
00284 else {
00285 resultf("unimplemented route subcommand %s", cmd);
00286 return TCL_ERROR;
00287 }
00288
00289 return TCL_OK;
00290 }
00291
00292 }