static gboolean lldp_hash_table_equal (GHashTable *a, GHashTable *b) { GHashTableIter iter; gpointer val; g_return_val_if_fail (a, FALSE); g_return_val_if_fail (b, FALSE); if (g_hash_table_size (a) != g_hash_table_size (b)) return FALSE; g_hash_table_iter_init (&iter, a); while (g_hash_table_iter_next (&iter, NULL, &val)) { LLDPNeighbor *neigh_a, *neigh_b; neigh_a = val; neigh_b = g_hash_table_lookup (b, val); if (!neigh_b) return FALSE; if (!lldp_neighbor_equal (neigh_a, neigh_b)) return FALSE; } return TRUE; }
static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) { _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *old = NULL; bool keep; int r; assert(lldp); assert(n); assert(!n->lldp); keep = lldp_keep_neighbor(lldp, n); /* First retrieve the old entry for this MSAP */ old = hashmap_get(lldp->neighbor_by_id, &n->id); if (old) { sd_lldp_neighbor_ref(old); if (!keep) { lldp_neighbor_unlink(old); lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, old); return 0; } if (lldp_neighbor_equal(n, old)) { /* Is this equal, then restart the TTL counter, but don't do anyting else. */ lldp_start_timer(lldp, old); lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old); return 0; } /* Data changed, remove the old entry, and add a new one */ lldp_neighbor_unlink(old); } else if (!keep) return 0; /* Then, make room for at least one new neighbor */ lldp_make_space(lldp, 1); r = hashmap_put(lldp->neighbor_by_id, &n->id, n); if (r < 0) goto finish; r = prioq_put(lldp->neighbor_by_expiry, n, &n->prioq_idx); if (r < 0) { assert_se(hashmap_remove(lldp->neighbor_by_id, &n->id) == n); goto finish; } n->lldp = lldp; lldp_start_timer(lldp, n); lldp_callback(lldp, old ? SD_LLDP_EVENT_UPDATED : SD_LLDP_EVENT_ADDED, n); return 1; finish: if (old) lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, n); return r; }