Skip to content

Commit

Permalink
Merge pull request #399 from mtomaschewski/bnc889981
Browse files Browse the repository at this point in the history
address: enable events and expose flags (partial bnc#889981)
  • Loading branch information
mtomaschewski committed Sep 3, 2014
2 parents 2454fd7 + 22f04e9 commit 0e7880b
Show file tree
Hide file tree
Showing 10 changed files with 182 additions and 49 deletions.
13 changes: 6 additions & 7 deletions client/ifstatus.c
Expand Up @@ -329,18 +329,17 @@ ni_ifstatus_show_addrs(const ni_netdev_t *dev, ni_bool_t verbose)
ni_address_t *ap;

for (ap = dev->addrs; ap; ap = ap->next) {
if (ni_address_is_duplicate(ap))
continue;
if (ni_address_is_deprecated(ap))
if (!ni_sockaddr_is_specified(&ap->local_addr))
continue;
if (ni_address_is_linklocal(ap) && !verbose)
continue;
if (!ni_sockaddr_is_specified(&ap->local_addr))
continue;

if_printf("", "addr:", "%s %s/%u",
ni_address_format_flags(&buf, ap->family, ap->flags, "|");
if_printf("", "addr:", "%s %s/%u%s%s",
ni_addrfamily_type_to_name(ap->family),
ni_sockaddr_print(&ap->local_addr), ap->prefixlen);
ni_sockaddr_print(&ap->local_addr), ap->prefixlen,
buf.string ? " " : "", buf.string ? buf.string : "");
ni_stringbuf_destroy(&buf);

if (verbose) {
if (ap->family == AF_INET) {
Expand Down
24 changes: 8 additions & 16 deletions dhcp6/device.c
Expand Up @@ -1125,6 +1125,13 @@ ni_dhcp6_device_event(ni_dhcp6_device_t *dev, ni_netdev_t *ifp, ni_event_t event
}
break;

case NI_EVENT_DEVICE_CHANGE:
if (dev->config && dev->config->mode == NI_DHCP6_MODE_AUTO) {
ni_dhcp6_device_update_mode(dev, ifp);
ni_dhcp6_device_start(dev);
}
break;

default:
ni_debug_dhcp("%s: received other event", dev->ifname);
break;
Expand Down Expand Up @@ -1170,22 +1177,7 @@ void
ni_dhcp6_prefix_event(ni_dhcp6_device_t *dev, ni_netdev_t *ifp, ni_event_t event,
const ni_ipv6_ra_pinfo_t *pi)
{
ni_ipv6_devinfo_t *ipv6;

ipv6 = ni_netdev_get_ipv6(ifp);
if (ipv6 == NULL)
return;

ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_EVENTS,
"%s: %s RA<%s> Prefix<%s/%u %s,%s> [%d,%d]", dev->ifname,
(event == NI_EVENT_PREFIX_UPDATE ? "update" : "delete"),
(ipv6->radv.managed_addr ? "managed-address" :
(ipv6->radv.other_config ? "managed-config" : "unmanaged")),
ni_sockaddr_print(&pi->prefix), pi->length,
(pi->on_link ? "onlink" : "not-onlink"),
(pi->autoconf ? "autoconf" : "no-autoconf"),
pi->lifetime.preferred_lft, pi->lifetime.valid_lft);

ni_server_trace_interface_prefix_events(ifp, event, pi);
switch (event) {
case NI_EVENT_PREFIX_UPDATE:
if (dev->config && dev->config->mode == NI_DHCP6_MODE_AUTO) {
Expand Down
1 change: 1 addition & 0 deletions dhcp6/main.c
Expand Up @@ -547,6 +547,7 @@ dhcp6_interface_event(ni_netdev_t *ifp, ni_event_t event)
dhcp6_device_destroy(dhcp6_dbus_server, ifp);
break;

case NI_EVENT_DEVICE_CHANGE:
case NI_EVENT_DEVICE_DOWN:
case NI_EVENT_DEVICE_UP:
case NI_EVENT_NETWORK_DOWN:
Expand Down
3 changes: 2 additions & 1 deletion include/wicked/address.h
Expand Up @@ -93,11 +93,12 @@ extern unsigned int ni_af_address_prefixlen(int af);
extern ni_address_t * ni_address_new(int af, unsigned int prefix_len,
const ni_sockaddr_t *local_addr,
ni_address_t **list);
extern void ni_address_free(ni_address_t *);
extern const char * ni_address_format_flags(ni_stringbuf_t *, unsigned int, unsigned int, const char *);
extern void ni_address_list_append(ni_address_t **, ni_address_t *);
extern void ni_address_list_destroy(ni_address_t **);
extern void ni_address_list_dedup(ni_address_t **);
extern ni_address_t * ni_address_list_find(ni_address_t *, const ni_sockaddr_t *);
extern unsigned int ni_address_list_count(ni_address_t *list);
extern void ni_address_free(ni_address_t *);

#endif /* __WICKED_ADDRESS_H__ */
3 changes: 3 additions & 0 deletions include/wicked/netinfo.h
Expand Up @@ -119,6 +119,9 @@ extern int ni_server_enable_interface_addr_events(void (*handler)(ni_netdev_t *
extern int ni_server_enable_interface_prefix_events(void (*handler)(ni_netdev_t *, ni_event_t, const ni_ipv6_ra_pinfo_t *));
extern int ni_server_enable_interface_nduseropt_events(void (*handler)(ni_netdev_t *, ni_event_t));
extern int ni_server_enable_interface_uevents(void);
extern void ni_server_trace_interface_addr_events(ni_netdev_t *, ni_event_t, const ni_address_t *);
extern void ni_server_trace_interface_prefix_events(ni_netdev_t *, ni_event_t, const ni_ipv6_ra_pinfo_t *);
extern void ni_server_trace_interface_nduseropt_events(ni_netdev_t *, ni_event_t);
extern void ni_server_deactivate_interface_events(void);
extern void ni_server_deactivate_interface_uevents(void);
extern ni_bool_t ni_server_listens_uevents(void);
Expand Down
4 changes: 4 additions & 0 deletions schema/interface.xml
Expand Up @@ -9,6 +9,10 @@
<peer type="network-address"/>
<anycast type="network-address"/>
<broadcast type="network-address"/>

<!-- currently raw flags -->
<flags type="uint32"/>
<!-- label is ipv4 only -->
<label type="string"/>

<cache-info class="dict">
Expand Down
27 changes: 27 additions & 0 deletions server/main.c
Expand Up @@ -85,6 +85,9 @@ static void run_interface_server(void);
static void discover_state(ni_dbus_server_t *);
static void recover_state(const char *filename);
static void handle_interface_event(ni_netdev_t *, ni_event_t);
static void handle_interface_addr_events(ni_netdev_t *, ni_event_t, const ni_address_t *);
static void handle_interface_prefix_events(ni_netdev_t *, ni_event_t, const ni_ipv6_ra_pinfo_t *);
static void handle_interface_nduseropt_events(ni_netdev_t *, ni_event_t);
static void handle_rfkill_event(ni_rfkill_type_t, ni_bool_t, void *);
static void handle_other_event(ni_event_t);
#ifdef MODEM
Expand Down Expand Up @@ -240,6 +243,12 @@ run_interface_server(void)
/* open global RTNL socket to listen for kernel events */
if (ni_server_listen_interface_events(handle_interface_event) < 0)
ni_fatal("unable to initialize netlink listener");
if (ni_server_enable_interface_addr_events(handle_interface_addr_events) < 0)
ni_fatal("unable to initialize netlink address listener");
if (ni_server_enable_interface_prefix_events(handle_interface_prefix_events) < 0)
ni_fatal("unable to initialize netlink prefix listener");
if (ni_server_enable_interface_nduseropt_events(handle_interface_nduseropt_events) < 0)
ni_fatal("unable to initialize netlink nduseropt listener");

if (ni_udev_net_subsystem_available()) {
if (ni_server_enable_interface_uevents() < 0)
Expand Down Expand Up @@ -421,6 +430,24 @@ handle_interface_event(ni_netdev_t *dev, ni_event_t event)
}
}

static void
handle_interface_addr_events(ni_netdev_t *dev, ni_event_t event, const ni_address_t *ap)
{
ni_server_trace_interface_addr_events(dev, event, ap);
}

static void
handle_interface_prefix_events(ni_netdev_t *dev, ni_event_t event, const ni_ipv6_ra_pinfo_t *pi)
{
ni_server_trace_interface_prefix_events(dev, event, pi);
}

static void
handle_interface_nduseropt_events(ni_netdev_t *dev, ni_event_t event)
{
ni_server_trace_interface_nduseropt_events(dev, event);
}

static void
handle_other_event(ni_event_t event)
{
Expand Down
56 changes: 56 additions & 0 deletions src/address.c
Expand Up @@ -24,6 +24,13 @@
#include <wicked/netinfo.h>
#include "util_priv.h"

#ifndef IFA_F_MANAGETEMPADDR
#define IFA_F_MANAGETEMPADDR 0x100
#endif
#ifndef IFA_F_NOPREFIXROUTE
#define IFA_F_NOPREFIXROUTE 0x200
#endif

#ifndef offsetof
# define offsetof(type, member) \
((unsigned long) &(((type *) NULL)->member))
Expand Down Expand Up @@ -68,6 +75,55 @@ ni_address_free(ni_address_t *ap)
free(ap);
}

static const ni_intmap_t __ni_address_ipv4_flag_map[] = {
{ "secondary", IFA_F_SECONDARY },
{ "permanent", IFA_F_PERMANENT },
{ "deprecated", IFA_F_DEPRECATED },
{ NULL, 0 }
};

static const ni_intmap_t __ni_address_ipv6_flag_map[] = {
{ "temporary", IFA_F_TEMPORARY },
{ "nodad", IFA_F_NODAD },
{ "optimistic", IFA_F_OPTIMISTIC },
{ "duplicate", IFA_F_DADFAILED },
{ "homeaddress", IFA_F_HOMEADDRESS },
{ "deprecated", IFA_F_DEPRECATED },
{ "tentative", IFA_F_TENTATIVE },
{ "permanent", IFA_F_PERMANENT },
{ "mngtmpaddr", IFA_F_MANAGETEMPADDR },
{ "noprefixroute", IFA_F_NOPREFIXROUTE },
{ NULL, 0 }
};

const char *
ni_address_format_flags(ni_stringbuf_t *buf, unsigned int family,
unsigned int flags, const char *sep)
{
const ni_intmap_t *map;
unsigned int i;

if (!buf)
return NULL;
switch (family) {
case AF_INET: map = __ni_address_ipv4_flag_map; break;
case AF_INET6: map = __ni_address_ipv6_flag_map; break;
default: return NULL;
}

if (ni_string_empty(sep))
sep = "|";

for (i = 0; map->name; ++map) {
if (flags & map->value) {
if (i++)
ni_stringbuf_puts(buf, sep);
ni_stringbuf_puts(buf, map->name);
}
}
return buf->string;
}

ni_bool_t
ni_address_is_loopback(const ni_address_t *laddr)
{
Expand Down
9 changes: 9 additions & 0 deletions src/dbus-objects/misc.c
Expand Up @@ -569,6 +569,10 @@ __ni_objectmodel_address_to_dict(const ni_address_t *ap, ni_dbus_variant_t *dict
__ni_objectmodel_dict_add_sockaddr(dict, "anycast", &ap->anycast_addr);
if (ap->bcast_addr.ss_family == ap->family)
__ni_objectmodel_dict_add_sockaddr(dict, "broadcast", &ap->bcast_addr);

if (ap->flags)
ni_dbus_dict_add_uint32(dict, "flags", ap->flags);

if (ap->family == AF_INET && ap->label)
ni_dbus_dict_add_string(dict, "label", ap->label);

Expand Down Expand Up @@ -607,6 +611,11 @@ __ni_objectmodel_address_from_dict(ni_address_t **list, const ni_dbus_variant_t
__ni_objectmodel_dict_get_sockaddr(dict, "anycast", &ap->anycast_addr);
__ni_objectmodel_dict_get_sockaddr(dict, "broadcast", &ap->bcast_addr);

/* Do we need to translate them and map to names?
* The usable flags differ between address families and
* ipv6 temporary flag is same bit as secondary in ipv4.
*/
ni_dbus_dict_get_uint32(dict, "flags", &ap->flags);
if (ap->family == AF_INET) {
if (ni_dbus_dict_get_string(dict, "label", &label))
ni_string_dup(&ap->label, label);
Expand Down
91 changes: 66 additions & 25 deletions src/ifevent.c
Expand Up @@ -370,16 +370,6 @@ __ni_rtevent_newprefix(ni_netconfig_t *nc, const struct sockaddr_nl *nladdr, str
free(pi);
return -1;
}
#if 0
ni_debug_verbose(NI_LOG_DEBUG3, NI_TRACE_EVENTS,
"%s: RA<%s>, Prefix<%s/%u %s,%s>[%u, %u]", dev->name,
(ipv6->radv.managed_addr ? "managed-address" :
(ipv6->radv.other_config ? "other-config" : "unmanaged")),
ni_sockaddr_print(&pi->prefix), pi->length,
(pi->on_link ? "onlink" : "not-onlink"),
(pi->autoconf ? "autoconf" : "no-autoconf"),
pi->lifetime.preferred_lft, pi->lifetime.valid_lft);
#endif

if ((old = ni_ipv6_ra_pinfo_list_remove(&ipv6->radv.pinfo, pi)) != NULL) {
if (pi->lifetime.valid_lft > 0) {
Expand Down Expand Up @@ -486,26 +476,12 @@ __ni_rtevent_process_rdnss_info(ni_netdev_t *dev, const struct nd_opt_hdr *opt,
ni_ipv6_ra_rdnss_reset(ipv6->radv.rdnss);

ipv6->radv.rdnss->lifetime = ntohl(rdnss->nd_opt_rdnss_lifetime);
if (ipv6->radv.rdnss->lifetime == 0xffffffff)
ni_debug_events("%s: rdnss lifetime: infinite", dev->name);
else
ni_debug_events("%s: rdnss lifetime: %u", dev->name,
ipv6->radv.rdnss->lifetime);

len -= sizeof(*rdnss);
addr = &rdnss->nd_opt_rdnss_addr[0];
for ( ; len >= sizeof(*addr); len -= sizeof(*addr), ++addr) {
if (IN6_IS_ADDR_LOOPBACK(addr) || IN6_IS_ADDR_UNSPECIFIED(addr))
continue;

ni_ipv6_ra_rdnss_add_server(ipv6->radv.rdnss, addr);

if (ni_log_facility(NI_TRACE_EVENTS)) {
const ni_sockaddr_array_t *addrs = &ipv6->radv.rdnss->addrs;

ni_debug_events("%s: rdnss address: %s", dev->name,
ni_sockaddr_print(&addrs->data[addrs->count-1]));
}
}
__ni_netdev_nduseropt_event(dev, NI_EVENT_RDNSS_UPDATE);
return 0;
Expand Down Expand Up @@ -544,7 +520,8 @@ __ni_rtevent_process_nd_radv_opts(ni_netdev_t *dev, const struct nd_opt_hdr *opt

default:
/* kernels up to at least 3.4 do not provide other */
ni_debug_events("%s: unhandled nd user option %d",
ni_debug_verbose(NI_LOG_DEBUG1, NI_TRACE_IPV6|NI_TRACE_EVENTS,
"%s: unhandled nd user option %d",
dev->name, opt->nd_opt_type);
break;
}
Expand Down Expand Up @@ -747,6 +724,20 @@ ni_server_listen_interface_events(void (*ifevent_handler)(ni_netdev_t *, ni_even
return 0;
}

void
ni_server_trace_interface_addr_events(ni_netdev_t *dev, ni_event_t event, const ni_address_t *ap)
{
ni_stringbuf_t flags = NI_STRINGBUF_INIT_DYNAMIC;

ni_address_format_flags(&flags, ap->family, ap->flags, NULL);
ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
"%s: %s event: %s flags[%u] %s",
dev->name, ni_event_type_to_name(event),
ni_sockaddr_prefix_print(&ap->local_addr, ap->prefixlen),
ap->flags, flags.string ? flags.string : "");
ni_stringbuf_destroy(&flags);
}

int
ni_server_enable_interface_addr_events(void (*ifaddr_handler)(ni_netdev_t *, ni_event_t, const ni_address_t *))
{
Expand All @@ -769,6 +760,20 @@ ni_server_enable_interface_addr_events(void (*ifaddr_handler)(ni_netdev_t *, ni_
return 0;
}

void
ni_server_trace_interface_prefix_events(ni_netdev_t *dev, ni_event_t event, const ni_ipv6_ra_pinfo_t *pi)
{
ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
"%s: %s IPv6 RA<%s> Prefix<%s/%u %s,%s>[%u, %u]", dev->name,
(event == NI_EVENT_PREFIX_UPDATE ? "update" : "delete"),
(dev->ipv6 && dev->ipv6->radv.managed_addr ? "managed" :
(dev->ipv6 && dev->ipv6->radv.other_config ? "config" : "unmanaged")),
ni_sockaddr_print(&pi->prefix), pi->length,
(pi->on_link ? "onlink" : "not-onlink"),
(pi->autoconf ? "autoconf" : "no-autoconf"),
pi->lifetime.preferred_lft, pi->lifetime.valid_lft);
}

int
ni_server_enable_interface_prefix_events(void (*ifprefix_handler)(ni_netdev_t *, ni_event_t, const ni_ipv6_ra_pinfo_t *))
{
Expand All @@ -784,6 +789,42 @@ ni_server_enable_interface_prefix_events(void (*ifprefix_handler)(ni_netdev_t *,
return 0;
}

void
ni_server_trace_interface_nduseropt_events(ni_netdev_t *dev, ni_event_t event)
{
ni_ipv6_devinfo_t *ipv6 = dev->ipv6;

if (!ni_debug_guard(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS))
return;

switch (event) {
case NI_EVENT_RDNSS_UPDATE:
if (ipv6 && ipv6->radv.rdnss && ipv6->radv.rdnss->addrs.count) {
char lifetime[32] = "infinite";
const char *rainfo;
unsigned int i;

rainfo = ipv6->radv.managed_addr ? "managed" :
ipv6->radv.other_config ? "config" : "unmanaged";
if (ipv6->radv.rdnss->lifetime != 0xffffffff) {
snprintf(lifetime, sizeof(lifetime), "%u",
ipv6->radv.rdnss->lifetime);
}
for (i = 0; i < ipv6->radv.rdnss->addrs.count; ++i) {
ni_trace("%s: update IPv6 RA<%s> RDNSS<%s>[%s]",
dev->name, rainfo,
ni_sockaddr_print(&ipv6->radv.rdnss->addrs.data[i]),
lifetime);
}
}
break;
default:
ni_debug_verbose(NI_LOG_DEBUG2, NI_TRACE_IPV6|NI_TRACE_EVENTS,
"%s: IPv6 RA %s event: ", dev->name, ni_event_type_to_name(event));
break;
}
}

int
ni_server_enable_interface_nduseropt_events(void (*ifnduseropt_handler)(ni_netdev_t *, ni_event_t))
{
Expand Down

0 comments on commit 0e7880b

Please sign in to comment.