[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