Skip to content

Commit

Permalink
lib: merge branch 'th/object-identical-fix'
Browse files Browse the repository at this point in the history
  • Loading branch information
thom311 committed Apr 17, 2020
2 parents 8637c70 + 36b0894 commit ab015e1
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
7 changes: 7 additions & 0 deletions include/netlink/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,13 @@ enum {
NL_CAPABILITY_VERSION_3_5_0 = 30,
#define NL_CAPABILITY_VERSION_3_5_0 NL_CAPABILITY_VERSION_3_5_0

/**
* nl_object_identical() can consider objects identical, if they both lack the same
* set of ID attributes.
*/
NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL = 31,
#define NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL

__NL_CAPABILITY_MAX,
NL_CAPABILITY_MAX = (__NL_CAPABILITY_MAX - 1),
#define NL_CAPABILITY_MAX NL_CAPABILITY_MAX
Expand Down
43 changes: 23 additions & 20 deletions lib/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,39 +306,42 @@ void nl_object_dump_buf(struct nl_object *obj, char *buf, size_t len)
*/
int nl_object_identical(struct nl_object *a, struct nl_object *b)
{
struct nl_object_ops *ops = obj_ops(a);
uint32_t req_attrs;
struct nl_object_ops *ops;
uint64_t req_attrs_a;
uint64_t req_attrs_b;

if (a == b)
return 1;

/* Both objects must be of same type */
ops = obj_ops(a);
if (ops != obj_ops(b))
return 0;

if (ops->oo_id_attrs_get) {
uint32_t req_attrs_a = ops->oo_id_attrs_get(a);
uint32_t req_attrs_b = ops->oo_id_attrs_get(b);
/* Can't judge unless we can compare */
if (ops->oo_compare == NULL)
return 0;

if (req_attrs_a != req_attrs_b)
return 0;
req_attrs = req_attrs_a;
if (ops->oo_id_attrs_get) {
req_attrs_a = ops->oo_id_attrs_get(a);
req_attrs_b = ops->oo_id_attrs_get(b);
} else if (ops->oo_id_attrs) {
req_attrs = ops->oo_id_attrs;
req_attrs_a = ops->oo_id_attrs;
req_attrs_b = req_attrs_a;
} else {
req_attrs = 0xFFFFFFFF;
req_attrs_a = UINT64_MAX;
req_attrs_b = req_attrs_a;
}
if (req_attrs == 0xFFFFFFFF)
req_attrs = a->ce_mask & b->ce_mask;

req_attrs_a &= a->ce_mask;
req_attrs_b &= b->ce_mask;

/* Both objects must provide all required attributes to uniquely
* identify an object */
if ((a->ce_mask & req_attrs) != req_attrs ||
(b->ce_mask & req_attrs) != req_attrs)
return 0;

/* Can't judge unless we can compare */
if (ops->oo_compare == NULL)
if (req_attrs_a != req_attrs_b)
return 0;

return !(ops->oo_compare(a, b, req_attrs, ID_COMPARISON));
return !(ops->oo_compare(a, b, req_attrs_a, ID_COMPARISON));
}

/**
Expand All @@ -360,7 +363,7 @@ uint64_t nl_object_diff64(struct nl_object *a, struct nl_object *b)
if (ops != obj_ops(b) || ops->oo_compare == NULL)
return UINT64_MAX;

return ops->oo_compare(a, b, ~0, 0);
return ops->oo_compare(a, b, UINT64_MAX, 0);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion lib/utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ int nl_has_capability (int capability)
NL_CAPABILITY_VERSION_3_4_0,
NL_CAPABILITY_ROUTE_FIX_VLAN_SET_EGRESS_MAP,
NL_CAPABILITY_VERSION_3_5_0,
0,
NL_CAPABILITY_NL_OBJECT_IDENTICAL_PARTIAL,
0),
/* IMPORTANT: these capability numbers are intended to be universal and stable
* for libnl3. Don't allocate new numbers on your own that differ from upstream
Expand Down

0 comments on commit ab015e1

Please sign in to comment.