"Fossies" - the Fresh Open Source Software Archive

Member "gvm-libs-11.0.1/util/kb.h" (12 May 2020, 18618 Bytes) of package /linux/misc/openvas/gvm-libs-11.0.1.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "kb.h" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 10.0.1_vs_11.0.0.

    1 /* Copyright (C) 2014-2019 Greenbone Networks GmbH
    2  *
    3  * SPDX-License-Identifier: GPL-2.0-or-later
    4  *
    5  * This program is free software; you can redistribute it and/or
    6  * modify it under the terms of the GNU General Public License
    7  * as published by the Free Software Foundation; either version 2
    8  * of the License, or (at your option) any later version.
    9  *
   10  * This program is distributed in the hope that it will be useful,
   11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
   12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   13  * GNU General Public License for more details.
   14  *
   15  * You should have received a copy of the GNU General Public License
   16  * along with this program; if not, write to the Free Software
   17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   18  */
   19 
   20 /**
   21  * @file
   22  * @brief Knowledge base management API - Redis backend.
   23  */
   24 
   25 #ifndef _GVM_KB_H
   26 #define _GVM_KB_H
   27 
   28 #include "../base/nvti.h" /* for nvti_t */
   29 
   30 #include <assert.h>
   31 #include <stddef.h>    /* for NULL */
   32 #include <sys/types.h> /* for size_t */
   33 
   34 /**
   35  * @brief Default KB location.
   36  */
   37 #ifdef REDIS_SOCKET_PATH
   38 #define KB_PATH_DEFAULT REDIS_SOCKET_PATH
   39 #else
   40 #define KB_PATH_DEFAULT "/run/redis/redis.sock"
   41 #endif
   42 
   43 /**
   44  * @brief Possible type of a kb_item.
   45  */
   46 enum kb_item_type
   47 {
   48   KB_TYPE_UNSPEC, /**< Ignore the value (name/presence test).              */
   49   KB_TYPE_INT,    /**< The kb_items v should then be interpreted as int.   */
   50   KB_TYPE_STR,    /**< The kb_items v should then be interpreted as char*. */
   51   /* -- */
   52   KB_TYPE_CNT,
   53 };
   54 
   55 /**
   56  * @brief Possible positions of nvt values in cache list.
   57  */
   58 enum kb_nvt_pos
   59 {
   60   NVT_FILENAME_POS,
   61   NVT_REQUIRED_KEYS_POS,
   62   NVT_MANDATORY_KEYS_POS,
   63   NVT_EXCLUDED_KEYS_POS,
   64   NVT_REQUIRED_UDP_PORTS_POS,
   65   NVT_REQUIRED_PORTS_POS,
   66   NVT_DEPENDENCIES_POS,
   67   NVT_TAGS_POS,
   68   NVT_CVES_POS,
   69   NVT_BIDS_POS,
   70   NVT_XREFS_POS,
   71   NVT_CATEGORY_POS,
   72   NVT_TIMEOUT_POS,
   73   NVT_FAMILY_POS,
   74   NVT_NAME_POS,
   75   NVT_TIMESTAMP_POS,
   76   NVT_OID_POS,
   77 };
   78 
   79 /**
   80  * @brief Knowledge base item (defined by name, type (int/char*) and value).
   81  *        Implemented as a singly linked list
   82  */
   83 struct kb_item
   84 {
   85   enum kb_item_type type; /**< One of KB_TYPE_INT or KB_TYPE_STR. */
   86 
   87   union /**< Store a char or an int. */
   88   {
   89     char *v_str; /**< Hold an str value for this kb item. */
   90     int v_int;   /**< Hold an int value for this kb item. */
   91   };             /**< Value of this knowledge base item. */
   92 
   93   size_t len;           /**< Length of string. */
   94   struct kb_item *next; /**< Next item in list. */
   95 
   96   size_t namelen; /**< Name length (including final NULL byte). */
   97   char name[0];   /**< Name of this knowledge base item.  */
   98 };
   99 
  100 struct kb_operations;
  101 
  102 /**
  103  * @brief Top-level KB. This is to be inherited by KB implementations.
  104  */
  105 struct kb
  106 {
  107   const struct kb_operations *kb_ops; /**< KB vtable. */
  108 };
  109 
  110 /**
  111  * @brief type abstraction to hide KB internals.
  112  */
  113 typedef struct kb *kb_t;
  114 
  115 /**
  116  * @brief KB interface. Functions provided by an implementation. All functions
  117  *        have to be provided, there is no default/fallback. These functions
  118  *        should be called via the corresponding static inline wrappers below.
  119  *        See the wrappers for the documentation.
  120  */
  121 struct kb_operations
  122 {
  123   /* ctor/dtor */
  124   int (*kb_new) (kb_t *, const char *);             /**< New KB. */
  125   int (*kb_delete) (kb_t);                          /**< Delete KB. */
  126   kb_t (*kb_find) (const char *, const char *);     /**< Find KB. */
  127   kb_t (*kb_direct_conn) (const char *, const int); /**< Connect to a KB. */
  128 
  129   /* Actual kb operations */
  130   /**
  131    * Function provided by an implementation to get a single kb element.
  132    */
  133   struct kb_item *(*kb_get_single) (kb_t, const char *, enum kb_item_type);
  134   /**
  135    * Function provided by an implementation to get single kb str item.
  136    */
  137   char *(*kb_get_str) (kb_t, const char *);
  138   /**
  139    * Function provided by an implementation to get single kb int item.
  140    */
  141   int (*kb_get_int) (kb_t, const char *);
  142   /**
  143    * Function provided by an implementation to get field of NVT.
  144    */
  145   char *(*kb_get_nvt) (kb_t, const char *, enum kb_nvt_pos);
  146   /**
  147    * Function provided by an implementation to get a full NVT.
  148    */
  149   nvti_t *(*kb_get_nvt_all) (kb_t, const char *);
  150   /**
  151    * Function provided by an implementation to get list of OIDs.
  152    */
  153   GSList *(*kb_get_nvt_oids) (kb_t);
  154   /**
  155    * Function provided by an implementation to push a new value under a key.
  156    */
  157   int (*kb_push_str) (kb_t, const char *, const char *);
  158   /**
  159    * Function provided by an implementation to pop a str under a key.
  160    */
  161   char *(*kb_pop_str) (kb_t, const char *);
  162   /**
  163    * Function provided by an implementation to get all items stored
  164    * under a given name.
  165    */
  166   struct kb_item *(*kb_get_all) (kb_t, const char *);
  167   /**
  168    * Function provided by an implementation to get all items stored
  169    * under a given pattern.
  170    */
  171   struct kb_item *(*kb_get_pattern) (kb_t, const char *);
  172   /**
  173    * Function provided by an implementation to count all items stored
  174    * under a given pattern.
  175    */
  176   size_t (*kb_count) (kb_t, const char *);
  177   /**
  178    * Function provided by an implementation to insert (append) a new entry
  179    * under a given name.
  180    */
  181   int (*kb_add_str) (kb_t, const char *, const char *, size_t);
  182   /**
  183    * Function provided by an implementation to insert (append) a new
  184    * unique entry under a given name.
  185    */
  186   int (*kb_add_str_unique) (kb_t, const char *, const char *, size_t);
  187   /**
  188    * Function provided by an implementation to get (replace) a new entry
  189    * under a given name.
  190    */
  191   int (*kb_set_str) (kb_t, const char *, const char *, size_t);
  192   /**
  193    * Function provided by an implementation to insert (append) a new entry
  194    * under a given name.
  195    */
  196   int (*kb_add_int) (kb_t, const char *, int);
  197   /**
  198    * Function provided by an implementation to insert (append) a new
  199    * unique entry under a given name.
  200    */
  201   int (*kb_add_int_unique) (kb_t, const char *, int);
  202   /**
  203    * Function provided by an implementation to get (replace) a new entry
  204    * under a given name.
  205    */
  206   int (*kb_set_int) (kb_t, const char *, int);
  207   /**
  208    * Function provided by an implementation to
  209    * insert a new nvt.
  210    */
  211   int (*kb_add_nvt) (kb_t, const nvti_t *, const char *);
  212   /**
  213    * Function provided by an implementation to delete all entries
  214    * under a given name.
  215    */
  216   int (*kb_del_items) (kb_t, const char *);
  217 
  218   /* Utils */
  219   int (*kb_save) (kb_t);                /**< Save all kb content. */
  220   int (*kb_lnk_reset) (kb_t);           /**< Reset connection to KB. */
  221   int (*kb_flush) (kb_t, const char *); /**< Flush redis DB. */
  222   int (*kb_get_kb_index) (kb_t);        /**< Get kb index. */
  223 };
  224 
  225 /**
  226  * @brief Default KB operations.
  227  *        No selection mechanism is provided yet since there's only one
  228  *        implementation (redis-based).
  229  */
  230 extern const struct kb_operations *KBDefaultOperations;
  231 
  232 /**
  233  * @brief Release a KB item (or a list).
  234  */
  235 void
  236 kb_item_free (struct kb_item *);
  237 
  238 /**
  239  * @brief Initialize a new Knowledge Base object.
  240  * @param[in] kb  Reference to a kb_t to initialize.
  241  * @param[in] kb_path   Path to KB.
  242  * @return 0 on success, -1 on connection error, -2 on unavailable DB spot.
  243  */
  244 static inline int
  245 kb_new (kb_t *kb, const char *kb_path)
  246 {
  247   assert (kb);
  248   assert (KBDefaultOperations);
  249   assert (KBDefaultOperations->kb_new);
  250 
  251   *kb = NULL;
  252 
  253   return KBDefaultOperations->kb_new (kb, kb_path);
  254 }
  255 
  256 /**
  257  * @brief Connect to a Knowledge Base object which has the given kb_index.
  258  * @param[in] kb_path   Path to KB.
  259  * @param[in] kb_index       DB index
  260  * @return Knowledge Base object, NULL otherwise.
  261  */
  262 static inline kb_t
  263 kb_direct_conn (const char *kb_path, const int kb_index)
  264 {
  265   assert (KBDefaultOperations);
  266   assert (KBDefaultOperations->kb_direct_conn);
  267 
  268   return KBDefaultOperations->kb_direct_conn (kb_path, kb_index);
  269 }
  270 
  271 /**
  272  * @brief Find an existing Knowledge Base object with key.
  273  * @param[in] kb_path   Path to KB.
  274  * @param[in] key       Marker key to search for in KB objects.
  275  * @return Knowledge Base object, NULL otherwise.
  276  */
  277 static inline kb_t
  278 kb_find (const char *kb_path, const char *key)
  279 {
  280   assert (KBDefaultOperations);
  281   assert (KBDefaultOperations->kb_find);
  282 
  283   return KBDefaultOperations->kb_find (kb_path, key);
  284 }
  285 
  286 /**
  287  * @brief Delete all entries and release ownership on the namespace.
  288  * @param[in] kb  KB handle to release.
  289  * @return 0 on success, non-null on error.
  290  */
  291 static inline int
  292 kb_delete (kb_t kb)
  293 {
  294   assert (kb);
  295   assert (kb->kb_ops);
  296   assert (kb->kb_ops->kb_delete);
  297 
  298   return kb->kb_ops->kb_delete (kb);
  299 }
  300 
  301 /**
  302  * @brief Get a single KB element.
  303  * @param[in] kb  KB handle where to fetch the item.
  304  * @param[in] name  Name of the element to retrieve.
  305  * @param[in] type  Desired element type.
  306  * @return A struct kb_item to be freed with kb_item_free() or NULL if no
  307  *         element was found or on error.
  308  */
  309 static inline struct kb_item *
  310 kb_item_get_single (kb_t kb, const char *name, enum kb_item_type type)
  311 {
  312   assert (kb);
  313   assert (kb->kb_ops);
  314   assert (kb->kb_ops->kb_get_single);
  315 
  316   return kb->kb_ops->kb_get_single (kb, name, type);
  317 }
  318 
  319 /**
  320  * @brief Get a single KB string item.
  321  * @param[in] kb  KB handle where to fetch the item.
  322  * @param[in] name  Name of the element to retrieve.
  323  * @return A struct kb_item to be freed with kb_item_free() or NULL if no
  324  *         element was found or on error.
  325  */
  326 static inline char *
  327 kb_item_get_str (kb_t kb, const char *name)
  328 {
  329   assert (kb);
  330   assert (kb->kb_ops);
  331   assert (kb->kb_ops->kb_get_str);
  332 
  333   return kb->kb_ops->kb_get_str (kb, name);
  334 }
  335 
  336 /**
  337  * @brief Get a single KB integer item.
  338  * @param[in] kb  KB handle where to fetch the item.
  339  * @param[in] name  Name of the element to retrieve.
  340  * @return A struct kb_item to be freed with kb_item_free() or NULL if no
  341  *         element was found or on error.
  342  */
  343 static inline int
  344 kb_item_get_int (kb_t kb, const char *name)
  345 {
  346   assert (kb);
  347   assert (kb->kb_ops);
  348   assert (kb->kb_ops->kb_get_int);
  349 
  350   return kb->kb_ops->kb_get_int (kb, name);
  351 }
  352 
  353 /**
  354  * @brief Get all items stored under a given name.
  355  * @param[in] kb  KB handle where to fetch the items.
  356  * @param[in] name  Name of the elements to retrieve.
  357  * @return Linked struct kb_item instances to be freed with kb_item_free() or
  358  *         NULL if no element was found or on error.
  359  */
  360 static inline struct kb_item *
  361 kb_item_get_all (kb_t kb, const char *name)
  362 {
  363   assert (kb);
  364   assert (kb->kb_ops);
  365   assert (kb->kb_ops->kb_get_all);
  366 
  367   return kb->kb_ops->kb_get_all (kb, name);
  368 }
  369 
  370 /**
  371  * @brief Get all items stored under a given pattern.
  372  * @param[in] kb  KB handle where to fetch the items.
  373  * @param[in] pattern  '*' pattern of the elements to retrieve.
  374  * @return Linked struct kb_item instances to be freed with kb_item_free() or
  375  *         NULL if no element was found or on error.
  376  */
  377 static inline struct kb_item *
  378 kb_item_get_pattern (kb_t kb, const char *pattern)
  379 {
  380   assert (kb);
  381   assert (kb->kb_ops);
  382   assert (kb->kb_ops->kb_get_pattern);
  383 
  384   return kb->kb_ops->kb_get_pattern (kb, pattern);
  385 }
  386 
  387 /**
  388  * @brief Push a new value under a given key.
  389  * @param[in] kb    KB handle where to store the item.
  390  * @param[in] name  Key to push to.
  391  * @param[in] value Value to push.
  392  * @return 0 on success, non-null on error.
  393  */
  394 static inline int
  395 kb_item_push_str (kb_t kb, const char *name, const char *value)
  396 {
  397   assert (kb);
  398   assert (kb->kb_ops);
  399   assert (kb->kb_ops->kb_push_str);
  400 
  401   return kb->kb_ops->kb_push_str (kb, name, value);
  402 }
  403 
  404 /**
  405  * @brief Pop a single KB string item.
  406  * @param[in] kb  KB handle where to fetch the item.
  407  * @param[in] name  Name of the element to retrieve.
  408  * @return A struct kb_item to be freed with kb_item_free() or NULL if no
  409  *         element was found or on error.
  410  */
  411 static inline char *
  412 kb_item_pop_str (kb_t kb, const char *name)
  413 {
  414   assert (kb);
  415   assert (kb->kb_ops);
  416   assert (kb->kb_ops->kb_pop_str);
  417 
  418   return kb->kb_ops->kb_pop_str (kb, name);
  419 }
  420 
  421 /**
  422  * @brief Count all items stored under a given pattern.
  423  *
  424  * @param[in] kb  KB handle where to count the items.
  425  * @param[in] pattern  '*' pattern of the elements to count.
  426  *
  427  * @return Count of items.
  428  */
  429 static inline size_t
  430 kb_item_count (kb_t kb, const char *pattern)
  431 {
  432   assert (kb);
  433   assert (kb->kb_ops);
  434   assert (kb->kb_ops->kb_count);
  435 
  436   return kb->kb_ops->kb_count (kb, pattern);
  437 }
  438 
  439 /**
  440  * @brief Insert (append) a new entry under a given name.
  441  * @param[in] kb  KB handle where to store the item.
  442  * @param[in] name  Item name.
  443  * @param[in] str  Item value.
  444  * @param[in] len  Value length. Used for blobs.
  445  * @return 0 on success, non-null on error.
  446  */
  447 static inline int
  448 kb_item_add_str (kb_t kb, const char *name, const char *str, size_t len)
  449 {
  450   assert (kb);
  451   assert (kb->kb_ops);
  452   assert (kb->kb_ops->kb_add_str);
  453 
  454   return kb->kb_ops->kb_add_str (kb, name, str, len);
  455 }
  456 
  457 /**
  458  * @brief Insert (append) a new unique entry under a given name.
  459  * @param[in] kb  KB handle where to store the item.
  460  * @param[in] name  Item name.
  461  * @param[in] str  Item value.
  462  * @param[in] len  Value length. Used for blobs.
  463  * @return 0 on success, non-null on error.
  464  */
  465 static inline int
  466 kb_item_add_str_unique (kb_t kb, const char *name, const char *str, size_t len)
  467 {
  468   assert (kb);
  469   assert (kb->kb_ops);
  470   assert (kb->kb_ops->kb_add_str_unique);
  471 
  472   return kb->kb_ops->kb_add_str_unique (kb, name, str, len);
  473 }
  474 
  475 /**
  476  * @brief Set (replace) a new entry under a given name.
  477  * @param[in] kb  KB handle where to store the item.
  478  * @param[in] name  Item name.
  479  * @param[in] str  Item value.
  480  * @param[in] len  Value length. Used for blobs.
  481  * @return 0 on success, non-null on error.
  482  */
  483 static inline int
  484 kb_item_set_str (kb_t kb, const char *name, const char *str, size_t len)
  485 {
  486   assert (kb);
  487   assert (kb->kb_ops);
  488   assert (kb->kb_ops->kb_set_str);
  489 
  490   return kb->kb_ops->kb_set_str (kb, name, str, len);
  491 }
  492 
  493 /**
  494  * @brief Insert (append) a new entry under a given name.
  495  * @param[in] kb  KB handle where to store the item.
  496  * @param[in] name  Item name.
  497  * @param[in] val  Item value.
  498  * @return 0 on success, non-null on error.
  499  */
  500 static inline int
  501 kb_item_add_int (kb_t kb, const char *name, int val)
  502 {
  503   assert (kb);
  504   assert (kb->kb_ops);
  505   assert (kb->kb_ops->kb_add_int);
  506 
  507   return kb->kb_ops->kb_add_int (kb, name, val);
  508 }
  509 
  510 /**
  511  * @brief Insert (append) a new unique entry under a given name.
  512  * @param[in] kb  KB handle where to store the item.
  513  * @param[in] name  Item name.
  514  * @param[in] val  Item value.
  515  * @return 0 on success, non-null on error.
  516  */
  517 static inline int
  518 kb_item_add_int_unique (kb_t kb, const char *name, int val)
  519 {
  520   assert (kb);
  521   assert (kb->kb_ops);
  522   assert (kb->kb_ops->kb_add_int_unique);
  523 
  524   return kb->kb_ops->kb_add_int_unique (kb, name, val);
  525 }
  526 
  527 /**
  528  * @brief Set (replace) a new entry under a given name.
  529  * @param[in] kb  KB handle where to store the item.
  530  * @param[in] name  Item name.
  531  * @param[in] val  Item value.
  532  * @return 0 on success, non-null on error.
  533  */
  534 static inline int
  535 kb_item_set_int (kb_t kb, const char *name, int val)
  536 {
  537   assert (kb);
  538   assert (kb->kb_ops);
  539   assert (kb->kb_ops->kb_set_int);
  540 
  541   return kb->kb_ops->kb_set_int (kb, name, val);
  542 }
  543 
  544 /**
  545  * @brief Insert a new nvt.
  546  * @param[in] kb        KB handle where to store the nvt.
  547  * @param[in] nvt       nvt to store.
  548  * @param[in] filename  Path to nvt to store.
  549  * @return 0 on success, non-null on error.
  550  */
  551 static inline int
  552 kb_nvt_add (kb_t kb, const nvti_t *nvt, const char *filename)
  553 {
  554   assert (kb);
  555   assert (kb->kb_ops);
  556   assert (kb->kb_ops->kb_add_nvt);
  557 
  558   return kb->kb_ops->kb_add_nvt (kb, nvt, filename);
  559 }
  560 
  561 /**
  562  * @brief Get field of a NVT.
  563  * @param[in] kb        KB handle where to store the nvt.
  564  * @param[in] oid       OID of NVT to get from.
  565  * @param[in] position  Position of field to get.
  566  * @return Value of field, NULL otherwise.
  567  */
  568 static inline char *
  569 kb_nvt_get (kb_t kb, const char *oid, enum kb_nvt_pos position)
  570 {
  571   assert (kb);
  572   assert (kb->kb_ops);
  573   assert (kb->kb_ops->kb_get_nvt);
  574 
  575   return kb->kb_ops->kb_get_nvt (kb, oid, position);
  576 }
  577 
  578 /**
  579  * @brief Get a full NVT.
  580  * @param[in] kb        KB handle where to store the nvt.
  581  * @param[in] oid       OID of NVT to get.
  582  * @return nvti_t of NVT, NULL otherwise.
  583  */
  584 static inline nvti_t *
  585 kb_nvt_get_all (kb_t kb, const char *oid)
  586 {
  587   assert (kb);
  588   assert (kb->kb_ops);
  589   assert (kb->kb_ops->kb_get_nvt_all);
  590 
  591   return kb->kb_ops->kb_get_nvt_all (kb, oid);
  592 }
  593 
  594 /**
  595  * @brief Get list of NVT OIDs.
  596  * @param[in] kb        KB handle where NVTs are stored.
  597  * @return Linked-list of OIDs, NULL otherwise.
  598  */
  599 static inline GSList *
  600 kb_nvt_get_oids (kb_t kb)
  601 {
  602   assert (kb);
  603   assert (kb->kb_ops);
  604   assert (kb->kb_ops->kb_get_nvt_oids);
  605 
  606   return kb->kb_ops->kb_get_nvt_oids (kb);
  607 }
  608 
  609 /**
  610  * @brief Delete all entries under a given name.
  611  * @param[in] kb  KB handle where to store the item.
  612  * @param[in] name  Item name.
  613  * @return 0 on success, non-null on error.
  614  */
  615 static inline int
  616 kb_del_items (kb_t kb, const char *name)
  617 {
  618   assert (kb);
  619   assert (kb->kb_ops);
  620   assert (kb->kb_ops->kb_del_items);
  621 
  622   return kb->kb_ops->kb_del_items (kb, name);
  623 }
  624 
  625 /**
  626  * @brief Save all the KB's content.
  627  * @param[in] kb        KB handle.
  628  * @return 0 on success, non-null on error.
  629  */
  630 static inline int
  631 kb_save (kb_t kb)
  632 {
  633   int rc = 0;
  634 
  635   assert (kb);
  636   assert (kb->kb_ops);
  637 
  638   if (kb->kb_ops->kb_save != NULL)
  639     rc = kb->kb_ops->kb_save (kb);
  640 
  641   return rc;
  642 }
  643 
  644 /**
  645  * @brief Reset connection to the KB. This is called after each fork() to make
  646  *        sure connections aren't shared between concurrent processes.
  647  * @param[in] kb  KB handle.
  648  * @return 0 on success, non-null on error.
  649  */
  650 static inline int
  651 kb_lnk_reset (kb_t kb)
  652 {
  653   int rc = 0;
  654 
  655   assert (kb);
  656   assert (kb->kb_ops);
  657 
  658   if (kb->kb_ops->kb_lnk_reset != NULL)
  659     rc = kb->kb_ops->kb_lnk_reset (kb);
  660 
  661   return rc;
  662 }
  663 
  664 /**
  665  * @brief Flush all the KB's content. Delete all namespaces.
  666  * @param[in] kb        KB handle.
  667  * @param[in] except    Don't flush DB with except key.
  668  * @return 0 on success, non-null on error.
  669  */
  670 static inline int
  671 kb_flush (kb_t kb, const char *except)
  672 {
  673   int rc = 0;
  674 
  675   assert (kb);
  676   assert (kb->kb_ops);
  677 
  678   if (kb->kb_ops->kb_flush != NULL)
  679     rc = kb->kb_ops->kb_flush (kb, except);
  680 
  681   return rc;
  682 }
  683 
  684 /**
  685  * @brief Return the kb index
  686  * @param[in] kb KB handle.
  687  * @return kb_index on success, null on error.
  688  */
  689 static inline int
  690 kb_get_kb_index (kb_t kb)
  691 {
  692   assert (kb);
  693   assert (kb->kb_ops);
  694   assert (kb->kb_ops->kb_get_kb_index);
  695 
  696   return kb->kb_ops->kb_get_kb_index (kb);
  697 }
  698 
  699 #endif