diff --git a/src/chain.c b/src/chain.c
index e0b1eaf6d73bc..c7026f486b104 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -217,21 +217,11 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
 
 	switch(attr) {
 	case NFTNL_CHAIN_NAME:
-		if (c->flags & (1 << NFTNL_CHAIN_NAME))
-			xfree(c->name);
-
-		c->name = strdup(data);
-		if (!c->name)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&c->name, &c->flags,
+					  attr, data, data_len);
 	case NFTNL_CHAIN_TABLE:
-		if (c->flags & (1 << NFTNL_CHAIN_TABLE))
-			xfree(c->table);
-
-		c->table = strdup(data);
-		if (!c->table)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&c->table, &c->flags,
+					  attr, data, data_len);
 	case NFTNL_CHAIN_HOOKNUM:
 		memcpy(&c->hooknum, data, sizeof(c->hooknum));
 		break;
@@ -257,21 +247,11 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr,
 		memcpy(&c->family, data, sizeof(c->family));
 		break;
 	case NFTNL_CHAIN_TYPE:
-		if (c->flags & (1 << NFTNL_CHAIN_TYPE))
-			xfree(c->type);
-
-		c->type = strdup(data);
-		if (!c->type)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&c->type, &c->flags,
+					  attr, data, data_len);
 	case NFTNL_CHAIN_DEV:
-		if (c->flags & (1 << NFTNL_CHAIN_DEV))
-			xfree(c->dev);
-
-		c->dev = strdup(data);
-		if (!c->dev)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&c->dev, &c->flags,
+					  attr, data, data_len);
 	case NFTNL_CHAIN_DEVICES:
 		dev_array = (const char **)data;
 		while (dev_array[len] != NULL)
diff --git a/src/flowtable.c b/src/flowtable.c
index 2f37cd4c7f04a..41a1456bb19b2 100644
--- a/src/flowtable.c
+++ b/src/flowtable.c
@@ -119,20 +119,11 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *c, uint16_t attr,
 
 	switch(attr) {
 	case NFTNL_FLOWTABLE_NAME:
-		if (c->flags & (1 << NFTNL_FLOWTABLE_NAME))
-			xfree(c->name);
-
-		c->name = strdup(data);
-		if (!c->name)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&c->name, &c->flags,
+					  attr, data, data_len);
 	case NFTNL_FLOWTABLE_TABLE:
-		if (c->flags & (1 << NFTNL_FLOWTABLE_TABLE))
-			xfree(c->table);
-
-		c->table = strdup(data);
-		if (!c->table)
-			return -1;
+		return nftnl_set_str_attr(&c->table, &c->flags,
+					  attr, data, data_len);
 		break;
 	case NFTNL_FLOWTABLE_HOOKNUM:
 		memcpy(&c->hooknum, data, sizeof(c->hooknum));
diff --git a/src/object.c b/src/object.c
index 2ddaa29cda0be..19cb7d0dbf73d 100644
--- a/src/object.c
+++ b/src/object.c
@@ -113,17 +113,12 @@ int nftnl_obj_set_data(struct nftnl_obj *obj, uint16_t attr,
 
 	switch (attr) {
 	case NFTNL_OBJ_TABLE:
-		xfree(obj->table);
-		obj->table = strdup(data);
-		if (!obj->table)
-			return -1;
+		return nftnl_set_str_attr(&obj->table, &obj->flags,
+					  attr, data, data_len);
 		break;
 	case NFTNL_OBJ_NAME:
-		xfree(obj->name);
-		obj->name = strdup(data);
-		if (!obj->name)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&obj->name, &obj->flags,
+					  attr, data, data_len);
 	case NFTNL_OBJ_TYPE:
 		obj->ops = nftnl_obj_ops_lookup(*((uint32_t *)data));
 		if (!obj->ops)
diff --git a/src/rule.c b/src/rule.c
index a52012b2177bb..e16e2c1aa5bf8 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -115,21 +115,11 @@ int nftnl_rule_set_data(struct nftnl_rule *r, uint16_t attr,
 
 	switch(attr) {
 	case NFTNL_RULE_TABLE:
-		if (r->flags & (1 << NFTNL_RULE_TABLE))
-			xfree(r->table);
-
-		r->table = strdup(data);
-		if (!r->table)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&r->table, &r->flags,
+					  attr, data, data_len);
 	case NFTNL_RULE_CHAIN:
-		if (r->flags & (1 << NFTNL_RULE_CHAIN))
-			xfree(r->chain);
-
-		r->chain = strdup(data);
-		if (!r->chain)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&r->chain, &r->flags,
+					  attr, data, data_len);
 	case NFTNL_RULE_HANDLE:
 		memcpy(&r->handle, data, sizeof(r->handle));
 		break;
diff --git a/src/set.c b/src/set.c
index a732bc032267a..07e332dcd6732 100644
--- a/src/set.c
+++ b/src/set.c
@@ -146,21 +146,11 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data,
 
 	switch(attr) {
 	case NFTNL_SET_TABLE:
-		if (s->flags & (1 << NFTNL_SET_TABLE))
-			xfree(s->table);
-
-		s->table = strdup(data);
-		if (!s->table)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&s->table, &s->flags,
+					  attr, data, data_len);
 	case NFTNL_SET_NAME:
-		if (s->flags & (1 << NFTNL_SET_NAME))
-			xfree(s->name);
-
-		s->name = strdup(data);
-		if (!s->name)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&s->name, &s->flags,
+					  attr, data, data_len);
 	case NFTNL_SET_HANDLE:
 		memcpy(&s->handle, data, sizeof(s->handle));
 		break;
diff --git a/src/table.c b/src/table.c
index 4f48e8c9e73e1..13f01cfbf1e6f 100644
--- a/src/table.c
+++ b/src/table.c
@@ -101,13 +101,8 @@ int nftnl_table_set_data(struct nftnl_table *t, uint16_t attr,
 
 	switch (attr) {
 	case NFTNL_TABLE_NAME:
-		if (t->flags & (1 << NFTNL_TABLE_NAME))
-			xfree(t->name);
-
-		t->name = strdup(data);
-		if (!t->name)
-			return -1;
-		break;
+		return nftnl_set_str_attr(&t->name, &t->flags,
+					  attr, data, data_len);
 	case NFTNL_TABLE_HANDLE:
 		memcpy(&t->handle, data, sizeof(t->handle));
 		break;
diff --git a/src/utils.c b/src/utils.c
index ffbad89a0dade..2f1ffd6227583 100644
--- a/src/utils.c
+++ b/src/utils.c
@@ -136,3 +136,17 @@ void __noreturn __abi_breakage(const char *file, int line, const char *reason)
 		       "%s:%d reason: %s\n", file, line, reason);
        exit(EXIT_FAILURE);
 }
+
+int nftnl_set_str_attr(const char **dptr, uint32_t *flags,
+		       uint16_t attr, const void *data, uint32_t data_len)
+{
+	if (*flags & (1 << attr))
+		xfree(*dptr);
+
+	*dptr = strndup(data, data_len);
+	if (!*dptr)
+		return -1;
+
+	*flags |= (1 << attr);
+	return 0;
+}
