예제 #1
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
/**
 * context: {link}
 * tokens : {igp-weight}
 * options: {--bidir --tos=<>}
 */
int cli_net_link_igpweight(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  net_iface_t * link= _link_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);
  const char * opt;
  igp_weight_t weight;
  net_tos_t tos= 0;
  int bidir= 0;
  int result;

  //cli_args_dump(gdsout, cmd->opts);

  // Get optional TOS
  opt= cli_get_opt_value(cmd, "tos");
  if (opt != NULL)
    if (!str2tos(opt, &tos)) {
      cli_set_user_error(cli_get(), "invalid TOS \"%s\"", opt);
      return CLI_ERROR_COMMAND_FAILED;
    }

  // Check option --bidir
  if (cli_has_opt_value(cmd, "bidir")) {
    if (link->type != NET_IFACE_RTR) {
      cli_set_user_error(cli_get(), ": --bidir only works with ptp links");
      return CLI_ERROR_COMMAND_FAILED;
    }
    bidir= 1;
  }

  // Get new IGP weight
  if (str2weight(arg, &weight)) {
    cli_set_user_error(cli_get(), "invalid weight \"%s\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Change link weight
  result= net_iface_set_metric(link, tos, weight, bidir);
  if (result != ESUCCESS) {
    cli_set_user_error(cli_get(), "cannot set metric (%s)",
		       network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #2
0
/**
 * context: {router, peer}
 * tokens: {}
 */
static int cli_peer_reset(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  bgp_peer_t * peer= _peer_from_context(ctx);

  // Try to close session
  if (bgp_peer_close_session(peer)) {
    cli_set_user_error(cli_get(), "could not close session");
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Try to open session
  if (bgp_peer_open_session(peer)) {
    cli_set_user_error(cli_get(), "could not close session");
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #3
0
after(): call(void loadConfig())
{
    kcli            = cli_get();
    jem_command     = cli_register_command(kcli, NULL, "jem", NULL, PRIVILEGE_UNPRIVILEGED,
                                           MODE_EXEC, NULL);
    jemtst_command  = cli_register_command(kcli, NULL, "utest", NULL, PRIVILEGE_UNPRIVILEGED,
                                           MODE_EXEC, NULL);
    cli_register_command(kcli, jemtst_command, "enter", jem_test_mode,
                         PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Enter jem test mode.");
}
예제 #4
0
/**
 * context: {}
 * tokens: {file}
 * options:
 *   --addr-sch=default|local
 *   --format=default|caida
 */
static int cli_bgp_topology_load(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg;
  uint8_t addr_scheme= ASLEVEL_ADDR_SCH_DEFAULT;
  uint8_t format= ASLEVEL_FORMAT_DEFAULT;
  int line_number;
  int result;

  // Optional addressing scheme specified ?
  arg= cli_opts_get_value(cmd->opts, "addr-sch");
  if (arg != NULL) {
    if (aslevel_str2addr_sch(arg, &addr_scheme) != ASLEVEL_SUCCESS) {
      cli_set_user_error(cli_get(), "invalid addressing scheme \"%s\"", arg);
      return CLI_ERROR_COMMAND_FAILED;
    }
  }

  // Optional format specified ?
  arg= cli_opts_get_value(cmd->opts, "format");
  if (arg != NULL) {
    if (aslevel_topo_str2format(arg, &format) != ASLEVEL_SUCCESS) {
      cli_set_user_error(cli_get(), "invalid format \"%s\"", arg);
      return CLI_ERROR_COMMAND_FAILED;
    }
  }

  // Load AS-level topology
  arg= cli_get_arg_value(cmd, 0);
  result= aslevel_topo_load(arg, format, addr_scheme, &line_number);
  if (result != ASLEVEL_SUCCESS) {
    if (line_number > 0)
      cli_set_user_error(cli_get(), "could not load topology \"%s\" "
			 "(%s, at line %u)", arg, aslevel_strerror(result),
			 line_number);
    else
      cli_set_user_error(cli_get(), "could not load topology \"%s\" "
			 "(%s)", arg, aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #5
0
/**
 * context: {}
 * tokens : {prefix}
 * options: {--output=FILE,--exact-match,--preserve-dups}
 */
static int cli_bgp_topology_recordroute(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  ip_pfx_t prefix;
  gds_stream_t * stream= gdsout;
  const char * arg= cli_get_arg_value(cmd, 0);
  int result;
  uint8_t options= 0;

  // Destination prefix
  if (str2prefix(arg, &prefix) < 0) {
    cli_set_user_error(cli_get(), "invalid prefix \"%s\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Optional output file ?
  arg= cli_get_opt_value(cmd, "output");
  if (arg != NULL) {
    stream= stream_create_file(arg);
    if (stream == NULL) {
      cli_set_user_error(cli_get(), "unable to create \"%s\"", arg);
      return CLI_ERROR_COMMAND_FAILED;
    }
  }

  if (cli_has_opt_value(cmd, "exact-match"))
    options|= AS_RECORD_ROUTE_OPT_EXACT_MATCH;
  if (cli_has_opt_value(cmd, "preserve-dups"))
    options|= AS_RECORD_ROUTE_OPT_PRESERVE_DUPS;

  // Record routes
  result= aslevel_topo_record_route(stream, prefix, options);
  if (result != ASLEVEL_SUCCESS) {
    cli_set_user_error(cli_get(), "could not record route (%s)",
		       aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  if (stream != gdsout)
    stream_destroy(&stream);

  return CLI_SUCCESS;
}
예제 #6
0
/**
 * context: {router, peer}
 * tokens: {src-addr}
 */
static int cli_peer_update_source(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  bgp_peer_t * peer= _peer_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);
  net_addr_t src_addr;

  // Get source address
  if (str2address(arg, &src_addr)) {
    cli_set_user_error(cli_get(), "invalid source address \"%s\".", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Try to open session
  if (bgp_peer_set_source(peer, src_addr)) {
    cli_set_user_error(cli_get(), "could not set source address");
    return CLI_ERROR_COMMAND_FAILED;
  }
    
  return CLI_SUCCESS;
}
예제 #7
0
/**
 * context: {}
 * tokens: {}
 */
static int cli_bgp_topology_run(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  int result= aslevel_topo_run();

  if (result != ASLEVEL_SUCCESS) {
    cli_set_user_error(cli_get(), "could not run topology (%s)",
		       aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }
  return CLI_SUCCESS;
}
예제 #8
0
/**
 * context: {router, peer}
 * tokens: {addr}
 */
static int cli_peer_nexthop(cli_ctx_t * ctx,
			    cli_cmd_t * cmd)
{
  bgp_peer_t * peer= _peer_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);
  net_addr_t next_hop;

  // Get next-hop address
  if (str2address(arg, &next_hop)) {
    cli_set_user_error(cli_get(), "invalid next-hop \"%s\".", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Set the next-hop to be used for routes advertised to this peer
  if (bgp_peer_set_nexthop(peer, next_hop)) {
    cli_set_user_error(cli_get(), "could not change next-hop");
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #9
0
/**
 * context: {}
 * tokens: {<asn>}
 */
static int cli_bgp_topology_filter_asn(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg= cli_get_arg_value(cmd, 0);
  asn_t asn;
  int result;
  
  // Get ASN
  if (str2asn(arg, &asn)) {
    cli_set_user_error(cli_get(), "invalid ASN (%s)", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Remove AS from topology
  result= aslevel_topo_filter_as(asn);
  if (result != ASLEVEL_SUCCESS) {
    cli_set_user_error(cli_get(), "could not filter ASN (%s)",
		       aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }
  return CLI_SUCCESS;
}
예제 #10
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
// ----- cli_ctx_create_net_subnet ----------------------------------
int cli_ctx_create_net_subnet(cli_ctx_t * ctx, cli_cmd_t * cmd, void ** item)
{
  const char * arg= cli_get_arg_value(cmd, 0);
  net_subnet_t * subnet;

  if (str2subnet(arg, &subnet)) {
    cli_set_user_error(cli_get(), "unable to find subnet \"%s\"", arg);
    return CLI_ERROR_CTX_CREATE;
  }
  *item= subnet;
  return CLI_SUCCESS;
}
예제 #11
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
/**
 * context: {}
 * tokens: {ntf_file}
 */
int cli_net_ntf_load(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg= cli_get_arg_value(cmd, 0);

  // Load given NTF file
  if (ntf_load(arg) < 0) {
    cli_set_user_error(cli_get(), "could not load NTF file \"%s\" (%s%s)",
		       arg, ntf_strerror(), ntf_strerrorloc());
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #12
0
/**
 * context: {router, peer}
 * tokens: {}
 */
static int cli_peer_softrestart(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  bgp_peer_t * peer= _peer_from_context(ctx);

  // Set the virtual flag of this peer
  if (!bgp_peer_flag_get(peer, PEER_FLAG_VIRTUAL)) {
    cli_set_user_error(cli_get(), "soft-restart option only available to virtual peers");
    return CLI_ERROR_COMMAND_FAILED;
  }
  bgp_peer_flag_set(peer, PEER_FLAG_SOFT_RESTART, 1);
    
  return CLI_SUCCESS;
}
예제 #13
0
/**
 * context: {iface}
 * tokens: {weight}
 */
static int cli_iface_igpweight(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  net_iface_t * iface= _iface_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);
  igp_weight_t weight;
  int result;

  // Get IGP weight
  if (str2weight(arg, &weight)) {
    cli_set_user_error(cli_get(), "invalid weight \"%s\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Change link weight in forward direction
  result= net_iface_set_metric(iface, 0, weight, 0);
  if (result != ESUCCESS) {
    cli_set_user_error(cli_get(), "cannot set weight (%s)",
		       network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }
  return CLI_SUCCESS;
}
예제 #14
0
/**
 * context: {router} -> {router, peer}
 * tokens: {addr}
 */
static int cli_ctx_create_peer(cli_ctx_t * ctx, cli_cmd_t * cmd, void ** item)
{
  bgp_router_t* router= _router_from_context(ctx);
  bgp_peer_t * peer;
  const char * arg= cli_get_arg_value(cmd, 0);
  net_addr_t addr;

  // Get the peer ID (address, ASN, ...)
  if (str2addr_id(arg, &addr)) {
    cli_set_user_error(cli_get(), "invalid peer address \"%s\"", arg);
    return CLI_ERROR_CTX_CREATE;
  }

  // Get the peer
  peer= bgp_router_find_peer(router, addr);
  if (peer == NULL) {
    cli_set_user_error(cli_get(), "unknown peer");
    return CLI_ERROR_CTX_CREATE;
  }

  *item= peer;
  return CLI_SUCCESS;
}
예제 #15
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
/**
 * context: {}
 * tokens : {file}
 */
int cli_net_traffic_save(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg= cli_get_arg_value(cmd, 0);
  gds_stream_t * stream;
  int result;

  // Get the optional parameter
  stream= stream_create_file(arg);
  if (stream == NULL) {
    cli_set_user_error(cli_get(), "could not create \"%d\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Save traffic matrix
  result= network_links_save(stream, network_get_default());
  if (result != 0) {
    cli_set_user_error(cli_get(), "could not save traffic matrix (%s)",
		       network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #16
0
static int cli_peer_walton_limit(cli_ctx_t * ctx, 
				 cli_cmd_t * cmd)
{
  bgp_peer_t * peer= _peer_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);
  unsigned int limit;

  if (str_as_uint(arg, &limit)) {
    cli_set_user_error(cli_get(), "invalid walton limit \"%s\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }
  peer_set_walton_limit(peer, limit);
  return CLI_SUCCESS;
}
예제 #17
0
/**
 * context: {iface}
 * tokens: {load}
 */
static int cli_iface_load_add(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  net_iface_t * iface= _iface_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);
  net_link_load_t load;

  // Get load
  if (str2capacity(arg, &load)) {
    cli_set_user_error(cli_get(), "invalid load \"%s\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }
  net_iface_set_load(iface, load);
  return CLI_SUCCESS;
}
예제 #18
0
/**
 * context: {}
 * tokens: {<what>}
 */
static int cli_bgp_topology_filter_group(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg= cli_get_arg_value(cmd, 0);
  int result;
  uint8_t filter;

  // Get filter parameter
  result= aslevel_filter_str2filter(arg, &filter);
  if (result != ASLEVEL_SUCCESS) {
    cli_set_user_error(cli_get(), "could not filter topology (%s)",
		       aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }
  
  // Filter topology
  result= aslevel_topo_filter_group(filter);
  if (result != ASLEVEL_SUCCESS) {
    cli_set_user_error(cli_get(), "could not filter topology (%s)",
		       aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #19
0
static int cli_peer_readv(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  bgp_peer_t * peer= _peer_from_context(ctx);
  bgp_router_t* router= peer->router;
  const char * arg= cli_get_arg_value(cmd, 0);
  ip_pfx_t prefix;

  /* Get prefix */
  if (!strcmp(arg, "*")) {
    prefix.mask= 0;
  } else if (!str2prefix(arg, &prefix)) {
  } else {
    cli_set_user_error(cli_get(), "invalid prefix|* \"%s\"", arg);
    return CLI_ERROR_COMMAND_FAILED;
  }

  /* Re-advertise */
  if (bgp_router_peer_readv_prefix(router, peer, prefix)) {
    cli_set_user_error(cli_get(), "could not re-advertise");
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #20
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
/**
 * context: {}
 * tokens : {addr}
 * options: {no-loopback}
 */
int cli_net_add_node(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  net_addr_t addr;
  net_node_t * node;
  int error;
  int options= 0; // default is: create loopback with address = node ID

  // Node address ?
  if (str2address(cli_get_arg_value(cmd, 0), &addr)) {
    cli_set_user_error(cli_get(), "could not add node (invalid address)");
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Option: no-loopback ?
  if (!cli_opts_has_value(cmd->opts, "no-loopback")) {
    options|= NODE_OPTIONS_LOOPBACK;
  }

  // Create new node
  error= node_create(addr, &node, options);
  if (error != ESUCCESS) {
    cli_set_user_error(cli_get(), "could not add node (%s)",
		       network_strerror(error));
    return CLI_ERROR_COMMAND_FAILED;    
  }

  // Add node
  error= network_add_node(network_get_default(), node);
  if (error != ESUCCESS) {
    node_destroy(&node);
    cli_set_user_error(cli_get(), "could not add node (%s)",
		       network_strerror(error));
    return CLI_ERROR_COMMAND_FAILED;
  }
  return CLI_SUCCESS;
}
예제 #21
0
/**
 * context: {}
 * tokens: {}
 * options: {--verbose}
 */
static int cli_bgp_topology_check(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  int result;
  int verbose= 0;

  // Verbose check ?
  if (cli_opts_has_value(cmd->opts, "verbose"))
    verbose= 1;

  result= aslevel_topo_check(verbose);
  if (result != ASLEVEL_SUCCESS) {
    cli_set_user_error(cli_get(), "check failed (%s)",
		       aslevel_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }
  return CLI_SUCCESS;
}
예제 #22
0
/**
 * context: {node}
 * tokens: {addr, area}
 */
int cli_net_node_ospf_area(SCliContext * pContext, STokens * pTokens)
{
  net_node_t * pNode;
  ospf_area_t uArea;

  // Get node from context
  pNode= (net_node_t *) cli_context_get_item_at_top(pContext);

  // Add ospf area to node
  tokens_get_uint_at(pTokens, 1, &uArea);
  if (node_add_OSPFArea(pNode, uArea) < 0) {
    cli_set_user_error(cli_get(), "unexpected error");
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #23
0
/**
 * context: {router, peer}
 * tokens: {in|out}
 */
static int cli_ctx_create_peer_filter(cli_ctx_t * ctx, cli_cmd_t * cmd,
				      void ** item_ref)
{
  bgp_peer_t * peer= _peer_from_context(ctx);
  const char * arg= cli_get_arg_value(cmd, 0);

  // Create filter context
  if (!strcmp(arg, "in"))
    *item_ref= &(peer->filter[FILTER_IN]);
  else if (!strcmp(arg, "out"))
    *item_ref= &(peer->filter[FILTER_OUT]);
  else {
    cli_set_user_error(cli_get(), "invalid filter type \"%s\"", arg);
    return CLI_ERROR_CTX_CREATE;
  }

  return CLI_SUCCESS;
}
예제 #24
0
int cli_get_last(int statement)
{
    return cli_get(statement, cli_cmd_get_last);
}
예제 #25
0
int cli_get_next(int statement)
{
    return cli_get(statement, cli_cmd_get_next);
}
예제 #26
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
/**
 * context: {}
 * tokens: {src-addr, src-iface-id, dst-addr, dst-iface-id}
 */
int cli_net_add_linkptp(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg_src   = cli_get_arg_value(cmd, 0);
  const char * arg_src_if= cli_get_arg_value(cmd, 1);
  const char * arg_dst   = cli_get_arg_value(cmd, 2);
  const char * arg_dst_if= cli_get_arg_value(cmd, 3);
  const char * opt;
  net_node_t * src_node;
  net_node_t * dst_node;
  net_iface_id_t src_if;
  net_iface_id_t dst_if;
  int result;
  net_iface_t * iface;
  net_link_delay_t delay= 0;
  net_link_load_t capacity= 0;

  // Get source node
  if (str2node(arg_src, &src_node)) {
    cli_set_user_error(cli_get(), "could not find node \"%s\"", arg_src);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Get source address
  if (net_iface_str2id(arg_src_if, &src_if)) {
    cli_set_user_error(cli_get(), "invalid interface id \"%\"", arg_src_if);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Get destination node
  if (str2node(arg_dst, &dst_node)) {
    cli_set_user_error(cli_get(), "could not find node \"%s\"", arg_dst);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // get destination address
  if (net_iface_str2id(arg_dst_if, &dst_if)) {
    cli_set_user_error(cli_get(), "invalid interface id \"%\"", arg_dst_if);
    return CLI_ERROR_COMMAND_FAILED;
  }

  // Get optional link capacity
  opt= cli_get_opt_value(cmd, "bw");
  if (opt != NULL) {
    if (str2capacity(opt, &capacity)) {
      cli_set_user_error(cli_get(), "invalid link capacity \"%s\"", opt);
      return CLI_ERROR_COMMAND_FAILED;
    }
  }

  // Get optional link delay
  opt= cli_get_opt_value(cmd, "delay");
  if (opt != NULL) {
    if (str2delay(opt, &delay)) {
      cli_set_user_error(cli_get(), "invalid link delay \"%s\"", opt);
      return CLI_ERROR_CMD_FAILED;
    }
  }
  
  // Create link
  result= net_link_create_ptp(src_node, src_if, dst_node, dst_if,
			      BIDIR, &iface);
  if (result != ESUCCESS) {
    cli_set_user_error(cli_get(), "could not create ptp link "
		       "from %s (%s) to %s (%s) (%s)",
		       arg_src, arg_src_if, arg_dst, arg_dst_if,
		       network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  result= net_link_set_phys_attr(iface, delay, capacity, BIDIR);
  if (result != ESUCCESS) {
    cli_set_user_error(cli_get(), "could not set physical attributes (%s)",
		       network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  return CLI_SUCCESS;
}
예제 #27
0
파일: net.c 프로젝트: gvsurenderreddy/cbgp
/**
 * context: {}
 * tokens: {addr-src, prefix-dst}
 * options: [--depth=, --capacity=, delay=]
 */
int cli_net_add_link(cli_ctx_t * ctx, cli_cmd_t * cmd)
{
  const char * arg_src= cli_get_arg_value(cmd, 0);
  const char * arg_dst= cli_get_arg_value(cmd, 1);
  const char * opt;
  net_node_t * src_node;
  net_node_t * dst_node;
  ip_dest_t dest;
  int result;
  uint8_t depth= 1;
  net_link_delay_t delay= 0;
  net_link_load_t capacity= 0;
  net_iface_dir_t dir;
  net_iface_t * iface;
  net_subnet_t * subnet;

  // Get optional link depth
  opt= cli_get_opt_value(cmd, "depth");
  if (opt != NULL) {
    if (str2depth(opt, &depth)) {
      cli_set_user_error(cli_get(), "invalid link depth \"%s\"", opt);
      return CLI_ERROR_COMMAND_FAILED;
    }
  }
  
  // Get optional link capacity
  opt= cli_get_opt_value(cmd, "bw");
  if (opt != NULL) {
    if (str2capacity(opt, &capacity)) {
      cli_set_user_error(cli_get(), "invalid link capacity \"%s\"", opt);
      return CLI_ERROR_COMMAND_FAILED;
    }
  }

  // Get optional link delay
  opt= cli_get_opt_value(cmd, "delay");
  if (opt != NULL) {
    if (str2delay(opt, &delay)) {
      cli_set_user_error(cli_get(), "invalid link delay \"%s\"", opt);
      return CLI_ERROR_CMD_FAILED;
    }
  }

  // Get source node
  if (str2node(arg_src, &src_node)) {
    cli_set_user_error(cli_get(), "could not find node \"%s\"", arg_src);
    return CLI_ERROR_COMMAND_FAILED;
  }
  
  // Get destination: can be a node / a subnet
  if ((ip_string_to_dest(arg_dst, &dest) < 0) ||
      (dest.type == NET_DEST_ANY)) {
    cli_set_user_error(cli_get(), "invalid destination \"%s\".", arg_dst);
    return CLI_ERROR_COMMAND_FAILED;
  }
  
  // Add link: RTR (to node) / PTMP (to subnet)
  if (dest.type == NET_DEST_ADDRESS) {
    dst_node= network_find_node(network_get_default(), dest.addr);
    if (dst_node == NULL) {
      cli_set_user_error(cli_get(), "tail-end \"%s\" does not exist.",
			 arg_dst);
      return CLI_ERROR_COMMAND_FAILED;
    }
    dir= BIDIR;
    result= net_link_create_rtr(src_node, dst_node, dir, &iface);
  } else {
    subnet= network_find_subnet(network_get_default(), dest.prefix);
    if (subnet == NULL) {
      cli_set_user_error(cli_get(), "tail-end \"%s\" does not exist.",
			 arg_dst);
      return CLI_ERROR_COMMAND_FAILED;
    }
    dir= UNIDIR;
    result= net_link_create_ptmp(src_node, subnet,
				 dest.prefix.network,
				 &iface);
  }
  if (result != ESUCCESS) {
    cli_set_user_error(cli_get(), "could not add link %s -> %s (%s)",
		       arg_src, arg_dst, network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }

  result= net_link_set_phys_attr(iface, delay, capacity, dir);
  if (result != ESUCCESS) {
    cli_set_user_error(cli_get(), "could not set physical attributes (%s)",
		       network_strerror(result));
    return CLI_ERROR_COMMAND_FAILED;
  }  

  return CLI_SUCCESS;
}
예제 #28
0
int cli_get_prev(int statement)
{
    return cli_get(statement, cli_cmd_get_prev);
}