[kea-dev] Kea python hook?
Dave Cole
davecole at nbnco.com.au
Mon Jan 22 22:32:28 UTC 2018
Sorry about the quoting style - I am forced to use LookOut here...
> Dave Cole writes:
> > I did not know that code existed!
>
> => it had 2 purposes:
> - show it is possible to write a hook in a script language vs requiring C++
> with examples in Python, Lua, OCaml and v8
My first attempt at embedding an interpreter here was with Lua.
I gave up on that when I realised the poor quality of the 3rd
party modules we had to use to implement our requirements
> - detail technical points so someone who wants to do the same thing
> can win a lot of time
> On big difference in approach is that the code you have created
> will not work with current Kea if the Python code imports a
> module with native code - unless you statically link your code
> with Kea. Kea loads hooks with RTLD_LOCAL which prevents symbols
> in the hook being visible in subsequent dynamic linking. The
> hook I created here connects to a database and publishes to Kafka
> - we need to load native modules.
> => currently hooks are dynamic shared objects which don't load
> other DSOs and have no dependency between hooks, so RTLD_LOCAL
> is enough. As it works for almost all cases and is simpler / faster
> I believe it will stay the default but you can open a ticket asking
> for a configure option to change it for RTLD_GLOBAL. If you provide
> a pair of DSOs, one behaving as a hook and loading the second, for
> unit tests, or pull a request on github, it will help because as
> you know we have limited man power.
I implement my hook with a Kea loaded DSO. This does as little
as possible due to the RTLD_LOCAL limitation. It just
initialises the Python interpreter then loads the kea extension
module via Python import. Inside the Python module is a Capsule
containing endpoints for bootstrapping the Kea/Python binding.
The advantage to this is I can move all of the Kea code into a
kea module which you can then load from the Python command line.
>From that point you are free to use plain Python code for things
like unit tests. I am working towards a public release of the
code as my boss is actively seeking permission to release it.
I want to get to the point where I can use pcap files for
regression tests of my complex hook. It is getting close. For
example:
- - 8< - - - - - - - - - - - - - - - - - - - - - - - - - - -
from kea import *
trans_id = 0x50ea1f55
p = Pkt4(DHCPDISCOVER, trans_id)
p.setGiaddr('11.0.0.1')
p.setHWAddr('02:42:ac:14:00:05')
p.addOption(Option(DHO_DHCP_PARAMETER_REQUEST_LIST)
.setString(chr(DHO_SUBNET_MASK)
+ chr(DHO_BROADCAST_ADDRESS)
+ chr(DHO_ROUTERS)
+ chr(DHO_DOMAIN_NAME)
+ chr(DHO_DOMAIN_NAME_SERVERS)))
o = Option(DHO_DHCP_AGENT_OPTIONS)
o.addOption(Option(1).setString('Relay Agent Option 1'))
o.addOption(Option(2).setString('Another Option'))
p.addOption(o)
p.pack()
raw = p.getBuffer()
r = Pkt4(raw)
r.unpack()
assert r.getType() == DHCPDISCOVER
assert r.getTransid() == trans_id
assert r.getGiaddr() == '11.0.0.1'
assert r.getHWAddr() == '02:42:ac:14:00:05'
assert r.getOption(DHO_DHCP_PARAMETER_REQUEST_LIST) \
.getString() == (chr(DHO_SUBNET_MASK)
+ chr(DHO_BROADCAST_ADDRESS)
+ chr(DHO_ROUTERS)
+ chr(DHO_DOMAIN_NAME)
+ chr(DHO_DOMAIN_NAME_SERVERS))
o = r.getOption(DHO_DHCP_AGENT_OPTIONS).getOptions()
assert o[1].getString() == 'Relay Agent Option 1'
assert o[2].getString() == 'Another Option'
- - 8< - - - - - - - - - - - - - - - - - - - - - - - - - - -
> > Another thing I am confused about in your code is that you do not
> > appear to do any exception handling. If Python code calls Kea
> > and an exception is raised, then the Python interpreter will get
> > corrupted.
>
> => I mention exceptions in the doc as one of the things which should
> be implemented. Of course it is simpler if the C++ code called
> from the external language does not raise exceptions (*) so
> you don't have to add a handler to stop stack unwinding.
I found that out the hard way :-).
More information about the kea-dev
mailing list