Dear Jon,

Here’s the business end of snat_msg_enum.h:

#define vl_msg_id(n,h) n,
typedef enum {
#include <snat/snat_all_api_h.h>
    /* We'll want to know how many messages IDs we need... */
    VL_MSG_FIRST_AVAILABLE,
} vl_msg_id_t;
#undef vl_msg_id

This will cause the problem you’ve mentioned. So, don’t use it!

Make your own:

#define vl_msg_id(n,h) n,
typedef enum {
#include <snat/snat_all_api_h.h>
} snat_msg_id_t;

typedef enum {
#include <another_plugin/another_all_api_h.h>
} another_plugin_msg_id_t

<etc>

#undef vl_msg_id

This will give you multiple overlapping enums. You’ll have to add the indicated 
plugin message ID block base, as described earlier.

You could also go for the one-minute-manager easy way to solve the problem: use 
the message-name + crc hash table, just like the python language binding does.

Take a look at the generated snat.api.h:

/****** Message name, crc list ******/

#ifdef vl_msg_name_crc_list
#define foreach_vl_msg_name_crc_snat \
_(VL_API_SNAT_ADD_ADDRESS_RANGE, snat_add_address_range, 689a7cae) \
_(VL_API_SNAT_ADD_ADDRESS_RANGE_REPLY, snat_add_address_range_reply, 7d360766) \
_(VL_API_SNAT_ADDRESS_DUMP, snat_address_dump, 27c92402) \
_(VL_API_SNAT_ADDRESS_DETAILS, snat_address_details, a86ec839)
<etc>

You could do something like so:

#define _(a,b,c) static char *STR_##a=#b##_#c;
#define vl_msg_name_crc_list
#include <snat.api.h>
#include <other.api.h>
...
#endif

Which resolves to ‘static char 
*STR_VL_API_SNAT_ADD_ADDRESS_RANGE=”snat_add_address_range_””689a7cae”;’.

Then:

   VL_API_SNAT_ADD_ADDRESS_RANGE_MSG_ID = vl_api_get_msg_index 
(STR_VL_API_SNAT_ADD_ADDRESS_RANGE);

HTH... D.

From: Jon Loeliger [mailto:j...@netgate.com]
Sent: Thursday, January 26, 2017 3:29 PM
To: Dave Barach (dbarach) <dbar...@cisco.com>
Cc: vpp-dev <vpp-dev@lists.fd.io>
Subject: Re: [vpp-dev] SNAT Plugin Use



On Wed, Jan 25, 2017 at 10:49 AM, Dave Barach (dbarach) 
<dbar...@cisco.com<mailto:dbar...@cisco.com>> wrote:
Dear Jon,

Sorry for the delayed response.

Anyhow, the constant VL_MSG_FIRST_AVAILABLE is a historical name for a simple 
thing: the number of binary API messages defined by a given plugin.

Understood.

I’m not sure what you’re trying to do, but it’s actually just as well that you 
ran into a compile error. I need to explain a number of details so you won’t 
end up seriously annoyed after wasting a bunch of your time.

Hrm.  Maybe too late for that... :-)

So, let me give a bit of insight into what I am doing, because I think
my intent may be being misunderstood a little.

I am doing what I suspect might be the obvious Use Case for the C API
to VPP lib.  Effectively we are are writing a totally different CLI front-end
to VPP through the VPP lib API.  We are strictly *using* vlib -- we are not,
at this time, writing any new plugin to VPP, nor are we extending VPP's
functionality via a new plugin.

However, we have need to use multiple plugins.  If you consider the "vpe"
pieces one plugin, then currently our next plug we need is SNAT.

When the vpp data-plane loads plugins, each plugin which defines a binary API 
is expected to do something like the following:

  name = format (0, "snat_%08x%c", api_version, 0);

  /* Ask for a correctly-sized block of API message decode slots */
  sm->msg_id_base = vl_msg_api_get_msg_ids
      ((char *) name, VL_MSG_FIRST_AVAILABLE);

The data-plane plugin asks for a block of message-ID’s. 
vl_msg_api_get_msg_ids(...) makes a string-hash entry, to map the string 
<plugin-name>_<api-version> to the base of the message-id block.

OK, good.  I get that, I believe.

When it comes time to send binary API messages to a given plugin, the 
control-plane agent recovers msg_id_base like so:

  /* Ask the vpp engine for the first assigned message-id */
  name = format (0, "snat_%08x%c", api_version, 0);
  sm->msg_id_base = vl_client_get_first_plugin_msg_id ((char *) name);

and adds it to the enumerated message id values:

  mp->_vl_msg_id = ntohs (msg_id_base + VL_API_some_msg_id);

This is the code that we can't currently write.  I have need of both the
interface and SNAT APIs in one C source file.  In that case, I had intended
to make both interface and SNAT API message calls.  I'm happy to offset
the number scheme for one of these sets, or both, by an offset.  But I
can't include both of the msg_id enumberations in the same C file because
they collide on the definition of the VL_MSG_FIRST_AVAILABLE as found
in the enum definitions.

Are we expected to have to interface to each plugin from a separate C
source file?  I can add an extra set of routines to hide all this in an 
additional
C source file if needed, I guess.

Would it make more sense for these enums to provide VL_MSG_ID_SNAT_N_MSGS
or something unique to that enum?

Also, is there an API call to "load" a plugin that I missed somewhere?   How 
does
my main-line code tell VLIB that the SNAT plugin will need to be loaded?


Since the set of plugins can change between runs, absolute message ID’s can’t 
be guaranteed.

Yep, I get that too.  Where is all this plugin stuff described?  I see, for 
example,
the "sample" plugin src/examples/sample-plugin/sample/.  However, I think that
describes how to write a new plugin to extend VPP's functionality.   That's not
what I'm doing.

Please let me know if there are other questions I could answer to help
clarify what I'm trying to do here!

Thanks… Dave

Thanks,
jdl
_______________________________________________
vpp-dev mailing list
vpp-dev@lists.fd.io
https://lists.fd.io/mailman/listinfo/vpp-dev

Reply via email to