=== modified file 'common/ntrackarchapi.h' --- a/common/ntrackarchapi.h 2010-12-19 22:22:23 +0000 +++ b/common/ntrackarchapi.h 2011-05-19 22:08:05 +0000 @@ -1,11 +1,11 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2009,2010 Alexander Sack + * Copyright (C) 2009-2011 Alexander Sack * * This file is part of: * ntrack - Network Status Tracking for Desktop Applications * http://launchpad.net/ntrack * * ntrack is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of @@ -21,16 +21,43 @@ */ #include "ntrackmonitor.h" #ifndef __NTRACK_ARCH_API_H__ #define __NTRACK_ARCH_API_H__ NTRACK_BEGIN_DECLS +#define NTRACK_MODULE_DEFINE(name,longname,function_table) \ + struct _ntrack_module ntrack_module = { \ + { name, longname, "" }, \ + function_table \ + }; + +struct _ntrack_module_info +{ + const char *name; + const char *longname; + const char *location; +}; + +struct _ntrack_module_functions +{ + ntrack_monitor_t* (*new) (ntrack_monitor_callback_f callback, ntrackpointer user_data); + int* (*get_rfds) (ntrack_monitor_t *self); + int (*process_data) (ntrackpointer self, int* fds); + void (*free) (ntrackpointer self); +}; + +struct _ntrack_module +{ + struct _ntrack_module_info parent; + struct _ntrack_module_functions *ftbl; +}; + struct _ntrack_monitor { ntrack_state_t state; struct _listener_pack **packs; int pack_len; int pack_size; }; @@ -39,23 +66,11 @@ struct _ntrack_monitor_arch ntrack_monitor_t parent; ntrackpointer data; ntrack_monitor_callback_f cb; ntrackpointer cb_user_data; }; -ntrack_monitor_t* -_ntrack_arch_new (ntrack_monitor_callback_f callback, ntrackpointer user_data); - -int* -_ntrack_arch_get_rfds (ntrack_monitor_t *self); - -int -_ntrack_arch_process_data (ntrackpointer self, int* fds); - -void -_ntrack_arch_free (ntrackpointer self); - NTRACK_END_DECLS #endif === modified file 'modules/ntrack-libnl.c' --- a/modules/ntrack-libnl.c 2010-12-20 00:23:43 +0000 +++ b/modules/ntrack-libnl.c 2011-05-19 22:06:40 +0000 @@ -1,11 +1,11 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* - * Copyright (C) 2009,2010 Alexander Sack + * Copyright (C) 2009-2011 Alexander Sack * * This file is part of: * ntrack - Network Status Tracking for Desktop Applications * http://launchpad.net/ntrack * * ntrack is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation, either version 3 of @@ -58,56 +58,60 @@ typedef struct nl_handle NTRACK_nl_handl cache_o = nl_cache_mngr_add (mngr, \ name, \ 0) #define NL_PRINT_ERROR(text,err) \ printf ("%s/%s\n", text, nl_geterror()) #define RTNL_ROUTE_GET_PRIO rtnl_route_get_prio -#else /* HAVE_LIBNL1 */ -#ifdef HAVE_LIBNL2 +#elif defined(HAVE_LIBNL2) || defined (HAVE_LIBNL3) + +/* define LIBNL1 name NL_DUMP_FULL as NL_DUMP_DETAILS */ +#define NL_DUMP_FULL NL_DUMP_DETAILS + typedef struct nl_sock NTRACK_nl_handle; #define NL_CACHE_MNGR_ALLOC(handle,mngr_o) \ nl_cache_mngr_alloc (handle, NETLINK_ROUTE, NL_AUTO_PROVIDE, &mngr_o) #define NL_CACHE_MNGR_ADD(mngr,name,cache_o) \ nl_cache_mngr_add (mngr, \ name, \ 0, \ + 0, \ &cache_o) #define NL_PRINT_ERROR(text,err) \ printf ("%s/%s\n", text, nl_geterror(err)) #define RTNL_ROUTE_GET_PRIO rtnl_route_get_priority #else #error no LIBNLx found -#endif /* HAVE_LIBNL2 */ #endif /* HAVE_LIBNL1 */ struct _nl_info { NTRACK_nl_handle *handle; NTRACK_nl_handle *smart_update_handle; struct nl_cache_mngr *update_cache_mngr; struct nl_cache_mngr *smart_update_cache_mngr; struct nl_cache *route_cache; struct nl_cache *addr_cache; struct nl_cache *link_cache; + struct nl_cache *neigh_cache; struct rtnl_route *topmost_route; int update_run; }; static void -setup_main_handle (struct _nl_info *nl_info); +resetup_main_handle (struct _nl_info *nl_info); static void setup_smart_handle (struct _nl_info *nl_info); static int smart_cache_update (ntrack_monitor_t *self, ntrackpointer user_data); static int @@ -138,34 +142,17 @@ _ntrack_arch_new (ntrack_monitor_callbac /* setup ntrack_monitor_t part */ ((ntrack_monitor_t *)arch)->state = NTRACK_STATE_UNKNOWN; /* setup struct ntrack_monitor_arch part */ arch->data = nl_info; arch->cb = callback; arch->cb_user_data = user_data; -#ifdef HAVE_LIBNL1 - nl_info->handle = nl_handle_alloc(); - nl_info->smart_update_handle = nl_handle_alloc(); -#else -#ifdef HAVE_LIBNL2 - nl_info->handle = nl_socket_alloc(); - nl_info->smart_update_handle = nl_socket_alloc(); -#else -#error "needs libnl-1 or -2.0" -#endif -#endif - if (!nl_info->handle) - error (1, 255, "OOM (nl_handle_alloc)"); - - if (!nl_info->smart_update_handle) - error (1, 257, "OOM (nl_handle_alloc)"); - - setup_main_handle (nl_info); + resetup_main_handle (nl_info); setup_smart_handle (nl_info); /* set smart update handle to nonblocking */ if (nl_socket_set_nonblocking (nl_info->smart_update_handle)) error (1,260,"cannot set smart handle to nonblocking"); update_caches (nl_info); update_connectivity ((ntrack_monitor_t *) arch, nl_info); @@ -199,19 +186,18 @@ _ntrack_arch_process_data (ntrackpointer int rval = nl_cache_mngr_data_ready (nl_info->smart_update_cache_mngr); /* * if all looks good and there was relevant data for the managed * caches then we attempt a smart cache update. This will flush * our caches and reinterpret the new state and emit events * as appropriate. */ - if(rval) - if (!smart_cache_update (self, nl_info)) - return -1; + if (!smart_cache_update (self, nl_info)) + return -1; return rval; } void _ntrack_arch_free (ntrackpointer self) { struct _ntrack_monitor_arch *arch = self; struct _nl_info *nl_info = arch->data; @@ -227,43 +213,77 @@ _ntrack_arch_free (ntrackpointer self) if (nl_info->handle) nl_close (nl_info->handle); free (nl_info); free (self); } static void -setup_main_handle (struct _nl_info *nl_info) +resetup_main_handle (struct _nl_info *nl_info) { - NL_CACHE_MNGR_ALLOC (nl_info->handle, nl_info->update_cache_mngr); +#ifdef HAVE_LIBNL1 + if (nl_info->handle) + nl_handle_destroy (nl_info->handle); + nl_info->handle = nl_handle_alloc(); +#elif defined(HAVE_LIBNL2) || defined(HAVE_LIBNL3) + if (nl_info->handle) + nl_socket_free (nl_info->handle); + nl_info->handle = nl_socket_alloc(); +#else +#error "needs libnl-1 or -2.0" +#endif + if (!nl_info->handle) + error (1, 255, "OOM (nl_handle_alloc)"); - if (!nl_info->addr_cache) { - NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/addr", nl_info->addr_cache); - if (!nl_info->addr_cache) - error (1, 366, "cache mngr add fail."); - } + if (nl_info->update_cache_mngr) + nl_cache_mngr_free (nl_info->update_cache_mngr); - if (!nl_info->link_cache) { - NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/link", nl_info->link_cache); - if (!nl_info->link_cache) - error (1, 367, "cache mngr add fail."); - } + NL_CACHE_MNGR_ALLOC (nl_info->handle, nl_info->update_cache_mngr); - if (!nl_info->route_cache) { - NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/route", nl_info->route_cache); - if (!nl_info->route_cache) - error (1, 368, "cache mngr add fail."); - } + NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/addr", nl_info->addr_cache); + if (!nl_info->addr_cache) + error (1, 366, "cache mngr add fail."); + + NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/link", nl_info->link_cache); + if (!nl_info->link_cache) + error (1, 367, "cache mngr add fail."); + + NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/route", nl_info->route_cache); + if (!nl_info->route_cache) + error (1, 368, "cache mngr add fail."); + + NL_CACHE_MNGR_ADD (nl_info->update_cache_mngr, "route/neigh", nl_info->neigh_cache); + if (!nl_info->neigh_cache) + error (1, 369, "cache mngr add fail."); } static void setup_smart_handle (struct _nl_info *nl_info) { struct nl_cache *tmp_cache = 0; + +#ifdef HAVE_LIBNL1 + if (nl_info->smart_update_handle) { + nl_close (nl_info->smart_update_handle); + nl_handle_destroy (nl_info->smart_update_handle); + } + nl_info->smart_update_handle = nl_handle_alloc(); +#elif defined(HAVE_LIBNL2) || defined(HAVE_LIBNL3) + if (nl_info->smart_update_handle) { + nl_close (nl_info->smart_update_handle); + nl_socket_free (nl_info->smart_update_handle); + } + nl_info->smart_update_handle = nl_socket_alloc(); +#else +#error "needs libnl-1 or -2.0" +#endif + if (!nl_info->smart_update_handle) + error (1, 257, "OOM (nl_handle_alloc)"); + NL_CACHE_MNGR_ALLOC (nl_info->smart_update_handle, nl_info->smart_update_cache_mngr); if (!nl_info->smart_update_cache_mngr) error (1, 265, "cache mngr alloc failed"); /* add caches for events we are interested in. We * don't need to remember them as we are solely * interested on whether something of relevance for @@ -283,16 +303,22 @@ setup_smart_handle (struct _nl_info *nl_ if (!tmp_cache) error (1, 267, "cache mngr add fail."); tmp_cache = 0; NL_CACHE_MNGR_ADD (nl_info->smart_update_cache_mngr, "route/route", tmp_cache); if (!tmp_cache) error (1, 268, "cache mngr add fail."); + + tmp_cache = 0; + NL_CACHE_MNGR_ADD (nl_info->smart_update_cache_mngr, "route/neigh", tmp_cache); + + if (!tmp_cache) + error (1, 269, "cache mngr add fail."); } static int smart_cache_update (ntrack_monitor_t *self, ntrackpointer user_data) { struct _nl_info *nl_info = user_data; @@ -379,28 +405,32 @@ get_nl_link_by_index (ntrack_monitor_t * struct rtnl_link *link = i->data; if (rtnl_link_get_ifindex(link) == iindex) { result = link; break; } if (rtnl_link_get_ifindex(link) > iindex) break; i = i->next; + + if (i == linklist) + break; } return result; } static void update_connectivity (ntrack_monitor_t *self, struct _nl_info *nl_info) { struct rtnl_route *topmost_route = NULL; struct rtnl_route *filter_route = rtnl_route_alloc (); struct nl_addr *dst_filter = nl_addr_alloc (0); struct nl_object *iter; ntrack_list_t *link_list = NULL; + struct rtnl_link *iter_link = NULL; /* fill link info */ iter = nl_cache_get_first (nl_info->link_cache); while (iter) { link_list = ntrack_list_insert_sorted (link_list, iter, nl_link_index_cmp); nl_object_get (iter); iter = nl_cache_get_next (iter); } @@ -408,45 +438,42 @@ update_connectivity (ntrack_monitor_t *s /* get topmost route with link that has is up and has carrier */ nl_addr_set_family (dst_filter, AF_INET); nl_addr_set_binary_addr (dst_filter, "\0", 0); nl_addr_set_prefixlen (dst_filter, 0); rtnl_route_set_dst (filter_route, dst_filter); iter = nl_cache_get_first (nl_info->route_cache); while (iter) { - struct rtnl_link *iter_link; -#ifdef HAVE_LIBNL2 +#if defined(HAVE_LIBNL2) || defined(HAVE_LIBNL3) struct rtnl_nexthop *nexth=0; int nhops=0; #endif if (!nl_object_match_filter (iter, OBJ_CAST(filter_route))) goto next; -#ifdef HAVE_LIBNL2 +#if defined(HAVE_LIBNL2) || defined(HAVE_LIBNL3) nhops = rtnl_route_get_nnexthops ((struct rtnl_route*) iter); if (nhops > 0) nexth = rtnl_route_nexthop_n ((struct rtnl_route*) iter, 0); iter_link = get_nl_link_by_index (self, link_list, rtnl_route_nh_get_ifindex (nexth)); -#else -#ifdef HAVE_LIBNL1 +#elif defined(HAVE_LIBNL1) iter_link = get_nl_link_by_index (self, link_list, rtnl_route_get_oif ((struct rtnl_route*) iter)); #else #error "no libnl" #endif -#endif /* if we dont have a link for the current oif, * this is not a valid topmost_route */ if (!iter_link) goto next; /* if new route is lower than the current topmost, continue */ - if (topmost_route && cmp_rtnl_route_metric (topmost_route, iter) <= 0) + if (topmost_route && (cmp_rtnl_route_metric (topmost_route, iter) <= 0 && iter_link != NULL)) goto next; /* if the link of the potential new topmost route is up, we replace the current topmost_route */ if (rtnl_link_get_flags (iter_link) & IFF_LOWER_UP) { /* release ref to current last topmost_route */ if (topmost_route) nl_object_put (OBJ_CAST(topmost_route)); @@ -508,8 +535,23 @@ update_connectivity (ntrack_monitor_t *s op_default_route_disappeared ((struct _ntrack_monitor_arch*) self, nl_info); } /* set to update_run mode so we dont signal disappear if no topmost_route * exists and nothing changed */ if (!nl_info->update_run) nl_info->update_run = TRUE; } +struct _ntrack_module_functions module_funcs = { + _ntrack_arch_new, + _ntrack_arch_get_rfds, + _ntrack_arch_process_data, + _ntrack_arch_free +}; + +#ifdef HAVE_LIBNL1 +NTRACK_MODULE_DEFINE("libnl1", "libnl v1", &module_funcs) +#elif defined(HAVE_LIBNL2) +NTRACK_MODULE_DEFINE("libnl2", "libnl v2", &module_funcs) +#elif defined(HAVE_LIBNL3) +NTRACK_MODULE_DEFINE("libnl3", "libnl v3", &module_funcs) +#endif +