📄 show_routes.cc
字号:
// -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-// Copyright (c) 2001-2007 International Computer Science Institute//// Permission is hereby granted, free of charge, to any person obtaining a// copy of this software and associated documentation files (the "Software")// to deal in the Software without restriction, subject to the conditions// listed in the XORP LICENSE file. These conditions include: you must// preserve this copyright notice, and you cannot mention the copyright// holders in advertising related to the Software without their permission.// The Software is provided WITHOUT ANY WARRANTY, EXPRESS OR IMPLIED. This// notice is a summary of the XORP LICENSE file; the license in that file is// legally binding.#ident "$XORP: xorp/rib/tools/show_routes.cc,v 1.23 2007/02/16 22:47:13 pavlin Exp $"#include "rib/rib_module.h"#include "libxorp/xorp.h"#include "libxorp/xlog.h"#include "libxorp/status_codes.h"#include <iomanip>#ifdef HAVE_GETOPT_H#include <getopt.h>#endif#include "libxorp/c_format.hh"#include "libxorp/eventloop.hh"#include "libxorp/ipv4.hh"#include "libxorp/ipv6.hh"#include "libxorp/service.hh"#include "libxipc/xrl_std_router.hh"#include "xrl/interfaces/rib_xif.hh"#include "xrl/interfaces/finder_event_notifier_xif.hh"#include "xrl/targets/show_routes_base.hh"//// TODO:// - Beware of multiple routes to the same destination.// Something in the upper code should be done?// - Print the time for each route.// - Show the route Status (active/last/both)// - Show the AS Path////// Print style//enum PrintStyle { PRINT_STYLE_BRIEF, PRINT_STYLE_DETAIL, PRINT_STYLE_TERSE, PRINT_STYLE_DEFAULT = PRINT_STYLE_BRIEF // XXX: default to BRIEF};// ----------------------------------------------------------------------------// Structure for holding command line optionsstruct ShowRoutesOptions { bool ribin; // ribin (true), ribout (false) bool ipv4; // IPv4 (true), IPv6(false) bool unicast; // unicast (true), multicast (false) PrintStyle print_style; // -b (BRIEF), -d (DETAIL), -t (TERSE) const char* protocol; string xrl_target; string finder_host; uint16_t finder_port; inline ShowRoutesOptions() : ribin(false), ipv4(true), unicast(true), print_style(PRINT_STYLE_DEFAULT), protocol("all") {}};// ----------------------------------------------------------------------------// Display functions and helperstemplate <typename A>static voiddisplay_route_brief(const IPNet<A>& net, const A& nexthop, const string& ifname, const string& vifname, uint32_t metric, uint32_t admin_distance, const string& protocol_origin){ cout << "" << net.str() << "\t"; cout << "["; cout << protocol_origin << "(" << admin_distance << ")"; cout << "/" << metric << "]"; // // XXX: At the end of the line we should print the age of the route, // but for now we don't have this information. // // cout << " 1w0d 01:58:27"; cout << endl; cout << "\t\t> "; if (admin_distance != 0) cout << "to " << nexthop.str() << " "; if (ifname.empty() == false) cout << "via " << ifname; if (vifname.empty() == false) cout << "/" << vifname; cout << endl;}template <typename A>static voiddisplay_route_detail(const IPNet<A>& net, const A& nexthop, const string& ifname, const string& vifname, uint32_t metric, uint32_t admin_distance, const string& protocol_origin){ string tmp_name; string unknown_name = "UNKNOWN"; cout << "Network " << net.str() << endl; cout << " Nexthop := " << nexthop.str() << endl; if (ifname.empty() == false) tmp_name = ifname; else tmp_name = unknown_name; cout << " Interface := " << tmp_name << endl; if (vifname.empty() == false) tmp_name = vifname; else tmp_name = unknown_name; cout << " Vif := " << tmp_name << endl; cout << " Metric := " << metric << endl; cout << " Protocol := " << protocol_origin << endl; cout << " Admin distance := " << admin_distance << endl;}template <typename A>static voiddisplay_route_terse(const IPNet<A>& net, const A& nexthop, const string& ifname, const string& vifname, uint32_t metric, uint32_t admin_distance, const string& protocol_origin){ string protocol_short = protocol_origin.substr(0, 1); // // TODO: Show status of route: // + = Active Route, // - = Last Active, // * = Both if (net.str().size() > 18) { cout << net.str() << endl << setw(19) << " "; } else { cout << setiosflags(ios::left) << setw(19) << net.str(); } cout << resetiosflags(ios::left) << protocol_short << " "; cout << setw(3) << admin_distance; cout << setw(10) << metric << " "; // XXX: We don't have second metric yet if (admin_distance != 0) cout << nexthop.str() << " "; if ((ifname.empty() == false) && (admin_distance == 0)) cout << ifname; if ((vifname.empty() == false) && (admin_distance == 0)) cout << "/" << vifname; // XXX: We don't have the AS path yet cout << endl;} // ----------------------------------------------------------------------------// Class for Querying RIB routesclass ShowRoutesProcessor : public XrlShowRoutesTargetBase, public ServiceBase {public: ShowRoutesProcessor(EventLoop& e, ShowRoutesOptions& opts); ~ShowRoutesProcessor(); bool startup(); bool shutdown();public: XrlCmdError common_0_1_get_target_name(string& name); XrlCmdError common_0_1_get_version(string& version); XrlCmdError common_0_1_get_status(uint32_t& status, string& reason); XrlCmdError common_0_1_shutdown(); XrlCmdError finder_event_observer_0_1_xrl_target_birth(const string& cls, const string& ins); XrlCmdError finder_event_observer_0_1_xrl_target_death(const string& cls, const string& ins); XrlCmdError redist4_0_1_starting_route_dump(const string& cookie); XrlCmdError redist4_0_1_finishing_route_dump(const string& cookie); XrlCmdError redist4_0_1_add_route(const IPv4Net& dst, const IPv4& nexthop, const string& ifname, const string& vifname, const uint32_t& metric, const uint32_t& admin_distance, const string& cookie, const string& protocol_origin); XrlCmdError redist4_0_1_delete_route(const IPv4Net& dst, const IPv4& nexthop, const string& ifname, const string& vifname, const uint32_t& metric, const uint32_t& admin_distance, const string& cookie, const string& protocol_origin); XrlCmdError redist6_0_1_starting_route_dump(const string& cookie); XrlCmdError redist6_0_1_finishing_route_dump(const string& cookie); XrlCmdError redist6_0_1_add_route(const IPv6Net& dst, const IPv6& nexthop, const string& ifname, const string& vifname, const uint32_t& metric, const uint32_t& admin_distance, const string& cookie, const string& protocol_origin); XrlCmdError redist6_0_1_delete_route(const IPv6Net& dst, const IPv6& nexthop, const string& ifname, const string& vifname, const uint32_t& metric, const uint32_t& admin_distance, const string& cookie, const string& protocol_origin); bool poll_ready_failed(); /** * @return true if cookie matches instance cookie, false otherwise. */ bool check_cookie(const string& cookie); /** * Register with Finder to watch RIB birth and death events. If * the RIB crashes we don't want to hang waiting for messages from * the RIB that will never arrive (start route dump, add route, * finish route dump) */ void step_100_watch_rib(); void watch_rib_cb(const XrlError& xe); /** * Request redistribution of user requested protocol. */ void step_200_request_redist(); void request_redist_cb(const XrlError& xe); /** * Request redistribution cease. */ void step_1000_request_cease(); void request_cease_cb(const XrlError& xe);protected: EventLoop& _e; const ShowRoutesOptions& _opts; XrlRouter* _rtr; XorpTimer _t; IPv4Net _network_prefix4; IPv6Net _network_prefix6; string _cookie;};ShowRoutesProcessor::ShowRoutesProcessor(EventLoop& e, ShowRoutesOptions& o) : _e(e), _opts(o), _rtr(NULL), _network_prefix4(IPv4::ZERO(), 0), // XXX: get the whole table _network_prefix6(IPv6::ZERO(), 0) // XXX: get the whole table{}ShowRoutesProcessor::~ShowRoutesProcessor(){ if (_rtr != NULL) { delete _rtr; _rtr = NULL; }}boolShowRoutesProcessor::startup(){ if (status() != SERVICE_READY) { return false; } // Create XrlRouter string process = c_format("show_routes<%d>", XORP_INT_CAST(getpid())); _rtr = new XrlStdRouter(_e, process.c_str(), _opts.finder_host.c_str(), _opts.finder_port); // Glue the router to the Xrl methods class exports this->set_command_map(_rtr); // Register methods with Finder _rtr->finalize(); // Start timer to poll whether XrlRouter becomes ready or fails so // we can continue processing. _t = _e.new_periodic_ms(250, callback(this, &ShowRoutesProcessor::poll_ready_failed)); set_status(SERVICE_STARTING); return true;}boolShowRoutesProcessor::shutdown(){ // Withdraw the Xrl methods this->set_command_map(NULL); ServiceStatus st = this->status(); if (st == SERVICE_FAILED || st == SERVICE_SHUTTING_DOWN || st == SERVICE_SHUTDOWN) return false; set_status(SERVICE_SHUTTING_DOWN); step_1000_request_cease(); return true;}boolShowRoutesProcessor::poll_ready_failed(){ if (_rtr == 0) { return false; } else if (_rtr->ready()) { set_status(SERVICE_RUNNING); step_100_watch_rib(); return false; } else if (_rtr->failed()) { set_status(SERVICE_FAILED, "Failed: No Finder?"); return false; } return true;}voidShowRoutesProcessor::step_100_watch_rib(){ XrlFinderEventNotifierV0p1Client fen(_rtr); if (fen.send_register_class_event_interest( "finder", _rtr->instance_name(), _opts.xrl_target, callback(this, &ShowRoutesProcessor::watch_rib_cb)) == false) { set_status(SERVICE_FAILED, c_format("Failed to register interest in %s", _opts.xrl_target.c_str())); return; }}voidShowRoutesProcessor::watch_rib_cb(const XrlError& xe){ if (xe == XrlError::OKAY()) { step_200_request_redist(); return; } set_status(SERVICE_FAILED, c_format("Failed to register interest in %s", _opts.xrl_target.c_str())); return;}inline stringrib_table_name(const string& protocol, bool ribin){ if (protocol == "all") return protocol; // "all" is a special name in the RIB for the rib out table. // "all-<proto>" adds redist with a filter for <proto> return c_format("%s%s", (ribin ? "" : "all-"), protocol.c_str());}voidShowRoutesProcessor::step_200_request_redist(){ string protocol = rib_table_name(_opts.protocol, _opts.ribin); XrlRibV0p1Client::RedistEnable4CB cb; cb = callback(this, &ShowRoutesProcessor::request_redist_cb); XrlRibV0p1Client rib(_rtr); bool sent = false; if (_opts.ipv4) { sent = rib.send_redist_enable4(_opts.xrl_target.c_str(), _rtr->instance_name(), protocol, _opts.unicast, !_opts.unicast, _network_prefix4, _cookie, cb); } else { sent = rib.send_redist_enable6(_opts.xrl_target.c_str(), _rtr->instance_name(), protocol, _opts.unicast, !_opts.unicast, _network_prefix6, _cookie, cb); } if (sent == false) { set_status(SERVICE_FAILED, "Failed to request redist."); }}voidShowRoutesProcessor::request_redist_cb(const XrlError& xe){ if (xe == XrlError::OKAY()) { return; } set_status(SERVICE_FAILED, c_format("Request for routes to be redistributed from %s " "failed.\nThe protocol is probably not active.", _opts.protocol)); return;}voidShowRoutesProcessor::step_1000_request_cease(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -