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;
}
Exemple #2
0
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;
}