xorp

netlink_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 
00021 #ifndef __FEA_DATA_PLANE_CONTROL_SOCKET_NETLINK_SOCKET_HH__
00022 #define __FEA_DATA_PLANE_CONTROL_SOCKET_NETLINK_SOCKET_HH__
00023 
00024 #include <xorp_config.h>
00025 #ifdef HAVE_NETLINK_SOCKETS
00026 
00027 
00028 
00029 #include "libxorp/eventloop.hh"
00030 #include "libxorp/exceptions.hh"
00031 
00032 class NetlinkSocketObserver;
00033 class NetlinkSocketPlumber;
00034 
00035 
00041 class NetlinkSocket :
00042     public NONCOPYABLE
00043 {
00044 public:
00045     NetlinkSocket(EventLoop& eventloop, uint32_t table_id);
00046     virtual ~NetlinkSocket();
00047 
00054     int start(string& error_msg);
00055 
00062     int stop(string& error_msg);
00063 
00072     bool is_open() const { return _fd >= 0; }
00073 
00082     ssize_t write(const void* data, size_t nbytes);
00083 
00092     ssize_t sendto(const void* data, size_t nbytes, int flags,
00093            const struct sockaddr* to, socklen_t tolen);
00094     
00104     uint32_t seqno() const { return (_instance_no << 16 | _seqno); }
00105 
00111     uint32_t nl_pid() const { return _nl_pid; }
00112 
00127     int force_recvmsg_flgs(int flags, bool only_kernel_messages, string& error_msg);
00128 
00132     int force_recvmsg(bool only_kernel_messages, string& err_msg);
00133 
00144     void    set_nl_groups(uint32_t v) { _nl_groups = v; }
00145 
00159     void    set_multipart_message_read(bool v) { _is_multipart_message_read = v; }
00160 
00163     virtual int notify_table_id_change(uint32_t new_tbl);
00164 
00165 private:
00166     typedef list<NetlinkSocketObserver*> ObserverList;
00167 
00173     void io_event(XorpFd fd, IoEventType sm);
00174 
00175     int bind_table_id();
00176 
00177     static const size_t NETLINK_SOCKET_BYTES = 8*1024;  // Initial guess at msg size
00178 
00179     EventLoop&   _eventloop;
00180     int      _fd;
00181     ObserverList _ol;
00182 
00183     uint16_t     _seqno;    // Seqno of next write()
00184     uint16_t     _instance_no;  // Instance number of this netlink socket
00185     
00186     static uint16_t _instance_cnt;
00187     uint32_t    _nl_pid;
00188 
00189     uint32_t    _nl_groups; // The netlink multicast groups to listen for
00190     uint32_t _table_id; // routing table.. or 0 if any/all (default behaviour) 
00191     bool    _is_multipart_message_read; // If true, expect to read a multipart message
00192 
00193     uint32_t   _nlm_count; // keep track of how many msgs received.
00194 
00195     friend class NetlinkSocketPlumber; // class that hooks observers in and out
00196 };
00197 
00198 class NetlinkSocketObserver {
00199 public:
00200     NetlinkSocketObserver(NetlinkSocket& ns);
00201     virtual ~NetlinkSocketObserver();
00202 
00212     virtual void netlink_socket_data(const vector<uint8_t>& buffer) = 0;
00213 
00217     NetlinkSocket& netlink_socket();
00218 
00219 private:
00220     NetlinkSocket& _ns;
00221 };
00222 
00223 class NetlinkSocketReader : public NetlinkSocketObserver {
00224 public:
00225     NetlinkSocketReader(NetlinkSocket& ns);
00226     virtual ~NetlinkSocketReader();
00227 
00236     int receive_data(NetlinkSocket& ns, uint32_t seqno, string& error_msg);
00237 
00243     const vector<uint8_t>& buffer() const { return (_cache_data); }
00244 
00254     virtual void netlink_socket_data(const vector<uint8_t>& buffer);
00255 
00256 private:
00257     NetlinkSocket&  _ns;
00258 
00259     bool        _cache_valid;   // Cache data arrived.
00260     uint32_t        _cache_seqno;   // Seqno of netlink socket data to
00261                     // cache so reading via netlink
00262                     // socket can appear synchronous.
00263     vector<uint8_t> _cache_data;    // Cached netlink socket data.
00264 };
00265 
00266 
00267 
00268 #endif // HAVE_NETLINK_SOCKETS
00269 #endif // __FEA_DATA_PLANE_CONTROL_SOCKET_NETLINK_SOCKET_HH__
 All Classes Namespaces Functions Variables Typedefs Enumerations