diff --git a/src/hostmngr.c b/src/hostmngr.c index c04dfc60a81636e1c8d25c3731919b41b61c98f0..eb24ae45d9f35b5b23ac8337e779790979995251 100644 --- a/src/hostmngr.c +++ b/src/hostmngr.c @@ -490,8 +490,10 @@ int hostmngr_get_neigh_hostname(struct neigh_queue *q, uint8_t *macaddr) return -1; ret = read_dhcpv4_lease_table(&entries, &num); - if (ret || num <= 0) - return -1; + if (ret || num <= 0) { + ret = -1; + goto out; + } dbg("%s: num-dhcphosts = %d\n", __func__, num); hosts = (struct dhcp_clients *)entries; @@ -503,6 +505,7 @@ int hostmngr_get_neigh_hostname(struct neigh_queue *q, uint8_t *macaddr) e->ipv4.family = AF_INET; e->leasetime = h->leasetime; e->ipv4_type_dhcp = 1; + e->ipv4_type_static = 0; ipn = neigh_ip_entry_lookup2(priv, &e->ipv4); if (ipn) { @@ -511,12 +514,24 @@ int hostmngr_get_neigh_hostname(struct neigh_queue *q, uint8_t *macaddr) dbg("Host " MACFMT " with ip = %s (0x%x) added to iptable\n", MAC2STR(e->macaddr), h->ipv4, e->ipv4.addr.ip4.s_addr); } + ret = 0; break; } } - free(entries); + +out: + /* if lease table has been consulted before with no results + * assume static IP address + */ + if (e->event_pending && !strlen(e->hostname)) { + e->ipv4_type_static = 1; + e->ipv4_type_dhcp = 0; + } + + if (entries) + free(entries); return ret; } diff --git a/src/neigh.c b/src/neigh.c index 9560dd725f98ac9b4cf36578d1585e3a1c8051d0..d100549064141b7d51e6dc803ab55c59def59658 100644 --- a/src/neigh.c +++ b/src/neigh.c @@ -830,6 +830,7 @@ void neigh_mark_reachable(void *nq, uint8_t *macaddr, const char *ifname) //struct neigh_history_entry *he = NULL; if (e->unreachable) { + hostmngr_get_neigh_hostname(q, macaddr); e->unreachable = 0; time(&e->lastchange); err("Marking " MACFMT " reachable through %s\n", @@ -837,7 +838,10 @@ void neigh_mark_reachable(void *nq, uint8_t *macaddr, const char *ifname) memset(e->ifname, 0, sizeof(e->ifname)); strncpy(e->ifname, ifname, strlen(ifname)); - hostmngr_host_event(priv, HOST_EVENT_CONNECT, e); + if (e->ipv4_type_static || strlen(e->hostname)) + hostmngr_host_event(priv, HOST_EVENT_CONNECT, e); + else + e->event_pending = 1; } /* he = neigh_history_lookup(nq, e->macaddr); @@ -1103,7 +1107,7 @@ void hostmngr_get_wifi_stations(struct hostmngr_private *priv, neigh_history_enqueue(priv, new, priv->cfg.history_ageout); - if (!ipaddr_is_zero(&new->ipv4) && (!new->ipv4_type_dhcp || strlen(new->hostname))) + if (!ipaddr_is_zero(&new->ipv4) && (new->ipv4_type_static || strlen(new->hostname))) hostmngr_host_event(priv, HOST_EVENT_CONNECT, new); else new->event_pending = 1; @@ -1187,7 +1191,9 @@ struct neigh_entry *neigh_enqueue(void *nq, uint8_t *macaddr, uint16_t state, if (ip) { /* can get overridden by dhcp lease entry */ if (ip->family == AF_INET) { - if (!ipaddr_equal(&e->ipv4, ip)) { + hostmngr_get_neigh_hostname(q, e->macaddr); + + if (!ipaddr_equal(&e->ipv4, ip) && (e->ipv4_type_static || strlen(e->hostname))) { memcpy(&e->ipv4, ip, sizeof(*ip)); e->event_pending = 0; hostmngr_host_event(priv, HOST_EVENT_CONNECT, e); diff --git a/src/neigh.h b/src/neigh.h index e9bf546652a06dc853782572aa5f34ab8bba8a93..2291f939870d9f514b9cb1a876cd41a5d35a5a03 100644 --- a/src/neigh.h +++ b/src/neigh.h @@ -74,6 +74,7 @@ struct neigh_entry { char hostname[256]; struct ip_address ipv4; /* from dhcp-lease table or neigh cache */ int ipv4_type_dhcp; /* set 1 when dhcp assigned ipv4 address */ + int ipv4_type_static; /* set 1 on statically assigned ipv4 address */ unsigned long leasetime; /* lease time() end if dhcp addresses */ struct list_head iflist; /* list of struct node_interface */ struct list_head iplist; /* list of struct ip_address_entry */ diff --git a/src/netlink.c b/src/netlink.c index c7cc29e1f92c01e66bf274a234043601a4c6755b..6c7e50717e0022d1ab273795bdb2518a41bdeda5 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -218,7 +218,11 @@ static int hostmngr_handle_neigh_tbl_change(struct hostmngr_private *priv, bool /* add/update history cache for this neigh */ neigh_history_enqueue(priv, new, priv->cfg.history_ageout); - hostmngr_host_event(priv, HOST_EVENT_CONNECT, new); + if (new->ipv4_type_static || strlen(new->hostname)) + hostmngr_host_event(priv, HOST_EVENT_CONNECT, new); + else + new->event_pending = 1; + } diff --git a/src/ubus.c b/src/ubus.c index 359b810b775f23bea4d1c41694e43903de15e396..6a5bfd040fceac4d050ca500c14ab5eea0761e36 100644 --- a/src/ubus.c +++ b/src/ubus.c @@ -426,7 +426,7 @@ static void hostmngr_1905topology_cb(struct ubus_request *req, int type, neigh_history_enqueue(priv, rn, priv->cfg.history_ageout); - if (!ipaddr_is_zero(&rn->ipv4) && (!rn->ipv4_type_dhcp || strlen(rn->hostname))) + if (!ipaddr_is_zero(&rn->ipv4) && (rn->ipv4_type_static || strlen(rn->hostname))) hostmngr_host_event(priv, HOST_EVENT_CONNECT, rn); else rn->event_pending = 1; @@ -1277,12 +1277,11 @@ static void hostmngr_wifi_sta_event_handler(struct hostmngr_private *p, if (new) { /* new wifi neigh added */ hostmngr_get_neigh_hostname(&p->neigh_q, macaddr); - /* add/update history cache for this neigh */ neigh_history_enqueue(p, new, p->cfg.history_ageout); - if (!ipaddr_is_zero(&new->ipv4) && (!new->ipv4_type_dhcp || strlen(new->hostname))) + if (!ipaddr_is_zero(&new->ipv4) && (new->ipv4_type_static || strlen(new->hostname))) hostmngr_host_event(p, HOST_EVENT_CONNECT, new); else new->event_pending = 1;