This is using standard ietf-interfaces.yang and ietf-ip.yang models.
Since ConfD-7.3.1 and up-to ConfD-7.4.1 the same code fails with:
TRACE CDB_GET /if:interfaces/interface{GigabitEthernet0/3/0}/ip:ipv4/address{10.0.1.1}/prefix-length
DEBUG badly formatted or nonexistent path - Bad tag value 1266954393 after : /interfaces/interface/ipv4
--> CONFD_ERR
Looking at the 7.3.1 CHANGES, the following might have introduced the regression:
confd: The id-values associated with each element in a data model are
now localized to each namespace to avoid conflicts between the loaded
data models.
(ENG-22839)
I suspect the issue occures when the keypath contains elements from two different namespaces, in this case if:interfaces and ip:ipv4.
Thank you all your active support and help. the issue is finally resolved.
all the new managed objects from the new yang files started showing up after i ran “show configuration mo” and after that all the commands were returning proper information. not sure what difference this caused but now it’s all working fine.
To file a ConfD issue with Tail-f support you need a ConfD license to get access to the RT support tool.
mk_kp_str() is a suggested alternative DIY solution.
static void mk_kp_str(char *kp_str, int bufsiz, confd_hkeypath_t *keypath)
{
int kp_len = keypath->len - 1;
confd_value_t *v = &(keypath->v[keypath->len - 1][0]);
int i, j, k, kp_strlen = 0;
char tmpbuf[confd_maxkeylen][BUFSIZ];
struct confd_cs_node *cs_node;
struct confd_type *type;
u_int64_t pseudo_key = -1;
for(i = kp_len; i >= 0; i--) {
v = &(keypath->v[i][0]);
if (v->type == C_XMLTAG) {
confd_format_keypath(&kp_str[kp_strlen], bufsiz - kp_strlen, "/%s:%x", confd_ns2prefix(v->val.xmltag.ns), v);
} else {
cs_node = confd_cs_node_cd(NULL, &kp_str[0]);
if (cs_node->info.flags & CS_NODE_IS_LEAF_LIST) {
type = confd_get_leaf_list_type(cs_node);
} else {
cs_node = cs_node->children;
type = cs_node->info.type;
}
if (cs_node->parent->info.keys == NULL && cs_node->parent->info.flags & CS_NODE_IS_LIST) {
/* keyless list - get the pseudo key */
pseudo_key = CONFD_GET_INT64(&(keypath->v[i][0]));
snprintf(&(tmpbuf[0][0]), BUFSIZ, "%ld", pseudo_key);
j = 1;
} else {
for (j = 0; keypath->v[i][j].type != C_NOEXISTS; j++) {
confd_val2str(type, &(keypath->v[i][j]), &(tmpbuf[j][0]), BUFSIZ);
if ((cs_node->info.flags & CS_NODE_IS_LEAF_LIST) == 0 && cs_node->next != NULL) {
cs_node = cs_node->next;
type = cs_node->info.type;
}
}
}
strcpy(&kp_str[kp_strlen], "{"); kp_strlen++;
for (k = 0; k < j; k++) {
snprintf(&kp_str[kp_strlen], bufsiz - kp_strlen, "%s ", &(tmpbuf[k][0]));
kp_strlen = strlen(kp_str);
}
strcpy(&kp_str[kp_strlen - 1], "}");
}
kp_strlen = strlen(kp_str);
}
}
Thanks for clarification @cohult!
I have a few questions:
Doesn’t confd_pp_kpath() achieve the same as your DIY solution?
It seems like your DIY solution was available for a while. Does this mean this was a known issue since 7.3.1?
If the answer to previous question was yes, a bug must have already been filed in the tracker. Would you mind providing it here, so I know what to look for in the CHANGELOG
confd_pp_kpath() does not do type independent mapping, so if for example an enum or identityref is used as a key for a list, confd_pp_kpath() will not translate it from value to string. confd_val2str() will do that and is therfore used in the mk_kp_str() solution.
No. See above + there was a need to change the namespace of the keypath for that use case. You should always use the DIY mk_kp_str() solution if your keypath can contain list keys of type enum or identityref.
See the confd_types(3) man page under USING SCHEMA INFORMATION for details.