Line data Source code
1 : #ifndef HEADER_fd_src_waltz_ip_fd_netlink_h 2 : #define HEADER_fd_src_waltz_ip_fd_netlink_h 3 : 4 : #if defined(__linux__) 5 : 6 : #include "../../util/fd_util_base.h" 7 : 8 : struct fd_netlink { 9 : int fd; /* netlink socket */ 10 : uint seq; /* netlink sequence number */ 11 : }; 12 : 13 : typedef struct fd_netlink fd_netlink_t; 14 : 15 : /* FIXME this should be a 'buffered reader' style API not an iterator since 16 : iterators are infallible by definition in Firedancer style. */ 17 : 18 : struct fd_netlink_iter { 19 : uchar * buf; 20 : ulong buf_sz; 21 : uchar * msg0; 22 : uchar * msg1; 23 : int err; 24 : }; 25 : 26 : typedef struct fd_netlink_iter fd_netlink_iter_t; 27 : 28 : FD_PROTOTYPES_BEGIN 29 : 30 : /* fd_netlink_enobufs_cnt counts the number of ENOBUFS error occurrences. */ 31 : 32 : extern FD_TL ulong fd_netlink_enobufs_cnt; 33 : 34 : /* fd_netlink_init creates a new netlink session. Creates a new netlink 35 : socket with explicit ACKs. seq0 is the initial sequence number. */ 36 : 37 : fd_netlink_t * 38 : fd_netlink_init( fd_netlink_t * netlink, 39 : uint seq0 ); 40 : 41 : /* fd_netlink_fini closes the netlink socket. */ 42 : 43 : void * 44 : fd_netlink_fini( fd_netlink_t * netlink ); 45 : 46 : /* fd_netlink_read_socket wraps recvfrom(fd,buf,buf_sz,0,0,0) but 47 : automatically skips EINTR and ENOBUFS errors. */ 48 : 49 : long 50 : fd_netlink_read_socket( int fd, 51 : uchar * buf, 52 : ulong buf_sz ); 53 : 54 : /* fd_netlink_iter_init prepares iteration over a sequence of incoming 55 : netlink multipart messages. */ 56 : 57 : fd_netlink_iter_t * 58 : fd_netlink_iter_init( fd_netlink_iter_t * iter, 59 : fd_netlink_t * netlink, 60 : uchar * buf, 61 : ulong buf_sz ); 62 : 63 : /* fd_netlink_iter_done returns 0 if there are more netlink messages to 64 : iterate over or 1 if not. */ 65 : 66 : int 67 : fd_netlink_iter_done( fd_netlink_iter_t const * iter ); 68 : 69 : /* fd_netlink_iter_next advances the iterator to the next netlink message 70 : (if any). Assumes !fd_netlink_iter_done(iter). Invalidates pointers 71 : previously returned by fd_netlink_iter_msg(iter). */ 72 : 73 : fd_netlink_iter_t * 74 : fd_netlink_iter_next( fd_netlink_iter_t * iter, 75 : fd_netlink_t * netlink ); 76 : 77 : /* fd_netlink_iter_msg returns a pointer to the current netlink message 78 : header. Assumes !fd_netlink_iter_done(iter). */ 79 : 80 : static inline struct nlmsghdr const * 81 78 : fd_netlink_iter_msg( fd_netlink_iter_t const * iter ) { 82 78 : return fd_type_pun_const( iter->msg0 ); 83 78 : } 84 : 85 : static FD_FN_UNUSED ulong 86 : fd_netlink_iter_drain( fd_netlink_iter_t * iter, 87 6 : fd_netlink_t * netlink ) { 88 6 : ulong cnt; 89 6 : for( cnt=0UL; !fd_netlink_iter_done( iter ); cnt++ ) { 90 0 : fd_netlink_iter_next( iter, netlink ); 91 0 : } 92 6 : return cnt; 93 6 : } 94 : 95 : /* Debug utils */ 96 : 97 : char const * 98 : fd_netlink_rtm_type_str( int rtm_type ); 99 : 100 : char const * 101 : fd_netlink_rtattr_str( int rta_type ); 102 : 103 : FD_PROTOTYPES_END 104 : 105 : #endif /* defined(__linux__) */ 106 : 107 : #endif /* HEADER_fd_src_waltz_ip_fd_netlink_h */