Cdb_get "%h" pattern broken since 7.3

Not sure where to post ConfD bug reports, so posting it here:

In ConfD-7.3, the "%h" pattern used to to work with cdb_get():

cdb_get_u_int8 (sock, &len, "%h/prefix-length", kp)
TRACE CDB_GET /if:interfaces/interface{GigabitEthernet0/3/0}/ip:ipv4/address{10.0.1.1}/prefix-length --> CONFD_OK

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

While the following workaround works:

char buf[1024];
confd_pp_kpath (buf, sizeof buf, kp);
cdb_get_u_int8 (sock, &len, "%s/prefix-length", buf)

Note, the missing namespaces in the trace

TRACE CDB_GET /interfaces/interface{GigabitEthernet0/3/0}/ipv4/address{10.0.1.1}/prefix-length --> CONFD_OK

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.

You are right, this looks like a bug indeed. Can you report it, do you have a support account?

which bug do you mean? why others dont see the issue?

not sure how to report this. this is my individual account since i was doing my own project.

how can this be resolved ? any workaround ?

Thanks for the ACK @mvf! I don’t have a support account. And I don’t mind creating one, just don’t know how.
Hence posted the bug report here.

See

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.

@cohult, I am not sure I follow. Are you suggesting to file an issue in Confd-Demos repo? Or were you referring to mk_kp_str() as a workaround?

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:

  1. Doesn’t confd_pp_kpath() achieve the same as your DIY solution?
  2. It seems like your DIY solution was available for a while. Does this mean this was a known issue since 7.3.1?
  3. 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

Thanks!

I did not use confd_pp_kpath()

there is no bug as such, not sure why the data objects was not showing in cli

you can treat this issue as resolved. Thank you very much !!

@ruslan,

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.

Regards