xorp

click_socket.hh

00001 // -*- c-basic-offset: 4; tab-width: 8; indent-tabs-mode: t -*-
00002 
00003 // Copyright (c) 2001-2011 XORP, Inc and Others
00004 //
00005 // This program is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License, Version 2, June
00007 // 1991 as published by the Free Software Foundation. Redistribution
00008 // and/or modification of this program under the terms of any other
00009 // version of the GNU General Public License is not permitted.
00010 // 
00011 // This program is distributed in the hope that it will be useful, but
00012 // WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For more details,
00014 // see the GNU General Public License, Version 2, a copy of which can be
00015 // found in the XORP LICENSE.gpl file.
00016 // 
00017 // XORP Inc, 2953 Bunker Hill Lane, Suite 204, Santa Clara, CA 95054, USA;
00018 // http://xorp.net
00019 
00020 // $XORP: xorp/fea/data_plane/control_socket/click_socket.hh,v 1.6 2008/10/02 21:56:53 bms Exp $
00021 
00022 #ifndef __FEA_DATA_PLANE_CONTROL_SOCKET_CLICK_SOCKET_HH__
00023 #define __FEA_DATA_PLANE_CONTROL_SOCKET_CLICK_SOCKET_HH__
00024 
00025 #include <xorp_config.h>
00026 #ifdef XORP_USE_CLICK
00027 
00028 
00029 
00030 #include "libxorp/eventloop.hh"
00031 #include "libxorp/exceptions.hh"
00032 #include "libxorp/ipvx.hh"
00033 
00034 class ClickSocketObserver;
00035 struct ClickSocketPlumber;
00036 class RunCommand;
00037 
00043 class ClickSocket :
00044     public NONCOPYABLE
00045 {
00046 public:
00047     ClickSocket(EventLoop& eventloop);
00048     ~ClickSocket();
00049 
00057     void enable_click(bool v) { _is_enabled = v; }
00058 
00064     bool is_enabled() const { return (_is_enabled); }
00065 
00072     bool is_duplicate_routes_to_kernel_enabled() const { return _duplicate_routes_to_kernel; }
00073 
00080     void enable_duplicate_routes_to_kernel(bool v) { _duplicate_routes_to_kernel = v; }
00081 
00090     void enable_kernel_click(bool v) { _is_kernel_click = v; }
00091 
00097     void enable_kernel_click_install_on_startup(bool v) {
00098     _kernel_click_install_on_startup = v;
00099     }
00100 
00107     void set_kernel_click_modules(const list<string>& v) {
00108     _kernel_click_modules = v;
00109     }
00110 
00116     void set_kernel_click_mount_directory(const string& v) {
00117     _kernel_click_mount_directory = v;
00118     }
00119 
00128     void enable_user_click(bool v) { _is_user_click = v; }
00129 
00135     bool is_kernel_click() const { return _is_kernel_click; }
00136 
00142     bool is_user_click() const { return _is_user_click; }
00143 
00150     int start(string& error_msg);
00151 
00158     int stop(string& error_msg);
00159 
00167     const string& kernel_click_config_generator_file() const {
00168     return (_kernel_click_config_generator_file);
00169     }
00170 
00178     void set_kernel_click_config_generator_file(const string& v) {
00179     _kernel_click_config_generator_file = v;
00180     }
00181 
00187     void set_user_click_command_file(const string& v) {
00188     _user_click_command_file = v;
00189     }
00190 
00196     void set_user_click_command_extra_arguments(const string& v) {
00197     _user_click_command_extra_arguments = v;
00198     }
00199 
00205     void set_user_click_command_execute_on_startup(bool v) {
00206     _user_click_command_execute_on_startup = v;
00207     }
00208 
00216     void set_user_click_startup_config_file(const string& v) {
00217     _user_click_startup_config_file = v;
00218     }
00219 
00227     void set_user_click_control_address(const IPv4& v) {
00228     _user_click_control_address = v;
00229     }
00230 
00238     void set_user_click_control_socket_port(uint16_t v) {
00239     _user_click_control_socket_port = v;
00240     }
00241 
00249     const string& user_click_config_generator_file() const {
00250     return (_user_click_config_generator_file);
00251     }
00252 
00260     void set_user_click_config_generator_file(const string& v) {
00261     _user_click_config_generator_file = v;
00262     }
00263 
00280     int write_config(const string& element, const string& handler,
00281              bool has_kernel_config, const string& kernel_config,
00282              bool has_user_config, const string& user_config,
00283              string& error_msg);
00284 
00293     ssize_t write(XorpFd fd, const void* data, size_t nbytes);
00294 
00308     int check_user_command_status(bool& is_warning, string& command_warning,
00309                   bool& is_error, string& command_error,
00310                   string& error_msg);
00311 
00321     uint32_t seqno() const { return (_instance_no << 16 | _seqno); }
00322 
00328     pid_t pid() const { return _pid; }
00329 
00340     int force_kernel_click_read(string& error_msg) {
00341     return (force_read(_kernel_fd, error_msg));
00342     }
00343 
00354     int force_user_click_read(string& error_msg) {
00355     return (force_read(_user_fd, error_msg));
00356     }
00357 
00358 private:
00359     typedef list<ClickSocketObserver*> ObserverList;
00360 
00372     int force_read(XorpFd fd, string& error_msg);
00373 
00379     void io_event(XorpFd fd, IoEventType type);
00380 
00392     int  force_read_message(XorpFd fd, vector<uint8_t>& message,
00393                 string& error_msg);
00394 
00401     int load_kernel_click_modules(string& error_msg);
00402 
00411     int unload_kernel_click_modules(string& error_msg);
00412 
00420     int load_kernel_module(const string& module_filename, string& error_msg);
00421 
00432     int unload_kernel_module(const string& module_filename, string& error_msg);
00433 
00444     string kernel_module_filename2modulename(const string& module_filename);
00445 
00452     int mount_click_file_system(string& error_msg);
00453 
00460     int unmount_click_file_system(string& error_msg);
00461 
00469     int execute_user_click_command(const string& command,
00470                    const list<string>& argument_list);
00471 
00475     void terminate_user_click_command();
00476 
00481     void user_click_command_stdout_cb(RunCommand* run_command,
00482                       const string& output);
00483 
00488     void user_click_command_stderr_cb(RunCommand* run_command,
00489                       const string& output);
00490 
00495     void user_click_command_done_cb(RunCommand* run_command, bool success,
00496                     const string& error_msg);
00497 
00498 private:
00499     static const size_t CLSOCK_BYTES = 8*1024; // Initial guess at msg size
00500 
00501     inline const IPv4 DEFAULT_USER_CLICK_CONTROL_ADDRESS() {
00502     return (IPv4::LOOPBACK());
00503     }
00504     static const uint16_t DEFAULT_USER_CLICK_CONTROL_SOCKET_PORT = 13000;
00505     static const int CLICK_MAJOR_VERSION = 1;
00506     static const int CLICK_MINOR_VERSION = 1;
00507     static const size_t CLICK_COMMAND_RESPONSE_MIN_SIZE = 4;
00508     static const size_t CLICK_COMMAND_RESPONSE_CODE_SEPARATOR_INDEX = 3;
00509     static const int CLICK_COMMAND_CODE_OK = 200;
00510     static const int CLICK_COMMAND_CODE_WARNING_MIN = 201;
00511     static const int CLICK_COMMAND_CODE_WARNING_MAX = 299;
00512     static const int CLICK_COMMAND_CODE_ERROR_MIN = 500;
00513     static const int CLICK_COMMAND_CODE_ERROR_MAX = 599;
00514     static const TimeVal USER_CLICK_STARTUP_MAX_WAIT_TIME;
00515 
00516     static const string PROC_LINUX_MODULES_FILE;
00517     static const string LINUX_COMMAND_LOAD_MODULE;
00518     static const string LINUX_COMMAND_UNLOAD_MODULE;
00519     static const string CLICK_FILE_SYSTEM_TYPE;
00520 
00521 private:
00522     EventLoop&   _eventloop;
00523     XorpFd   _kernel_fd;
00524     XorpFd   _user_fd;
00525     ObserverList _ol;
00526 
00527     uint16_t     _seqno;    // Seqno of next write()
00528     uint16_t     _instance_no;  // Instance number of this Click socket
00529 
00530     static uint16_t _instance_cnt;
00531     static pid_t    _pid;
00532 
00533     bool    _is_enabled;        // True if Click is enabled
00534     bool    _duplicate_routes_to_kernel; // True if duplicating the Click
00535                     // routes to the kernel is enabled
00536     bool    _is_kernel_click;   // True if kernel Click is enabled
00537     bool    _is_user_click;     // True if user Click is enabled
00538 
00539     bool    _kernel_click_install_on_startup;
00540     list<string> _kernel_click_modules;
00541     list<string> _loaded_kernel_click_modules;
00542     string  _kernel_click_mount_directory;
00543     string  _mounted_kernel_click_mount_directory;
00544     string  _kernel_click_config_generator_file;
00545     string  _user_click_command_file;
00546     string  _user_click_command_extra_arguments;
00547     bool    _user_click_command_execute_on_startup;
00548     string  _user_click_startup_config_file;
00549     IPv4    _user_click_control_address;
00550     uint16_t    _user_click_control_socket_port;
00551     string  _user_click_config_generator_file;
00552 
00553     RunCommand* _user_click_run_command;
00554     
00555     friend class ClickSocketPlumber; // class that hooks observers in and out
00556 };
00557 
00558 class ClickSocketObserver {
00559 public:
00560     ClickSocketObserver(ClickSocket& cs);
00561 
00562     virtual ~ClickSocketObserver();
00563 
00574     virtual void clsock_data(const uint8_t* data, size_t nbytes) = 0;
00575 
00579     ClickSocket& click_socket();
00580 
00581 private:
00582     ClickSocket& _cs;
00583 };
00584 
00585 class ClickSocketReader : public ClickSocketObserver {
00586 public:
00587     ClickSocketReader(ClickSocket& cs);
00588     virtual ~ClickSocketReader();
00589 
00599     int receive_kernel_click_data(ClickSocket& cs, uint32_t seqno,
00600                   string& error_msg);
00601 
00611     int receive_user_click_data(ClickSocket& cs, uint32_t seqno,
00612                 string& error_msg);
00613 
00619     const string& buffer_str() const { return (_cache_data); }
00620 
00631     virtual void clsock_data(const uint8_t* data, size_t nbytes);
00632 
00633 private:
00634     ClickSocket&    _cs;
00635 
00636     bool        _cache_valid;   // Cache data arrived.
00637     uint32_t        _cache_seqno;   // Seqno of Click socket data to
00638                     // cache so reading via Click
00639                     // socket can appear synchronous.
00640     string      _cache_data;    // Cached Click socket data.
00641 };
00642 
00643 #endif // click
00644 #endif // __FEA_DATA_PLANE_CONTROL_SOCKET_CLICK_SOCKET_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations