thom311 / libnl

Netlink Library Suite
GNU Lesser General Public License v2.1
423 stars 311 forks source link

lib: object: Rectify attribute mask logic in 'nl_object_compare()' #321

Closed voldymyr closed 2 years ago

voldymyr commented 2 years ago

Setting of the attribute mask could be narrowed down to two cases:

1. Object possesses either or both 'oo_id_attrs_get' and
'oo_id_attrs'
2. Object lacks both 'oo_id_attrs_get' and 'oo_id_attrs'

In the primary case, one would expect to set, for upcoming comparison, objects 'ce_mask', to already pre-set required attributes. This would enable comparison of required attributes together with those set in the object's 'ce_mask', if such exist.

In the secondary case, with no required attributes in place and 64bit mask used instead, one would expect to set object's 'ce_mask' and exclude all other bits. This would enable comparison of only those attributes defined in the object's 'ce_mask'.

This patch takes care of the above mentioned cases, while previous behavior would neglect the primary case and never actually compare any attributes set in the object's 'ce_mask', except the required.

Signed-off-by: Volodymyr Bendiuga volodymyr.bendiuga@westermo.com

thom311 commented 2 years ago

in other words...

we have primary key attributes (req_attrs_a + req_attrs_b) which are used for comparing the ID of two objects.

Usually, we'd expect that both objects need all key attributes set. Then &= a->ce_mask has no effect, and we proceed to compare all the key attributes.

In the case where the object has some key attributes unset, we still need to do something. Maybe such an incomplete object should never compare identical to another object. However, instead, even such an incomplete object can still compare identical to another object b, if-and-only-if that other object

That is what &= a->ce_mask accomplishes.

There is a small twist, that with req_attrs_a = ops->oo_id_attrs_get(a), the key attributes can depend on the object itself. So we also require that the set of key attributes is the same if (req_attrs_a != req_attrs_b) return 0;.