diff mbox series

[AUH] kronosnet: upgrading to 1.90 FAILED

Message ID 0101018b9851ba54-ae1f2210-a263-4097-9446-64e996ce5b0d-000000@us-west-2.amazonses.com
State New
Headers show
Series [AUH] kronosnet: upgrading to 1.90 FAILED | expand

Commit Message

auh@yoctoproject.org Nov. 4, 2023, 3:12 a.m. UTC
Hello,

this email is a notification from the Auto Upgrade Helper
that the automatic attempt to upgrade the recipe *kronosnet* to *1.90* has Failed(do_compile).

Detailed error information:

do_compile failed



Next steps:
    - apply the patch: git am 0001-kronosnet-upgrade-1.24-1.90.patch
    - check the changes to upstream patches and summarize them in the commit message,
    - compile an image that contains the package
    - perform some basic sanity tests
    - amend the patch and sign it off: git commit -s --reset-author --amend
    - send it to the appropriate mailing list

Alternatively, if you believe the recipe should not be upgraded at this time,
you can fill RECIPE_NO_UPDATE_REASON in respective recipe file so that
automatic upgrades would no longer be attempted.

Please review the attached files for further information and build/update failures.
Any problem please file a bug at https://bugzilla.yoctoproject.org/enter_bug.cgi?product=Automated%20Update%20Handler

Regards,
The Upgrade Helper

-- >8 --
From 99cc315f2ed3967734d09e8c00ffdac764d6d5b1 Mon Sep 17 00:00:00 2001
From: Upgrade Helper <auh@yoctoproject.org>
Date: Sat, 4 Nov 2023 02:17:07 +0000
Subject: [PATCH] kronosnet: upgrade 1.24 -> 1.90

---
 ...ne-SOURCE_EPOCH-during-configuration.patch |    61 +
 ...ild-distribute-the-source_epoch-file.patch |    25 +
 ...man-Add-date-year-options-to-doxyxml.patch |   112 +
 ...yxml-date-options-to-build-man-pages.patch |    30 +
 ...ec-use-the-source-epoch-here-as-well.patch |    26 +
 ...ccomodate-to-the-actual-date-utility.patch |   214 +
 ...-is-a-relatively-new-option-avoid-it.patch |    26 +
 ...rovide-proper-error-if-source-tree-v.patch |    37 +
 ...SOURCE_DATE_EPOCH-before-turning-to-.patch |    44 +
 ...uild-look-for-source_epoch-in-srcdir.patch |    28 +
 ...improve-checks-around-RX-packet-size.patch |    90 +
 ...Init-the-parameter-is-reserved-must-.patch |    26 +
 ...lush_logs-remove-redundant-condition.patch |    42 +
 ...eads-will-overwrite-the-entire-msg-s.patch |    25 +
 ...sh_logs-don-t-repeat-the-type-of-msg.patch |    29 +
 ...or-loop-is-more-straightforward-here.patch |    32 +
 ...lush_logs-while-loop-instead-of-goto.patch |    53 +
 ...t-ever-print-past-the-message-buffer.patch |    48 +
 ...t-returns-the-number-of-set-bits-as-.patch |    43 +
 ...logthread-while-loop-instead-of-goto.patch |    67 +
 ...-documentation-the-closing-newline-i.patch |    27 +
 ...nt-in-putting-NL-after-the-final-NUL.patch |    34 +
 ...-parentheses-after-the-sizeof-operat.patch |    43 +
 ...024-tests-add-another-lzma-exception.patch |    39 +
 ...correct-library-in-memcheck-comments.patch |    23 +
 ...-internal-memory-leak-3.38-non-recur.patch |    55 +
 ...-to-log_msg-that-would-have-no-effec.patch |    25 +
 ...g-drop-locking-inside-log_msg-part-1.patch |    69 +
 ..._lock_done-as-it-was-used-only-by-lo.patch |    64 +
 ...rror-in-case-logging-buffer-is-bigge.patch |    45 +
 ...age-of-handle_config_mutex-to-wrap-o.patch |   123 +
 ...ore-overrides-for-fedora28-arm-glibc.patch |    32 +
 ...define-symbols-from-the-main-library.patch |    39 +
 ...rnal-array-to-track-status-of-thread.patch |   397 +
 ...-tests-cleanup-nss-memcheck-supports.patch |    90 +
 ...xceptions-as-they-have-been-fixed-in.patch |    32 +
 ...-Support-for-git-archive-stored-tags.patch |   133 +
 ...-lightweight-tags-in-git-version-gen.patch |    28 +
 ...-version-gen-fail-on-UNKNOWN-version.patch |    29 +
 ...Use-gitarchive-version-for-spec-file.patch |    36 +
 ...easier-to-debug-thread-startup-stop-.patch |   142 +
 ...-2-handling-mostly-affects-slow-mach.patch |    46 +
 ...o-to-avoid-incorrect-propagation-fro.patch |    26 +
 ...length-not-dividable-by-wrap-key-blo.patch |   113 +
 ...0045-links-Don-t-close-loopback-link.patch |    28 +
 .../0046-misc-keep-covscan-happy.patch        |    43 +
 ...an-update-XML-directory-in-doxyxml.c.patch |    25 +
 .../kronosnet/kronosnet/0048-fix-typo.patch   |    23 +
 .../0049-tests-fix-output-message.patch       |    53 +
 ...supported-compiler-warning-detection.patch |    57 +
 ...ransport_modules_cmd-array-out-of-ra.patch |    25 +
 ...fier-to-compress-crypto-transport-_m.patch |    52 +
 ...oto-statement-to-improve-readability.patch |    50 +
 ...-packet-length-in-_parse_recv_from_l.patch |    32 +
 ...ressed_packets-stats-collect-in-_par.patch |    24 +
 ...ssl-fix-return-type-for-pthread_self.patch |    28 +
 ...in-each-exported-API-when-the-call-s.patch |   570 +
 ...condition-in-api_knet_-addrtostr-str.patch |    92 +
 ...or-message-in-api_knet_-addrtostr-st.patch |    92 +
 ...0060-misc-fix-a-few-typos-stylistics.patch |    43 +
 ...h-EPERM-returned-from-sendmsg-sendto.patch |    28 +
 ...low-random-localhost-IPs-for-testing.patch |   360 +
 ...-better-IPv6-private-address-space-r.patch |    74 +
 ...reebsd-and-fix-a-bunch-of-small-bugs.patch |   860 ++
 .../0065-libtap-update-README-for-BSD.patch   |    19 +
 ...NAMSIZ-for-applications-that-don-t-n.patch |    26 +
 ...itch-to-ioctl-to-destroy-tap-devices.patch |    97 +
 ...le-rename-libtap-to-libnozzle-part-1.patch |   498 +
 .../0069-nozzle-add-Doxygen-header.patch      |    30 +
 ...et-if.h-to-define-IFNAMSIZ-instead-o.patch |    27 +
 ...0071-nozzle-rename-tap_t-to-nozzle_t.patch |   394 +
 ...ruct-_iface-to-nozzle_iface-looks-be.patch |    68 +
 ...le-fix-pkg-config-to-point-to-nozzle.patch |    21 +
 ...zzle-rename-API-from-tap_-to-nozzle_.patch |   897 ++
 ...ozzle-rename-last-tap-bits-to-nozzle.patch |  1795 +++
 ...ozzle_open-coding-style-and-return-c.patch |   246 +
 ...cleanup-nozzle_close-to-be-more-info.patch |   420 +
 ...e-cleanup-and-document-nozzle_set_up.patch |   133 +
 ...cleanup-and-document-nozzle_set_down.patch |   134 +
 ...der-functions-in-order-of-importance.patch |    41 +
 ...e-cleanup-and-document-nozzle_add_ip.patch |   111 +
 ...e-cleanup-and-document-nozzle_del_ip.patch |    96 +
 ...p-and-document-nozzle_get_ips-part-1.patch |   149 +
 .../0084-nozzle-fix-test-on-BSD.patch         |    28 +
 ...-cleanup-and-document-nozzle_get_mtu.patch |    95 +
 ...nd-document-nozzle_set_mtu-and-nozzl.patch |   213 +
 .../kronosnet/0087-Tidy-some-English.patch    |    61 +
 ...-cleanup-and-document-nozzle_get_mac.patch |   133 +
 ...anup-and-document-nozzle_-re-set_mac.patch |   113 +
 ...nd-document-nozzle_get_handle_by_nam.patch |    97 +
 ...nd-document-nozzle_get_name_by_handl.patch |    77 +
 ...e-cleanup-and-document-nozzle_get_fd.patch |    89 +
 ...litting-the-code-across-multiple-fil.patch |   163 +
 ...-rename-_config-to-nozzle_lib_config.patch |    50 +
 ...truct-_ip-to-struct-nozzle_ip-and-cl.patch |   172 +
 ...096-cleanup-rename-sockfd-to-ioctlfd.patch |   166 +
 ...097-cleanup-rename-ip_addr-to-ipaddr.patch |   346 +
 ...-nozzle_iface-struct-drop-unnecessar.patch |   536 +
 .../0099-build-fix-build-on-BSD.patch         |    23 +
 ...zle-rename-lib_mutex-to-config_mutex.patch |   283 +
 ...split-tests-man-pages-and-build-dirs.patch |   238 +
 ...e-around-to-separate-libnozzle-and-t.patch |  4495 ++++++
 ...art-cleaning-internal-function-names.patch |   305 +
 ...-be-more-explicit-on-function-naming.patch |    69 +
 ...e-explicit-on-function-naming-part-2.patch |   190 +
 ...heck-to-is_valid_nozzle-make-it-more.patch |   288 +
 ...-around-to-reflect-completion-and-dr.patch |   345 +
 ...-around-to-reflect-public-API-and-in.patch |   601 +
 ...nozzle-cleanup-mac-address-functions.patch |   584 +
 ...zle-move-ipv4-broadcast-to-internals.patch |   155 +
 ...111-nozzle-move-find_ip-to-internals.patch |   152 +
 ...running-pre-up.d-up.d-down.d-post-do.patch |   220 +
 ...running-pre-up.d-up.d-down.d-post-do.patch |   249 +
 ...running-pre-up.d-up.d-down.d-post-do.patch |   359 +
 ...running-pre-up.d-up.d-down.d-post-do.patch |   315 +
 ...up-and-down-to-the-stable-API-sectio.patch |   402 +
 ...en-and-nozzle_close-should-be-stable.patch |   570 +
 .../0118-nozzle-fix-build-on-BSD.patch        |    23 +
 ...-nozzle-propagate-errors-all-the-way.patch |    32 +
 .../0120-nozzle-fix-man-page-generation.patch |    38 +
 ...zzle-move-man-pages-to-top-level-dir.patch |   141 +
 ...le-enable-libnozzle-build-by-default.patch |    23 +
 .../0123-nozzle-drop-duplicated-code.patch    |   616 +
 ...ffers-to-deal-with-strncpy-and-Werro.patch |    49 +
 .../0125-libnozzle-whitespace-cleanup.patch   |    55 +
 ...bnl3.0-for-ip-address-management-on-.patch |   354 +
 ...e-enable-libnl3-3.3-build-workaround.patch |    46 +
 .../0128-tests-remove-debugging-sleep.patch   |    30 +
 ...ests-properly-check-symbols-on-PPC64.patch |    26 +
 ...zzle_run_updown-to-completed-section.patch |   182 +
 ...-error_string-requirement-from-many-.patch |  1087 ++
 .../0132-libnozzle-fix-build-on-BSD.patch     |    23 +
 .../0133-libnozzle-Update-copyright.patch     |    23 +
 .../0134-global-Update-copyright-across.patch |    97 +
 .../0135-libnozzle-fix-whitespaces.patch      |    27 +
 ...le-cleanup-nozzle_get_ips-public-API.patch |   261 +
 ...-add-comment-about-BSD-ip_add-status.patch |    24 +
 ...tate-error-checking-in-nozzle_get_ip.patch |    26 +
 ...add-per-API-call-test-coverage-check.patch |    58 +
 .../0140-libnozzle-fix-API-check-paths.patch  |    34 +
 ...e-Makefile.am-to-explode-with-API-te.patch |    82 +
 ...2-libnozzle-add-api_nozzle_open-test.patch |   498 +
 ...ibnozzle-fix-test-suite-build-on-BSD.patch |    22 +
 ...-libnozzle-add-api_nozzle_close_test.patch |   473 +
 .../0145-libnozzle-drop-redundant-check.patch |    71 +
 ...nnecessary-indirection-to-call-set_d.patch |    93 +
 ...le-add-api_nozzle_set_-up-down-tests.patch |   278 +
 ...0148-libnozzle-improve-set_down-test.patch |    28 +
 ...bnozzle-clean-up-code-in-set_up-test.patch |    42 +
 ...ulti-nozzle-device-test-to-api_nozzl.patch |   224 +
 ...zzle_get_mtu-nozzle_set_mtu-nozzle_r.patch |   718 +
 ...zzle_get_mac-nozzle_set_mac-nozzle_r.patch |   503 +
 ...-add-nozzle_get_handle_by_name-tests.patch |   125 +
 ...e-add-nozzle_get_name_by_handle-test.patch |   114 +
 ...155-libnozzle-add-nozzle_get_fd-test.patch |   117 +
 ...-libnozzle-cleanup-tests-Makefile.am.patch |    49 +
 ...internal-execute_bin_sh_command-test.patch |   281 +
 ...zzle-add-api_nozzle_run_updown-tests.patch |   912 ++
 ...59-libnozzle-add-nozzle_add_ip-tests.patch |   336 +
 ...l_ip-removal-of-Ipv6-addresses-when-.patch |    36 +
 ...61-libnozzle-add-nozzle_del_ip-tests.patch |   309 +
 ...zzle_get_ips-tests-and-kill-nozzle_t.patch |   484 +
 .../0163-global-fix-copyright-across.patch    |   141 +
 ...nozzle-fix-variable-assignment-order.patch |    23 +
 ...truct-size-for-SCTP-event-subscripti.patch |   132 +
 .../kronosnet/kronosnet/0166-Tabify.patch     |    31 +
 ...-update-notes-to-package-maintainers.patch |    41 +
 ...ix-build-with-older-openssl-versions.patch |    25 +
 .../0169-Install-the-nozzle-man-pages.patch   |    39 +
 .../kronosnet/kronosnet/0170-Fix-typos.patch  |    63 +
 .../0171-rpm-ship-libnozzle-man-pages.patch   |    22 +
 ...ates-to-SOURCE_EPOCH-just-like-we-fi.patch |    24 +
 ...initialization-if-the-protocol-is-no.patch |    28 +
 ...PI-version-in-libknet.h-to-make-it-e.patch |    24 +
 ...nable-all-compilers-warnings-at-once.patch |   110 +
 ...-better-handling-of-internal-threads.patch |   273 +
 ...-reporting-a-true-dlinfo-error-cause.patch |    28 +
 ...make-sure-all-generated-man-pages-ar.patch |    87 +
 ...ash-if-there-s-no-doxygen-stanza-for.patch |    28 +
 .../0180-tests-fix-knet_bench-help-text.patch |    23 +
 ...libnozzle-man-page-generation-target.patch |    22 +
 ...s-add-ability-to-create-ipv6-sockets.patch |    59 +
 ...n-page-build-dependency-for-BSD-Make.patch |    30 +
 ...specify-destination-address-for-conn.patch |   279 +
 ...e-log-level-for-currently-used-links.patch |    34 +
 ...sts-allow-shipping-of-the-test-suite.patch |   152 +
 .../0187-manpages-Document-enums-206.patch    |   184 +
 ...hould-match-currently-installed-vers.patch |    23 +
 ...sage-after-free-of-transport-info-me.patch |    51 +
 ...ress-families-on-a-link-always-match.patch |    70 +
 ...al-update-copyright-across-the-board.patch |  2443 +++
 ...ther-exception-to-valgrind-nss-combo.patch |    35 +
 ...e-minimum-crypto-key-size-to-1024bit.patch |    35 +
 ...94-crypto-remove-libnss-3des-support.patch |    74 +
 .../0195-man-Tidy-manpages-215.patch          |   296 +
 .../0196-man-Tidy-more-man-pages.patch        |    46 +
 ...net_host_set_policy-parameters-order.patch |    27 +
 ...ge-check-to-verify-doxy-header-order.patch |    37 +
 ...h-for-errors-detected-by-newly-added.patch |    41 +
 ...udp-use-defines-vs-hardcoded-numbers.patch |    36 +
 ...or-message-decoding-from-ICMP-errors.patch |    38 +
 ...e-into-libknet-dir-and-rename-to-lin.patch |   196 +
 ..._handle_enable_access_lists-api-call.patch |   235 +
 ...nformation-about-the-nature-of-the-t.patch |   115 +
 ...e-code-more-generic-to-accept-more-t.patch |   436 +
 ...operly-initialize-fd-tracker-buffers.patch |    26 +
 ...omatically-add-and-remove-point-to-p.patch |   283 +
 ...s-add-tests-for-default-access-lists.patch |    63 +
 ...ow-knet_bench-to-enable-disable-acce.patch |    62 +
 ...ble-access-lists-for-GENERIC_ACL-pro.patch |    80 +
 ...ble-generic-access-lists-only-for-pr.patch |    55 +
 ...sts-add-access-lists-support-to-sctp.patch |    96 +
 ...13-access-lists-fix-build-on-freebsd.patch |    54 +
 ...e-all-acl-wrappers-to-links_acl-and-.patch |  1025 ++
 ...e-access-lists-structs-and-data-type.patch |   168 +
 ...e-use-of-generic-wrappers-and-remove.patch |    73 +
 .../0217-access-lists-cleanup-API-a-bit.patch |    98 +
 ...-lists-remove-2-unnecessary-wrappers.patch |    70 +
 ...nsport_type-to-transport-to-avoid-co.patch |   196 +
 ...nport_type-to-transport-to-avoid-con.patch |    78 +
 ...s-lists-make-internal-API-consistent.patch |    73 +
 ...-build-on-BSD-and-add-some-include-f.patch |    65 +
 ...dd-errno-around-and-start-using-them.patch |   195 +
 ...fine-access-lists-data-structs-withi.patch |   226 +
 ...-better-name-for-fd_tracker-structur.patch |    95 +
 ...-arrays-to-access-per-protocol-funct.patch |   309 +
 ...ame-ip1-2-to-ss1-2-to-keep-it-more-g.patch |   219 +
 ...s-list-add-internal-API-to-gather-wh.patch |   161 +
 ...-documentation-for-enable_access_lis.patch |    58 +
 ...-external-API-calls-to-manage-access.patch |   746 +
 ...t-implicit-access-lists-management-f.patch |    50 +
 ...improve-checks-on-various-data-types.patch |    74 +
 ...33-access-lists-add-public-API-tests.patch |  1019 ++
 .../0234-acl-Fix-English-in-commments.patch   |   106 +
 ...-more-extensive-test-for-links_acl_i.patch |   717 +
 ...g-target-of-recently-added-API-calls.patch |    52 +
 .../0237-tests-remove-stray-comment.patch     |    22 +
 .../0238-manpages-Document-enums-206.patch    |    38 +
 ...239-compress-add-support-for-libzstd.patch |   342 +
 ...m-internal-memory-leak-non-recurring.patch |    25 +
 ...it-for-packet-implementation-to-flus.patch |   135 +
 ...h-for-errors-detected-by-newly-added.patch |    50 +
 ...al-update-copyright-across-the-board.patch |   129 +
 ...ump-soname-to-indicate-new-API-calls.patch |    23 +
 ...m-URLs-to-point-to-https-and-officia.patch |    31 +
 ...conditionals-to-determine-BuildRequi.patch |    59 +
 ...ict-about-plugins-version-and-archit.patch |   167 +
 ...-up-useless-conditionals-and-defines.patch |   376 +
 ...e-fedora-spec-file-into-upstream-spe.patch |   375 +
 ...0-spec-fix-a-bunch-of-rpmlint-errors.patch |    51 +
 ...1-spec-drop-support-for-init-scripts.patch |   108 +
 ...dconfig_scriptlets-only-when-defined.patch |    40 +
 .../0253-misc-some-coverity-fixes.patch       |   223 +
 .../0254-misc-Fix-more-covscan-warnings.patch |   191 +
 ...-to-clear-all-security-info-on-crypt.patch |    51 +
 ...mon-shared-code-to-trigger-PMTUd-rer.patch |    79 +
 ...-to-trigger-a-PMTUd-rerun-on-each-go.patch |    25 +
 ...et_handle_crypto-external-API-to-be-.patch |   599 +
 ...ernal-rerun-API-to-allow-full-PMTUd-.patch |    74 +
 ...o-fix-openssl1.0-initialization-code.patch |    98 +
 ...ncorrect-merge-when-cherry-picking-7.patch |    29 +
 ...crypto-openssl-error-strings-release.patch |    28 +
 ...rop-calls-to-RAND_seed-as-they-don-t.patch |    68 +
 ...e-errors-generated-by-openssl-1.1.1c.patch |   137 +
 ...oversight-from-541d7faf9068d10e12b42.patch |    23 +
 ...icense-entry-per-file-to-match-READM.patch |  2929 ++++
 .../0267-global-update-copyrights.patch       |    21 +
 ...gnore-libnss-errors-from-OpenSuse-15.patch |    50 +
 ...bnss-errors-from-OpenSuse-Tumbleweed.patch |    98 +
 ...et_handle_setfwd-to-flush-socket-que.patch |   449 +
 .../0271-crypto-fix-log-information.patch     |    32 +
 ...nformation-about-detected-kernel-MTU.patch |    22 +
 .../0273-docs-add-knet-packet-layout.patch    |    43 +
 ...lculation-when-using-crypto-and-add-.patch |   100 +
 ...work-the-whole-math-to-calculate-MTU.patch |  1108 ++
 ...namic-pong-timeout-when-using-crypto.patch |   195 +
 ...y-to-manually-override-MTU-and-disab.patch |   445 +
 ...bump-soname-to-indicate-new-API-call.patch |    23 +
 .../0279-Default-compress-level-use.patch     |   396 +
 ...mpress-Default-compression-level-use.patch |    44 +
 ...ew-minor-space-vs-tab-and-code-forma.patch |    50 +
 ...ress-fix-if-def-around-BZIP2-testing.patch |    35 +
 ...avis.yml-to-integrate-CI-with-coveri.patch |    79 +
 ...-sctp-fix-deference-after-null-check.patch |    23 +
 ...ess-list-only-if-the-socket-is-valid.patch |    24 +
 .../kronosnet/0286-rx-align-data-types.patch  |    25 +
 ...-that-the-pmtud-buf-contains-at-leas.patch |    32 +
 ...idate-fd-to-make-coverity-scan-happy.patch |    42 +
 ...tests-fix-knet_bench-coverity-errors.patch |   166 +
 ...290-common-fix-dlopen-error-handling.patch |    32 +
 ...report-if-we-can-t-resolve-hostname-.patch |    33 +
 ...2-acl-avoid-forward-null-deferencing.patch |    31 +
 ...s-detected-in-error-paths-by-coverit.patch |    40 +
 ...ive-return-detected-by-coverity-scan.patch |    23 +
 ...95-nozzle-don-t-leak-memory-on-error.patch |    24 +
 ...eak-memory-in-case-of-errors-during-.patch |    33 +
 ...e-not-to-overrun-buffers-by-pre-allo.patch |    33 +
 ...overrun-allocated-array-for-compress.patch |    44 +
 ...t-targets-to-run-coverity-automatica.patch |    81 +
 ...o-not-double-unlock-global-read-lock.patch |    27 +
 ...oid-tons-of-possible-buffer-overruns.patch |    46 +
 .../0302-test-simplify-flush-log.patch        |    53 +
 ...-make-sure-string-is-null-terminated.patch |    22 +
 ...ary-usleep-when-sending-to-localhost.patch |    22 +
 ...ew-coverity-errors-in-the-test-suite.patch |    76 +
 ...nel-management-code-for-internal-com.patch |    85 +
 ...ctp-retry-locking-in-case-of-failure.patch |    79 +
 ...iority-description-of-POLICY_PASSIVE.patch |    25 +
 .../0309-common-Include-correct-errno.h.patch |    53 +
 ...common-Conditionalize-RTLD_DI_ORIGIN.patch |    83 +
 ...ndle-Set-thread-stack-size-on-create.patch |   116 +
 ...latency-calculation-when-nodes-are-n.patch |   133 +
 ...use-async-version-of-dstcache-update.patch |    24 +
 ...zzle-fix-tapX-range-on-newer-FreeBSD.patch |    38 +
 ...5-tests-fix-ip-generation-boundaries.patch |    27 +
 ...give-PMTUd-more-time-to-redetect-MTU.patch |    26 +
 ...-memory-corryption-of-link-structure.patch |    39 +
 ...CTP-test-if-SCTP-is-not-supported-by.patch |    36 +
 .../0319-Fix-typo-trasport-transport.patch    |    26 +
 ...-function-to-sleep-based-on-how-the-.patch |    96 +
 ...ables-to-make-it-easier-to-read-the-.patch |    65 +
 ...ost-fix-defrag-buffers-reclaim-logic.patch |    94 +
 ...o-the-defrag-buffer-only-if-we-know-.patch |    28 +
 ...-to-knet_bench-to-specify-a-fixed-pa.patch |   102 +
 ...-MTU-for-a-link-if-the-value-is-lowe.patch |    36 +
 ...et-verification-option-to-knet_bench.patch |   138 +
 ...newline-to-knet_send-timeout-message.patch |    22 +
 ...l-version-detection-when-not-using-p.patch |    98 +
 ...ing-packets-if-knet-cannot-reply-bac.patch |    31 +
 ...rt-write-to-the-application-properly.patch |    51 +
 ...ig-packets-when-reading-from-socketp.patch |    82 +
 ...defrag-buffer-expiration-debug-error.patch |    27 +
 ...e-to-unlock-config-handle-on-failure.patch |    22 +
 ...handle-fix-typo-in-error-log-message.patch |    22 +
 .../0335-tests-mark-array-as-static.patch     |    43 +
 ...t-use-KNET_MAX_HOST_LEN-consistently.patch |    43 +
 ...face-name-size-consistently-and-drop.patch |   114 +
 ...socket-spin-if-a-network-I-F-is-down.patch |    37 +
 .../0339-udp-simplify-code-same-logic.patch   |    36 +
 .../0340-udp-Better-fix-for-ENETUNREACH.patch |    43 +
 ...rrect-math-that-could-lead-to-bad-la.patch |   117 +
 ...-values-to-a-capped-value-to-link-pr.patch |    36 +
 ...ckets-only-when-transport-is-connect.patch |   138 +
 ...turn-512-EOF-messages-from-_recvmmsg.patch |    62 +
 ...-Clear-out-msghdr-for-all-transports.patch |    42 +
 ...o-determine-RX-data-types-vs-random-.patch |    97 +
 ...ry-to-use-only-SCTP-events-to-determ.patch |   547 +
 ...al-Update-copyright-across-the-board.patch |  2587 ++++
 ...man-Fix-covscan-reports-in-doxyxml.c.patch |   133 +
 .../0350-man-Change-strcat-to-strncat.patch   |    73 +
 ...e-prio-description-of-POLICY_PASSIVE.patch |    27 +
 ...ports-use-SO_REUSEADDR-only-for-sctp.patch |    51 +
 ...work-test-suite-link-port-allocation.patch |  1017 ++
 .../0354-rx-kill-unused-variable.patch        |    30 +
 ..._handle_get_stats-to-operate-in-a-re.patch |   382 +
 ..._link_get_status-to-operate-in-readl.patch |   501 +
 ...fix-return-code-from-wait_for_packet.patch |    21 +
 ...ts-fix-build-with-recent-gcc-changes.patch |    33 +
 ...nal-implementation-and-use-libqb-one.patch |   418 +
 ...-missing-build-CFLAGS-for-test-suite.patch |    23 +
 ...to-use-correct-libqb-include-files-a.patch |    25 +
 ...ersion-of-doxygen2man-when-available.patch |   140 +
 ...utgoing-connections-are-bound-to-a-s.patch |    54 +
 .../kronosnet/0364-links-fix-spacing.patch    |    23 +
 ...ckaddr_len-definition-where-it-belon.patch |    61 +
 ...fdown-handling-for-connected-sockets.patch |    25 +
 ...otify-transports-that-a-link-is-down.patch |   189 +
 ...ways-define-the-Automake-conditional.patch |    27 +
 ...a-symbol-information-generated-by-ne.patch |    39 +
 ...e-of-deprecated-HMAC-interface-with-.patch |    36 +
 ...n-sync-doxygen2man-from-libqb-master.patch |   925 ++
 ...fallback-handling-in-git-version-gen.patch |    29 +
 ...it-version-gen-during-specfile-build.patch |    63 +
 ...-remove-unnecessary-shutdown-locking.patch |    55 +
 ...ink_get_enable-instead-of-get_status.patch |    52 +
 ...framework-to-create-join-and-stop-ma.patch |   174 +
 ...lts-for-coverity-scan-check-to-match.patch |    28 +
 ...ate-valgrind-memcheck-exception-file.patch |  1101 ++
 ...add-support-for-live-reconfiguration.patch |  2504 +++
 .../kronosnet/0380-Update-copyright.patch     |    57 +
 ...le-increment-logic-detected-by-clang.patch |    47 +
 ...nssl-errors-triggered-when-building-.patch |   133 +
 ...re-ignore-list-of-nss-internal-stuff.patch |    35 +
 .../0384-man-fix-type-comparison.patch        |    23 +
 ...1c05112c520ccda3b28e7676acbc6b8a7938.patch |    23 +
 ...6-crypto-add-support-for-openssl-3.0.patch |   228 +
 ...lic-APIs-calls-to-more-suitable-loca.patch |  2565 ++++
 ...kill-all-unsupported-kronosnetd-code.patch |  5820 +++++++
 ...cleanup-drop-no-longer-used-poc-code.patch |   307 +
 ...reads-make-sure-to-initialize-events.patch |    60 +
 ...-fix-per-link-stats-for-data-packets.patch |   208 +
 ...x-data-stats-on-RX-to-match-TX-model.patch |    89 +
 ...ternal-nss-memory-leak-non-recurring.patch |    37 +
 ...send-ping-if-transport-is-not-connec.patch |    93 +
 ...-don-t-send-ping-if-transport-is-not.patch |    92 +
 ...k-and-warn-about-internal-fd-tracker.patch |    46 +
 ...nused-infrastructure-to-send-HOSTINF.patch |   553 +
 ...xceptions-to-deal-with-Ubuntu-latest.patch |   138 +
 ...xceptions-to-deal-with-Ubuntu-latest.patch |    86 +
 ...er-internal-libnss-non-recurring-mem.patch |    55 +
 .../kronosnet/0401-Drop-travis-support.patch  |    79 +
 ...02-tests-Fix-some-random-CI-failures.patch |    83 +
 ...ests-use-callbacks-to-wait-for-nodes.patch |   216 +
 ...some-more-uses-for-event-based-tests.patch |    99 +
 ...ssl-port-knet-top-openssl3.0-alpha13.patch |    81 +
 ...6-docs-Update-README-for-BSD-section.patch |    30 +
 .../0407-global-Update-copyright.patch        |  2296 +++
 ...handle-validate-handle-in-public-API.patch |   902 ++
 .../0409-nozzle-Remove-inet_ntoa-call.patch   |    32 +
 .../kronosnet/0410-lib-Don-t-use-rpath.patch  |   237 +
 ...0411-nozzle-fix-nozzle_up-on-FreeBSD.patch |    64 +
 ...uffer-initialization-potential-issue.patch |    39 +
 ...cs-IRC-channel-is-now-on-Libera-Chat.patch |    23 +
 ...ect-sockaddr-lengths-to-socket-calls.patch |   270 +
 ...ations-to-avoid-recalculating-socksi.patch |    24 +
 .../kronosnet/0416-Require-make-utility.patch |    22 +
 .../0417-Update-copyright-around.patch        |   105 +
 ...dr_storage-structs-coming-in-the-API.patch |    94 +
 ...ment-about-log_fd-in-knet_handle_new.patch |    22 +
 ...ec-cleanup-some-krosnonetd-leftovers.patch |    34 +
 ...1-tests-suppress-more-libnss3-errors.patch |    30 +
 ...resources-if-link-configuration-fail.patch |    98 +
 ...sly-cached-value-as-link-info-might-.patch |    24 +
 ...llow-mix-of-dynamic-and-static-links.patch |    85 +
 ...oc-Add-comments-to-structure-members.patch |   500 +
 ...ate-doxygen2man-to-latest-from-libqb.patch |   973 ++
 ...ag-buffers-to-better-deal-with-netwo.patch |    93 +
 ...e-correct-seq_num-to-reclaim-buffers.patch |    29 +
 ...nk_add_acl-a-wrapper-to-knet_link_in.patch |   133 +
 .../0430-acl-major-internal-rework.patch      |  1037 ++
 ...ports-remove-unused-internal-ACL-API.patch |   167 +
 .../kronosnet/0432-send-Fix-send_sync.patch   |    98 +
 ...tion-of-functional-testing-optionals.patch |    56 +
 ...e-to-synchronise-wait_for_xxx-events.patch |   234 +
 ...ests-if-TUN-support-is-not-available.patch |   263 +
 ...-preserve-test-result-across-cleanup.patch |    23 +
 ...sts-on-machines-that-don-t-have-bash.patch |    35 +
 ...uild-Add-annobin-build-check-support.patch |   244 +
 ...disable-annobin-lto-check-for-centos.patch |    40 +
 ...ests-Correct-include-path-for-poll.h.patch |    28 +
 ...-debug-build-vs-annocheck-parameters.patch |    62 +
 ...x-nss-crypto-buffer-boundaries-usage.patch |    32 +
 ...eq_num-initialization-race-condition.patch |    46 +
 ...or-messages-to-trigger-faster-link-d.patch |    85 +
 ...ogging-when-failing-to-decrypt-packe.patch |   117 +
 ...n-knet-a-bit-when-log-socket-is-busy.patch |    58 +
 ...-to-mailing-lists-and-drop-obsolete-.patch |    29 +
 ...48-build-fix-flag-detections-for-gcc.patch |    28 +
 .../0449-UDP-Check-for-EHOSTUNREACH.patch     |    26 +
 ...move-all-tests-to-new-infrastructure.patch | 12692 ++++++++++++++++
 ...451-tests-update-memcheck-exceptions.patch |    75 +
 ...al-with-new-annocheck-symlink-checks.patch |    41 +
 ...nt-size-to-cope-with-extra-event-on-.patch |    26 +
 .../0454-logging-Fix-Initializing-typo.patch  |    65 +
 ...oved-to-projects.clusterlabs.org-379.patch |    22 +
 .../kronosnet/kronosnet_1.24.bb               |    32 -
 .../kronosnet/kronosnet_1.90.bb               |   487 +
 457 files changed, 102569 insertions(+), 32 deletions(-)
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0001-build-determine-SOURCE_EPOCH-during-configuration.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0002-build-distribute-the-source_epoch-file.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0003-man-Add-date-year-options-to-doxyxml.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0004-man-use-new-doxyxml-date-options-to-build-man-pages.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0005-spec-use-the-source-epoch-here-as-well.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0006-build-accomodate-to-the-actual-date-utility.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0007-build-git-C-is-a-relatively-new-option-avoid-it.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0008-build-fail-and-provide-proper-error-if-source-tree-v.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0009-build-check-for-SOURCE_DATE_EPOCH-before-turning-to-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0010-build-look-for-source_epoch-in-srcdir.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0011-crypto-improve-checks-around-RX-packet-size.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0012-crypto-NSS_NoDB_Init-the-parameter-is-reserved-must-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0013-flush_logs-remove-redundant-condition.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0014-flush_logs-the-reads-will-overwrite-the-entire-msg-s.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0015-flush_logs-don-t-repeat-the-type-of-msg.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0016-flush_logs-a-for-loop-is-more-straightforward-here.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0017-flush_logs-while-loop-instead-of-goto.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0018-flush_logs-don-t-ever-print-past-the-message-buffer.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0019-_logthread-select-returns-the-number-of-set-bits-as-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0020-_logthread-while-loop-instead-of-goto.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0021-knet_log_msg-fix-documentation-the-closing-newline-i.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0022-log_msg-no-point-in-putting-NL-after-the-final-NUL.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0023-coding-style-add-parentheses-after-the-sizeof-operat.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0024-tests-add-another-lzma-exception.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0025-tests-reference-correct-library-in-memcheck-comments.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0026-tests-ignore-nss-internal-memory-leak-3.38-non-recur.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0027-handle-drop-call-to-log_msg-that-would-have-no-effec.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0028-logging-drop-locking-inside-log_msg-part-1.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0029-handle-drop-init_lock_done-as-it-was-used-only-by-lo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0030-logging-report-error-in-case-logging-buffer-is-bigge.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0031-handle-reduce-usage-of-handle_config_mutex-to-wrap-o.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0032-tests-adds-more-overrides-for-fedora28-arm-glibc.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0033-tests-don-t-redefine-symbols-from-the-main-library.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0034-threads-use-internal-array-to-track-status-of-thread.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0035-tests-cleanup-nss-memcheck-supports.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0036-tests-drop-arm-exceptions-as-they-have-been-fixed-in.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0037-Support-for-git-archive-stored-tags.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0038-Do-not-match-lightweight-tags-in-git-version-gen.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0039-git-version-gen-fail-on-UNKNOWN-version.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0040-Use-gitarchive-version-for-spec-file.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0041-threads-make-it-easier-to-debug-thread-startup-stop-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0042-tests-fix-select-2-handling-mostly-affects-slow-mach.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0043-tests-clear-errno-to-avoid-incorrect-propagation-fro.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0044-Import-key-with-length-not-dividable-by-wrap-key-blo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0045-links-Don-t-close-loopback-link.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0046-misc-keep-covscan-happy.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0047-man-update-XML-directory-in-doxyxml.c.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0048-fix-typo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0049-tests-fix-output-message.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0050-build-fix-supported-compiler-warning-detection.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0051-transports-fix-transport_modules_cmd-array-out-of-ra.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0052-Add-static-qualifier-to-compress-crypto-transport-_m.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0053-tx-remove-goto-statement-to-improve-readability.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0054-rx-fix-incorrect-packet-length-in-_parse_recv_from_l.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0055-tx-fix-tx_uncompressed_packets-stats-collect-in-_par.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0056-openssl-fix-return-type-for-pthread_self.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0057-clear-the-errno-in-each-exported-API-when-the-call-s.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0058-tests-fix-check-condition-in-api_knet_-addrtostr-str.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0059-tests-update-error-message-in-api_knet_-addrtostr-st.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0060-misc-fix-a-few-typos-stylistics.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0061-UDP-Cope-with-EPERM-returned-from-sendmsg-sendto.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0062-libtap-tests-allow-random-localhost-IPs-for-testing.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0063-libtap-tests-add-better-IPv6-private-address-space-r.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0064-libtap-port-to-freebsd-and-fix-a-bunch-of-small-bugs.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0065-libtap-update-README-for-BSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0066-libtap-define-IFNAMSIZ-for-applications-that-don-t-n.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0067-libtap-BSD-switch-to-ioctl-to-destroy-tap-devices.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0068-libnozzle-rename-libtap-to-libnozzle-part-1.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0069-nozzle-add-Doxygen-header.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0070-nozzle-include-net-if.h-to-define-IFNAMSIZ-instead-o.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0071-nozzle-rename-tap_t-to-nozzle_t.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0072-nozzle-rename-struct-_iface-to-nozzle_iface-looks-be.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0073-nozzle-fix-pkg-config-to-point-to-nozzle.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0074-nozzle-rename-API-from-tap_-to-nozzle_.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0075-nozzle-rename-last-tap-bits-to-nozzle.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0076-nozzle-cleanup-nozzle_open-coding-style-and-return-c.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0077-nozzle-start-to-cleanup-nozzle_close-to-be-more-info.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0078-nozzle-cleanup-and-document-nozzle_set_up.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0079-nozzle-cleanup-and-document-nozzle_set_down.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0080-nozzle-re-order-functions-in-order-of-importance.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0081-nozzle-cleanup-and-document-nozzle_add_ip.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0082-nozzle-cleanup-and-document-nozzle_del_ip.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0083-nozzle-cleanup-and-document-nozzle_get_ips-part-1.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0084-nozzle-fix-test-on-BSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0085-nozzle-cleanup-and-document-nozzle_get_mtu.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0086-nozzle-cleanup-and-document-nozzle_set_mtu-and-nozzl.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0087-Tidy-some-English.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0088-nozzle-cleanup-and-document-nozzle_get_mac.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0089-nozzle-cleanup-and-document-nozzle_-re-set_mac.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0090-nozzle-cleanup-and-document-nozzle_get_handle_by_nam.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0091-nozzle-cleanup-and-document-nozzle_get_name_by_handl.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0092-nozzle-cleanup-and-document-nozzle_get_fd.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0093-cleanup-start-splitting-the-code-across-multiple-fil.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0094-nozzle-rename-_config-to-nozzle_lib_config.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0095-cleanup-rename-struct-_ip-to-struct-nozzle_ip-and-cl.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0096-cleanup-rename-sockfd-to-ioctlfd.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0097-cleanup-rename-ip_addr-to-ipaddr.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0098-cleanup-document-nozzle_iface-struct-drop-unnecessar.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0099-build-fix-build-on-BSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0100-nozzle-rename-lib_mutex-to-config_mutex.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0101-build-split-tests-man-pages-and-build-dirs.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0102-nozzle-split-code-around-to-separate-libnozzle-and-t.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0103-nozzle-start-cleaning-internal-function-names.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0104-nozzle-be-more-explicit-on-function-naming.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0105-nozzle-be-more-explicit-on-function-naming-part-2.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0106-nozzle-rename-_check-to-is_valid_nozzle-make-it-more.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0107-nozzle-move-code-around-to-reflect-completion-and-dr.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0108-nozzle-move-code-around-to-reflect-public-API-and-in.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0109-nozzle-cleanup-mac-address-functions.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0110-nozzle-move-ipv4-broadcast-to-internals.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0111-nozzle-move-find_ip-to-internals.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0112-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0113-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0114-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0115-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0116-nozzle-move-set-up-and-down-to-the-stable-API-sectio.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0117-nozzle-nozzle_open-and-nozzle_close-should-be-stable.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0118-nozzle-fix-build-on-BSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0119-nozzle-propagate-errors-all-the-way.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0120-nozzle-fix-man-page-generation.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0121-nozzle-move-man-pages-to-top-level-dir.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0122-nozzle-enable-libnozzle-build-by-default.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0123-nozzle-drop-duplicated-code.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0124-nozzle-expand-buffers-to-deal-with-strncpy-and-Werro.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0125-libnozzle-whitespace-cleanup.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0126-libnozzle-Use-libnl3.0-for-ip-address-management-on-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0127-libnozzle-enable-libnl3-3.3-build-workaround.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0128-tests-remove-debugging-sleep.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0129-tests-properly-check-symbols-on-PPC64.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0130-libtap-move-nozzle_run_updown-to-completed-section.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0131-libnozzle-remove-error_string-requirement-from-many-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0132-libnozzle-fix-build-on-BSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0133-libnozzle-Update-copyright.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0134-global-Update-copyright-across.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0135-libnozzle-fix-whitespaces.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0136-libnozzle-cleanup-nozzle_get_ips-public-API.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0137-libnozzle-add-comment-about-BSD-ip_add-status.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0138-libnozzle-re-instate-error-checking-in-nozzle_get_ip.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0139-libnozzle-add-per-API-call-test-coverage-check.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0140-libnozzle-fix-API-check-paths.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0141-libnozzle-prepare-Makefile.am-to-explode-with-API-te.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0142-libnozzle-add-api_nozzle_open-test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0143-libnozzle-fix-test-suite-build-on-BSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0144-libnozzle-add-api_nozzle_close_test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0145-libnozzle-drop-redundant-check.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0146-libnozzle-drop-unnecessary-indirection-to-call-set_d.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0147-libnozzle-add-api_nozzle_set_-up-down-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0148-libnozzle-improve-set_down-test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0149-libnozzle-clean-up-code-in-set_up-test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0150-libnozzle-move-multi-nozzle-device-test-to-api_nozzl.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0151-libnozzle-add-nozzle_get_mtu-nozzle_set_mtu-nozzle_r.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0152-libnozzle-add-nozzle_get_mac-nozzle_set_mac-nozzle_r.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0153-libnozzle-add-nozzle_get_handle_by_name-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0154-libnozzle-add-nozzle_get_name_by_handle-test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0155-libnozzle-add-nozzle_get_fd-test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0156-libnozzle-cleanup-tests-Makefile.am.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0157-libnozzle-add-internal-execute_bin_sh_command-test.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0158-libnozzle-add-api_nozzle_run_updown-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0159-libnozzle-add-nozzle_add_ip-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0160-libnozzle-fix-del_ip-removal-of-Ipv6-addresses-when-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0161-libnozzle-add-nozzle_del_ip-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0162-libnozzle-add-nozzle_get_ips-tests-and-kill-nozzle_t.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0163-global-fix-copyright-across.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0164-libnozzle-fix-variable-assignment-order.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0165-Use-the-kernel-struct-size-for-SCTP-event-subscripti.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0166-Tabify.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0167-global-update-notes-to-package-maintainers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0168-knet-fix-build-with-older-openssl-versions.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0169-Install-the-nozzle-man-pages.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0170-Fix-typos.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0171-rpm-ship-libnozzle-man-pages.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0172-Fix-nozzle-man-dates-to-SOURCE_EPOCH-just-like-we-fi.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0173-Skip-SCTP-event-initialization-if-the-protocol-is-no.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0174-libknet-expose-API-version-in-libknet.h-to-make-it-e.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0175-build-enable-all-compilers-warnings-at-once.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0176-libknet-allow-better-handling-of-internal-threads.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0177-common-fix-not-reporting-a-true-dlinfo-error-cause.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0178-man-add-test-to-make-sure-all-generated-man-pages-ar.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0179-doxyxml-Don-t-crash-if-there-s-no-doxygen-stanza-for.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0180-tests-fix-knet_bench-help-text.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0181-man-fix-libnozzle-man-page-generation-target.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0182-tests-add-ability-to-create-ipv6-sockets.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0183-man-fix-man-page-build-dependency-for-BSD-Make.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0184-transport-don-t-specify-destination-address-for-conn.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0185-host-increase-log-level-for-currently-used-links.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0186-tests-allow-shipping-of-the-test-suite.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0187-manpages-Document-enums-206.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0188-tests-test-rpm-should-match-currently-installed-vers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0189-transports-fix-usage-after-free-of-transport-info-me.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0190-link-Check-address-families-on-a-link-always-match.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0191-global-update-copyright-across-the-board.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0192-build-add-another-exception-to-valgrind-nss-combo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0193-reduce-minimum-crypto-key-size-to-1024bit.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0194-crypto-remove-libnss-3des-support.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0195-man-Tidy-manpages-215.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0196-man-Tidy-more-man-pages.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0197-man-fix-knet_host_set_policy-parameters-order.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0198-tests-add-man-page-check-to-verify-doxy-header-order.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0199-man-fix-libknet.h-for-errors-detected-by-newly-added.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0200-udp-use-defines-vs-hardcoded-numbers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0201-udp-improve-error-message-decoding-from-ICMP-errors.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0202-acl-move-poc-code-into-libknet-dir-and-rename-to-lin.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0203-acl-add-knet_handle_enable_access_lists-api-call.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0204-transports-add-information-about-the-nature-of-the-t.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0205-access-lists-make-code-more-generic-to-accept-more-t.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0206-handle-properly-initialize-fd-tracker-buffers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0207-access-lists-automatically-add-and-remove-point-to-p.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0208-access-lists-add-tests-for-default-access-lists.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0209-access-lists-allow-knet_bench-to-enable-disable-acce.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0210-access-lists-enable-access-lists-for-GENERIC_ACL-pro.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0211-access-lists-enable-generic-access-lists-only-for-pr.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0212-access-lists-add-access-lists-support-to-sctp.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0213-access-lists-fix-build-on-freebsd.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0214-access-lists-move-all-acl-wrappers-to-links_acl-and-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0215-access-lists-move-access-lists-structs-and-data-type.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0216-access-lists-more-use-of-generic-wrappers-and-remove.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0217-access-lists-cleanup-API-a-bit.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0218-access-lists-remove-2-unnecessary-wrappers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0219-links-rename-transport_type-to-transport-to-avoid-co.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0220-links-rename-tranport_type-to-transport-to-avoid-con.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0221-access-lists-make-internal-API-consistent.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0222-access-lists-fix-build-on-BSD-and-add-some-include-f.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0223-access-lists-add-errno-around-and-start-using-them.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0224-access-lists-confine-access-lists-data-structs-withi.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0225-access-lists-use-better-name-for-fd_tracker-structur.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0226-access-lists-use-arrays-to-access-per-protocol-funct.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0227-access-lists-rename-ip1-2-to-ss1-2-to-keep-it-more-g.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0228-transports-access-list-add-internal-API-to-gather-wh.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0229-access-lists-add-documentation-for-enable_access_lis.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0230-access-lists-add-external-API-calls-to-manage-access.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0231-access-lists-test-implicit-access-lists-management-f.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0232-access-lists-improve-checks-on-various-data-types.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0233-access-lists-add-public-API-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0234-acl-Fix-English-in-commments.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0235-access-lists-add-more-extensive-test-for-links_acl_i.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0236-logging-fix-log-target-of-recently-added-API-calls.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0237-tests-remove-stray-comment.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0238-manpages-Document-enums-206.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0239-compress-add-support-for-libzstd.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0240-tests-hide-an-arm-internal-memory-leak-non-recurring.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0241-tests-improve-wait-for-packet-implementation-to-flus.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0242-man-fix-libknet.h-for-errors-detected-by-newly-added.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0243-global-update-copyright-across-the-board.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0244-build-bump-soname-to-indicate-new-API-calls.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0245-spec-fix-upstream-URLs-to-point-to-https-and-officia.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0246-spec-use-distro-conditionals-to-determine-BuildRequi.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0247-spec-be-more-strict-about-plugins-version-and-archit.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0248-spec-clean-up-useless-conditionals-and-defines.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0249-spec-reconciliate-fedora-spec-file-into-upstream-spe.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0250-spec-fix-a-bunch-of-rpmlint-errors.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0251-spec-drop-support-for-init-scripts.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0252-spec-use-ldconfig_scriptlets-only-when-defined.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0253-misc-some-coverity-fixes.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0254-misc-Fix-more-covscan-warnings.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0255-crypto-make-sure-to-clear-all-security-info-on-crypt.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0256-PMTUd-create-common-shared-code-to-trigger-PMTUd-rer.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0257-crypto-make-sure-to-trigger-a-PMTUd-rerun-on-each-go.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0258-crypto-rework-knet_handle_crypto-external-API-to-be-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0259-PMTUd-extend-internal-rerun-API-to-allow-full-PMTUd-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0260-crypto-fix-openssl1.0-initialization-code.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0261-transports-fix-incorrect-merge-when-cherry-picking-7.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0262-crypto-openssl-error-strings-release.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0263-crypto-openssl-drop-calls-to-RAND_seed-as-they-don-t.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0264-crypto-hide-errors-generated-by-openssl-1.1.1c.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0265-doc-fix-a-merge-oversight-from-541d7faf9068d10e12b42.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0266-global-clarify-license-entry-per-file-to-match-READM.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0267-global-update-copyrights.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0268-tests-ignore-libnss-errors-from-OpenSuse-15.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0269-tests-ignore-libnss-errors-from-OpenSuse-Tumbleweed.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0270-threads-allow-knet_handle_setfwd-to-flush-socket-que.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0271-crypto-fix-log-information.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0272-udp-log-information-about-detected-kernel-MTU.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0273-docs-add-knet-packet-layout.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0274-PMTUd-fix-MTU-calculation-when-using-crypto-and-add-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0275-PMTUd-rework-the-whole-math-to-calculate-MTU.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0276-PMTUd-add-dynamic-pong-timeout-when-using-crypto.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0277-PMTUd-add-ability-to-manually-override-MTU-and-disab.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0278-build-bump-soname-to-indicate-new-API-call.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0279-Default-compress-level-use.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0280-compress-Default-compression-level-use.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0281-compress-fix-a-few-minor-space-vs-tab-and-code-forma.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0282-compress-fix-if-def-around-BZIP2-testing.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0283-coverity-add-.travis.yml-to-integrate-CI-with-coveri.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0284-sctp-fix-deference-after-null-check.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0285-sctp-free-access-list-only-if-the-socket-is-valid.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0286-rx-align-data-types.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0287-handle-make-sure-that-the-pmtud-buf-contains-at-leas.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0288-sctp-revalidate-fd-to-make-coverity-scan-happy.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0289-tests-fix-knet_bench-coverity-errors.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0290-common-fix-dlopen-error-handling.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0291-rx-better-error-report-if-we-can-t-resolve-hostname-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0292-acl-avoid-forward-null-deferencing.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0293-sctp-cleanup-bugs-detected-in-error-paths-by-coverit.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0294-nozzle-fix-negative-return-detected-by-coverity-scan.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0295-nozzle-don-t-leak-memory-on-error.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0296-compress-don-t-leak-memory-in-case-of-errors-during-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0297-logging-make-sure-not-to-overrun-buffers-by-pre-allo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0298-compress-do-not-overrun-allocated-array-for-compress.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0299-coverity-add-test-targets-to-run-coverity-automatica.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0300-PMTUd-do-not-double-unlock-global-read-lock.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0301-nozzle-avoid-tons-of-possible-buffer-overruns.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0302-test-simplify-flush-log.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0303-common-make-sure-string-is-null-terminated.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0304-tx-drop-unnecessary-usleep-when-sending-to-localhost.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0305-nozzle-fix-a-few-coverity-errors-in-the-test-suite.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0306-tx-clean-up-channel-management-code-for-internal-com.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0307-sctp-retry-locking-in-case-of-failure.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0308-man-Fix-priority-description-of-POLICY_PASSIVE.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0309-common-Include-correct-errno.h.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0310-common-Conditionalize-RTLD_DI_ORIGIN.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0311-handle-Set-thread-stack-size-on-create.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0312-links-stabilize-latency-calculation-when-nodes-are-n.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0313-pmtud-switch-to-use-async-version-of-dstcache-update.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0314-nozzle-fix-tapX-range-on-newer-FreeBSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0315-tests-fix-ip-generation-boundaries.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0316-tests-give-PMTUd-more-time-to-redetect-MTU.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0317-links-fix-memory-corryption-of-link-structure.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0318-tests-skip-the-SCTP-test-if-SCTP-is-not-supported-by.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0319-Fix-typo-trasport-transport.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0320-tests-add-common-function-to-sleep-based-on-how-the-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0321-host-rename-variables-to-make-it-easier-to-read-the-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0322-host-fix-defrag-buffers-reclaim-logic.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0323-rx-copy-data-into-the-defrag-buffer-only-if-we-know-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0324-test-add-ability-to-knet_bench-to-specify-a-fixed-pa.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0325-PMTUd-invalidate-MTU-for-a-link-if-the-value-is-lowe.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0326-test-add-packet-verification-option-to-knet_bench.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0327-test-append-newline-to-knet_send-timeout-message.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0328-build-fix-openssl-version-detection-when-not-using-p.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0329-RX-Discard-incoming-packets-if-knet-cannot-reply-bac.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0330-RX-handle-short-write-to-the-application-properly.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0331-TX-discard-too-big-packets-when-reading-from-socketp.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0332-RX-silence-defrag-buffer-expiration-debug-error.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0333-handle-make-sure-to-unlock-config-handle-on-failure.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0334-handle-fix-typo-in-error-log-message.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0335-tests-mark-array-as-static.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0336-host-use-KNET_MAX_HOST_LEN-consistently.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0337-nozzle-use-interface-name-size-consistently-and-drop.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0338-udp-don-t-make-socket-spin-if-a-network-I-F-is-down.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0339-udp-simplify-code-same-logic.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0340-udp-Better-fix-for-ENETUNREACH.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0341-latency-fix-incorrect-math-that-could-lead-to-bad-la.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0342-rx-unify-latency-values-to-a-capped-value-to-link-pr.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0343-rx-send-reply-packets-only-when-transport-is-connect.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0344-rx-Don-t-return-512-EOF-messages-from-_recvmmsg.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0345-tx-Don-t-Clear-out-msghdr-for-all-transports.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0346-rx-use-defines-to-determine-RX-data-types-vs-random-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0347-sctp-major-surgery-to-use-only-SCTP-events-to-determ.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0348-global-Update-copyright-across-the-board.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0349-man-Fix-covscan-reports-in-doxyxml.c.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0350-man-Change-strcat-to-strncat.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0351-man-Enhance-prio-description-of-POLICY_PASSIVE.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0352-transports-use-SO_REUSEADDR-only-for-sctp.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0353-tests-rework-test-suite-link-port-allocation.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0354-rx-kill-unused-variable.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0355-stats-allow-knet_handle_get_stats-to-operate-in-a-re.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0356-stats-allow-knet_link_get_status-to-operate-in-readl.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0357-tests-fix-return-code-from-wait_for_packet.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0358-lists-fix-build-with-recent-gcc-changes.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0359-lists-drop-internal-implementation-and-use-libqb-one.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0360-lists-add-missing-build-CFLAGS-for-test-suite.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0361-build-make-sure-to-use-correct-libqb-include-files-a.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0362-man-use-libqb-version-of-doxygen2man-when-available.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0363-sctp-make-sure-outgoing-connections-are-bound-to-a-s.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0364-links-fix-spacing.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0365-netutils-move-sockaddr_len-definition-where-it-belon.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0366-sctp-fix-ifup-ifdown-handling-for-connected-sockets.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0367-transport-notify-transports-that-a-link-is-down.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0368-Always-define-the-Automake-conditional.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0369-tests-strip-extra-symbol-information-generated-by-ne.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0370-openssl-allow-use-of-deprecated-HMAC-interface-with-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0371-man-sync-doxygen2man-from-libqb-master.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0372-build-Fix-fallback-handling-in-git-version-gen.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0373-build-Use-git-version-gen-during-specfile-build.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0374-tests-remove-unnecessary-shutdown-locking.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0375-tests-use-link_get_enable-instead-of-get_status.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0376-tests-add-basic-framework-to-create-join-and-stop-ma.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0377-tests-sets-defaults-for-coverity-scan-check-to-match.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0378-build-update-valgrind-memcheck-exception-file.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0379-crypto-add-support-for-live-reconfiguration.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0380-Update-copyright.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0381-tests-fix-variable-increment-logic-detected-by-clang.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0382-tests-ignore-openssl-errors-triggered-when-building-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0383-tests-more-ignore-list-of-nss-internal-stuff.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0384-man-fix-type-comparison.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0385-f6b11c05112c520ccda3b28e7676acbc6b8a7938.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0386-crypto-add-support-for-openssl-3.0.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0387-cleanup-Move-public-APIs-calls-to-more-suitable-loca.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0388-cleanup-kill-all-unsupported-kronosnetd-code.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0389-cleanup-drop-no-longer-used-poc-code.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0390-threads-make-sure-to-initialize-events.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0391-rx-fix-per-link-stats-for-data-packets.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0392-rx-fix-data-stats-on-RX-to-match-TX-model.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0393-tests-hide-internal-nss-memory-leak-non-recurring.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0394-heartbeat-don-t-send-ping-if-transport-is-not-connec.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0395-Revert-heartbeat-don-t-send-ping-if-transport-is-not.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0396-sctp-check-and-warn-about-internal-fd-tracker.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0397-cleanup-remove-unused-infrastructure-to-send-HOSTINF.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0398-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0399-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0400-tests-hide-another-internal-libnss-non-recurring-mem.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0401-Drop-travis-support.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0402-tests-Fix-some-random-CI-failures.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0403-tests-use-callbacks-to-wait-for-nodes.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0404-Add-some-more-uses-for-event-based-tests.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0405-openssl-port-knet-top-openssl3.0-alpha13.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0406-docs-Update-README-for-BSD-section.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0407-global-Update-copyright.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0408-handle-validate-handle-in-public-API.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0409-nozzle-Remove-inet_ntoa-call.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0410-lib-Don-t-use-rpath.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0411-nozzle-fix-nozzle_up-on-FreeBSD.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0412-coverity-fix-2-buffer-initialization-potential-issue.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0413-docs-IRC-channel-is-now-on-Libera-Chat.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0414-send-correct-sockaddr-lengths-to-socket-calls.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0415-tx-minor-optimizations-to-avoid-recalculating-socksi.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0416-Require-make-utility.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0417-Update-copyright-around.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0418-Sanitise-sockaddr_storage-structs-coming-in-the-API.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0419-Add-comment-about-log_fd-in-knet_handle_new.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0420-spec-cleanup-some-krosnonetd-leftovers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0421-tests-suppress-more-libnss3-errors.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0422-link-don-t-leak-resources-if-link-configuration-fail.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0423-link-use-previously-cached-value-as-link-info-might-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0424-link-don-t-allow-mix-of-dynamic-and-static-links.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0425-doc-Add-comments-to-structure-members.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0426-man-update-doxygen2man-to-latest-from-libqb.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0427-rx-increase-defrag-buffers-to-better-deal-with-netwo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0428-host-use-correct-seq_num-to-reclaim-buffers.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0429-acl-make-knet_link_add_acl-a-wrapper-to-knet_link_in.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0430-acl-major-internal-rework.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0431-transports-remove-unused-internal-ACL-API.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0432-send-Fix-send_sync.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0433-tests-make-execution-of-functional-testing-optionals.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0434-test-Use-a-pipe-to-synchronise-wait_for_xxx-events.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0435-nozzle-skip-tests-if-TUN-support-is-not-available.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0436-nozzle-preserve-test-result-across-cleanup.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0437-nozzle-fix-tests-on-machines-that-don-t-have-bash.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0438-build-Add-annobin-build-check-support.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0439-tests-temporary-disable-annobin-lto-check-for-centos.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0440-libknet-tests-Correct-include-path-for-poll.h.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0441-build-fix-debug-build-vs-annocheck-parameters.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0442-crypto-fix-nss-crypto-buffer-boundaries-usage.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0443-host-fix-dst_seq_num-initialization-race-condition.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0444-udp-use-ICMP-error-messages-to-trigger-faster-link-d.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0445-crypto-improve-logging-when-failing-to-decrypt-packe.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0446-logging-slow-down-knet-a-bit-when-log-socket-is-busy.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0447-doc-update-links-to-mailing-lists-and-drop-obsolete-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0448-build-fix-flag-detections-for-gcc.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0449-UDP-Check-for-EHOSTUNREACH.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0450-tests-move-all-tests-to-new-infrastructure.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0451-tests-update-memcheck-exceptions.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0452-tests-deal-with-new-annocheck-symlink-checks.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0453-tx-fix-epoll-event-size-to-cope-with-extra-event-on-.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0454-logging-Fix-Initializing-typo.patch
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet/0455-doc-To-Do-list-moved-to-projects.clusterlabs.org-379.patch
 delete mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet_1.24.bb
 create mode 100644 meta-networking/recipes-extended/kronosnet/kronosnet_1.90.bb
diff mbox series

Patch

diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0001-build-determine-SOURCE_EPOCH-during-configuration.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0001-build-determine-SOURCE_EPOCH-during-configuration.patch
new file mode 100644
index 000000000..012298dba
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0001-build-determine-SOURCE_EPOCH-during-configuration.patch
@@ -0,0 +1,61 @@ 
+From f3d6e21b2f4f55b13b7a7c2d01452f6cb6149d69 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Thu, 22 Mar 2018 10:29:07 +0100
+Subject: [PATCH] build: determine SOURCE_EPOCH during configuration
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ .gitattributes |  1 +
+ configure.ac   | 28 ++++++++++++++++++++++++++++
+ 2 files changed, 29 insertions(+)
+ create mode 100644 .gitattributes
+
+diff --git a/.gitattributes b/.gitattributes
+new file mode 100644
+index 00000000..2418181b
+--- /dev/null
++++ b/.gitattributes
+@@ -0,0 +1 @@
++configure.ac export-subst
+diff --git a/configure.ac b/configure.ac
+index bd122016..f6bcbb38 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -454,6 +454,34 @@ done
+ 
+ AC_SUBST([AM_CFLAGS],["$OPT_CFLAGS $GDB_FLAGS $EXTRA_WARNINGS"])
+ 
++AC_ARG_VAR([SOURCE_EPOCH],[last modification date of the source])
++AC_MSG_NOTICE([trying to determine source epoch])
++AC_MSG_CHECKING([for source epoch in \$SOURCE_EPOCH])
++AS_IF([test -n "$SOURCE_EPOCH"],
++	[AC_MSG_RESULT([yes])],
++	[AC_MSG_RESULT([no])
++	 AC_MSG_CHECKING([for source epoch in source_epoch file])
++	 AS_IF([test -e source_epoch],
++		[read SOURCE_EPOCH <source_epoch
++		 AC_MSG_RESULT([yes])],
++		[AC_MSG_RESULT([no])
++		 AC_MSG_CHECKING([for source epoch baked in by gitattributes export-subst])
++		 SOURCE_EPOCH='$Format:%at$' # template for rewriting by git-archive
++		 AS_CASE([$SOURCE_EPOCH],
++			[?Format:*], # was not rewritten
++				[AC_MSG_RESULT([no])
++				 AC_MSG_CHECKING([whether git log can provide a source epoch])
++				 SOURCE_EPOCH=f${SOURCE_EPOCH#\$F} # convert into git log --pretty format
++				 SOURCE_EPOCH=$(git -C "$srcdir" log -1 --pretty=${SOURCE_EPOCH%$} 2>/dev/null)
++				 AS_IF([test -n "$SOURCE_EPOCH"],
++					[AC_MSG_RESULT([yes])],
++					[AC_MSG_RESULT([no, using current time and breaking reproducibility])
++					 SOURCE_EPOCH=$(date +%s)])],
++			[AC_MSG_RESULT([yes])]
++		 )])
++	])
++AC_MSG_NOTICE([using source epoch $(date --iso-8601=s --utc -d @$SOURCE_EPOCH)])
++
+ AC_CONFIG_FILES([
+ 		Makefile
+ 		init/Makefile
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0002-build-distribute-the-source_epoch-file.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0002-build-distribute-the-source_epoch-file.patch
new file mode 100644
index 000000000..d03c583c6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0002-build-distribute-the-source_epoch-file.patch
@@ -0,0 +1,25 @@ 
+From 9f6d5727de1902f65771c5c041385d85047d5907 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Thu, 22 Mar 2018 12:12:33 +0100
+Subject: [PATCH] build: distribute the source_epoch file
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/Makefile.am b/Makefile.am
+index d5657687..fe19313c 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -191,6 +191,7 @@ BUILT_SOURCES	= .version
+ 
+ dist-hook: gen-ChangeLog
+ 	echo $(VERSION) > $(distdir)/.tarball-version
++	echo $(SOURCE_EPOCH) > $(distdir)/source_epoch
+ 
+ gen_start_date = 2000-01-01
+ .PHONY: gen-ChangeLog
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0003-man-Add-date-year-options-to-doxyxml.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0003-man-Add-date-year-options-to-doxyxml.patch
new file mode 100644
index 000000000..a9208731e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0003-man-Add-date-year-options-to-doxyxml.patch
@@ -0,0 +1,112 @@ 
+From 7755cdf544c2176e0eff5d3be2bb20e67c3c8fce Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 15 Mar 2018 14:08:20 +0000
+Subject: [PATCH] man: Add date & year options to doxyxml
+
+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+---
+ man/doxyxml.c | 35 +++++++++++++++++++++++++++++++----
+ 1 file changed, 31 insertions(+), 4 deletions(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index ebdda868..fdd2d072 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -44,6 +44,8 @@ static const char *header="Kronosnet Programmer's Manual";
+ static const char *output_dir="./";
+ static const char *xml_dir = XML_DIR;
+ static const char *xml_file = XML_FILE;
++static const char *manpage_date = NULL;
++static long manpage_year = LONG_MIN;
+ static struct qb_list_head params_list;
+ static struct qb_list_head retval_list;
+ static qb_map_t *function_map;
+@@ -432,6 +434,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ {
+ 	char manfilename[PATH_MAX];
+ 	char gendate[64];
++	const char *dateptr = gendate;
+ 	FILE *manfile;
+ 	time_t t;
+ 	struct tm *tm;
+@@ -455,6 +458,13 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	}
+ 	strftime(gendate, sizeof(gendate), "%Y-%m-%d", tm);
+ 
++	if (manpage_date) {
++		dateptr = manpage_date;
++	}
++	if (manpage_year == LONG_MIN) {
++		manpage_year = tm->tm_year+1900;
++	}
++
+ 	snprintf(manfilename, sizeof(manfilename), "%s/%s.%s", output_dir, name, man_section);
+ 	manfile = fopen(manfilename, "w+");
+ 	if (!manfile) {
+@@ -486,7 +496,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	/* Off we go */
+ 
+ 	fprintf(manfile, ".\\\"  Automatically generated man page, do not edit\n");
+-	fprintf(manfile, ".TH %s %s %s \"%s\" \"%s\"\n", name, man_section, gendate, package_name, header);
++	fprintf(manfile, ".TH %s %s %s \"%s\" \"%s\"\n", name, man_section, dateptr, package_name, header);
+ 
+ 	fprintf(manfile, ".SH NAME\n");
+ 	fprintf(manfile, "%s \\- %s\n", name, brief);
+@@ -580,7 +590,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	fprintf(manfile, ".hy\n");
+ 	fprintf(manfile, ".SH \"COPYRIGHT\"\n");
+ 	fprintf(manfile, ".PP\n");
+-	fprintf(manfile, "Copyright (C) 2010-%4d Red Hat, Inc. All rights reserved.\n", tm->tm_year+1900);
++	fprintf(manfile, "Copyright (C) 2010-%4ld Red Hat, Inc. All rights reserved.\n", manpage_year);
+ 	fclose(manfile);
+ 
+ 	/* Free the params & retval info */
+@@ -731,7 +741,7 @@ static void traverse_node(xmlNode *parentnode, const char *leafname, void (do_me
+ static void usage(char *name)
+ {
+ 	printf("Usage:\n");
+-	printf("      %s -[am] [-s <section>] [-p<packagename>] [-H <header>] [-o <output dir>] [<XML file>]\n", name);
++	printf("      %s [OPTIONS] [<XML file>]\n", name);
+ 	printf("\n");
+ 	printf("      <XML file> defaults to %s\n", XML_FILE);
+ 	printf("\n");
+@@ -741,6 +751,8 @@ static void usage(char *name)
+ 	printf("       -s <s>        Write man pages into section <s> <default 3)\n");
+ 	printf("       -p <package>  Use <package> name. default <Kronosnet>\n");
+ 	printf("       -H <header>   Set header (default \"Kronosnet Programmer's Manual\"\n");
++	printf("       -D <date>     Date to print at top of man pages (format not checked, default: today)\n");
++	printf("       -Y <year>     Year to print at end of copyright line (default: today's year)\n");
+ 	printf("       -o <dir>      Write all man pages to <dir> (default .)\n");
+ 	printf("       -d <dir>      Directory for XML files (default %s)\n", XML_DIR);
+ 	printf("       -h            Print this usage text\n");
+@@ -754,7 +766,7 @@ int main(int argc, char *argv[])
+ 	int opt;
+ 	char xml_filename[PATH_MAX];
+ 
+-	while ( (opt = getopt_long(argc, argv, "H:amPs:d:o:p:f:h?", NULL, NULL)) != EOF)
++	while ( (opt = getopt_long(argc, argv, "H:amPD:Y:s:d:o:p:f:h?", NULL, NULL)) != EOF)
+ 	{
+ 		switch(opt)
+ 		{
+@@ -775,6 +787,21 @@ int main(int argc, char *argv[])
+ 			case 'd':
+ 				xml_dir = optarg;
+ 				break;
++			case 'D':
++				manpage_date = optarg;
++				break;
++			case 'Y':
++				manpage_year = strtol(optarg, NULL, 10);
++				/*
++				 * Don't make too many assumptions about the year. I was on call at the
++				 * 2000 rollover. #experience
++				 */
++				if (manpage_year == LONG_MIN || manpage_year == LONG_MAX ||
++				    manpage_year < 1900) {
++					fprintf(stderr, "Value passed to -Y is not a valid year number\n");
++					return 1;
++				}
++				break;
+ 			case 'p':
+ 				package_name = optarg;
+ 				break;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0004-man-use-new-doxyxml-date-options-to-build-man-pages.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0004-man-use-new-doxyxml-date-options-to-build-man-pages.patch
new file mode 100644
index 000000000..959e062c2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0004-man-use-new-doxyxml-date-options-to-build-man-pages.patch
@@ -0,0 +1,30 @@ 
+From a448d3ec365c76bb70e9fd644bab39cb44f440ca Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Thu, 22 Mar 2018 14:18:18 +0100
+Subject: [PATCH] man: use new doxyxml date options to build man pages
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Based on Fabio's original patch.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ man/Makefile.am | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index ec53439e..de1e4bdc 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -101,7 +101,8 @@ $(MANS): doxyfile-knet.stamp
+ 
+ doxyfile-knet.stamp: $(builddir)/doxyxml Doxyfile-knet $(top_srcdir)/libknet/libknet.h
+ 	$(DOXYGEN) Doxyfile-knet
+-	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" -d $(builddir)/xml-knet/ libknet_8h.xml
++	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
++		$$(date --utc -d "@$(SOURCE_EPOCH)" +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
+ 	touch doxyfile-knet.stamp
+ 
+ endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0005-spec-use-the-source-epoch-here-as-well.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0005-spec-use-the-source-epoch-here-as-well.patch
new file mode 100644
index 000000000..1f8af4131
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0005-spec-use-the-source-epoch-here-as-well.patch
@@ -0,0 +1,26 @@ 
+From 9edc19cea0fcb077db526a1eebe76e5ec7a5594d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Thu, 22 Mar 2018 14:26:20 +0100
+Subject: [PATCH] spec: use the source epoch here as well
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index fe19313c..ec054701 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -56,7 +56,7 @@ distclean-local:
+ 
+ $(SPEC): $(SPEC).in .version config.status
+ 	rm -f $@-t $@
+-	date="`LC_ALL=C date "+%a %b %d %Y"`" && \
++	date="`LC_ALL=C date -d "@$(SOURCE_EPOCH)" "+%a %b %d %Y"`" && \
+ 	if [ -f $(abs_srcdir)/.tarball-version ]; then \
+ 		gitver="`cat $(abs_srcdir)/.tarball-version`" && \
+ 		rpmver=$$gitver && \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0006-build-accomodate-to-the-actual-date-utility.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0006-build-accomodate-to-the-actual-date-utility.patch
new file mode 100644
index 000000000..7834e5db2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0006-build-accomodate-to-the-actual-date-utility.patch
@@ -0,0 +1,214 @@ 
+From eae9f3239e6669a7c1578fad1d77b6d12db250f7 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Fri, 23 Mar 2018 15:33:53 +0100
+Subject: [PATCH] build: accomodate to the actual date utility
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ Makefile.am        |   2 +-
+ configure.ac       |  10 +++-
+ m4/ax_prog_date.m4 | 137 +++++++++++++++++++++++++++++++++++++++++++++
+ man/Makefile.am    |   2 +-
+ 4 files changed, 148 insertions(+), 3 deletions(-)
+ create mode 100644 m4/ax_prog_date.m4
+
+diff --git a/Makefile.am b/Makefile.am
+index ec054701..0dee6075 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -56,7 +56,7 @@ distclean-local:
+ 
+ $(SPEC): $(SPEC).in .version config.status
+ 	rm -f $@-t $@
+-	date="`LC_ALL=C date -d "@$(SOURCE_EPOCH)" "+%a %b %d %Y"`" && \
++	date="`LC_ALL=C $(UTC_DATE_AT)$(SOURCE_EPOCH) "+%a %b %d %Y"`" && \
+ 	if [ -f $(abs_srcdir)/.tarball-version ]; then \
+ 		gitver="`cat $(abs_srcdir)/.tarball-version`" && \
+ 		rpmver=$$gitver && \
+diff --git a/configure.ac b/configure.ac
+index f6bcbb38..b0163382 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -454,6 +454,14 @@ done
+ 
+ AC_SUBST([AM_CFLAGS],["$OPT_CFLAGS $GDB_FLAGS $EXTRA_WARNINGS"])
+ 
++AX_PROG_DATE
++AS_IF([test "$ax_cv_prog_date_gnu_date:$ax_cv_prog_date_gnu_utc" = yes:yes],
++	[UTC_DATE_AT="date -u -d@"],
++	[AS_IF([test "x$ax_cv_prog_date_bsd_date" = xyes],
++		[UTC_DATE_AT="date -u -r"],
++		[AC_MSG_ERROR([date utility unable to convert epoch to UTC])])])
++AC_SUBST([UTC_DATE_AT])
++
+ AC_ARG_VAR([SOURCE_EPOCH],[last modification date of the source])
+ AC_MSG_NOTICE([trying to determine source epoch])
+ AC_MSG_CHECKING([for source epoch in \$SOURCE_EPOCH])
+@@ -480,7 +488,7 @@ AS_IF([test -n "$SOURCE_EPOCH"],
+ 			[AC_MSG_RESULT([yes])]
+ 		 )])
+ 	])
+-AC_MSG_NOTICE([using source epoch $(date --iso-8601=s --utc -d @$SOURCE_EPOCH)])
++AC_MSG_NOTICE([using source epoch $($UTC_DATE_AT$SOURCE_EPOCH +'%F %T %Z')])
+ 
+ AC_CONFIG_FILES([
+ 		Makefile
+diff --git a/m4/ax_prog_date.m4 b/m4/ax_prog_date.m4
+new file mode 100644
+index 00000000..c85f0f24
+--- /dev/null
++++ b/m4/ax_prog_date.m4
+@@ -0,0 +1,137 @@
++# ===========================================================================
++#       https://www.gnu.org/software/autoconf-archive/ax_prog_date.html
++# ===========================================================================
++#
++# SYNOPSIS
++#
++#   AX_PROG_DATE()
++#
++# DESCRIPTION
++#
++#   This macro tries to determine the type of the date (1) command and some
++#   of its non-standard capabilities.
++#
++#   The type is determined as follow:
++#
++#     * If the version string contains "GNU", then:
++#       - The variable ax_cv_prog_date_gnu is set to "yes".
++#       - The variable ax_cv_prog_date_type is set to "gnu".
++#
++#     * If date supports the "-v 1d" option, then:
++#       - The variable ax_cv_prog_date_bsd is set to "yes".
++#       - The variable ax_cv_prog_date_type is set to "bsd".
++#
++#     * If both previous checks fail, then:
++#       - The variable ax_cv_prog_date_type is set to "unknown".
++#
++#   The following capabilities of GNU date are checked:
++#
++#     * If date supports the --date arg option, then:
++#       - The variable ax_cv_prog_date_gnu_date is set to "yes".
++#
++#     * If date supports the --utc arg option, then:
++#       - The variable ax_cv_prog_date_gnu_utc is set to "yes".
++#
++#   The following capabilities of BSD date are checked:
++#
++#     * If date supports the -v 1d  option, then:
++#       - The variable ax_cv_prog_date_bsd_adjust is set to "yes".
++#
++#     * If date supports the -r arg option, then:
++#       - The variable ax_cv_prog_date_bsd_date is set to "yes".
++#
++#   All the aforementioned variables are set to "no" before a check is
++#   performed.
++#
++# LICENSE
++#
++#   Copyright (c) 2017 Enrico M. Crisostomo <enrico.m.crisostomo@gmail.com>
++#
++#   This program is free software: you can redistribute it and/or modify it
++#   under the terms of the GNU General Public License as published by the
++#   Free Software Foundation, either version 3 of the License, or (at your
++#   option) any later version.
++#
++#   This program is distributed in the hope that it will be useful, but
++#   WITHOUT ANY WARRANTY; without even the implied warranty of
++#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++#   Public License for more details.
++#
++#   You should have received a copy of the GNU General Public License along
++#   with this program. If not, see <http://www.gnu.org/licenses/>.
++#
++#   As a special exception, the respective Autoconf Macro's copyright owner
++#   gives unlimited permission to copy, distribute and modify the configure
++#   scripts that are the output of Autoconf when processing the Macro. You
++#   need not follow the terms of the GNU General Public License when using
++#   or distributing such scripts, even though portions of the text of the
++#   Macro appear in them. The GNU General Public License (GPL) does govern
++#   all other use of the material that constitutes the Autoconf Macro.
++#
++#   This special exception to the GPL applies to versions of the Autoconf
++#   Macro released by the Autoconf Archive. When you make and distribute a
++#   modified version of the Autoconf Macro, you may extend this special
++#   exception to the GPL to apply to your modified version as well.
++
++#serial 3
++
++AC_DEFUN([AX_PROG_DATE], [dnl
++  AC_CACHE_CHECK([for GNU date], [ax_cv_prog_date_gnu], [
++    ax_cv_prog_date_gnu=no
++    if date --version 2>/dev/null | head -1 | grep -q GNU
++    then
++      ax_cv_prog_date_gnu=yes
++    fi
++  ])
++  AC_CACHE_CHECK([for BSD date], [ax_cv_prog_date_bsd], [
++    ax_cv_prog_date_bsd=no
++    if date -v 1d > /dev/null 2>&1
++    then
++      ax_cv_prog_date_bsd=yes
++    fi
++  ])
++  AC_CACHE_CHECK([for date type], [ax_cv_prog_date_type], [
++    ax_cv_prog_date_type=unknown
++    if test "x${ax_cv_prog_date_gnu}" = "xyes"
++    then
++      ax_cv_prog_date_type=gnu
++    elif test "x${ax_cv_prog_date_bsd}" = "xyes"
++    then
++      ax_cv_prog_date_type=bsd
++    fi
++  ])
++  AS_VAR_IF([ax_cv_prog_date_gnu], [yes], [
++    AC_CACHE_CHECK([whether GNU date supports --date], [ax_cv_prog_date_gnu_date], [
++      ax_cv_prog_date_gnu_date=no
++      if date --date=@1512031231 > /dev/null 2>&1
++      then
++        ax_cv_prog_date_gnu_date=yes
++      fi
++    ])
++    AC_CACHE_CHECK([whether GNU date supports --utc], [ax_cv_prog_date_gnu_utc], [
++      ax_cv_prog_date_gnu_utc=no
++      if date --utc > /dev/null 2>&1
++      then
++        ax_cv_prog_date_gnu_utc=yes
++      fi
++    ])
++  ])
++  AS_VAR_IF([ax_cv_prog_date_bsd], [yes], [
++    AC_CACHE_CHECK([whether BSD date supports -r], [ax_cv_prog_date_bsd_date], [
++      ax_cv_prog_date_bsd_date=no
++      if date -r 1512031231 > /dev/null 2>&1
++      then
++        ax_cv_prog_date_bsd_date=yes
++      fi
++    ])
++  ])
++    AS_VAR_IF([ax_cv_prog_date_bsd], [yes], [
++    AC_CACHE_CHECK([whether BSD date supports -v], [ax_cv_prog_date_bsd_adjust], [
++      ax_cv_prog_date_bsd_adjust=no
++      if date -v 1d > /dev/null 2>&1
++      then
++        ax_cv_prog_date_bsd_adjust=yes
++      fi
++    ])
++  ])
++])dnl AX_PROG_DATE
+diff --git a/man/Makefile.am b/man/Makefile.am
+index de1e4bdc..9f2741b1 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -102,7 +102,7 @@ $(MANS): doxyfile-knet.stamp
+ doxyfile-knet.stamp: $(builddir)/doxyxml Doxyfile-knet $(top_srcdir)/libknet/libknet.h
+ 	$(DOXYGEN) Doxyfile-knet
+ 	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+-		$$(date --utc -d "@$(SOURCE_EPOCH)" +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
++		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
+ 	touch doxyfile-knet.stamp
+ 
+ endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0007-build-git-C-is-a-relatively-new-option-avoid-it.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0007-build-git-C-is-a-relatively-new-option-avoid-it.patch
new file mode 100644
index 000000000..19cec2e0b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0007-build-git-C-is-a-relatively-new-option-avoid-it.patch
@@ -0,0 +1,26 @@ 
+From a7033cc891eb17ed1ebff98a88d215f49c74ec8a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Fri, 23 Mar 2018 15:46:16 +0100
+Subject: [PATCH] build: git -C is a relatively new option, avoid it
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index b0163382..69b36c5d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -480,7 +480,7 @@ AS_IF([test -n "$SOURCE_EPOCH"],
+ 				[AC_MSG_RESULT([no])
+ 				 AC_MSG_CHECKING([whether git log can provide a source epoch])
+ 				 SOURCE_EPOCH=f${SOURCE_EPOCH#\$F} # convert into git log --pretty format
+-				 SOURCE_EPOCH=$(git -C "$srcdir" log -1 --pretty=${SOURCE_EPOCH%$} 2>/dev/null)
++				 SOURCE_EPOCH=$(cd "$srcdir" && git log -1 --pretty=${SOURCE_EPOCH%$} 2>/dev/null)
+ 				 AS_IF([test -n "$SOURCE_EPOCH"],
+ 					[AC_MSG_RESULT([yes])],
+ 					[AC_MSG_RESULT([no, using current time and breaking reproducibility])
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0008-build-fail-and-provide-proper-error-if-source-tree-v.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0008-build-fail-and-provide-proper-error-if-source-tree-v.patch
new file mode 100644
index 000000000..f04f74193
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0008-build-fail-and-provide-proper-error-if-source-tree-v.patch
@@ -0,0 +1,37 @@ 
+From 575a076bd90e4eedfb682590181c11ea7fc16b4c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 13 Mar 2018 15:44:11 +0100
+Subject: [PATCH] [build] fail and provide proper error if source tree version
+ is unknown
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ configure.ac | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/configure.ac b/configure.ac
+index 69b36c5d..90e0b056 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -507,4 +507,17 @@ AC_CONFIG_FILES([
+ 		poc-code/access-list/Makefile
+ 		])
+ 
++if test "x$VERSION" = "xUNKNOWN"; then
++	AC_MSG_ERROR([m4_text_wrap([
++  configure was unable to determine the source tree's current version. This
++  generally happens when using git archive (or the github download button)
++  generated tarball/zip file. In order to workaround this issue, either use git
++  clone https://github.com/kronosnet/kronosnet.git or use an official release
++  tarball, available at https://kronosnet.org/releases/.  Alternatively you
++  can add a compatible version in a .tarball-version file at the top of the
++  source tree, wipe your autom4te.cache dir and generated configure, and rerun
++  autogen.sh.
++  ], [  ], [   ], [76])])
++fi
++
+ AC_OUTPUT
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0009-build-check-for-SOURCE_DATE_EPOCH-before-turning-to-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0009-build-check-for-SOURCE_DATE_EPOCH-before-turning-to-.patch
new file mode 100644
index 000000000..fbfcec9bd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0009-build-check-for-SOURCE_DATE_EPOCH-before-turning-to-.patch
@@ -0,0 +1,44 @@ 
+From a89e6c3191b4ff00eb34d540ec3cc9cd075d6c6d Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Sun, 25 Mar 2018 22:07:25 +0200
+Subject: [PATCH] build: check for SOURCE_DATE_EPOCH before turning to Git for
+ an epoch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ configure.ac | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 90e0b056..ed4c7d7c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -478,13 +478,18 @@ AS_IF([test -n "$SOURCE_EPOCH"],
+ 		 AS_CASE([$SOURCE_EPOCH],
+ 			[?Format:*], # was not rewritten
+ 				[AC_MSG_RESULT([no])
+-				 AC_MSG_CHECKING([whether git log can provide a source epoch])
+-				 SOURCE_EPOCH=f${SOURCE_EPOCH#\$F} # convert into git log --pretty format
+-				 SOURCE_EPOCH=$(cd "$srcdir" && git log -1 --pretty=${SOURCE_EPOCH%$} 2>/dev/null)
+-				 AS_IF([test -n "$SOURCE_EPOCH"],
+-					[AC_MSG_RESULT([yes])],
+-					[AC_MSG_RESULT([no, using current time and breaking reproducibility])
+-					 SOURCE_EPOCH=$(date +%s)])],
++				 AC_MSG_CHECKING([for source epoch in \$SOURCE_DATE_EPOCH])
++				 AS_IF([test "x$SOURCE_DATE_EPOCH" != x],
++					[SOURCE_EPOCH="$SOURCE_DATE_EPOCH"
++					 AC_MSG_RESULT([yes])],
++					[AC_MSG_RESULT([no])
++					 AC_MSG_CHECKING([whether git log can provide a source epoch])
++					 SOURCE_EPOCH=f${SOURCE_EPOCH#\$F} # convert into git log --pretty format
++					 SOURCE_EPOCH=$(cd "$srcdir" && git log -1 --pretty=${SOURCE_EPOCH%$} 2>/dev/null)
++					 AS_IF([test -n "$SOURCE_EPOCH"],
++						[AC_MSG_RESULT([yes])],
++						[AC_MSG_RESULT([no, using current time and breaking reproducibility])
++						 SOURCE_EPOCH=$(date +%s)])])],
+ 			[AC_MSG_RESULT([yes])]
+ 		 )])
+ 	])
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0010-build-look-for-source_epoch-in-srcdir.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0010-build-look-for-source_epoch-in-srcdir.patch
new file mode 100644
index 000000000..ff23f9355
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0010-build-look-for-source_epoch-in-srcdir.patch
@@ -0,0 +1,28 @@ 
+From 73bf72cb044ec70cfc86674c7f535aadf95d535f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 26 Mar 2018 10:56:36 +0200
+Subject: [PATCH] build: look for source_epoch in srcdir
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ configure.ac | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index ed4c7d7c..85ac60c9 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -469,8 +469,8 @@ AS_IF([test -n "$SOURCE_EPOCH"],
+ 	[AC_MSG_RESULT([yes])],
+ 	[AC_MSG_RESULT([no])
+ 	 AC_MSG_CHECKING([for source epoch in source_epoch file])
+-	 AS_IF([test -e source_epoch],
+-		[read SOURCE_EPOCH <source_epoch
++	 AS_IF([test -e "$srcdir/source_epoch"],
++		[read SOURCE_EPOCH <"$srcdir/source_epoch"
+ 		 AC_MSG_RESULT([yes])],
+ 		[AC_MSG_RESULT([no])
+ 		 AC_MSG_CHECKING([for source epoch baked in by gitattributes export-subst])
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0011-crypto-improve-checks-around-RX-packet-size.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0011-crypto-improve-checks-around-RX-packet-size.patch
new file mode 100644
index 000000000..068a754b0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0011-crypto-improve-checks-around-RX-packet-size.patch
@@ -0,0 +1,90 @@ 
+From 899bfd262f11c2a64f0efb29e11a6a1f63bdc45d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 20 Apr 2018 06:19:13 +0200
+Subject: [PATCH] [crypto] improve checks around RX packet size
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_nss.c     |  8 ++++++--
+ libknet/crypto_openssl.c | 14 +++++++++++---
+ 2 files changed, 17 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index b2eff193..fb2c80ba 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -426,6 +426,11 @@ static int decrypt_nss (
+ 	int		datalen = buf_in_len - SALT_SIZE;
+ 	int		err = -1;
+ 
++	if (datalen <= 0) {
++		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Packet is too short");
++		goto out;
++	}
++
+ 	/* Create cipher context for decryption */
+ 	decrypt_param.type = siBuffer;
+ 	decrypt_param.data = salt;
+@@ -466,7 +471,6 @@ out:
+ 	return err;
+ }
+ 
+-
+ /*
+  * hash/hmac/digest functions
+  */
+@@ -672,7 +676,7 @@ static int nsscrypto_authenticate_and_decrypt (
+ 		unsigned char tmp_hash[nsshash_len[instance->crypto_hash_type]];
+ 		ssize_t temp_buf_len = buf_in_len - nsshash_len[instance->crypto_hash_type];
+ 
+-		if ((temp_buf_len < 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
++		if ((temp_buf_len <= 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
+ 			log_err(knet_h, KNET_SUB_NSSCRYPTO, "Incorrect packet size.");
+ 			return -1;
+ 		}
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 13e2d8f4..93ebc4fd 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -229,7 +229,7 @@ static int decrypt_openssl (
+ 	ssize_t *buf_out_len)
+ {
+ 	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
+-	EVP_CIPHER_CTX	*ctx;
++	EVP_CIPHER_CTX	*ctx = NULL;
+ 	int		tmplen1 = 0, tmplen2 = 0;
+ 	unsigned char	*salt = (unsigned char *)buf_in;
+ 	unsigned char	*data = salt + SALT_SIZE;
+@@ -237,6 +237,12 @@ static int decrypt_openssl (
+ 	int		err = 0;
+ 	char		sslerr[SSLERR_BUF_SIZE];
+ 
++	if (datalen <= 0) {
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Packet is too short");
++		err = -1;
++		goto out;
++	}
++
+ 	ctx = EVP_CIPHER_CTX_new();
+ 
+ 	/*
+@@ -266,7 +272,9 @@ static int decrypt_openssl (
+ 	*buf_out_len = tmplen1 + tmplen2;
+ 
+ out:
+-	EVP_CIPHER_CTX_free(ctx);
++	if (ctx) {
++		EVP_CIPHER_CTX_free(ctx);
++	}
+ 	return err;
+ }
+ #endif
+@@ -366,7 +374,7 @@ static int opensslcrypto_authenticate_and_decrypt (
+ 		unsigned char tmp_hash[knet_h->sec_hash_size];
+ 		ssize_t temp_buf_len = buf_in_len - knet_h->sec_hash_size;
+ 
+-		if ((temp_buf_len < 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
++		if ((temp_buf_len <= 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
+ 			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Incorrect packet size.");
+ 			return -1;
+ 		}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0012-crypto-NSS_NoDB_Init-the-parameter-is-reserved-must-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0012-crypto-NSS_NoDB_Init-the-parameter-is-reserved-must-.patch
new file mode 100644
index 000000000..9d7225989
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0012-crypto-NSS_NoDB_Init-the-parameter-is-reserved-must-.patch
@@ -0,0 +1,26 @@ 
+From c0ad32444d32375b57a4fffdc352843283032cf2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 20 Apr 2018 14:36:12 +0200
+Subject: [PATCH] [crypto] NSS_NoDB_Init: the parameter is reserved, must be
+ NULL
+
+Thanks to Feri for spotting it in corosync
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_nss.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index fb2c80ba..9191d9a3 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -590,7 +590,7 @@ static int init_nss(knet_handle_t knet_h)
+ 	}
+ 
+ 	if (!nss_db_is_init) {
+-		if (NSS_NoDB_Init(".") != SECSuccess) {
++		if (NSS_NoDB_Init(NULL) != SECSuccess) {
+ 			log_err(knet_h, KNET_SUB_NSSCRYPTO, "NSS DB initialization failed (err %d): %s",
+ 				PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
+ 			errno = EAGAIN;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0013-flush_logs-remove-redundant-condition.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0013-flush_logs-remove-redundant-condition.patch
new file mode 100644
index 000000000..b5ec32369
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0013-flush_logs-remove-redundant-condition.patch
@@ -0,0 +1,42 @@ 
+From 5ce1dddc50e028d53f7134d8b83f8d929e877e64 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 15:53:33 +0200
+Subject: [PATCH] flush_logs: remove redundant condition
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The read loop is always entered, resetting len and returning from the
+function if it isn't greater than 0.
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index e32b47ed..075830b5 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -222,7 +222,6 @@ void flush_logs(int logfd, FILE *std)
+ 	int len;
+ 
+ next:
+-	len = 0;
+ 	bytes_read = 0;
+ 	memset(&msg, 0, sizeof(struct knet_log_msg));
+ 
+@@ -235,13 +234,11 @@ next:
+ 		bytes_read += len;
+ 	}
+ 
+-	if (len > 0) {
+ 		fprintf(std, "[knet]: [%s] %s: %s\n",
+ 			knet_log_get_loglevel_name(msg.msglevel),
+ 			knet_log_get_subsystem_name(msg.subsystem),
+ 			msg.msg);
+ 		goto next;
+-	}
+ }
+ 
+ static void *_logthread(void *args)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0014-flush_logs-the-reads-will-overwrite-the-entire-msg-s.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0014-flush_logs-the-reads-will-overwrite-the-entire-msg-s.patch
new file mode 100644
index 000000000..44900fffd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0014-flush_logs-the-reads-will-overwrite-the-entire-msg-s.patch
@@ -0,0 +1,25 @@ 
+From f1f5bc55a03e90cb275c22abfef086431d7749bd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 15:56:34 +0200
+Subject: [PATCH] flush_logs: the reads will overwrite the entire msg structure
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 075830b5..5daa0cd4 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -223,7 +223,6 @@ void flush_logs(int logfd, FILE *std)
+ 
+ next:
+ 	bytes_read = 0;
+-	memset(&msg, 0, sizeof(struct knet_log_msg));
+ 
+ 	while (bytes_read < sizeof(struct knet_log_msg)) {
+ 		len = read(logfd, &msg + bytes_read,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0015-flush_logs-don-t-repeat-the-type-of-msg.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0015-flush_logs-don-t-repeat-the-type-of-msg.patch
new file mode 100644
index 000000000..cb05af71a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0015-flush_logs-don-t-repeat-the-type-of-msg.patch
@@ -0,0 +1,29 @@ 
+From e61982add55fd47654532a8c6f1e7e906edc6b59 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 15:59:22 +0200
+Subject: [PATCH] flush_logs: don't repeat the type of msg
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 5daa0cd4..ed9c60a3 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -224,9 +224,9 @@ void flush_logs(int logfd, FILE *std)
+ next:
+ 	bytes_read = 0;
+ 
+-	while (bytes_read < sizeof(struct knet_log_msg)) {
++	while (bytes_read < sizeof msg) {
+ 		len = read(logfd, &msg + bytes_read,
+-			   sizeof(struct knet_log_msg) - bytes_read);
++			   sizeof msg - bytes_read);
+ 		if (len <= 0) {
+ 			return;
+ 		}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0016-flush_logs-a-for-loop-is-more-straightforward-here.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0016-flush_logs-a-for-loop-is-more-straightforward-here.patch
new file mode 100644
index 000000000..5e67c44eb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0016-flush_logs-a-for-loop-is-more-straightforward-here.patch
@@ -0,0 +1,32 @@ 
+From 0f00faffcbdd5f3685096e4e157fb530c9c70571 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 16:02:58 +0200
+Subject: [PATCH] flush_logs: a for loop is more straightforward here
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index ed9c60a3..c4a8c22a 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -218,13 +218,10 @@ void close_logpipes(int *logfds)
+ void flush_logs(int logfd, FILE *std)
+ {
+ 	struct knet_log_msg msg;
+-	size_t bytes_read;
+ 	int len;
+ 
+ next:
+-	bytes_read = 0;
+-
+-	while (bytes_read < sizeof msg) {
++	for (size_t bytes_read = 0; bytes_read < sizeof msg; ) {
+ 		len = read(logfd, &msg + bytes_read,
+ 			   sizeof msg - bytes_read);
+ 		if (len <= 0) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0017-flush_logs-while-loop-instead-of-goto.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0017-flush_logs-while-loop-instead-of-goto.patch
new file mode 100644
index 000000000..34aac94a1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0017-flush_logs-while-loop-instead-of-goto.patch
@@ -0,0 +1,53 @@ 
+From e1acd84d2c3035f3307b80c18bf6774407c7dba8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 16:14:14 +0200
+Subject: [PATCH] flush_logs: while loop instead of goto
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 23 +++++++++++------------
+ 1 file changed, 11 insertions(+), 12 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index c4a8c22a..8240c8fc 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -217,24 +217,23 @@ void close_logpipes(int *logfds)
+ 
+ void flush_logs(int logfd, FILE *std)
+ {
+-	struct knet_log_msg msg;
+-	int len;
+-
+-next:
+-	for (size_t bytes_read = 0; bytes_read < sizeof msg; ) {
+-		len = read(logfd, &msg + bytes_read,
+-			   sizeof msg - bytes_read);
+-		if (len <= 0) {
+-			return;
++	while (1) {
++		struct knet_log_msg msg;
++
++		for (size_t bytes_read = 0; bytes_read < sizeof msg; ) {
++			int len = read(logfd, &msg + bytes_read,
++				       sizeof msg - bytes_read);
++			if (len <= 0) {
++				return;
++			}
++			bytes_read += len;
+ 		}
+-		bytes_read += len;
+-	}
+ 
+ 		fprintf(std, "[knet]: [%s] %s: %s\n",
+ 			knet_log_get_loglevel_name(msg.msglevel),
+ 			knet_log_get_subsystem_name(msg.subsystem),
+ 			msg.msg);
+-		goto next;
++	}
+ }
+ 
+ static void *_logthread(void *args)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0018-flush_logs-don-t-ever-print-past-the-message-buffer.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0018-flush_logs-don-t-ever-print-past-the-message-buffer.patch
new file mode 100644
index 000000000..4bba76fbd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0018-flush_logs-don-t-ever-print-past-the-message-buffer.patch
@@ -0,0 +1,48 @@ 
+From 06b7ed32af3b449b86765831972e1d45bac4abb4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 16:17:59 +0200
+Subject: [PATCH] flush_logs: don't ever print past the message buffer
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/libknet.h           | 4 ++--
+ libknet/tests/test-common.c | 4 ++--
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 976ca911..17e44da8 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1915,10 +1915,10 @@ uint8_t knet_log_get_loglevel_id(const char *name);
+  * straight to stdout/stderr (see knet_bench.c stdout option).
+  */
+ 
+-#define KNET_MAX_LOG_MSG_SIZE    256
++#define KNET_MAX_LOG_MSG_SIZE    254
+ 
+ struct knet_log_msg {
+-	char	msg[KNET_MAX_LOG_MSG_SIZE - (sizeof(uint8_t)*2)];
++	char	msg[KNET_MAX_LOG_MSG_SIZE];
+ 	uint8_t	subsystem;	/* KNET_SUB_* */
+ 	uint8_t msglevel;	/* KNET_LOG_* */
+ };
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 8240c8fc..c50a9e4b 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -229,10 +229,10 @@ void flush_logs(int logfd, FILE *std)
+ 			bytes_read += len;
+ 		}
+ 
+-		fprintf(std, "[knet]: [%s] %s: %s\n",
++		fprintf(std, "[knet]: [%s] %s: %.*s\n",
+ 			knet_log_get_loglevel_name(msg.msglevel),
+ 			knet_log_get_subsystem_name(msg.subsystem),
+-			msg.msg);
++			KNET_MAX_LOG_MSG_SIZE, msg.msg);
+ 	}
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0019-_logthread-select-returns-the-number-of-set-bits-as-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0019-_logthread-select-returns-the-number-of-set-bits-as-.patch
new file mode 100644
index 000000000..164203623
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0019-_logthread-select-returns-the-number-of-set-bits-as-.patch
@@ -0,0 +1,43 @@ 
+From 82fd098a09493a09ec8e1f4c2514a8495f51af91 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 18:03:21 +0200
+Subject: [PATCH] _logthread: select() returns the number of set bits, as an
+ int
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index c50a9e4b..ff4c1bf4 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -239,7 +239,7 @@ void flush_logs(int logfd, FILE *std)
+ static void *_logthread(void *args)
+ {
+ 	fd_set rfds;
+-	ssize_t len;
++	int num;
+ 	struct timeval tv;
+ 
+ select_loop:
+@@ -249,12 +249,12 @@ select_loop:
+ 	FD_ZERO(&rfds);
+ 	FD_SET(data.logfd, &rfds);
+ 
+-	len = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
+-	if (len < 0) {
++	num = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
++	if (num < 0) {
+ 		fprintf(data.std, "Unable select over logfd!\nHALTING LOGTHREAD!\n");
+ 		return NULL;
+ 	}
+-	if (!len) {
++	if (num == 0) {
+ 		fprintf(data.std, "[knet]: No logs in the last 60 seconds\n");
+ 	}
+ 	if (FD_ISSET(data.logfd, &rfds)) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0020-_logthread-while-loop-instead-of-goto.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0020-_logthread-while-loop-instead-of-goto.patch
new file mode 100644
index 000000000..bb228ea41
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0020-_logthread-while-loop-instead-of-goto.patch
@@ -0,0 +1,67 @@ 
+From 699ba543244cb15433bd0869ba260ee3c7f1341f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 18:11:25 +0200
+Subject: [PATCH] _logthread: while loop instead of goto
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/test-common.c | 40 +++++++++++++++++--------------------
+ 1 file changed, 18 insertions(+), 22 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index ff4c1bf4..0dba3392 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -238,31 +238,27 @@ void flush_logs(int logfd, FILE *std)
+ 
+ static void *_logthread(void *args)
+ {
+-	fd_set rfds;
+-	int num;
+-	struct timeval tv;
+-
+-select_loop:
+-	tv.tv_sec = 60;
+-	tv.tv_usec = 0;
++	while (1) {
++		int num;
++		struct timeval tv = { 60, 0 };
++		fd_set rfds;
+ 
+-	FD_ZERO(&rfds);
+-	FD_SET(data.logfd, &rfds);
++		FD_ZERO(&rfds);
++		FD_SET(data.logfd, &rfds);
+ 
+-	num = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
+-	if (num < 0) {
+-		fprintf(data.std, "Unable select over logfd!\nHALTING LOGTHREAD!\n");
+-		return NULL;
+-	}
+-	if (num == 0) {
+-		fprintf(data.std, "[knet]: No logs in the last 60 seconds\n");
+-	}
+-	if (FD_ISSET(data.logfd, &rfds)) {
+-		flush_logs(data.logfd, data.std);
++		num = select(FD_SETSIZE, &rfds, NULL, NULL, &tv);
++		if (num < 0) {
++			fprintf(data.std, "Unable select over logfd!\nHALTING LOGTHREAD!\n");
++			return NULL;
++		}
++		if (num == 0) {
++			fprintf(data.std, "[knet]: No logs in the last 60 seconds\n");
++			continue;
++		}
++		if (FD_ISSET(data.logfd, &rfds)) {
++			flush_logs(data.logfd, data.std);
++		}
+ 	}
+-	goto select_loop;
+-
+-	return NULL;
+ }
+ 
+ int start_logthread(int logfd, FILE *std)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0021-knet_log_msg-fix-documentation-the-closing-newline-i.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0021-knet_log_msg-fix-documentation-the-closing-newline-i.patch
new file mode 100644
index 000000000..61eaec132
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0021-knet_log_msg-fix-documentation-the-closing-newline-i.patch
@@ -0,0 +1,27 @@ 
+From 0f318f47268b72ddf868f8b590ce458835b09cde Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 18:18:20 +0200
+Subject: [PATCH] knet_log_msg: fix documentation: the closing newline is added
+ by flush_logs
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/libknet.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 17e44da8..8222eef0 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1909,7 +1909,7 @@ const char *knet_log_get_loglevel_name(uint8_t level);
+ uint8_t knet_log_get_loglevel_id(const char *name);
+ 
+ /*
+- * every log message is composed by a text message (including a trailing \n)
++ * every log message is composed by a text message
+  * and message level/subsystem IDs.
+  * In order to make debugging easier it is possible to send those packets
+  * straight to stdout/stderr (see knet_bench.c stdout option).
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0022-log_msg-no-point-in-putting-NL-after-the-final-NUL.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0022-log_msg-no-point-in-putting-NL-after-the-final-NUL.patch
new file mode 100644
index 000000000..066e4c9f5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0022-log_msg-no-point-in-putting-NL-after-the-final-NUL.patch
@@ -0,0 +1,34 @@ 
+From ba52b895ce225b386b488985b1a042b2e49c6ac3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 23 Apr 2018 18:56:34 +0200
+Subject: [PATCH] log_msg: no point in putting NL after the final NUL
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/logging.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 32db292a..fe409565 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -235,15 +235,12 @@ void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wformat-nonliteral"
+ #endif
+-	vsnprintf(msg.msg, sizeof(msg.msg) - 2, fmt, ap);
++	vsnprintf(msg.msg, sizeof msg.msg, fmt, ap);
+ #ifdef __clang__
+ #pragma clang diagnostic pop
+ #endif
+ 	va_end(ap);
+ 
+-	len = strlen(msg.msg);
+-	msg.msg[len+1] = '\n';
+-
+ 	while (byte_cnt < sizeof(struct knet_log_msg)) {
+ 		len = write(knet_h->logfd, &msg, sizeof(struct knet_log_msg) - byte_cnt);
+ 		if (len <= 0) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0023-coding-style-add-parentheses-after-the-sizeof-operat.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0023-coding-style-add-parentheses-after-the-sizeof-operat.patch
new file mode 100644
index 000000000..c7ebc4d53
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0023-coding-style-add-parentheses-after-the-sizeof-operat.patch
@@ -0,0 +1,43 @@ 
+From f8eb9d32b841dc5ea5079adecd8f03759a195b29 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Tue, 24 Apr 2018 20:10:49 +0200
+Subject: [PATCH] coding style: add parentheses after the sizeof operator
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/logging.c           | 2 +-
+ libknet/tests/test-common.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/logging.c b/libknet/logging.c
+index fe409565..5ea14176 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -235,7 +235,7 @@ void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
+ #pragma clang diagnostic push
+ #pragma clang diagnostic ignored "-Wformat-nonliteral"
+ #endif
+-	vsnprintf(msg.msg, sizeof msg.msg, fmt, ap);
++	vsnprintf(msg.msg, sizeof(msg.msg), fmt, ap);
+ #ifdef __clang__
+ #pragma clang diagnostic pop
+ #endif
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 0dba3392..f01f8320 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -220,9 +220,9 @@ void flush_logs(int logfd, FILE *std)
+ 	while (1) {
+ 		struct knet_log_msg msg;
+ 
+-		for (size_t bytes_read = 0; bytes_read < sizeof msg; ) {
++		for (size_t bytes_read = 0; bytes_read < sizeof(msg); ) {
+ 			int len = read(logfd, &msg + bytes_read,
+-				       sizeof msg - bytes_read);
++				       sizeof(msg) - bytes_read);
+ 			if (len <= 0) {
+ 				return;
+ 			}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0024-tests-add-another-lzma-exception.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0024-tests-add-another-lzma-exception.patch
new file mode 100644
index 000000000..11c90e530
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0024-tests-add-another-lzma-exception.patch
@@ -0,0 +1,39 @@ 
+From aff6d1024ec970734fd40c0dda4d36519f97429a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 8 Jun 2018 06:59:54 +0200
+Subject: [PATCH] [tests] add another lzma exception
+
+spotted on Debian Experimental, the latest toolchain appears to add
+full path to objects and valgrind would generate an error.
+
+add a generic catch-all path exception.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 149aba35..3d0fd0b0 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -459,6 +459,19 @@
+    fun:_handle_send_to_links_thread
+    fun:start_thread
+ }
++{
++   lzma internal stuff (Debian Experimental)
++   Memcheck:Cond
++   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++   fun:lzma_block_buffer_encode
++   fun:lzma_stream_buffer_encode
++   fun:lzma_easy_buffer_encode
++   obj:*/libknet/.libs/compress_lzma.so
++   obj:*
++}
+ {
+    lzma internal stuff (Debian / Ubuntu)
+    Memcheck:Cond
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0025-tests-reference-correct-library-in-memcheck-comments.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0025-tests-reference-correct-library-in-memcheck-comments.patch
new file mode 100644
index 000000000..95ec92ce8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0025-tests-reference-correct-library-in-memcheck-comments.patch
@@ -0,0 +1,23 @@ 
+From 2d010237be3a0b2e7e91b6bc3f6c8aaa1e16c8fc Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 17 Jul 2018 06:42:00 +0200
+Subject: [PATCH] [tests] reference correct library in memcheck comments
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 3d0fd0b0..e631e161 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -571,7 +571,7 @@
+    obj:/usr/local/lib/nss/libnss3.so
+ }
+ {
+-   nss internal stuff (FreeBSD 11.1)
++   openssl internal stuff (FreeBSD 11.1)
+    Memcheck:Addr8
+    obj:/libexec/ld-elf.so.1
+    obj:/libexec/ld-elf.so.1
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0026-tests-ignore-nss-internal-memory-leak-3.38-non-recur.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0026-tests-ignore-nss-internal-memory-leak-3.38-non-recur.patch
new file mode 100644
index 000000000..4b397611f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0026-tests-ignore-nss-internal-memory-leak-3.38-non-recur.patch
@@ -0,0 +1,55 @@ 
+From fdaaccbc5f9f1874382fa45478389ab65a97912a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 17 Jul 2018 13:02:08 +0200
+Subject: [PATCH] [tests] ignore nss internal memory leak (3.38+) non recurring
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 34 +++++++++++++++++++++++++++
+ 1 file changed, 34 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index e631e161..27bba569 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -570,6 +570,40 @@
+    fun:SECMOD_LoadModule
+    obj:/usr/local/lib/nss/libnss3.so
+ }
++{
++   nss internal leak (3.38+) non recurring
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   fun:init_nss
++   fun:nsscrypto_init
++   fun:crypto_init
++   fun:knet_handle_crypto
++   fun:test
++   fun:main
++}
++{
++   nss internal leak (3.38+) non recurring
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:calloc
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   fun:init_nss
++   fun:nsscrypto_init
++   fun:crypto_init
++   fun:knet_handle_crypto
++   fun:test
++   fun:main
++}
+ {
+    openssl internal stuff (FreeBSD 11.1)
+    Memcheck:Addr8
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0027-handle-drop-call-to-log_msg-that-would-have-no-effec.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0027-handle-drop-call-to-log_msg-that-would-have-no-effec.patch
new file mode 100644
index 000000000..b291a31ce
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0027-handle-drop-call-to-log_msg-that-would-have-no-effec.patch
@@ -0,0 +1,25 @@ 
+From efee4a3a9057e75ec7c737e897c5a82b9f4749fd Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 29 Jul 2018 05:59:20 +0200
+Subject: [PATCH] [handle] drop call to log_msg that would have no effect
+
+logging is not setup yet at this stage and we can't log just yet.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 8e952558..eeb98a31 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -581,8 +581,6 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 
+ 	savederrno = pthread_mutex_lock(&handle_config_mutex);
+ 	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get handle mutex lock: %s",
+-			strerror(savederrno));
+ 		errno = savederrno;
+ 		goto exit_fail;
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0028-logging-drop-locking-inside-log_msg-part-1.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0028-logging-drop-locking-inside-log_msg-part-1.patch
new file mode 100644
index 000000000..dc53045f3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0028-logging-drop-locking-inside-log_msg-part-1.patch
@@ -0,0 +1,69 @@ 
+From bc6f1364bdc8d0c05554b06c41b3555305f766bf Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 29 Jul 2018 06:28:11 +0200
+Subject: [PATCH] [logging] drop locking inside log_msg (part 1)
+
+looking at the code, there are only few calls to log_msg happening outside
+of locking context (error reports when failing to grab the lock).
+Everything else appears to be safe.
+
+drop the attempt to lock inside log_msg for now, part 2 will address those
+few calls that can happen outside of locking context.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/logging.c | 23 ++++-------------------
+ 1 file changed, 4 insertions(+), 19 deletions(-)
+
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 5ea14176..5d7191bf 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -207,24 +207,15 @@ void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
+ 	va_list ap;
+ 	struct knet_log_msg msg;
+ 	size_t byte_cnt = 0;
+-	int len, err;
++	int len;
+ 
+ 	if ((!knet_h) ||
+ 	    (subsystem == KNET_MAX_SUBSYSTEMS) ||
+ 	    (msglevel > knet_h->log_levels[subsystem]))
+ 			return;
+ 
+-	/*
+-	 * most logging calls will take place with locking in place.
+-	 * if we get an EINVAL and locking is initialized, then
+-	 * we are getting a real error and we need to stop
+-	 */
+-	err = pthread_rwlock_tryrdlock(&knet_h->global_rwlock);
+-	if ((err == EAGAIN) && (knet_h->lock_init_done))
+-		return;
+-
+ 	if (knet_h->logfd <= 0)
+-		goto out_unlock;
++		goto out;
+ 
+ 	memset(&msg, 0, sizeof(struct knet_log_msg));
+ 	msg.subsystem = subsystem;
+@@ -244,18 +235,12 @@ void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
+ 	while (byte_cnt < sizeof(struct knet_log_msg)) {
+ 		len = write(knet_h->logfd, &msg, sizeof(struct knet_log_msg) - byte_cnt);
+ 		if (len <= 0) {
+-			goto out_unlock;
++			goto out;
+ 		}
+ 
+ 		byte_cnt += len;
+ 	}
+ 
+-out_unlock:
+-	/*
+-	 * unlock only if we are holding the lock
+-	 */
+-	if (!err)
+-		pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
++out:
+ 	return;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0029-handle-drop-init_lock_done-as-it-was-used-only-by-lo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0029-handle-drop-init_lock_done-as-it-was-used-only-by-lo.patch
new file mode 100644
index 000000000..e607faaa8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0029-handle-drop-init_lock_done-as-it-was-used-only-by-lo.patch
@@ -0,0 +1,64 @@ 
+From 196e10e2366b1789f5669210975b0534cc8fed2d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 29 Jul 2018 06:31:45 +0200
+Subject: [PATCH] [handle] drop init_lock_done as it was used only by locked
+ version of log_msg
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c    | 8 --------
+ libknet/internals.h | 1 -
+ 2 files changed, 9 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index eeb98a31..a3f067af 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -80,8 +80,6 @@ static int _init_locks(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
+-	knet_h->lock_init_done = 1;
+-
+ 	savederrno = pthread_mutex_init(&knet_h->pmtud_mutex, NULL);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize pmtud mutex: %s",
+@@ -140,7 +138,6 @@ exit_fail:
+ 
+ static void _destroy_locks(knet_handle_t knet_h)
+ {
+-	knet_h->lock_init_done = 0;
+ 	pthread_rwlock_destroy(&knet_h->global_rwlock);
+ 	pthread_mutex_destroy(&knet_h->pmtud_mutex);
+ 	pthread_mutex_destroy(&knet_h->kmtu_mutex);
+@@ -721,10 +718,6 @@ int knet_handle_free(knet_handle_t knet_h)
+ 		return -1;
+ 	}
+ 
+-	if (!knet_h->lock_init_done) {
+-		goto exit_nolock;
+-	}
+-
+ 	savederrno = get_global_wrlock(knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+@@ -758,7 +751,6 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	compress_fini(knet_h, 1);
+ 	_destroy_locks(knet_h);
+ 
+-exit_nolock:
+ 	free(knet_h);
+ 	knet_h = NULL;
+ 	knet_ref--;
+diff --git a/libknet/internals.h b/libknet/internals.h
+index a785cd72..06f8750f 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -179,7 +179,6 @@ struct knet_handle {
+ 	pthread_t heartbt_thread;
+ 	pthread_t dst_link_handler_thread;
+ 	pthread_t pmtud_link_handler_thread;
+-	int lock_init_done;
+ 	pthread_rwlock_t global_rwlock;		/* global config lock */
+ 	pthread_mutex_t pmtud_mutex;		/* pmtud mutex to handle conditional send/recv + timeout */
+ 	pthread_cond_t pmtud_cond;		/* conditional for above */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0030-logging-report-error-in-case-logging-buffer-is-bigge.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0030-logging-report-error-in-case-logging-buffer-is-bigge.patch
new file mode 100644
index 000000000..298c42e5f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0030-logging-report-error-in-case-logging-buffer-is-bigge.patch
@@ -0,0 +1,45 @@ 
+From ed58227ef764820329f58e9864a52d4455b88666 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 30 Jul 2018 06:19:56 +0200
+Subject: [PATCH] [logging] report error in case logging buffer is bigger than
+ PIPE_BUF
+
+See https://github.com/kronosnet/kronosnet/pull/148
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 8222eef0..c0f11a0b 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -14,6 +14,7 @@
+ #include <time.h>
+ #include <netinet/in.h>
+ #include <unistd.h>
++#include <limits.h>
+ 
+ /**
+  * @file libknet.h
+@@ -109,6 +110,9 @@ typedef struct knet_handle *knet_handle_t;
+  *            Make sure to either read from this filedescriptor properly and/or
+  *            mark it O_NONBLOCK, otherwise if the fd becomes full, libknet could
+  *            block.
++ *            It is strongly encouraged to use pipes (ex: pipe(2) or pipe2(2)) for
++ *            logging fds due to the atomic nature of writes between fds.
++ *            See also libknet test suite for reference and guidance.
+  *
+  * default_log_level -
+  *            If logfd is specified, it will initialize all subsystems to log
+@@ -1916,6 +1920,9 @@ uint8_t knet_log_get_loglevel_id(const char *name);
+  */
+ 
+ #define KNET_MAX_LOG_MSG_SIZE    254
++#if KNET_MAX_LOG_MSG_SIZE > PIPE_BUF
++#error KNET_MAX_LOG_MSG_SIZE cannot be bigger than PIPE_BUF for guaranteed system atomic writes
++#endif
+ 
+ struct knet_log_msg {
+ 	char	msg[KNET_MAX_LOG_MSG_SIZE];
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0031-handle-reduce-usage-of-handle_config_mutex-to-wrap-o.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0031-handle-reduce-usage-of-handle_config_mutex-to-wrap-o.patch
new file mode 100644
index 000000000..4417618f3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0031-handle-reduce-usage-of-handle_config_mutex-to-wrap-o.patch
@@ -0,0 +1,123 @@ 
+From dce986ba1a91686ed6785e7506f9f019ec0fd1b4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 30 Jul 2018 16:12:18 +0200
+Subject: [PATCH] [handle] reduce usage of handle_config_mutex to wrap only
+ global lib init
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c | 44 +++++++++++++++++++++++---------------------
+ 1 file changed, 23 insertions(+), 21 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index a3f067af..8fc0dcbe 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -574,13 +574,13 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 	}
+ 	memset(knet_h, 0, sizeof(struct knet_handle));
+ 
+-	knet_h->flags = flags;
++	/*
++	 * setting up some handle data so that we can use logging
++	 * also when initializing the library global locks
++	 * and trackers
++	 */
+ 
+-	savederrno = pthread_mutex_lock(&handle_config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		goto exit_fail;
+-	}
++	knet_h->flags = flags;
+ 
+ 	/*
+ 	 * copy config in place
+@@ -614,6 +614,18 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 	/*
+ 	 * init global shlib tracker
+ 	 */
++	savederrno = pthread_mutex_lock(&handle_config_mutex);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get handle mutex lock: %s",
++			strerror(savederrno));
++		free(knet_h);
++		knet_h = NULL;
++		errno = savederrno;
++		return NULL;
++	}
++
++	knet_ref++;
++
+ 	if (_init_shlib_tracker(knet_h) < 0) {
+ 		savederrno = errno;
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to init handles traceker: %s",
+@@ -622,6 +634,8 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 		goto exit_fail;
+ 	}
+ 
++	pthread_mutex_unlock(&handle_config_mutex);
++
+ 	/*
+ 	 * init main locking structures
+ 	 */
+@@ -681,13 +695,9 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 		goto exit_fail;
+ 	}
+ 
+-	knet_ref++;
+-
+-	pthread_mutex_unlock(&handle_config_mutex);
+ 	return knet_h;
+ 
+ exit_fail:
+-	pthread_mutex_unlock(&handle_config_mutex);
+ 	knet_handle_free(knet_h);
+ 	errno = savederrno;
+ 	return NULL;
+@@ -704,16 +714,7 @@ int knet_handle_free(knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
+ 
+-	savederrno = pthread_mutex_lock(&handle_config_mutex);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get handle mutex lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+ 	if (!knet_h) {
+-		pthread_mutex_unlock(&handle_config_mutex);
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -722,7 +723,6 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+ 			strerror(savederrno));
+-		pthread_mutex_unlock(&handle_config_mutex);
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+@@ -733,7 +733,6 @@ int knet_handle_free(knet_handle_t knet_h)
+ 			"Unable to free handle: host(s) or listener(s) are still active: %s",
+ 			strerror(savederrno));
+ 		pthread_rwlock_unlock(&knet_h->global_rwlock);
+-		pthread_mutex_unlock(&handle_config_mutex);
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+@@ -753,9 +752,12 @@ int knet_handle_free(knet_handle_t knet_h)
+ 
+ 	free(knet_h);
+ 	knet_h = NULL;
++
++	pthread_mutex_lock(&handle_config_mutex);
+ 	knet_ref--;
+ 	_fini_shlib_tracker();
+ 	pthread_mutex_unlock(&handle_config_mutex);
++
+ 	return 0;
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0032-tests-adds-more-overrides-for-fedora28-arm-glibc.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0032-tests-adds-more-overrides-for-fedora28-arm-glibc.patch
new file mode 100644
index 000000000..cabf1e6b3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0032-tests-adds-more-overrides-for-fedora28-arm-glibc.patch
@@ -0,0 +1,32 @@ 
+From 8d08d80e728dd5bfcb5023c194994bd84cd3bab1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 30 Jul 2018 18:15:24 +0200
+Subject: [PATCH] [tests] adds more overrides for fedora28/arm/glibc
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 27bba569..65abfb4a 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -620,3 +620,17 @@
+    fun:OPENSSL_init_crypto
+    fun:opensslcrypto_init
+ }
++{
++   Internal glibc memory leak (Fedora 28 on arm)
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   fun:_dl_map_object_deps
++}
++{
++   Internal glibc memory leak (Fedora 28 on arm)
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   fun:dl_open_worker
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0033-tests-don-t-redefine-symbols-from-the-main-library.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0033-tests-don-t-redefine-symbols-from-the-main-library.patch
new file mode 100644
index 000000000..d2820fe33
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0033-tests-don-t-redefine-symbols-from-the-main-library.patch
@@ -0,0 +1,39 @@ 
+From ba7efabb7cae812cc930319ab6d754731eb397bc Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 1 Aug 2018 07:56:21 +0200
+Subject: [PATCH] [tests] don't redefine symbols from the main library
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index f01f8320..55776236 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -34,7 +34,7 @@ struct log_thread_data {
+ };
+ static struct log_thread_data data;
+ static pthread_mutex_t shutdown_mutex = PTHREAD_MUTEX_INITIALIZER;
+-static int shutdown_in_progress = 0;
++static int stop_in_progress = 0;
+ 
+ static int _read_pipe(int fd, char **file, size_t *length)
+ {
+@@ -376,13 +376,13 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 		return -1;
+ 	}
+ 
+-	if (shutdown_in_progress) {
++	if (stop_in_progress) {
+ 		pthread_mutex_unlock(&shutdown_mutex);
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+-	shutdown_in_progress = 1;
++	stop_in_progress = 1;
+ 
+ 	pthread_mutex_unlock(&shutdown_mutex);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0034-threads-use-internal-array-to-track-status-of-thread.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0034-threads-use-internal-array-to-track-status-of-thread.patch
new file mode 100644
index 000000000..d637ed386
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0034-threads-use-internal-array-to-track-status-of-thread.patch
@@ -0,0 +1,397 @@ 
+From 3fdfa4f1cb03252688c353a9b8704f456d75b17e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 1 Aug 2018 14:21:38 +0200
+Subject: [PATCH] [threads] use internal array to track status of threads
+ (running/stopped) vs a random sleep()
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c             | 20 ++++++++++-------
+ libknet/internals.h          |  3 +++
+ libknet/tests/int_timediff.c |  2 --
+ libknet/threads_common.c     | 43 ++++++++++++++++++++++++++++++++++++
+ libknet/threads_common.h     | 18 +++++++++++++++
+ libknet/threads_dsthandler.c |  6 ++++-
+ libknet/threads_heartbeat.c  |  4 ++++
+ libknet/threads_pmtud.c      |  4 ++++
+ libknet/threads_rx.c         | 13 ++++++++++-
+ libknet/threads_tx.c         | 13 ++++++++++-
+ libknet/transport_sctp.c     | 28 +++++++++++++++++++++--
+ 11 files changed, 139 insertions(+), 15 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 8fc0dcbe..71b6117e 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -80,6 +80,13 @@ static int _init_locks(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	savederrno = pthread_mutex_init(&knet_h->threads_status_mutex, NULL);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize threads status mutex: %s",
++			strerror(savederrno));
++		goto exit_fail;
++	}
++
+ 	savederrno = pthread_mutex_init(&knet_h->pmtud_mutex, NULL);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize pmtud mutex: %s",
+@@ -146,6 +153,7 @@ static void _destroy_locks(knet_handle_t knet_h)
+ 	pthread_mutex_destroy(&knet_h->tx_mutex);
+ 	pthread_mutex_destroy(&knet_h->backoff_mutex);
+ 	pthread_mutex_destroy(&knet_h->tx_seq_num_mutex);
++	pthread_mutex_destroy(&knet_h->threads_status_mutex);
+ }
+ 
+ static int _init_socks(knet_handle_t knet_h)
+@@ -485,6 +493,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 			strerror(savederrno));
+ 		goto exit_fail;
+ 	}
++
+ 	return 0;
+ 
+ exit_fail:
+@@ -496,14 +505,7 @@ static void _stop_threads(knet_handle_t knet_h)
+ {
+ 	void *retval;
+ 
+-	/*
+-	 * allow threads to catch on shutdown request
+-	 * and release locks before we stop them.
+-	 * this isn't the most efficent way to handle it
+-	 * but it works good enough for now
+-	 */
+-
+-	sleep(1);
++	wait_all_threads_status(knet_h, KNET_THREAD_STOPPED);
+ 
+ 	if (knet_h->heartbt_thread) {
+ 		pthread_cancel(knet_h->heartbt_thread);
+@@ -695,6 +697,8 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 		goto exit_fail;
+ 	}
+ 
++	wait_all_threads_status(knet_h, KNET_THREAD_RUNNING);
++
+ 	return knet_h;
+ 
+ exit_fail:
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 06f8750f..a980d19c 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -18,6 +18,7 @@
+ #include "libknet.h"
+ #include "onwire.h"
+ #include "compat.h"
++#include "threads_common.h"
+ 
+ #define KNET_DATABUFSIZE KNET_MAX_PACKET_SIZE + KNET_HEADER_ALL_SIZE
+ 
+@@ -174,6 +175,8 @@ struct knet_handle {
+ 	struct knet_header *recv_from_links_buf[PCKT_RX_BUFS];
+ 	struct knet_header *pingbuf;
+ 	struct knet_header *pmtudbuf;
++	uint8_t threads_status[KNET_THREAD_MAX];
++	pthread_mutex_t threads_status_mutex;
+ 	pthread_t send_to_links_thread;
+ 	pthread_t recv_from_links_thread;
+ 	pthread_t heartbt_thread;
+diff --git a/libknet/tests/int_timediff.c b/libknet/tests/int_timediff.c
+index 087655fb..0006b625 100644
+--- a/libknet/tests/int_timediff.c
++++ b/libknet/tests/int_timediff.c
+@@ -14,8 +14,6 @@
+ #include <stdlib.h>
+ #include <pthread.h>
+ 
+-#include "threads_common.h"
+-
+ #include "test-common.h"
+ 
+ #define timespec_set(x, sec, nsec) \
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index ac2a1811..efa0ab8d 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -63,3 +63,46 @@ int get_global_wrlock(knet_handle_t knet_h)
+ 	}
+ 	return pthread_rwlock_wrlock(&knet_h->global_rwlock);
+ }
++
++int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status)
++{
++	if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock");
++		return -1;
++	}
++
++	knet_h->threads_status[thread_id] = status;
++
++	log_debug(knet_h, KNET_SUB_HANDLE, "Updated status for thread %u to %u",
++		  thread_id, status);
++
++	pthread_mutex_unlock(&knet_h->threads_status_mutex);
++	return 0;
++}
++
++int wait_all_threads_status(knet_handle_t knet_h, uint8_t status)
++{
++	uint8_t i = 0, found = 0;
++
++	while (!found) {
++		usleep(KNET_THREADS_TIMERES);
++
++		if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
++			continue;
++		}
++
++		found = 1;
++
++		for (i = 0; i < KNET_THREAD_MAX; i++) {
++			log_debug(knet_h, KNET_SUB_HANDLE, "Checking thread: %u status: %u req: %u",
++					i, knet_h->threads_status[i], status);
++			if (knet_h->threads_status[i] != status) {
++				found = 0;
++			}
++		}
++
++		pthread_mutex_unlock(&knet_h->threads_status_mutex);
++	}
++
++	return 0;
++}
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 585b79fc..45e36e2c 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -14,6 +14,22 @@
+ 
+ #define KNET_THREADS_TIMERES 200000
+ 
++#define KNET_THREAD_STOPPED	0
++#define KNET_THREAD_RUNNING	1
++
++#define KNET_THREAD_TX		0
++#define KNET_THREAD_RX		1
++#define KNET_THREAD_HB		2
++#define KNET_THREAD_PMTUD	3
++#define KNET_THREAD_DST_LINK	4
++#ifndef HAVE_NETINET_SCTP_H
++#define KNET_THREAD_MAX		KNET_THREAD_DST_LINK + 1
++#else
++#define KNET_THREAD_SCTP_LISTEN	5
++#define KNET_THREAD_SCTP_CONN	6
++#define KNET_THREAD_MAX		KNET_THREAD_SCTP_CONN + 1
++#endif
++
+ #define timespec_diff(start, end, diff) \
+ do { \
+ 	if (end.tv_sec > start.tv_sec) \
+@@ -25,5 +41,7 @@ do { \
+ 
+ int shutdown_in_progress(knet_handle_t knet_h);
+ int get_global_wrlock(knet_handle_t knet_h);
++int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status);
++int wait_all_threads_status(knet_handle_t knet_h, uint8_t status);
+ 
+ #endif
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 27fee361..529ff153 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -53,10 +53,14 @@ void *_handle_dst_link_handler_thread(void *data)
+ 	knet_handle_t knet_h = (knet_handle_t) data;
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 
++	set_thread_status(knet_h, KNET_THREAD_DST_LINK, KNET_THREAD_RUNNING);
++
+ 	while (!shutdown_in_progress(knet_h)) {
+-		if (epoll_wait(knet_h->dst_link_handler_epollfd, events, KNET_EPOLL_MAX_EVENTS, -1) >= 1)
++		if (epoll_wait(knet_h->dst_link_handler_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000) >= 1)
+ 			_handle_dst_link_updates(knet_h);
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_DST_LINK, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index d9d8bff0..c3838129 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -186,6 +186,8 @@ void *_handle_heartbt_thread(void *data)
+ 	knet_handle_t knet_h = (knet_handle_t) data;
+ 	int i = 1;
+ 
++	set_thread_status(knet_h, KNET_THREAD_HB, KNET_THREAD_RUNNING);
++
+ 	/* preparing ping buffer */
+ 	knet_h->pingbuf->kh_version = KNET_HEADER_VERSION;
+ 	knet_h->pingbuf->kh_type = KNET_HEADER_TYPE_PING;
+@@ -214,5 +216,7 @@ void *_handle_heartbt_thread(void *data)
+ 		pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_HB, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 67cd3bdb..820f273c 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -479,6 +479,8 @@ void *_handle_pmtud_link_thread(void *data)
+ 	int link_has_mtu;
+ 	int force_run = 0;
+ 
++	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_RUNNING);
++
+ 	knet_h->data_mtu = KNET_PMTUD_MIN_MTU_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
+ 
+ 	/* preparing pmtu buffer */
+@@ -558,5 +560,7 @@ out_unlock:
+ 		}
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 3b047786..3017ce4c 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -814,6 +814,8 @@ void *_handle_recv_from_links_thread(void *data)
+ 	struct knet_mmsghdr msg[PCKT_RX_BUFS];
+ 	struct iovec iov_in[PCKT_RX_BUFS];
+ 
++	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_RUNNING);
++
+ 	memset(&msg, 0, sizeof(msg));
+ 
+ 	for (i = 0; i < PCKT_RX_BUFS; i++) {
+@@ -829,12 +831,21 @@ void *_handle_recv_from_links_thread(void *data)
+ 	}
+ 
+ 	while (!shutdown_in_progress(knet_h)) {
+-		nev = epoll_wait(knet_h->recv_from_links_epollfd, events, KNET_EPOLL_MAX_EVENTS, -1);
++		nev = epoll_wait(knet_h->recv_from_links_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
++
++		/*
++		 * we use timeout to detect if thread is shutting down
++		 */
++		if (nev == 0) {
++			continue;
++		}
+ 
+ 		for (i = 0; i < nev; i++) {
+ 			_handle_recv_from_links(knet_h, events[i].data.fd, msg);
+ 		}
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 3c7a7f3b..20798c0c 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -686,6 +686,8 @@ void *_handle_send_to_links_thread(void *data)
+ 	struct msghdr msg;
+ 	struct sockaddr_storage address;
+ 
++	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_RUNNING);
++
+ 	memset(&iov_in, 0, sizeof(iov_in));
+ 	iov_in.iov_base = (void *)knet_h->recv_from_sock_buf->khp_data_userdata;
+ 	iov_in.iov_len = KNET_MAX_PACKET_SIZE;
+@@ -707,7 +709,14 @@ void *_handle_send_to_links_thread(void *data)
+ 	}
+ 
+ 	while (!shutdown_in_progress(knet_h)) {
+-		nev = epoll_wait(knet_h->send_to_links_epollfd, events, KNET_EPOLL_MAX_EVENTS + 1, -1);
++		nev = epoll_wait(knet_h->send_to_links_epollfd, events, KNET_EPOLL_MAX_EVENTS + 1, KNET_THREADS_TIMERES / 1000);
++
++		/*
++		 * we use timeout to detect if thread is shutting down
++		 */
++		if (nev == 0) {
++			continue;
++		}
+ 
+ 		if (pthread_rwlock_rdlock(&knet_h->global_rwlock) != 0) {
+ 			log_debug(knet_h, KNET_SUB_TX, "Unable to get read lock");
+@@ -741,5 +750,7 @@ void *_handle_send_to_links_thread(void *data)
+ 		pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 4288f678..7a635338 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -629,8 +629,17 @@ static void *_sctp_connect_thread(void *data)
+ 	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 
++	set_thread_status(knet_h, KNET_THREAD_SCTP_CONN, KNET_THREAD_RUNNING);
++
+ 	while (!shutdown_in_progress(knet_h)) {
+-		nev = epoll_wait(handle_info->connect_epollfd, events, KNET_EPOLL_MAX_EVENTS, -1);
++		nev = epoll_wait(handle_info->connect_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
++
++		/*
++		 * we use timeout to detect if thread is shutting down
++		 */
++		if (nev == 0) {
++			continue;
++		}
+ 
+ 		if (nev < 0) {
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP connect handler EPOLL ERROR: %s",
+@@ -676,6 +685,9 @@ static void *_sctp_connect_thread(void *data)
+ 		 */
+ 		usleep(knet_h->reconnect_int * 1000);
+ 	}
++
++	set_thread_status(knet_h, KNET_THREAD_SCTP_CONN, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+ 
+@@ -862,8 +874,17 @@ static void *_sctp_listen_thread(void *data)
+ 	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 
++	set_thread_status(knet_h, KNET_THREAD_SCTP_LISTEN, KNET_THREAD_RUNNING);
++
+ 	while (!shutdown_in_progress(knet_h)) {
+-		nev = epoll_wait(handle_info->listen_epollfd, events, KNET_EPOLL_MAX_EVENTS, -1);
++		nev = epoll_wait(handle_info->listen_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
++
++		/*
++		 * we use timeout to detect if thread is shutting down
++		 */
++		if (nev == 0) {
++			continue;
++		}
+ 
+ 		if (nev < 0) {
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP listen handler EPOLL ERROR: %s",
+@@ -895,6 +916,9 @@ static void *_sctp_listen_thread(void *data)
+ 		}
+ 		pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	}
++
++	set_thread_status(knet_h, KNET_THREAD_SCTP_LISTEN, KNET_THREAD_STOPPED);
++
+ 	return NULL;
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0035-tests-cleanup-nss-memcheck-supports.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0035-tests-cleanup-nss-memcheck-supports.patch
new file mode 100644
index 000000000..55152dc8e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0035-tests-cleanup-nss-memcheck-supports.patch
@@ -0,0 +1,90 @@ 
+From 76d577b0a7fca58ab977ebe5f79cb12c317cd74f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Aug 2018 07:01:29 +0200
+Subject: [PATCH] [tests] cleanup nss memcheck supports
+
+add one more exception for newer nss (spotted on fedora rawhide)
+drop FreeBSD excetions as we don't support running under valgrind on BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 58 ++++++---------------------
+ 1 file changed, 13 insertions(+), 45 deletions(-)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 65abfb4a..31d62f2c 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -538,38 +538,6 @@
+    fun:compress_cfg
+    fun:knet_handle_compress
+ }
+-{
+-   nss internal stuff (FreeBSD 11.1)
+-   Memcheck:Addr8
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   fun:PR_LoadLibraryWithFlags
+-   obj:/usr/local/lib/nss/libnssutil3.so
+-   fun:PORT_LoadLibraryFromOrigin
+-   obj:/usr/local/lib/nss/libnss3.so
+-   fun:PR_CallOnce
+-   obj:/usr/local/lib/nss/libnss3.so
+-}
+-{
+-   nss internal stuff (FreeBSD 11.1)
+-   Memcheck:Addr8
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   fun:PR_LoadLibraryWithFlags
+-   obj:/usr/local/lib/nss/libnssutil3.so
+-   fun:PORT_LoadLibraryFromOrigin
+-   obj:/usr/local/lib/nss/libnss3.so
+-   fun:PR_CallOnce
+-   obj:/usr/local/lib/nss/libnss3.so
+-   fun:SECMOD_LoadModule
+-   obj:/usr/local/lib/nss/libnss3.so
+-}
+ {
+    nss internal leak (3.38+) non recurring
+    Memcheck:Leak
+@@ -605,20 +573,20 @@
+    fun:main
+ }
+ {
+-   openssl internal stuff (FreeBSD 11.1)
++   nss internal leak (3.38+) non recurring
+    Memcheck:Addr8
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/libexec/ld-elf.so.1
+-   obj:/usr/local/lib/libcrypto.so.10
+-   fun:DSO_load
+-   fun:DSO_dsobyaddr
+-   obj:/usr/local/lib/libcrypto.so.10
+-   fun:pthread_once
+-   fun:CRYPTO_THREAD_run_once
+-   fun:OPENSSL_init_crypto
+-   fun:opensslcrypto_init
++   obj:/usr/lib64/libp11-kit.so.0.3.0
++   obj:/usr/lib64/libp11-kit.so.0.3.0
++   fun:_dl_close_worker
++   fun:_dl_close
++   fun:_dl_catch_exception
++   fun:_dl_catch_error
++   fun:_dlerror_run
++   fun:dlclose
++   fun:PR_UnloadLibrary
++   obj:/usr/lib64/libnss3.so
++   obj:/usr/lib64/libnss3.so
++   obj:/usr/lib64/libnss3.so
+ }
+ {
+    Internal glibc memory leak (Fedora 28 on arm)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0036-tests-drop-arm-exceptions-as-they-have-been-fixed-in.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0036-tests-drop-arm-exceptions-as-they-have-been-fixed-in.patch
new file mode 100644
index 000000000..98ed2c595
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0036-tests-drop-arm-exceptions-as-they-have-been-fixed-in.patch
@@ -0,0 +1,32 @@ 
+From f0afbd73d8f06f8d78a57c58acf078925de8bc5f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Aug 2018 08:01:53 +0200
+Subject: [PATCH] [tests] drop arm exceptions as they have been fixed in glibc
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 14 --------------
+ 1 file changed, 14 deletions(-)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 31d62f2c..8b3f95f3 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -588,17 +588,3 @@
+    obj:/usr/lib64/libnss3.so
+    obj:/usr/lib64/libnss3.so
+ }
+-{
+-   Internal glibc memory leak (Fedora 28 on arm)
+-   Memcheck:Leak
+-   match-leak-kinds: definite
+-   fun:malloc
+-   fun:_dl_map_object_deps
+-}
+-{
+-   Internal glibc memory leak (Fedora 28 on arm)
+-   Memcheck:Leak
+-   match-leak-kinds: definite
+-   fun:malloc
+-   fun:dl_open_worker
+-}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0037-Support-for-git-archive-stored-tags.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0037-Support-for-git-archive-stored-tags.patch
new file mode 100644
index 000000000..562766d85
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0037-Support-for-git-archive-stored-tags.patch
@@ -0,0 +1,133 @@ 
+From efe02235b12796e5510412aa31ca3485a0c3a41d Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Tue, 4 Sep 2018 17:51:21 +0200
+Subject: [PATCH] Support for git archive stored tags
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Attempt to solve problem with git archive generated tarballs
+(used for example by github when release is downloaded) which are no
+longer git tree and (in contrast to officially released tarballs) also
+doesn't contain .tarball-version file so git-version-gen script simply
+cannot obtain valid version info.
+
+Solution is based on using gitattributes which is instructs git to
+replace string in the .gitarchivever file by known ref names.
+git-version-gen is enhanced to support this file and tries to parse
+any string which looks like "tag: v[0-9][^,)]*". If such string
+is found it's used as a version. This file is used as a last attempt and
+other methods (.tarball-version, git abbrev) have precedence.
+
+Based on idea stated by Jan Pokorný <jpokorny@redhat.com>.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ .gitarchivever            |  1 +
+ .gitattributes            |  1 +
+ build-aux/git-version-gen | 35 ++++++++++++++++++++++++++++++++---
+ configure.ac              |  2 +-
+ 4 files changed, 35 insertions(+), 4 deletions(-)
+ create mode 100644 .gitarchivever
+
+diff --git a/.gitarchivever b/.gitarchivever
+new file mode 100644
+index 00000000..37b24fb0
+--- /dev/null
++++ b/.gitarchivever
+@@ -0,0 +1 @@
++ref names:$Format:%d$
+diff --git a/.gitattributes b/.gitattributes
+index 2418181b..d3e56915 100644
+--- a/.gitattributes
++++ b/.gitattributes
+@@ -1 +1,2 @@
+ configure.ac export-subst
++.gitarchivever export-subst
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index ef95f148..5f81f793 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -1,7 +1,8 @@
+ #!/bin/sh
+ # Print a version string.
+-scriptversion=2016-01-11.22; # UTC
++scriptversion=2018-08-31.20; # UTC
+ 
++# Copyright (C) 2018 Red Hat, Inc.
+ # Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ #
+ # This program is free software: you can redistribute it and/or modify
+@@ -49,6 +50,17 @@ scriptversion=2016-01-11.22; # UTC
+ # .tarball-version is never generated in a VC'd directory, so needn't
+ # be listed there.
+ #
++# In order to use git archive versions another two files has to be presented:
++#
++# .gitarchive-version - present in checked-out repository and git
++#   archive tarball, but not in the distribution tarball. Used as a last
++#   option for version. File must contain special string $Format:%d$,
++#   which is substitued by git on archive operation.
++#
++# .gitattributes - present in checked-out repository and git archive
++#   tarball, but not in the distribution tarball. Must set export-subst
++#   attribute for .gitarchive-version file.
++#
+ # Use the following line in your configure.ac, so that $(VERSION) will
+ # automatically be up-to-date each time configure is run (and note that
+ # since configure.ac no longer includes a version string, Makefile rules
+@@ -80,7 +92,7 @@ under the terms of the GNU General Public License.
+ For more information about these matters, see the files named COPYING."
+ 
+ usage="\
+-Usage: $me [OPTION]... \$srcdir/.tarball-version [TAG-NORMALIZATION-SED-SCRIPT]
++Usage: $me [OPTION]... \$srcdir/.tarball-version [\$srcdir/.gitarchive-version] [TAG-NORMALIZATION-SED-SCRIPT]
+ Print a version string.
+ 
+ Options:
+@@ -110,6 +122,8 @@ while test $# -gt 0; do
+     *)
+       if test "x$tarball_version_file" = x; then
+         tarball_version_file="$1"
++      elif test "x$gitarchive_version_file" = x; then
++        gitarchive_version_file="$1"
+       elif test "x$tag_sed_script" = x; then
+         tag_sed_script="$1"
+       else
+@@ -189,7 +203,22 @@ then
+     v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1-/'`;
+     v_from_git=1
+ elif test "x$fallback" = x || git --version >/dev/null 2>&1; then
+-    v=UNKNOWN
++    if test -f $gitarchive_version_file
++    then
++        v=`sed "s/^.*tag: \($prefix[0-9)][^,)]*\).*\$/\1/" $gitarchive_version_file \
++            | sed "$tag_sed_script"` || exit 1
++        case $v in
++            *$nl*) v= ;; # reject multi-line output
++            $prefix[0-9]*) ;;
++            *) v= ;;
++        esac
++
++        test -z "$v" \
++            && echo "$0: WARNING: $gitarchive_version_file doesn't contain valid version tag" 1>&2 \
++            && v=UNKNOWN
++    else
++        v=UNKNOWN
++    fi
+ else
+     v=$fallback
+ fi
+diff --git a/configure.ac b/configure.ac
+index 85ac60c9..07997ab4 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -13,7 +13,7 @@
+ 
+ AC_PREREQ([2.63])
+ AC_INIT([kronosnet],
+-	m4_esyscmd([build-aux/git-version-gen .tarball-version]),
++	m4_esyscmd([build-aux/git-version-gen .tarball-version .gitarchivever]),
+ 	[devel@lists.kronosnet.org])
+ # Don't let AC_PROC_CC (invoked by AC_USE_SYSTEM_EXTENSIONS) replace
+ # undefined CFLAGS with -g -O2, overriding our special OPT_CFLAGS.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0038-Do-not-match-lightweight-tags-in-git-version-gen.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0038-Do-not-match-lightweight-tags-in-git-version-gen.patch
new file mode 100644
index 000000000..0a41a8d92
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0038-Do-not-match-lightweight-tags-in-git-version-gen.patch
@@ -0,0 +1,28 @@ 
+From 3fddab6793d02fd949d9f001cf4e7ecb6f40c08b Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Tue, 4 Sep 2018 17:52:11 +0200
+Subject: [PATCH] Do not match lightweight tags in git-version-gen
+
+Fix leftover from 175b517fd71d999150aa701ec847510490a18a6e which added
+matching of lightweight git tags.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ build-aux/git-version-gen | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index 5f81f793..0b593283 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -169,8 +169,8 @@ then
+ # directory, and "git describe" output looks sensible, use that to
+ # derive a version string.
+ elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
+-    && v=`git describe --abbrev=4 --match="$prefix*" --tags HEAD 2>/dev/null \
+-          || git describe --abbrev=4 --tags HEAD 2>/dev/null` \
++    && v=`git describe --abbrev=4 --match="$prefix*" HEAD 2>/dev/null \
++          || git describe --abbrev=4 HEAD 2>/dev/null` \
+     && v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \
+     && case $v in
+          $prefix[0-9]*) ;;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0039-git-version-gen-fail-on-UNKNOWN-version.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0039-git-version-gen-fail-on-UNKNOWN-version.patch
new file mode 100644
index 000000000..2fcfb5a34
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0039-git-version-gen-fail-on-UNKNOWN-version.patch
@@ -0,0 +1,29 @@ 
+From df6534ed2b4258dc31bc153eb7237985fa6f7a74 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Mon, 3 Sep 2018 17:43:03 +0200
+Subject: [PATCH] git-version-gen fail on UNKNOWN version
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ build-aux/git-version-gen | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index 0b593283..693513e7 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -223,6 +223,14 @@ else
+     v=$fallback
+ fi
+ 
++if test "x$fallback" = x -a "$v" = "UNKNOWN"
++then
++  echo "$0: ERROR: Can't find valid version. Please use valid git repository," \
++    "released tarball or version tagged archive" 1>&2
++
++  exit 1
++fi
++
+ v=`echo "$v" |sed "s/^$prefix//"`
+ 
+ # Test whether to append the "-dirty" suffix only if the version
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0040-Use-gitarchive-version-for-spec-file.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0040-Use-gitarchive-version-for-spec-file.patch
new file mode 100644
index 000000000..b8102fcc0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0040-Use-gitarchive-version-for-spec-file.patch
@@ -0,0 +1,36 @@ 
+From 74067a2c775ef5b50b828b858da2dbd018f775c2 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Tue, 4 Sep 2018 18:02:19 +0200
+Subject: [PATCH] Use gitarchive-version for spec file
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ Makefile.am | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 0dee6075..25398bbb 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -63,7 +63,7 @@ $(SPEC): $(SPEC).in .version config.status
+ 		alphatag="" && \
+ 		dirty="" && \
+ 		numcomm="0"; \
+-	else \
++	elif [ "`git log -1 --pretty=format:x . 2>&1`" = "x" ]; then \
+ 		gitver="`GIT_DIR=$(abs_srcdir)/.git git describe --abbrev=4 --match='v*' HEAD 2>/dev/null`" && \
+ 		rpmver=`echo $$gitver | sed -e "s/^v//" -e "s/-.*//g"` && \
+ 		alphatag=`echo $$gitver | sed -e "s/.*-//" -e "s/^g//"` && \
+@@ -72,6 +72,12 @@ $(SPEC): $(SPEC).in .version config.status
+ 		cd $(abs_srcdir) && \
+ 		git update-index --refresh > /dev/null 2>&1 || true && \
+ 		dirty=`git diff-index --name-only HEAD 2>/dev/null` && cd - 2>/dev/null; \
++	else \
++		gitver="`cd $(abs_srcdir); build-aux/git-version-gen .tarball-version .gitarchivever`" && \
++		rpmver=$$gitver && \
++		alphatag="" && \
++		dirty="" && \
++		numcomm="0"; \
+ 	fi && \
+ 	if [ -n "$$dirty" ]; then dirty="dirty"; else dirty=""; fi && \
+ 	if [ "$$numcomm" = "0" ]; then \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0041-threads-make-it-easier-to-debug-thread-startup-stop-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0041-threads-make-it-easier-to-debug-thread-startup-stop-.patch
new file mode 100644
index 000000000..1878fefae
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0041-threads-make-it-easier-to-debug-thread-startup-stop-.patch
@@ -0,0 +1,142 @@ 
+From ae24eae302cd31d3aa801e3fcb1283fa2f651106 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 6 Sep 2018 13:32:06 +0200
+Subject: [PATCH] [threads] make it easier to debug thread startup / stop
+ operations with pretty names
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h      |  5 ++++
+ libknet/logging.c        |  5 ----
+ libknet/threads_common.c | 59 +++++++++++++++++++++++++++++++++++++---
+ libknet/threads_common.h |  1 +
+ 4 files changed, 61 insertions(+), 9 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index a980d19c..3e4bbfaf 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -337,6 +337,11 @@ typedef struct knet_transport_ops {
+ 
+ socklen_t sockaddr_len(const struct sockaddr_storage *ss);
+ 
++struct pretty_names {
++	const char *name;
++	uint8_t val;
++};
++
+ /**
+  * This is a kernel style list implementation.
+  *
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 5d7191bf..543269a5 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -20,11 +20,6 @@
+ #include "logging.h"
+ #include "threads_common.h"
+ 
+-struct pretty_names {
+-	const char *name;
+-	uint8_t val;
+-};
+-
+ static struct pretty_names subsystem_names[] =
+ {
+ 	{ "common", KNET_SUB_COMMON },
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index efa0ab8d..fc10a029 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -64,6 +64,55 @@ int get_global_wrlock(knet_handle_t knet_h)
+ 	return pthread_rwlock_wrlock(&knet_h->global_rwlock);
+ }
+ 
++static struct pretty_names thread_names[] =
++{
++	{ "TX", KNET_THREAD_TX },
++	{ "RX", KNET_THREAD_RX },
++	{ "HB", KNET_THREAD_HB },
++	{ "PMTUD", KNET_THREAD_PMTUD },
++#ifdef HAVE_NETINET_SCTP_H
++	{ "SCTP_LISTEN", KNET_THREAD_SCTP_LISTEN },
++	{ "SCTP_CONN", KNET_THREAD_SCTP_CONN },
++#endif
++	{ "DST_LINK", KNET_THREAD_DST_LINK }
++};
++
++static struct pretty_names thread_status[] =
++{
++	{ "stopped", KNET_THREAD_STOPPED },
++	{ "running", KNET_THREAD_RUNNING }
++};
++
++/*
++ * this seems overloaded at the moment but
++ * we might want to expand status checks
++ * to include "starting" and "stopping"
++ */
++
++static const char *get_thread_status_name(uint8_t status)
++{
++	unsigned int i;
++
++	for (i = 0; i < KNET_THREAD_STATUS_MAX; i++) {
++		if (thread_status[i].val == status) {
++			return thread_status[i].name;
++		}
++	}
++	return "unknown";
++}
++
++static const char *get_thread_name(uint8_t thread_id)
++{
++	unsigned int i;
++
++	for (i = 0; i < KNET_THREAD_MAX; i++) {
++		if (thread_names[i].val == thread_id) {
++			return thread_names[i].name;
++		}
++	}
++	return "unknown";
++}
++
+ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status)
+ {
+ 	if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
+@@ -73,8 +122,8 @@ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status)
+ 
+ 	knet_h->threads_status[thread_id] = status;
+ 
+-	log_debug(knet_h, KNET_SUB_HANDLE, "Updated status for thread %u to %u",
+-		  thread_id, status);
++	log_debug(knet_h, KNET_SUB_HANDLE, "Updated status for thread %s to %s",
++		  get_thread_name(thread_id), get_thread_status_name(status));
+ 
+ 	pthread_mutex_unlock(&knet_h->threads_status_mutex);
+ 	return 0;
+@@ -94,8 +143,10 @@ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status)
+ 		found = 1;
+ 
+ 		for (i = 0; i < KNET_THREAD_MAX; i++) {
+-			log_debug(knet_h, KNET_SUB_HANDLE, "Checking thread: %u status: %u req: %u",
+-					i, knet_h->threads_status[i], status);
++			log_debug(knet_h, KNET_SUB_HANDLE, "Checking thread: %s status: %s req: %s",
++					get_thread_name(i),
++					get_thread_status_name(knet_h->threads_status[i]),
++					get_thread_status_name(status));
+ 			if (knet_h->threads_status[i] != status) {
+ 				found = 0;
+ 			}
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 45e36e2c..78e1cf02 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -16,6 +16,7 @@
+ 
+ #define KNET_THREAD_STOPPED	0
+ #define KNET_THREAD_RUNNING	1
++#define KNET_THREAD_STATUS_MAX	KNET_THREAD_RUNNING + 1
+ 
+ #define KNET_THREAD_TX		0
+ #define KNET_THREAD_RX		1
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0042-tests-fix-select-2-handling-mostly-affects-slow-mach.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0042-tests-fix-select-2-handling-mostly-affects-slow-mach.patch
new file mode 100644
index 000000000..c7a13ec1b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0042-tests-fix-select-2-handling-mostly-affects-slow-mach.patch
@@ -0,0 +1,46 @@ 
+From d9dde216aeda24dcfb18988f889f56bf012368c8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 11 Sep 2018 16:07:41 +0200
+Subject: [PATCH] [tests] fix select(2) handling (mostly affects slow machines)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 55776236..2ddcc36b 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -472,13 +472,14 @@ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd)
+ {
+ 	fd_set rfds;
+ 	struct timeval tv;
+-	int err = 0;
++	int err = 0, i = 0;
+ 
+ 	if (is_memcheck() || is_helgrind()) {
+ 		printf("Test suite is running under valgrind, adjusting wait_for_packet timeout\n");
+ 		seconds = seconds * 16;
+ 	}
+ 
++try_again:
+ 	FD_ZERO(&rfds);
+ 	FD_SET(datafd, &rfds);
+ 
+@@ -486,6 +487,15 @@ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd)
+ 	tv.tv_usec = 0;
+ 
+ 	err = select(datafd+1, &rfds, NULL, NULL, &tv);
++	/*
++	 * on slow arches the first call to select can return 0.
++	 * pick an arbitrary 10 times loop (multiplied by waiting seconds)
++	 * before failing.
++	 */
++	if ((!err) && (i < 10)) {
++		i++;
++		goto try_again;
++	}
+ 	if ((err > 0) && (FD_ISSET(datafd, &rfds))) {
+ 		return 0;
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0043-tests-clear-errno-to-avoid-incorrect-propagation-fro.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0043-tests-clear-errno-to-avoid-incorrect-propagation-fro.patch
new file mode 100644
index 000000000..05c39f988
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0043-tests-clear-errno-to-avoid-incorrect-propagation-fro.patch
@@ -0,0 +1,26 @@ 
+From 6885406c40cbee88c58ffc834eb89b55f8c265a7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 11 Sep 2018 16:09:09 +0200
+Subject: [PATCH] [tests] clear errno to avoid incorrect propagation from void
+ fn call
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 2ddcc36b..91759ab5 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -224,6 +224,10 @@ void flush_logs(int logfd, FILE *std)
+ 			int len = read(logfd, &msg + bytes_read,
+ 				       sizeof(msg) - bytes_read);
+ 			if (len <= 0) {
++				/*
++				 * clear errno to avoid incorrect propagation
++				 */
++				errno = 0;
+ 				return;
+ 			}
+ 			bytes_read += len;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0044-Import-key-with-length-not-dividable-by-wrap-key-blo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0044-Import-key-with-length-not-dividable-by-wrap-key-blo.patch
new file mode 100644
index 000000000..f7494d7ed
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0044-Import-key-with-length-not-dividable-by-wrap-key-blo.patch
@@ -0,0 +1,113 @@ 
+From 7727729417400d3eb692b8ec197f6f72f1961d54 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Mon, 1 Oct 2018 11:39:09 +0200
+Subject: [PATCH] Import key with length not dividable by wrap key block size
+
+Wrapping of the key is standard crypto operation which needs data
+aligned to cipher block size, otherwise it fails.
+
+Possible solution is to use a zero filled buffer with size aligned to
+required wrap key block size. Private key is copied to the beginning of
+the buffer and unwrap operation keeps using only required private key
+size.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ libknet/crypto_nss.c                   | 28 ++++++++++++++++++++++++--
+ libknet/tests/api_knet_handle_crypto.c | 21 +++++++++++++++++++
+ 2 files changed, 47 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 9191d9a3..ae2d2b01 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -176,7 +176,9 @@ static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h, enum sym_key_ty
+ 	SECItem tmp_sec_item;
+ 	SECItem wrapped_key;
+ 	int wrapped_key_len;
++	int wrap_key_block_size;
+ 	unsigned char wrapped_key_data[KNET_MAX_KEY_LEN];
++	unsigned char pad_key_data[KNET_MAX_KEY_LEN];
+ 
+ 	memset(&key_item, 0, sizeof(key_item));
+ 	slot = NULL;
+@@ -184,8 +186,15 @@ static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h, enum sym_key_ty
+ 	res_key = NULL;
+ 	wrap_key_crypt_context = NULL;
+ 
++	if (instance->private_key_len > sizeof(pad_key_data)) {
++		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Import symmetric key failed. Private key is too long");
++		goto exit_res_key;
++	}
++	memset(pad_key_data, 0, sizeof(pad_key_data));
++	memcpy(pad_key_data, instance->private_key, instance->private_key_len);
++
+ 	key_item.type = siBuffer;
+-	key_item.data = instance->private_key;
++	key_item.data = pad_key_data;
+ 
+ 	switch (key_type) {
+ 		case SYM_KEY_TYPE_CRYPT:
+@@ -237,6 +246,21 @@ static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h, enum sym_key_ty
+ 	 * Encrypt authkey with wrapping key
+ 	 */
+ 
++	/*
++	 * Key must be padded to a block size
++	 */
++	wrap_key_block_size = PK11_GetBlockSize(wrap_mechanism, 0);
++	if (wrap_key_block_size < 0) {
++		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to get wrap key block size (%d): %s",
++			PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		goto exit_res_key;
++	}
++	if (sizeof(pad_key_data) % wrap_key_block_size != 0) {
++		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Padded key buffer size (%zu) is not dividable by "
++			"wrap key block size (%u).", sizeof(pad_key_data), (unsigned int)wrap_key_block_size);
++		goto exit_res_key;
++	}
++
+ 	/*
+ 	 * Initialization of IV is not needed because PK11_GetBestWrapMechanism should return ECB mode
+ 	 */
+@@ -252,7 +276,7 @@ static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h, enum sym_key_ty
+ 	wrapped_key_len = (int)sizeof(wrapped_key_data);
+ 
+ 	if (PK11_CipherOp(wrap_key_crypt_context, wrapped_key_data, &wrapped_key_len,
+-			  sizeof(wrapped_key_data), key_item.data, key_item.len) != SECSuccess) {
++			  sizeof(wrapped_key_data), key_item.data, sizeof(pad_key_data)) != SECSuccess) {
+ 		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to encrypt authkey (%d): %s",
+ 			PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
+ 		goto exit_res_key;
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index 4d7fe59a..97ff354e 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -170,6 +170,27 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_handle_crypto with %s/aes128/sha1 and key where (key_len %% wrap_key_block_size != 0)\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	/*
++	 * Prime number so chance that (private_key_len % wrap_key_block_size == 0) is minimalized
++	 */
++	knet_handle_crypto_cfg.private_key_len = 2003;
++
++	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg) < 0) {
++		printf("knet_handle_crypto doesn't accept private_ley with len 2003: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
+ 	printf("Shutdown crypto\n");
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0045-links-Don-t-close-loopback-link.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0045-links-Don-t-close-loopback-link.patch
new file mode 100644
index 000000000..13c8bf26e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0045-links-Don-t-close-loopback-link.patch
@@ -0,0 +1,28 @@ 
+From bc8364af0114662586dca03a7ab039b89e9d63fb Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 19 Oct 2018 13:13:47 +0100
+Subject: [PATCH] links: Don't close loopback link
+
+knet_link_clear_config would incorrectly clear the local
+loopback link if the last 'real' link to an external node
+was closed. We didn't check the nodeid in the code, just
+the link number when clearing the loopback flag.
+
+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+---
+ libknet/links.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index df570de4..6185d4df 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -401,7 +401,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	memset(link, 0, sizeof(struct knet_link));
+ 	link->link_id = link_id;
+ 
+-	if (knet_h->has_loop_link && link_id == knet_h->loop_link) {
++	if (knet_h->has_loop_link && host_id == knet_h->host_id && link_id == knet_h->loop_link) {
+ 		knet_h->has_loop_link = 0;
+ 		if (host->active_link_entries == 0) {
+ 			host->status.reachable = 0;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0046-misc-keep-covscan-happy.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0046-misc-keep-covscan-happy.patch
new file mode 100644
index 000000000..35f6462e0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0046-misc-keep-covscan-happy.patch
@@ -0,0 +1,43 @@ 
+From 1e13684e7d05a7146e595c2baecb547ca26f4a74 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 22 Oct 2018 16:10:08 +0100
+Subject: [PATCH] misc: keep covscan happy
+
+covscan complains about is ignoring returns from pthread_mutex_lock()
+but in those 2 circumstances we don't have much choice.
+
+This patch just keeps coverity quiet so we don't miss any real bugs it
+might find.
+
+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+---
+ libknet/crypto_openssl.c | 2 +-
+ libknet/handle.c         | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 93ebc4fd..7bfa18f1 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -409,7 +409,7 @@ static pthread_mutex_t *openssl_internal_lock;
+ static void openssl_internal_locking_callback(int mode, int type, char *file, int line)
+ {
+ 	if (mode & CRYPTO_LOCK) {
+-		pthread_mutex_lock(&(openssl_internal_lock[type]));
++		(void)pthread_mutex_lock(&(openssl_internal_lock[type]));
+ 	} else {
+ 		pthread_mutex_unlock(&(openssl_internal_lock[type]));
+ 	}
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 71b6117e..7932e36d 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -757,7 +757,7 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	free(knet_h);
+ 	knet_h = NULL;
+ 
+-	pthread_mutex_lock(&handle_config_mutex);
++	(void)pthread_mutex_lock(&handle_config_mutex);
+ 	knet_ref--;
+ 	_fini_shlib_tracker();
+ 	pthread_mutex_unlock(&handle_config_mutex);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0047-man-update-XML-directory-in-doxyxml.c.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0047-man-update-XML-directory-in-doxyxml.c.patch
new file mode 100644
index 000000000..b6f0b7bb9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0047-man-update-XML-directory-in-doxyxml.c.patch
@@ -0,0 +1,25 @@ 
+From 6f86cee84fbbe593cd0077c4bf83dd24adaca7fa Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <chenjingpiao@gmail.com>
+Date: Mon, 5 Nov 2018 10:10:44 +0800
+Subject: [PATCH] man: update XML directory in doxyxml.c
+
+Fixes: 31945b18 ("[man] move libknet man pages and man pages build tools to top level dir")
+
+Signed-off-by: Chen Jingpiao <chenjingpiao@gmail.com>
+---
+ man/doxyxml.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index fdd2d072..9f493b26 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -31,7 +31,7 @@
+ #include <qb/qblist.h>
+ #include <qb/qbmap.h>
+ 
+-#define XML_DIR "../../libknet/man/xml"
++#define XML_DIR "../man/xml-knet"
+ #define XML_FILE "libknet_8h.xml"
+ 
+ static int print_ascii = 1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0048-fix-typo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0048-fix-typo.patch
new file mode 100644
index 000000000..680a7dad7
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0048-fix-typo.patch
@@ -0,0 +1,23 @@ 
+From 1fbbc2db7c0dfcf22b4f5154e871c181cb159ee2 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <chenjingpiao@gmail.com>
+Date: Mon, 5 Nov 2018 10:22:45 +0800
+Subject: [PATCH] fix typo
+
+Signed-off-by: Chen Jingpiao <chenjingpiao@gmail.com>
+---
+ libknet/libknet.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index c0f11a0b..45fb3cbb 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -99,7 +99,7 @@ typedef struct knet_handle *knet_handle_t;
+  *
+  * host_id  - Each host in a knet is identified with a unique
+  *            ID. when creating a new handle local host_id
+- *            must be specified (0 to UINT16T_MAX are all valid).
++ *            must be specified (0 to UINT16_MAX are all valid).
+  *            It is the user's responsibility to check that the value
+  *            is unique, or bad things might happen.
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0049-tests-fix-output-message.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0049-tests-fix-output-message.patch
new file mode 100644
index 000000000..5fda6af94
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0049-tests-fix-output-message.patch
@@ -0,0 +1,53 @@ 
+From 5a2ec430df4db9a083c861e69882eef2c26d7228 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <chenjingpiao@gmail.com>
+Date: Wed, 31 Oct 2018 16:09:44 +0800
+Subject: [PATCH] tests: fix output message
+
+Fixes: 04537c57 ("[transports] cleanup API calls")
+
+Signed-off-by: Chen Jingpiao <chenjingpiao@gmail.com>
+---
+ libknet/tests/api_knet_get_transport_id_by_name.c | 2 +-
+ libknet/tests/api_knet_get_transport_list.c       | 2 +-
+ libknet/tests/api_knet_get_transport_name_by_id.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/tests/api_knet_get_transport_id_by_name.c b/libknet/tests/api_knet_get_transport_id_by_name.c
+index eff12e79..97d8a6c3 100644
+--- a/libknet/tests/api_knet_get_transport_id_by_name.c
++++ b/libknet/tests/api_knet_get_transport_id_by_name.c
+@@ -41,7 +41,7 @@ static void test(void)
+ 
+ 	id = knet_get_transport_id_by_name("UDP");
+ 	if (id != KNET_TRANSPORT_UDP) {
+-		printf("knet_handle_get_transport_id_by_name failed: %s\n", strerror(errno));
++		printf("knet_get_transport_id_by_name failed: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ }
+diff --git a/libknet/tests/api_knet_get_transport_list.c b/libknet/tests/api_knet_get_transport_list.c
+index bd12b5d0..0c2fa938 100644
+--- a/libknet/tests/api_knet_get_transport_list.c
++++ b/libknet/tests/api_knet_get_transport_list.c
+@@ -28,7 +28,7 @@ static void test(void)
+ 
+ 	memset(transport_list, 0, sizeof(transport_list));
+ 
+-	printf("Test knet_handle_get_transport_list with no entries_list\n");
++	printf("Test knet_get_transport_list with no entries_list\n");
+ 
+ 	if ((!knet_get_transport_list(transport_list, NULL)) || (errno != EINVAL)) {
+ 		printf("knet_get_transport_list accepted invalid list_entries or returned incorrect error: %s\n", strerror(errno));
+diff --git a/libknet/tests/api_knet_get_transport_name_by_id.c b/libknet/tests/api_knet_get_transport_name_by_id.c
+index 46fc4b30..7f5fa46b 100644
+--- a/libknet/tests/api_knet_get_transport_name_by_id.c
++++ b/libknet/tests/api_knet_get_transport_name_by_id.c
+@@ -23,7 +23,7 @@ static void test(void)
+ {
+ 	const char *name = NULL;
+ 
+-	printf("Test knet_handle_get_transport_name_by_id with incorrect transport\n");
++	printf("Test knet_get_transport_name_by_id with incorrect transport\n");
+ 
+ 	if ((knet_get_transport_name_by_id(KNET_MAX_TRANSPORTS) != NULL) || (errno != EINVAL)) {
+ 		printf("knet_get_transport_name_by_id accepted invalid transport or returned incorrect error: %s\n", strerror(errno));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0050-build-fix-supported-compiler-warning-detection.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0050-build-fix-supported-compiler-warning-detection.patch
new file mode 100644
index 000000000..f606b4549
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0050-build-fix-supported-compiler-warning-detection.patch
@@ -0,0 +1,57 @@ 
+From 52314b64f9e8eba22a0e0f7787d9f08ad67b27f7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 7 Nov 2018 14:27:16 +0100
+Subject: [PATCH] [build] fix supported compiler warning detection
+
+move from AC_PREPROC_IFELSE (strongly discouraged) to AC_COMPILE_IFELSE
+
+our detection system was very weak and recent versions of clang did
+show that PREPROC_IFELFE (cpp) would enable warning options that
+the compiler does not support (clang).
+
+use a full compilation test to detect what works and what doesn't.
+
+Also expand the warning list to include new / renamed clang options
+of equivalents already enabled for older versions of clang and gcc.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 07997ab4..e906e4a3 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -185,7 +185,7 @@ cc_supports_flag() {
+ 		CPPFLAGS="-Werror $CPPFLAGS"
+ 	fi
+ 	AC_MSG_CHECKING([whether $CC supports "$@"])
+-	AC_PREPROC_IFELSE([AC_LANG_PROGRAM([])],
++	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+ 			  [RC=0; AC_MSG_RESULT([yes])],
+ 			  [RC=1; AC_MSG_RESULT([no])])
+ 	CPPFLAGS="$saveCPPFLAGS"
+@@ -409,6 +409,7 @@ WARNLIST="
+ 	missing-declarations
+ 	suggest-attribute=noreturn
+ 	suggest-attribute=format
++	property-attribute-mismatch
+ 	strict-prototypes
+ 	declaration-after-statement
+ 	pointer-arith
+@@ -432,12 +433,14 @@ WARNLIST="
+ 	parentheses
+ 	sequence-point
+ 	switch
++	shift-overflow
+ 	shift-overflow=2
+ 	overlength-strings
+ 	retundent-decls
+ 	init-self
+ 	uninitialized
+ 	unused-but-set-variable
++	unused-const-variable
+ 	unused-function
+ 	unused-result
+ 	unused-value
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0051-transports-fix-transport_modules_cmd-array-out-of-ra.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0051-transports-fix-transport_modules_cmd-array-out-of-ra.patch
new file mode 100644
index 000000000..646c57110
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0051-transports-fix-transport_modules_cmd-array-out-of-ra.patch
@@ -0,0 +1,25 @@ 
+From a9347253f86c4419d00e14278e8cb966a1305405 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Mon, 12 Nov 2018 10:30:18 +0800
+Subject: [PATCH] [transports] fix transport_modules_cmd array out of range
+
+Fixes: 18ab4888
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/transports.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 42f169ce..e7f1196a 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -29,7 +29,7 @@
+ 
+ #define empty_module 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+-knet_transport_ops_t transport_modules_cmd[] = {
++knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+ 	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+ 	{ "UDP", KNET_TRANSPORT_UDP, 1, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0052-Add-static-qualifier-to-compress-crypto-transport-_m.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0052-Add-static-qualifier-to-compress-crypto-transport-_m.patch
new file mode 100644
index 000000000..a2f65d3da
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0052-Add-static-qualifier-to-compress-crypto-transport-_m.patch
@@ -0,0 +1,52 @@ 
+From 0099d292475e7def088374be75c22ee68dbdff93 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Mon, 12 Nov 2018 10:50:54 +0800
+Subject: [PATCH] Add static qualifier to {compress, crypto,
+ transport}_modules_cmds
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/compress.c   | 2 +-
+ libknet/crypto.c     | 2 +-
+ libknet/transports.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 536b0439..c7c0d0e6 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -32,7 +32,7 @@
+  * Always add new items before the last NULL.
+  */
+ 
+-compress_model_t compress_modules_cmds[] = {
++static compress_model_t compress_modules_cmds[] = {
+ 	{ "none" , 0, 0, 0, NULL },
+ 	{ "zlib" , 1, WITH_COMPRESS_ZLIB , 0, NULL },
+ 	{ "lz4"  , 2, WITH_COMPRESS_LZ4  , 0, NULL },
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 43c21994..6b1ead7d 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -24,7 +24,7 @@
+  * internal module switch data
+  */
+ 
+-crypto_model_t crypto_modules_cmds[] = {
++static crypto_model_t crypto_modules_cmds[] = {
+ 	{ "nss", WITH_CRYPTO_NSS, 0, NULL },
+ 	{ "openssl", WITH_CRYPTO_OPENSSL, 0, NULL },
+ 	{ NULL, 0, 0, NULL }
+diff --git a/libknet/transports.c b/libknet/transports.c
+index e7f1196a..67ebc6ef 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -29,7 +29,7 @@
+ 
+ #define empty_module 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+-knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
++static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+ 	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+ 	{ "UDP", KNET_TRANSPORT_UDP, 1, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0053-tx-remove-goto-statement-to-improve-readability.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0053-tx-remove-goto-statement-to-improve-readability.patch
new file mode 100644
index 000000000..c2c0e4150
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0053-tx-remove-goto-statement-to-improve-readability.patch
@@ -0,0 +1,50 @@ 
+From c23d614acda648333d45e195f319303693cc23d1 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Fri, 9 Nov 2018 17:47:17 +0800
+Subject: [PATCH] [tx] remove goto statement to improve readability
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/threads_tx.c | 20 ++++++--------------
+ 1 file changed, 6 insertions(+), 14 deletions(-)
+
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 20798c0c..a1b407d3 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -639,21 +639,11 @@ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int
+ 	if (inlen == 0) {
+ 		savederrno = 0;
+ 		docallback = 1;
+-		goto out;
+-	}
+-	if (inlen < 0) {
+-		savederrno = errno;
+-		docallback = 1;
+-		goto out;
+-	}
+-
+-	knet_h->recv_from_sock_buf->kh_type = type;
+-	_parse_recv_from_sock(knet_h, inlen, channel, 0);
+-
+-out:
+-	if (inlen < 0) {
++	} else if (inlen < 0) {
+ 		struct epoll_event ev;
+ 
++		savederrno = errno;
++		docallback = 1;
+ 		memset(&ev, 0, sizeof(struct epoll_event));
+ 
+ 		if (epoll_ctl(knet_h->send_to_links_epollfd,
+@@ -663,7 +653,9 @@ out:
+ 		} else {
+ 			knet_h->sockfd[channel].has_error = 1;
+ 		}
+-
++	} else {
++		knet_h->recv_from_sock_buf->kh_type = type;
++		_parse_recv_from_sock(knet_h, inlen, channel, 0);
+ 	}
+ 
+ 	if (docallback) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0054-rx-fix-incorrect-packet-length-in-_parse_recv_from_l.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0054-rx-fix-incorrect-packet-length-in-_parse_recv_from_l.patch
new file mode 100644
index 000000000..c01b25e2d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0054-rx-fix-incorrect-packet-length-in-_parse_recv_from_l.patch
@@ -0,0 +1,32 @@ 
+From 7ec44712413dc758ad0cb3c1137baa3c663ac549 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Tue, 13 Nov 2018 10:24:53 +0800
+Subject: [PATCH] [rx] fix incorrect packet length in _parse_recv_from_links
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/threads_rx.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 3017ce4c..2aa1164a 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -566,7 +566,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		if (knet_h->crypto_instance) {
+ 			if (crypto_encrypt_and_sign(knet_h,
+ 						    (const unsigned char *)inbuf,
+-						    len,
++						    outlen,
+ 						    knet_h->recv_from_links_buf_crypt,
+ 						    &outlen) < 0) {
+ 				log_debug(knet_h, KNET_SUB_RX, "Unable to encrypt pong packet");
+@@ -654,7 +654,7 @@ retry_pong:
+ 		if (knet_h->crypto_instance) {
+ 			if (crypto_encrypt_and_sign(knet_h,
+ 						    (const unsigned char *)inbuf,
+-						    len,
++						    outlen,
+ 						    knet_h->recv_from_links_buf_crypt,
+ 						    &outlen) < 0) {
+ 				log_debug(knet_h, KNET_SUB_RX, "Unable to encrypt PMTUd reply packet");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0055-tx-fix-tx_uncompressed_packets-stats-collect-in-_par.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0055-tx-fix-tx_uncompressed_packets-stats-collect-in-_par.patch
new file mode 100644
index 000000000..16206705e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0055-tx-fix-tx_uncompressed_packets-stats-collect-in-_par.patch
@@ -0,0 +1,24 @@ 
+From c1aef36e33014364aecd4c3be9778b37ad14a101 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Sun, 11 Nov 2018 14:49:09 +0800
+Subject: [PATCH] [tx] fix tx_uncompressed_packets stats collect in
+ _parse_recv_from_sock
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/threads_tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index a1b407d3..817d3a20 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -375,7 +375,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 			}
+ 		}
+ 	}
+-	if ((knet_h->compress_model > 0) && (inlen <= knet_h->compress_threshold)) {
++	if (knet_h->compress_model > 0 && !data_compressed) {
+ 		knet_h->stats.tx_uncompressed_packets++;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0056-openssl-fix-return-type-for-pthread_self.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0056-openssl-fix-return-type-for-pthread_self.patch
new file mode 100644
index 000000000..cf96bab54
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0056-openssl-fix-return-type-for-pthread_self.patch
@@ -0,0 +1,28 @@ 
+From ae2403348cf0cfb859f7f452d34f2225417a33e9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 20 Nov 2018 05:31:58 +0100
+Subject: [PATCH] [openssl] fix return type for pthread_self
+
+spotted on freebsd-devel
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 7bfa18f1..ca06c451 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -415,9 +415,9 @@ static void openssl_internal_locking_callback(int mode, int type, char *file, in
+ 	}
+ }
+ 
+-static unsigned long openssl_internal_thread_id(void)
++static pthread_t openssl_internal_thread_id(void)
+ {
+-	return (unsigned long)pthread_self();
++	return pthread_self();
+ }
+ 
+ static void openssl_internal_lock_cleanup(void)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0057-clear-the-errno-in-each-exported-API-when-the-call-s.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0057-clear-the-errno-in-each-exported-API-when-the-call-s.patch
new file mode 100644
index 000000000..543444a16
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0057-clear-the-errno-in-each-exported-API-when-the-call-s.patch
@@ -0,0 +1,570 @@ 
+From 29c02921a2a8ac40cdf199d9c65ef48a6eecd0d2 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Tue, 27 Nov 2018 10:46:49 +0800
+Subject: [PATCH] clear the errno in each exported API when the call success
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/compress.c   |  2 ++
+ libknet/crypto.c     |  2 ++
+ libknet/handle.c     | 29 +++++++++++++++++++----------
+ libknet/host.c       | 19 ++++++++++---------
+ libknet/links.c      | 26 +++++++++++++-------------
+ libknet/logging.c    |  6 ++++++
+ libknet/netutils.c   | 15 ++++++++++++---
+ libknet/threads_tx.c |  2 +-
+ libknet/transports.c |  8 ++++++--
+ 9 files changed, 71 insertions(+), 38 deletions(-)
+
+diff --git a/libknet/compress.c b/libknet/compress.c
+index c7c0d0e6..8af7beff 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -477,5 +477,7 @@ int knet_get_compress_list(struct knet_compress_info *compress_list, size_t *com
+ 	}
+ 	*compress_list_entries = outidx;
+ 
++	if (!err)
++		errno = 0;
+ 	return err;
+ }
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 6b1ead7d..172bac7b 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -208,5 +208,7 @@ int knet_get_crypto_list(struct knet_crypto_info *crypto_list, size_t *crypto_li
+ 	}
+ 	*crypto_list_entries = outidx;
+ 
++	if (!err)
++		errno = 0;
+ 	return err;
+ }
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 7932e36d..71bcb569 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -699,6 +699,7 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 
+ 	wait_all_threads_status(knet_h, KNET_THREAD_RUNNING);
+ 
++	errno = 0;
+ 	return knet_h;
+ 
+ exit_fail:
+@@ -762,6 +763,7 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	_fini_shlib_tracker();
+ 	pthread_mutex_unlock(&handle_config_mutex);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -801,6 +803,7 @@ int knet_handle_enable_sock_notify(knet_handle_t knet_h,
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -941,7 +944,7 @@ int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel)
+ 
+ out_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1005,7 +1008,7 @@ int knet_handle_remove_datafd(knet_handle_t knet_h, int datafd)
+ 
+ out_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1046,7 +1049,7 @@ int knet_handle_get_datafd(knet_handle_t knet_h, const int8_t channel, int *data
+ 
+ out_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1096,7 +1099,7 @@ int knet_handle_get_channel(knet_handle_t knet_h, const int datafd, int8_t *chan
+ 
+ out_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1138,6 +1141,7 @@ int knet_handle_enable_filter(knet_handle_t knet_h,
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -1173,6 +1177,7 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled)
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -1202,6 +1207,7 @@ int knet_handle_pmtud_getfreq(knet_handle_t knet_h, unsigned int *interval)
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -1232,6 +1238,7 @@ int knet_handle_pmtud_setfreq(knet_handle_t knet_h, unsigned int interval)
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -1266,6 +1273,7 @@ int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -1296,6 +1304,7 @@ int knet_handle_pmtud_get(knet_handle_t knet_h,
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -1357,7 +1366,7 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1389,7 +1398,7 @@ int knet_handle_compress(knet_handle_t knet_h, struct knet_handle_compress_cfg *
+ 	savederrno = errno;
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1452,7 +1461,7 @@ ssize_t knet_recv(knet_handle_t knet_h, char *buff, const size_t buff_len, const
+ 
+ out_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1516,7 +1525,7 @@ ssize_t knet_send(knet_handle_t knet_h, const char *buff, const size_t buff_len,
+ 
+ out_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1563,7 +1572,7 @@ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats,
+ 	stats->size = sizeof(struct knet_handle_stats);
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1598,7 +1607,7 @@ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+ 	}
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+diff --git a/libknet/host.c b/libknet/host.c
+index 9f6648e8..00e2298e 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -107,7 +107,7 @@ exit_unlock:
+ 	if (err < 0) {
+ 		free(host);
+ 	}
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -179,7 +179,7 @@ int knet_host_remove(knet_handle_t knet_h, knet_node_id_t host_id)
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -239,7 +239,7 @@ int knet_host_set_name(knet_handle_t knet_h, knet_node_id_t host_id, const char
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -277,7 +277,7 @@ int knet_host_get_name_by_host_id(knet_handle_t knet_h, knet_node_id_t host_id,
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -324,7 +324,7 @@ int knet_host_get_id_by_host_name(knet_handle_t knet_h, const char *name,
+ 	}
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -355,7 +355,7 @@ int knet_host_get_host_list(knet_handle_t knet_h,
+ 	*host_ids_entries = knet_h->host_ids_entries;
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -406,7 +406,7 @@ int knet_host_set_policy(knet_handle_t knet_h, knet_node_id_t host_id,
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -445,7 +445,7 @@ int knet_host_get_policy(knet_handle_t knet_h, knet_node_id_t host_id,
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -486,7 +486,7 @@ int knet_host_get_status(knet_handle_t knet_h, knet_node_id_t host_id,
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -524,6 +524,7 @@ int knet_host_enable_status_change_notify(knet_handle_t knet_h,
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	errno = 0;
+ 	return 0;
+ }
+ 
+diff --git a/libknet/links.c b/libknet/links.c
+index 6185d4df..ba28dbd9 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -244,7 +244,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -336,7 +336,7 @@ int knet_link_get_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -413,7 +413,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -483,7 +483,7 @@ int knet_link_set_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -540,7 +540,7 @@ int knet_link_get_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -601,7 +601,7 @@ int knet_link_set_pong_count(knet_handle_t knet_h, knet_node_id_t host_id, uint8
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -658,7 +658,7 @@ int knet_link_get_pong_count(knet_handle_t knet_h, knet_node_id_t host_id, uint8
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -733,7 +733,7 @@ int knet_link_set_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -802,7 +802,7 @@ int knet_link_get_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -876,7 +876,7 @@ int knet_link_set_priority(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -933,7 +933,7 @@ int knet_link_get_priority(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -989,7 +989,7 @@ int knet_link_get_link_list(knet_handle_t knet_h, knet_node_id_t host_id,
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -1081,6 +1081,6 @@ int knet_link_get_status(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 543269a5..14c6eff5 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -59,6 +59,7 @@ const char *knet_log_get_subsystem_name(uint8_t subsystem)
+ 			break;
+ 		}
+ 		if (subsystem_names[i].val == subsystem) {
++			errno = 0;
+ 			return subsystem_names[i].name;
+ 		}
+ 	}
+@@ -74,6 +75,7 @@ uint8_t knet_log_get_subsystem_id(const char *name)
+ 			break;
+ 		}
+ 		if (strcasecmp(name, subsystem_names[i].name) == 0) {
++			errno = 0;
+ 			return subsystem_names[i].val;
+ 		}
+ 	}
+@@ -110,6 +112,7 @@ const char *knet_log_get_loglevel_name(uint8_t level)
+ 
+ 	for (i = 0; i <= KNET_LOG_DEBUG; i++) {
+ 		if (loglevel_names[i].val == level) {
++			errno = 0;
+ 			return loglevel_names[i].name;
+ 		}
+ 	}
+@@ -122,6 +125,7 @@ uint8_t knet_log_get_loglevel_id(const char *name)
+ 
+ 	for (i = 0; i <= KNET_LOG_DEBUG; i++) {
+ 		if (strcasecmp(name, loglevel_names[i].name) == 0) {
++			errno = 0;
+ 			return loglevel_names[i].val;
+ 		}
+ 	}
+@@ -159,6 +163,7 @@ int knet_log_set_loglevel(knet_handle_t knet_h, uint8_t subsystem,
+ 	knet_h->log_levels[subsystem] = level;
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -193,6 +198,7 @@ int knet_log_get_loglevel(knet_handle_t knet_h, uint8_t subsystem,
+ 	*level = knet_h->log_levels[subsystem];
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = 0;
+ 	return 0;
+ }
+ 
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index 69c704a9..f30054ba 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -134,6 +134,8 @@ int knet_strtoaddr(const char *host, const char *port, struct sockaddr_storage *
+ 		freeaddrinfo(result);
+ 	}
+ 
++	if (!err)
++		errno = 0;
+ 	return err;
+ }
+ 
+@@ -141,6 +143,8 @@ int knet_addrtostr(const struct sockaddr_storage *ss, socklen_t sslen,
+ 		   char *addr_buf, size_t addr_buf_size,
+ 		   char *port_buf, size_t port_buf_size)
+ {
++	int err;
++
+ 	if (!ss) {
+ 		errno = EINVAL;
+ 		return -1;
+@@ -161,7 +165,12 @@ int knet_addrtostr(const struct sockaddr_storage *ss, socklen_t sslen,
+ 		return -1;
+ 	}
+ 
+-	return getnameinfo((struct sockaddr *)ss, sockaddr_len(ss), addr_buf, addr_buf_size,
+-				port_buf, port_buf_size,
+-				NI_NUMERICHOST | NI_NUMERICSERV);
++	err = getnameinfo((struct sockaddr *)ss, sockaddr_len(ss),
++			  addr_buf, addr_buf_size,
++			  port_buf, port_buf_size,
++			  NI_NUMERICHOST | NI_NUMERICSERV);
++
++	if (!err)
++		errno = 0;
++	return err;
+ }
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 817d3a20..f73592ab 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -619,7 +619,7 @@ int knet_send_sync(knet_handle_t knet_h, const char *buff, const size_t buff_len
+ out:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
+-	errno = savederrno;
++	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 67ebc6ef..b685212f 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -147,6 +147,8 @@ int knet_get_transport_list(struct knet_transport_info *transport_list,
+ 
+ 	*transport_list_entries = outidx;
+ 
++	if (!err)
++		errno = 0;
+ 	return err;
+ }
+ 
+@@ -167,7 +169,7 @@ const char *knet_get_transport_name_by_id(uint8_t transport)
+ 		savederrno = ENOENT;
+ 	}
+ 
+-	errno = savederrno;
++	errno = name ? 0 : savederrno;
+ 	return name;
+ }
+ 
+@@ -199,7 +201,7 @@ uint8_t knet_get_transport_id_by_name(const char *name)
+ 		savederrno = EINVAL;
+ 	}
+ 
+-	errno = savederrno;
++	errno = err == KNET_MAX_TRANSPORTS ? savederrno : 0;
+ 	return err;
+ }
+ 
+@@ -236,6 +238,7 @@ int knet_handle_set_transport_reconnect_interval(knet_handle_t knet_h, uint32_t
+ 	knet_h->reconnect_int = msecs;
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = 0;
+ 	return 0;
+ }
+ 
+@@ -264,5 +267,6 @@ int knet_handle_get_transport_reconnect_interval(knet_handle_t knet_h, uint32_t
+ 	*msecs = knet_h->reconnect_int;
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = 0;
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0058-tests-fix-check-condition-in-api_knet_-addrtostr-str.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0058-tests-fix-check-condition-in-api_knet_-addrtostr-str.patch
new file mode 100644
index 000000000..ac88f2b8d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0058-tests-fix-check-condition-in-api_knet_-addrtostr-str.patch
@@ -0,0 +1,92 @@ 
+From beda3970f0edf4a9a318ead307d2d17cf35168e2 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Thu, 22 Nov 2018 13:20:07 +0800
+Subject: [PATCH] [tests] fix check condition in
+ api_knet_{addrtostr,strtoaddr}.c
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/tests/api_knet_addrtostr.c | 8 ++++----
+ libknet/tests/api_knet_strtoaddr.c | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index d7c43959..d2447135 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -34,7 +34,7 @@ static void test(void)
+ 
+ 	if (!knet_addrtostr(NULL, sizeof(struct sockaddr_storage),
+ 			    addr_str, KNET_MAX_HOST_LEN,
+-			    port_str, KNET_MAX_PORT_LEN) && (errno != EINVAL)) {
++			    port_str, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+ 		printf("knet_addrtostr accepted invalid ss\n");
+ 		exit(FAIL);
+ 	}
+@@ -43,7 +43,7 @@ static void test(void)
+ 
+ 	if (!knet_addrtostr(&addr, 0,
+ 			    addr_str, KNET_MAX_HOST_LEN,
+-			    port_str, KNET_MAX_PORT_LEN) && (errno != EINVAL)) {
++			    port_str, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+ 		printf("knet_addrtostr accepted invalid sslen\n");
+ 		exit(FAIL);
+ 	}
+@@ -52,7 +52,7 @@ static void test(void)
+ 
+ 	if (!knet_addrtostr(&addr, sizeof(struct sockaddr_storage),
+ 			    NULL, KNET_MAX_HOST_LEN,
+-			    port_str, KNET_MAX_PORT_LEN) && (errno != EINVAL)) {
++			    port_str, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+ 		printf("knet_addrtostr accepted invalid addr_str\n");
+ 		exit(FAIL);
+ 	}
+@@ -61,7 +61,7 @@ static void test(void)
+ 
+ 	if (!knet_addrtostr(&addr, sizeof(struct sockaddr_storage),
+ 			    addr_str, KNET_MAX_HOST_LEN,
+-			    NULL, KNET_MAX_PORT_LEN) && (errno != EINVAL)) {
++			    NULL, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+ 		printf("knet_addrtostr accepted invalid addr_str\n");
+ 		exit(FAIL);
+ 	}
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index ac301ffe..5fc17c55 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -34,7 +34,7 @@ static void test(void)
+ 
+ 	printf("Checking knet_strtoaddr with invalid host\n");
+ 
+-	if (!knet_strtoaddr(NULL, "50000", &out_addr, sizeof(struct sockaddr_storage)) &&
++	if (!knet_strtoaddr(NULL, "50000", &out_addr, sizeof(struct sockaddr_storage)) ||
+ 	    (errno != EINVAL)) {
+ 		printf("knet_strtoaddr accepted invalid host\n");
+ 		exit(FAIL);
+@@ -42,7 +42,7 @@ static void test(void)
+ 
+ 	printf("Checking knet_strtoaddr with invalid port\n");
+ 
+-	if (!knet_strtoaddr("127.0.0.1", NULL, &out_addr, sizeof(struct sockaddr_storage)) &&
++	if (!knet_strtoaddr("127.0.0.1", NULL, &out_addr, sizeof(struct sockaddr_storage)) ||
+ 	    (errno != EINVAL)) {
+ 		printf("knet_strtoaddr accepted invalid port\n");
+ 		exit(FAIL);
+@@ -50,7 +50,7 @@ static void test(void)
+ 
+ 	printf("Checking knet_strtoaddr with invalid addr\n");
+ 
+-	if (!knet_strtoaddr("127.0.0.1", "50000", NULL, sizeof(struct sockaddr_storage)) &&
++	if (!knet_strtoaddr("127.0.0.1", "50000", NULL, sizeof(struct sockaddr_storage)) ||
+ 	    (errno != EINVAL)) {
+ 		printf("knet_strtoaddr accepted invalid addr\n");
+ 		exit(FAIL);
+@@ -58,7 +58,7 @@ static void test(void)
+ 
+ 	printf("Checking knet_strtoaddr with invalid size\n");
+ 
+-	if (!knet_strtoaddr("127.0.0.1", "50000", &out_addr, 0) &&
++	if (!knet_strtoaddr("127.0.0.1", "50000", &out_addr, 0) ||
+ 	    (errno != EINVAL)) {
+ 		printf("knet_strtoaddr accepted invalid size\n");
+ 		exit(FAIL);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0059-tests-update-error-message-in-api_knet_-addrtostr-st.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0059-tests-update-error-message-in-api_knet_-addrtostr-st.patch
new file mode 100644
index 000000000..058a46e28
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0059-tests-update-error-message-in-api_knet_-addrtostr-st.patch
@@ -0,0 +1,92 @@ 
+From e03e2d1b65c4338bbe5d5ee09c75faf43c263008 Mon Sep 17 00:00:00 2001
+From: Chen Jingpiao <jchen@suse.com>
+Date: Thu, 22 Nov 2018 13:23:42 +0800
+Subject: [PATCH] [tests] update error message in
+ api_knet_{addrtostr,strtoaddr}.c
+
+Signed-off-by: Chen Jingpiao <jchen@suse.com>
+---
+ libknet/tests/api_knet_addrtostr.c | 8 ++++----
+ libknet/tests/api_knet_strtoaddr.c | 8 ++++----
+ 2 files changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index d2447135..71fc2cfe 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -35,7 +35,7 @@ static void test(void)
+ 	if (!knet_addrtostr(NULL, sizeof(struct sockaddr_storage),
+ 			    addr_str, KNET_MAX_HOST_LEN,
+ 			    port_str, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+-		printf("knet_addrtostr accepted invalid ss\n");
++		printf("knet_addrtostr accepted invalid ss or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+@@ -44,7 +44,7 @@ static void test(void)
+ 	if (!knet_addrtostr(&addr, 0,
+ 			    addr_str, KNET_MAX_HOST_LEN,
+ 			    port_str, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+-		printf("knet_addrtostr accepted invalid sslen\n");
++		printf("knet_addrtostr accepted invalid sslen or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+@@ -53,7 +53,7 @@ static void test(void)
+ 	if (!knet_addrtostr(&addr, sizeof(struct sockaddr_storage),
+ 			    NULL, KNET_MAX_HOST_LEN,
+ 			    port_str, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+-		printf("knet_addrtostr accepted invalid addr_str\n");
++		printf("knet_addrtostr accepted invalid addr_str or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+@@ -62,7 +62,7 @@ static void test(void)
+ 	if (!knet_addrtostr(&addr, sizeof(struct sockaddr_storage),
+ 			    addr_str, KNET_MAX_HOST_LEN,
+ 			    NULL, KNET_MAX_PORT_LEN) || (errno != EINVAL)) {
+-		printf("knet_addrtostr accepted invalid addr_str\n");
++		printf("knet_addrtostr accepted invalid addr_str or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index 5fc17c55..08786034 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -36,7 +36,7 @@ static void test(void)
+ 
+ 	if (!knet_strtoaddr(NULL, "50000", &out_addr, sizeof(struct sockaddr_storage)) ||
+ 	    (errno != EINVAL)) {
+-		printf("knet_strtoaddr accepted invalid host\n");
++		printf("knet_strtoaddr accepted invalid host or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+@@ -44,7 +44,7 @@ static void test(void)
+ 
+ 	if (!knet_strtoaddr("127.0.0.1", NULL, &out_addr, sizeof(struct sockaddr_storage)) ||
+ 	    (errno != EINVAL)) {
+-		printf("knet_strtoaddr accepted invalid port\n");
++		printf("knet_strtoaddr accepted invalid port or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+@@ -52,7 +52,7 @@ static void test(void)
+ 
+ 	if (!knet_strtoaddr("127.0.0.1", "50000", NULL, sizeof(struct sockaddr_storage)) ||
+ 	    (errno != EINVAL)) {
+-		printf("knet_strtoaddr accepted invalid addr\n");
++		printf("knet_strtoaddr accepted invalid addr or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+@@ -60,7 +60,7 @@ static void test(void)
+ 
+ 	if (!knet_strtoaddr("127.0.0.1", "50000", &out_addr, 0) ||
+ 	    (errno != EINVAL)) {
+-		printf("knet_strtoaddr accepted invalid size\n");
++		printf("knet_strtoaddr accepted invalid size or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0060-misc-fix-a-few-typos-stylistics.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0060-misc-fix-a-few-typos-stylistics.patch
new file mode 100644
index 000000000..996155d0f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0060-misc-fix-a-few-typos-stylistics.patch
@@ -0,0 +1,43 @@ 
+From 00abf814f8af6fdad7b6a17eed449323c70cbf07 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
+Date: Mon, 3 Dec 2018 11:36:55 +0100
+Subject: [PATCH] [misc] fix a few typos/stylistics
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
+---
+ libknet/libknet.h          | 4 ++--
+ libknet/transport_common.c | 2 +-
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 45fb3cbb..d4591e87 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -236,9 +236,9 @@ int knet_handle_enable_sock_notify(knet_handle_t knet_h,
+  *            socketpair only if they have been created by knet_handle_add_datafd.
+  *
+  *            It is possible to pass either sockets or normal fds.
+- *            User provided datafd will be marked as non-blocking and close-on-exit.
++ *            User provided datafd will be marked as non-blocking and close-on-exec.
+  *
+- * *channel - This value has the same effect of VLAN tagging.
++ * *channel - This value is analogous to the tag in VLAN tagging.
+  *            A negative value will auto-allocate a channel.
+  *            Setting a value between 0 and 31 will try to allocate that
+  *            specific channel (unless already in use).
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index ffae0a5c..6df50027 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -28,7 +28,7 @@
+ /*
+  * reuse Jan Friesse's compat layer as wrapper to drop usage of sendmmsg
+  *
+- * TODO: kill those wrappers once we work on packet delivery guaranteed
++ * TODO: kill those wrappers once we work on packet delivery guarantees
+  */
+ 
+ int _recvmmsg(int sockfd, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0061-UDP-Cope-with-EPERM-returned-from-sendmsg-sendto.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0061-UDP-Cope-with-EPERM-returned-from-sendmsg-sendto.patch
new file mode 100644
index 000000000..9a9a78a70
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0061-UDP-Cope-with-EPERM-returned-from-sendmsg-sendto.patch
@@ -0,0 +1,28 @@ 
+From 119a713d0e0f2b2a92c7dc8d1f82da7bc78aa306 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 13 Dec 2018 09:59:30 +0000
+Subject: [PATCH] UDP: Cope with EPERM returned from sendmsg/sendto
+
+IPtables can cause -EPERM to be returned from socket sends, so
+we need to be able to handle it without going into a spin.
+
+SCTP seems to be unaffected.
+
+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+---
+ libknet/transport_udp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 25e1ae64..31445023 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -401,7 +401,7 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 			read_errs_from_sock(knet_h, sockfd);
+ 			return 0;
+ 		}
+-		if (recv_errno == EINVAL) {
++		if (recv_errno == EINVAL || recv_errno == EPERM) {
+ 			return -1;
+ 		}
+ 		if ((recv_errno == ENOBUFS) || (recv_errno == EAGAIN)) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0062-libtap-tests-allow-random-localhost-IPs-for-testing.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0062-libtap-tests-allow-random-localhost-IPs-for-testing.patch
new file mode 100644
index 000000000..6aa6c306a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0062-libtap-tests-allow-random-localhost-IPs-for-testing.patch
@@ -0,0 +1,360 @@ 
+From 1da0561125e4f3b4d633dff10ca0b60872ac5d40 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 7 Nov 2017 09:33:07 +0100
+Subject: [PATCH] [libtap] tests: allow random localhost IPs for testing
+
+- avoids clashing with machine routing
+- allows parallel testing
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libtap/libtap.c | 149 +++++++++++++++++++++++++++++++++++++-----------
+ 1 file changed, 115 insertions(+), 34 deletions(-)
+
+diff --git a/libtap/libtap.c b/libtap/libtap.c
+index 060db012..e0ebee2b 100644
+--- a/libtap/libtap.c
++++ b/libtap/libtap.c
+@@ -979,6 +979,12 @@ out_clean:
+ }
+ 
+ #ifdef TEST
++
++char testipv4_1[1024];
++char testipv4_2[1024];
++char testipv6_1[1024];
++char testipv6_2[1024];
++
+ static int is_if_in_system(char *name)
+ {
+ 	struct ifaddrs *ifap = NULL;
+@@ -1263,6 +1269,7 @@ static int check_knet_mtu_ipv6(void)
+ {
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
++	char verifycmd[1024];
+ 	int err=0;
+ 	tap_t tap;
+ 	char *error_string = NULL;
+@@ -1277,9 +1284,9 @@ static int check_knet_mtu_ipv6(void)
+ 		return -1;
+ 	}
+ 
+-	printf("Adding ip: 3ffe::1/64\n");
++	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = tap_add_ip(tap, "3ffe::1", "64", &error_string);
++	err = tap_add_ip(tap, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -1291,7 +1298,10 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1310,7 +1320,7 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1322,8 +1332,8 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Adding ip: 3ffe::2/64\n");
+-	err = tap_add_ip(tap, "3ffe::2", "64", &error_string);
++	printf("Adding ip: %s/64\n", testipv6_2);
++	err = tap_add_ip(tap, testipv6_2, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -1335,7 +1345,10 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::2/64", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++		 "ip addr show dev kronostest | grep -q %s/64", testipv6_2);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1354,7 +1367,10 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd) -1,
++		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1366,7 +1382,10 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::2/64", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd) -1,
++		 "ip addr show dev kronostest | grep -q %s/64", testipv6_2);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1840,9 +1859,9 @@ static int check_knet_close_leak(void)
+ 		return -1;
+ 	}
+ 
+-	printf("Adding ip: 192.168.168.168/24\n");
++	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_add_ip(tap, "192.168.168.168", "24", &error_string);
++	err = tap_add_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -1854,9 +1873,9 @@ static int check_knet_close_leak(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Adding ip: 192.168.169.169/24\n");
++	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = tap_add_ip(tap, "192.168.169.169", "24", &error_string);
++	err = tap_add_ip(tap, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -1879,6 +1898,7 @@ static int check_knet_set_del_ip(void)
+ {
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
++	char verifycmd[1024];
+ 	int err=0;
+ 	tap_t tap;
+ 	char *ip_list = NULL;
+@@ -1895,9 +1915,9 @@ static int check_knet_set_del_ip(void)
+ 		return -1;
+ 	}
+ 
+-	printf("Adding ip: 192.168.168.168/24\n");
++	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_add_ip(tap, "192.168.168.168", "24", &error_string);
++	err = tap_add_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -1909,9 +1929,9 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Adding ip: 192.168.169.169/24\n");
++	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = tap_add_ip(tap, "192.168.169.169", "24", &error_string);
++	err = tap_add_ip(tap, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -1923,9 +1943,9 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Adding duplicate ip: 192.168.168.168/24\n");
++	printf("Adding duplicate ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_add_ip(tap, "192.168.168.168", "24", &error_string);
++	err = tap_add_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -1937,9 +1957,12 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Checking ip: 192.168.168.168/24\n");
++	printf("Checking ip: %s/24\n", testipv4_1);
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 192.168.168.168/24", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++		 "ip addr show dev kronostest | grep -q %s/24", testipv4_1);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1973,9 +1996,9 @@ static int check_knet_set_del_ip(void)
+ 
+ 	free(ip_list);
+ 
+-	printf("Deleting ip: 192.168.168.168/24\n");
++	printf("Deleting ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_del_ip(tap, "192.168.168.168", "24", &error_string);
++	err = tap_del_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -1987,9 +2010,9 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Deleting ip: 192.168.169.169/24\n");
++	printf("Deleting ip: %s/24\n", testipv4_2);
+ 
+-	err = tap_del_ip(tap, "192.168.169.169", "24", &error_string);
++	err = tap_del_ip(tap, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2001,9 +2024,9 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Deleting again ip: 192.168.168.168/24\n");
++	printf("Deleting again ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_del_ip(tap, "192.168.168.168", "24", &error_string);
++	err = tap_del_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2015,7 +2038,10 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 192.168.168.168/24", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++		 "ip addr show dev kronostest | grep -q %s/24", testipv4_1);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -2027,9 +2053,9 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Adding ip: 3ffe::1/64\n");
++	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = tap_add_ip(tap, "3ffe::1", "64", &error_string);
++	err = tap_add_ip(tap, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -2041,7 +2067,10 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -2053,9 +2082,9 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Deleting ip: 3ffe::1/64\n");
++	printf("Deleting ip: %s/64\n", testipv6_1);
+ 
+-	err = tap_del_ip(tap, "3ffe::1", "64", &error_string);
++	err = tap_del_ip(tap, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -2067,7 +2096,10 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ip addr show dev kronostest | grep -q 3ffe::1/64", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -2086,6 +2118,53 @@ out_clean:
+ 	return err;
+ }
+ 
++static void make_local_ips(void)
++{
++	pid_t mypid;
++	uint8_t *pid;
++
++	if (sizeof(pid_t) < 4) {
++		printf("pid_t is smaller than 4 bytes?\n");
++		exit(77);
++	}
++
++	memset(testipv4_1, 0, sizeof(testipv4_1));
++	memset(testipv4_2, 0, sizeof(testipv4_2));
++	memset(testipv6_1, 0, sizeof(testipv6_1));
++	memset(testipv6_2, 0, sizeof(testipv6_2));
++
++	mypid = getpid();
++	pid = (uint8_t *)&mypid;
++
++	snprintf(testipv4_1,
++		 sizeof(testipv4_1) - 1,
++		 "127.%u.%u.%u",
++		 pid[0],
++		 pid[1],
++		 pid[2]);
++
++	snprintf(testipv4_2,
++		 sizeof(testipv4_2) - 1,
++		 "127.%u.%d.%u",
++		 pid[0],
++		 pid[1]+1,
++		 pid[2]);
++
++	snprintf(testipv6_1,
++		 sizeof(testipv6_1) - 1,
++		 "::%u:%u:%u:1",
++		 pid[0],
++		 pid[1],
++		 pid[2]);
++
++	snprintf(testipv6_2,
++		 sizeof(testipv6_2) - 1,
++		 "::%u:%u:%d:1",
++		 pid[0],
++		 pid[1],
++		 pid[2]+1);
++}
++
+ int main(void)
+ {
+ 	if (geteuid() != 0) {
+@@ -2093,6 +2172,8 @@ int main(void)
+ 		exit(77);
+ 	}
+ 
++	make_local_ips();
++
+ 	if (check_tap_open_close() < 0)
+ 		return -1;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0063-libtap-tests-add-better-IPv6-private-address-space-r.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0063-libtap-tests-add-better-IPv6-private-address-space-r.patch
new file mode 100644
index 000000000..f7c7a4c16
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0063-libtap-tests-add-better-IPv6-private-address-space-r.patch
@@ -0,0 +1,74 @@ 
+From 86ad0e3f115d3eb528f619f199b0f1e9f124cee8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 7 Nov 2017 11:08:32 +0100
+Subject: [PATCH] [libtap] tests: add better IPv6 private address space
+ randomization
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libtap/libtap.c | 29 ++++++++++++++++++-----------
+ 1 file changed, 18 insertions(+), 11 deletions(-)
+
+diff --git a/libtap/libtap.c b/libtap/libtap.c
+index e0ebee2b..b8e5f536 100644
+--- a/libtap/libtap.c
++++ b/libtap/libtap.c
+@@ -2122,6 +2122,7 @@ static void make_local_ips(void)
+ {
+ 	pid_t mypid;
+ 	uint8_t *pid;
++	uint8_t i;
+ 
+ 	if (sizeof(pid_t) < 4) {
+ 		printf("pid_t is smaller than 4 bytes?\n");
+@@ -2136,33 +2137,39 @@ static void make_local_ips(void)
+ 	mypid = getpid();
+ 	pid = (uint8_t *)&mypid;
+ 
++	for (i = 0; i < sizeof(pid_t); i++) {
++		if (pid[i] == 0) {
++			pid[i] = 128;
++		}
++	}
++
+ 	snprintf(testipv4_1,
+ 		 sizeof(testipv4_1) - 1,
+ 		 "127.%u.%u.%u",
+-		 pid[0],
+ 		 pid[1],
+-		 pid[2]);
++		 pid[2],
++		 pid[0]);
+ 
+ 	snprintf(testipv4_2,
+ 		 sizeof(testipv4_2) - 1,
+ 		 "127.%u.%d.%u",
+-		 pid[0],
+-		 pid[1]+1,
+-		 pid[2]);
++		 pid[1],
++		 pid[2]+1,
++		 pid[0]);
+ 
+ 	snprintf(testipv6_1,
+ 		 sizeof(testipv6_1) - 1,
+-		 "::%u:%u:%u:1",
+-		 pid[0],
++		 "fd%x:%x%x::1",
+ 		 pid[1],
+-		 pid[2]);
++		 pid[2],
++		 pid[0]);
+ 
+ 	snprintf(testipv6_2,
+ 		 sizeof(testipv6_2) - 1,
+-		 "::%u:%u:%d:1",
+-		 pid[0],
++		 "fd%x:%x%x:1::1",
+ 		 pid[1],
+-		 pid[2]+1);
++		 pid[2],
++		 pid[0]);
+ }
+ 
+ int main(void)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0064-libtap-port-to-freebsd-and-fix-a-bunch-of-small-bugs.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0064-libtap-port-to-freebsd-and-fix-a-bunch-of-small-bugs.patch
new file mode 100644
index 000000000..3913ce1c4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0064-libtap-port-to-freebsd-and-fix-a-bunch-of-small-bugs.patch
@@ -0,0 +1,860 @@ 
+From 29ff6e1b69acd31e9af54eea4c90fc4efb6f4a02 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 9 Nov 2017 08:29:26 +0100
+Subject: [PATCH] [libtap] port to freebsd and fix a bunch of small bugs
+
+- tap_open: do mutex lock only after malloc to avoid deadlock
+- fix test suite to increase randomness when testing named tap devices
+- remove hardcoded paths to /bin/true /bin/false and /bin/grep
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac    |   3 -
+ libtap/libtap.c | 383 ++++++++++++++++++++++++++++++++++++++++--------
+ 2 files changed, 324 insertions(+), 62 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index e906e4a3..c35e3f4c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -217,9 +217,6 @@ case "$host_os" in
+ 	*bsd*)
+ 		AC_DEFINE_UNQUOTED([KNET_BSD], [1], [Compiling for BSD platform])
+ 		AC_MSG_RESULT([BSD])
+-		if test "x$enable_libtap" = xyes; then
+-			AC_MSG_ERROR([libtap is not currently supported on BSD platforms])
+-		fi
+ 		;;
+ 	*)
+ 		AC_MSG_ERROR([Unsupported OS? hmmmm])
+diff --git a/libtap/libtap.c b/libtap/libtap.c
+index b8e5f536..0c46d4e3 100644
+--- a/libtap/libtap.c
++++ b/libtap/libtap.c
+@@ -18,9 +18,7 @@
+ #include <fcntl.h>
+ #include <unistd.h>
+ #include <sys/ioctl.h>
+-#include <linux/if_tun.h>
+ #include <net/ethernet.h>
+-#include <netinet/ether.h>
+ #include <arpa/inet.h>
+ #include <pthread.h>
+ #include <limits.h>
+@@ -29,6 +27,14 @@
+ #include <ifaddrs.h>
+ #include <stdint.h>
+ 
++#ifdef KNET_LINUX
++#include <linux/if_tun.h>
++#include <netinet/ether.h>
++#endif
++#ifdef KNET_BSD
++#include <net/if_dl.h>
++#endif
++
+ #include "libtap.h"
+ 
+ #define MAX_IP_CHAR	128
+@@ -79,7 +85,7 @@ static int _set_down(tap_t tap, char **error_down, char **error_postdown);
+ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix);
+ static int _set_ip(tap_t tap, const char *command,
+ 		      const char *ip_addr, const char *prefix,
+-		      char **error_string);
++		      char **error_string, int secondary);
+ static int _find_ip(tap_t tap,
+ 			const char *ip_addr, const char *prefix,
+ 			struct _ip **ip, struct _ip **ip_prev);
+@@ -242,12 +248,29 @@ static int _check(const tap_t tap)
+ 
+ static void _close(tap_t tap)
+ {
++#ifdef KNET_BSD
++	char command[PATH_MAX];
++	char *error_string = NULL;
++#endif
++
+ 	if (!tap)
+ 		return;
+ 
+ 	if (tap->fd)
+ 		close(tap->fd);
+ 
++#ifdef KNET_BSD
++	memset(command, 0, PATH_MAX);
++
++	snprintf(command, PATH_MAX, "ifconfig %s destroy", tap->tapname);
++
++	_execute_shell(command, &error_string);
++	if (error_string) {
++		free(error_string);
++		error_string = NULL;
++	}
++#endif
++
+ 	free(tap);
+ 
+ 	return;
+@@ -280,18 +303,56 @@ out_clean:
+ 
+ static int _get_mac(const tap_t tap, char **ether_addr)
+ {
+-	int err;
++	int err = 0;
+ 	char mac[MAX_MAC_CHAR];
++#ifdef KNET_BSD
++	struct ifaddrs *ifap = NULL;
++	struct ifaddrs *ifa;
++	int found = 0;
++#endif
+ 
++	memset(&mac, 0, MAX_MAC_CHAR);
+ 	memset(&tap->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
+ 
++#ifdef KNET_LINUX
+ 	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &tap->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+ 	ether_ntoa_r((struct ether_addr *)tap->ifr.ifr_hwaddr.sa_data, mac);
++#endif
++#ifdef KNET_BSD
++	/*
++	 * there is no ioctl to get the ether address of an interface on FreeBSD
++	 * (not to be confused with hwaddr). Use workaround described here:
++	 * https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
++	 */
++	err = getifaddrs(&ifap);
++	if (err < 0)
++		goto out_clean;
++
++	ifa = ifap;
+ 
++	while (ifa) {
++		if (!strncmp(tap->tapname, ifa->ifa_name, IFNAMSIZ)) {
++			found = 1;
++			break;
++		}
++		ifa=ifa->ifa_next;
++	}
++
++	if (found) {
++		ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
++	} else {
++		err = -1;
++	}
++	freeifaddrs(ifap);
++
++	if (err)
++		goto out_clean;
++
++#endif
+ 	*ether_addr = strdup(mac);
+ 	if (!*ether_addr)
+ 		err = -1;
+@@ -337,6 +398,11 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ {
+ 	tap_t tap;
+ 	char *temp_mac = NULL;
++#ifdef KNET_BSD
++	uint16_t i;
++	long int tapnum = 0;
++	char curtap[IFNAMSIZ];
++#endif
+ 
+ 	if (dev == NULL) {
+ 		errno = EINVAL;
+@@ -353,6 +419,30 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 		return NULL;
+ 	}
+ 
++#ifdef KNET_BSD
++	/*
++	 * BSD does not support named devices like Linux
++	 * but it is possible to force a tapX device number
++	 * where X is 0 to 255.
++	 */
++	if (strlen(dev)) {
++		if (strncmp(dev, "tap", 3)) {
++			errno = EINVAL;
++			return NULL;
++		}
++		errno = 0;
++		tapnum = strtol(dev+3, NULL, 10);
++		if (errno) {
++			errno = EINVAL;
++			return NULL;
++		}
++		if ((tapnum < 0) || (tapnum > 255)) {
++			errno = EINVAL;
++			return NULL;
++		}
++	}
++#endif
++
+ 	if (updownpath) {
+ 		/* only absolute paths */
+ 		if (updownpath[0] != '/') {
+@@ -366,18 +456,42 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 		}
+ 	}
+ 
+-	pthread_mutex_lock(&lib_mutex);
+-
+ 	tap = malloc(sizeof(struct _iface));
+-	if (!tap)
++	if (!tap) {
+ 		return NULL;
++	}
+ 
+ 	memset(tap, 0, sizeof(struct _iface));
+ 
++	pthread_mutex_lock(&lib_mutex);
++
++#ifdef KNET_BSD
++	if (!strlen(dev)) {
++		for (i = 0; i < 256; i++) {
++			snprintf(curtap, sizeof(curtap) - 1, "/dev/tap%u", i);
++			tap->fd = open(curtap, O_RDWR);
++			if (tap->fd > 0) {
++				break;
++			}
++		}
++		snprintf(curtap, sizeof(curtap) -1 , "tap%u", i);
++	} else {
++		snprintf(curtap, sizeof(curtap) - 1, "/dev/%s", dev);
++		tap->fd = open(curtap, O_RDWR);
++		snprintf(curtap, sizeof(curtap) - 1, "%s", dev);
++	}
++	if (tap->fd < 0) {
++		errno = EBUSY;
++		goto out_error;
++	}
++	strncpy(dev, curtap, IFNAMSIZ);
++	strncpy(tap->tapname, curtap, IFNAMSIZ);
++#endif
++
++#ifdef KNET_LINUX
+ 	if ((tap->fd = open("/dev/net/tun", O_RDWR)) < 0)
+ 		goto out_error;
+ 
+-	strncpy(tap->tapname, dev, IFNAMSIZ);
+ 	memset(&tap->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(tap->ifname, dev, IFNAMSIZ);
+ 	tap->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+@@ -390,12 +504,18 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 		goto out_error;
+ 	}
+ 
+-	strcpy(dev, tap->ifname);
+-	strcpy(tap->tapname, tap->ifname);
++	strncpy(dev, tap->ifname, IFNAMSIZ);
++	strncpy(tap->tapname, tap->ifname, IFNAMSIZ);
++#endif
+ 
+ 	if (!lib_init) {
+ 		lib_cfg.head = NULL;
++#ifdef KNET_LINUX
+ 		lib_cfg.sockfd = socket(AF_INET, SOCK_STREAM, 0);
++#endif
++#ifdef KNET_BSD
++		lib_cfg.sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
++#endif
+ 		if (lib_cfg.sockfd < 0)
+ 			goto out_error;
+ 		lib_init = 1;
+@@ -403,8 +523,14 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 
+ 	memset(&tap->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++#ifdef KNET_LINUX
+ 	if (ioctl(lib_cfg.sockfd, SIOGIFINDEX, &tap->ifr) < 0)
+ 		goto out_error;
++#endif
++#ifdef KNET_BSD
++	if (ioctl(lib_cfg.sockfd, SIOCGIFINDEX, &tap->ifr) < 0)
++		goto out_error;
++#endif
+ 
+ 	tap->default_mtu = _get_mtu(tap);
+ 	if (tap->default_mtu < 0)
+@@ -477,7 +603,7 @@ int tap_close(tap_t tap)
+ 	ip = tap->ip;
+ 	while (ip) {
+ 		ip_next = ip->next;
+-		_set_ip(tap, "del", ip->ip_addr, ip->prefix, &error_string);
++		_set_ip(tap, "del", ip->ip_addr, ip->prefix, &error_string, 0);
+ 		if (error_string) {
+ 			free(error_string);
+ 			error_string = NULL;
+@@ -541,7 +667,7 @@ int tap_set_mtu(tap_t tap, const int mtu)
+ 		tmp_ip = tap->ip;
+ 		while(tmp_ip) {
+ 			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(tap, "add", tmp_ip->ip_addr, tmp_ip->prefix, &error_string);
++				err = _set_ip(tap, "add", tmp_ip->ip_addr, tmp_ip->prefix, &error_string, 0);
+ 				if (error_string) {
+ 					free(error_string);
+ 					error_string = NULL;
+@@ -596,6 +722,7 @@ int tap_set_mac(tap_t tap, const char *ether_addr)
+ 
+ 	memset(&tap->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++#ifdef KNET_LINUX
+ 	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &tap->ifr);
+ 	if (err)
+ 		goto out_clean;
+@@ -603,7 +730,17 @@ int tap_set_mac(tap_t tap, const char *ether_addr)
+ 	memmove(tap->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+ 
+ 	err = ioctl(lib_cfg.sockfd, SIOCSIFHWADDR, &tap->ifr);
++#endif
++#ifdef KNET_BSD
++	err = ioctl(lib_cfg.sockfd, SIOCGIFADDR, &tap->ifr);
++	if (err)
++		goto out_clean;
++
++	memmove(tap->ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
++	tap->ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ 
++	err = ioctl(lib_cfg.sockfd, SIOCSIFLLADDR, &tap->ifr);
++#endif
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+ 
+@@ -741,10 +878,16 @@ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix)
+ 
+ static int _set_ip(tap_t tap, const char *command,
+ 		      const char *ip_addr, const char *prefix,
+-		      char **error_string)
++		      char **error_string, int secondary)
+ {
+ 	char *broadcast = NULL;
+ 	char cmdline[4096];
++#ifdef KNET_BSD
++	char proto[6];
++	int v4 = 1;
++
++	snprintf(proto, sizeof(proto), "inet");
++#endif
+ 
+ 	if (!strchr(ip_addr, ':')) {
+ 		broadcast = _get_v4_broadcast(ip_addr, prefix);
+@@ -753,22 +896,52 @@ static int _set_ip(tap_t tap, const char *command,
+ 			return -1;
+ 		}
+ 	}
++#ifdef KNET_BSD
++	  else {
++		v4 = 0;
++		snprintf(proto, sizeof(proto), "inet6");
++	}
++#endif
+ 
+ 	memset(cmdline, 0, sizeof(cmdline));
+ 
++#ifdef KNET_LINUX
+ 	if (broadcast) {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+-			"ip addr %s %s/%s dev %s broadcast %s",
++			 "ip addr %s %s/%s dev %s broadcast %s",
+ 			 command, ip_addr, prefix,
+ 			 tap->tapname, broadcast);
+-		free(broadcast);
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+-			"ip addr %s %s/%s dev %s",
++			 "ip addr %s %s/%s dev %s",
+ 			command, ip_addr, prefix,
+ 			tap->tapname);
+ 	}
+-
++#endif
++#ifdef KNET_BSD
++	if (!strcmp(command, "add")) {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ifconfig %s %s %s/%s",
++			 tap->tapname, proto, ip_addr, prefix);
++		if (broadcast) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " broadcast %s", broadcast);
++		}
++		if ((secondary) && (v4)) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " alias");
++		}
++	} else {
++		snprintf(cmdline, sizeof(cmdline)-1,
++				 "ifconfig %s %s %s/%s delete",
++				 tap->tapname, proto, ip_addr, prefix);
++	}
++#endif
++	if (broadcast) {
++		free(broadcast);
++	}
+ 	return _execute_shell(cmdline, error_string);
+ }
+ 
+@@ -802,6 +975,7 @@ int tap_add_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
++	int secondary = 0;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+@@ -836,7 +1010,10 @@ int tap_add_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_
+ 	if ((ip->domain == AF_INET6) && (_get_mtu(tap) < 1280)) {
+ 		err = 0;
+ 	} else {
+-		err = _set_ip(tap, "add", ip_addr, prefix, error_string);
++		if (tap->ip) {
++			secondary = 1;
++		}
++		err = _set_ip(tap, "add", ip_addr, prefix, error_string, secondary);
+ 	}
+ 
+ 	if (err) {
+@@ -877,7 +1054,7 @@ int tap_del_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_
+ 	if (!found)
+ 		goto out_clean;
+ 
+-	err = _set_ip(tap, "del", ip_addr, prefix, error_string);
++	err = _set_ip(tap, "del", ip_addr, prefix, error_string, 0);
+ 
+ 	if (!err) {
+ 		if (ip == ip_prev) {
+@@ -984,6 +1161,11 @@ char testipv4_1[1024];
+ char testipv4_2[1024];
+ char testipv6_1[1024];
+ char testipv6_2[1024];
++/*
++ * use this one to randomize knet interface name
++ * for named creation test
++ */
++uint8_t randombyte = 0;
+ 
+ static int is_if_in_system(char *name)
+ {
+@@ -1057,13 +1239,30 @@ static int check_tap_open_close(void)
+ 		return -1;
+ 	}
+ 
+-	printf("Creating kronostest tap interface:\n");
+-	strncpy(device_name, "kronostest", IFNAMSIZ);
++#ifdef KNET_LINUX
++	printf("Creating kronostest%u tap interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+ 	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create kronosnet interface\n");
++		printf("Unable to create kronostest%u interface\n", randombyte);
++		return -1;
++	}
++#endif
++#ifdef KNET_BSD
++	printf("Creating tap%u tap interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
++	if (test_iface(device_name, size, NULL) < 0) {
++		printf("Unable to create tap%u interface\n", randombyte);
+ 		return -1;
+ 	}
+ 
++	printf("Creating kronostest%u tap interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
++	if (test_iface(device_name, size, NULL) == 0) {
++		printf("BSD should not accept kronostest%u interface\n", randombyte);
++		return -1;
++	}
++#endif
++
+ 	printf("Testing ERROR conditions\n");
+ 
+ 	printf("Testing dev == NULL\n");
+@@ -1090,7 +1289,8 @@ static int check_tap_open_close(void)
+ 
+ 	printf("Testing updown path != abs\n");
+ 	errno=0;
+-	strcpy(device_name, "kronostest");
++
++	memset(device_name, 0, IFNAMSIZ);
+ 	if ((test_iface(device_name, IFNAMSIZ, "foo")  >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in tap_open sanity checks\n");
+ 		return -1;
+@@ -1101,7 +1301,8 @@ static int check_tap_open_close(void)
+ 
+ 	printf("Testing updown path > PATH_MAX\n");
+ 	errno=0;
+-	strcpy(device_name, "kronostest");
++
++	memset(device_name, 0, IFNAMSIZ);
+ 	if ((test_iface(device_name, IFNAMSIZ, fakepath)  >= 0) || (errno != E2BIG)) {
+ 		printf("Something is wrong in tap_open sanity checks\n");
+ 		return -1;
+@@ -1124,9 +1325,6 @@ static int check_knet_multi_eth(void)
+ 	memset(device_name1, 0, size);
+ 	memset(device_name2, 0, size);
+ 
+-	strncpy(device_name1, "kronostest1", size);
+-	strncpy(device_name2, "kronostest2", size);
+-
+ 	tap1 = tap_open(device_name1, size, NULL);
+ 	if (!tap1) {
+ 		printf("Unable to init %s\n", device_name1);
+@@ -1162,6 +1360,8 @@ static int check_knet_multi_eth(void)
+ 
+ 	printf("Open same device twice\n");
+ 
++	memset(device_name1, 0, size);
++
+ 	tap1 = tap_open(device_name1, size, NULL);
+ 	if (!tap1) {
+ 		printf("Unable to init %s\n", device_name1);
+@@ -1203,7 +1403,6 @@ static int check_knet_mtu(void)
+ 	printf("Testing get/set MTU\n");
+ 
+ 	memset(device_name, 0, size);
+-	strncpy(device_name, "kronostest", size);
+ 	tap = tap_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1277,7 +1476,7 @@ static int check_knet_mtu_ipv6(void)
+ 	printf("Testing get/set MTU with IPv6 address\n");
+ 
+ 	memset(device_name, 0, size);
+-	strncpy(device_name, "kronostest", size);
++
+ 	tap = tap_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1292,15 +1491,21 @@ static int check_knet_mtu_ipv6(void)
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
+-	if (err < 0) {
++	if (err) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
++		sleep(30);
+ 		goto out_clean;
+ 	}
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+-		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -1326,7 +1531,12 @@ static int check_knet_mtu_ipv6(void)
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
++#ifdef KNET_LINUX
+ 	if (!err) {
++#endif
++#ifdef KNET_BSD
++	if (err) {
++#endif
+ 		printf("Unable to verify IP address\n");
+ 		err=-1;
+ 		goto out_clean;
+@@ -1347,7 +1557,12 @@ static int check_knet_mtu_ipv6(void)
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+-		 "ip addr show dev kronostest | grep -q %s/64", testipv6_2);
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_2);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -1368,8 +1583,13 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd) -1,
+-		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -1383,8 +1603,13 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd) -1,
+-		 "ip addr show dev kronostest | grep -q %s/64", testipv6_2);
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_2);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -1415,7 +1640,6 @@ static int check_knet_mac(void)
+ 	printf("Testing get/set MAC\n");
+ 
+ 	memset(device_name, 0, size);
+-	strncpy(device_name, "kronostest", size);
+ 	tap = tap_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1455,6 +1679,7 @@ static int check_knet_mac(void)
+ 	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
+ 		printf("Mac addresses are not the same?!\n");
+ 		err = -1;
++		sleep(20);
+ 		goto out_clean;
+ 	}
+ 
+@@ -1519,58 +1744,58 @@ static int check_tap_execute_shell(void)
+ 
+ 	printf("Testing _execute_shell\n");
+ 
+-	printf("command /bin/true\n");
++	printf("command true\n");
+ 
+-	err = _execute_shell("/bin/true", &error_string);
++	err = _execute_shell("true", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
+-	if (err < 0) {
+-		printf("Unable to execute /bin/true ?!?!\n");
++	if (err) {
++		printf("Unable to execute true ?!?!\n");
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Testing ERROR conditions\n");
+ 
+-	printf("command /bin/false\n");
++	printf("command false\n");
+ 
+-	err = _execute_shell("/bin/false", &error_string);
++	err = _execute_shell("false", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
+ 	if (!err) {
+-		printf("Can we really execute /bin/false successfully?!?!\n");
++		printf("Can we really execute false successfully?!?!\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("command that outputs to stdout (enforcing redirect)\n");
+ 
+-	err = _execute_shell("/bin/grep -h 2>&1", &error_string);
++	err = _execute_shell("grep -h 2>&1", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
+ 	if (!err) {
+-		printf("Can we really execute /bin/grep -h successfully?!?\n");
++		printf("Can we really execute grep -h successfully?!?\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	} 
+ 
+ 	printf("command that outputs to stderr\n");
+-	err = _execute_shell("/bin/grep -h", &error_string);
++	err = _execute_shell("grep -h", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
+ 	if (!err) {
+-		printf("Can we really execute /bin/grep -h successfully?!?\n");
++		printf("Can we really execute grep -h successfully?!?\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	} 
+@@ -1589,7 +1814,7 @@ static int check_tap_execute_shell(void)
+ 	}
+ 
+ 	printf("empty error\n");
+-	err = _execute_shell("/bin/true", NULL);
++	err = _execute_shell("true", NULL);
+ 	if (!err) {
+ 		printf("Check EINVAL filter for no error_string!\n");
+ 		err = -1;
+@@ -1605,6 +1830,7 @@ out_clean:
+ 
+ static int check_knet_up_down(void)
+ {
++	char verifycmd[1024];
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+@@ -1616,7 +1842,6 @@ static int check_knet_up_down(void)
+ 	printf("Testing interface up/down\n");
+ 
+ 	memset(device_name, 0, size);
+-	strncpy(device_name, "kronostest", size);
+ 	tap = tap_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1642,8 +1867,15 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-
+-	err = _execute_shell("ip addr show dev kronostest | grep -q UP", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", tap->tapname);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", tap->tapname);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1674,7 +1906,15 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell("ifconfig kronostest | grep -q UP", &error_string);
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", tap->tapname);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", tap->tapname);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1690,6 +1930,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+ 
++	memset(device_name, 0, size);
+ 	tap = tap_open(device_name, size, ABSBUILDDIR "/tap_updown_bad");
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1738,6 +1979,8 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Testing interface pre-up/up/down/post-down\n");
+ 
++	memset(device_name, 0, size);
++
+ 	tap = tap_open(device_name, size, ABSBUILDDIR "/tap_updown_good");
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1852,7 +2095,7 @@ static int check_knet_close_leak(void)
+ 	printf("Testing close leak (needs valgrind)\n");
+ 
+ 	memset(device_name, 0, size);
+-	strncpy(device_name, "kronostest", size);
++
+ 	tap = tap_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1908,7 +2151,7 @@ static int check_knet_set_del_ip(void)
+ 	printf("Testing interface add/remove ip\n");
+ 
+ 	memset(device_name, 0, size);
+-	strncpy(device_name, "kronostest", size);
++
+ 	tap = tap_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+@@ -1961,7 +2204,12 @@ static int check_knet_set_del_ip(void)
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+-		 "ip addr show dev kronostest | grep -q %s/24", testipv4_1);
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", tap->tapname, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv4_1);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -2040,7 +2288,12 @@ static int check_knet_set_del_ip(void)
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+-		 "ip addr show dev kronostest | grep -q %s/24", testipv4_1);
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", tap->tapname, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv4_1);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -2069,7 +2322,12 @@ static int check_knet_set_del_ip(void)
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+-		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -2098,7 +2356,12 @@ static int check_knet_set_del_ip(void)
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+-		 "ip addr show dev kronostest | grep -q %s/64", testipv6_1);
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++#endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+@@ -2143,6 +2406,8 @@ static void make_local_ips(void)
+ 		}
+ 	}
+ 
++	randombyte = pid[1];
++
+ 	snprintf(testipv4_1,
+ 		 sizeof(testipv4_1) - 1,
+ 		 "127.%u.%u.%u",
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0065-libtap-update-README-for-BSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0065-libtap-update-README-for-BSD.patch
new file mode 100644
index 000000000..ed86f05cb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0065-libtap-update-README-for-BSD.patch
@@ -0,0 +1,19 @@ 
+From 80a43c0d26b9d66a6992e7c70f2291d2a71f0faf Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 9 Nov 2017 14:24:56 +0100
+Subject: [PATCH] [libtap] update README for BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ README | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/README b/README
+index bf602992..95aaf483 100644
+--- a/README
++++ b/README
+@@ -33,3 +33,4 @@ knet requires big socket buffers and you need to set:
+ kern.ipc.maxsockbuf=18388608
+ in /etc/sysctl.conf or knet will fail to run.
+ 
++libtap requires if_tap.ko loaded in the kernel.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0066-libtap-define-IFNAMSIZ-for-applications-that-don-t-n.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0066-libtap-define-IFNAMSIZ-for-applications-that-don-t-n.patch
new file mode 100644
index 000000000..d00b150b9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0066-libtap-define-IFNAMSIZ-for-applications-that-don-t-n.patch
@@ -0,0 +1,26 @@ 
+From 71ac9316d5b48c639acef16fd16ad13b0a69e3fb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 10 Nov 2017 16:55:23 +0100
+Subject: [PATCH] [libtap] define IFNAMSIZ for applications that don't
+ need/want to include net/if.h
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libtap/libtap.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libtap/libtap.h b/libtap/libtap.h
+index 124c3292..abc78f26 100644
+--- a/libtap/libtap.h
++++ b/libtap/libtap.h
+@@ -11,6 +11,10 @@
+ 
+ #include <sys/types.h>
+ 
++#ifndef IFNAMSIZ
++#define IFNAMSIZ 16
++#endif
++
+ typedef struct _iface *tap_t;
+ 
+ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0067-libtap-BSD-switch-to-ioctl-to-destroy-tap-devices.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0067-libtap-BSD-switch-to-ioctl-to-destroy-tap-devices.patch
new file mode 100644
index 000000000..c6817cf45
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0067-libtap-BSD-switch-to-ioctl-to-destroy-tap-devices.patch
@@ -0,0 +1,97 @@ 
+From a4f82aefbe5804d456edecc35e3a659dc7aa0b13 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 06:18:57 +0100
+Subject: [PATCH] [libtap] BSD: switch to ioctl to destroy tap devices
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libtap/libtap.c | 54 ++++++++++++++++---------------------------------
+ 1 file changed, 17 insertions(+), 37 deletions(-)
+
+diff --git a/libtap/libtap.c b/libtap/libtap.c
+index 0c46d4e3..ce0a6117 100644
+--- a/libtap/libtap.c
++++ b/libtap/libtap.c
+@@ -248,11 +248,6 @@ static int _check(const tap_t tap)
+ 
+ static void _close(tap_t tap)
+ {
+-#ifdef KNET_BSD
+-	char command[PATH_MAX];
+-	char *error_string = NULL;
+-#endif
+-
+ 	if (!tap)
+ 		return;
+ 
+@@ -260,15 +255,10 @@ static void _close(tap_t tap)
+ 		close(tap->fd);
+ 
+ #ifdef KNET_BSD
+-	memset(command, 0, PATH_MAX);
+-
+-	snprintf(command, PATH_MAX, "ifconfig %s destroy", tap->tapname);
++	memset(&tap->ifr, 0, sizeof(struct ifreq));
++	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
+ 
+-	_execute_shell(command, &error_string);
+-	if (error_string) {
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	ioctl(lib_cfg.sockfd, SIOCIFDESTROY, &tap->ifr);
+ #endif
+ 
+ 	free(tap);
+@@ -465,6 +455,20 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
++	if (!lib_init) {
++		lib_cfg.head = NULL;
++#ifdef KNET_LINUX
++		lib_cfg.sockfd = socket(AF_INET, SOCK_STREAM, 0);
++#endif
++#ifdef KNET_BSD
++		lib_cfg.sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
++#endif
++		if (lib_cfg.sockfd < 0)
++			goto out_error;
++		lib_init = 1;
++	}
++
++
+ #ifdef KNET_BSD
+ 	if (!strlen(dev)) {
+ 		for (i = 0; i < 256; i++) {
+@@ -508,30 +512,6 @@ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 	strncpy(tap->tapname, tap->ifname, IFNAMSIZ);
+ #endif
+ 
+-	if (!lib_init) {
+-		lib_cfg.head = NULL;
+-#ifdef KNET_LINUX
+-		lib_cfg.sockfd = socket(AF_INET, SOCK_STREAM, 0);
+-#endif
+-#ifdef KNET_BSD
+-		lib_cfg.sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+-#endif
+-		if (lib_cfg.sockfd < 0)
+-			goto out_error;
+-		lib_init = 1;
+-	}
+-
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
+-#ifdef KNET_LINUX
+-	if (ioctl(lib_cfg.sockfd, SIOGIFINDEX, &tap->ifr) < 0)
+-		goto out_error;
+-#endif
+-#ifdef KNET_BSD
+-	if (ioctl(lib_cfg.sockfd, SIOCGIFINDEX, &tap->ifr) < 0)
+-		goto out_error;
+-#endif
+-
+ 	tap->default_mtu = _get_mtu(tap);
+ 	if (tap->default_mtu < 0)
+ 		goto out_error;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0068-libnozzle-rename-libtap-to-libnozzle-part-1.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0068-libnozzle-rename-libtap-to-libnozzle-part-1.patch
new file mode 100644
index 000000000..137045712
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0068-libnozzle-rename-libtap-to-libnozzle-part-1.patch
@@ -0,0 +1,498 @@ 
+From bb3059da8acfc060843c424a178bb80102e9666d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 06:41:25 +0100
+Subject: [PATCH] [libnozzle] rename libtap to libnozzle (part 1)
+
+Our fearless Debian maintainer wferi made us aware that TAP is an overloaded
+term already and it would be very confusing to add yet another one.
+
+nozzle is a good pick from http://www.thesaurus.com/browse/tap
+
+I am sure lib*cock* would have cause havoc :-)
+
+This commit only rename files and allow builds. The API needs to be renamed too,
+but that will come over time with major code cleanup as documented here:
+https://trello.com/c/pyEKd4UH/396-libnozzle-make-it-production-ga-ready
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ Makefile.am                                   |  8 ++--
+ NOTES_TO_PACKAGE_MAINTAINERS                  |  2 +-
+ README                                        |  2 +-
+ configure.ac                                  | 14 +++----
+ kronosnet.spec.in                             | 40 +++++++++----------
+ kronosnetd/Makefile.am                        |  4 +-
+ kronosnetd/cfg.c                              |  2 +-
+ kronosnetd/cfg.h                              |  2 +-
+ kronosnetd/vty_cli_cmds.c                     |  2 +-
+ {libtap => libnozzle}/Makefile.am             | 28 ++++++-------
+ {libtap => libnozzle}/api-test-coverage       |  8 ++--
+ libtap/libtap.c => libnozzle/libnozzle.c      |  2 +-
+ libtap/libtap.h => libnozzle/libnozzle.h      |  4 +-
+ .../libtap.pc.in => libnozzle/libnozzle.pc.in |  2 +-
+ .../libnozzle_exported_syms                   |  4 +-
+ .../tap_updown_bad/down.d/kronostest          |  0
+ .../tap_updown_bad/post-down.d/kronostest     |  0
+ .../tap_updown_bad/pre-up.d/kronostest        |  0
+ .../tap_updown_bad/up.d/kronostest            |  0
+ .../tap_updown_good/down.d/kronostest         |  0
+ .../tap_updown_good/post-down.d/kronostest    |  0
+ .../tap_updown_good/pre-up.d/kronostest       |  0
+ .../tap_updown_good/up.d/kronostest           |  0
+ 23 files changed, 62 insertions(+), 62 deletions(-)
+ rename {libtap => libnozzle}/Makefile.am (58%)
+ rename {libtap => libnozzle}/api-test-coverage (69%)
+ rename libtap/libtap.c => libnozzle/libnozzle.c (99%)
+ rename libtap/libtap.h => libnozzle/libnozzle.h (95%)
+ rename libtap/libtap.pc.in => libnozzle/libnozzle.pc.in (96%)
+ rename libtap/libtap_exported_syms => libnozzle/libnozzle_exported_syms (78%)
+ rename {libtap => libnozzle}/tap_updown_bad/down.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_bad/post-down.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_bad/pre-up.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_bad/up.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_good/down.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_good/post-down.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_good/pre-up.d/kronostest (100%)
+ rename {libtap => libnozzle}/tap_updown_good/up.d/kronostest (100%)
+
+diff --git a/Makefile.am b/Makefile.am
+index 25398bbb..047127d5 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -27,7 +27,7 @@ EXTRA_DIST		= autogen.sh .version \
+ 			  NOTES_TO_PACKAGE_MAINTAINERS \
+ 			  $(SPEC).in build-aux
+ 
+-SUBDIRS			= init libtap libknet kronosnetd
++SUBDIRS			= init libnozzle libknet kronosnetd
+ 
+ if BUILD_MAN
+ SUBDIRS			+= man
+@@ -143,10 +143,10 @@ if BUILD_KRONOSNETD
+ else
+ 	sed -i -e "s#@kronosnetd@#bcond_with#g" $@-t
+ endif
+-if BUILD_LIBTAP
+-	sed -i -e "s#@libtap@#bcond_without#g" $@-t
++if BUILD_LIBNOZZLE
++	sed -i -e "s#@libnozzle@#bcond_without#g" $@-t
+ else
+-	sed -i -e "s#@libtap@#bcond_with#g" $@-t
++	sed -i -e "s#@libnozzle@#bcond_with#g" $@-t
+ endif
+ if BUILD_RUNAUTOGEN
+ 	sed -i -e "s#@runautogen@#bcond_without#g" $@-t
+diff --git a/NOTES_TO_PACKAGE_MAINTAINERS b/NOTES_TO_PACKAGE_MAINTAINERS
+index 829e7331..eae9a9da 100644
+--- a/NOTES_TO_PACKAGE_MAINTAINERS
++++ b/NOTES_TO_PACKAGE_MAINTAINERS
+@@ -8,7 +8,7 @@ DO NOT ship kronosnetd. It's an experimental piece of super
+ crappy code. IF you decide to ship it anyway, you get to
+ be also the upstream maintainer :-) you have been warned.
+ 
+-libtap is a simple commodity library used only by kronosnetd.
++libnozzle is a simple commodity library used only by kronosnetd.
+ I don't mind to support it, but don't ship just for the fun of it.
+ It has no users, that I know of, outside of kronosnetd.
+ 
+diff --git a/README b/README
+index 95aaf483..a50f27fd 100644
+--- a/README
++++ b/README
+@@ -33,4 +33,4 @@ knet requires big socket buffers and you need to set:
+ kern.ipc.maxsockbuf=18388608
+ in /etc/sysctl.conf or knet will fail to run.
+ 
+-libtap requires if_tap.ko loaded in the kernel.
++libnozzle requires if_tap.ko loaded in the kernel.
+diff --git a/configure.ac b/configure.ac
+index c35e3f4c..ed6eb3ef 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -166,14 +166,14 @@ AC_ARG_ENABLE([rpm-debuginfo],
+ AM_CONDITIONAL([BUILD_RPM_DEBUGINFO], [test x$enable_rpm_debuginfo = xyes])
+ AM_CONDITIONAL([OVERRIDE_RPM_DEBUGINFO], [test x$override_rpm_debuginfo_option = xyes])
+ 
+-AC_ARG_ENABLE([libtap],
+-	[AS_HELP_STRING([--enable-libtap],[libtap support])],,
+-	[ enable_libtap="no" ])
++AC_ARG_ENABLE([libnozzle],
++	[AS_HELP_STRING([--enable-libnozzle],[libnozzle support])],,
++	[ enable_libnozzle="no" ])
+ 
+ if test "x$enable_kronosnetd" = xyes; then
+-	enable_libtap=yes
++	enable_libnozzle=yes
+ fi
+-AM_CONDITIONAL([BUILD_LIBTAP], [test x$enable_libtap = xyes])
++AM_CONDITIONAL([BUILD_LIBNOZZLE], [test x$enable_libnozzle = xyes])
+ 
+ ## local helper functions
+ # this function checks if CC support options passed as
+@@ -498,8 +498,8 @@ AC_MSG_NOTICE([using source epoch $($UTC_DATE_AT$SOURCE_EPOCH +'%F %T %Z')])
+ AC_CONFIG_FILES([
+ 		Makefile
+ 		init/Makefile
+-		libtap/Makefile
+-		libtap/libtap.pc
++		libnozzle/Makefile
++		libnozzle/libnozzle.pc
+ 		kronosnetd/Makefile
+ 		kronosnetd/kronosnetd.logrotate
+ 		libknet/Makefile
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index a9cb445e..d07103b4 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -25,7 +25,7 @@
+ %@lzma@ lzma
+ %@bzip2@ bzip2
+ %@kronosnetd@ kronosnetd
+-%@libtap@ libtap
++%@libnozzle@ libnozzle
+ %@runautogen@ runautogen
+ %@rpmdebuginfo@ rpmdebuginfo
+ %@overriderpmdebuginfo@ overriderpmdebuginfo
+@@ -59,11 +59,11 @@
+ %if %{with bzip2}
+ %global buildcompressbzip2 1
+ %endif
+-%if %{with libtap}
+-%global buildlibtap 1
++%if %{with libnozzle}
++%global buildlibnozzle 1
+ %endif
+ %if %{with kronosnetd}
+-%global buildlibtap 1
++%global buildlibnozzle 1
+ %global buildkronosnetd 1
+ %endif
+ %if %{with runautogen}
+@@ -185,8 +185,8 @@ BuildRequires: libtool
+ %if %{defined buildkronosnetd}
+ 	--enable-kronosnetd \
+ %endif
+-%if %{defined buildlibtap}
+-	--enable-libtap \
++%if %{defined buildlibnozzle}
++	--enable-libnozzle \
+ %endif
+ 	--with-initdefaultdir=%{_sysconfdir}/sysconfig/ \
+ %if %{defined _unitdir}
+@@ -301,42 +301,42 @@ fi
+ %{_mandir}/man8/*
+ %endif
+ 
+-%if %{defined buildlibtap}
+-%package -n libtap1
++%if %{defined buildlibnozzle}
++%package -n libnozzle1
+ Group: System Environment/Libraries
+ Summary: Simple userland wrapper around kernel tap devices
+ 
+-%description -n libtap1
++%description -n libnozzle1
+  This is an over-engineered commodity library to manage a pool
+  of tap devices and provides the basic
+  pre-up.d/up.d/down.d/post-down.d infrastructure.
+ 
+-%files -n libtap1
++%files -n libnozzle1
+ %defattr(-,root,root,-)
+ %doc COPYING.* COPYRIGHT
+-%{_libdir}/libtap.so.*
++%{_libdir}/libnozzle.so.*
+ 
+-%post -n libtap1 -p /sbin/ldconfig
++%post -n libnozzle1 -p /sbin/ldconfig
+ 
+-%postun -n libtap1 -p /sbin/ldconfig
++%postun -n libnozzle1 -p /sbin/ldconfig
+ 
+-%package -n libtap1-devel
++%package -n libnozzle1-devel
+ Group: Development/Libraries
+ Summary: Simple userland wrapper around kernel tap devices (developer files)
+-Requires: libtap1 = %{version}-%{release}
++Requires: libnozzle1 = %{version}-%{release}
+ Requires: pkgconfig
+ 
+-%description -n libtap1-devel
++%description -n libnozzle1-devel
+  This is an over-engineered commodity library to manage a pool
+  of tap devices and provides the basic
+  pre-up.d/up.d/down.d/post-down.d infrastructure.
+ 
+-%files -n libtap1-devel
++%files -n libnozzle1-devel
+ %defattr(-,root,root,-)
+ %doc COPYING.* COPYRIGHT
+-%{_libdir}/libtap.so
+-%{_includedir}/libtap.h
+-%{_libdir}/pkgconfig/libtap.pc
++%{_libdir}/libnozzle.so
++%{_includedir}/libnozzle.h
++%{_libdir}/pkgconfig/libnozzle.pc
+ %endif
+ 
+ %package -n libknet1
+diff --git a/kronosnetd/Makefile.am b/kronosnetd/Makefile.am
+index 8c233579..9dfb2445 100644
+--- a/kronosnetd/Makefile.am
++++ b/kronosnetd/Makefile.am
+@@ -34,14 +34,14 @@ kronosnetd_SOURCES	= \
+ 			  vty_utils.c
+ 
+ kronosnetd_CPPFLAGS	= \
+-			  -I$(top_srcdir)/libtap \
++			  -I$(top_srcdir)/libnozzle \
+ 			  -I$(top_srcdir)/libknet
+ 
+ kronosnetd_CFLAGS	= $(AM_CFLAGS) $(libqb_CFLAGS)
+ 
+ kronosnetd_LDADD	= \
+ 			  $(top_builddir)/libknet/libknet.la \
+-			  $(top_builddir)/libtap/libtap.la \
++			  $(top_builddir)/libnozzle/libnozzle.la \
+ 			  $(libqb_LIBS) \
+ 			  $(pam_misc_LIBS) $(pam_LIBS)
+ 
+diff --git a/kronosnetd/cfg.c b/kronosnetd/cfg.c
+index 60fdc15d..d2663926 100644
+--- a/kronosnetd/cfg.c
++++ b/kronosnetd/cfg.c
+@@ -14,7 +14,7 @@
+ #include <string.h>
+ 
+ #include "cfg.h"
+-#include "libtap.h"
++#include "libnozzle.h"
+ 
+ struct knet_cfg *knet_get_iface(const char *name, int create)
+ {
+diff --git a/kronosnetd/cfg.h b/kronosnetd/cfg.h
+index 49f66af7..b884ffb4 100644
+--- a/kronosnetd/cfg.h
++++ b/kronosnetd/cfg.h
+@@ -13,7 +13,7 @@
+ #include <stdint.h>
+ #include <net/if.h>
+ 
+-#include "libtap.h"
++#include "libnozzle.h"
+ #include "libknet.h"
+ 
+ #define KNET_RING_DEFPORT 50000
+diff --git a/kronosnetd/vty_cli_cmds.c b/kronosnetd/vty_cli_cmds.c
+index 5ed875e8..bf795e6e 100644
+--- a/kronosnetd/vty_cli_cmds.c
++++ b/kronosnetd/vty_cli_cmds.c
+@@ -20,7 +20,7 @@
+ #include "cfg.h"
+ #include "etherfilter.h"
+ #include "logging.h"
+-#include "libtap.h"
++#include "libnozzle.h"
+ #include "netutils.h"
+ #include "vty.h"
+ #include "vty_cli.h"
+diff --git a/libtap/Makefile.am b/libnozzle/Makefile.am
+similarity index 58%
+rename from libtap/Makefile.am
+rename to libnozzle/Makefile.am
+index 0690daea..06d2b4a1 100644
+--- a/libtap/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -11,32 +11,32 @@ MAINTAINERCLEANFILES	= Makefile.in
+ include $(top_srcdir)/build-aux/check.mk
+ 
+ 
+-SYMFILE			= libtap_exported_syms
++SYMFILE			= libnozzle_exported_syms
+ 
+ EXTRA_DIST		= $(SYMFILE) tap_updown_bad tap_updown_good api-test-coverage
+ 
+-sources			= libtap.c
++sources			= libnozzle.c
+ 
+ libversion		= 1:0:0
+ 
+ AM_CFLAGS		+= $(PTHREAD_CFLAGS)
+ LIBS			= $(PTHREAD_LIBS)
+ 
+-if BUILD_LIBTAP
++if BUILD_LIBNOZZLE
+ 
+-include_HEADERS		= libtap.h
++include_HEADERS		= libnozzle.h
+ 
+ pkgconfigdir		= $(libdir)/pkgconfig
+ 
+-pkgconfig_DATA		= libtap.pc
++pkgconfig_DATA		= libnozzle.pc
+ 
+-lib_LTLIBRARIES		= libtap.la
++lib_LTLIBRARIES		= libnozzle.la
+ 
+-libtap_la_SOURCES	= $(sources)
++libnozzle_la_SOURCES	= $(sources)
+ 
+-EXTRA_libtap_la_DEPENDENCIES	= $(SYMFILE)
++EXTRA_libnozzle_la_DEPENDENCIES	= $(SYMFILE)
+ 
+-libtap_la_LDFLAGS	= $(AM_LDFLAGS) \
++libnozzle_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 			  -Wl,-version-script,$(srcdir)/$(SYMFILE) \
+ 			  -version-info $(libversion)
+ 
+@@ -44,17 +44,17 @@ TESTS			= $(check_PROGRAMS)
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+ 
+-check_PROGRAMS		= tap_test
++check_PROGRAMS		= nozzle_test
+ 
+ check-local: check-api-test-coverage
+ 
+ check-api-test-coverage:
+-	chmod u+x $(top_srcdir)/libtap/api-test-coverage
+-	$(top_srcdir)/libtap/api-test-coverage $(top_srcdir) $(top_builddir)
++	chmod u+x $(top_srcdir)/libnozzle/api-test-coverage
++	$(top_srcdir)/libnozzle/api-test-coverage $(top_srcdir) $(top_builddir)
+ 
+-tap_test_SOURCES	= $(sources)
++nozzle_test_SOURCES	= $(sources)
+ 
+-tap_test_CPPFLAGS	= -DTEST \
++nozzle_test_CPPFLAGS	= -DTEST \
+ 			  -DABSBUILDDIR=\"$(abs_builddir)\"
+ 
+ endif
+diff --git a/libtap/api-test-coverage b/libnozzle/api-test-coverage
+similarity index 69%
+rename from libtap/api-test-coverage
+rename to libnozzle/api-test-coverage
+index e25cb2b0..8d26a59b 100755
+--- a/libtap/api-test-coverage
++++ b/libnozzle/api-test-coverage
+@@ -7,12 +7,12 @@
+ # This software licensed under GPL-2.0+, LGPL-2.0+
+ #
+ 
+-srcdir="$1"/libtap
+-builddir="$2"/libtap
++srcdir="$1"/libnozzle
++builddir="$2"/libnozzle
+ 
+-headerapicalls="$(grep tap_ "$srcdir"/libtap.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
++headerapicalls="$(grep tap_ "$srcdir"/libnozzle.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
+ 
+-exportedapicalls="$(nm -B -D "$builddir"/.libs/libtap.so | grep ' T ' | awk '{print $3}')"
++exportedapicalls="$(nm -B -D "$builddir"/.libs/libnozzle.so | grep ' T ' | awk '{print $3}')"
+ 
+ echo "Checking for exported symbols NOT available in header file"
+ 
+diff --git a/libtap/libtap.c b/libnozzle/libnozzle.c
+similarity index 99%
+rename from libtap/libtap.c
+rename to libnozzle/libnozzle.c
+index ce0a6117..26616a14 100644
+--- a/libtap/libtap.c
++++ b/libnozzle/libnozzle.c
+@@ -35,7 +35,7 @@
+ #include <net/if_dl.h>
+ #endif
+ 
+-#include "libtap.h"
++#include "libnozzle.h"
+ 
+ #define MAX_IP_CHAR	128
+ #define MAX_PREFIX_CHAR	4
+diff --git a/libtap/libtap.h b/libnozzle/libnozzle.h
+similarity index 95%
+rename from libtap/libtap.h
+rename to libnozzle/libnozzle.h
+index abc78f26..6b03c863 100644
+--- a/libtap/libtap.h
++++ b/libnozzle/libnozzle.h
+@@ -6,8 +6,8 @@
+  * This software licensed under GPL-2.0+, LGPL-2.0+
+  */
+ 
+-#ifndef __LIBTAP_H__
+-#define __LIBTAP_H__
++#ifndef __LIBNOZZLE_H__
++#define __LIBNOZZLE_H__
+ 
+ #include <sys/types.h>
+ 
+diff --git a/libtap/libtap.pc.in b/libnozzle/libnozzle.pc.in
+similarity index 96%
+rename from libtap/libtap.pc.in
+rename to libnozzle/libnozzle.pc.in
+index 97340fc5..c53a7a43 100644
+--- a/libtap/libtap.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -11,7 +11,7 @@ exec_prefix=${prefix}
+ libdir=@libdir@
+ includedir=${prefix}/include
+ 
+-Name: libtap
++Name: libnozzle
+ Version: @VERSION@
+ Description: library to manage a pool of tap devices
+ Requires:
+diff --git a/libtap/libtap_exported_syms b/libnozzle/libnozzle_exported_syms
+similarity index 78%
+rename from libtap/libtap_exported_syms
+rename to libnozzle/libnozzle_exported_syms
+index cfb3502b..55ca485c 100644
+--- a/libtap/libtap_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -1,4 +1,4 @@
+-# Version and symbol export for libtap.so
++# Version and symbol export for libnozzle.so
+ #
+ # Copyright (C) 2011-2018 Red Hat, Inc.  All rights reserved.
+ #
+@@ -7,7 +7,7 @@
+ # This software licensed under GPL-2.0+, LGPL-2.0+
+ #
+ 
+-LIBTAP {
++LIBNOZZLE {
+ 	global:
+ 		tap_*;
+ 	local:
+diff --git a/libtap/tap_updown_bad/down.d/kronostest b/libnozzle/tap_updown_bad/down.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_bad/down.d/kronostest
+rename to libnozzle/tap_updown_bad/down.d/kronostest
+diff --git a/libtap/tap_updown_bad/post-down.d/kronostest b/libnozzle/tap_updown_bad/post-down.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_bad/post-down.d/kronostest
+rename to libnozzle/tap_updown_bad/post-down.d/kronostest
+diff --git a/libtap/tap_updown_bad/pre-up.d/kronostest b/libnozzle/tap_updown_bad/pre-up.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_bad/pre-up.d/kronostest
+rename to libnozzle/tap_updown_bad/pre-up.d/kronostest
+diff --git a/libtap/tap_updown_bad/up.d/kronostest b/libnozzle/tap_updown_bad/up.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_bad/up.d/kronostest
+rename to libnozzle/tap_updown_bad/up.d/kronostest
+diff --git a/libtap/tap_updown_good/down.d/kronostest b/libnozzle/tap_updown_good/down.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_good/down.d/kronostest
+rename to libnozzle/tap_updown_good/down.d/kronostest
+diff --git a/libtap/tap_updown_good/post-down.d/kronostest b/libnozzle/tap_updown_good/post-down.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_good/post-down.d/kronostest
+rename to libnozzle/tap_updown_good/post-down.d/kronostest
+diff --git a/libtap/tap_updown_good/pre-up.d/kronostest b/libnozzle/tap_updown_good/pre-up.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_good/pre-up.d/kronostest
+rename to libnozzle/tap_updown_good/pre-up.d/kronostest
+diff --git a/libtap/tap_updown_good/up.d/kronostest b/libnozzle/tap_updown_good/up.d/kronostest
+similarity index 100%
+rename from libtap/tap_updown_good/up.d/kronostest
+rename to libnozzle/tap_updown_good/up.d/kronostest
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0069-nozzle-add-Doxygen-header.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0069-nozzle-add-Doxygen-header.patch
new file mode 100644
index 000000000..c0382b6aa
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0069-nozzle-add-Doxygen-header.patch
@@ -0,0 +1,30 @@ 
+From 0a975d2cb95ec8dcb50475a04d104310114e05d1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 13:43:53 +0100
+Subject: [PATCH] [nozzle] add Doxygen header
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.h | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 6b03c863..d3ae8b54 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -15,6 +15,15 @@
+ #define IFNAMSIZ 16
+ #endif
+ 
++/**
++ *
++ * @file libnozzle.h
++ * @brief tap interfaces management API include file
++ * @copyright Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ *
++ * nozzle is a commodity library to manage tap (ethernet) interfaces
++ */
++
+ typedef struct _iface *tap_t;
+ 
+ tap_t tap_open(char *dev, size_t dev_size, const char *updownpath);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0070-nozzle-include-net-if.h-to-define-IFNAMSIZ-instead-o.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0070-nozzle-include-net-if.h-to-define-IFNAMSIZ-instead-o.patch
new file mode 100644
index 000000000..8759fcf11
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0070-nozzle-include-net-if.h-to-define-IFNAMSIZ-instead-o.patch
@@ -0,0 +1,27 @@ 
+From 51da54e432837cc20ef95827a977b35bfe68e54f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 13:44:19 +0100
+Subject: [PATCH] [nozzle] include net/if.h to define IFNAMSIZ instead of
+ redefine
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.h | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index d3ae8b54..e97254d8 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -10,10 +10,7 @@
+ #define __LIBNOZZLE_H__
+ 
+ #include <sys/types.h>
+-
+-#ifndef IFNAMSIZ
+-#define IFNAMSIZ 16
+-#endif
++#include <net/if.h>
+ 
+ /**
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0071-nozzle-rename-tap_t-to-nozzle_t.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0071-nozzle-rename-tap_t-to-nozzle_t.patch
new file mode 100644
index 000000000..8eb460a66
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0071-nozzle-rename-tap_t-to-nozzle_t.patch
@@ -0,0 +1,394 @@ 
+From ca00548fb124e1e9a0480921002a48c053de34c2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 13:46:19 +0100
+Subject: [PATCH] [nozzle] rename tap_t to nozzle_t
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 92 +++++++++++++++++++++----------------------
+ libnozzle/libnozzle.h | 34 ++++++++--------
+ 2 files changed, 63 insertions(+), 63 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 26616a14..6c21072f 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -74,19 +74,19 @@ static pthread_mutex_t lib_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+ /* forward declarations */
+ static int _execute_shell(const char *command, char **error_string);
+-static int _exec_updown(const tap_t tap, const char *action, char **error_string);
++static int _exec_updown(const nozzle_t tap, const char *action, char **error_string);
+ static int _read_pipe(int fd, char **file, size_t *length);
+-static int _check(const tap_t tap);
+-static void _close(tap_t tap);
++static int _check(const nozzle_t tap);
++static void _close(nozzle_t tap);
+ static void _close_cfg(void);
+-static int _get_mtu(const tap_t tap);
+-static int _get_mac(const tap_t tap, char **ether_addr);
+-static int _set_down(tap_t tap, char **error_down, char **error_postdown);
++static int _get_mtu(const nozzle_t tap);
++static int _get_mac(const nozzle_t tap, char **ether_addr);
++static int _set_down(nozzle_t tap, char **error_down, char **error_postdown);
+ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix);
+-static int _set_ip(tap_t tap, const char *command,
++static int _set_ip(nozzle_t tap, const char *command,
+ 		      const char *ip_addr, const char *prefix,
+ 		      char **error_string, int secondary);
+-static int _find_ip(tap_t tap,
++static int _find_ip(nozzle_t tap,
+ 			const char *ip_addr, const char *prefix,
+ 			struct _ip **ip, struct _ip **ip_prev);
+ 
+@@ -202,7 +202,7 @@ out_clean0:
+ 	return err;
+ }
+ 
+-static int _exec_updown(const tap_t tap, const char *action, char **error_string)
++static int _exec_updown(const nozzle_t tap, const char *action, char **error_string)
+ {
+ 	char command[PATH_MAX];
+ 	struct stat sb;
+@@ -228,9 +228,9 @@ static int _exec_updown(const tap_t tap, const char *action, char **error_string
+ 	return err;
+ }
+ 
+-static int _check(const tap_t tap)
++static int _check(const nozzle_t tap)
+ {
+-	tap_t temp = lib_cfg.head;
++	nozzle_t temp = lib_cfg.head;
+ 
+ 	if (!tap) {
+ 		return 0;
+@@ -246,7 +246,7 @@ static int _check(const tap_t tap)
+ 	return 0;
+ }
+ 
+-static void _close(tap_t tap)
++static void _close(nozzle_t tap)
+ {
+ 	if (!tap)
+ 		return;
+@@ -274,7 +274,7 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _get_mtu(const tap_t tap)
++static int _get_mtu(const nozzle_t tap)
+ {
+ 	int err;
+ 
+@@ -291,7 +291,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int _get_mac(const tap_t tap, char **ether_addr)
++static int _get_mac(const nozzle_t tap, char **ether_addr)
+ {
+ 	int err = 0;
+ 	char mac[MAX_MAC_CHAR];
+@@ -352,9 +352,9 @@ out_clean:
+ 	return err;
+ }
+ 
+-tap_t tap_find(char *dev, size_t dev_size)
++nozzle_t tap_find(char *dev, size_t dev_size)
+ {
+-	tap_t tap;
++	nozzle_t tap;
+ 
+ 	if (dev == NULL) {
+ 		errno = EINVAL;
+@@ -384,9 +384,9 @@ tap_t tap_find(char *dev, size_t dev_size)
+ 	return tap;
+ }
+ 
+-tap_t tap_open(char *dev, size_t dev_size, const char *updownpath)
++nozzle_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ {
+-	tap_t tap;
++	nozzle_t tap;
+ 	char *temp_mac = NULL;
+ #ifdef KNET_BSD
+ 	uint16_t i;
+@@ -546,11 +546,11 @@ out_error:
+ }
+ 
+ // TODO: consider better error report from here
+-int tap_close(tap_t tap)
++int tap_close(nozzle_t tap)
+ {
+ 	int err = 0;
+-	tap_t temp = lib_cfg.head;
+-	tap_t prev = lib_cfg.head;
++	nozzle_t temp = lib_cfg.head;
++	nozzle_t prev = lib_cfg.head;
+ 	struct _ip *ip, *ip_next;
+ 	char *error_string = NULL;
+ 	char *error_down = NULL, *error_postdown = NULL;
+@@ -601,7 +601,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_get_mtu(const tap_t tap)
++int tap_get_mtu(const nozzle_t tap)
+ {
+ 	int err;
+ 
+@@ -621,7 +621,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_set_mtu(tap_t tap, const int mtu)
++int tap_set_mtu(nozzle_t tap, const int mtu)
+ {
+ 	struct _ip *tmp_ip;
+ 	char *error_string = NULL;
+@@ -663,12 +663,12 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_reset_mtu(tap_t tap)
++int tap_reset_mtu(nozzle_t tap)
+ {
+ 	return tap_set_mtu(tap, tap->default_mtu);
+ }
+ 
+-int tap_get_mac(const tap_t tap, char **ether_addr)
++int tap_get_mac(const nozzle_t tap, char **ether_addr)
+ {
+ 	int err;
+ 
+@@ -688,7 +688,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_set_mac(tap_t tap, const char *ether_addr)
++int tap_set_mac(nozzle_t tap, const char *ether_addr)
+ {
+ 	int err;
+ 
+@@ -727,12 +727,12 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_reset_mac(tap_t tap)
++int tap_reset_mac(nozzle_t tap)
+ {
+ 	return tap_set_mac(tap, tap->default_mac);
+ }
+ 
+-int tap_set_up(tap_t tap, char **error_preup, char **error_up)
++int tap_set_up(nozzle_t tap, char **error_preup, char **error_up)
+ {
+ 	int err = 0;
+ 
+@@ -777,7 +777,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int _set_down(tap_t tap, char **error_down, char **error_postdown)
++static int _set_down(nozzle_t tap, char **error_down, char **error_postdown)
+ {
+ 	int err = 0;
+ 
+@@ -807,7 +807,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_set_down(tap_t tap, char **error_down, char **error_postdown)
++int tap_set_down(nozzle_t tap, char **error_down, char **error_postdown)
+ {
+ 	int err = 0;
+ 
+@@ -856,7 +856,7 @@ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix)
+ 	return strdup(inet_ntoa(broadcast));
+ }
+ 
+-static int _set_ip(tap_t tap, const char *command,
++static int _set_ip(nozzle_t tap, const char *command,
+ 		      const char *ip_addr, const char *prefix,
+ 		      char **error_string, int secondary)
+ {
+@@ -925,7 +925,7 @@ static int _set_ip(tap_t tap, const char *command,
+ 	return _execute_shell(cmdline, error_string);
+ }
+ 
+-static int _find_ip(tap_t tap,
++static int _find_ip(nozzle_t tap,
+ 			const char *ip_addr, const char *prefix,
+ 			struct _ip **ip, struct _ip **ip_prev)
+ {
+@@ -951,7 +951,7 @@ static int _find_ip(tap_t tap,
+ 	return found;
+ }
+ 
+-int tap_add_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_string)
++int tap_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+@@ -1017,7 +1017,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_del_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_string)
++int tap_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL;
+@@ -1051,7 +1051,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_get_fd(const tap_t tap)
++int tap_get_fd(const nozzle_t tap)
+ {
+ 	int fd;
+ 
+@@ -1071,7 +1071,7 @@ out_clean:
+ 	return fd;
+ }
+ 
+-const char *tap_get_name(const tap_t tap)
++const char *tap_get_name(const nozzle_t tap)
+ {
+ 	char *name = NULL;
+ 
+@@ -1090,7 +1090,7 @@ out_clean:
+ 	return name;
+ }
+ 
+-int tap_get_ips(const tap_t tap, char **ip_addr_list, int *entries)
++int tap_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries)
+ {
+ 	int err = 0;
+ 	int found = 0;
+@@ -1174,7 +1174,7 @@ static int is_if_in_system(char *name)
+ 
+ static int test_iface(char *name, size_t size, const char *updownpath)
+ {
+-	tap_t tap;
++	nozzle_t tap;
+ 
+ 	tap=tap_open(name, size, updownpath);
+ 	if (!tap) {
+@@ -1297,8 +1297,8 @@ static int check_knet_multi_eth(void)
+ 	char device_name2[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	tap_t tap1 = NULL;
+-	tap_t tap2 = NULL;
++	nozzle_t tap1 = NULL;
++	nozzle_t tap2 = NULL;
+ 
+ 	printf("Testing multiple knet interface instances\n");
+ 
+@@ -1375,7 +1375,7 @@ static int check_knet_mtu(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	tap_t tap;
++	nozzle_t tap;
+ 
+ 	int current_mtu = 0;
+ 	int expected_mtu = 1500;
+@@ -1450,7 +1450,7 @@ static int check_knet_mtu_ipv6(void)
+ 	size_t size = IFNAMSIZ;
+ 	char verifycmd[1024];
+ 	int err=0;
+-	tap_t tap;
++	nozzle_t tap;
+ 	char *error_string = NULL;
+ 
+ 	printf("Testing get/set MTU with IPv6 address\n");
+@@ -1613,7 +1613,7 @@ static int check_knet_mac(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	tap_t tap;
++	nozzle_t tap;
+ 	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
+ 	struct ether_addr *cur_mac, *tmp_mac;
+ 
+@@ -1814,7 +1814,7 @@ static int check_knet_up_down(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	tap_t tap;
++	nozzle_t tap;
+ 	char *error_string = NULL;
+ 	char *error_preup = NULL, *error_up = NULL;
+ 	char *error_down = NULL, *error_postdown = NULL;
+@@ -2069,7 +2069,7 @@ static int check_knet_close_leak(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	tap_t tap;
++	nozzle_t tap;
+ 	char *error_string = NULL;
+ 
+ 	printf("Testing close leak (needs valgrind)\n");
+@@ -2123,7 +2123,7 @@ static int check_knet_set_del_ip(void)
+ 	size_t size = IFNAMSIZ;
+ 	char verifycmd[1024];
+ 	int err=0;
+-	tap_t tap;
++	nozzle_t tap;
+ 	char *ip_list = NULL;
+ 	int ip_list_entries = 0, i, offset = 0;
+ 	char *error_string = NULL;
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index e97254d8..3066ec6b 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -21,30 +21,30 @@
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+ 
+-typedef struct _iface *tap_t;
++typedef struct _iface *nozzle_t;
+ 
+-tap_t tap_open(char *dev, size_t dev_size, const char *updownpath);
+-int tap_close(tap_t tap);
++nozzle_t tap_open(char *dev, size_t dev_size, const char *updownpath);
++int tap_close(nozzle_t tap);
+ 
+-tap_t tap_find(char *dev, size_t dev_size);
++nozzle_t tap_find(char *dev, size_t dev_size);
+ 
+-int tap_get_fd(const tap_t tap);
++int tap_get_fd(const nozzle_t tap);
+ 
+-const char *tap_get_name(const tap_t tap);
++const char *tap_get_name(const nozzle_t tap);
+ 
+-int tap_get_mtu(const tap_t tap);
+-int tap_set_mtu(tap_t tap, const int mtu);
+-int tap_reset_mtu(tap_t tap);
++int tap_get_mtu(const nozzle_t tap);
++int tap_set_mtu(nozzle_t tap, const int mtu);
++int tap_reset_mtu(nozzle_t tap);
+ 
+-int tap_get_mac(const tap_t tap, char **ether_addr);
+-int tap_set_mac(tap_t tap, const char *ether_addr);
+-int tap_reset_mac(tap_t tap);
++int tap_get_mac(const nozzle_t tap, char **ether_addr);
++int tap_set_mac(nozzle_t tap, const char *ether_addr);
++int tap_reset_mac(nozzle_t tap);
+ 
+-int tap_set_up(tap_t tap, char **error_preup, char **error_up);
+-int tap_set_down(tap_t tap, char **error_down, char **error_postdown);
++int tap_set_up(nozzle_t tap, char **error_preup, char **error_up);
++int tap_set_down(nozzle_t tap, char **error_down, char **error_postdown);
+ 
+-int tap_add_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_string);
+-int tap_del_ip(tap_t tap, const char *ip_addr, const char *prefix, char **error_string);
+-int tap_get_ips(const tap_t tap, char **ip_addr_list, int *entries);
++int tap_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
++int tap_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
++int tap_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0072-nozzle-rename-struct-_iface-to-nozzle_iface-looks-be.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0072-nozzle-rename-struct-_iface-to-nozzle_iface-looks-be.patch
new file mode 100644
index 000000000..598780c26
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0072-nozzle-rename-struct-_iface-to-nozzle_iface-looks-be.patch
@@ -0,0 +1,68 @@ 
+From 1a254bd9560d5e39eebc9871e1a3ab55ed7b6ce4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 13:48:38 +0100
+Subject: [PATCH] [nozzle] rename struct _iface to nozzle_iface (looks better
+ on public headers)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 10 +++++-----
+ libnozzle/libnozzle.h |  2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 6c21072f..634f5ad6 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -48,7 +48,7 @@ struct _ip {
+ 	struct _ip *next;
+ };
+ 
+-struct _iface {
++struct nozzle_iface {
+ 	struct ifreq ifr;
+ 	int fd;
+ 	char tapname[IFNAMSIZ];
+@@ -59,12 +59,12 @@ struct _iface {
+ 	int hasupdown;
+ 	int up;
+ 	struct _ip *ip;
+-	struct _iface *next;
++	struct nozzle_iface *next;
+ };
+ #define ifname ifr.ifr_name
+ 
+ struct _config {
+-	struct _iface *head;
++	struct nozzle_iface *head;
+ 	int sockfd;
+ };
+ 
+@@ -446,12 +446,12 @@ nozzle_t tap_open(char *dev, size_t dev_size, const char *updownpath)
+ 		}
+ 	}
+ 
+-	tap = malloc(sizeof(struct _iface));
++	tap = malloc(sizeof(struct nozzle_iface));
+ 	if (!tap) {
+ 		return NULL;
+ 	}
+ 
+-	memset(tap, 0, sizeof(struct _iface));
++	memset(tap, 0, sizeof(struct nozzle_iface));
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 3066ec6b..20b3bb80 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -21,7 +21,7 @@
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+ 
+-typedef struct _iface *nozzle_t;
++typedef struct nozzle_iface *nozzle_t;
+ 
+ nozzle_t tap_open(char *dev, size_t dev_size, const char *updownpath);
+ int tap_close(nozzle_t tap);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0073-nozzle-fix-pkg-config-to-point-to-nozzle.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0073-nozzle-fix-pkg-config-to-point-to-nozzle.patch
new file mode 100644
index 000000000..be603ba22
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0073-nozzle-fix-pkg-config-to-point-to-nozzle.patch
@@ -0,0 +1,21 @@ 
+From 91606855f5243cdaff35a19b71f0a935724e49a4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 13:51:43 +0100
+Subject: [PATCH] [nozzle] fix pkg-config to point to nozzle
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.pc.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.pc.in b/libnozzle/libnozzle.pc.in
+index c53a7a43..901e3af5 100644
+--- a/libnozzle/libnozzle.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -15,5 +15,5 @@ Name: libnozzle
+ Version: @VERSION@
+ Description: library to manage a pool of tap devices
+ Requires:
+-Libs: -L${libdir} -ltap
++Libs: -L${libdir} -lnozzle
+ Cflags: -I${includedir}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0074-nozzle-rename-API-from-tap_-to-nozzle_.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0074-nozzle-rename-API-from-tap_-to-nozzle_.patch
new file mode 100644
index 000000000..6974a6807
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0074-nozzle-rename-API-from-tap_-to-nozzle_.patch
@@ -0,0 +1,897 @@ 
+From b3fd7aecb6a6f5c089da05d65a19dc7554ffb5fa Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 13:52:08 +0100
+Subject: [PATCH] [nozzle] rename API from tap_ to nozzle_
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/api-test-coverage       |   2 +-
+ libnozzle/libnozzle.c             | 212 +++++++++++++++---------------
+ libnozzle/libnozzle.h             |  32 ++---
+ libnozzle/libnozzle_exported_syms |   2 +-
+ 4 files changed, 124 insertions(+), 124 deletions(-)
+
+diff --git a/libnozzle/api-test-coverage b/libnozzle/api-test-coverage
+index 8d26a59b..c68f862b 100755
+--- a/libnozzle/api-test-coverage
++++ b/libnozzle/api-test-coverage
+@@ -10,7 +10,7 @@
+ srcdir="$1"/libnozzle
+ builddir="$2"/libnozzle
+ 
+-headerapicalls="$(grep tap_ "$srcdir"/libnozzle.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
++headerapicalls="$(grep nozzle_ "$srcdir"/libnozzle.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
+ 
+ exportedapicalls="$(nm -B -D "$builddir"/.libs/libnozzle.so | grep ' T ' | awk '{print $3}')"
+ 
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 634f5ad6..73df6bec 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -352,7 +352,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-nozzle_t tap_find(char *dev, size_t dev_size)
++nozzle_t nozzle_find(char *dev, size_t dev_size)
+ {
+ 	nozzle_t tap;
+ 
+@@ -384,7 +384,7 @@ nozzle_t tap_find(char *dev, size_t dev_size)
+ 	return tap;
+ }
+ 
+-nozzle_t tap_open(char *dev, size_t dev_size, const char *updownpath)
++nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ {
+ 	nozzle_t tap;
+ 	char *temp_mac = NULL;
+@@ -546,7 +546,7 @@ out_error:
+ }
+ 
+ // TODO: consider better error report from here
+-int tap_close(nozzle_t tap)
++int nozzle_close(nozzle_t tap)
+ {
+ 	int err = 0;
+ 	nozzle_t temp = lib_cfg.head;
+@@ -601,7 +601,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_get_mtu(const nozzle_t tap)
++int nozzle_get_mtu(const nozzle_t tap)
+ {
+ 	int err;
+ 
+@@ -621,7 +621,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_set_mtu(nozzle_t tap, const int mtu)
++int nozzle_set_mtu(nozzle_t tap, const int mtu)
+ {
+ 	struct _ip *tmp_ip;
+ 	char *error_string = NULL;
+@@ -663,12 +663,12 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_reset_mtu(nozzle_t tap)
++int nozzle_reset_mtu(nozzle_t tap)
+ {
+-	return tap_set_mtu(tap, tap->default_mtu);
++	return nozzle_set_mtu(tap, tap->default_mtu);
+ }
+ 
+-int tap_get_mac(const nozzle_t tap, char **ether_addr)
++int nozzle_get_mac(const nozzle_t tap, char **ether_addr)
+ {
+ 	int err;
+ 
+@@ -688,7 +688,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_set_mac(nozzle_t tap, const char *ether_addr)
++int nozzle_set_mac(nozzle_t tap, const char *ether_addr)
+ {
+ 	int err;
+ 
+@@ -727,12 +727,12 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_reset_mac(nozzle_t tap)
++int nozzle_reset_mac(nozzle_t tap)
+ {
+-	return tap_set_mac(tap, tap->default_mac);
++	return nozzle_set_mac(tap, tap->default_mac);
+ }
+ 
+-int tap_set_up(nozzle_t tap, char **error_preup, char **error_up)
++int nozzle_set_up(nozzle_t tap, char **error_preup, char **error_up)
+ {
+ 	int err = 0;
+ 
+@@ -807,7 +807,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_set_down(nozzle_t tap, char **error_down, char **error_postdown)
++int nozzle_set_down(nozzle_t tap, char **error_down, char **error_postdown)
+ {
+ 	int err = 0;
+ 
+@@ -951,7 +951,7 @@ static int _find_ip(nozzle_t tap,
+ 	return found;
+ }
+ 
+-int tap_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
++int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+@@ -1017,7 +1017,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
++int nozzle_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL;
+@@ -1051,7 +1051,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int tap_get_fd(const nozzle_t tap)
++int nozzle_get_fd(const nozzle_t tap)
+ {
+ 	int fd;
+ 
+@@ -1071,7 +1071,7 @@ out_clean:
+ 	return fd;
+ }
+ 
+-const char *tap_get_name(const nozzle_t tap)
++const char *nozzle_get_name(const nozzle_t tap)
+ {
+ 	char *name = NULL;
+ 
+@@ -1090,7 +1090,7 @@ out_clean:
+ 	return name;
+ }
+ 
+-int tap_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries)
++int nozzle_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries)
+ {
+ 	int err = 0;
+ 	int found = 0;
+@@ -1176,7 +1176,7 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ {
+ 	nozzle_t tap;
+ 
+-	tap=tap_open(name, size, updownpath);
++	tap=nozzle_open(name, size, updownpath);
+ 	if (!tap) {
+ 		if (lib_cfg.sockfd < 0)
+ 			printf("Unable to open knet_socket\n");
+@@ -1191,13 +1191,13 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 		printf("Unable to find interface %s on the system\n", name);
+ 	}
+ 
+-	if (!tap_find(name, size)) {
++	if (!nozzle_find(name, size)) {
+ 		printf("Unable to find interface %s in tap db\n", name);
+ 	} else {
+ 		printf("Found interface %s in tap db\n", name);
+ 	}
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	if (is_if_in_system(name) == 0)
+ 		printf("Successfully removed interface %s from the system\n", name);
+@@ -1205,7 +1205,7 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 	return 0;
+ }
+ 
+-static int check_tap_open_close(void)
++static int check_nozzle_open_close(void)
+ {
+ 	char device_name[2*IFNAMSIZ];
+ 	char fakepath[PATH_MAX];
+@@ -1248,14 +1248,14 @@ static int check_tap_open_close(void)
+ 	printf("Testing dev == NULL\n");
+ 	errno=0;
+ 	if ((test_iface(NULL, size, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_open sanity checks\n");
++		printf("Something is wrong in nozzle_open sanity checks\n");
+ 		return -1;
+ 	}
+ 
+ 	printf("Testing size < IFNAMSIZ\n");
+ 	errno=0;
+ 	if ((test_iface(device_name, 1, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_open sanity checks\n");
++		printf("Something is wrong in nozzle_open sanity checks\n");
+ 		return -1;
+ 	}
+ 
+@@ -1263,7 +1263,7 @@ static int check_tap_open_close(void)
+ 	errno=0;
+ 	strcpy(device_name, "abcdefghilmnopqrstuvwz");
+ 	if ((test_iface(device_name, IFNAMSIZ, NULL) >= 0) || (errno != E2BIG)) {
+-		printf("Something is wrong in tap_open sanity checks\n");
++		printf("Something is wrong in nozzle_open sanity checks\n");
+ 		return -1;
+ 	}
+ 
+@@ -1272,7 +1272,7 @@ static int check_tap_open_close(void)
+ 
+ 	memset(device_name, 0, IFNAMSIZ);
+ 	if ((test_iface(device_name, IFNAMSIZ, "foo")  >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_open sanity checks\n");
++		printf("Something is wrong in nozzle_open sanity checks\n");
+ 		return -1;
+ 	}
+ 
+@@ -1284,7 +1284,7 @@ static int check_tap_open_close(void)
+ 
+ 	memset(device_name, 0, IFNAMSIZ);
+ 	if ((test_iface(device_name, IFNAMSIZ, fakepath)  >= 0) || (errno != E2BIG)) {
+-		printf("Something is wrong in tap_open sanity checks\n");
++		printf("Something is wrong in nozzle_open sanity checks\n");
+ 		return -1;
+ 	}
+ 
+@@ -1305,7 +1305,7 @@ static int check_knet_multi_eth(void)
+ 	memset(device_name1, 0, size);
+ 	memset(device_name2, 0, size);
+ 
+-	tap1 = tap_open(device_name1, size, NULL);
++	tap1 = nozzle_open(device_name1, size, NULL);
+ 	if (!tap1) {
+ 		printf("Unable to init %s\n", device_name1);
+ 		err = -1;
+@@ -1318,7 +1318,7 @@ static int check_knet_multi_eth(void)
+ 		printf("Unable to find interface %s on the system\n", device_name1);
+ 	}
+ 
+-	tap2 = tap_open(device_name2, size, NULL);
++	tap2 = nozzle_open(device_name2, size, NULL);
+ 	if (!tap2) {
+ 		printf("Unable to init %s\n", device_name2);
+ 		err = -1;
+@@ -1332,9 +1332,9 @@ static int check_knet_multi_eth(void)
+ 	}
+ 
+ 	if (tap1)
+-		tap_close(tap1);
++		nozzle_close(tap1);
+ 	if (tap2)
+-		tap_close(tap2);
++		nozzle_close(tap2);
+ 
+ 	printf("Testing error conditions\n");
+ 
+@@ -1342,7 +1342,7 @@ static int check_knet_multi_eth(void)
+ 
+ 	memset(device_name1, 0, size);
+ 
+-	tap1 = tap_open(device_name1, size, NULL);
++	tap1 = nozzle_open(device_name1, size, NULL);
+ 	if (!tap1) {
+ 		printf("Unable to init %s\n", device_name1);
+ 		err = -1;
+@@ -1355,7 +1355,7 @@ static int check_knet_multi_eth(void)
+ 		printf("Unable to find interface %s on the system\n", device_name1);
+ 	}
+ 
+-	tap2 = tap_open(device_name1, size, NULL);
++	tap2 = nozzle_open(device_name1, size, NULL);
+ 	if (tap2) {
+ 		printf("We were able to init 2 interfaces with the same name!\n");
+ 		err = -1;
+@@ -1364,9 +1364,9 @@ static int check_knet_multi_eth(void)
+ 
+ out_clean:
+ 	if (tap1)
+-		tap_close(tap1);
++		nozzle_close(tap1);
+ 	if (tap2)
+-		tap_close(tap2);
++		nozzle_close(tap2);
+ 	return err;
+ }
+ 
+@@ -1383,14 +1383,14 @@ static int check_knet_mtu(void)
+ 	printf("Testing get/set MTU\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = tap_open(device_name, size, NULL);
++	tap = nozzle_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Comparing default MTU\n");
+-	current_mtu = tap_get_mtu(tap);
++	current_mtu = nozzle_get_mtu(tap);
+ 	if (current_mtu < 0) {
+ 		printf("Unable to get MTU\n");
+ 		err = -1;
+@@ -1404,13 +1404,13 @@ static int check_knet_mtu(void)
+ 
+ 	printf("Setting MTU to 9000\n");
+ 	expected_mtu = 9000;
+-	if (tap_set_mtu(tap, expected_mtu) < 0) {
++	if (nozzle_set_mtu(tap, expected_mtu) < 0) {
+ 		printf("Unable to set MTU to %d\n", expected_mtu);
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	current_mtu = tap_get_mtu(tap);
++	current_mtu = nozzle_get_mtu(tap);
+ 	if (current_mtu < 0) {
+ 		printf("Unable to get MTU\n");
+ 		err = -1;
+@@ -1425,21 +1425,21 @@ static int check_knet_mtu(void)
+ 	printf("Testing ERROR conditions\n");
+ 
+ 	printf("Passing empty struct to get_mtu\n");
+-	if (tap_get_mtu(NULL) > 0) {
+-		printf("Something is wrong in tap_get_mtu sanity checks\n");
++	if (nozzle_get_mtu(NULL) > 0) {
++		printf("Something is wrong in nozzle_get_mtu sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Passing empty struct to set_mtu\n");
+-	if (tap_set_mtu(NULL, 1500) == 0) {
+-		printf("Something is wrong in tap_set_mtu sanity checks\n"); 
++	if (nozzle_set_mtu(NULL, 1500) == 0) {
++		printf("Something is wrong in nozzle_set_mtu sanity checks\n"); 
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ out_clean:
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	return err;
+ }
+@@ -1457,7 +1457,7 @@ static int check_knet_mtu_ipv6(void)
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = tap_open(device_name, size, NULL);
++	tap = nozzle_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -1465,7 +1465,7 @@ static int check_knet_mtu_ipv6(void)
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = tap_add_ip(tap, testipv6_1, "64", &error_string);
++	err = nozzle_add_ip(tap, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -1499,7 +1499,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Setting MTU to 1200\n");
+-	if (tap_set_mtu(tap, 1200) < 0) {
++	if (nozzle_set_mtu(tap, 1200) < 0) {
+ 		printf("Unable to set MTU to 1200\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1523,7 +1523,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_2);
+-	err = tap_add_ip(tap, testipv6_2, "64", &error_string);
++	err = nozzle_add_ip(tap, testipv6_2, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -1556,7 +1556,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Restoring MTU to default\n");
+-	if (tap_reset_mtu(tap) < 0) {
++	if (nozzle_reset_mtu(tap) < 0) {
+ 		printf("Unable to reset mtu\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1603,7 +1603,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ out_clean:
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	return err;
+ }
+@@ -1620,7 +1620,7 @@ static int check_knet_mac(void)
+ 	printf("Testing get/set MAC\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = tap_open(device_name, size, NULL);
++	tap = nozzle_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -1628,7 +1628,7 @@ static int check_knet_mac(void)
+ 
+ 	printf("Get current MAC\n");
+ 
+-	if (tap_get_mac(tap, &current_mac) < 0) {
++	if (nozzle_get_mac(tap, &current_mac) < 0) {
+ 		printf("Unable to get current MAC address.\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1638,13 +1638,13 @@ static int check_knet_mac(void)
+ 
+ 	printf("Setting MAC: 00:01:01:01:01:01\n");
+ 
+-	if (tap_set_mac(tap, "00:01:01:01:01:01") < 0) {
++	if (nozzle_set_mac(tap, "00:01:01:01:01:01") < 0) {
+ 		printf("Unable to set current MAC address.\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	if (tap_get_mac(tap, &temp_mac) < 0) {
++	if (nozzle_get_mac(tap, &temp_mac) < 0) {
+ 		printf("Unable to get current MAC address.\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1667,32 +1667,32 @@ static int check_knet_mac(void)
+ 
+ 	printf("Pass NULL to get_mac (pass1)\n");
+ 	errno = 0;
+-	if ((tap_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_get_mac sanity checks\n");
++	if ((nozzle_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to get_mac (pass2)\n");
+ 	errno = 0;
+-	if ((tap_get_mac(tap, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_get_mac sanity checks\n");
++	if ((nozzle_get_mac(tap, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to set_mac (pass1)\n");
+ 	errno = 0;
+-	if ((tap_set_mac(tap, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_mac sanity checks\n");
++	if ((nozzle_set_mac(tap, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to set_mac (pass2)\n");
+ 	errno = 0;
+-	if ((tap_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_mac sanity checks\n");
++	if ((nozzle_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -1709,12 +1709,12 @@ out_clean:
+ 	if (temp_mac)
+ 		free(temp_mac);
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	return err;
+ }
+ 
+-static int check_tap_execute_shell(void)
++static int check_nozzle_execute_shell(void)
+ {
+ 	int err = 0;
+ 	char command[4096];
+@@ -1822,7 +1822,7 @@ static int check_knet_up_down(void)
+ 	printf("Testing interface up/down\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = tap_open(device_name, size, NULL);
++	tap = nozzle_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -1830,7 +1830,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = tap_set_up(tap, &error_preup, &error_up);
++	err = nozzle_set_up(tap, &error_preup, &error_up);
+ 	if (error_preup) {
+ 		printf("preup output: %s\n", error_preup);
+ 		free(error_preup);
+@@ -1869,7 +1869,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = tap_set_down(tap, &error_down, &error_postdown);
++	err = nozzle_set_down(tap, &error_down, &error_postdown);
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+@@ -1906,12 +1906,12 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = tap_open(device_name, size, ABSBUILDDIR "/tap_updown_bad");
++	tap = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -1919,7 +1919,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = tap_set_up(tap, &error_preup, &error_up);
++	err = nozzle_set_up(tap, &error_preup, &error_up);
+ 	if (error_preup) {
+ 		printf("preup output: %s\n", error_preup);
+ 		free(error_preup);
+@@ -1938,7 +1938,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = tap_set_down(tap, &error_down, &error_postdown);
++	err = nozzle_set_down(tap, &error_down, &error_postdown);
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+@@ -1955,13 +1955,13 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	printf("Testing interface pre-up/up/down/post-down\n");
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = tap_open(device_name, size, ABSBUILDDIR "/tap_updown_good");
++	tap = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -1969,7 +1969,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = tap_set_up(tap, &error_preup, &error_up);
++	err = nozzle_set_up(tap, &error_preup, &error_up);
+ 	if (error_preup) {
+ 		printf("preup output: %s\n", error_preup);
+ 		free(error_preup);
+@@ -1988,7 +1988,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = tap_set_down(tap, &error_down, &error_postdown);
++	err = nozzle_set_down(tap, &error_down, &error_postdown);
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+@@ -2005,61 +2005,61 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	printf("Test ERROR conditions\n");
+ 
+ 	printf("Pass NULL to tap set_up\n");
+ 	errno = 0;
+-	if ((tap_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_up sanity checks\n");
++	if ((nozzle_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to error_preup set_up\n");
+ 	errno = 0;
+-	if ((tap_set_up(tap, NULL, &error_up) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_up sanity checks\n");
++	if ((nozzle_set_up(tap, NULL, &error_up) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to error_up set_up\n");
+ 	errno = 0;
+-	if ((tap_set_up(tap, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_up sanity checks\n");
++	if ((nozzle_set_up(tap, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to tap set_down\n");
+ 	errno = 0;
+-	if ((tap_set_down(NULL, &error_down, &error_postdown) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_down sanity checks\n");
++	if ((nozzle_set_down(NULL, &error_down, &error_postdown) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to error_down set_down\n");
+ 	errno = 0;
+-	if ((tap_set_down(tap, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_down sanity checks\n");
++	if ((nozzle_set_down(tap, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to error_postdown set_down\n");
+ 	errno = 0;
+-	if ((tap_set_down(tap, &error_down, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in tap_set_down sanity checks\n");
++	if ((nozzle_set_down(tap, &error_down, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ out_clean:
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	return err;
+ }
+@@ -2076,7 +2076,7 @@ static int check_knet_close_leak(void)
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = tap_open(device_name, size, NULL);
++	tap = nozzle_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -2084,7 +2084,7 @@ static int check_knet_close_leak(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_add_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_add_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2098,7 +2098,7 @@ static int check_knet_close_leak(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = tap_add_ip(tap, testipv4_2, "24", &error_string);
++	err = nozzle_add_ip(tap, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2112,7 +2112,7 @@ static int check_knet_close_leak(void)
+ 
+ out_clean:
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	return err;
+ }
+@@ -2132,7 +2132,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = tap_open(device_name, size, NULL);
++	tap = nozzle_open(device_name, size, NULL);
+ 	if (!tap) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+@@ -2140,7 +2140,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_add_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_add_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2154,7 +2154,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = tap_add_ip(tap, testipv4_2, "24", &error_string);
++	err = nozzle_add_ip(tap, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2168,7 +2168,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding duplicate ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_add_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_add_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2204,7 +2204,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Get ip list from libtap:\n");
+ 
+-	if (tap_get_ips(tap, &ip_list, &ip_list_entries) < 0) {
++	if (nozzle_get_ips(tap, &ip_list, &ip_list_entries) < 0) {
+ 		printf("Not enough mem?\n");
+ 		err=-1;
+ 		goto out_clean;
+@@ -2226,7 +2226,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_del_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_del_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2240,7 +2240,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/24\n", testipv4_2);
+ 
+-	err = tap_del_ip(tap, testipv4_2, "24", &error_string);
++	err = nozzle_del_ip(tap, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2254,7 +2254,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting again ip: %s/24\n", testipv4_1);
+ 
+-	err = tap_del_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_del_ip(tap, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2288,7 +2288,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = tap_add_ip(tap, testipv6_1, "64", &error_string);
++	err = nozzle_add_ip(tap, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -2322,7 +2322,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/64\n", testipv6_1);
+ 
+-	err = tap_del_ip(tap, testipv6_1, "64", &error_string);
++	err = nozzle_del_ip(tap, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -2356,7 +2356,7 @@ static int check_knet_set_del_ip(void)
+ 
+ out_clean:
+ 
+-	tap_close(tap);
++	nozzle_close(tap);
+ 
+ 	return err;
+ }
+@@ -2426,7 +2426,7 @@ int main(void)
+ 
+ 	make_local_ips();
+ 
+-	if (check_tap_open_close() < 0)
++	if (check_nozzle_open_close() < 0)
+ 		return -1;
+ 
+ 	if (check_knet_multi_eth() < 0)
+@@ -2441,7 +2441,7 @@ int main(void)
+ 	if (check_knet_mac() < 0)
+ 		return -1;
+ 
+-	if (check_tap_execute_shell() < 0)
++	if (check_nozzle_execute_shell() < 0)
+ 		return -1;
+ 
+ 	if (check_knet_up_down() < 0)
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 20b3bb80..a88d8dbc 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -23,28 +23,28 @@
+ 
+ typedef struct nozzle_iface *nozzle_t;
+ 
+-nozzle_t tap_open(char *dev, size_t dev_size, const char *updownpath);
+-int tap_close(nozzle_t tap);
++nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath);
++int nozzle_close(nozzle_t tap);
+ 
+-nozzle_t tap_find(char *dev, size_t dev_size);
++nozzle_t nozzle_find(char *dev, size_t dev_size);
+ 
+-int tap_get_fd(const nozzle_t tap);
++int nozzle_get_fd(const nozzle_t tap);
+ 
+-const char *tap_get_name(const nozzle_t tap);
++const char *nozzle_get_name(const nozzle_t tap);
+ 
+-int tap_get_mtu(const nozzle_t tap);
+-int tap_set_mtu(nozzle_t tap, const int mtu);
+-int tap_reset_mtu(nozzle_t tap);
++int nozzle_get_mtu(const nozzle_t tap);
++int nozzle_set_mtu(nozzle_t tap, const int mtu);
++int nozzle_reset_mtu(nozzle_t tap);
+ 
+-int tap_get_mac(const nozzle_t tap, char **ether_addr);
+-int tap_set_mac(nozzle_t tap, const char *ether_addr);
+-int tap_reset_mac(nozzle_t tap);
++int nozzle_get_mac(const nozzle_t tap, char **ether_addr);
++int nozzle_set_mac(nozzle_t tap, const char *ether_addr);
++int nozzle_reset_mac(nozzle_t tap);
+ 
+-int tap_set_up(nozzle_t tap, char **error_preup, char **error_up);
+-int tap_set_down(nozzle_t tap, char **error_down, char **error_postdown);
++int nozzle_set_up(nozzle_t tap, char **error_preup, char **error_up);
++int nozzle_set_down(nozzle_t tap, char **error_down, char **error_postdown);
+ 
+-int tap_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
+-int tap_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
+-int tap_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries);
++int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries);
+ 
+ #endif
+diff --git a/libnozzle/libnozzle_exported_syms b/libnozzle/libnozzle_exported_syms
+index 55ca485c..6745c9ba 100644
+--- a/libnozzle/libnozzle_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -9,7 +9,7 @@
+ 
+ LIBNOZZLE {
+ 	global:
+-		tap_*;
++		nozzle_*;
+ 	local:
+ 		*;
+ };
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0075-nozzle-rename-last-tap-bits-to-nozzle.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0075-nozzle-rename-last-tap-bits-to-nozzle.patch
new file mode 100644
index 000000000..2aa07d560
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0075-nozzle-rename-last-tap-bits-to-nozzle.patch
@@ -0,0 +1,1795 @@ 
+From 1749b45b2b581ef2d91d0e6193e46de63bbb2464 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 14:03:56 +0100
+Subject: [PATCH] [nozzle] rename last tap bits to nozzle
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 588 +++++++++++++++++++++---------------------
+ libnozzle/libnozzle.h |  28 +-
+ 2 files changed, 308 insertions(+), 308 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 73df6bec..48e4ca23 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -51,7 +51,7 @@ struct _ip {
+ struct nozzle_iface {
+ 	struct ifreq ifr;
+ 	int fd;
+-	char tapname[IFNAMSIZ];
++	char nozzlename[IFNAMSIZ];
+ 	char default_mac[MAX_MAC_CHAR];
+ 	int default_mtu;
+ 	int current_mtu;
+@@ -74,19 +74,19 @@ static pthread_mutex_t lib_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+ /* forward declarations */
+ static int _execute_shell(const char *command, char **error_string);
+-static int _exec_updown(const nozzle_t tap, const char *action, char **error_string);
++static int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string);
+ static int _read_pipe(int fd, char **file, size_t *length);
+-static int _check(const nozzle_t tap);
+-static void _close(nozzle_t tap);
++static int _check(const nozzle_t nozzle);
++static void _close(nozzle_t nozzle);
+ static void _close_cfg(void);
+-static int _get_mtu(const nozzle_t tap);
+-static int _get_mac(const nozzle_t tap, char **ether_addr);
+-static int _set_down(nozzle_t tap, char **error_down, char **error_postdown);
++static int _get_mtu(const nozzle_t nozzle);
++static int _get_mac(const nozzle_t nozzle, char **ether_addr);
++static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix);
+-static int _set_ip(nozzle_t tap, const char *command,
++static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ip_addr, const char *prefix,
+ 		      char **error_string, int secondary);
+-static int _find_ip(nozzle_t tap,
++static int _find_ip(nozzle_t nozzle,
+ 			const char *ip_addr, const char *prefix,
+ 			struct _ip **ip, struct _ip **ip_prev);
+ 
+@@ -202,18 +202,18 @@ out_clean0:
+ 	return err;
+ }
+ 
+-static int _exec_updown(const nozzle_t tap, const char *action, char **error_string)
++static int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string)
+ {
+ 	char command[PATH_MAX];
+ 	struct stat sb;
+ 	int err = 0;
+ 
+-	if (!tap->hasupdown)
++	if (!nozzle->hasupdown)
+ 		return 0;
+ 
+ 	memset(command, 0, PATH_MAX);
+ 
+-	snprintf(command, PATH_MAX, "%s%s/%s", tap->updownpath, action, tap->tapname);
++	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action, nozzle->nozzlename);
+ 
+ 	err = stat(command, &sb);
+ 	if ((err < 0) && (errno == ENOENT))
+@@ -228,16 +228,16 @@ static int _exec_updown(const nozzle_t tap, const char *action, char **error_str
+ 	return err;
+ }
+ 
+-static int _check(const nozzle_t tap)
++static int _check(const nozzle_t nozzle)
+ {
+ 	nozzle_t temp = lib_cfg.head;
+ 
+-	if (!tap) {
++	if (!nozzle) {
+ 		return 0;
+ 	}
+ 
+ 	while (temp != NULL) {
+-		if (tap == temp)
++		if (nozzle == temp)
+ 			return 1;
+ 
+ 		temp = temp->next;
+@@ -246,22 +246,22 @@ static int _check(const nozzle_t tap)
+ 	return 0;
+ }
+ 
+-static void _close(nozzle_t tap)
++static void _close(nozzle_t nozzle)
+ {
+-	if (!tap)
++	if (!nozzle)
+ 		return;
+ 
+-	if (tap->fd)
+-		close(tap->fd);
++	if (nozzle->fd)
++		close(nozzle->fd);
+ 
+ #ifdef KNET_BSD
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	ioctl(lib_cfg.sockfd, SIOCIFDESTROY, &tap->ifr);
++	ioctl(lib_cfg.sockfd, SIOCIFDESTROY, &nozzle->ifr);
+ #endif
+ 
+-	free(tap);
++	free(nozzle);
+ 
+ 	return;
+ }
+@@ -274,24 +274,24 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _get_mtu(const nozzle_t tap)
++static int _get_mtu(const nozzle_t nozzle)
+ {
+ 	int err;
+ 
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFMTU, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCGIFMTU, &nozzle->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+-	err = tap->ifr.ifr_mtu;
++	err = nozzle->ifr.ifr_mtu;
+ 
+ out_clean:
+ 	return err;
+ }
+ 
+-static int _get_mac(const nozzle_t tap, char **ether_addr)
++static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err = 0;
+ 	char mac[MAX_MAC_CHAR];
+@@ -302,15 +302,15 @@ static int _get_mac(const nozzle_t tap, char **ether_addr)
+ #endif
+ 
+ 	memset(&mac, 0, MAX_MAC_CHAR);
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+ #ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &nozzle->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+-	ether_ntoa_r((struct ether_addr *)tap->ifr.ifr_hwaddr.sa_data, mac);
++	ether_ntoa_r((struct ether_addr *)nozzle->ifr.ifr_hwaddr.sa_data, mac);
+ #endif
+ #ifdef KNET_BSD
+ 	/*
+@@ -325,7 +325,7 @@ static int _get_mac(const nozzle_t tap, char **ether_addr)
+ 	ifa = ifap;
+ 
+ 	while (ifa) {
+-		if (!strncmp(tap->tapname, ifa->ifa_name, IFNAMSIZ)) {
++		if (!strncmp(nozzle->nozzlename, ifa->ifa_name, IFNAMSIZ)) {
+ 			found = 1;
+ 			break;
+ 		}
+@@ -354,7 +354,7 @@ out_clean:
+ 
+ nozzle_t nozzle_find(char *dev, size_t dev_size)
+ {
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 
+ 	if (dev == NULL) {
+ 		errno = EINVAL;
+@@ -373,25 +373,25 @@ nozzle_t nozzle_find(char *dev, size_t dev_size)
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	tap = lib_cfg.head;
+-	while (tap != NULL) {
+-		if (!strcmp(dev, tap->tapname))
++	nozzle = lib_cfg.head;
++	while (nozzle != NULL) {
++		if (!strcmp(dev, nozzle->nozzlename))
+ 			break;
+-		tap = tap->next;
++		nozzle = nozzle->next;
+ 	}
+ 
+ 	pthread_mutex_unlock(&lib_mutex);
+-	return tap;
++	return nozzle;
+ }
+ 
+ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ {
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 	char *temp_mac = NULL;
+ #ifdef KNET_BSD
+ 	uint16_t i;
+-	long int tapnum = 0;
+-	char curtap[IFNAMSIZ];
++	long int nozzlenum = 0;
++	char curnozzle[IFNAMSIZ];
+ #endif
+ 
+ 	if (dev == NULL) {
+@@ -412,7 +412,7 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ #ifdef KNET_BSD
+ 	/*
+ 	 * BSD does not support named devices like Linux
+-	 * but it is possible to force a tapX device number
++	 * but it is possible to force a nozzleX device number
+ 	 * where X is 0 to 255.
+ 	 */
+ 	if (strlen(dev)) {
+@@ -421,12 +421,12 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ 			return NULL;
+ 		}
+ 		errno = 0;
+-		tapnum = strtol(dev+3, NULL, 10);
++		nozzlenum = strtol(dev+3, NULL, 10);
+ 		if (errno) {
+ 			errno = EINVAL;
+ 			return NULL;
+ 		}
+-		if ((tapnum < 0) || (tapnum > 255)) {
++		if ((nozzlenum < 0) || (nozzlenum > 255)) {
+ 			errno = EINVAL;
+ 			return NULL;
+ 		}
+@@ -446,12 +446,12 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ 		}
+ 	}
+ 
+-	tap = malloc(sizeof(struct nozzle_iface));
+-	if (!tap) {
++	nozzle = malloc(sizeof(struct nozzle_iface));
++	if (!nozzle) {
+ 		return NULL;
+ 	}
+ 
+-	memset(tap, 0, sizeof(struct nozzle_iface));
++	memset(nozzle, 0, sizeof(struct nozzle_iface));
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+@@ -472,81 +472,81 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ #ifdef KNET_BSD
+ 	if (!strlen(dev)) {
+ 		for (i = 0; i < 256; i++) {
+-			snprintf(curtap, sizeof(curtap) - 1, "/dev/tap%u", i);
+-			tap->fd = open(curtap, O_RDWR);
+-			if (tap->fd > 0) {
++			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/nozzle%u", i);
++			nozzle->fd = open(curnozzle, O_RDWR);
++			if (nozzle->fd > 0) {
+ 				break;
+ 			}
+ 		}
+-		snprintf(curtap, sizeof(curtap) -1 , "tap%u", i);
++		snprintf(curnozzle, sizeof(curnozzle) -1 , "nozzle%u", i);
+ 	} else {
+-		snprintf(curtap, sizeof(curtap) - 1, "/dev/%s", dev);
+-		tap->fd = open(curtap, O_RDWR);
+-		snprintf(curtap, sizeof(curtap) - 1, "%s", dev);
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", dev);
++		nozzle->fd = open(curnozzle, O_RDWR);
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", dev);
+ 	}
+-	if (tap->fd < 0) {
++	if (nozzle->fd < 0) {
+ 		errno = EBUSY;
+ 		goto out_error;
+ 	}
+-	strncpy(dev, curtap, IFNAMSIZ);
+-	strncpy(tap->tapname, curtap, IFNAMSIZ);
++	strncpy(dev, curnozzle, IFNAMSIZ);
++	strncpy(nozzle->nozzlename, curnozzle, IFNAMSIZ);
+ #endif
+ 
+ #ifdef KNET_LINUX
+-	if ((tap->fd = open("/dev/net/tun", O_RDWR)) < 0)
++	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0)
+ 		goto out_error;
+ 
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, dev, IFNAMSIZ);
+-	tap->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, dev, IFNAMSIZ);
++	nozzle->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ 
+-	if (ioctl(tap->fd, TUNSETIFF, &tap->ifr) < 0)
++	if (ioctl(nozzle->fd, TUNSETIFF, &nozzle->ifr) < 0)
+ 		goto out_error;
+ 
+-	if ((strlen(dev) > 0) && (strcmp(dev, tap->ifname) != 0)) {
++	if ((strlen(dev) > 0) && (strcmp(dev, nozzle->ifname) != 0)) {
+ 		errno = EBUSY;
+ 		goto out_error;
+ 	}
+ 
+-	strncpy(dev, tap->ifname, IFNAMSIZ);
+-	strncpy(tap->tapname, tap->ifname, IFNAMSIZ);
++	strncpy(dev, nozzle->ifname, IFNAMSIZ);
++	strncpy(nozzle->nozzlename, nozzle->ifname, IFNAMSIZ);
+ #endif
+ 
+-	tap->default_mtu = _get_mtu(tap);
+-	if (tap->default_mtu < 0)
++	nozzle->default_mtu = _get_mtu(nozzle);
++	if (nozzle->default_mtu < 0)
+ 		goto out_error;
+ 
+-	if (_get_mac(tap, &temp_mac) < 0)
++	if (_get_mac(nozzle, &temp_mac) < 0)
+ 		goto out_error;
+ 
+-	strncpy(tap->default_mac, temp_mac, 18);
++	strncpy(nozzle->default_mac, temp_mac, 18);
+ 	free(temp_mac);
+ 
+ 	if (updownpath) {
+ 		int len = strlen(updownpath);
+ 
+-		strcpy(tap->updownpath, updownpath);
+-		if (tap->updownpath[len-1] != '/') {
+-			tap->updownpath[len] = '/';
++		strcpy(nozzle->updownpath, updownpath);
++		if (nozzle->updownpath[len-1] != '/') {
++			nozzle->updownpath[len] = '/';
+ 		}
+-		tap->hasupdown = 1;
++		nozzle->hasupdown = 1;
+ 	}
+ 
+-	tap->next = lib_cfg.head;
+-	lib_cfg.head = tap;
++	nozzle->next = lib_cfg.head;
++	lib_cfg.head = nozzle;
+ 
+ 	pthread_mutex_unlock(&lib_mutex);
+-	return tap;
++	return nozzle;
+ 
+ out_error:
+-	_close(tap);
++	_close(nozzle);
+ 	_close_cfg();
+ 	pthread_mutex_unlock(&lib_mutex);
+ 	return NULL;
+ }
+ 
+ // TODO: consider better error report from here
+-int nozzle_close(nozzle_t tap)
++int nozzle_close(nozzle_t nozzle)
+ {
+ 	int err = 0;
+ 	nozzle_t temp = lib_cfg.head;
+@@ -557,33 +557,33 @@ int nozzle_close(nozzle_t tap)
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	while ((temp) && (temp != tap)) {
++	while ((temp) && (temp != nozzle)) {
+ 		prev = temp;
+ 		temp = temp->next;
+ 	}
+ 
+-	if (tap == prev) {
+-		lib_cfg.head = tap->next;
++	if (nozzle == prev) {
++		lib_cfg.head = nozzle->next;
+ 	} else {
+-		prev->next = tap->next;
++		prev->next = nozzle->next;
+ 	}
+ 
+-	_set_down(tap, &error_down, &error_postdown);
++	_set_down(nozzle, &error_down, &error_postdown);
+ 	if (error_down)
+ 		free(error_down);
+ 	if (error_postdown)
+ 		free(error_postdown);
+ 
+-	ip = tap->ip;
++	ip = nozzle->ip;
+ 	while (ip) {
+ 		ip_next = ip->next;
+-		_set_ip(tap, "del", ip->ip_addr, ip->prefix, &error_string, 0);
++		_set_ip(nozzle, "del", ip->ip_addr, ip->prefix, &error_string, 0);
+ 		if (error_string) {
+ 			free(error_string);
+ 			error_string = NULL;
+@@ -592,7 +592,7 @@ int nozzle_close(nozzle_t tap)
+ 		ip = ip_next;
+ 	}
+ 
+-	_close(tap);
++	_close(nozzle);
+ 	_close_cfg();
+ 
+ out_clean:
+@@ -601,19 +601,19 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_get_mtu(const nozzle_t tap)
++int nozzle_get_mtu(const nozzle_t nozzle)
+ {
+ 	int err;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	err = _get_mtu(tap);
++	err = _get_mtu(nozzle);
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -621,7 +621,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_set_mtu(nozzle_t tap, const int mtu)
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
+ {
+ 	struct _ip *tmp_ip;
+ 	char *error_string = NULL;
+@@ -629,25 +629,25 @@ int nozzle_set_mtu(nozzle_t tap, const int mtu)
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	err = tap->current_mtu = _get_mtu(tap);
++	err = nozzle->current_mtu = _get_mtu(nozzle);
+ 	if (err < 0)
+ 		goto out_clean;
+ 
+-	tap->ifr.ifr_mtu = mtu;
++	nozzle->ifr.ifr_mtu = mtu;
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFMTU, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCSIFMTU, &nozzle->ifr);
+ 
+-	if ((!err) && (tap->current_mtu < 1280) && (mtu >= 1280)) {
+-		tmp_ip = tap->ip;
++	if ((!err) && (nozzle->current_mtu < 1280) && (mtu >= 1280)) {
++		tmp_ip = nozzle->ip;
+ 		while(tmp_ip) {
+ 			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(tap, "add", tmp_ip->ip_addr, tmp_ip->prefix, &error_string, 0);
++				err = _set_ip(nozzle, "add", tmp_ip->ip_addr, tmp_ip->prefix, &error_string, 0);
+ 				if (error_string) {
+ 					free(error_string);
+ 					error_string = NULL;
+@@ -663,24 +663,24 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_reset_mtu(nozzle_t tap)
++int nozzle_reset_mtu(nozzle_t nozzle)
+ {
+-	return nozzle_set_mtu(tap, tap->default_mtu);
++	return nozzle_set_mtu(nozzle, nozzle->default_mtu);
+ }
+ 
+-int nozzle_get_mac(const nozzle_t tap, char **ether_addr)
++int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if ((!_check(tap)) || (!ether_addr)) {
++	if ((!_check(nozzle)) || (!ether_addr)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	err = _get_mac(tap, ether_addr);
++	err = _get_mac(nozzle, ether_addr);
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -688,38 +688,38 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_set_mac(nozzle_t tap, const char *ether_addr)
++int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ {
+ 	int err;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if ((!_check(tap)) || (!ether_addr)) {
++	if ((!_check(nozzle)) || (!ether_addr)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ #ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &nozzle->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+-	memmove(tap->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
++	memmove(nozzle->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFHWADDR, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCSIFHWADDR, &nozzle->ifr);
+ #endif
+ #ifdef KNET_BSD
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFADDR, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCGIFADDR, &nozzle->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+-	memmove(tap->ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
+-	tap->ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
++	memmove(nozzle->ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
++	nozzle->ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFLLADDR, &tap->ifr);
++	err = ioctl(lib_cfg.sockfd, SIOCSIFLLADDR, &nozzle->ifr);
+ #endif
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -727,105 +727,105 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_reset_mac(nozzle_t tap)
++int nozzle_reset_mac(nozzle_t nozzle)
+ {
+-	return nozzle_set_mac(tap, tap->default_mac);
++	return nozzle_set_mac(nozzle, nozzle->default_mac);
+ }
+ 
+-int nozzle_set_up(nozzle_t tap, char **error_preup, char **error_up)
++int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ {
+ 	int err = 0;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	if ((tap->hasupdown) && ((!error_preup) || (!error_up))) {
++	if ((nozzle->hasupdown) && ((!error_preup) || (!error_up))) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	if (tap->up)
++	if (nozzle->up)
+ 		goto out_clean;
+ 
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err=ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &tap->ifr);
++	err=ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+-	_exec_updown(tap, "pre-up.d", error_preup);
++	_exec_updown(nozzle, "pre-up.d", error_preup);
+ 
+-	tap->ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+-	err=ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &tap->ifr);
++	nozzle->ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
++	err=ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
+ 
+ 	if (err)
+ 		goto out_clean;
+ 
+-	_exec_updown(tap, "up.d", error_up);
++	_exec_updown(nozzle, "up.d", error_up);
+ 
+-	tap->up = 1;
++	nozzle->up = 1;
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+ 
+ 	return err;
+ }
+ 
+-static int _set_down(nozzle_t tap, char **error_down, char **error_postdown)
++static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+ 	int err = 0;
+ 
+-	if (!tap->up)
++	if (!nozzle->up)
+ 		goto out_clean;
+ 
+-	memset(&tap->ifr, 0, sizeof(struct ifreq));
+-	strncpy(tap->ifname, tap->tapname, IFNAMSIZ);
++	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err=ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &tap->ifr);
++	err=ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
+ 	if (err)
+ 		goto out_clean;
+ 
+-	_exec_updown(tap, "down.d", error_down);
++	_exec_updown(nozzle, "down.d", error_down);
+ 
+-	tap->ifr.ifr_flags &= ~IFF_UP;
+-	err=ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &tap->ifr);
++	nozzle->ifr.ifr_flags &= ~IFF_UP;
++	err=ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
+ 
+ 	if (err)
+ 		goto out_clean;
+ 
+-	_exec_updown(tap, "post-down.d", error_postdown);
++	_exec_updown(nozzle, "post-down.d", error_postdown);
+ 
+-	tap->up = 0;
++	nozzle->up = 0;
+ 
+ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_set_down(nozzle_t tap, char **error_down, char **error_postdown)
++int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+ 	int err = 0;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	if ((tap->hasupdown) && ((!error_down) || (!error_postdown))) {
++	if ((nozzle->hasupdown) && ((!error_down) || (!error_postdown))) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	err = _set_down(tap, error_down, error_postdown);
++	err = _set_down(nozzle, error_down, error_postdown);
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -856,7 +856,7 @@ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix)
+ 	return strdup(inet_ntoa(broadcast));
+ }
+ 
+-static int _set_ip(nozzle_t tap, const char *command,
++static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ip_addr, const char *prefix,
+ 		      char **error_string, int secondary)
+ {
+@@ -890,19 +890,19 @@ static int _set_ip(nozzle_t tap, const char *command,
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ip addr %s %s/%s dev %s broadcast %s",
+ 			 command, ip_addr, prefix,
+-			 tap->tapname, broadcast);
++			 nozzle->nozzlename, broadcast);
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ip addr %s %s/%s dev %s",
+ 			command, ip_addr, prefix,
+-			tap->tapname);
++			nozzle->nozzlename);
+ 	}
+ #endif
+ #ifdef KNET_BSD
+ 	if (!strcmp(command, "add")) {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ifconfig %s %s %s/%s",
+-			 tap->tapname, proto, ip_addr, prefix);
++			 nozzle->nozzlename, proto, ip_addr, prefix);
+ 		if (broadcast) {
+ 			snprintf(cmdline + strlen(cmdline),
+ 				 sizeof(cmdline) - strlen(cmdline) -1,
+@@ -916,7 +916,7 @@ static int _set_ip(nozzle_t tap, const char *command,
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 				 "ifconfig %s %s %s/%s delete",
+-				 tap->tapname, proto, ip_addr, prefix);
++				 nozzle->nozzlename, proto, ip_addr, prefix);
+ 	}
+ #endif
+ 	if (broadcast) {
+@@ -925,14 +925,14 @@ static int _set_ip(nozzle_t tap, const char *command,
+ 	return _execute_shell(cmdline, error_string);
+ }
+ 
+-static int _find_ip(nozzle_t tap,
++static int _find_ip(nozzle_t nozzle,
+ 			const char *ip_addr, const char *prefix,
+ 			struct _ip **ip, struct _ip **ip_prev)
+ {
+ 	struct _ip *local_ip, *local_ip_prev;
+ 	int found = 0;
+ 
+-	local_ip = local_ip_prev = tap->ip;
++	local_ip = local_ip_prev = nozzle->ip;
+ 
+ 	while(local_ip) {
+ 		if ((!strcmp(local_ip->ip_addr, ip_addr)) && (!strcmp(local_ip->prefix, prefix))) {
+@@ -951,7 +951,7 @@ static int _find_ip(nozzle_t tap,
+ 	return found;
+ }
+ 
+-int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
++int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+@@ -959,13 +959,13 @@ int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if ((!_check(tap)) || (!ip_addr) || (!prefix) || (!error_string)) {
++	if ((!_check(nozzle)) || (!ip_addr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	found = _find_ip(tap, ip_addr, prefix, &ip, &ip_prev);
++	found = _find_ip(nozzle, ip_addr, prefix, &ip, &ip_prev);
+ 	if (found)
+ 		goto out_clean;
+ 
+@@ -987,13 +987,13 @@ int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **
+ 	 * if user asks for an IPv6 address, but MTU < 1280
+ 	 * store the IP and bring it up later if and when MTU > 1280
+ 	 */
+-	if ((ip->domain == AF_INET6) && (_get_mtu(tap) < 1280)) {
++	if ((ip->domain == AF_INET6) && (_get_mtu(nozzle) < 1280)) {
+ 		err = 0;
+ 	} else {
+-		if (tap->ip) {
++		if (nozzle->ip) {
+ 			secondary = 1;
+ 		}
+-		err = _set_ip(tap, "add", ip_addr, prefix, error_string, secondary);
++		err = _set_ip(nozzle, "add", ip_addr, prefix, error_string, secondary);
+ 	}
+ 
+ 	if (err) {
+@@ -1001,14 +1001,14 @@ int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **
+ 		goto out_clean;
+ 	}
+ 
+-	if (tap->ip) {
+-		ip_last = tap->ip;
++	if (nozzle->ip) {
++		ip_last = nozzle->ip;
+ 		while (ip_last->next != NULL) {
+ 			ip_last = ip_last->next;
+ 		}
+ 		ip_last->next = ip;
+ 	} else {
+-		tap->ip = ip;
++		nozzle->ip = ip;
+ 	}
+ 
+ out_clean:
+@@ -1017,28 +1017,28 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string)
++int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, found;
+ 	struct _ip *ip = NULL, *ip_prev = NULL;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if ((!_check(tap)) || (!ip_addr) || (!prefix) || (!error_string)) {
++	if ((!_check(nozzle)) || (!ip_addr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	found = _find_ip(tap, ip_addr, prefix, &ip, &ip_prev);
++	found = _find_ip(nozzle, ip_addr, prefix, &ip, &ip_prev);
+ 	if (!found)
+ 		goto out_clean;
+ 
+-	err = _set_ip(tap, "del", ip_addr, prefix, error_string, 0);
++	err = _set_ip(nozzle, "del", ip_addr, prefix, error_string, 0);
+ 
+ 	if (!err) {
+ 		if (ip == ip_prev) {
+-			tap->ip = ip->next;
++			nozzle->ip = ip->next;
+ 		} else {
+ 			ip_prev->next = ip->next;
+ 		}
+@@ -1051,19 +1051,19 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_get_fd(const nozzle_t tap)
++int nozzle_get_fd(const nozzle_t nozzle)
+ {
+ 	int fd;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		fd = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	fd = tap->fd;
++	fd = nozzle->fd;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -1071,18 +1071,18 @@ out_clean:
+ 	return fd;
+ }
+ 
+-const char *nozzle_get_name(const nozzle_t tap)
++const char *nozzle_get_name(const nozzle_t nozzle)
+ {
+ 	char *name = NULL;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+-	if (!_check(tap)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		goto out_clean;
+ 	}
+ 
+-	name = tap->tapname;
++	name = nozzle->nozzlename;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -1090,13 +1090,13 @@ out_clean:
+ 	return name;
+ }
+ 
+-int nozzle_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries)
++int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ {
+ 	int err = 0;
+ 	int found = 0;
+ 	char *ip_list = NULL;
+ 	int size = 0, offset = 0, len;
+-	struct _ip *ip = tap->ip;
++	struct _ip *ip = nozzle->ip;
+ 
+ 	pthread_mutex_lock(&lib_mutex);
+ 
+@@ -1114,7 +1114,7 @@ int nozzle_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries)
+ 
+ 	memset(ip_list, 0, size);
+ 
+-	ip = tap->ip;
++	ip = nozzle->ip;
+ 
+ 	while (ip) {
+ 		len = strlen(ip->ip_addr);
+@@ -1174,10 +1174,10 @@ static int is_if_in_system(char *name)
+ 
+ static int test_iface(char *name, size_t size, const char *updownpath)
+ {
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 
+-	tap=nozzle_open(name, size, updownpath);
+-	if (!tap) {
++	nozzle=nozzle_open(name, size, updownpath);
++	if (!nozzle) {
+ 		if (lib_cfg.sockfd < 0)
+ 			printf("Unable to open knet_socket\n");
+ 		printf("Unable to open knet.\n");
+@@ -1192,12 +1192,12 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 	}
+ 
+ 	if (!nozzle_find(name, size)) {
+-		printf("Unable to find interface %s in tap db\n", name);
++		printf("Unable to find interface %s in nozzle db\n", name);
+ 	} else {
+-		printf("Found interface %s in tap db\n", name);
++		printf("Found interface %s in nozzle db\n", name);
+ 	}
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	if (is_if_in_system(name) == 0)
+ 		printf("Successfully removed interface %s from the system\n", name);
+@@ -1213,14 +1213,14 @@ static int check_nozzle_open_close(void)
+ 
+ 	memset(device_name, 0, sizeof(device_name));
+ 
+-	printf("Creating random tap interface:\n");
++	printf("Creating random nozzle interface:\n");
+ 	if (test_iface(device_name, size,  NULL) < 0) {
+ 		printf("Unable to create random interface\n");
+ 		return -1;
+ 	}
+ 
+ #ifdef KNET_LINUX
+-	printf("Creating kronostest%u tap interface:\n", randombyte);
++	printf("Creating kronostest%u nozzle interface:\n", randombyte);
+ 	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+ 	if (test_iface(device_name, size, NULL) < 0) {
+ 		printf("Unable to create kronostest%u interface\n", randombyte);
+@@ -1228,14 +1228,14 @@ static int check_nozzle_open_close(void)
+ 	}
+ #endif
+ #ifdef KNET_BSD
+-	printf("Creating tap%u tap interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
++	printf("Creating nozzle%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "nozzle%u", randombyte);
+ 	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create tap%u interface\n", randombyte);
++		printf("Unable to create nozzle%u interface\n", randombyte);
+ 		return -1;
+ 	}
+ 
+-	printf("Creating kronostest%u tap interface:\n", randombyte);
++	printf("Creating kronostest%u nozzle interface:\n", randombyte);
+ 	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+ 	if (test_iface(device_name, size, NULL) == 0) {
+ 		printf("BSD should not accept kronostest%u interface\n", randombyte);
+@@ -1297,16 +1297,16 @@ static int check_knet_multi_eth(void)
+ 	char device_name2[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	nozzle_t tap1 = NULL;
+-	nozzle_t tap2 = NULL;
++	nozzle_t nozzle1 = NULL;
++	nozzle_t nozzle2 = NULL;
+ 
+ 	printf("Testing multiple knet interface instances\n");
+ 
+ 	memset(device_name1, 0, size);
+ 	memset(device_name2, 0, size);
+ 
+-	tap1 = nozzle_open(device_name1, size, NULL);
+-	if (!tap1) {
++	nozzle1 = nozzle_open(device_name1, size, NULL);
++	if (!nozzle1) {
+ 		printf("Unable to init %s\n", device_name1);
+ 		err = -1;
+ 		goto out_clean;
+@@ -1318,8 +1318,8 @@ static int check_knet_multi_eth(void)
+ 		printf("Unable to find interface %s on the system\n", device_name1);
+ 	}
+ 
+-	tap2 = nozzle_open(device_name2, size, NULL);
+-	if (!tap2) {
++	nozzle2 = nozzle_open(device_name2, size, NULL);
++	if (!nozzle2) {
+ 		printf("Unable to init %s\n", device_name2);
+ 		err = -1;
+ 		goto out_clean;
+@@ -1331,10 +1331,10 @@ static int check_knet_multi_eth(void)
+ 		printf("Unable to find interface %s on the system\n", device_name2);
+ 	}
+ 
+-	if (tap1)
+-		nozzle_close(tap1);
+-	if (tap2)
+-		nozzle_close(tap2);
++	if (nozzle1)
++		nozzle_close(nozzle1);
++	if (nozzle2)
++		nozzle_close(nozzle2);
+ 
+ 	printf("Testing error conditions\n");
+ 
+@@ -1342,8 +1342,8 @@ static int check_knet_multi_eth(void)
+ 
+ 	memset(device_name1, 0, size);
+ 
+-	tap1 = nozzle_open(device_name1, size, NULL);
+-	if (!tap1) {
++	nozzle1 = nozzle_open(device_name1, size, NULL);
++	if (!nozzle1) {
+ 		printf("Unable to init %s\n", device_name1);
+ 		err = -1;
+ 		goto out_clean;
+@@ -1355,18 +1355,18 @@ static int check_knet_multi_eth(void)
+ 		printf("Unable to find interface %s on the system\n", device_name1);
+ 	}
+ 
+-	tap2 = nozzle_open(device_name1, size, NULL);
+-	if (tap2) {
++	nozzle2 = nozzle_open(device_name1, size, NULL);
++	if (nozzle2) {
+ 		printf("We were able to init 2 interfaces with the same name!\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ out_clean:
+-	if (tap1)
+-		nozzle_close(tap1);
+-	if (tap2)
+-		nozzle_close(tap2);
++	if (nozzle1)
++		nozzle_close(nozzle1);
++	if (nozzle2)
++		nozzle_close(nozzle2);
+ 	return err;
+ }
+ 
+@@ -1375,7 +1375,7 @@ static int check_knet_mtu(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 
+ 	int current_mtu = 0;
+ 	int expected_mtu = 1500;
+@@ -1383,14 +1383,14 @@ static int check_knet_mtu(void)
+ 	printf("Testing get/set MTU\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = nozzle_open(device_name, size, NULL);
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Comparing default MTU\n");
+-	current_mtu = nozzle_get_mtu(tap);
++	current_mtu = nozzle_get_mtu(nozzle);
+ 	if (current_mtu < 0) {
+ 		printf("Unable to get MTU\n");
+ 		err = -1;
+@@ -1404,13 +1404,13 @@ static int check_knet_mtu(void)
+ 
+ 	printf("Setting MTU to 9000\n");
+ 	expected_mtu = 9000;
+-	if (nozzle_set_mtu(tap, expected_mtu) < 0) {
++	if (nozzle_set_mtu(nozzle, expected_mtu) < 0) {
+ 		printf("Unable to set MTU to %d\n", expected_mtu);
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	current_mtu = nozzle_get_mtu(tap);
++	current_mtu = nozzle_get_mtu(nozzle);
+ 	if (current_mtu < 0) {
+ 		printf("Unable to get MTU\n");
+ 		err = -1;
+@@ -1439,7 +1439,7 @@ static int check_knet_mtu(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -1450,22 +1450,22 @@ static int check_knet_mtu_ipv6(void)
+ 	size_t size = IFNAMSIZ;
+ 	char verifycmd[1024];
+ 	int err=0;
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 	char *error_string = NULL;
+ 
+ 	printf("Testing get/set MTU with IPv6 address\n");
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = nozzle_open(device_name, size, NULL);
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = nozzle_add_ip(tap, testipv6_1, "64", &error_string);
++	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -1481,10 +1481,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1499,7 +1499,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Setting MTU to 1200\n");
+-	if (nozzle_set_mtu(tap, 1200) < 0) {
++	if (nozzle_set_mtu(nozzle, 1200) < 0) {
+ 		printf("Unable to set MTU to 1200\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1523,7 +1523,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_2);
+-	err = nozzle_add_ip(tap, testipv6_2, "64", &error_string);
++	err = nozzle_add_ip(nozzle, testipv6_2, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -1538,10 +1538,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_2);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_2);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_2);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_2);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1556,7 +1556,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Restoring MTU to default\n");
+-	if (nozzle_reset_mtu(tap) < 0) {
++	if (nozzle_reset_mtu(nozzle) < 0) {
+ 		printf("Unable to reset mtu\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1565,10 +1565,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1585,10 +1585,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_2);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_2);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_2);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_2);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1603,7 +1603,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -1613,22 +1613,22 @@ static int check_knet_mac(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
+ 	struct ether_addr *cur_mac, *tmp_mac;
+ 
+ 	printf("Testing get/set MAC\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = nozzle_open(device_name, size, NULL);
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Get current MAC\n");
+ 
+-	if (nozzle_get_mac(tap, &current_mac) < 0) {
++	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
+ 		printf("Unable to get current MAC address.\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1638,13 +1638,13 @@ static int check_knet_mac(void)
+ 
+ 	printf("Setting MAC: 00:01:01:01:01:01\n");
+ 
+-	if (nozzle_set_mac(tap, "00:01:01:01:01:01") < 0) {
++	if (nozzle_set_mac(nozzle, "00:01:01:01:01:01") < 0) {
+ 		printf("Unable to set current MAC address.\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	if (nozzle_get_mac(tap, &temp_mac) < 0) {
++	if (nozzle_get_mac(nozzle, &temp_mac) < 0) {
+ 		printf("Unable to get current MAC address.\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1675,7 +1675,7 @@ static int check_knet_mac(void)
+ 
+ 	printf("Pass NULL to get_mac (pass2)\n");
+ 	errno = 0;
+-	if ((nozzle_get_mac(tap, NULL) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_get_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1683,7 +1683,7 @@ static int check_knet_mac(void)
+ 
+ 	printf("Pass NULL to set_mac (pass1)\n");
+ 	errno = 0;
+-	if ((nozzle_set_mac(tap, NULL) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -1709,7 +1709,7 @@ out_clean:
+ 	if (temp_mac)
+ 		free(temp_mac);
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -1814,7 +1814,7 @@ static int check_knet_up_down(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 	char *error_string = NULL;
+ 	char *error_preup = NULL, *error_up = NULL;
+ 	char *error_down = NULL, *error_postdown = NULL;
+@@ -1822,15 +1822,15 @@ static int check_knet_up_down(void)
+ 	printf("Testing interface up/down\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = nozzle_open(device_name, size, NULL);
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(tap, &error_preup, &error_up);
++	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+ 	if (error_preup) {
+ 		printf("preup output: %s\n", error_preup);
+ 		free(error_preup);
+@@ -1850,10 +1850,10 @@ static int check_knet_up_down(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", tap->tapname);
++		 "ip addr show dev %s | grep -q UP", nozzle->nozzlename);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", tap->tapname);
++		 "ifconfig %s | grep -q UP", nozzle->nozzlename);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1869,7 +1869,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_set_down(tap, &error_down, &error_postdown);
++	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+@@ -1889,10 +1889,10 @@ static int check_knet_up_down(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", tap->tapname);
++		 "ip addr show dev %s | grep -q UP", nozzle->nozzlename);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", tap->tapname);
++		 "ifconfig %s | grep -q UP", nozzle->nozzlename);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1906,20 +1906,20 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+ 
+ 	memset(device_name, 0, size);
+-	tap = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(tap, &error_preup, &error_up);
++	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+ 	if (error_preup) {
+ 		printf("preup output: %s\n", error_preup);
+ 		free(error_preup);
+@@ -1938,7 +1938,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_set_down(tap, &error_down, &error_postdown);
++	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+@@ -1955,21 +1955,21 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	printf("Testing interface pre-up/up/down/post-down\n");
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(tap, &error_preup, &error_up);
++	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+ 	if (error_preup) {
+ 		printf("preup output: %s\n", error_preup);
+ 		free(error_preup);
+@@ -1988,7 +1988,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_set_down(tap, &error_down, &error_postdown);
++	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+@@ -2005,11 +2005,11 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	printf("Test ERROR conditions\n");
+ 
+-	printf("Pass NULL to tap set_up\n");
++	printf("Pass NULL to nozzle set_up\n");
+ 	errno = 0;
+ 	if ((nozzle_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_up sanity checks\n");
+@@ -2019,7 +2019,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Pass NULL to error_preup set_up\n");
+ 	errno = 0;
+-	if ((nozzle_set_up(tap, NULL, &error_up) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_up(nozzle, NULL, &error_up) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_up sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -2027,13 +2027,13 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Pass NULL to error_up set_up\n");
+ 	errno = 0;
+-	if ((nozzle_set_up(tap, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_up(nozzle, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_up sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Pass NULL to tap set_down\n");
++	printf("Pass NULL to nozzle set_down\n");
+ 	errno = 0;
+ 	if ((nozzle_set_down(NULL, &error_down, &error_postdown) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_down sanity checks\n");
+@@ -2043,7 +2043,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Pass NULL to error_down set_down\n");
+ 	errno = 0;
+-	if ((nozzle_set_down(tap, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_down(nozzle, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_down sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -2051,7 +2051,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Pass NULL to error_postdown set_down\n");
+ 	errno = 0;
+-	if ((nozzle_set_down(tap, &error_down, NULL) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_down(nozzle, &error_down, NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_down sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -2059,7 +2059,7 @@ static int check_knet_up_down(void)
+ 
+ out_clean:
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -2069,22 +2069,22 @@ static int check_knet_close_leak(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 	char *error_string = NULL;
+ 
+ 	printf("Testing close leak (needs valgrind)\n");
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = nozzle_open(device_name, size, NULL);
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_add_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2098,7 +2098,7 @@ static int check_knet_close_leak(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = nozzle_add_ip(tap, testipv4_2, "24", &error_string);
++	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2112,7 +2112,7 @@ static int check_knet_close_leak(void)
+ 
+ out_clean:
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -2123,7 +2123,7 @@ static int check_knet_set_del_ip(void)
+ 	size_t size = IFNAMSIZ;
+ 	char verifycmd[1024];
+ 	int err=0;
+-	nozzle_t tap;
++	nozzle_t nozzle;
+ 	char *ip_list = NULL;
+ 	int ip_list_entries = 0, i, offset = 0;
+ 	char *error_string = NULL;
+@@ -2132,15 +2132,15 @@ static int check_knet_set_del_ip(void)
+ 
+ 	memset(device_name, 0, size);
+ 
+-	tap = nozzle_open(device_name, size, NULL);
+-	if (!tap) {
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
+ 		printf("Unable to init %s\n", device_name);
+ 		return -1;
+ 	}
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_add_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2154,7 +2154,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = nozzle_add_ip(tap, testipv4_2, "24", &error_string);
++	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2168,14 +2168,14 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding duplicate ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_add_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("add ip output: %s\n", error_string);
+ 		free(error_string);
+ 		error_string = NULL;
+ 	}
+ 	if (err < 0) {
+-		printf("Unable to find IP address in libtap db\n");
++		printf("Unable to find IP address in libnozzle db\n");
+ 		err=-1;
+ 		goto out_clean;
+ 	}
+@@ -2185,10 +2185,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", tap->tapname, testipv4_1);
++		 "ip addr show dev %s | grep -q %s/24", nozzle->nozzlename, testipv4_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv4_1);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv4_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2202,22 +2202,22 @@ static int check_knet_set_del_ip(void)
+ 		goto out_clean;
+ 	}
+ 
+-	printf("Get ip list from libtap:\n");
++	printf("Get ip list from libnozzle:\n");
+ 
+-	if (nozzle_get_ips(tap, &ip_list, &ip_list_entries) < 0) {
++	if (nozzle_get_ips(nozzle, &ip_list, &ip_list_entries) < 0) {
+ 		printf("Not enough mem?\n");
+ 		err=-1;
+ 		goto out_clean;
+ 	}
+ 
+ 	if (ip_list_entries != 2) {
+-		printf("Didn't get enough ip back from libtap?\n");
++		printf("Didn't get enough ip back from libnozzle?\n");
+ 		err=-1;
+ 		goto out_clean;
+ 	}
+ 
+ 	for (i = 1; i <= ip_list_entries; i++) {
+-		printf("Found IP %s %s in libtap db\n", ip_list + offset, ip_list + offset + strlen(ip_list + offset) + 1);
++		printf("Found IP %s %s in libnozzle db\n", ip_list + offset, ip_list + offset + strlen(ip_list + offset) + 1);
+ 		offset = offset + strlen(ip_list) + 1;
+ 		offset = offset + strlen(ip_list + offset) + 1;
+ 	}
+@@ -2226,7 +2226,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_del_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2240,7 +2240,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/24\n", testipv4_2);
+ 
+-	err = nozzle_del_ip(tap, testipv4_2, "24", &error_string);
++	err = nozzle_del_ip(nozzle, testipv4_2, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2254,7 +2254,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting again ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_del_ip(tap, testipv4_1, "24", &error_string);
++	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
+ 	if (error_string) {
+ 		printf("del ip output: %s\n", error_string);
+ 		free(error_string);
+@@ -2269,10 +2269,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", tap->tapname, testipv4_1);
++		 "ip addr show dev %s | grep -q %s/24", nozzle->nozzlename, testipv4_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv4_1);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv4_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2288,7 +2288,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = nozzle_add_ip(tap, testipv6_1, "64", &error_string);
++	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("add ipv6 output: %s\n", error_string);
+ 		free(error_string);
+@@ -2303,10 +2303,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2322,7 +2322,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/64\n", testipv6_1);
+ 
+-	err = nozzle_del_ip(tap, testipv6_1, "64", &error_string);
++	err = nozzle_del_ip(nozzle, testipv6_1, "64", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -2337,10 +2337,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", tap->tapname, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", tap->tapname, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2356,7 +2356,7 @@ static int check_knet_set_del_ip(void)
+ 
+ out_clean:
+ 
+-	nozzle_close(tap);
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index a88d8dbc..6f05491f 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -24,27 +24,27 @@
+ typedef struct nozzle_iface *nozzle_t;
+ 
+ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath);
+-int nozzle_close(nozzle_t tap);
++int nozzle_close(nozzle_t nozzle);
+ 
+ nozzle_t nozzle_find(char *dev, size_t dev_size);
+ 
+-int nozzle_get_fd(const nozzle_t tap);
++int nozzle_get_fd(const nozzle_t nozzle);
+ 
+-const char *nozzle_get_name(const nozzle_t tap);
++const char *nozzle_get_name(const nozzle_t nozzle);
+ 
+-int nozzle_get_mtu(const nozzle_t tap);
+-int nozzle_set_mtu(nozzle_t tap, const int mtu);
+-int nozzle_reset_mtu(nozzle_t tap);
++int nozzle_get_mtu(const nozzle_t nozzle);
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
++int nozzle_reset_mtu(nozzle_t nozzle);
+ 
+-int nozzle_get_mac(const nozzle_t tap, char **ether_addr);
+-int nozzle_set_mac(nozzle_t tap, const char *ether_addr);
+-int nozzle_reset_mac(nozzle_t tap);
++int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
++int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
++int nozzle_reset_mac(nozzle_t nozzle);
+ 
+-int nozzle_set_up(nozzle_t tap, char **error_preup, char **error_up);
+-int nozzle_set_down(nozzle_t tap, char **error_down, char **error_postdown);
++int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
++int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
+-int nozzle_add_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
+-int nozzle_del_ip(nozzle_t tap, const char *ip_addr, const char *prefix, char **error_string);
+-int nozzle_get_ips(const nozzle_t tap, char **ip_addr_list, int *entries);
++int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0076-nozzle-cleanup-nozzle_open-coding-style-and-return-c.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0076-nozzle-cleanup-nozzle_open-coding-style-and-return-c.patch
new file mode 100644
index 000000000..71da3e32f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0076-nozzle-cleanup-nozzle_open-coding-style-and-return-c.patch
@@ -0,0 +1,246 @@ 
+From 248c1fdc77a4059a137f07979f10be4563cdf0fa Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 15:21:07 +0100
+Subject: [PATCH] [nozzle] cleanup nozzle_open coding style and return codes
+
+also update the header file for Doxygen man pages
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 77 +++++++++++++++++++++++++++----------------
+ libnozzle/libnozzle.h | 31 ++++++++++++++++-
+ 2 files changed, 78 insertions(+), 30 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 48e4ca23..e3a8ea2e 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -384,9 +384,10 @@ nozzle_t nozzle_find(char *dev, size_t dev_size)
+ 	return nozzle;
+ }
+ 
+-nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
++nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ {
+-	nozzle_t nozzle;
++	int savederrno = 0;
++	nozzle_t nozzle = NULL;
+ 	char *temp_mac = NULL;
+ #ifdef KNET_BSD
+ 	uint16_t i;
+@@ -394,17 +395,17 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ 	char curnozzle[IFNAMSIZ];
+ #endif
+ 
+-	if (dev == NULL) {
++	if (devname == NULL) {
+ 		errno = EINVAL;
+ 		return NULL;
+ 	}
+ 
+-	if (dev_size < IFNAMSIZ) {
++	if (devname_size < IFNAMSIZ) {
+ 		errno = EINVAL;
+ 		return NULL;
+ 	}
+ 
+-	if (strlen(dev) > IFNAMSIZ) {
++	if (strlen(devname) > IFNAMSIZ) {
+ 		errno = E2BIG;
+ 		return NULL;
+ 	}
+@@ -415,13 +416,13 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ 	 * but it is possible to force a nozzleX device number
+ 	 * where X is 0 to 255.
+ 	 */
+-	if (strlen(dev)) {
+-		if (strncmp(dev, "tap", 3)) {
++	if (strlen(devname)) {
++		if (strncmp(devname, "tap", 3)) {
+ 			errno = EINVAL;
+ 			return NULL;
+ 		}
+ 		errno = 0;
+-		nozzlenum = strtol(dev+3, NULL, 10);
++		nozzlenum = strtol(devname+3, NULL, 10);
+ 		if (errno) {
+ 			errno = EINVAL;
+ 			return NULL;
+@@ -440,21 +441,18 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ 			return NULL;
+ 		}
+ 		/* 14: 2 for /, 1 for \0 + 11 (post-down.d) */
+-		if (strlen(updownpath) >= (PATH_MAX - (strlen(dev) + 14))) {
++		if (strlen(updownpath) >= (PATH_MAX - (strlen(devname) + 14))) {
+ 			errno = E2BIG;
+ 			return NULL;
+ 		}
+ 	}
+ 
+-	nozzle = malloc(sizeof(struct nozzle_iface));
+-	if (!nozzle) {
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
+ 		return NULL;
+ 	}
+ 
+-	memset(nozzle, 0, sizeof(struct nozzle_iface));
+-
+-	pthread_mutex_lock(&lib_mutex);
+-
+ 	if (!lib_init) {
+ 		lib_cfg.head = NULL;
+ #ifdef KNET_LINUX
+@@ -463,61 +461,80 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ #ifdef KNET_BSD
+ 		lib_cfg.sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ #endif
+-		if (lib_cfg.sockfd < 0)
++		if (lib_cfg.sockfd < 0) {
++			savederrno = errno;
+ 			goto out_error;
++		}
+ 		lib_init = 1;
+ 	}
+ 
++	nozzle = malloc(sizeof(struct nozzle_iface));
++	if (!nozzle) {
++		savederrno = ENOMEM;
++		goto out_error;
++	}
++
++	memset(nozzle, 0, sizeof(struct nozzle_iface));
+ 
+ #ifdef KNET_BSD
+-	if (!strlen(dev)) {
++	if (!strlen(devname)) {
+ 		for (i = 0; i < 256; i++) {
+-			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/nozzle%u", i);
++			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
+ 			nozzle->fd = open(curnozzle, O_RDWR);
++			savederrno = errno;
+ 			if (nozzle->fd > 0) {
+ 				break;
+ 			}
+ 		}
+-		snprintf(curnozzle, sizeof(curnozzle) -1 , "nozzle%u", i);
++		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
+ 	} else {
+-		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", dev);
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
+ 		nozzle->fd = open(curnozzle, O_RDWR);
+-		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", dev);
++		savederrno = errno;
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
+ 	}
+ 	if (nozzle->fd < 0) {
+ 		errno = EBUSY;
+ 		goto out_error;
+ 	}
+-	strncpy(dev, curnozzle, IFNAMSIZ);
++	strncpy(devname, curnozzle, IFNAMSIZ);
+ 	strncpy(nozzle->nozzlename, curnozzle, IFNAMSIZ);
+ #endif
+ 
+ #ifdef KNET_LINUX
+-	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0)
++	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
++		savederrno = errno;
+ 		goto out_error;
++	}
+ 
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, dev, IFNAMSIZ);
++	strncpy(nozzle->ifname, devname, IFNAMSIZ);
+ 	nozzle->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ 
+-	if (ioctl(nozzle->fd, TUNSETIFF, &nozzle->ifr) < 0)
++	if (ioctl(nozzle->fd, TUNSETIFF, &nozzle->ifr) < 0) {
++		savederrno = errno;
+ 		goto out_error;
++	}
+ 
+-	if ((strlen(dev) > 0) && (strcmp(dev, nozzle->ifname) != 0)) {
++	if ((strlen(devname) > 0) && (strcmp(devname, nozzle->ifname) != 0)) {
+ 		errno = EBUSY;
+ 		goto out_error;
+ 	}
+ 
+-	strncpy(dev, nozzle->ifname, IFNAMSIZ);
++	strncpy(devname, nozzle->ifname, IFNAMSIZ);
+ 	strncpy(nozzle->nozzlename, nozzle->ifname, IFNAMSIZ);
+ #endif
+ 
+ 	nozzle->default_mtu = _get_mtu(nozzle);
+-	if (nozzle->default_mtu < 0)
++	if (nozzle->default_mtu < 0) {
++		savederrno = errno;
+ 		goto out_error;
++	}
+ 
+-	if (_get_mac(nozzle, &temp_mac) < 0)
++	if (_get_mac(nozzle, &temp_mac) < 0) {
++		savederrno = errno;
+ 		goto out_error;
++	}
+ 
+ 	strncpy(nozzle->default_mac, temp_mac, 18);
+ 	free(temp_mac);
+@@ -536,12 +553,14 @@ nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath)
+ 	lib_cfg.head = nozzle;
+ 
+ 	pthread_mutex_unlock(&lib_mutex);
++	errno = savederrno;
+ 	return nozzle;
+ 
+ out_error:
+ 	_close(nozzle);
+ 	_close_cfg();
+ 	pthread_mutex_unlock(&lib_mutex);
++	errno = savederrno;
+ 	return NULL;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 6f05491f..4b3da214 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -23,7 +23,36 @@
+ 
+ typedef struct nozzle_iface *nozzle_t;
+ 
+-nozzle_t nozzle_open(char *dev, size_t dev_size, const char *updownpath);
++/**
++ * nozzle_open
++ * @brief create a new tap device on the system.
++ *
++ * devname - pointer to device name of at least size IFNAMSIZ.
++ *           if the dev strlen is 0, then the system will assign a name automatically.
++ *           if a string is specified, the system will try to create a device with
++ *           the specified name.
++ *           NOTE: on FreeBSD the tap device names can only be tapX where X is a
++ *           number from 0 to 255. On Linux such limitation does not apply.
++ *           The name must be unique to the system. If an interface with the same
++ *           name is already configured on the system, an error will be returned.
++ *
++ * devname_size - lenght of the buffer provided in dev (has to be at least IFNAMSIZ).
++ *
++ * updownpath - nozzle supports the typical filesystem structure to execute
++ *              actions for: down.d  post-down.d  pre-up.d  up.d
++ *              in the form of:
++ *              updownpath/<action>/<interface_name>
++ *              updownpath specifies where to find those directories on the
++ *              filesystem and it must be an absolute path.
++ *
++ * @return
++ * nozzle_open returns
++ * a pointer to a nozzle struct on success
++ * NULL on error and errno is set.
++ */
++
++nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath);
++
+ int nozzle_close(nozzle_t nozzle);
+ 
+ nozzle_t nozzle_find(char *dev, size_t dev_size);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0077-nozzle-start-to-cleanup-nozzle_close-to-be-more-info.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0077-nozzle-start-to-cleanup-nozzle_close-to-be-more-info.patch
new file mode 100644
index 000000000..22d807cdc
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0077-nozzle-start-to-cleanup-nozzle_close-to-be-more-info.patch
@@ -0,0 +1,420 @@ 
+From 4b3eed88405d11ba045d4ff06192f0140406d3f6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 15:51:18 +0100
+Subject: [PATCH] [nozzle] start to cleanup nozzle_close to be more informative
+ and effective
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 207 +++++++++++++++++++++++++++++++++++-------
+ libnozzle/libnozzle.h |  24 ++++-
+ 2 files changed, 197 insertions(+), 34 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index e3a8ea2e..b5bb82c0 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -564,20 +564,22 @@ out_error:
+ 	return NULL;
+ }
+ 
+-// TODO: consider better error report from here
+-int nozzle_close(nozzle_t nozzle)
++int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ {
+-	int err = 0;
++	int err = 0, savederrno = 0;
+ 	nozzle_t temp = lib_cfg.head;
+ 	nozzle_t prev = lib_cfg.head;
+ 	struct _ip *ip, *ip_next;
+ 	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+ 	if (!_check(nozzle)) {
+-		errno = EINVAL;
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -593,11 +595,7 @@ int nozzle_close(nozzle_t nozzle)
+ 		prev->next = nozzle->next;
+ 	}
+ 
+-	_set_down(nozzle, &error_down, &error_postdown);
+-	if (error_down)
+-		free(error_down);
+-	if (error_postdown)
+-		free(error_postdown);
++	_set_down(nozzle, error_down, error_postdown);
+ 
+ 	ip = nozzle->ip;
+ 	while (ip) {
+@@ -616,7 +614,7 @@ int nozzle_close(nozzle_t nozzle)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+@@ -1194,6 +1192,7 @@ static int is_if_in_system(char *name)
+ static int test_iface(char *name, size_t size, const char *updownpath)
+ {
+ 	nozzle_t nozzle;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	nozzle=nozzle_open(name, size, updownpath);
+ 	if (!nozzle) {
+@@ -1216,7 +1215,17 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 		printf("Found interface %s in nozzle db\n", name);
+ 	}
+ 
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++
++	if (error_down) {
++		printf("Error from error_down: %s\n", error_down);
++		free(error_down);
++	}
++
++	if (error_postdown) {
++		printf("Error from error_down: %s\n", error_postdown);
++		free(error_postdown);
++	}
+ 
+ 	if (is_if_in_system(name) == 0)
+ 		printf("Successfully removed interface %s from the system\n", name);
+@@ -1318,6 +1327,7 @@ static int check_knet_multi_eth(void)
+ 	int err=0;
+ 	nozzle_t nozzle1 = NULL;
+ 	nozzle_t nozzle2 = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing multiple knet interface instances\n");
+ 
+@@ -1350,10 +1360,29 @@ static int check_knet_multi_eth(void)
+ 		printf("Unable to find interface %s on the system\n", device_name2);
+ 	}
+ 
+-	if (nozzle1)
+-		nozzle_close(nozzle1);
+-	if (nozzle2)
+-		nozzle_close(nozzle2);
++	if (nozzle1) {
++		nozzle_close(nozzle1, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	if (nozzle2) {
++		nozzle_close(nozzle2, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
+ 
+ 	printf("Testing error conditions\n");
+ 
+@@ -1382,10 +1411,30 @@ static int check_knet_multi_eth(void)
+ 	}
+ 
+ out_clean:
+-	if (nozzle1)
+-		nozzle_close(nozzle1);
+-	if (nozzle2)
+-		nozzle_close(nozzle2);
++	if (nozzle1) {
++		nozzle_close(nozzle1, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	if (nozzle2) {
++		nozzle_close(nozzle2, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
+ 	return err;
+ }
+ 
+@@ -1395,6 +1444,7 @@ static int check_knet_mtu(void)
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+ 	nozzle_t nozzle;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	int current_mtu = 0;
+ 	int expected_mtu = 1500;
+@@ -1458,7 +1508,17 @@ static int check_knet_mtu(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(nozzle);
++	if (nozzle) {
++		nozzle_close(nozzle, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
+ 
+ 	return err;
+ }
+@@ -1471,6 +1531,7 @@ static int check_knet_mtu_ipv6(void)
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_string = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing get/set MTU with IPv6 address\n");
+ 
+@@ -1622,7 +1683,17 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(nozzle);
++	if (nozzle) {
++		nozzle_close(nozzle, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
+ 
+ 	return err;
+ }
+@@ -1635,6 +1706,7 @@ static int check_knet_mac(void)
+ 	nozzle_t nozzle;
+ 	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
+ 	struct ether_addr *cur_mac, *tmp_mac;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing get/set MAC\n");
+ 
+@@ -1728,7 +1800,17 @@ out_clean:
+ 	if (temp_mac)
+ 		free(temp_mac);
+ 
+-	nozzle_close(nozzle);
++	if (nozzle) {
++		nozzle_close(nozzle, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
+ 
+ 	return err;
+ }
+@@ -1925,7 +2007,17 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+ 
+@@ -1974,7 +2066,17 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	printf("Testing interface pre-up/up/down/post-down\n");
+ 
+@@ -2024,7 +2126,17 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	printf("Test ERROR conditions\n");
+ 
+@@ -2077,8 +2189,17 @@ static int check_knet_up_down(void)
+ 	}
+ 
+ out_clean:
+-
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	return err;
+ }
+@@ -2090,6 +2211,7 @@ static int check_knet_close_leak(void)
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_string = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing close leak (needs valgrind)\n");
+ 
+@@ -2130,8 +2252,17 @@ static int check_knet_close_leak(void)
+ 	}
+ 
+ out_clean:
+-
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	return err;
+ }
+@@ -2146,6 +2277,7 @@ static int check_knet_set_del_ip(void)
+ 	char *ip_list = NULL;
+ 	int ip_list_entries = 0, i, offset = 0;
+ 	char *error_string = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing interface add/remove ip\n");
+ 
+@@ -2374,8 +2506,17 @@ static int check_knet_set_del_ip(void)
+ 	}
+ 
+ out_clean:
+-
+-	nozzle_close(nozzle);
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	return err;
+ }
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 4b3da214..1447778d 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -53,7 +53,29 @@ typedef struct nozzle_iface *nozzle_t;
+ 
+ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath);
+ 
+-int nozzle_close(nozzle_t nozzle);
++/**
++ * nozzle_close
++ * @brief deconfigure and destroy a nozzle device
++ *
++ * nozzle - pointer to the nozzle struct to destroy
++ *
++ * error_down - pointers to string to record errors from executing down.d
++ *              when configured. The string is malloc'ed, the caller needs to free those
++ *              buffers.
++ *
++ * error_postdown - pointers to string to record errors from executing post-down.d
++ *                  when configured. The string is malloc'ed, the caller needs to free
++ *                  those buffers.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and error is set.
++ * error_down / error_postdown are set to NULL if execution of external scripts
++ * is sucessful
++ * error_down / error_postdown will contain strings recording the execution error.
++ */
++
++int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
+ nozzle_t nozzle_find(char *dev, size_t dev_size);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0078-nozzle-cleanup-and-document-nozzle_set_up.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0078-nozzle-cleanup-and-document-nozzle_set_up.patch
new file mode 100644
index 000000000..72238eca3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0078-nozzle-cleanup-and-document-nozzle_set_up.patch
@@ -0,0 +1,133 @@ 
+From a13796b6ff8eec163fecede537d4bbdb619db7f4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 16:18:08 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_set_up
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 36 +++++++++++++++++++++++++-----------
+ libnozzle/libnozzle.h | 28 +++++++++++++++++++++++++---
+ 2 files changed, 50 insertions(+), 14 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index b5bb82c0..7afb1a36 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -751,46 +751,60 @@ int nozzle_reset_mac(nozzle_t nozzle)
+ 
+ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ {
+-	int err = 0;
++	int err = 0, savederrno = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+ 	if (!_check(nozzle)) {
+-		errno = EINVAL;
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	if ((nozzle->hasupdown) && ((!error_preup) || (!error_up))) {
+-		errno = EINVAL;
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+-	if (nozzle->up)
++	if (nozzle->up) {
+ 		goto out_clean;
++	}
+ 
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err=ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
+-	if (err)
++	err = ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	_exec_updown(nozzle, "pre-up.d", error_preup);
+ 
+ 	nozzle->ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+-	err=ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
+-
+-	if (err)
++	err = ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	_exec_updown(nozzle, "up.d", error_up);
+ 
+ 	nozzle->up = 1;
++
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 1447778d..1f2a3ee3 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -77,6 +77,31 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 
+ int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
++/**
++ * nozzle_set_up
++ * @brief equivalent of ifconfig up, executes pre-up.d up.d if configured
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * error_preup - pointers to string to record errors from executing pre-up.d
++ *               when configured. The string is malloc'ed, the caller needs to free those
++ *               buffers.
++ *
++ * error_up - pointers to string to record errors from executing up.d
++ *            when configured. The string is malloc'ed, the caller needs to free those
++ *            buffers.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and error is set.
++ * error_preup / error_up are set to NULL if execution of external scripts
++ * is sucessful
++ * error_preup / error_up will contain strings recording the execution error.
++ */
++
++int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
++int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
++
+ nozzle_t nozzle_find(char *dev, size_t dev_size);
+ 
+ int nozzle_get_fd(const nozzle_t nozzle);
+@@ -91,9 +116,6 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
+ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+-int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
+-int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+-
+ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0079-nozzle-cleanup-and-document-nozzle_set_down.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0079-nozzle-cleanup-and-document-nozzle_set_down.patch
new file mode 100644
index 000000000..c945c1cdf
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0079-nozzle-cleanup-and-document-nozzle_set_down.patch
@@ -0,0 +1,134 @@ 
+From 109041bd8fba661bb190081c693f52dd5d8933e6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 16:23:09 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_set_down
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 38 +++++++++++++++++++++++++++-----------
+ libnozzle/libnozzle.h | 23 +++++++++++++++++++++++
+ 2 files changed, 50 insertions(+), 11 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 7afb1a36..93c678d7 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -810,57 +810,73 @@ out_clean:
+ 
+ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+-	int err = 0;
++	int err = 0, savederrno = 0;
+ 
+-	if (!nozzle->up)
++	if (!nozzle->up) {
+ 		goto out_clean;
++	}
+ 
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err=ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
+-	if (err)
++	err = ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	_exec_updown(nozzle, "down.d", error_down);
+ 
+ 	nozzle->ifr.ifr_flags &= ~IFF_UP;
+-	err=ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
+ 
+-	if (err)
++	err = ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	_exec_updown(nozzle, "post-down.d", error_postdown);
+ 
+ 	nozzle->up = 0;
+ 
+ out_clean:
++	errno = savederrno;
+ 	return err;
+ }
+ 
+ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+-	int err = 0;
++	int err = 0, savederrno = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+ 	if (!_check(nozzle)) {
+-		errno = EINVAL;
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	if ((nozzle->hasupdown) && ((!error_down) || (!error_postdown))) {
+-		errno = EINVAL;
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	err = _set_down(nozzle, error_down, error_postdown);
++	savederrno = errno;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 1f2a3ee3..42dfa354 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -100,6 +100,29 @@ int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
+  */
+ 
+ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
++
++/**
++ * nozzle_set_down
++ * @brief equivalent of ifconfig down, executes down.d post-down.d
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * error_down - pointers to string to record errors from executing down.d
++ *              when configured. The string is malloc'ed, the caller needs to free those
++ *              buffers.
++ *
++ * error_postdown - pointers to string to record errors from executing post-down.d
++ *                  when configured. The string is malloc'ed, the caller needs to free
++ *                  those buffers.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and error is set.
++ * error_down / error_postdown are set to NULL if execution of external scripts
++ * is sucessful
++ * error_down / error_postdown will contain strings recording the execution error.
++ */
++
+ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
+ nozzle_t nozzle_find(char *dev, size_t dev_size);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0080-nozzle-re-order-functions-in-order-of-importance.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0080-nozzle-re-order-functions-in-order-of-importance.patch
new file mode 100644
index 000000000..e7b1ca4b8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0080-nozzle-re-order-functions-in-order-of-importance.patch
@@ -0,0 +1,41 @@ 
+From a90da621728cb317454cdef1e5b3c7021139322b Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 16:28:52 +0100
+Subject: [PATCH] [nozzle] re-order functions in order of importance
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.h | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 42dfa354..a57915a7 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -125,11 +125,9 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
+ 
+ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
+-nozzle_t nozzle_find(char *dev, size_t dev_size);
+-
+-int nozzle_get_fd(const nozzle_t nozzle);
+-
+-const char *nozzle_get_name(const nozzle_t nozzle);
++int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
+ 
+ int nozzle_get_mtu(const nozzle_t nozzle);
+ int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
+@@ -139,8 +137,8 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
+ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+-int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+-int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+-int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
++nozzle_t nozzle_find(char *dev, size_t dev_size);
++int nozzle_get_fd(const nozzle_t nozzle);
++const char *nozzle_get_name(const nozzle_t nozzle);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0081-nozzle-cleanup-and-document-nozzle_add_ip.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0081-nozzle-cleanup-and-document-nozzle_add_ip.patch
new file mode 100644
index 000000000..b3763947a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0081-nozzle-cleanup-and-document-nozzle_add_ip.patch
@@ -0,0 +1,111 @@ 
+From 4391d34e60bb5d1ddf76b4d972a1b942954075f8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 16:52:35 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_add_ip
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 24 +++++++++++++++++++-----
+ libnozzle/libnozzle.h | 23 +++++++++++++++++++++++
+ 2 files changed, 42 insertions(+), 5 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 93c678d7..f3bec3af 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1000,27 +1000,40 @@ static int _find_ip(nozzle_t nozzle,
+ 
+ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string)
+ {
+-	int err = 0, found;
++	int err = 0, savederrno = 0;
++	int found = 0;
+ 	struct _ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+ 	int secondary = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if ((!nozzle) || (!ip_addr) || (!prefix) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
+ 
+-	if ((!_check(nozzle)) || (!ip_addr) || (!prefix) || (!error_string)) {
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	found = _find_ip(nozzle, ip_addr, prefix, &ip, &ip_prev);
+-	if (found)
++	if (found) {
+ 		goto out_clean;
++	}
+ 
+ 	ip = malloc(sizeof(struct _ip));
+ 	if (!ip) {
++		savederrno = errno;
+ 		err = -1 ;
+ 		goto out_clean;
+ 	}
++
+ 	memset(ip, 0, sizeof(struct _ip));
+ 	strncpy(ip->ip_addr, ip_addr, MAX_IP_CHAR);
+ 	strncpy(ip->prefix, prefix, MAX_PREFIX_CHAR);
+@@ -1041,6 +1054,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 			secondary = 1;
+ 		}
+ 		err = _set_ip(nozzle, "add", ip_addr, prefix, error_string, secondary);
++		savederrno = errno;
+ 	}
+ 
+ 	if (err) {
+@@ -1060,7 +1074,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index a57915a7..ecf242dd 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -125,6 +125,29 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
+ 
+ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
++/**
++ * nozzle_add_ip
++ * @brief equivalent of ip addr or ifconfig <ipaddress/prefix>
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * ip_addr - string containing either an IPv4 or an IPv6 address.
++ *           Please note that Linux will automatically remove any IPv6 addresses from an interface
++ *           with MTU < 1280. libnozzle will cache those IPs and re-instate them when MTU is > 1280.
++ *           MTU must be set via nozzle_set_mtu for IPv6 to be re-instated.
++ *
++ * prefix - 24, 64 or any valid network prefix for the requested address.
++ *
++ * error_string - pointers to string to record errors from ipaddr2 (Linux) or ifconfig (BSD).
++ *                The string is malloc'ed, the caller needs to free this buffer.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and error is set.
++ *  error_string is set to NULL on success
++ *  error_string will contain a string recording the execution error.
++ */
++
+ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0082-nozzle-cleanup-and-document-nozzle_del_ip.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0082-nozzle-cleanup-and-document-nozzle_del_ip.patch
new file mode 100644
index 000000000..f0ea452de
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0082-nozzle-cleanup-and-document-nozzle_del_ip.patch
@@ -0,0 +1,96 @@ 
+From 7d5e7bfae378c609e20065a446be8f0b7da3e083 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 17:04:36 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_del_ip
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 23 +++++++++++++++++------
+ libnozzle/libnozzle.h | 21 +++++++++++++++++++++
+ 2 files changed, 38 insertions(+), 6 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index f3bec3af..98b13f1e 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1080,23 +1080,34 @@ out_clean:
+ 
+ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string)
+ {
+-	int err = 0, found;
++	int err = 0, savederrno = 0;
++        int found = 0;
+ 	struct _ip *ip = NULL, *ip_prev = NULL;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if ((!nozzle) || (!ip_addr) || (!prefix) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+-	if ((!_check(nozzle)) || (!ip_addr) || (!prefix) || (!error_string)) {
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	found = _find_ip(nozzle, ip_addr, prefix, &ip, &ip_prev);
+-	if (!found)
++	if (!found) {
+ 		goto out_clean;
++	}
+ 
+ 	err = _set_ip(nozzle, "del", ip_addr, prefix, error_string, 0);
+-
++	savederrno = errno;
+ 	if (!err) {
+ 		if (ip == ip_prev) {
+ 			nozzle->ip = ip->next;
+@@ -1108,7 +1119,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index ecf242dd..dccc1f0b 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -149,6 +149,27 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+  */
+ 
+ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++
++/**
++ * nozzle_del_ip
++ * @brief equivalent of ip addr del or ifconfig del <ipaddress/prefix>
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * ip_addr - string containing either an IPv4 or an IPv6 address.
++ *
++ * prefix - 24, 64 or any valid network prefix for the requested address.
++ *
++ * error_string - pointers to string to record errors from ipaddr2 (Linux) or ifconfig (BSD).
++ *                The string is malloc'ed, the caller needs to free this buffer.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and error is set.
++ *  error_string is set to NULL on success
++ *  error_string will contain a string recording the execution error.
++ */
++
+ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
+ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0083-nozzle-cleanup-and-document-nozzle_get_ips-part-1.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0083-nozzle-cleanup-and-document-nozzle_get_ips-part-1.patch
new file mode 100644
index 000000000..1f60990fe
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0083-nozzle-cleanup-and-document-nozzle_get_ips-part-1.patch
@@ -0,0 +1,149 @@ 
+From a0e3c5cc24122d295b2a2cdc448908bceb1fa717 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 17:18:04 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_get_ips (part 1)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 32 ++++++++++++++++++++++++++++----
+ libnozzle/libnozzle.h | 31 ++++++++++++++++++++++++++-----
+ 2 files changed, 54 insertions(+), 9 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 98b13f1e..045cdc76 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1164,22 +1164,46 @@ out_clean:
+ 
+ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ {
+-	int err = 0;
++	int err = 0, savederrno = 0;
+ 	int found = 0;
+ 	char *ip_list = NULL;
+ 	int size = 0, offset = 0, len;
+-	struct _ip *ip = nozzle->ip;
++	struct _ip *ip = NULL;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if ((!nozzle) || (!ip_addr_list) || (!entries)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		goto out_clean;
++	}
++
++	ip = nozzle->ip;
+ 
+ 	while (ip) {
+ 		found++;
+ 		ip = ip->next;
+ 	}
+ 
++	if (!found) {
++		*ip_addr_list = NULL;
++		*entries = 0;
++		goto out_clean;
++	}
++
+ 	size = found * (MAX_IP_CHAR + MAX_PREFIX_CHAR + 2);
++
+ 	ip_list = malloc(size);
+ 	if (!ip_list) {
++		savederrno = errno;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -1203,7 +1227,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index dccc1f0b..4e827077 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -69,7 +69,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+  *
+  * @return
+  * 0 on success
+- * -1 on error and error is set.
++ * -1 on error and errno is set.
+  * error_down / error_postdown are set to NULL if execution of external scripts
+  * is sucessful
+  * error_down / error_postdown will contain strings recording the execution error.
+@@ -93,7 +93,7 @@ int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
+  *
+  * @return
+  * 0 on success
+- * -1 on error and error is set.
++ * -1 on error and errno is set.
+  * error_preup / error_up are set to NULL if execution of external scripts
+  * is sucessful
+  * error_preup / error_up will contain strings recording the execution error.
+@@ -117,7 +117,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
+  *
+  * @return
+  * 0 on success
+- * -1 on error and error is set.
++ * -1 on error and errno is set.
+  * error_down / error_postdown are set to NULL if execution of external scripts
+  * is sucessful
+  * error_down / error_postdown will contain strings recording the execution error.
+@@ -143,7 +143,7 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+  *
+  * @return
+  * 0 on success
+- * -1 on error and error is set.
++ * -1 on error and errno is set.
+  *  error_string is set to NULL on success
+  *  error_string will contain a string recording the execution error.
+  */
+@@ -165,12 +165,33 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+  *
+  * @return
+  * 0 on success
+- * -1 on error and error is set.
++ * -1 on error and errno is set.
+  *  error_string is set to NULL on success
+  *  error_string will contain a string recording the execution error.
+  */
+ 
+ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++
++/**
++ * nozzle_get_ips
++ * @brief retrive the list of all configured ips for a given interface
++ *
++ * TODO: change to use a ip_addr_list struct!
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * ip_addr_list - list of strings containing either an IPv4 or an IPv6 address and their prefixes.
++ *
++ * entries - entries recorded.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and errno is set.
++ * ip_addr_list is a malloc'ed buffer that the user needs to parse and free after use. ip_addr_list can
++ * be NULL if entries is 0.
++ *
++ */
++
+ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
+ 
+ int nozzle_get_mtu(const nozzle_t nozzle);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0084-nozzle-fix-test-on-BSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0084-nozzle-fix-test-on-BSD.patch
new file mode 100644
index 000000000..ea7a5c99f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0084-nozzle-fix-test-on-BSD.patch
@@ -0,0 +1,28 @@ 
+From c67dd1769d1a81a23b8ee632dbd998dc3eeda7bb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 17:25:16 +0100
+Subject: [PATCH] [nozzle] fix test on BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 045cdc76..909b0361 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1335,10 +1335,10 @@ static int check_nozzle_open_close(void)
+ 	}
+ #endif
+ #ifdef KNET_BSD
+-	printf("Creating nozzle%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "nozzle%u", randombyte);
++	printf("Creating tap%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
+ 	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create nozzle%u interface\n", randombyte);
++		printf("Unable to create tap%u interface\n", randombyte);
+ 		return -1;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0085-nozzle-cleanup-and-document-nozzle_get_mtu.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0085-nozzle-cleanup-and-document-nozzle_get_mtu.patch
new file mode 100644
index 000000000..009781164
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0085-nozzle-cleanup-and-document-nozzle_get_mtu.patch
@@ -0,0 +1,95 @@ 
+From 1b5353bcdb42c398d02ed347b81661f4439deb4c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 17:40:20 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_get_mtu
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 23 ++++++++++++++++++-----
+ libnozzle/libnozzle.h | 11 +++++++++++
+ 2 files changed, 29 insertions(+), 5 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 909b0361..bba6a2e6 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -276,18 +276,21 @@ static void _close_cfg(void)
+ 
+ static int _get_mtu(const nozzle_t nozzle)
+ {
+-	int err;
++	int err = 0, savederrno = 0;
+ 
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+ 	err = ioctl(lib_cfg.sockfd, SIOCGIFMTU, &nozzle->ifr);
+-	if (err)
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	err = nozzle->ifr.ifr_mtu;
+ 
+ out_clean:
++	errno = savederrno;
+ 	return err;
+ }
+ 
+@@ -620,9 +623,18 @@ out_clean:
+ 
+ int nozzle_get_mtu(const nozzle_t nozzle)
+ {
+-	int err;
++	int err = 0, savederrno = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+ 	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+@@ -631,10 +643,11 @@ int nozzle_get_mtu(const nozzle_t nozzle)
+ 	}
+ 
+ 	err = _get_mtu(nozzle);
++	savederrno = errno;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	savederrno = errno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 4e827077..b391e452 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -194,6 +194,17 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 
+ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
+ 
++/**
++ * nozzle_get_mtu
++ * @brief retrive mtu on a given nozzle interface
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * @return
++ * MTU on success
++ * -1 on error and errno is set.
++ */
++
+ int nozzle_get_mtu(const nozzle_t nozzle);
+ int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
+ int nozzle_reset_mtu(nozzle_t nozzle);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0086-nozzle-cleanup-and-document-nozzle_set_mtu-and-nozzl.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0086-nozzle-cleanup-and-document-nozzle_set_mtu-and-nozzl.patch
new file mode 100644
index 000000000..cf6a10ef1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0086-nozzle-cleanup-and-document-nozzle_set_mtu-and-nozzl.patch
@@ -0,0 +1,213 @@ 
+From 30dd6b79ace7d0e9a2c586e6ae226ef602b12be9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 16 Nov 2017 18:02:08 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_set_mtu and
+ nozzle_reset_mtu
+
+couldn't split those 2 because they are stricly related
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 66 ++++++++++++++++++++++++++++++++-----------
+ libnozzle/libnozzle.h | 42 +++++++++++++++++++++++++--
+ 2 files changed, 89 insertions(+), 19 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index bba6a2e6..1a5e82f0 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -651,13 +651,21 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ {
++	int err = 0, savederrno = 0;
+ 	struct _ip *tmp_ip;
+-	char *error_string = NULL;
+-	int err;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if ((!nozzle) || (!mtu) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+ 	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+@@ -666,21 +674,28 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
+ 	}
+ 
+ 	err = nozzle->current_mtu = _get_mtu(nozzle);
+-	if (err < 0)
++	if (err < 0) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	nozzle->ifr.ifr_mtu = mtu;
+ 
+ 	err = ioctl(lib_cfg.sockfd, SIOCSIFMTU, &nozzle->ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
+ 
+-	if ((!err) && (nozzle->current_mtu < 1280) && (mtu >= 1280)) {
++	if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
+ 		tmp_ip = nozzle->ip;
+ 		while(tmp_ip) {
+ 			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(nozzle, "add", tmp_ip->ip_addr, tmp_ip->prefix, &error_string, 0);
+-				if (error_string) {
+-					free(error_string);
+-					error_string = NULL;
++				err = _set_ip(nozzle, "add", tmp_ip->ip_addr, tmp_ip->prefix, error_string, 0);
++				if (err) {
++					savederrno = errno;
++					err = -1;
++					goto out_clean;
+ 				}
+ 			}
+ 			tmp_ip = tmp_ip->next;
+@@ -689,13 +704,13 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+-int nozzle_reset_mtu(nozzle_t nozzle)
++int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ {
+-	return nozzle_set_mtu(nozzle, nozzle->default_mtu);
++	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+ }
+ 
+ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+@@ -1537,6 +1552,7 @@ static int check_knet_mtu(void)
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_down = NULL, *error_postdown = NULL;
++	char *error_string = NULL;
+ 
+ 	int current_mtu = 0;
+ 	int expected_mtu = 1500;
+@@ -1565,8 +1581,12 @@ static int check_knet_mtu(void)
+ 
+ 	printf("Setting MTU to 9000\n");
+ 	expected_mtu = 9000;
+-	if (nozzle_set_mtu(nozzle, expected_mtu) < 0) {
++	if (nozzle_set_mtu(nozzle, expected_mtu, &error_string) < 0) {
+ 		printf("Unable to set MTU to %d\n", expected_mtu);
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -1593,8 +1613,12 @@ static int check_knet_mtu(void)
+ 	}
+ 
+ 	printf("Passing empty struct to set_mtu\n");
+-	if (nozzle_set_mtu(NULL, 1500) == 0) {
++	if (nozzle_set_mtu(NULL, 1500, &error_string) == 0) {
+ 		printf("Something is wrong in nozzle_set_mtu sanity checks\n"); 
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -1671,8 +1695,12 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Setting MTU to 1200\n");
+-	if (nozzle_set_mtu(nozzle, 1200) < 0) {
++	if (nozzle_set_mtu(nozzle, 1200, &error_string) < 0) {
+ 		printf("Unable to set MTU to 1200\n");
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -1728,8 +1756,12 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Restoring MTU to default\n");
+-	if (nozzle_reset_mtu(nozzle) < 0) {
++	if (nozzle_reset_mtu(nozzle, &error_string) < 0) {
+ 		printf("Unable to reset mtu\n");
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index b391e452..d653d6d7 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -206,8 +206,46 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
+  */
+ 
+ int nozzle_get_mtu(const nozzle_t nozzle);
+-int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
+-int nozzle_reset_mtu(nozzle_t nozzle);
++
++/**
++ * nozzle_set_mtu
++ * @brief set mtu on a given nozzle interface
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * mtu - new MTU value
++ *
++ * error_string - pointer to string to record errors from ipaddr2 (Linux) or ifconfig (BSD)
++ *                when re-instanting IPv6 address if MTU is becoming again > 1280.
++ *                The string is malloc'ed, the caller needs to free this buffer.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and errno is set.
++ * error_string is set to NULL on success
++ * error_string will contain a string recording the execution error.
++ */
++
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string);
++
++/**
++ * nozzle_reset_mtu
++ * @brief reset mtu on a given nozzle interface to the system default
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * error_string - pointer to string to record errors from ipaddr2 (Linux) or ifconfig (BSD)
++ *                when re-instanting IPv6 address if MTU is becoming again > 1280.
++ *                The string is malloc'ed, the caller needs to free this buffer.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and errno is set.
++ * error_string is set to NULL on success
++ * error_string will contain a string recording the execution error.
++ */
++
++int nozzle_reset_mtu(nozzle_t nozzle, char **error_string);
+ 
+ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0087-Tidy-some-English.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0087-Tidy-some-English.patch
new file mode 100644
index 000000000..e1c261c1e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0087-Tidy-some-English.patch
@@ -0,0 +1,61 @@ 
+From e9700f632be82e7da3c299a280fc570b7c1fd156 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 17 Nov 2017 14:41:07 +0000
+Subject: [PATCH] Tidy some English
+
+---
+ libnozzle/libnozzle.h | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index d653d6d7..f1e53671 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -36,7 +36,7 @@ typedef struct nozzle_iface *nozzle_t;
+  *           The name must be unique to the system. If an interface with the same
+  *           name is already configured on the system, an error will be returned.
+  *
+- * devname_size - lenght of the buffer provided in dev (has to be at least IFNAMSIZ).
++ * devname_size - length of the buffer provided in dev (has to be at least IFNAMSIZ).
+  *
+  * updownpath - nozzle supports the typical filesystem structure to execute
+  *              actions for: down.d  post-down.d  pre-up.d  up.d
+@@ -83,13 +83,13 @@ int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * error_preup - pointers to string to record errors from executing pre-up.d
+- *               when configured. The string is malloc'ed, the caller needs to free those
+- *               buffers.
++ * error_preup - pointer to string pointer to record errors from executing pre-up.d
++ *               when configured. The string is malloc'ed, the caller needs to free that
++ *               buffer.
+  *
+- * error_up - pointers to string to record errors from executing up.d
+- *            when configured. The string is malloc'ed, the caller needs to free those
+- *            buffers.
++ * error_up - pointer to string pointer to record errors from executing up.d
++ *            when configured. The string is malloc'ed, the caller needs to free that
++ *            buffer.
+  *
+  * @return
+  * 0 on success
+@@ -107,13 +107,13 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * error_down - pointers to string to record errors from executing down.d
+- *              when configured. The string is malloc'ed, the caller needs to free those
+- *              buffers.
++ * error_down - pointer to a string pointer to record errors from executing down.d
++ *              when configured. The string is malloc'ed, the caller needs to free that
++ *              buffer.
+  *
+- * error_postdown - pointers to string to record errors from executing post-down.d
++ * error_postdown - pointer to a string pointer to record errors from executing post-down.d
+  *                  when configured. The string is malloc'ed, the caller needs to free
+- *                  those buffers.
++ *                  that buffer.
+  *
+  * @return
+  * 0 on success
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0088-nozzle-cleanup-and-document-nozzle_get_mac.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0088-nozzle-cleanup-and-document-nozzle_get_mac.patch
new file mode 100644
index 000000000..81bb1398c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0088-nozzle-cleanup-and-document-nozzle_get_mac.patch
@@ -0,0 +1,133 @@ 
+From eea28232a4f001b13d850094d6dd7dde312bc7e5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Nov 2017 06:21:55 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_get_mac
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 37 +++++++++++++++++++++++++++----------
+ libnozzle/libnozzle.h | 13 +++++++++++++
+ 2 files changed, 40 insertions(+), 10 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 1a5e82f0..fefb0400 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -296,7 +296,7 @@ out_clean:
+ 
+ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+-	int err = 0;
++	int err = 0, savederrno = 0;
+ 	char mac[MAX_MAC_CHAR];
+ #ifdef KNET_BSD
+ 	struct ifaddrs *ifap = NULL;
+@@ -310,8 +310,10 @@ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ 
+ #ifdef KNET_LINUX
+ 	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &nozzle->ifr);
+-	if (err)
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	ether_ntoa_r((struct ether_addr *)nozzle->ifr.ifr_hwaddr.sa_data, mac);
+ #endif
+@@ -322,8 +324,10 @@ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ 	 * https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
+ 	 */
+ 	err = getifaddrs(&ifap);
+-	if (err < 0)
++	if (err < 0) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	ifa = ifap;
+ 
+@@ -338,20 +342,24 @@ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ 	if (found) {
+ 		ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
+ 	} else {
++		errno = EINVAL;
+ 		err = -1;
+ 	}
+ 	freeifaddrs(ifap);
+ 
+-	if (err)
++	if (err) {
+ 		goto out_clean;
++	}
+ 
+ #endif
+ 	*ether_addr = strdup(mac);
+-	if (!*ether_addr)
++	if (!*ether_addr) {
++		savederrno = errno;
+ 		err = -1;
++	}
+ 
+ out_clean:
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+@@ -715,11 +723,20 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ 
+ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+-	int err;
++	int err = 0, savederrno = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if ((!nozzle) || (!ether_addr)) {
++		errno = EINVAL;
++		return -1;
++	}
+ 
+-	if ((!_check(nozzle)) || (!ether_addr)) {
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+@@ -729,7 +746,7 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index f1e53671..5f75cb06 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -247,6 +247,19 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string);
+ 
+ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string);
+ 
++/**
++ * nozzle_get_mac
++ * @brief retrive mac address on a given nozzle interface
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * ether_addr - pointers to string containing the current mac address.
++ *              The string is malloc'ed, the caller needs to free this buffer.
++ * @return
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
+ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
+ int nozzle_reset_mac(nozzle_t nozzle);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0089-nozzle-cleanup-and-document-nozzle_-re-set_mac.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0089-nozzle-cleanup-and-document-nozzle_-re-set_mac.patch
new file mode 100644
index 000000000..82b09b17e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0089-nozzle-cleanup-and-document-nozzle_-re-set_mac.patch
@@ -0,0 +1,113 @@ 
+From 8c90bf595ec41e8c6e7559d046618a9517c4ebeb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Nov 2017 06:26:01 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_(re)set_mac
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 27 +++++++++++++++++++++------
+ libnozzle/libnozzle.h | 26 ++++++++++++++++++++++++++
+ 2 files changed, 47 insertions(+), 6 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index fefb0400..1a4423d0 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -752,11 +752,20 @@ out_clean:
+ 
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ {
+-	int err;
++	int err = 0, savederrno = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if ((!nozzle) || (!ether_addr)) {
++		errno = EINVAL;
++		return -1;
++	}
+ 
+-	if ((!_check(nozzle)) || (!ether_addr)) {
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
+ 		errno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+@@ -766,26 +775,32 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ #ifdef KNET_LINUX
+ 	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &nozzle->ifr);
+-	if (err)
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	memmove(nozzle->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+ 
+ 	err = ioctl(lib_cfg.sockfd, SIOCSIFHWADDR, &nozzle->ifr);
++	savederrno = errno;
+ #endif
+ #ifdef KNET_BSD
+ 	err = ioctl(lib_cfg.sockfd, SIOCGIFADDR, &nozzle->ifr);
+-	if (err)
++	if (err) {
++		savederrno = errno;
+ 		goto out_clean;
++	}
+ 
+ 	memmove(nozzle->ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
+ 	nozzle->ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ 
+ 	err = ioctl(lib_cfg.sockfd, SIOCSIFLLADDR, &nozzle->ifr);
++	savederrno = errno;
+ #endif
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return err;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 5f75cb06..813ca25d 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -261,7 +261,33 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string);
+  */
+ 
+ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
++
++/**
++ * nozzle_set_mac
++ * @brief set mac address on a given nozzle interface
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * ether_addr - pointers to string containing the new mac address.
++ *
++ * @return
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
++
++/**
++ * nozzle_reset_mac
++ * @brief reset mac address on a given nozzle interface to system default
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * @return
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
+ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+ nozzle_t nozzle_find(char *dev, size_t dev_size);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0090-nozzle-cleanup-and-document-nozzle_get_handle_by_nam.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0090-nozzle-cleanup-and-document-nozzle_get_handle_by_nam.patch
new file mode 100644
index 000000000..792b6458a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0090-nozzle-cleanup-and-document-nozzle_get_handle_by_nam.patch
@@ -0,0 +1,97 @@ 
+From 3f64482138c611f5c9fbbe0b53146bc808ce793e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Nov 2017 06:36:29 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_get_handle_by_name
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 26 +++++++++++++-------------
+ libnozzle/libnozzle.h | 14 +++++++++++++-
+ 2 files changed, 26 insertions(+), 14 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 1a4423d0..29e0c022 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -363,35 +363,35 @@ out_clean:
+ 	return err;
+ }
+ 
+-nozzle_t nozzle_find(char *dev, size_t dev_size)
++nozzle_t nozzle_get_handle_by_name(char *devname)
+ {
++	int savederrno = 0;
+ 	nozzle_t nozzle;
+ 
+-	if (dev == NULL) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	if (dev_size < IFNAMSIZ) {
++	if ((devname == NULL) || (strlen(devname) > IFNAMSIZ)) {
+ 		errno = EINVAL;
+ 		return NULL;
+ 	}
+ 
+-	if (strlen(dev) > IFNAMSIZ) {
+-		errno = E2BIG;
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
+ 		return NULL;
+ 	}
+ 
+-	pthread_mutex_lock(&lib_mutex);
+-
+ 	nozzle = lib_cfg.head;
+ 	while (nozzle != NULL) {
+-		if (!strcmp(dev, nozzle->nozzlename))
++		if (!strcmp(devname, nozzle->nozzlename))
+ 			break;
+ 		nozzle = nozzle->next;
+ 	}
+ 
++	if (!nozzle) {
++		savederrno = ENOENT;
++	}
++
+ 	pthread_mutex_unlock(&lib_mutex);
++	errno = savederrno;
+ 	return nozzle;
+ }
+ 
+@@ -1348,7 +1348,7 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 		printf("Unable to find interface %s on the system\n", name);
+ 	}
+ 
+-	if (!nozzle_find(name, size)) {
++	if (!nozzle_get_handle_by_name(name)) {
+ 		printf("Unable to find interface %s in nozzle db\n", name);
+ 	} else {
+ 		printf("Found interface %s in nozzle db\n", name);
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 813ca25d..858125ae 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -290,7 +290,19 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
+ 
+ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+-nozzle_t nozzle_find(char *dev, size_t dev_size);
++/**
++ * nozzle_get_handle_by_name
++ * @brief fine a nozzle handle by device name
++ *
++ * devname - string containing the name of the interface
++ *
++ * @return
++ * handle on success.
++ * NULL on error and errno is set.
++ */
++
++nozzle_t nozzle_get_handle_by_name(char *devname);
++
+ int nozzle_get_fd(const nozzle_t nozzle);
+ const char *nozzle_get_name(const nozzle_t nozzle);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0091-nozzle-cleanup-and-document-nozzle_get_name_by_handl.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0091-nozzle-cleanup-and-document-nozzle_get_name_by_handl.patch
new file mode 100644
index 000000000..654d5bc45
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0091-nozzle-cleanup-and-document-nozzle_get_name_by_handl.patch
@@ -0,0 +1,77 @@ 
+From 6e5b3ffc74e8c692b2e10e87ff287147a0354295 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Nov 2017 06:40:04 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_get_name_by_handle
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 18 ++++++++++++++----
+ libnozzle/libnozzle.h | 14 +++++++++++++-
+ 2 files changed, 27 insertions(+), 5 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 29e0c022..3e32d97c 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1203,14 +1203,24 @@ out_clean:
+ 	return fd;
+ }
+ 
+-const char *nozzle_get_name(const nozzle_t nozzle)
++const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+ {
++	int savederrno = 0;
+ 	char *name = NULL;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if (!nozzle) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
+ 
+ 	if (!_check(nozzle)) {
+-		errno = EINVAL;
++		errno = ENOENT;
+ 		goto out_clean;
+ 	}
+ 
+@@ -1218,7 +1228,7 @@ const char *nozzle_get_name(const nozzle_t nozzle)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return name;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 858125ae..92c5d126 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -303,7 +303,19 @@ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+ nozzle_t nozzle_get_handle_by_name(char *devname);
+ 
++/**
++ * nozzle_get_name_by_handle
++ * @brief fine a nozzle handle by device name
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * @return
++ * pointer to the interface name
++ * NULL on error and errno is set.
++ */
++
++const char *nozzle_get_name_by_handle(const nozzle_t nozzle);
++
+ int nozzle_get_fd(const nozzle_t nozzle);
+-const char *nozzle_get_name(const nozzle_t nozzle);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0092-nozzle-cleanup-and-document-nozzle_get_fd.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0092-nozzle-cleanup-and-document-nozzle_get_fd.patch
new file mode 100644
index 000000000..9a81d633f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0092-nozzle-cleanup-and-document-nozzle_get_fd.patch
@@ -0,0 +1,89 @@ 
+From 65629ec755300812df7356f19f2dbe9a50f3fbdb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Nov 2017 06:43:28 +0100
+Subject: [PATCH] [nozzle] cleanup and document nozzle_get_fd
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 17 +++++++++++++----
+ libnozzle/libnozzle.h | 15 +++++++++++++--
+ 2 files changed, 26 insertions(+), 6 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 3e32d97c..1254fc21 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1185,12 +1185,21 @@ out_clean:
+ 
+ int nozzle_get_fd(const nozzle_t nozzle)
+ {
+-	int fd;
++	int fd = -1, savederrno = 0;
+ 
+-	pthread_mutex_lock(&lib_mutex);
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&lib_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
+ 
+ 	if (!_check(nozzle)) {
+-		errno = EINVAL;
++		savederrno = ENOENT;
+ 		fd = -1;
+ 		goto out_clean;
+ 	}
+@@ -1199,7 +1208,7 @@ int nozzle_get_fd(const nozzle_t nozzle)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+-
++	errno = savederrno;
+ 	return fd;
+ }
+ 
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 92c5d126..789e6ad5 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -292,7 +292,7 @@ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_handle_by_name
+- * @brief fine a nozzle handle by device name
++ * @brief find a nozzle handle by device name
+  *
+  * devname - string containing the name of the interface
+  *
+@@ -305,7 +305,7 @@ nozzle_t nozzle_get_handle_by_name(char *devname);
+ 
+ /**
+  * nozzle_get_name_by_handle
+- * @brief fine a nozzle handle by device name
++ * @brief retrive nozzle interface name by handle
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+@@ -316,6 +316,17 @@ nozzle_t nozzle_get_handle_by_name(char *devname);
+ 
+ const char *nozzle_get_name_by_handle(const nozzle_t nozzle);
+ 
++/**
++ * nozzle_get_fd
++ * @brief 
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * @return
++ * fd associated to a given nozzle on success.
++ * -1 on error and errno is set.
++ */
++
+ int nozzle_get_fd(const nozzle_t nozzle);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0093-cleanup-start-splitting-the-code-across-multiple-fil.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0093-cleanup-start-splitting-the-code-across-multiple-fil.patch
new file mode 100644
index 000000000..af9f2a6d4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0093-cleanup-start-splitting-the-code-across-multiple-fil.patch
@@ -0,0 +1,163 @@ 
+From a0e373a6a570882a7e6527d2250544800a4e66bc Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 05:57:41 +0100
+Subject: [PATCH] [cleanup] start splitting the code across multiple files
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/Makefile.am | 18 ++++++++++++-----
+ libnozzle/internals.h | 46 +++++++++++++++++++++++++++++++++++++++++++
+ libnozzle/libnozzle.c | 32 +-----------------------------
+ 3 files changed, 60 insertions(+), 36 deletions(-)
+ create mode 100644 libnozzle/internals.h
+
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 06d2b4a1..563c47ec 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -19,9 +19,6 @@ sources			= libnozzle.c
+ 
+ libversion		= 1:0:0
+ 
+-AM_CFLAGS		+= $(PTHREAD_CFLAGS)
+-LIBS			= $(PTHREAD_LIBS)
+-
+ if BUILD_LIBNOZZLE
+ 
+ include_HEADERS		= libnozzle.h
+@@ -30,22 +27,29 @@ pkgconfigdir		= $(libdir)/pkgconfig
+ 
+ pkgconfig_DATA		= libnozzle.pc
+ 
++noinst_HEADERS		= \
++			  internals.h
++
+ lib_LTLIBRARIES		= libnozzle.la
+ 
+ libnozzle_la_SOURCES	= $(sources)
+ 
++libnozzle_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS)
++
+ EXTRA_libnozzle_la_DEPENDENCIES	= $(SYMFILE)
+ 
+ libnozzle_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 			  -Wl,-version-script,$(srcdir)/$(SYMFILE) \
+ 			  -version-info $(libversion)
+ 
++libnozzle_la_LIBADD	= $(PTHREAD_LIBS)
++
++check_PROGRAMS		= nozzle_test
++
+ TESTS			= $(check_PROGRAMS)
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+ 
+-check_PROGRAMS		= nozzle_test
+-
+ check-local: check-api-test-coverage
+ 
+ check-api-test-coverage:
+@@ -57,4 +61,8 @@ nozzle_test_SOURCES	= $(sources)
+ nozzle_test_CPPFLAGS	= -DTEST \
+ 			  -DABSBUILDDIR=\"$(abs_builddir)\"
+ 
++nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS)
++
++nozzle_test_LDFLAGS	= $(PTHREAD_LIBS)
++
+ endif
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+new file mode 100644
+index 00000000..839afa47
+--- /dev/null
++++ b/libnozzle/internals.h
+@@ -0,0 +1,46 @@
++/*
++ * Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#ifndef __NOZZLE_INTERNALS_H__
++#define __NOZZLE_INTERNALS_H__
++
++#include "config.h"
++#include <net/if.h>
++
++#define MAX_IP_CHAR	128
++#define MAX_PREFIX_CHAR	4
++#define MAX_MAC_CHAR	18
++
++struct _ip {
++	char ip_addr[MAX_IP_CHAR];
++	char prefix[MAX_PREFIX_CHAR];
++	int  domain;
++	struct _ip *next;
++};
++
++struct nozzle_iface {
++	struct ifreq ifr;
++	int fd;
++	char nozzlename[IFNAMSIZ];
++	char default_mac[MAX_MAC_CHAR];
++	int default_mtu;
++	int current_mtu;
++	char updownpath[PATH_MAX - 11 - 1 - IFNAMSIZ]; /* 11 = post-down.d 1 = / */
++	int hasupdown;
++	int up;
++	struct _ip *ip;
++	struct nozzle_iface *next;
++};
++#define ifname ifr.ifr_name
++
++struct _config {
++	struct nozzle_iface *head;
++	int sockfd;
++};
++
++#endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 1254fc21..655a83ab 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -36,37 +36,7 @@
+ #endif
+ 
+ #include "libnozzle.h"
+-
+-#define MAX_IP_CHAR	128
+-#define MAX_PREFIX_CHAR	4
+-#define MAX_MAC_CHAR	18
+-
+-struct _ip {
+-	char ip_addr[MAX_IP_CHAR];
+-	char prefix[MAX_PREFIX_CHAR];
+-	int  domain;
+-	struct _ip *next;
+-};
+-
+-struct nozzle_iface {
+-	struct ifreq ifr;
+-	int fd;
+-	char nozzlename[IFNAMSIZ];
+-	char default_mac[MAX_MAC_CHAR];
+-	int default_mtu;
+-	int current_mtu;
+-	char updownpath[PATH_MAX - 11 - 1 - IFNAMSIZ]; /* 11 = post-down.d 1 = / */
+-	int hasupdown;
+-	int up;
+-	struct _ip *ip;
+-	struct nozzle_iface *next;
+-};
+-#define ifname ifr.ifr_name
+-
+-struct _config {
+-	struct nozzle_iface *head;
+-	int sockfd;
+-};
++#include "internals.h"
+ 
+ static int lib_init = 0;
+ static struct _config lib_cfg;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0094-nozzle-rename-_config-to-nozzle_lib_config.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0094-nozzle-rename-_config-to-nozzle_lib_config.patch
new file mode 100644
index 000000000..fd4eadc3a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0094-nozzle-rename-_config-to-nozzle_lib_config.patch
@@ -0,0 +1,50 @@ 
+From e2c00d64cb821ef679d11d33ad7600403a2239a9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 06:01:32 +0100
+Subject: [PATCH] [nozzle] rename _config to nozzle_lib_config
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h | 10 +++++-----
+ libnozzle/libnozzle.c |  2 +-
+ 2 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 839afa47..75096932 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -12,6 +12,11 @@
+ #include "config.h"
+ #include <net/if.h>
+ 
++struct nozzle_lib_config {
++	struct nozzle_iface *head;
++	int sockfd;
++};
++
+ #define MAX_IP_CHAR	128
+ #define MAX_PREFIX_CHAR	4
+ #define MAX_MAC_CHAR	18
+@@ -38,9 +43,4 @@ struct nozzle_iface {
+ };
+ #define ifname ifr.ifr_name
+ 
+-struct _config {
+-	struct nozzle_iface *head;
+-	int sockfd;
+-};
+-
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 655a83ab..ec005bc4 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -39,7 +39,7 @@
+ #include "internals.h"
+ 
+ static int lib_init = 0;
+-static struct _config lib_cfg;
++static struct nozzle_lib_config lib_cfg;
+ static pthread_mutex_t lib_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+ /* forward declarations */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0095-cleanup-rename-struct-_ip-to-struct-nozzle_ip-and-cl.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0095-cleanup-rename-struct-_ip-to-struct-nozzle_ip-and-cl.patch
new file mode 100644
index 000000000..a4810df93
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0095-cleanup-rename-struct-_ip-to-struct-nozzle_ip-and-cl.patch
@@ -0,0 +1,172 @@ 
+From e75bc6f828c2a4135eecd4edf5eeecf853833c41 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 06:12:15 +0100
+Subject: [PATCH] [cleanup] rename struct _ip to struct nozzle_ip and cleanup
+ related defines
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h | 19 ++++++++++---------
+ libnozzle/libnozzle.c | 30 +++++++++++++++---------------
+ 2 files changed, 25 insertions(+), 24 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 75096932..6ba9119c 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -17,28 +17,29 @@ struct nozzle_lib_config {
+ 	int sockfd;
+ };
+ 
+-#define MAX_IP_CHAR	128
+-#define MAX_PREFIX_CHAR	4
+-#define MAX_MAC_CHAR	18
++#define IPADDR_CHAR_MAX   128
++#define PREFIX_CHAR_MAX	    4
+ 
+-struct _ip {
+-	char ip_addr[MAX_IP_CHAR];
+-	char prefix[MAX_PREFIX_CHAR];
++struct nozzle_ip {
++	char ip_addr[IPADDR_CHAR_MAX];
++	char prefix[PREFIX_CHAR_MAX];
+ 	int  domain;
+-	struct _ip *next;
++	struct nozzle_ip *next;
+ };
+ 
++#define MACADDR_CHAR_MAX   18
++
+ struct nozzle_iface {
+ 	struct ifreq ifr;
+ 	int fd;
+ 	char nozzlename[IFNAMSIZ];
+-	char default_mac[MAX_MAC_CHAR];
++	char default_mac[MACADDR_CHAR_MAX];
+ 	int default_mtu;
+ 	int current_mtu;
+ 	char updownpath[PATH_MAX - 11 - 1 - IFNAMSIZ]; /* 11 = post-down.d 1 = / */
+ 	int hasupdown;
+ 	int up;
+-	struct _ip *ip;
++	struct nozzle_ip *ip;
+ 	struct nozzle_iface *next;
+ };
+ #define ifname ifr.ifr_name
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index ec005bc4..c1b72cfe 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -58,7 +58,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      char **error_string, int secondary);
+ static int _find_ip(nozzle_t nozzle,
+ 			const char *ip_addr, const char *prefix,
+-			struct _ip **ip, struct _ip **ip_prev);
++			struct nozzle_ip **ip, struct nozzle_ip **ip_prev);
+ 
+ static int _read_pipe(int fd, char **file, size_t *length)
+ {
+@@ -267,14 +267,14 @@ out_clean:
+ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err = 0, savederrno = 0;
+-	char mac[MAX_MAC_CHAR];
++	char mac[MACADDR_CHAR_MAX];
+ #ifdef KNET_BSD
+ 	struct ifaddrs *ifap = NULL;
+ 	struct ifaddrs *ifa;
+ 	int found = 0;
+ #endif
+ 
+-	memset(&mac, 0, MAX_MAC_CHAR);
++	memset(&mac, 0, MACADDR_CHAR_MAX);
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+@@ -550,7 +550,7 @@ int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ 	int err = 0, savederrno = 0;
+ 	nozzle_t temp = lib_cfg.head;
+ 	nozzle_t prev = lib_cfg.head;
+-	struct _ip *ip, *ip_next;
++	struct nozzle_ip *ip, *ip_next;
+ 	char *error_string = NULL;
+ 
+ 	savederrno = pthread_mutex_lock(&lib_mutex);
+@@ -632,7 +632,7 @@ out_clean:
+ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+-	struct _ip *tmp_ip;
++	struct nozzle_ip *tmp_ip;
+ 
+ 	if ((!nozzle) || (!mtu) || (!error_string)) {
+ 		errno = EINVAL;
+@@ -1004,9 +1004,9 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 
+ static int _find_ip(nozzle_t nozzle,
+ 			const char *ip_addr, const char *prefix,
+-			struct _ip **ip, struct _ip **ip_prev)
++			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
+ {
+-	struct _ip *local_ip, *local_ip_prev;
++	struct nozzle_ip *local_ip, *local_ip_prev;
+ 	int found = 0;
+ 
+ 	local_ip = local_ip_prev = nozzle->ip;
+@@ -1032,7 +1032,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ {
+ 	int err = 0, savederrno = 0;
+ 	int found = 0;
+-	struct _ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
++	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+ 	int secondary = 0;
+ 
+ 	if ((!nozzle) || (!ip_addr) || (!prefix) || (!error_string)) {
+@@ -1057,16 +1057,16 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 		goto out_clean;
+ 	}
+ 
+-	ip = malloc(sizeof(struct _ip));
++	ip = malloc(sizeof(struct nozzle_ip));
+ 	if (!ip) {
+ 		savederrno = errno;
+ 		err = -1 ;
+ 		goto out_clean;
+ 	}
+ 
+-	memset(ip, 0, sizeof(struct _ip));
+-	strncpy(ip->ip_addr, ip_addr, MAX_IP_CHAR);
+-	strncpy(ip->prefix, prefix, MAX_PREFIX_CHAR);
++	memset(ip, 0, sizeof(struct nozzle_ip));
++	strncpy(ip->ip_addr, ip_addr, IPADDR_CHAR_MAX);
++	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
+ 	if (!strchr(ip->ip_addr, ':')) {
+ 		ip->domain = AF_INET;
+ 	} else {
+@@ -1112,7 +1112,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ {
+ 	int err = 0, savederrno = 0;
+         int found = 0;
+-	struct _ip *ip = NULL, *ip_prev = NULL;
++	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
+ 
+ 	if ((!nozzle) || (!ip_addr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+@@ -1217,7 +1217,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 	int found = 0;
+ 	char *ip_list = NULL;
+ 	int size = 0, offset = 0, len;
+-	struct _ip *ip = NULL;
++	struct nozzle_ip *ip = NULL;
+ 
+ 	if ((!nozzle) || (!ip_addr_list) || (!entries)) {
+ 		errno = EINVAL;
+@@ -1248,7 +1248,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 		goto out_clean;
+ 	}
+ 
+-	size = found * (MAX_IP_CHAR + MAX_PREFIX_CHAR + 2);
++	size = found * (IPADDR_CHAR_MAX + PREFIX_CHAR_MAX + 2);
+ 
+ 	ip_list = malloc(size);
+ 	if (!ip_list) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0096-cleanup-rename-sockfd-to-ioctlfd.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0096-cleanup-rename-sockfd-to-ioctlfd.patch
new file mode 100644
index 000000000..9dacf6cf6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0096-cleanup-rename-sockfd-to-ioctlfd.patch
@@ -0,0 +1,166 @@ 
+From 3d62ef663a21ff75f6a0d630f68bff47364f12dd Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 06:14:37 +0100
+Subject: [PATCH] [cleanup] rename sockfd to ioctlfd
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h |  2 +-
+ libnozzle/libnozzle.c | 34 +++++++++++++++++-----------------
+ 2 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 6ba9119c..873b3d12 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -14,7 +14,7 @@
+ 
+ struct nozzle_lib_config {
+ 	struct nozzle_iface *head;
+-	int sockfd;
++	int ioctlfd;
+ };
+ 
+ #define IPADDR_CHAR_MAX   128
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index c1b72cfe..5e0296cd 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -228,7 +228,7 @@ static void _close(nozzle_t nozzle)
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	ioctl(lib_cfg.sockfd, SIOCIFDESTROY, &nozzle->ifr);
++	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &nozzle->ifr);
+ #endif
+ 
+ 	free(nozzle);
+@@ -239,7 +239,7 @@ static void _close(nozzle_t nozzle)
+ static void _close_cfg(void)
+ {
+ 	if (lib_cfg.head == NULL) {
+-		close(lib_cfg.sockfd);
++		close(lib_cfg.ioctlfd);
+ 		lib_init = 0;
+ 	}
+ }
+@@ -251,7 +251,7 @@ static int _get_mtu(const nozzle_t nozzle)
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFMTU, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -279,7 +279,7 @@ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+ #ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -437,12 +437,12 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	if (!lib_init) {
+ 		lib_cfg.head = NULL;
+ #ifdef KNET_LINUX
+-		lib_cfg.sockfd = socket(AF_INET, SOCK_STREAM, 0);
++		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
+ #endif
+ #ifdef KNET_BSD
+-		lib_cfg.sockfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
++		lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+ #endif
+-		if (lib_cfg.sockfd < 0) {
++		if (lib_cfg.ioctlfd < 0) {
+ 			savederrno = errno;
+ 			goto out_error;
+ 		}
+@@ -659,7 +659,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 
+ 	nozzle->ifr.ifr_mtu = mtu;
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFMTU, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -744,7 +744,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ #ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFHWADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -752,11 +752,11 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 
+ 	memmove(nozzle->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFHWADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &nozzle->ifr);
+ 	savederrno = errno;
+ #endif
+ #ifdef KNET_BSD
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -765,7 +765,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 	memmove(nozzle->ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
+ 	nozzle->ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFLLADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &nozzle->ifr);
+ 	savederrno = errno;
+ #endif
+ out_clean:
+@@ -813,7 +813,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -822,7 +822,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 	_exec_updown(nozzle, "pre-up.d", error_preup);
+ 
+ 	nozzle->ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -849,7 +849,7 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+ 	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCGIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -859,7 +859,7 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 
+ 	nozzle->ifr.ifr_flags &= ~IFF_UP;
+ 
+-	err = ioctl(lib_cfg.sockfd, SIOCSIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &nozzle->ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -1324,7 +1324,7 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 
+ 	nozzle=nozzle_open(name, size, updownpath);
+ 	if (!nozzle) {
+-		if (lib_cfg.sockfd < 0)
++		if (lib_cfg.ioctlfd < 0)
+ 			printf("Unable to open knet_socket\n");
+ 		printf("Unable to open knet.\n");
+ 		return -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0097-cleanup-rename-ip_addr-to-ipaddr.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0097-cleanup-rename-ip_addr-to-ipaddr.patch
new file mode 100644
index 000000000..9d133fde6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0097-cleanup-rename-ip_addr-to-ipaddr.patch
@@ -0,0 +1,346 @@ 
+From 460f01b6122e050f0289f3129275a0933b3fd321 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 06:17:51 +0100
+Subject: [PATCH] [cleanup] rename ip_addr to ipaddr
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h |  4 +--
+ libnozzle/libnozzle.c | 64 +++++++++++++++++++++----------------------
+ libnozzle/libnozzle.h | 16 +++++------
+ 3 files changed, 42 insertions(+), 42 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 873b3d12..478e67ea 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -21,9 +21,9 @@ struct nozzle_lib_config {
+ #define PREFIX_CHAR_MAX	    4
+ 
+ struct nozzle_ip {
+-	char ip_addr[IPADDR_CHAR_MAX];
++	char ipaddr[IPADDR_CHAR_MAX];
+ 	char prefix[PREFIX_CHAR_MAX];
+-	int  domain;
++	int  domain;			/* AF_INET or AF_INET6 */
+ 	struct nozzle_ip *next;
+ };
+ 
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 5e0296cd..e51cfde5 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -52,12 +52,12 @@ static void _close_cfg(void);
+ static int _get_mtu(const nozzle_t nozzle);
+ static int _get_mac(const nozzle_t nozzle, char **ether_addr);
+ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+-static char *_get_v4_broadcast(const char *ip_addr, const char *prefix);
++static char *_get_v4_broadcast(const char *ipaddr, const char *prefix);
+ static int _set_ip(nozzle_t nozzle, const char *command,
+-		      const char *ip_addr, const char *prefix,
++		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary);
+ static int _find_ip(nozzle_t nozzle,
+-			const char *ip_addr, const char *prefix,
++			const char *ipaddr, const char *prefix,
+ 			struct nozzle_ip **ip, struct nozzle_ip **ip_prev);
+ 
+ static int _read_pipe(int fd, char **file, size_t *length)
+@@ -581,7 +581,7 @@ int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ 	ip = nozzle->ip;
+ 	while (ip) {
+ 		ip_next = ip->next;
+-		_set_ip(nozzle, "del", ip->ip_addr, ip->prefix, &error_string, 0);
++		_set_ip(nozzle, "del", ip->ipaddr, ip->prefix, &error_string, 0);
+ 		if (error_string) {
+ 			free(error_string);
+ 			error_string = NULL;
+@@ -669,7 +669,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 		tmp_ip = nozzle->ip;
+ 		while(tmp_ip) {
+ 			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(nozzle, "add", tmp_ip->ip_addr, tmp_ip->prefix, error_string, 0);
++				err = _set_ip(nozzle, "add", tmp_ip->ipaddr, tmp_ip->prefix, error_string, 0);
+ 				if (err) {
+ 					savederrno = errno;
+ 					err = -1;
+@@ -910,7 +910,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-static char *_get_v4_broadcast(const char *ip_addr, const char *prefix)
++static char *_get_v4_broadcast(const char *ipaddr, const char *prefix)
+ {
+ 	int prefix_len;
+ 	struct in_addr mask;
+@@ -922,7 +922,7 @@ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix)
+ 	if ((prefix_len > 32) || (prefix_len < 0))
+ 		return NULL;
+ 
+-	if (inet_pton(AF_INET, ip_addr, &address) <= 0)
++	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
+ 		return NULL;
+ 
+ 	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
+@@ -934,7 +934,7 @@ static char *_get_v4_broadcast(const char *ip_addr, const char *prefix)
+ }
+ 
+ static int _set_ip(nozzle_t nozzle, const char *command,
+-		      const char *ip_addr, const char *prefix,
++		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+ {
+ 	char *broadcast = NULL;
+@@ -946,8 +946,8 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	snprintf(proto, sizeof(proto), "inet");
+ #endif
+ 
+-	if (!strchr(ip_addr, ':')) {
+-		broadcast = _get_v4_broadcast(ip_addr, prefix);
++	if (!strchr(ipaddr, ':')) {
++		broadcast = _get_v4_broadcast(ipaddr, prefix);
+ 		if (!broadcast) {
+ 			errno = EINVAL;
+ 			return -1;
+@@ -966,12 +966,12 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	if (broadcast) {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ip addr %s %s/%s dev %s broadcast %s",
+-			 command, ip_addr, prefix,
++			 command, ipaddr, prefix,
+ 			 nozzle->nozzlename, broadcast);
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ip addr %s %s/%s dev %s",
+-			command, ip_addr, prefix,
++			command, ipaddr, prefix,
+ 			nozzle->nozzlename);
+ 	}
+ #endif
+@@ -979,7 +979,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	if (!strcmp(command, "add")) {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ifconfig %s %s %s/%s",
+-			 nozzle->nozzlename, proto, ip_addr, prefix);
++			 nozzle->nozzlename, proto, ipaddr, prefix);
+ 		if (broadcast) {
+ 			snprintf(cmdline + strlen(cmdline),
+ 				 sizeof(cmdline) - strlen(cmdline) -1,
+@@ -993,7 +993,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 				 "ifconfig %s %s %s/%s delete",
+-				 nozzle->nozzlename, proto, ip_addr, prefix);
++				 nozzle->nozzlename, proto, ipaddr, prefix);
+ 	}
+ #endif
+ 	if (broadcast) {
+@@ -1003,7 +1003,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ }
+ 
+ static int _find_ip(nozzle_t nozzle,
+-			const char *ip_addr, const char *prefix,
++			const char *ipaddr, const char *prefix,
+ 			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
+ {
+ 	struct nozzle_ip *local_ip, *local_ip_prev;
+@@ -1012,7 +1012,7 @@ static int _find_ip(nozzle_t nozzle,
+ 	local_ip = local_ip_prev = nozzle->ip;
+ 
+ 	while(local_ip) {
+-		if ((!strcmp(local_ip->ip_addr, ip_addr)) && (!strcmp(local_ip->prefix, prefix))) {
++		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
+ 			found = 1;
+ 			break;
+ 		}
+@@ -1028,14 +1028,14 @@ static int _find_ip(nozzle_t nozzle,
+ 	return found;
+ }
+ 
+-int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string)
++int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+ 	int found = 0;
+ 	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+ 	int secondary = 0;
+ 
+-	if ((!nozzle) || (!ip_addr) || (!prefix) || (!error_string)) {
++	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -1052,7 +1052,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 		goto out_clean;
+ 	}
+ 
+-	found = _find_ip(nozzle, ip_addr, prefix, &ip, &ip_prev);
++	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+ 	if (found) {
+ 		goto out_clean;
+ 	}
+@@ -1065,9 +1065,9 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 	}
+ 
+ 	memset(ip, 0, sizeof(struct nozzle_ip));
+-	strncpy(ip->ip_addr, ip_addr, IPADDR_CHAR_MAX);
++	strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
+ 	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
+-	if (!strchr(ip->ip_addr, ':')) {
++	if (!strchr(ip->ipaddr, ':')) {
+ 		ip->domain = AF_INET;
+ 	} else {
+ 		ip->domain = AF_INET6;
+@@ -1083,7 +1083,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 		if (nozzle->ip) {
+ 			secondary = 1;
+ 		}
+-		err = _set_ip(nozzle, "add", ip_addr, prefix, error_string, secondary);
++		err = _set_ip(nozzle, "add", ipaddr, prefix, error_string, secondary);
+ 		savederrno = errno;
+ 	}
+ 
+@@ -1108,13 +1108,13 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string)
++int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+         int found = 0;
+ 	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
+ 
+-	if ((!nozzle) || (!ip_addr) || (!prefix) || (!error_string)) {
++	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -1131,12 +1131,12 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+ 		goto out_clean;
+ 	}
+ 
+-	found = _find_ip(nozzle, ip_addr, prefix, &ip, &ip_prev);
++	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+ 	if (!found) {
+ 		goto out_clean;
+ 	}
+ 
+-	err = _set_ip(nozzle, "del", ip_addr, prefix, error_string, 0);
++	err = _set_ip(nozzle, "del", ipaddr, prefix, error_string, 0);
+ 	savederrno = errno;
+ 	if (!err) {
+ 		if (ip == ip_prev) {
+@@ -1211,7 +1211,7 @@ out_clean:
+ 	return name;
+ }
+ 
+-int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
++int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ {
+ 	int err = 0, savederrno = 0;
+ 	int found = 0;
+@@ -1219,7 +1219,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 	int size = 0, offset = 0, len;
+ 	struct nozzle_ip *ip = NULL;
+ 
+-	if ((!nozzle) || (!ip_addr_list) || (!entries)) {
++	if ((!nozzle) || (!ipaddr_list) || (!entries)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -1243,7 +1243,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 	}
+ 
+ 	if (!found) {
+-		*ip_addr_list = NULL;
++		*ipaddr_list = NULL;
+ 		*entries = 0;
+ 		goto out_clean;
+ 	}
+@@ -1262,8 +1262,8 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 	ip = nozzle->ip;
+ 
+ 	while (ip) {
+-		len = strlen(ip->ip_addr);
+-		memmove(ip_list + offset, ip->ip_addr, len);
++		len = strlen(ip->ipaddr);
++		memmove(ip_list + offset, ip->ipaddr, len);
+ 		offset = offset + len + 1;
+ 		len = strlen(ip->prefix);
+ 		memmove(ip_list + offset, ip->prefix, len);
+@@ -1271,7 +1271,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries)
+ 		ip = ip->next;
+ 	}
+ 
+-	*ip_addr_list = ip_list;
++	*ipaddr_list = ip_list;
+ 	*entries = found;
+ 
+ out_clean:
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 789e6ad5..355f07eb 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -131,7 +131,7 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * ip_addr - string containing either an IPv4 or an IPv6 address.
++ * ipaddr - string containing either an IPv4 or an IPv6 address.
+  *           Please note that Linux will automatically remove any IPv6 addresses from an interface
+  *           with MTU < 1280. libnozzle will cache those IPs and re-instate them when MTU is > 1280.
+  *           MTU must be set via nozzle_set_mtu for IPv6 to be re-instated.
+@@ -148,7 +148,7 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+  *  error_string will contain a string recording the execution error.
+  */
+ 
+-int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string);
+ 
+ /**
+  * nozzle_del_ip
+@@ -156,7 +156,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * ip_addr - string containing either an IPv4 or an IPv6 address.
++ * ipaddr - string containing either an IPv4 or an IPv6 address.
+  *
+  * prefix - 24, 64 or any valid network prefix for the requested address.
+  *
+@@ -170,29 +170,29 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char
+  *  error_string will contain a string recording the execution error.
+  */
+ 
+-int nozzle_del_ip(nozzle_t nozzle, const char *ip_addr, const char *prefix, char **error_string);
++int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string);
+ 
+ /**
+  * nozzle_get_ips
+  * @brief retrive the list of all configured ips for a given interface
+  *
+- * TODO: change to use a ip_addr_list struct!
++ * TODO: change to use a ipaddr_list struct!
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * ip_addr_list - list of strings containing either an IPv4 or an IPv6 address and their prefixes.
++ * ipaddr_list - list of strings containing either an IPv4 or an IPv6 address and their prefixes.
+  *
+  * entries - entries recorded.
+  *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * ip_addr_list is a malloc'ed buffer that the user needs to parse and free after use. ip_addr_list can
++ * ipaddr_list is a malloc'ed buffer that the user needs to parse and free after use. ipaddr_list can
+  * be NULL if entries is 0.
+  *
+  */
+ 
+-int nozzle_get_ips(const nozzle_t nozzle, char **ip_addr_list, int *entries);
++int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries);
+ 
+ /**
+  * nozzle_get_mtu
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0098-cleanup-document-nozzle_iface-struct-drop-unnecessar.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0098-cleanup-document-nozzle_iface-struct-drop-unnecessar.patch
new file mode 100644
index 000000000..e98024548
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0098-cleanup-document-nozzle_iface-struct-drop-unnecessar.patch
@@ -0,0 +1,536 @@ 
+From e5eef72602314b8ad0485e3521a8a0456ef4d88f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 06:43:45 +0100
+Subject: [PATCH] [cleanup] document nozzle_iface struct, drop unnecessary ifr
+ struct and cleanup names
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h |  34 +++++++---
+ libnozzle/libnozzle.c | 154 +++++++++++++++++++++++-------------------
+ 2 files changed, 109 insertions(+), 79 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 478e67ea..eaaa09e4 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -29,19 +29,35 @@ struct nozzle_ip {
+ 
+ #define MACADDR_CHAR_MAX   18
+ 
++/*
++ * 11 = post-down.d
++ * 1  = /
++ */
++#define UPDOWN_PATH_MAX    PATH_MAX - 11 - 1 - IFNAMSIZ
++
+ struct nozzle_iface {
+-	struct ifreq ifr;
+-	int fd;
+-	char nozzlename[IFNAMSIZ];
++	char name[IFNAMSIZ];		/* interface name */
++	int fd;				/* interface fd */
++	int up;				/* interface status 0 is down, 1 is up */
++	/*
++	 * extra data
++	 */
++	struct nozzle_ip *ip;		/* configured ip addresses */
++
++	/*
++	 * default MAC address assigned by the kernel at creation time
++	 */
+ 	char default_mac[MACADDR_CHAR_MAX];
+-	int default_mtu;
+-	int current_mtu;
+-	char updownpath[PATH_MAX - 11 - 1 - IFNAMSIZ]; /* 11 = post-down.d 1 = / */
+-	int hasupdown;
+-	int up;
+-	struct nozzle_ip *ip;
++
++	int default_mtu;		/* MTU assigned by the kernel at creation time */
++	int current_mtu;		/* MTU configured by libnozzle user */
++
++	int hasupdown;			/* interface has up/down path to scripts configured */
++	char updownpath[UPDOWN_PATH_MAX]; /* path to up/down scripts if configured */
++
+ 	struct nozzle_iface *next;
+ };
++
+ #define ifname ifr.ifr_name
+ 
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index e51cfde5..b258f484 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -183,7 +183,7 @@ static int _exec_updown(const nozzle_t nozzle, const char *action, char **error_
+ 
+ 	memset(command, 0, PATH_MAX);
+ 
+-	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action, nozzle->nozzlename);
++	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action, nozzle->name);
+ 
+ 	err = stat(command, &sb);
+ 	if ((err < 0) && (errno == ENOENT))
+@@ -218,6 +218,10 @@ static int _check(const nozzle_t nozzle)
+ 
+ static void _close(nozzle_t nozzle)
+ {
++#ifdef KNET_BSD
++	struct ifreq ifr;
++#endif
++
+ 	if (!nozzle)
+ 		return;
+ 
+@@ -225,10 +229,10 @@ static void _close(nozzle_t nozzle)
+ 		close(nozzle->fd);
+ 
+ #ifdef KNET_BSD
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(nozzle->ifname, nozzle->name, IFNAMSIZ);
+ 
+-	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &nozzle->ifr);
++	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
+ #endif
+ 
+ 	free(nozzle);
+@@ -247,17 +251,18 @@ static void _close_cfg(void)
+ static int _get_mtu(const nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
++	struct ifreq ifr;
+ 
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+ 	}
+ 
+-	err = nozzle->ifr.ifr_mtu;
++	err = ifr.ifr_mtu;
+ 
+ out_clean:
+ 	errno = savederrno;
+@@ -267,6 +272,7 @@ out_clean:
+ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err = 0, savederrno = 0;
++	struct ifreq ifr;
+ 	char mac[MACADDR_CHAR_MAX];
+ #ifdef KNET_BSD
+ 	struct ifaddrs *ifap = NULL;
+@@ -275,17 +281,17 @@ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ #endif
+ 
+ 	memset(&mac, 0, MACADDR_CHAR_MAX);
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
+ 
+ #ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+ 	}
+ 
+-	ether_ntoa_r((struct ether_addr *)nozzle->ifr.ifr_hwaddr.sa_data, mac);
++	ether_ntoa_r((struct ether_addr *)ifr.ifr_hwaddr.sa_data, mac);
+ #endif
+ #ifdef KNET_BSD
+ 	/*
+@@ -302,7 +308,7 @@ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ 	ifa = ifap;
+ 
+ 	while (ifa) {
+-		if (!strncmp(nozzle->nozzlename, ifa->ifa_name, IFNAMSIZ)) {
++		if (!strncmp(nozzle->name, ifa->ifa_name, IFNAMSIZ)) {
+ 			found = 1;
+ 			break;
+ 		}
+@@ -351,7 +357,7 @@ nozzle_t nozzle_get_handle_by_name(char *devname)
+ 
+ 	nozzle = lib_cfg.head;
+ 	while (nozzle != NULL) {
+-		if (!strcmp(devname, nozzle->nozzlename))
++		if (!strcmp(devname, nozzle->name))
+ 			break;
+ 		nozzle = nozzle->next;
+ 	}
+@@ -370,6 +376,9 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	int savederrno = 0;
+ 	nozzle_t nozzle = NULL;
+ 	char *temp_mac = NULL;
++#ifdef KNET_LINUX
++	struct ifreq ifr;
++#endif
+ #ifdef KNET_BSD
+ 	uint16_t i;
+ 	long int nozzlenum = 0;
+@@ -421,8 +430,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 			errno = EINVAL;
+ 			return NULL;
+ 		}
+-		/* 14: 2 for /, 1 for \0 + 11 (post-down.d) */
+-		if (strlen(updownpath) >= (PATH_MAX - (strlen(devname) + 14))) {
++		if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
+ 			errno = E2BIG;
+ 			return NULL;
+ 		}
+@@ -479,7 +487,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		goto out_error;
+ 	}
+ 	strncpy(devname, curnozzle, IFNAMSIZ);
+-	strncpy(nozzle->nozzlename, curnozzle, IFNAMSIZ);
++	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
+ #endif
+ 
+ #ifdef KNET_LINUX
+@@ -488,22 +496,22 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		goto out_error;
+ 	}
+ 
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, devname, IFNAMSIZ);
+-	nozzle->ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, devname, IFNAMSIZ);
++	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ 
+-	if (ioctl(nozzle->fd, TUNSETIFF, &nozzle->ifr) < 0) {
++	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
+ 		savederrno = errno;
+ 		goto out_error;
+ 	}
+ 
+-	if ((strlen(devname) > 0) && (strcmp(devname, nozzle->ifname) != 0)) {
++	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
+ 		errno = EBUSY;
+ 		goto out_error;
+ 	}
+ 
+-	strncpy(devname, nozzle->ifname, IFNAMSIZ);
+-	strncpy(nozzle->nozzlename, nozzle->ifname, IFNAMSIZ);
++	strncpy(devname, ifname, IFNAMSIZ);
++	strncpy(nozzle->name, ifname, IFNAMSIZ);
+ #endif
+ 
+ 	nozzle->default_mtu = _get_mtu(nozzle);
+@@ -633,6 +641,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+ 	struct nozzle_ip *tmp_ip;
++	struct ifreq ifr;
+ 
+ 	if ((!nozzle) || (!mtu) || (!error_string)) {
+ 		errno = EINVAL;
+@@ -657,9 +666,11 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle->ifr.ifr_mtu = mtu;
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	ifr.ifr_mtu = mtu;
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -723,6 +734,7 @@ out_clean:
+ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ {
+ 	int err = 0, savederrno = 0;
++	struct ifreq ifr;
+ 
+ 	if ((!nozzle) || (!ether_addr)) {
+ 		errno = EINVAL;
+@@ -741,31 +753,31 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 		goto out_clean;
+ 	}
+ 
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
+ #ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+ 	}
+ 
+-	memmove(nozzle->ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
++	memmove(ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &ifr);
+ 	savederrno = errno;
+ #endif
+ #ifdef KNET_BSD
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+ 	}
+ 
+-	memmove(nozzle->ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
+-	nozzle->ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
++	memmove(ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
++	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &ifr);
+ 	savederrno = errno;
+ #endif
+ out_clean:
+@@ -782,6 +794,7 @@ int nozzle_reset_mac(nozzle_t nozzle)
+ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ {
+ 	int err = 0, savederrno = 0;
++	struct ifreq ifr;
+ 
+ 	if (!nozzle) {
+ 		errno = EINVAL;
+@@ -810,10 +823,10 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		goto out_clean;
+ 	}
+ 
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -821,8 +834,8 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 
+ 	_exec_updown(nozzle, "pre-up.d", error_preup);
+ 
+-	nozzle->ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &nozzle->ifr);
++	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -841,15 +854,16 @@ out_clean:
+ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+ 	int err = 0, savederrno = 0;
++	struct ifreq ifr;
+ 
+ 	if (!nozzle->up) {
+ 		goto out_clean;
+ 	}
+ 
+-	memset(&nozzle->ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->nozzlename, IFNAMSIZ);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -857,9 +871,9 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 
+ 	_exec_updown(nozzle, "down.d", error_down);
+ 
+-	nozzle->ifr.ifr_flags &= ~IFF_UP;
++	ifr.ifr_flags &= ~IFF_UP;
+ 
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &nozzle->ifr);
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+ 	if (err) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -967,19 +981,19 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ip addr %s %s/%s dev %s broadcast %s",
+ 			 command, ipaddr, prefix,
+-			 nozzle->nozzlename, broadcast);
++			 nozzle->name, broadcast);
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ip addr %s %s/%s dev %s",
+ 			command, ipaddr, prefix,
+-			nozzle->nozzlename);
++			nozzle->name);
+ 	}
+ #endif
+ #ifdef KNET_BSD
+ 	if (!strcmp(command, "add")) {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ifconfig %s %s %s/%s",
+-			 nozzle->nozzlename, proto, ipaddr, prefix);
++			 nozzle->name, proto, ipaddr, prefix);
+ 		if (broadcast) {
+ 			snprintf(cmdline + strlen(cmdline),
+ 				 sizeof(cmdline) - strlen(cmdline) -1,
+@@ -993,7 +1007,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	} else {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 				 "ifconfig %s %s %s/%s delete",
+-				 nozzle->nozzlename, proto, ipaddr, prefix);
++				 nozzle->name, proto, ipaddr, prefix);
+ 	}
+ #endif
+ 	if (broadcast) {
+@@ -1203,7 +1217,7 @@ const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+ 		goto out_clean;
+ 	}
+ 
+-	name = nozzle->nozzlename;
++	name = nozzle->name;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&lib_mutex);
+@@ -1698,10 +1712,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1759,10 +1773,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_2);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_2);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1790,10 +1804,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -1810,10 +1824,10 @@ static int check_knet_mtu_ipv6(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_2);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_2);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2096,10 +2110,10 @@ static int check_knet_up_down(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", nozzle->nozzlename);
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", nozzle->nozzlename);
++		 "ifconfig %s | grep -q UP", nozzle->name);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2135,10 +2149,10 @@ static int check_knet_up_down(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", nozzle->nozzlename);
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", nozzle->nozzlename);
++		 "ifconfig %s | grep -q UP", nozzle->name);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2481,10 +2495,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", nozzle->nozzlename, testipv4_1);
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv4_1);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2565,10 +2579,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", nozzle->nozzlename, testipv4_1);
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv4_1);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2599,10 +2613,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
+@@ -2633,10 +2647,10 @@ static int check_knet_set_del_ip(void)
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+ #ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->nozzlename, testipv6_1);
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+ #endif
+ #ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->nozzlename, testipv6_1);
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+ 	err = _execute_shell(verifycmd, &error_string);
+ 	if (error_string) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0099-build-fix-build-on-BSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0099-build-fix-build-on-BSD.patch
new file mode 100644
index 000000000..3ea4d2d2e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0099-build-fix-build-on-BSD.patch
@@ -0,0 +1,23 @@ 
+From 50793554ac4a7aedb329acee1591f18f9d8056b9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Dec 2017 06:47:40 +0100
+Subject: [PATCH] [build] fix build on BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index b258f484..3de54da0 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -230,7 +230,7 @@ static void _close(nozzle_t nozzle)
+ 
+ #ifdef KNET_BSD
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(nozzle->ifname, nozzle->name, IFNAMSIZ);
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
+ 
+ 	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0100-nozzle-rename-lib_mutex-to-config_mutex.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0100-nozzle-rename-lib_mutex-to-config_mutex.patch
new file mode 100644
index 000000000..cf568c16f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0100-nozzle-rename-lib_mutex-to-config_mutex.patch
@@ -0,0 +1,283 @@ 
+From d58c5756bd619baa0546cbcbeb8a7998708157c4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 18 Dec 2017 06:35:10 +0100
+Subject: [PATCH] [nozzle] rename lib_mutex to config_mutex
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 60 +++++++++++++++++++++----------------------
+ 1 file changed, 30 insertions(+), 30 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 3de54da0..24ed6e72 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -40,7 +40,7 @@
+ 
+ static int lib_init = 0;
+ static struct nozzle_lib_config lib_cfg;
+-static pthread_mutex_t lib_mutex = PTHREAD_MUTEX_INITIALIZER;
++static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+ /* forward declarations */
+ static int _execute_shell(const char *command, char **error_string);
+@@ -349,7 +349,7 @@ nozzle_t nozzle_get_handle_by_name(char *devname)
+ 		return NULL;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return NULL;
+@@ -366,7 +366,7 @@ nozzle_t nozzle_get_handle_by_name(char *devname)
+ 		savederrno = ENOENT;
+ 	}
+ 
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return nozzle;
+ }
+@@ -436,7 +436,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		}
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return NULL;
+@@ -541,14 +541,14 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	nozzle->next = lib_cfg.head;
+ 	lib_cfg.head = nozzle;
+ 
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return nozzle;
+ 
+ out_error:
+ 	_close(nozzle);
+ 	_close_cfg();
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return NULL;
+ }
+@@ -561,7 +561,7 @@ int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ 	struct nozzle_ip *ip, *ip_next;
+ 	char *error_string = NULL;
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -602,7 +602,7 @@ int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ 	_close_cfg();
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -616,7 +616,7 @@ int nozzle_get_mtu(const nozzle_t nozzle)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -632,7 +632,7 @@ int nozzle_get_mtu(const nozzle_t nozzle)
+ 	savederrno = errno;
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	savederrno = errno;
+ 	return err;
+ }
+@@ -648,7 +648,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -692,7 +692,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 	}
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -711,7 +711,7 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -726,7 +726,7 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ 	err = _get_mac(nozzle, ether_addr);
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -741,7 +741,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -781,7 +781,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 	savederrno = errno;
+ #endif
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -801,7 +801,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -846,7 +846,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 	nozzle->up = 1;
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -897,7 +897,7 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -919,7 +919,7 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 	savederrno = errno;
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -1054,7 +1054,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -1117,7 +1117,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 	}
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -1133,7 +1133,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -1162,7 +1162,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 	}
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -1176,7 +1176,7 @@ int nozzle_get_fd(const nozzle_t nozzle)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -1191,7 +1191,7 @@ int nozzle_get_fd(const nozzle_t nozzle)
+ 	fd = nozzle->fd;
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return fd;
+ }
+@@ -1206,7 +1206,7 @@ const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+ 		return NULL;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return NULL;
+@@ -1220,7 +1220,7 @@ const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+ 	name = nozzle->name;
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return name;
+ }
+@@ -1238,7 +1238,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ 		return -1;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&lib_mutex);
++	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+@@ -1289,7 +1289,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ 	*entries = found;
+ 
+ out_clean:
+-	pthread_mutex_unlock(&lib_mutex);
++	pthread_mutex_unlock(&config_mutex);
+ 	errno = savederrno;
+ 	return err;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0101-build-split-tests-man-pages-and-build-dirs.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0101-build-split-tests-man-pages-and-build-dirs.patch
new file mode 100644
index 000000000..9efd57f1d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0101-build-split-tests-man-pages-and-build-dirs.patch
@@ -0,0 +1,238 @@ 
+From e2013b4cbdd8dfe082400c7a8ffd0ffdb875e63b Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 18 Dec 2017 06:51:13 +0100
+Subject: [PATCH] [build] split tests, man pages and build dirs
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac                                  |  3 ++
+ libnozzle/Makefile.am                         | 30 +++------------
+ libnozzle/man/Doxyfile.in                     | 17 +++++++++
+ libnozzle/man/Makefile.am                     | 27 +++++++++++++
+ libnozzle/tests/Makefile.am                   | 38 +++++++++++++++++++
+ libnozzle/{ => tests}/api-test-coverage       |  0
+ .../tap_updown_bad/down.d/kronostest          |  0
+ .../tap_updown_bad/post-down.d/kronostest     |  0
+ .../tap_updown_bad/pre-up.d/kronostest        |  0
+ .../tap_updown_bad/up.d/kronostest            |  0
+ .../tap_updown_good/down.d/kronostest         |  0
+ .../tap_updown_good/post-down.d/kronostest    |  0
+ .../tap_updown_good/pre-up.d/kronostest       |  0
+ .../tap_updown_good/up.d/kronostest           |  0
+ 14 files changed, 91 insertions(+), 24 deletions(-)
+ create mode 100644 libnozzle/man/Doxyfile.in
+ create mode 100644 libnozzle/man/Makefile.am
+ create mode 100644 libnozzle/tests/Makefile.am
+ rename libnozzle/{ => tests}/api-test-coverage (100%)
+ rename libnozzle/{ => tests}/tap_updown_bad/down.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_bad/post-down.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_bad/pre-up.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_bad/up.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_good/down.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_good/post-down.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_good/pre-up.d/kronostest (100%)
+ rename libnozzle/{ => tests}/tap_updown_good/up.d/kronostest (100%)
+
+diff --git a/configure.ac b/configure.ac
+index ed6eb3ef..686157e7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -500,6 +500,9 @@ AC_CONFIG_FILES([
+ 		init/Makefile
+ 		libnozzle/Makefile
+ 		libnozzle/libnozzle.pc
++		libnozzle/tests/Makefile
++		libnozzle/man/Doxyfile
++		libnozzle/man/Makefile
+ 		kronosnetd/Makefile
+ 		kronosnetd/kronosnetd.logrotate
+ 		libknet/Makefile
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 563c47ec..3d4111d9 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -10,16 +10,17 @@ MAINTAINERCLEANFILES	= Makefile.in
+ 
+ include $(top_srcdir)/build-aux/check.mk
+ 
+-
+ SYMFILE			= libnozzle_exported_syms
+ 
+-EXTRA_DIST		= $(SYMFILE) tap_updown_bad tap_updown_good api-test-coverage
++EXTRA_DIST		= $(SYMFILE)
+ 
+-sources			= libnozzle.c
++if BUILD_LIBNOZZLE
++
++SUBDIRS			= . tests man
+ 
+ libversion		= 1:0:0
+ 
+-if BUILD_LIBNOZZLE
++sources			= libnozzle.c
+ 
+ include_HEADERS		= libnozzle.h
+ 
+@@ -44,25 +45,6 @@ libnozzle_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 
+ libnozzle_la_LIBADD	= $(PTHREAD_LIBS)
+ 
+-check_PROGRAMS		= nozzle_test
+-
+-TESTS			= $(check_PROGRAMS)
+-
+-noinst_PROGRAMS		= $(check_PROGRAMS)
+-
+-check-local: check-api-test-coverage
+-
+-check-api-test-coverage:
+-	chmod u+x $(top_srcdir)/libnozzle/api-test-coverage
+-	$(top_srcdir)/libnozzle/api-test-coverage $(top_srcdir) $(top_builddir)
+-
+-nozzle_test_SOURCES	= $(sources)
+-
+-nozzle_test_CPPFLAGS	= -DTEST \
+-			  -DABSBUILDDIR=\"$(abs_builddir)\"
+-
+-nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS)
+-
+-nozzle_test_LDFLAGS	= $(PTHREAD_LIBS)
++dist_man_MANS		= man
+ 
+ endif
+diff --git a/libnozzle/man/Doxyfile.in b/libnozzle/man/Doxyfile.in
+new file mode 100644
+index 00000000..78b1f9b2
+--- /dev/null
++++ b/libnozzle/man/Doxyfile.in
+@@ -0,0 +1,17 @@
++#
++# Copyright (C) 2017 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#         Christine Caulfield <ccaulfie@redhat.com>
++#
++# This software licensed under GPL-2.0+, LGPL-2.0+
++#
++PROJECT_NAME	       = @PACKAGE_NAME@
++PROJECT_NUMBER         = @PACKAGE_VERSION@
++INPUT                  = @srcdir@/../libnozzle.h
++XML_OUTPUT             = @abs_builddir@/xml
++GENERATE_XML           = YES
++XML_PROGRAMLISTING     = NO
++AUTOLINK_SUPPORT       = NO
++GENERATE_HTML          = NO
++GENERATE_LATEX         = NO
+diff --git a/libnozzle/man/Makefile.am b/libnozzle/man/Makefile.am
+new file mode 100644
+index 00000000..49381eef
+--- /dev/null
++++ b/libnozzle/man/Makefile.am
+@@ -0,0 +1,27 @@
++#
++# Copyright (C) 2017 Red Hat, Inc.  All rights reserved.
++#
++# Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+, LGPL-2.0+
++#
++
++MAINTAINERCLEANFILES	= Makefile.in
++
++include $(top_srcdir)/build-aux/check.mk
++
++dist_man_MANS =
++
++update-man-pages: doxyfile.stamp
++
++doxyfile.stamp: Doxyfile
++if MANPAGEUPDATES
++	$(DOXYGEN) Doxyfile
++	$(DOXY2MAN) -o $(abs_srcdir) -s 3 --short-pkg @PACKAGE_NAME@ --pkg "Kronosnet Programmer's Manual" $(builddir)/xml/libnozzle_8h.xml
++else
++	@echo this system does not have doxy2man or doxygen installed. Unable to update man pages automatically.
++endif
++	touch doxyfile.stamp
++
++clean-local:
++	rm -rf doxyfile.stamp xml
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+new file mode 100644
+index 00000000..73cd8ccc
+--- /dev/null
++++ b/libnozzle/tests/Makefile.am
+@@ -0,0 +1,38 @@
++#
++# Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+, LGPL-2.0+
++#
++
++MAINTAINERCLEANFILES	= Makefile.in
++
++include $(top_srcdir)/build-aux/check.mk
++
++EXTRA_DIST		= tap_updown_bad tap_updown_good api-test-coverage
++
++if BUILD_LIBNOZZLE
++
++check_PROGRAMS		= nozzle_test
++
++TESTS			= $(check_PROGRAMS)
++
++noinst_PROGRAMS		= $(check_PROGRAMS)
++
++check-local: check-api-test-coverage
++
++check-api-test-coverage:
++	chmod u+x $(top_srcdir)/libnozzle/api-test-coverage
++	$(top_srcdir)/libnozzle/api-test-coverage $(top_srcdir) $(top_builddir)
++
++nozzle_test_SOURCES	= ../libnozzle.c
++
++nozzle_test_CPPFLAGS	= -DTEST \
++			  -DABSBUILDDIR=\"$(abs_builddir)\"
++
++nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS)
++
++nozzle_test_LDFLAGS	= $(PTHREAD_LIBS)
++
++endif
+diff --git a/libnozzle/api-test-coverage b/libnozzle/tests/api-test-coverage
+similarity index 100%
+rename from libnozzle/api-test-coverage
+rename to libnozzle/tests/api-test-coverage
+diff --git a/libnozzle/tap_updown_bad/down.d/kronostest b/libnozzle/tests/tap_updown_bad/down.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_bad/down.d/kronostest
+rename to libnozzle/tests/tap_updown_bad/down.d/kronostest
+diff --git a/libnozzle/tap_updown_bad/post-down.d/kronostest b/libnozzle/tests/tap_updown_bad/post-down.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_bad/post-down.d/kronostest
+rename to libnozzle/tests/tap_updown_bad/post-down.d/kronostest
+diff --git a/libnozzle/tap_updown_bad/pre-up.d/kronostest b/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_bad/pre-up.d/kronostest
+rename to libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
+diff --git a/libnozzle/tap_updown_bad/up.d/kronostest b/libnozzle/tests/tap_updown_bad/up.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_bad/up.d/kronostest
+rename to libnozzle/tests/tap_updown_bad/up.d/kronostest
+diff --git a/libnozzle/tap_updown_good/down.d/kronostest b/libnozzle/tests/tap_updown_good/down.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_good/down.d/kronostest
+rename to libnozzle/tests/tap_updown_good/down.d/kronostest
+diff --git a/libnozzle/tap_updown_good/post-down.d/kronostest b/libnozzle/tests/tap_updown_good/post-down.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_good/post-down.d/kronostest
+rename to libnozzle/tests/tap_updown_good/post-down.d/kronostest
+diff --git a/libnozzle/tap_updown_good/pre-up.d/kronostest b/libnozzle/tests/tap_updown_good/pre-up.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_good/pre-up.d/kronostest
+rename to libnozzle/tests/tap_updown_good/pre-up.d/kronostest
+diff --git a/libnozzle/tap_updown_good/up.d/kronostest b/libnozzle/tests/tap_updown_good/up.d/kronostest
+similarity index 100%
+rename from libnozzle/tap_updown_good/up.d/kronostest
+rename to libnozzle/tests/tap_updown_good/up.d/kronostest
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0102-nozzle-split-code-around-to-separate-libnozzle-and-t.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0102-nozzle-split-code-around-to-separate-libnozzle-and-t.patch
new file mode 100644
index 000000000..582aaf62b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0102-nozzle-split-code-around-to-separate-libnozzle-and-t.patch
@@ -0,0 +1,4495 @@ 
+From 9be67d9848d739fb8e92e8ac743223c42b270dfb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 18 Dec 2017 07:17:39 +0100
+Subject: [PATCH] [nozzle] split code around to separate libnozzle and
+ testsuite
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/Makefile.am         |    3 +-
+ libnozzle/internals.c         | 1259 +++++++++++++++++++++++++
+ libnozzle/internals.h         |    3 +
+ libnozzle/libnozzle.c         | 1623 ---------------------------------
+ libnozzle/tests/Makefile.am   |   12 +-
+ libnozzle/tests/nozzle_test.c | 1507 ++++++++++++++++++++++++++++++
+ 6 files changed, 2778 insertions(+), 1629 deletions(-)
+ create mode 100644 libnozzle/internals.c
+ create mode 100644 libnozzle/tests/nozzle_test.c
+
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 3d4111d9..57e97065 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -20,7 +20,8 @@ SUBDIRS			= . tests man
+ 
+ libversion		= 1:0:0
+ 
+-sources			= libnozzle.c
++sources			= libnozzle.c \
++			  internals.c
+ 
+ include_HEADERS		= libnozzle.h
+ 
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+new file mode 100644
+index 00000000..24d988d8
+--- /dev/null
++++ b/libnozzle/internals.c
+@@ -0,0 +1,1259 @@
++/*
++ * Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdlib.h>
++#include <string.h>
++#include <sys/types.h>
++#include <sys/stat.h>
++#include <sys/wait.h>
++#include <unistd.h>
++#include <limits.h>
++#include <stdio.h>
++#include <stdint.h>
++
++#include "libnozzle.h"
++#include "internals.h"
++
++static int _read_pipe(int fd, char **file, size_t *length)
++{
++	char buf[4096];
++	int n;
++	int done = 0;
++
++	*file = NULL;
++	*length = 0;
++
++	memset(buf, 0, sizeof(buf));
++
++	while (!done) {
++
++		n = read(fd, buf, sizeof(buf));
++
++		if (n < 0) {
++			if (errno == EINTR)
++				continue;
++
++			if (*file)
++				free(*file);
++
++			return n;
++		}
++
++		if (n == 0 && (!*length))
++			return 0;
++
++		if (n == 0)
++			done = 1;
++
++		if (*file)
++			*file = realloc(*file, (*length) + n + done);
++		else
++			*file = malloc(n + done);
++
++		if (!*file)
++			return -1;
++
++		memmove((*file) + (*length), buf, n);
++		*length += (done + n);
++	}
++
++	/* Null terminator */
++	(*file)[(*length) - 1] = 0;
++
++	return 0;
++}
++
++int _execute_shell(const char *command, char **error_string)
++{
++	pid_t pid;
++	int status, err = 0;
++	int fd[2];
++	size_t size = 0;
++
++	if ((command == NULL) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	*error_string = NULL;
++
++	err = pipe(fd);
++	if (err)
++		goto out_clean;
++
++	pid = fork();
++	if (pid < 0) {
++		err = pid;
++		goto out_clean;
++	}
++
++	if (pid) { /* parent */
++
++		close(fd[1]);
++		err = _read_pipe(fd[0], error_string, &size);
++		if (err)
++			goto out_clean0;
++
++		waitpid(pid, &status, 0);
++		if (!WIFEXITED(status)) {
++			err = -1;
++			goto out_clean0;
++		}
++		if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
++			err = WEXITSTATUS(status);
++			goto out_clean0;
++		}
++		goto out_clean0;
++	} else { /* child */
++		close(0);
++		close(1);
++		close(2);
++
++		close(fd[0]);
++		dup2(fd[1], 1);
++		dup2(fd[1], 2);
++		close(fd[1]);
++
++		execlp("/bin/sh", "/bin/sh", "-c", command, NULL);
++		exit(EXIT_FAILURE);
++	}
++
++out_clean:
++	close(fd[1]);
++out_clean0:
++	close(fd[0]);
++
++	return err;
++}
++
++int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string)
++{
++	char command[PATH_MAX];
++	struct stat sb;
++	int err = 0;
++
++	if (!nozzle->hasupdown)
++		return 0;
++
++	memset(command, 0, PATH_MAX);
++
++	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action, nozzle->name);
++
++	err = stat(command, &sb);
++	if ((err < 0) && (errno == ENOENT))
++		return 0;
++
++	err = _execute_shell(command, error_string);
++	if ((!err) && (*error_string)) {
++		free(*error_string);
++		*error_string = NULL;
++	}
++
++	return err;
++}
++
++#if 0
++static int _check(const nozzle_t nozzle)
++{
++	nozzle_t temp = lib_cfg.head;
++
++	if (!nozzle) {
++		return 0;
++	}
++
++	while (temp != NULL) {
++		if (nozzle == temp)
++			return 1;
++
++		temp = temp->next;
++	}
++
++	return 0;
++}
++
++static void _close(nozzle_t nozzle)
++{
++#ifdef KNET_BSD
++	struct ifreq ifr;
++#endif
++
++	if (!nozzle)
++		return;
++
++	if (nozzle->fd)
++		close(nozzle->fd);
++
++#ifdef KNET_BSD
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
++#endif
++
++	free(nozzle);
++
++	return;
++}
++
++static void _close_cfg(void)
++{
++	if (lib_cfg.head == NULL) {
++		close(lib_cfg.ioctlfd);
++		lib_init = 0;
++	}
++}
++
++static int _get_mtu(const nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	err = ifr.ifr_mtu;
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
++static int _get_mac(const nozzle_t nozzle, char **ether_addr)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++	char mac[MACADDR_CHAR_MAX];
++#ifdef KNET_BSD
++	struct ifaddrs *ifap = NULL;
++	struct ifaddrs *ifa;
++	int found = 0;
++#endif
++
++	memset(&mac, 0, MACADDR_CHAR_MAX);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++#ifdef KNET_LINUX
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ether_ntoa_r((struct ether_addr *)ifr.ifr_hwaddr.sa_data, mac);
++#endif
++#ifdef KNET_BSD
++	/*
++	 * there is no ioctl to get the ether address of an interface on FreeBSD
++	 * (not to be confused with hwaddr). Use workaround described here:
++	 * https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
++	 */
++	err = getifaddrs(&ifap);
++	if (err < 0) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ifa = ifap;
++
++	while (ifa) {
++		if (!strncmp(nozzle->name, ifa->ifa_name, IFNAMSIZ)) {
++			found = 1;
++			break;
++		}
++		ifa=ifa->ifa_next;
++	}
++
++	if (found) {
++		ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
++	} else {
++		errno = EINVAL;
++		err = -1;
++	}
++	freeifaddrs(ifap);
++
++	if (err) {
++		goto out_clean;
++	}
++
++#endif
++	*ether_addr = strdup(mac);
++	if (!*ether_addr) {
++		savederrno = errno;
++		err = -1;
++	}
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
++nozzle_t nozzle_get_handle_by_name(char *devname)
++{
++	int savederrno = 0;
++	nozzle_t nozzle;
++
++	if ((devname == NULL) || (strlen(devname) > IFNAMSIZ)) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
++
++	nozzle = lib_cfg.head;
++	while (nozzle != NULL) {
++		if (!strcmp(devname, nozzle->name))
++			break;
++		nozzle = nozzle->next;
++	}
++
++	if (!nozzle) {
++		savederrno = ENOENT;
++	}
++
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return nozzle;
++}
++
++nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
++{
++	int savederrno = 0;
++	nozzle_t nozzle = NULL;
++	char *temp_mac = NULL;
++#ifdef KNET_LINUX
++	struct ifreq ifr;
++#endif
++#ifdef KNET_BSD
++	uint16_t i;
++	long int nozzlenum = 0;
++	char curnozzle[IFNAMSIZ];
++#endif
++
++	if (devname == NULL) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	if (devname_size < IFNAMSIZ) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	if (strlen(devname) > IFNAMSIZ) {
++		errno = E2BIG;
++		return NULL;
++	}
++
++#ifdef KNET_BSD
++	/*
++	 * BSD does not support named devices like Linux
++	 * but it is possible to force a nozzleX device number
++	 * where X is 0 to 255.
++	 */
++	if (strlen(devname)) {
++		if (strncmp(devname, "tap", 3)) {
++			errno = EINVAL;
++			return NULL;
++		}
++		errno = 0;
++		nozzlenum = strtol(devname+3, NULL, 10);
++		if (errno) {
++			errno = EINVAL;
++			return NULL;
++		}
++		if ((nozzlenum < 0) || (nozzlenum > 255)) {
++			errno = EINVAL;
++			return NULL;
++		}
++	}
++#endif
++
++	if (updownpath) {
++		/* only absolute paths */
++		if (updownpath[0] != '/') {
++			errno = EINVAL;
++			return NULL;
++		}
++		if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
++			errno = E2BIG;
++			return NULL;
++		}
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
++
++	if (!lib_init) {
++		lib_cfg.head = NULL;
++#ifdef KNET_LINUX
++		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
++#endif
++#ifdef KNET_BSD
++		lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
++#endif
++		if (lib_cfg.ioctlfd < 0) {
++			savederrno = errno;
++			goto out_error;
++		}
++		lib_init = 1;
++	}
++
++	nozzle = malloc(sizeof(struct nozzle_iface));
++	if (!nozzle) {
++		savederrno = ENOMEM;
++		goto out_error;
++	}
++
++	memset(nozzle, 0, sizeof(struct nozzle_iface));
++
++#ifdef KNET_BSD
++	if (!strlen(devname)) {
++		for (i = 0; i < 256; i++) {
++			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
++			nozzle->fd = open(curnozzle, O_RDWR);
++			savederrno = errno;
++			if (nozzle->fd > 0) {
++				break;
++			}
++		}
++		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
++	} else {
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
++		nozzle->fd = open(curnozzle, O_RDWR);
++		savederrno = errno;
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
++	}
++	if (nozzle->fd < 0) {
++		errno = EBUSY;
++		goto out_error;
++	}
++	strncpy(devname, curnozzle, IFNAMSIZ);
++	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
++#endif
++
++#ifdef KNET_LINUX
++	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, devname, IFNAMSIZ);
++	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
++
++	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
++		errno = EBUSY;
++		goto out_error;
++	}
++
++	strncpy(devname, ifname, IFNAMSIZ);
++	strncpy(nozzle->name, ifname, IFNAMSIZ);
++#endif
++
++	nozzle->default_mtu = _get_mtu(nozzle);
++	if (nozzle->default_mtu < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	if (_get_mac(nozzle, &temp_mac) < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	strncpy(nozzle->default_mac, temp_mac, 18);
++	free(temp_mac);
++
++	if (updownpath) {
++		int len = strlen(updownpath);
++
++		strcpy(nozzle->updownpath, updownpath);
++		if (nozzle->updownpath[len-1] != '/') {
++			nozzle->updownpath[len] = '/';
++		}
++		nozzle->hasupdown = 1;
++	}
++
++	nozzle->next = lib_cfg.head;
++	lib_cfg.head = nozzle;
++
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return nozzle;
++
++out_error:
++	_close(nozzle);
++	_close_cfg();
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return NULL;
++}
++
++int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
++{
++	int err = 0, savederrno = 0;
++	nozzle_t temp = lib_cfg.head;
++	nozzle_t prev = lib_cfg.head;
++	struct nozzle_ip *ip, *ip_next;
++	char *error_string = NULL;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	while ((temp) && (temp != nozzle)) {
++		prev = temp;
++		temp = temp->next;
++	}
++
++	if (nozzle == prev) {
++		lib_cfg.head = nozzle->next;
++	} else {
++		prev->next = nozzle->next;
++	}
++
++	_set_down(nozzle, error_down, error_postdown);
++
++	ip = nozzle->ip;
++	while (ip) {
++		ip_next = ip->next;
++		_set_ip(nozzle, "del", ip->ipaddr, ip->prefix, &error_string, 0);
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++		free(ip);
++		ip = ip_next;
++	}
++
++	_close(nozzle);
++	_close_cfg();
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_get_mtu(const nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = _get_mtu(nozzle);
++	savederrno = errno;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	savederrno = errno;
++	return err;
++}
++
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
++{
++	int err = 0, savederrno = 0;
++	struct nozzle_ip *tmp_ip;
++	struct ifreq ifr;
++
++	if ((!nozzle) || (!mtu) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = nozzle->current_mtu = _get_mtu(nozzle);
++	if (err < 0) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	ifr.ifr_mtu = mtu;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
++		tmp_ip = nozzle->ip;
++		while(tmp_ip) {
++			if (tmp_ip->domain == AF_INET6) {
++				err = _set_ip(nozzle, "add", tmp_ip->ipaddr, tmp_ip->prefix, error_string, 0);
++				if (err) {
++					savederrno = errno;
++					err = -1;
++					goto out_clean;
++				}
++			}
++			tmp_ip = tmp_ip->next;
++		}
++	}
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
++{
++	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
++}
++
++int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
++{
++	int err = 0, savederrno = 0;
++
++	if ((!nozzle) || (!ether_addr)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = _get_mac(nozzle, ether_addr);
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	if ((!nozzle) || (!ether_addr)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++#ifdef KNET_LINUX
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	memmove(ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &ifr);
++	savederrno = errno;
++#endif
++#ifdef KNET_BSD
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	memmove(ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
++	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &ifr);
++	savederrno = errno;
++#endif
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_reset_mac(nozzle_t nozzle)
++{
++	return nozzle_set_mac(nozzle, nozzle->default_mac);
++}
++
++int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	if ((nozzle->hasupdown) && ((!error_preup) || (!error_up))) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	if (nozzle->up) {
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	_exec_updown(nozzle, "pre-up.d", error_preup);
++
++	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	_exec_updown(nozzle, "up.d", error_up);
++
++	nozzle->up = 1;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	if (!nozzle->up) {
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	_exec_updown(nozzle, "down.d", error_down);
++
++	ifr.ifr_flags &= ~IFF_UP;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	_exec_updown(nozzle, "post-down.d", error_postdown);
++
++	nozzle->up = 0;
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
++{
++	int err = 0, savederrno = 0;
++
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	if ((nozzle->hasupdown) && ((!error_down) || (!error_postdown))) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = _set_down(nozzle, error_down, error_postdown);
++	savederrno = errno;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++static char *_get_v4_broadcast(const char *ipaddr, const char *prefix)
++{
++	int prefix_len;
++	struct in_addr mask;
++	struct in_addr broadcast;
++	struct in_addr address;
++
++	prefix_len = atoi(prefix);
++
++	if ((prefix_len > 32) || (prefix_len < 0))
++		return NULL;
++
++	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
++		return NULL;
++
++	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
++
++	memset(&broadcast, 0, sizeof(broadcast));
++	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
++
++	return strdup(inet_ntoa(broadcast));
++}
++
++static int _set_ip(nozzle_t nozzle, const char *command,
++		      const char *ipaddr, const char *prefix,
++		      char **error_string, int secondary)
++{
++	char *broadcast = NULL;
++	char cmdline[4096];
++#ifdef KNET_BSD
++	char proto[6];
++	int v4 = 1;
++
++	snprintf(proto, sizeof(proto), "inet");
++#endif
++
++	if (!strchr(ipaddr, ':')) {
++		broadcast = _get_v4_broadcast(ipaddr, prefix);
++		if (!broadcast) {
++			errno = EINVAL;
++			return -1;
++		}
++	}
++#ifdef KNET_BSD
++	  else {
++		v4 = 0;
++		snprintf(proto, sizeof(proto), "inet6");
++	}
++#endif
++
++	memset(cmdline, 0, sizeof(cmdline));
++
++#ifdef KNET_LINUX
++	if (broadcast) {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ip addr %s %s/%s dev %s broadcast %s",
++			 command, ipaddr, prefix,
++			 nozzle->name, broadcast);
++	} else {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ip addr %s %s/%s dev %s",
++			command, ipaddr, prefix,
++			nozzle->name);
++	}
++#endif
++#ifdef KNET_BSD
++	if (!strcmp(command, "add")) {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ifconfig %s %s %s/%s",
++			 nozzle->name, proto, ipaddr, prefix);
++		if (broadcast) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " broadcast %s", broadcast);
++		}
++		if ((secondary) && (v4)) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " alias");
++		}
++	} else {
++		snprintf(cmdline, sizeof(cmdline)-1,
++				 "ifconfig %s %s %s/%s delete",
++				 nozzle->name, proto, ipaddr, prefix);
++	}
++#endif
++	if (broadcast) {
++		free(broadcast);
++	}
++	return _execute_shell(cmdline, error_string);
++}
++
++static int _find_ip(nozzle_t nozzle,
++			const char *ipaddr, const char *prefix,
++			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
++{
++	struct nozzle_ip *local_ip, *local_ip_prev;
++	int found = 0;
++
++	local_ip = local_ip_prev = nozzle->ip;
++
++	while(local_ip) {
++		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
++			found = 1;
++			break;
++		}
++		local_ip_prev = local_ip;
++		local_ip = local_ip->next;
++	}
++
++	if (found) {
++		*ip = local_ip;
++		*ip_prev = local_ip_prev;
++	}
++
++	return found;
++}
++
++int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
++{
++	int err = 0, savederrno = 0;
++	int found = 0;
++	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
++	int secondary = 0;
++
++	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
++	if (found) {
++		goto out_clean;
++	}
++
++	ip = malloc(sizeof(struct nozzle_ip));
++	if (!ip) {
++		savederrno = errno;
++		err = -1 ;
++		goto out_clean;
++	}
++
++	memset(ip, 0, sizeof(struct nozzle_ip));
++	strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
++	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
++	if (!strchr(ip->ipaddr, ':')) {
++		ip->domain = AF_INET;
++	} else {
++		ip->domain = AF_INET6;
++	}
++
++	/*
++	 * if user asks for an IPv6 address, but MTU < 1280
++	 * store the IP and bring it up later if and when MTU > 1280
++	 */
++	if ((ip->domain == AF_INET6) && (_get_mtu(nozzle) < 1280)) {
++		err = 0;
++	} else {
++		if (nozzle->ip) {
++			secondary = 1;
++		}
++		err = _set_ip(nozzle, "add", ipaddr, prefix, error_string, secondary);
++		savederrno = errno;
++	}
++
++	if (err) {
++		free(ip);
++		goto out_clean;
++	}
++
++	if (nozzle->ip) {
++		ip_last = nozzle->ip;
++		while (ip_last->next != NULL) {
++			ip_last = ip_last->next;
++		}
++		ip_last->next = ip;
++	} else {
++		nozzle->ip = ip;
++	}
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
++{
++	int err = 0, savederrno = 0;
++        int found = 0;
++	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
++
++	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
++	if (!found) {
++		goto out_clean;
++	}
++
++	err = _set_ip(nozzle, "del", ipaddr, prefix, error_string, 0);
++	savederrno = errno;
++	if (!err) {
++		if (ip == ip_prev) {
++			nozzle->ip = ip->next;
++		} else {
++			ip_prev->next = ip->next;
++		}
++		free(ip);
++	}
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_get_fd(const nozzle_t nozzle)
++{
++	int fd = -1, savederrno = 0;
++
++	if (!nozzle) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		savederrno = ENOENT;
++		fd = -1;
++		goto out_clean;
++	}
++
++	fd = nozzle->fd;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return fd;
++}
++
++const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
++{
++	int savederrno = 0;
++	char *name = NULL;
++
++	if (!nozzle) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
++
++	if (!_check(nozzle)) {
++		errno = ENOENT;
++		goto out_clean;
++	}
++
++	name = nozzle->name;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return name;
++}
++
++int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
++{
++	int err = 0, savederrno = 0;
++	int found = 0;
++	char *ip_list = NULL;
++	int size = 0, offset = 0, len;
++	struct nozzle_ip *ip = NULL;
++
++	if ((!nozzle) || (!ipaddr_list) || (!entries)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!_check(nozzle)) {
++		errno = EINVAL;
++		goto out_clean;
++	}
++
++	ip = nozzle->ip;
++
++	while (ip) {
++		found++;
++		ip = ip->next;
++	}
++
++	if (!found) {
++		*ipaddr_list = NULL;
++		*entries = 0;
++		goto out_clean;
++	}
++
++	size = found * (IPADDR_CHAR_MAX + PREFIX_CHAR_MAX + 2);
++
++	ip_list = malloc(size);
++	if (!ip_list) {
++		savederrno = errno;
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(ip_list, 0, size);
++
++	ip = nozzle->ip;
++
++	while (ip) {
++		len = strlen(ip->ipaddr);
++		memmove(ip_list + offset, ip->ipaddr, len);
++		offset = offset + len + 1;
++		len = strlen(ip->prefix);
++		memmove(ip_list + offset, ip->prefix, len);
++		offset = offset + len + 1;
++		ip = ip->next;
++	}
++
++	*ipaddr_list = ip_list;
++	*entries = found;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++#endif
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index eaaa09e4..166f8700 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -60,4 +60,7 @@ struct nozzle_iface {
+ 
+ #define ifname ifr.ifr_name
+ 
++int _execute_shell(const char *command, char **error_string);
++int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string);
++
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 24ed6e72..6d4efb30 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -43,9 +43,6 @@ static struct nozzle_lib_config lib_cfg;
+ static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+ /* forward declarations */
+-static int _execute_shell(const char *command, char **error_string);
+-static int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string);
+-static int _read_pipe(int fd, char **file, size_t *length);
+ static int _check(const nozzle_t nozzle);
+ static void _close(nozzle_t nozzle);
+ static void _close_cfg(void);
+@@ -60,144 +57,6 @@ static int _find_ip(nozzle_t nozzle,
+ 			const char *ipaddr, const char *prefix,
+ 			struct nozzle_ip **ip, struct nozzle_ip **ip_prev);
+ 
+-static int _read_pipe(int fd, char **file, size_t *length)
+-{
+-	char buf[4096];
+-	int n;
+-	int done = 0;
+-
+-	*file = NULL;
+-	*length = 0;
+-
+-	memset(buf, 0, sizeof(buf));
+-
+-	while (!done) {
+-
+-		n = read(fd, buf, sizeof(buf));
+-
+-		if (n < 0) {
+-			if (errno == EINTR)
+-				continue;
+-
+-			if (*file)
+-				free(*file);
+-
+-			return n;
+-		}
+-
+-		if (n == 0 && (!*length))
+-			return 0;
+-
+-		if (n == 0)
+-			done = 1;
+-
+-		if (*file)
+-			*file = realloc(*file, (*length) + n + done);
+-		else
+-			*file = malloc(n + done);
+-
+-		if (!*file)
+-			return -1;
+-
+-		memmove((*file) + (*length), buf, n);
+-		*length += (done + n);
+-	}
+-
+-	/* Null terminator */
+-	(*file)[(*length) - 1] = 0;
+-
+-	return 0;
+-}
+-
+-static int _execute_shell(const char *command, char **error_string)
+-{
+-	pid_t pid;
+-	int status, err = 0;
+-	int fd[2];
+-	size_t size = 0;
+-
+-	if ((command == NULL) || (!error_string)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	*error_string = NULL;
+-
+-	err = pipe(fd);
+-	if (err)
+-		goto out_clean;
+-
+-	pid = fork();
+-	if (pid < 0) {
+-		err = pid;
+-		goto out_clean;
+-	}
+-
+-	if (pid) { /* parent */
+-
+-		close(fd[1]);
+-		err = _read_pipe(fd[0], error_string, &size);
+-		if (err)
+-			goto out_clean0;
+-
+-		waitpid(pid, &status, 0);
+-		if (!WIFEXITED(status)) {
+-			err = -1;
+-			goto out_clean0;
+-		}
+-		if (WIFEXITED(status) && WEXITSTATUS(status) != 0) {
+-			err = WEXITSTATUS(status);
+-			goto out_clean0;
+-		}
+-		goto out_clean0;
+-	} else { /* child */
+-		close(0);
+-		close(1);
+-		close(2);
+-
+-		close(fd[0]);
+-		dup2(fd[1], 1);
+-		dup2(fd[1], 2);
+-		close(fd[1]);
+-
+-		execlp("/bin/sh", "/bin/sh", "-c", command, NULL);
+-		exit(EXIT_FAILURE);
+-	}
+-
+-out_clean:
+-	close(fd[1]);
+-out_clean0:
+-	close(fd[0]);
+-
+-	return err;
+-}
+-
+-static int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string)
+-{
+-	char command[PATH_MAX];
+-	struct stat sb;
+-	int err = 0;
+-
+-	if (!nozzle->hasupdown)
+-		return 0;
+-
+-	memset(command, 0, PATH_MAX);
+-
+-	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action, nozzle->name);
+-
+-	err = stat(command, &sb);
+-	if ((err < 0) && (errno == ENOENT))
+-		return 0;
+-
+-	err = _execute_shell(command, error_string);
+-	if ((!err) && (*error_string)) {
+-		free(*error_string);
+-		*error_string = NULL;
+-	}
+-
+-	return err;
+-}
+-
+ static int _check(const nozzle_t nozzle)
+ {
+ 	nozzle_t temp = lib_cfg.head;
+@@ -1293,1485 +1152,3 @@ out_clean:
+ 	errno = savederrno;
+ 	return err;
+ }
+-
+-#ifdef TEST
+-
+-char testipv4_1[1024];
+-char testipv4_2[1024];
+-char testipv6_1[1024];
+-char testipv6_2[1024];
+-/*
+- * use this one to randomize knet interface name
+- * for named creation test
+- */
+-uint8_t randombyte = 0;
+-
+-static int is_if_in_system(char *name)
+-{
+-	struct ifaddrs *ifap = NULL;
+-	struct ifaddrs *ifa;
+-	int found = 0;
+-
+-	if (getifaddrs(&ifap) < 0) {
+-		printf("Unable to get interface list.\n");
+-		return -1;
+-	}
+-
+-	ifa = ifap;
+-
+-	while (ifa) {
+-		if (!strncmp(name, ifa->ifa_name, IFNAMSIZ)) {
+-			found = 1;
+-			break;
+-		}
+-		ifa=ifa->ifa_next;
+-	}
+-
+-	freeifaddrs(ifap);
+-	return found;
+-}
+-
+-static int test_iface(char *name, size_t size, const char *updownpath)
+-{
+-	nozzle_t nozzle;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	nozzle=nozzle_open(name, size, updownpath);
+-	if (!nozzle) {
+-		if (lib_cfg.ioctlfd < 0)
+-			printf("Unable to open knet_socket\n");
+-		printf("Unable to open knet.\n");
+-		return -1;
+-	}
+-	printf("Created interface: %s\n", name);
+-
+-	if (is_if_in_system(name) > 0) {
+-		printf("Found interface %s on the system\n", name);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", name);
+-	}
+-
+-	if (!nozzle_get_handle_by_name(name)) {
+-		printf("Unable to find interface %s in nozzle db\n", name);
+-	} else {
+-		printf("Found interface %s in nozzle db\n", name);
+-	}
+-
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-
+-	if (error_down) {
+-		printf("Error from error_down: %s\n", error_down);
+-		free(error_down);
+-	}
+-
+-	if (error_postdown) {
+-		printf("Error from error_down: %s\n", error_postdown);
+-		free(error_postdown);
+-	}
+-
+-	if (is_if_in_system(name) == 0)
+-		printf("Successfully removed interface %s from the system\n", name);
+-
+-	return 0;
+-}
+-
+-static int check_nozzle_open_close(void)
+-{
+-	char device_name[2*IFNAMSIZ];
+-	char fakepath[PATH_MAX];
+-	size_t size = IFNAMSIZ;
+-
+-	memset(device_name, 0, sizeof(device_name));
+-
+-	printf("Creating random nozzle interface:\n");
+-	if (test_iface(device_name, size,  NULL) < 0) {
+-		printf("Unable to create random interface\n");
+-		return -1;
+-	}
+-
+-#ifdef KNET_LINUX
+-	printf("Creating kronostest%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+-	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create kronostest%u interface\n", randombyte);
+-		return -1;
+-	}
+-#endif
+-#ifdef KNET_BSD
+-	printf("Creating tap%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
+-	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create tap%u interface\n", randombyte);
+-		return -1;
+-	}
+-
+-	printf("Creating kronostest%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+-	if (test_iface(device_name, size, NULL) == 0) {
+-		printf("BSD should not accept kronostest%u interface\n", randombyte);
+-		return -1;
+-	}
+-#endif
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("Testing dev == NULL\n");
+-	errno=0;
+-	if ((test_iface(NULL, size, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	printf("Testing size < IFNAMSIZ\n");
+-	errno=0;
+-	if ((test_iface(device_name, 1, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	printf("Testing device_name size > IFNAMSIZ\n");
+-	errno=0;
+-	strcpy(device_name, "abcdefghilmnopqrstuvwz");
+-	if ((test_iface(device_name, IFNAMSIZ, NULL) >= 0) || (errno != E2BIG)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	printf("Testing updown path != abs\n");
+-	errno=0;
+-
+-	memset(device_name, 0, IFNAMSIZ);
+-	if ((test_iface(device_name, IFNAMSIZ, "foo")  >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	memset(fakepath, 0, PATH_MAX);
+-	memset(fakepath, '/', PATH_MAX - 2);
+-
+-	printf("Testing updown path > PATH_MAX\n");
+-	errno=0;
+-
+-	memset(device_name, 0, IFNAMSIZ);
+-	if ((test_iface(device_name, IFNAMSIZ, fakepath)  >= 0) || (errno != E2BIG)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int check_knet_multi_eth(void)
+-{
+-	char device_name1[IFNAMSIZ];
+-	char device_name2[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle1 = NULL;
+-	nozzle_t nozzle2 = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	printf("Testing multiple knet interface instances\n");
+-
+-	memset(device_name1, 0, size);
+-	memset(device_name2, 0, size);
+-
+-	nozzle1 = nozzle_open(device_name1, size, NULL);
+-	if (!nozzle1) {
+-		printf("Unable to init %s\n", device_name1);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (is_if_in_system(device_name1) > 0) {
+-		printf("Found interface %s on the system\n", device_name1);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", device_name1);
+-	}
+-
+-	nozzle2 = nozzle_open(device_name2, size, NULL);
+-	if (!nozzle2) {
+-		printf("Unable to init %s\n", device_name2);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (is_if_in_system(device_name2) > 0) {
+-		printf("Found interface %s on the system\n", device_name2);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", device_name2);
+-	}
+-
+-	if (nozzle1) {
+-		nozzle_close(nozzle1, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	if (nozzle2) {
+-		nozzle_close(nozzle2, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	printf("Testing error conditions\n");
+-
+-	printf("Open same device twice\n");
+-
+-	memset(device_name1, 0, size);
+-
+-	nozzle1 = nozzle_open(device_name1, size, NULL);
+-	if (!nozzle1) {
+-		printf("Unable to init %s\n", device_name1);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (is_if_in_system(device_name1) > 0) {
+-		printf("Found interface %s on the system\n", device_name1);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", device_name1);
+-	}
+-
+-	nozzle2 = nozzle_open(device_name1, size, NULL);
+-	if (nozzle2) {
+-		printf("We were able to init 2 interfaces with the same name!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (nozzle1) {
+-		nozzle_close(nozzle1, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	if (nozzle2) {
+-		nozzle_close(nozzle2, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	return err;
+-}
+-
+-static int check_knet_mtu(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *error_down = NULL, *error_postdown = NULL;
+-	char *error_string = NULL;
+-
+-	int current_mtu = 0;
+-	int expected_mtu = 1500;
+-
+-	printf("Testing get/set MTU\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Comparing default MTU\n");
+-	current_mtu = nozzle_get_mtu(nozzle);
+-	if (current_mtu < 0) {
+-		printf("Unable to get MTU\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	if (current_mtu != expected_mtu) {
+-		printf("current mtu [%d] does not match expected default [%d]\n", current_mtu, expected_mtu);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Setting MTU to 9000\n");
+-	expected_mtu = 9000;
+-	if (nozzle_set_mtu(nozzle, expected_mtu, &error_string) < 0) {
+-		printf("Unable to set MTU to %d\n", expected_mtu);
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	current_mtu = nozzle_get_mtu(nozzle);
+-	if (current_mtu < 0) {
+-		printf("Unable to get MTU\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	if (current_mtu != expected_mtu) {
+-		printf("current mtu [%d] does not match expected value [%d]\n", current_mtu, expected_mtu);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("Passing empty struct to get_mtu\n");
+-	if (nozzle_get_mtu(NULL) > 0) {
+-		printf("Something is wrong in nozzle_get_mtu sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Passing empty struct to set_mtu\n");
+-	if (nozzle_set_mtu(NULL, 1500, &error_string) == 0) {
+-		printf("Something is wrong in nozzle_set_mtu sanity checks\n"); 
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (nozzle) {
+-		nozzle_close(nozzle, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	return err;
+-}
+-
+-static int check_knet_mtu_ipv6(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	char verifycmd[1024];
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	printf("Testing get/set MTU with IPv6 address\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Adding ip: %s/64\n", testipv6_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
+-	if (error_string) {
+-		printf("add ipv6 output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		sleep(30);
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Setting MTU to 1200\n");
+-	if (nozzle_set_mtu(nozzle, 1200, &error_string) < 0) {
+-		printf("Unable to set MTU to 1200\n");
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-#ifdef KNET_LINUX
+-	if (!err) {
+-#endif
+-#ifdef KNET_BSD
+-	if (err) {
+-#endif
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/64\n", testipv6_2);
+-	err = nozzle_add_ip(nozzle, testipv6_2, "64", &error_string);
+-	if (error_string) {
+-		printf("add ipv6 output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Restoring MTU to default\n");
+-	if (nozzle_reset_mtu(nozzle, &error_string) < 0) {
+-		printf("Unable to reset mtu\n");
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (nozzle) {
+-		nozzle_close(nozzle, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	return err;
+-}
+-
+-static int check_knet_mac(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
+-	struct ether_addr *cur_mac, *tmp_mac;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	printf("Testing get/set MAC\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Get current MAC\n");
+-
+-	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
+-		printf("Unable to get current MAC address.\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Current MAC: %s\n", current_mac);
+-
+-	printf("Setting MAC: 00:01:01:01:01:01\n");
+-
+-	if (nozzle_set_mac(nozzle, "00:01:01:01:01:01") < 0) {
+-		printf("Unable to set current MAC address.\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (nozzle_get_mac(nozzle, &temp_mac) < 0) {
+-		printf("Unable to get current MAC address.\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Current MAC: %s\n", temp_mac);
+-
+-	cur_mac = ether_aton(current_mac);
+-	tmp_mac = ether_aton(temp_mac);
+-
+-	printf("Comparing MAC addresses\n");
+-	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
+-		printf("Mac addresses are not the same?!\n");
+-		err = -1;
+-		sleep(20);
+-		goto out_clean;
+-	}
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("Pass NULL to get_mac (pass1)\n");
+-	errno = 0;
+-	if ((nozzle_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to get_mac (pass2)\n");
+-	errno = 0;
+-	if ((nozzle_get_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to set_mac (pass1)\n");
+-	errno = 0;
+-	if ((nozzle_set_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to set_mac (pass2)\n");
+-	errno = 0;
+-	if ((nozzle_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (err_mac) {
+-		printf("Something managed to set err_mac!\n");
+-		err = -1;
+-		free(err_mac);
+-	}
+-
+-	if (current_mac)
+-		free(current_mac);
+-	if (temp_mac)
+-		free(temp_mac);
+-
+-	if (nozzle) {
+-		nozzle_close(nozzle, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
+-	}
+-
+-	return err;
+-}
+-
+-static int check_nozzle_execute_shell(void)
+-{
+-	int err = 0;
+-	char command[4096];
+-	char *error_string = NULL;
+-
+-	memset(command, 0, sizeof(command));
+-
+-	printf("Testing _execute_shell\n");
+-
+-	printf("command true\n");
+-
+-	err = _execute_shell("true", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to execute true ?!?!\n");
+-		goto out_clean;
+-	}
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("command false\n");
+-
+-	err = _execute_shell("false", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute false successfully?!?!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("command that outputs to stdout (enforcing redirect)\n");
+-
+-	err = _execute_shell("grep -h 2>&1", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute grep -h successfully?!?\n");
+-		err = -1;
+-		goto out_clean;
+-	} 
+-
+-	printf("command that outputs to stderr\n");
+-	err = _execute_shell("grep -h", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute grep -h successfully?!?\n");
+-		err = -1;
+-		goto out_clean;
+-	} 
+-
+-	printf("empty command\n");
+-	err = _execute_shell(NULL, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute (nil) successfully?!?!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("empty error\n");
+-	err = _execute_shell("true", NULL);
+-	if (!err) {
+-		printf("Check EINVAL filter for no error_string!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = 0;
+-
+-out_clean:
+-
+-	return err;
+-}
+-
+-static int check_knet_up_down(void)
+-{
+-	char verifycmd[1024];
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *error_string = NULL;
+-	char *error_preup = NULL, *error_up = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	printf("Testing interface up/down\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Put the interface up\n");
+-
+-	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+-	if (error_preup) {
+-		printf("preup output: %s\n", error_preup);
+-		free(error_preup);
+-		error_preup = NULL;
+-	}
+-	if (error_up) {
+-		printf("up output: %s\n", error_up);
+-		free(error_up);
+-		error_up = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to set interface up\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", nozzle->name);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", nozzle->name);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to verify inteface UP\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Put the interface down\n");
+-
+-	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to put the interface down\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", nozzle->name);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", nozzle->name);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify inteface DOWN\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-
+-	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Put the interface up\n");
+-
+-	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+-	if (error_preup) {
+-		printf("preup output: %s\n", error_preup);
+-		free(error_preup);
+-		error_preup = NULL;
+-	}
+-	if (error_up) {
+-		printf("up output: %s\n", error_up);
+-		free(error_up);
+-		error_up = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to set interface up\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Put the interface down\n");
+-
+-	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to put the interface down\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-
+-	printf("Testing interface pre-up/up/down/post-down\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Put the interface up\n");
+-
+-	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+-	if (error_preup) {
+-		printf("preup output: %s\n", error_preup);
+-		free(error_preup);
+-		error_preup = NULL;
+-	}
+-	if (error_up) {
+-		printf("up output: %s\n", error_up);
+-		free(error_up);
+-		error_up = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to set interface up\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Put the interface down\n");
+-
+-	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to put the interface down\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-
+-	printf("Test ERROR conditions\n");
+-
+-	printf("Pass NULL to nozzle set_up\n");
+-	errno = 0;
+-	if ((nozzle_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_up sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_preup set_up\n");
+-	errno = 0;
+-	if ((nozzle_set_up(nozzle, NULL, &error_up) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_up sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_up set_up\n");
+-	errno = 0;
+-	if ((nozzle_set_up(nozzle, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_up sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to nozzle set_down\n");
+-	errno = 0;
+-	if ((nozzle_set_down(NULL, &error_down, &error_postdown) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_down sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_down set_down\n");
+-	errno = 0;
+-	if ((nozzle_set_down(nozzle, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_down sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_postdown set_down\n");
+-	errno = 0;
+-	if ((nozzle_set_down(nozzle, &error_down, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_down sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-
+-	return err;
+-}
+-
+-static int check_knet_close_leak(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	printf("Testing close leak (needs valgrind)\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_2);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-
+-	return err;
+-}
+-
+-static int check_knet_set_del_ip(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	char verifycmd[1024];
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *ip_list = NULL;
+-	int ip_list_entries = 0, i, offset = 0;
+-	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+-
+-	printf("Testing interface add/remove ip\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_2);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding duplicate ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to find IP address in libnozzle db\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Checking ip: %s/24\n", testipv4_1);
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Get ip list from libnozzle:\n");
+-
+-	if (nozzle_get_ips(nozzle, &ip_list, &ip_list_entries) < 0) {
+-		printf("Not enough mem?\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	if (ip_list_entries != 2) {
+-		printf("Didn't get enough ip back from libnozzle?\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	for (i = 1; i <= ip_list_entries; i++) {
+-		printf("Found IP %s %s in libnozzle db\n", ip_list + offset, ip_list + offset + strlen(ip_list + offset) + 1);
+-		offset = offset + strlen(ip_list) + 1;
+-		offset = offset + strlen(ip_list + offset) + 1;
+-	}
+-
+-	free(ip_list);
+-
+-	printf("Deleting ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("del ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting ip: %s/24\n", testipv4_2);
+-
+-	err = nozzle_del_ip(nozzle, testipv4_2, "24", &error_string);
+-	if (error_string) {
+-		printf("del ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting again ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("del ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/64\n", testipv6_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
+-	if (error_string) {
+-		printf("add ipv6 output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting ip: %s/64\n", testipv6_1);
+-
+-	err = nozzle_del_ip(nozzle, testipv6_1, "64", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = _execute_shell(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-
+-	return err;
+-}
+-
+-static void make_local_ips(void)
+-{
+-	pid_t mypid;
+-	uint8_t *pid;
+-	uint8_t i;
+-
+-	if (sizeof(pid_t) < 4) {
+-		printf("pid_t is smaller than 4 bytes?\n");
+-		exit(77);
+-	}
+-
+-	memset(testipv4_1, 0, sizeof(testipv4_1));
+-	memset(testipv4_2, 0, sizeof(testipv4_2));
+-	memset(testipv6_1, 0, sizeof(testipv6_1));
+-	memset(testipv6_2, 0, sizeof(testipv6_2));
+-
+-	mypid = getpid();
+-	pid = (uint8_t *)&mypid;
+-
+-	for (i = 0; i < sizeof(pid_t); i++) {
+-		if (pid[i] == 0) {
+-			pid[i] = 128;
+-		}
+-	}
+-
+-	randombyte = pid[1];
+-
+-	snprintf(testipv4_1,
+-		 sizeof(testipv4_1) - 1,
+-		 "127.%u.%u.%u",
+-		 pid[1],
+-		 pid[2],
+-		 pid[0]);
+-
+-	snprintf(testipv4_2,
+-		 sizeof(testipv4_2) - 1,
+-		 "127.%u.%d.%u",
+-		 pid[1],
+-		 pid[2]+1,
+-		 pid[0]);
+-
+-	snprintf(testipv6_1,
+-		 sizeof(testipv6_1) - 1,
+-		 "fd%x:%x%x::1",
+-		 pid[1],
+-		 pid[2],
+-		 pid[0]);
+-
+-	snprintf(testipv6_2,
+-		 sizeof(testipv6_2) - 1,
+-		 "fd%x:%x%x:1::1",
+-		 pid[1],
+-		 pid[2],
+-		 pid[0]);
+-}
+-
+-int main(void)
+-{
+-	if (geteuid() != 0) {
+-		printf("This test requires root privileges\n");
+-		exit(77);
+-	}
+-
+-	make_local_ips();
+-
+-	if (check_nozzle_open_close() < 0)
+-		return -1;
+-
+-	if (check_knet_multi_eth() < 0)
+-		return -1;
+-
+-	if (check_knet_mtu() < 0)
+-		return -1;
+-
+-	if (check_knet_mtu_ipv6() < 0)
+-		return -1;
+-
+-	if (check_knet_mac() < 0)
+-		return -1;
+-
+-	if (check_nozzle_execute_shell() < 0)
+-		return -1;
+-
+-	if (check_knet_up_down() < 0)
+-		return -1;
+-
+-	if (check_knet_set_del_ip() < 0)
+-		return -1;
+-
+-	if (check_knet_close_leak() < 0)
+-		return -1;
+-
+-	return 0;
+-}
+-#endif
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 73cd8ccc..e02593df 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -23,16 +23,18 @@ noinst_PROGRAMS		= $(check_PROGRAMS)
+ check-local: check-api-test-coverage
+ 
+ check-api-test-coverage:
+-	chmod u+x $(top_srcdir)/libnozzle/api-test-coverage
+-	$(top_srcdir)/libnozzle/api-test-coverage $(top_srcdir) $(top_builddir)
++	chmod u+x $(top_srcdir)/libnozzle/tests/api-test-coverage
++	$(top_srcdir)/libnozzle/tests/api-test-coverage $(top_srcdir) $(top_builddir)
+ 
+-nozzle_test_SOURCES	= ../libnozzle.c
++nozzle_test_SOURCES	= nozzle_test.c \
++			  ../internals.c
+ 
+-nozzle_test_CPPFLAGS	= -DTEST \
++nozzle_test_CPPFLAGS	= -I$(top_srcdir)/libnozzle \
+ 			  -DABSBUILDDIR=\"$(abs_builddir)\"
+ 
+ nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS)
+ 
+-nozzle_test_LDFLAGS	= $(PTHREAD_LIBS)
++nozzle_test_LDFLAGS	= $(top_builddir)/libnozzle/libnozzle.la \
++			  $(PTHREAD_LIBS)
+ 
+ endif
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+new file mode 100644
+index 00000000..f8683b63
+--- /dev/null
++++ b/libnozzle/tests/nozzle_test.c
+@@ -0,0 +1,1507 @@
++/*
++ * Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <sys/types.h>
++#include <errno.h>
++#include <ifaddrs.h>
++#include <stdint.h>
++#include <limits.h>
++
++#ifdef KNET_LINUX
++#include <linux/if_tun.h>
++#include <netinet/ether.h>
++#endif
++#ifdef KNET_BSD
++#include <net/if_dl.h>
++#endif
++
++#include "libnozzle.h"
++#include "internals.h"
++
++char testipv4_1[1024];
++char testipv4_2[1024];
++char testipv6_1[1024];
++char testipv6_2[1024];
++/*
++ * use this one to randomize knet interface name
++ * for named creation test
++ */
++uint8_t randombyte = 0;
++
++static int is_if_in_system(char *name)
++{
++	struct ifaddrs *ifap = NULL;
++	struct ifaddrs *ifa;
++	int found = 0;
++
++	if (getifaddrs(&ifap) < 0) {
++		printf("Unable to get interface list.\n");
++		return -1;
++	}
++
++	ifa = ifap;
++
++	while (ifa) {
++		if (!strncmp(name, ifa->ifa_name, IFNAMSIZ)) {
++			found = 1;
++			break;
++		}
++		ifa=ifa->ifa_next;
++	}
++
++	freeifaddrs(ifap);
++	return found;
++}
++
++static int test_iface(char *name, size_t size, const char *updownpath)
++{
++	nozzle_t nozzle;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	nozzle=nozzle_open(name, size, updownpath);
++	if (!nozzle) {
++		printf("Unable to open knet.\n");
++		return -1;
++	}
++	printf("Created interface: %s\n", name);
++
++	if (is_if_in_system(name) > 0) {
++		printf("Found interface %s on the system\n", name);
++	} else {
++		printf("Unable to find interface %s on the system\n", name);
++	}
++
++	if (!nozzle_get_handle_by_name(name)) {
++		printf("Unable to find interface %s in nozzle db\n", name);
++	} else {
++		printf("Found interface %s in nozzle db\n", name);
++	}
++
++	nozzle_close(nozzle, &error_down, &error_postdown);
++
++	if (error_down) {
++		printf("Error from error_down: %s\n", error_down);
++		free(error_down);
++	}
++
++	if (error_postdown) {
++		printf("Error from error_down: %s\n", error_postdown);
++		free(error_postdown);
++	}
++
++	if (is_if_in_system(name) == 0)
++		printf("Successfully removed interface %s from the system\n", name);
++
++	return 0;
++}
++
++static int check_nozzle_open_close(void)
++{
++	char device_name[2*IFNAMSIZ];
++	char fakepath[PATH_MAX];
++	size_t size = IFNAMSIZ;
++
++	memset(device_name, 0, sizeof(device_name));
++
++	printf("Creating random nozzle interface:\n");
++	if (test_iface(device_name, size,  NULL) < 0) {
++		printf("Unable to create random interface\n");
++		return -1;
++	}
++
++#ifdef KNET_LINUX
++	printf("Creating kronostest%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
++	if (test_iface(device_name, size, NULL) < 0) {
++		printf("Unable to create kronostest%u interface\n", randombyte);
++		return -1;
++	}
++#endif
++#ifdef KNET_BSD
++	printf("Creating tap%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
++	if (test_iface(device_name, size, NULL) < 0) {
++		printf("Unable to create tap%u interface\n", randombyte);
++		return -1;
++	}
++
++	printf("Creating kronostest%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
++	if (test_iface(device_name, size, NULL) == 0) {
++		printf("BSD should not accept kronostest%u interface\n", randombyte);
++		return -1;
++	}
++#endif
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Testing dev == NULL\n");
++	errno=0;
++	if ((test_iface(NULL, size, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing size < IFNAMSIZ\n");
++	errno=0;
++	if ((test_iface(device_name, 1, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing device_name size > IFNAMSIZ\n");
++	errno=0;
++	strcpy(device_name, "abcdefghilmnopqrstuvwz");
++	if ((test_iface(device_name, IFNAMSIZ, NULL) >= 0) || (errno != E2BIG)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing updown path != abs\n");
++	errno=0;
++
++	memset(device_name, 0, IFNAMSIZ);
++	if ((test_iface(device_name, IFNAMSIZ, "foo")  >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	memset(fakepath, 0, PATH_MAX);
++	memset(fakepath, '/', PATH_MAX - 2);
++
++	printf("Testing updown path > PATH_MAX\n");
++	errno=0;
++
++	memset(device_name, 0, IFNAMSIZ);
++	if ((test_iface(device_name, IFNAMSIZ, fakepath)  >= 0) || (errno != E2BIG)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	return 0;
++}
++
++static int check_knet_multi_eth(void)
++{
++	char device_name1[IFNAMSIZ];
++	char device_name2[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle1 = NULL;
++	nozzle_t nozzle2 = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	printf("Testing multiple knet interface instances\n");
++
++	memset(device_name1, 0, size);
++	memset(device_name2, 0, size);
++
++	nozzle1 = nozzle_open(device_name1, size, NULL);
++	if (!nozzle1) {
++		printf("Unable to init %s\n", device_name1);
++		err = -1;
++		goto out_clean;
++	}
++
++	if (is_if_in_system(device_name1) > 0) {
++		printf("Found interface %s on the system\n", device_name1);
++	} else {
++		printf("Unable to find interface %s on the system\n", device_name1);
++	}
++
++	nozzle2 = nozzle_open(device_name2, size, NULL);
++	if (!nozzle2) {
++		printf("Unable to init %s\n", device_name2);
++		err = -1;
++		goto out_clean;
++	}
++
++	if (is_if_in_system(device_name2) > 0) {
++		printf("Found interface %s on the system\n", device_name2);
++	} else {
++		printf("Unable to find interface %s on the system\n", device_name2);
++	}
++
++	if (nozzle1) {
++		nozzle_close(nozzle1, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	if (nozzle2) {
++		nozzle_close(nozzle2, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Open same device twice\n");
++
++	memset(device_name1, 0, size);
++
++	nozzle1 = nozzle_open(device_name1, size, NULL);
++	if (!nozzle1) {
++		printf("Unable to init %s\n", device_name1);
++		err = -1;
++		goto out_clean;
++	}
++
++	if (is_if_in_system(device_name1) > 0) {
++		printf("Found interface %s on the system\n", device_name1);
++	} else {
++		printf("Unable to find interface %s on the system\n", device_name1);
++	}
++
++	nozzle2 = nozzle_open(device_name1, size, NULL);
++	if (nozzle2) {
++		printf("We were able to init 2 interfaces with the same name!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle1) {
++		nozzle_close(nozzle1, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	if (nozzle2) {
++		nozzle_close(nozzle2, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	return err;
++}
++
++static int check_knet_mtu(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *error_down = NULL, *error_postdown = NULL;
++	char *error_string = NULL;
++
++	int current_mtu = 0;
++	int expected_mtu = 1500;
++
++	printf("Testing get/set MTU\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Comparing default MTU\n");
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected default [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Setting MTU to 9000\n");
++	expected_mtu = 9000;
++	if (nozzle_set_mtu(nozzle, expected_mtu, &error_string) < 0) {
++		printf("Unable to set MTU to %d\n", expected_mtu);
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
++		err = -1;
++		goto out_clean;
++	}
++
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected value [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Passing empty struct to get_mtu\n");
++	if (nozzle_get_mtu(NULL) > 0) {
++		printf("Something is wrong in nozzle_get_mtu sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Passing empty struct to set_mtu\n");
++	if (nozzle_set_mtu(NULL, 1500, &error_string) == 0) {
++		printf("Something is wrong in nozzle_set_mtu sanity checks\n"); 
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle) {
++		nozzle_close(nozzle, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	return err;
++}
++
++static int check_knet_mtu_ipv6(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	char verifycmd[1024];
++	int err=0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	printf("Testing get/set MTU with IPv6 address\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
++	if (error_string) {
++		printf("add ipv6 output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		sleep(30);
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Setting MTU to 1200\n");
++	if (nozzle_set_mtu(nozzle, 1200, &error_string) < 0) {
++		printf("Unable to set MTU to 1200\n");
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
++		err = -1;
++		goto out_clean;
++	}
++
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++#ifdef KNET_LINUX
++	if (!err) {
++#endif
++#ifdef KNET_BSD
++	if (err) {
++#endif
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_2);
++	err = nozzle_add_ip(nozzle, testipv6_2, "64", &error_string);
++	if (error_string) {
++		printf("add ipv6 output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Restoring MTU to default\n");
++	if (nozzle_reset_mtu(nozzle, &error_string) < 0) {
++		printf("Unable to reset mtu\n");
++		if (error_string) {
++			printf("error: %s\n", error_string);
++			free(error_string);
++		}
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle) {
++		nozzle_close(nozzle, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	return err;
++}
++
++static int check_knet_mac(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
++	struct ether_addr *cur_mac, *tmp_mac;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	printf("Testing get/set MAC\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Get current MAC\n");
++
++	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Current MAC: %s\n", current_mac);
++
++	printf("Setting MAC: 00:01:01:01:01:01\n");
++
++	if (nozzle_set_mac(nozzle, "00:01:01:01:01:01") < 0) {
++		printf("Unable to set current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (nozzle_get_mac(nozzle, &temp_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Current MAC: %s\n", temp_mac);
++
++	cur_mac = ether_aton(current_mac);
++	tmp_mac = ether_aton(temp_mac);
++
++	printf("Comparing MAC addresses\n");
++	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
++		printf("Mac addresses are not the same?!\n");
++		err = -1;
++		sleep(20);
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Pass NULL to get_mac (pass1)\n");
++	errno = 0;
++	if ((nozzle_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_get_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to get_mac (pass2)\n");
++	errno = 0;
++	if ((nozzle_get_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_get_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to set_mac (pass1)\n");
++	errno = 0;
++	if ((nozzle_set_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to set_mac (pass2)\n");
++	errno = 0;
++	if ((nozzle_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (err_mac) {
++		printf("Something managed to set err_mac!\n");
++		err = -1;
++		free(err_mac);
++	}
++
++	if (current_mac)
++		free(current_mac);
++	if (temp_mac)
++		free(temp_mac);
++
++	if (nozzle) {
++		nozzle_close(nozzle, &error_down, &error_postdown);
++		if (error_down) {
++			printf("Error from error_down: %s\n", error_down);
++			free(error_down);
++		}
++		if (error_postdown) {
++			printf("Error from error_down: %s\n", error_postdown);
++			free(error_postdown);
++		}
++	}
++
++	return err;
++}
++
++static int check_nozzle_execute_shell(void)
++{
++	int err = 0;
++	char command[4096];
++	char *error_string = NULL;
++
++	memset(command, 0, sizeof(command));
++
++	printf("Testing _execute_shell\n");
++
++	printf("command true\n");
++
++	err = _execute_shell("true", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to execute true ?!?!\n");
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("command false\n");
++
++	err = _execute_shell("false", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute false successfully?!?!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("command that outputs to stdout (enforcing redirect)\n");
++
++	err = _execute_shell("grep -h 2>&1", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute grep -h successfully?!?\n");
++		err = -1;
++		goto out_clean;
++	} 
++
++	printf("command that outputs to stderr\n");
++	err = _execute_shell("grep -h", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute grep -h successfully?!?\n");
++		err = -1;
++		goto out_clean;
++	} 
++
++	printf("empty command\n");
++	err = _execute_shell(NULL, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute (nil) successfully?!?!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("empty error\n");
++	err = _execute_shell("true", NULL);
++	if (!err) {
++		printf("Check EINVAL filter for no error_string!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	err = 0;
++
++out_clean:
++
++	return err;
++}
++
++static int check_knet_up_down(void)
++{
++	char verifycmd[1024];
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++	char *error_preup = NULL, *error_up = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	printf("Testing interface up/down\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Put the interface up\n");
++
++	err = nozzle_set_up(nozzle, &error_preup, &error_up);
++	if (error_preup) {
++		printf("preup output: %s\n", error_preup);
++		free(error_preup);
++		error_preup = NULL;
++	}
++	if (error_up) {
++		printf("up output: %s\n", error_up);
++		free(error_up);
++		error_up = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to set interface up\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", nozzle->name);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to verify inteface UP\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Put the interface down\n");
++
++	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to put the interface down\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", nozzle->name);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify inteface DOWN\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++
++	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Put the interface up\n");
++
++	err = nozzle_set_up(nozzle, &error_preup, &error_up);
++	if (error_preup) {
++		printf("preup output: %s\n", error_preup);
++		free(error_preup);
++		error_preup = NULL;
++	}
++	if (error_up) {
++		printf("up output: %s\n", error_up);
++		free(error_up);
++		error_up = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to set interface up\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Put the interface down\n");
++
++	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to put the interface down\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++
++	printf("Testing interface pre-up/up/down/post-down\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Put the interface up\n");
++
++	err = nozzle_set_up(nozzle, &error_preup, &error_up);
++	if (error_preup) {
++		printf("preup output: %s\n", error_preup);
++		free(error_preup);
++		error_preup = NULL;
++	}
++	if (error_up) {
++		printf("up output: %s\n", error_up);
++		free(error_up);
++		error_up = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to set interface up\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Put the interface down\n");
++
++	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to put the interface down\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++
++	printf("Test ERROR conditions\n");
++
++	printf("Pass NULL to nozzle set_up\n");
++	errno = 0;
++	if ((nozzle_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to error_preup set_up\n");
++	errno = 0;
++	if ((nozzle_set_up(nozzle, NULL, &error_up) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to error_up set_up\n");
++	errno = 0;
++	if ((nozzle_set_up(nozzle, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to nozzle set_down\n");
++	errno = 0;
++	if ((nozzle_set_down(NULL, &error_down, &error_postdown) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to error_down set_down\n");
++	errno = 0;
++	if ((nozzle_set_down(nozzle, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to error_postdown set_down\n");
++	errno = 0;
++	if ((nozzle_set_down(nozzle, &error_down, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++
++	return err;
++}
++
++static int check_knet_close_leak(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	printf("Testing close leak (needs valgrind)\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
++	if (error_string) {
++		printf("add ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_2);
++
++	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
++	if (error_string) {
++		printf("add ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++
++	return err;
++}
++
++static int check_knet_set_del_ip(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	char verifycmd[1024];
++	int err=0;
++	nozzle_t nozzle;
++	char *ip_list = NULL;
++	int ip_list_entries = 0, i, offset = 0;
++	char *error_string = NULL;
++	char *error_down = NULL, *error_postdown = NULL;
++
++	printf("Testing interface add/remove ip\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
++	if (error_string) {
++		printf("add ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_2);
++
++	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
++	if (error_string) {
++		printf("add ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding duplicate ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
++	if (error_string) {
++		printf("add ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to find IP address in libnozzle db\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Checking ip: %s/24\n", testipv4_1);
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Get ip list from libnozzle:\n");
++
++	if (nozzle_get_ips(nozzle, &ip_list, &ip_list_entries) < 0) {
++		printf("Not enough mem?\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	if (ip_list_entries != 2) {
++		printf("Didn't get enough ip back from libnozzle?\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	for (i = 1; i <= ip_list_entries; i++) {
++		printf("Found IP %s %s in libnozzle db\n", ip_list + offset, ip_list + offset + strlen(ip_list + offset) + 1);
++		offset = offset + strlen(ip_list) + 1;
++		offset = offset + strlen(ip_list + offset) + 1;
++	}
++
++	free(ip_list);
++
++	printf("Deleting ip: %s/24\n", testipv4_1);
++
++	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
++	if (error_string) {
++		printf("del ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24\n", testipv4_2);
++
++	err = nozzle_del_ip(nozzle, testipv4_2, "24", &error_string);
++	if (error_string) {
++		printf("del ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Deleting again ip: %s/24\n", testipv4_1);
++
++	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
++	if (error_string) {
++		printf("del ip output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
++	if (error_string) {
++		printf("add ipv6 output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64\n", testipv6_1);
++
++	err = nozzle_del_ip(nozzle, testipv6_1, "64", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = _execute_shell(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle, &error_down, &error_postdown);
++	if (error_down) {
++		printf("down output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
++
++	return err;
++}
++
++static void make_local_ips(void)
++{
++	pid_t mypid;
++	uint8_t *pid;
++	uint8_t i;
++
++	if (sizeof(pid_t) < 4) {
++		printf("pid_t is smaller than 4 bytes?\n");
++		exit(77);
++	}
++
++	memset(testipv4_1, 0, sizeof(testipv4_1));
++	memset(testipv4_2, 0, sizeof(testipv4_2));
++	memset(testipv6_1, 0, sizeof(testipv6_1));
++	memset(testipv6_2, 0, sizeof(testipv6_2));
++
++	mypid = getpid();
++	pid = (uint8_t *)&mypid;
++
++	for (i = 0; i < sizeof(pid_t); i++) {
++		if (pid[i] == 0) {
++			pid[i] = 128;
++		}
++	}
++
++	randombyte = pid[1];
++
++	snprintf(testipv4_1,
++		 sizeof(testipv4_1) - 1,
++		 "127.%u.%u.%u",
++		 pid[1],
++		 pid[2],
++		 pid[0]);
++
++	snprintf(testipv4_2,
++		 sizeof(testipv4_2) - 1,
++		 "127.%u.%d.%u",
++		 pid[1],
++		 pid[2]+1,
++		 pid[0]);
++
++	snprintf(testipv6_1,
++		 sizeof(testipv6_1) - 1,
++		 "fd%x:%x%x::1",
++		 pid[1],
++		 pid[2],
++		 pid[0]);
++
++	snprintf(testipv6_2,
++		 sizeof(testipv6_2) - 1,
++		 "fd%x:%x%x:1::1",
++		 pid[1],
++		 pid[2],
++		 pid[0]);
++}
++
++int main(void)
++{
++	if (geteuid() != 0) {
++		printf("This test requires root privileges\n");
++		exit(77);
++	}
++
++	make_local_ips();
++
++	if (check_nozzle_open_close() < 0)
++		return -1;
++
++	if (check_knet_multi_eth() < 0)
++		return -1;
++
++	if (check_knet_mtu() < 0)
++		return -1;
++
++	if (check_knet_mtu_ipv6() < 0)
++		return -1;
++
++	if (check_knet_mac() < 0)
++		return -1;
++
++	if (check_nozzle_execute_shell() < 0)
++		return -1;
++
++	if (check_knet_up_down() < 0)
++		return -1;
++
++	if (check_knet_set_del_ip() < 0)
++		return -1;
++
++	if (check_knet_close_leak() < 0)
++		return -1;
++
++	return 0;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0103-nozzle-start-cleaning-internal-function-names.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0103-nozzle-start-cleaning-internal-function-names.patch
new file mode 100644
index 000000000..a0682715c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0103-nozzle-start-cleaning-internal-function-names.patch
@@ -0,0 +1,305 @@ 
+From 6a5dc6ef1c68907bfa6c97e1de9d96aebd3a662f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 19 Dec 2017 06:04:32 +0100
+Subject: [PATCH] [nozzle] start cleaning internal function names
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c         | 10 ++++-----
+ libnozzle/internals.h         |  4 ++--
+ libnozzle/libnozzle.c         | 10 ++++-----
+ libnozzle/tests/nozzle_test.c | 40 +++++++++++++++++------------------
+ 4 files changed, 32 insertions(+), 32 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 24d988d8..b2ed26aa 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -22,7 +22,7 @@
+ #include "libnozzle.h"
+ #include "internals.h"
+ 
+-static int _read_pipe(int fd, char **file, size_t *length)
++static int read_pipe(int fd, char **file, size_t *length)
+ {
+ 	char buf[4096];
+ 	int n;
+@@ -71,7 +71,7 @@ static int _read_pipe(int fd, char **file, size_t *length)
+ 	return 0;
+ }
+ 
+-int _execute_shell(const char *command, char **error_string)
++int execute_shell_command(const char *command, char **error_string)
+ {
+ 	pid_t pid;
+ 	int status, err = 0;
+@@ -98,7 +98,7 @@ int _execute_shell(const char *command, char **error_string)
+ 	if (pid) { /* parent */
+ 
+ 		close(fd[1]);
+-		err = _read_pipe(fd[0], error_string, &size);
++		err = read_pipe(fd[0], error_string, &size);
+ 		if (err)
+ 			goto out_clean0;
+ 
+@@ -134,7 +134,7 @@ out_clean0:
+ 	return err;
+ }
+ 
+-int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string)
++int run_updown(const nozzle_t nozzle, const char *action, char **error_string)
+ {
+ 	char command[PATH_MAX];
+ 	struct stat sb;
+@@ -151,7 +151,7 @@ int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string)
+ 	if ((err < 0) && (errno == ENOENT))
+ 		return 0;
+ 
+-	err = _execute_shell(command, error_string);
++	err = execute_shell_command(command, error_string);
+ 	if ((!err) && (*error_string)) {
+ 		free(*error_string);
+ 		*error_string = NULL;
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 166f8700..de7214ee 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -60,7 +60,7 @@ struct nozzle_iface {
+ 
+ #define ifname ifr.ifr_name
+ 
+-int _execute_shell(const char *command, char **error_string);
+-int _exec_updown(const nozzle_t nozzle, const char *action, char **error_string);
++int execute_shell_command(const char *command, char **error_string);
++int run_updown(const nozzle_t nozzle, const char *action, char **error_string);
+ 
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 6d4efb30..009816d4 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -691,7 +691,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		goto out_clean;
+ 	}
+ 
+-	_exec_updown(nozzle, "pre-up.d", error_preup);
++	run_updown(nozzle, "pre-up.d", error_preup);
+ 
+ 	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+@@ -700,7 +700,7 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		goto out_clean;
+ 	}
+ 
+-	_exec_updown(nozzle, "up.d", error_up);
++	run_updown(nozzle, "up.d", error_up);
+ 
+ 	nozzle->up = 1;
+ 
+@@ -728,7 +728,7 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 		goto out_clean;
+ 	}
+ 
+-	_exec_updown(nozzle, "down.d", error_down);
++	run_updown(nozzle, "down.d", error_down);
+ 
+ 	ifr.ifr_flags &= ~IFF_UP;
+ 
+@@ -738,7 +738,7 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 		goto out_clean;
+ 	}
+ 
+-	_exec_updown(nozzle, "post-down.d", error_postdown);
++	run_updown(nozzle, "post-down.d", error_postdown);
+ 
+ 	nozzle->up = 0;
+ 
+@@ -872,7 +872,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	if (broadcast) {
+ 		free(broadcast);
+ 	}
+-	return _execute_shell(cmdline, error_string);
++	return execute_shell_command(cmdline, error_string);
+ }
+ 
+ static int _find_ip(nozzle_t nozzle,
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index f8683b63..e892d351 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -448,7 +448,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -471,7 +471,7 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -509,7 +509,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -540,7 +540,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -560,7 +560,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -705,7 +705,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int check_nozzle_execute_shell(void)
++static int check_nozzle_execute_shell_command(void)
+ {
+ 	int err = 0;
+ 	char command[4096];
+@@ -713,11 +713,11 @@ static int check_nozzle_execute_shell(void)
+ 
+ 	memset(command, 0, sizeof(command));
+ 
+-	printf("Testing _execute_shell\n");
++	printf("Testing execute_shell_command\n");
+ 
+ 	printf("command true\n");
+ 
+-	err = _execute_shell("true", &error_string);
++	err = execute_shell_command("true", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -732,7 +732,7 @@ static int check_nozzle_execute_shell(void)
+ 
+ 	printf("command false\n");
+ 
+-	err = _execute_shell("false", &error_string);
++	err = execute_shell_command("false", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -746,7 +746,7 @@ static int check_nozzle_execute_shell(void)
+ 
+ 	printf("command that outputs to stdout (enforcing redirect)\n");
+ 
+-	err = _execute_shell("grep -h 2>&1", &error_string);
++	err = execute_shell_command("grep -h 2>&1", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -759,7 +759,7 @@ static int check_nozzle_execute_shell(void)
+ 	} 
+ 
+ 	printf("command that outputs to stderr\n");
+-	err = _execute_shell("grep -h", &error_string);
++	err = execute_shell_command("grep -h", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -772,7 +772,7 @@ static int check_nozzle_execute_shell(void)
+ 	} 
+ 
+ 	printf("empty command\n");
+-	err = _execute_shell(NULL, &error_string);
++	err = execute_shell_command(NULL, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -785,7 +785,7 @@ static int check_nozzle_execute_shell(void)
+ 	}
+ 
+ 	printf("empty error\n");
+-	err = _execute_shell("true", NULL);
++	err = execute_shell_command("true", NULL);
+ 	if (!err) {
+ 		printf("Check EINVAL filter for no error_string!\n");
+ 		err = -1;
+@@ -846,7 +846,7 @@ static int check_knet_up_down(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q UP", nozzle->name);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -885,7 +885,7 @@ static int check_knet_up_down(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q UP", nozzle->name);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1231,7 +1231,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1315,7 +1315,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1349,7 +1349,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1383,7 +1383,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = _execute_shell(verifycmd, &error_string);
++	err = execute_shell_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1491,7 +1491,7 @@ int main(void)
+ 	if (check_knet_mac() < 0)
+ 		return -1;
+ 
+-	if (check_nozzle_execute_shell() < 0)
++	if (check_nozzle_execute_shell_command() < 0)
+ 		return -1;
+ 
+ 	if (check_knet_up_down() < 0)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0104-nozzle-be-more-explicit-on-function-naming.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0104-nozzle-be-more-explicit-on-function-naming.patch
new file mode 100644
index 000000000..3c773e835
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0104-nozzle-be-more-explicit-on-function-naming.patch
@@ -0,0 +1,69 @@ 
+From 7a065bc484412367f3f364a43935c9a5c6ac5255 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 05:21:34 +0100
+Subject: [PATCH] [nozzle] be more explicit on function naming
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 6 +++---
+ libnozzle/internals.h | 2 +-
+ libnozzle/libnozzle.c | 2 +-
+ 3 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index b2ed26aa..be81b569 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -71,7 +71,7 @@ static int read_pipe(int fd, char **file, size_t *length)
+ 	return 0;
+ }
+ 
+-int execute_shell_command(const char *command, char **error_string)
++int execute_bin_sh_command(const char *command, char **error_string)
+ {
+ 	pid_t pid;
+ 	int status, err = 0;
+@@ -151,7 +151,7 @@ int run_updown(const nozzle_t nozzle, const char *action, char **error_string)
+ 	if ((err < 0) && (errno == ENOENT))
+ 		return 0;
+ 
+-	err = execute_shell_command(command, error_string);
++	err = execute_bin_sh_command(command, error_string);
+ 	if ((!err) && (*error_string)) {
+ 		free(*error_string);
+ 		*error_string = NULL;
+@@ -976,7 +976,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	if (broadcast) {
+ 		free(broadcast);
+ 	}
+-	return _execute_shell(cmdline, error_string);
++	return _execute_bin_sh(cmdline, error_string);
+ }
+ 
+ static int _find_ip(nozzle_t nozzle,
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index de7214ee..01ea3940 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -60,7 +60,7 @@ struct nozzle_iface {
+ 
+ #define ifname ifr.ifr_name
+ 
+-int execute_shell_command(const char *command, char **error_string);
++int execute_bin_sh_command(const char *command, char **error_string);
+ int run_updown(const nozzle_t nozzle, const char *action, char **error_string);
+ 
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 009816d4..29a695ba 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -872,7 +872,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	if (broadcast) {
+ 		free(broadcast);
+ 	}
+-	return execute_shell_command(cmdline, error_string);
++	return execute_bin_sh_command(cmdline, error_string);
+ }
+ 
+ static int _find_ip(nozzle_t nozzle,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0105-nozzle-be-more-explicit-on-function-naming-part-2.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0105-nozzle-be-more-explicit-on-function-naming-part-2.patch
new file mode 100644
index 000000000..6062bf051
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0105-nozzle-be-more-explicit-on-function-naming-part-2.patch
@@ -0,0 +1,190 @@ 
+From 73389efe914f7d4e9168dce506dd45d4a53bd5e4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 05:22:26 +0100
+Subject: [PATCH] [nozzle] be more explicit on function naming (part 2)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/nozzle_test.c | 40 +++++++++++++++++------------------
+ 1 file changed, 20 insertions(+), 20 deletions(-)
+
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index e892d351..b83f62c4 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -448,7 +448,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -471,7 +471,7 @@ static int check_knet_mtu_ipv6(void)
+ 		goto out_clean;
+ 	}
+ 
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -509,7 +509,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -540,7 +540,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -560,7 +560,7 @@ static int check_knet_mtu_ipv6(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -705,7 +705,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int check_nozzle_execute_shell_command(void)
++static int check_nozzle_execute_bin_sh_command(void)
+ {
+ 	int err = 0;
+ 	char command[4096];
+@@ -713,11 +713,11 @@ static int check_nozzle_execute_shell_command(void)
+ 
+ 	memset(command, 0, sizeof(command));
+ 
+-	printf("Testing execute_shell_command\n");
++	printf("Testing execute_bin_sh_command\n");
+ 
+ 	printf("command true\n");
+ 
+-	err = execute_shell_command("true", &error_string);
++	err = execute_bin_sh_command("true", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -732,7 +732,7 @@ static int check_nozzle_execute_shell_command(void)
+ 
+ 	printf("command false\n");
+ 
+-	err = execute_shell_command("false", &error_string);
++	err = execute_bin_sh_command("false", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -746,7 +746,7 @@ static int check_nozzle_execute_shell_command(void)
+ 
+ 	printf("command that outputs to stdout (enforcing redirect)\n");
+ 
+-	err = execute_shell_command("grep -h 2>&1", &error_string);
++	err = execute_bin_sh_command("grep -h 2>&1", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -759,7 +759,7 @@ static int check_nozzle_execute_shell_command(void)
+ 	} 
+ 
+ 	printf("command that outputs to stderr\n");
+-	err = execute_shell_command("grep -h", &error_string);
++	err = execute_bin_sh_command("grep -h", &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -772,7 +772,7 @@ static int check_nozzle_execute_shell_command(void)
+ 	} 
+ 
+ 	printf("empty command\n");
+-	err = execute_shell_command(NULL, &error_string);
++	err = execute_bin_sh_command(NULL, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -785,7 +785,7 @@ static int check_nozzle_execute_shell_command(void)
+ 	}
+ 
+ 	printf("empty error\n");
+-	err = execute_shell_command("true", NULL);
++	err = execute_bin_sh_command("true", NULL);
+ 	if (!err) {
+ 		printf("Check EINVAL filter for no error_string!\n");
+ 		err = -1;
+@@ -846,7 +846,7 @@ static int check_knet_up_down(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q UP", nozzle->name);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -885,7 +885,7 @@ static int check_knet_up_down(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q UP", nozzle->name);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1231,7 +1231,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1315,7 +1315,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1349,7 +1349,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1383,7 +1383,7 @@ static int check_knet_set_del_ip(void)
+ #ifdef KNET_BSD
+ 		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+ #endif
+-	err = execute_shell_command(verifycmd, &error_string);
++	err = execute_bin_sh_command(verifycmd, &error_string);
+ 	if (error_string) {
+ 		printf("Error string: %s\n", error_string);
+ 		free(error_string);
+@@ -1491,7 +1491,7 @@ int main(void)
+ 	if (check_knet_mac() < 0)
+ 		return -1;
+ 
+-	if (check_nozzle_execute_shell_command() < 0)
++	if (check_nozzle_execute_bin_sh_command() < 0)
+ 		return -1;
+ 
+ 	if (check_knet_up_down() < 0)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0106-nozzle-rename-_check-to-is_valid_nozzle-make-it-more.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0106-nozzle-rename-_check-to-is_valid_nozzle-make-it-more.patch
new file mode 100644
index 000000000..36f9e8eff
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0106-nozzle-rename-_check-to-is_valid_nozzle-make-it-more.patch
@@ -0,0 +1,288 @@ 
+From b2c7876df6e74fc55991d15e937cb5e327774087 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 05:47:19 +0100
+Subject: [PATCH] [nozzle] rename _check to is_valid_nozzle, make it more
+ useful and fixup error code checking
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 92 ++++++++++++++++++-------------------------
+ 1 file changed, 38 insertions(+), 54 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 29a695ba..207d445e 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -38,12 +38,15 @@
+ #include "libnozzle.h"
+ #include "internals.h"
+ 
++/*
++ * internal functions are all _unlocked_
++ * locking should be handled at external API functions
++ */
+ static int lib_init = 0;
+ static struct nozzle_lib_config lib_cfg;
+ static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+ /* forward declarations */
+-static int _check(const nozzle_t nozzle);
+ static void _close(nozzle_t nozzle);
+ static void _close_cfg(void);
+ static int _get_mtu(const nozzle_t nozzle);
+@@ -57,14 +60,20 @@ static int _find_ip(nozzle_t nozzle,
+ 			const char *ipaddr, const char *prefix,
+ 			struct nozzle_ip **ip, struct nozzle_ip **ip_prev);
+ 
+-static int _check(const nozzle_t nozzle)
++static int is_valid_nozzle(const nozzle_t nozzle)
+ {
+-	nozzle_t temp = lib_cfg.head;
++	nozzle_t temp;
+ 
+ 	if (!nozzle) {
+ 		return 0;
+ 	}
+ 
++	if (!lib_init) {
++		return 0;
++	}
++
++	temp = lib_cfg.head;
++
+ 	while (temp != NULL) {
+ 		if (nozzle == temp)
+ 			return 1;
+@@ -426,7 +435,7 @@ int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
++	if (!is_valid_nozzle(nozzle)) {
+ 		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+@@ -470,19 +479,14 @@ int nozzle_get_mtu(const nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+ 
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -502,7 +506,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 	struct nozzle_ip *tmp_ip;
+ 	struct ifreq ifr;
+ 
+-	if ((!nozzle) || (!mtu) || (!error_string)) {
++	if ((!mtu) || (!error_string)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -513,8 +517,8 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -565,7 +569,7 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err = 0, savederrno = 0;
+ 
+-	if ((!nozzle) || (!ether_addr)) {
++	if (!ether_addr) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -576,8 +580,8 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -595,7 +599,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 	int err = 0, savederrno = 0;
+ 	struct ifreq ifr;
+ 
+-	if ((!nozzle) || (!ether_addr)) {
++	if (!ether_addr) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -606,8 +610,8 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -655,18 +659,13 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 	int err = 0, savederrno = 0;
+ 	struct ifreq ifr;
+ 
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
++	if (!is_valid_nozzle(nozzle)) {
+ 		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+@@ -751,18 +750,13 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+ 	int err = 0, savederrno = 0;
+ 
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
++	if (!is_valid_nozzle(nozzle)) {
+ 		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+@@ -908,7 +902,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+ 	int secondary = 0;
+ 
+-	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
++	if ((!ipaddr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -919,8 +913,8 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -987,7 +981,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+         int found = 0;
+ 	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
+ 
+-	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
++	if ((!ipaddr) || (!prefix) || (!error_string)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -998,8 +992,8 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -1030,18 +1024,13 @@ int nozzle_get_fd(const nozzle_t nozzle)
+ {
+ 	int fd = -1, savederrno = 0;
+ 
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
++	if (!is_valid_nozzle(nozzle)) {
+ 		savederrno = ENOENT;
+ 		fd = -1;
+ 		goto out_clean;
+@@ -1060,19 +1049,14 @@ const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+ 	int savederrno = 0;
+ 	char *name = NULL;
+ 
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
+ 		return NULL;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = ENOENT;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = ENOENT;
+ 		goto out_clean;
+ 	}
+ 
+@@ -1092,7 +1076,7 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ 	int size = 0, offset = 0, len;
+ 	struct nozzle_ip *ip = NULL;
+ 
+-	if ((!nozzle) || (!ipaddr_list) || (!entries)) {
++	if ((!ipaddr_list) || (!entries)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -1103,8 +1087,8 @@ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ 		return -1;
+ 	}
+ 
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
+ 		goto out_clean;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0107-nozzle-move-code-around-to-reflect-completion-and-dr.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0107-nozzle-move-code-around-to-reflect-completion-and-dr.patch
new file mode 100644
index 000000000..5b219ed3e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0107-nozzle-move-code-around-to-reflect-completion-and-dr.patch
@@ -0,0 +1,345 @@ 
+From 1624f49db3c7788b824fae3e4576d8e44e40478f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 06:01:06 +0100
+Subject: [PATCH] [nozzle] move code around to reflect completion and drop copy
+ of code from internals.c
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 108 ----------------------------
+ libnozzle/libnozzle.c | 164 +++++++++++++++++++++---------------------
+ libnozzle/libnozzle.h |   2 +-
+ 3 files changed, 85 insertions(+), 189 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index be81b569..2a385db8 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -161,24 +161,6 @@ int run_updown(const nozzle_t nozzle, const char *action, char **error_string)
+ }
+ 
+ #if 0
+-static int _check(const nozzle_t nozzle)
+-{
+-	nozzle_t temp = lib_cfg.head;
+-
+-	if (!nozzle) {
+-		return 0;
+-	}
+-
+-	while (temp != NULL) {
+-		if (nozzle == temp)
+-			return 1;
+-
+-		temp = temp->next;
+-	}
+-
+-	return 0;
+-}
+-
+ static void _close(nozzle_t nozzle)
+ {
+ #ifdef KNET_BSD
+@@ -302,38 +284,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-nozzle_t nozzle_get_handle_by_name(char *devname)
+-{
+-	int savederrno = 0;
+-	nozzle_t nozzle;
+-
+-	if ((devname == NULL) || (strlen(devname) > IFNAMSIZ)) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return NULL;
+-	}
+-
+-	nozzle = lib_cfg.head;
+-	while (nozzle != NULL) {
+-		if (!strcmp(devname, nozzle->name))
+-			break;
+-		nozzle = nozzle->next;
+-	}
+-
+-	if (!nozzle) {
+-		savederrno = ENOENT;
+-	}
+-
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return nozzle;
+-}
+-
+ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ {
+ 	int savederrno = 0;
+@@ -1130,64 +1080,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_get_fd(const nozzle_t nozzle)
+-{
+-	int fd = -1, savederrno = 0;
+-
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		savederrno = ENOENT;
+-		fd = -1;
+-		goto out_clean;
+-	}
+-
+-	fd = nozzle->fd;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return fd;
+-}
+-
+-const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+-{
+-	int savederrno = 0;
+-	char *name = NULL;
+-
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return NULL;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = ENOENT;
+-		goto out_clean;
+-	}
+-
+-	name = nozzle->name;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return name;
+-}
+-
+ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ {
+ 	int err = 0, savederrno = 0;
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 207d445e..736abda4 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -207,38 +207,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-nozzle_t nozzle_get_handle_by_name(char *devname)
+-{
+-	int savederrno = 0;
+-	nozzle_t nozzle;
+-
+-	if ((devname == NULL) || (strlen(devname) > IFNAMSIZ)) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return NULL;
+-	}
+-
+-	nozzle = lib_cfg.head;
+-	while (nozzle != NULL) {
+-		if (!strcmp(devname, nozzle->name))
+-			break;
+-		nozzle = nozzle->next;
+-	}
+-
+-	if (!nozzle) {
+-		savederrno = ENOENT;
+-	}
+-
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return nozzle;
+-}
+-
+ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ {
+ 	int savederrno = 0;
+@@ -1020,54 +988,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_get_fd(const nozzle_t nozzle)
+-{
+-	int fd = -1, savederrno = 0;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = ENOENT;
+-		fd = -1;
+-		goto out_clean;
+-	}
+-
+-	fd = nozzle->fd;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return fd;
+-}
+-
+-const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
+-{
+-	int savederrno = 0;
+-	char *name = NULL;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return NULL;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = ENOENT;
+-		goto out_clean;
+-	}
+-
+-	name = nozzle->name;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return name;
+-}
+-
+ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -1136,3 +1056,87 @@ out_clean:
+ 	errno = savederrno;
+ 	return err;
+ }
++
++/*
++ * functions below should be completed
++ */
++
++nozzle_t nozzle_get_handle_by_name(const char *devname)
++{
++	int savederrno = 0;
++	nozzle_t nozzle;
++
++	if ((devname == NULL) || (strlen(devname) > IFNAMSIZ)) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
++
++	nozzle = lib_cfg.head;
++	while (nozzle != NULL) {
++		if (!strcmp(devname, nozzle->name))
++			break;
++		nozzle = nozzle->next;
++	}
++
++	if (!nozzle) {
++		savederrno = ENOENT;
++	}
++
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return nozzle;
++}
++
++const char *nozzle_get_name_by_handle(const nozzle_t nozzle)
++{
++	int savederrno = 0;
++	char *name = NULL;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = ENOENT;
++		goto out_clean;
++	}
++
++	name = nozzle->name;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return name;
++}
++
++int nozzle_get_fd(const nozzle_t nozzle)
++{
++	int fd = -1, savederrno = 0;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = ENOENT;
++		fd = -1;
++		goto out_clean;
++	}
++
++	fd = nozzle->fd;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return fd;
++}
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 355f07eb..dbbadf51 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -301,7 +301,7 @@ int nozzle_reset_mac(nozzle_t nozzle);
+  * NULL on error and errno is set.
+  */
+ 
+-nozzle_t nozzle_get_handle_by_name(char *devname);
++nozzle_t nozzle_get_handle_by_name(const char *devname);
+ 
+ /**
+  * nozzle_get_name_by_handle
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0108-nozzle-move-code-around-to-reflect-public-API-and-in.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0108-nozzle-move-code-around-to-reflect-public-API-and-in.patch
new file mode 100644
index 000000000..33b7ad38f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0108-nozzle-move-code-around-to-reflect-public-API-and-in.patch
@@ -0,0 +1,601 @@ 
+From ad1258eb3ba999a08422e6bff3a9feb179d816d7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 06:15:30 +0100
+Subject: [PATCH] [nozzle] move code around to reflect public API and internal
+ functions
+
+cleanup _get_mtu in the process
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c |  21 --
+ libnozzle/libnozzle.c | 481 +++++++++++++++++++++---------------------
+ 2 files changed, 240 insertions(+), 262 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 2a385db8..8861b23c 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -193,27 +193,6 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _get_mtu(const nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	err = ifr.ifr_mtu;
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err = 0, savederrno = 0;
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 736abda4..0b399f5d 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -46,43 +46,9 @@ static int lib_init = 0;
+ static struct nozzle_lib_config lib_cfg;
+ static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+ 
+-/* forward declarations */
+-static void _close(nozzle_t nozzle);
+-static void _close_cfg(void);
+-static int _get_mtu(const nozzle_t nozzle);
+-static int _get_mac(const nozzle_t nozzle, char **ether_addr);
+-static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
+-static char *_get_v4_broadcast(const char *ipaddr, const char *prefix);
+-static int _set_ip(nozzle_t nozzle, const char *command,
+-		      const char *ipaddr, const char *prefix,
+-		      char **error_string, int secondary);
+-static int _find_ip(nozzle_t nozzle,
+-			const char *ipaddr, const char *prefix,
+-			struct nozzle_ip **ip, struct nozzle_ip **ip_prev);
+-
+-static int is_valid_nozzle(const nozzle_t nozzle)
+-{
+-	nozzle_t temp;
+-
+-	if (!nozzle) {
+-		return 0;
+-	}
+-
+-	if (!lib_init) {
+-		return 0;
+-	}
+-
+-	temp = lib_cfg.head;
+-
+-	while (temp != NULL) {
+-		if (nozzle == temp)
+-			return 1;
+-
+-		temp = temp->next;
+-	}
+-
+-	return 0;
+-}
++/*
++ * internal helpers
++ */
+ 
+ static void _close(nozzle_t nozzle)
+ {
+@@ -116,27 +82,6 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _get_mtu(const nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	err = ifr.ifr_mtu;
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -207,6 +152,214 @@ out_clean:
+ 	return err;
+ }
+ 
++static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	if (!nozzle->up) {
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	run_updown(nozzle, "down.d", error_down);
++
++	ifr.ifr_flags &= ~IFF_UP;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	run_updown(nozzle, "post-down.d", error_postdown);
++
++	nozzle->up = 0;
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
++static char *_get_v4_broadcast(const char *ipaddr, const char *prefix)
++{
++	int prefix_len;
++	struct in_addr mask;
++	struct in_addr broadcast;
++	struct in_addr address;
++
++	prefix_len = atoi(prefix);
++
++	if ((prefix_len > 32) || (prefix_len < 0))
++		return NULL;
++
++	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
++		return NULL;
++
++	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
++
++	memset(&broadcast, 0, sizeof(broadcast));
++	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
++
++	return strdup(inet_ntoa(broadcast));
++}
++
++static int _set_ip(nozzle_t nozzle, const char *command,
++		      const char *ipaddr, const char *prefix,
++		      char **error_string, int secondary)
++{
++	char *broadcast = NULL;
++	char cmdline[4096];
++#ifdef KNET_BSD
++	char proto[6];
++	int v4 = 1;
++
++	snprintf(proto, sizeof(proto), "inet");
++#endif
++
++	if (!strchr(ipaddr, ':')) {
++		broadcast = _get_v4_broadcast(ipaddr, prefix);
++		if (!broadcast) {
++			errno = EINVAL;
++			return -1;
++		}
++	}
++#ifdef KNET_BSD
++	  else {
++		v4 = 0;
++		snprintf(proto, sizeof(proto), "inet6");
++	}
++#endif
++
++	memset(cmdline, 0, sizeof(cmdline));
++
++#ifdef KNET_LINUX
++	if (broadcast) {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ip addr %s %s/%s dev %s broadcast %s",
++			 command, ipaddr, prefix,
++			 nozzle->name, broadcast);
++	} else {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ip addr %s %s/%s dev %s",
++			command, ipaddr, prefix,
++			nozzle->name);
++	}
++#endif
++#ifdef KNET_BSD
++	if (!strcmp(command, "add")) {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ifconfig %s %s %s/%s",
++			 nozzle->name, proto, ipaddr, prefix);
++		if (broadcast) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " broadcast %s", broadcast);
++		}
++		if ((secondary) && (v4)) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " alias");
++		}
++	} else {
++		snprintf(cmdline, sizeof(cmdline)-1,
++				 "ifconfig %s %s %s/%s delete",
++				 nozzle->name, proto, ipaddr, prefix);
++	}
++#endif
++	if (broadcast) {
++		free(broadcast);
++	}
++	return execute_bin_sh_command(cmdline, error_string);
++}
++
++static int _find_ip(nozzle_t nozzle,
++			const char *ipaddr, const char *prefix,
++			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
++{
++	struct nozzle_ip *local_ip, *local_ip_prev;
++	int found = 0;
++
++	local_ip = local_ip_prev = nozzle->ip;
++
++	while(local_ip) {
++		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
++			found = 1;
++			break;
++		}
++		local_ip_prev = local_ip;
++		local_ip = local_ip->next;
++	}
++
++	if (found) {
++		*ip = local_ip;
++		*ip_prev = local_ip_prev;
++	}
++
++	return found;
++}
++
++/*
++ * internal helpers below should be completed
++ */
++
++static int is_valid_nozzle(const nozzle_t nozzle)
++{
++	nozzle_t temp;
++
++	if (!nozzle) {
++		return 0;
++	}
++
++	if (!lib_init) {
++		return 0;
++	}
++
++	temp = lib_cfg.head;
++
++	while (temp != NULL) {
++		if (nozzle == temp)
++			return 1;
++
++		temp = temp->next;
++	}
++
++	return 0;
++}
++
++static int get_iface_mtu(const nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	err = ifr.ifr_mtu;
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
++/*
++ * public API
++ */
++
+ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ {
+ 	int savederrno = 0;
+@@ -350,7 +503,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	strncpy(nozzle->name, ifname, IFNAMSIZ);
+ #endif
+ 
+-	nozzle->default_mtu = _get_mtu(nozzle);
++	nozzle->default_mtu = get_iface_mtu(nozzle);
+ 	if (nozzle->default_mtu < 0) {
+ 		savederrno = errno;
+ 		goto out_error;
+@@ -443,31 +596,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_get_mtu(const nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _get_mtu(nozzle);
+-	savederrno = errno;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	savederrno = errno;
+-	return err;
+-}
+-
+ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -491,7 +619,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 		goto out_clean;
+ 	}
+ 
+-	err = nozzle->current_mtu = _get_mtu(nozzle);
++	err = nozzle->current_mtu = get_iface_mtu(nozzle);
+ 	if (err < 0) {
+ 		savederrno = errno;
+ 		goto out_clean;
+@@ -677,43 +805,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if (!nozzle->up) {
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	run_updown(nozzle, "down.d", error_down);
+-
+-	ifr.ifr_flags &= ~IFF_UP;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	run_updown(nozzle, "post-down.d", error_postdown);
+-
+-	nozzle->up = 0;
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -745,124 +836,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-static char *_get_v4_broadcast(const char *ipaddr, const char *prefix)
+-{
+-	int prefix_len;
+-	struct in_addr mask;
+-	struct in_addr broadcast;
+-	struct in_addr address;
+-
+-	prefix_len = atoi(prefix);
+-
+-	if ((prefix_len > 32) || (prefix_len < 0))
+-		return NULL;
+-
+-	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
+-		return NULL;
+-
+-	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
+-
+-	memset(&broadcast, 0, sizeof(broadcast));
+-	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
+-
+-	return strdup(inet_ntoa(broadcast));
+-}
+-
+-static int _set_ip(nozzle_t nozzle, const char *command,
+-		      const char *ipaddr, const char *prefix,
+-		      char **error_string, int secondary)
+-{
+-	char *broadcast = NULL;
+-	char cmdline[4096];
+-#ifdef KNET_BSD
+-	char proto[6];
+-	int v4 = 1;
+-
+-	snprintf(proto, sizeof(proto), "inet");
+-#endif
+-
+-	if (!strchr(ipaddr, ':')) {
+-		broadcast = _get_v4_broadcast(ipaddr, prefix);
+-		if (!broadcast) {
+-			errno = EINVAL;
+-			return -1;
+-		}
+-	}
+-#ifdef KNET_BSD
+-	  else {
+-		v4 = 0;
+-		snprintf(proto, sizeof(proto), "inet6");
+-	}
+-#endif
+-
+-	memset(cmdline, 0, sizeof(cmdline));
+-
+-#ifdef KNET_LINUX
+-	if (broadcast) {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ip addr %s %s/%s dev %s broadcast %s",
+-			 command, ipaddr, prefix,
+-			 nozzle->name, broadcast);
+-	} else {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ip addr %s %s/%s dev %s",
+-			command, ipaddr, prefix,
+-			nozzle->name);
+-	}
+-#endif
+-#ifdef KNET_BSD
+-	if (!strcmp(command, "add")) {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ifconfig %s %s %s/%s",
+-			 nozzle->name, proto, ipaddr, prefix);
+-		if (broadcast) {
+-			snprintf(cmdline + strlen(cmdline),
+-				 sizeof(cmdline) - strlen(cmdline) -1,
+-				 " broadcast %s", broadcast);
+-		}
+-		if ((secondary) && (v4)) {
+-			snprintf(cmdline + strlen(cmdline),
+-				 sizeof(cmdline) - strlen(cmdline) -1,
+-				 " alias");
+-		}
+-	} else {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-				 "ifconfig %s %s %s/%s delete",
+-				 nozzle->name, proto, ipaddr, prefix);
+-	}
+-#endif
+-	if (broadcast) {
+-		free(broadcast);
+-	}
+-	return execute_bin_sh_command(cmdline, error_string);
+-}
+-
+-static int _find_ip(nozzle_t nozzle,
+-			const char *ipaddr, const char *prefix,
+-			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
+-{
+-	struct nozzle_ip *local_ip, *local_ip_prev;
+-	int found = 0;
+-
+-	local_ip = local_ip_prev = nozzle->ip;
+-
+-	while(local_ip) {
+-		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
+-			found = 1;
+-			break;
+-		}
+-		local_ip_prev = local_ip;
+-		local_ip = local_ip->next;
+-	}
+-
+-	if (found) {
+-		*ip = local_ip;
+-		*ip_prev = local_ip_prev;
+-	}
+-
+-	return found;
+-}
+-
+ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -912,7 +885,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 	 * if user asks for an IPv6 address, but MTU < 1280
+ 	 * store the IP and bring it up later if and when MTU > 1280
+ 	 */
+-	if ((ip->domain == AF_INET6) && (_get_mtu(nozzle) < 1280)) {
++	if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
+ 		err = 0;
+ 	} else {
+ 		if (nozzle->ip) {
+@@ -1061,6 +1034,32 @@ out_clean:
+  * functions below should be completed
+  */
+ 
++int nozzle_get_mtu(const nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = get_iface_mtu(nozzle);
++	savederrno = errno;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	savederrno = errno;
++	return err;
++}
++
++
+ nozzle_t nozzle_get_handle_by_name(const char *devname)
+ {
+ 	int savederrno = 0;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0109-nozzle-cleanup-mac-address-functions.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0109-nozzle-cleanup-mac-address-functions.patch
new file mode 100644
index 000000000..af9dc739b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0109-nozzle-cleanup-mac-address-functions.patch
@@ -0,0 +1,584 @@ 
+From 41091400f2432e95a6dc3b9b4bcba0ec85b60480 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 08:53:22 +0100
+Subject: [PATCH] [nozzle] cleanup mac address functions
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 189 -------------------------
+ libnozzle/libnozzle.c | 320 +++++++++++++++++++++---------------------
+ 2 files changed, 160 insertions(+), 349 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 8861b23c..82427ae0 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -193,76 +193,6 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-	char mac[MACADDR_CHAR_MAX];
+-#ifdef KNET_BSD
+-	struct ifaddrs *ifap = NULL;
+-	struct ifaddrs *ifa;
+-	int found = 0;
+-#endif
+-
+-	memset(&mac, 0, MACADDR_CHAR_MAX);
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-#ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ether_ntoa_r((struct ether_addr *)ifr.ifr_hwaddr.sa_data, mac);
+-#endif
+-#ifdef KNET_BSD
+-	/*
+-	 * there is no ioctl to get the ether address of an interface on FreeBSD
+-	 * (not to be confused with hwaddr). Use workaround described here:
+-	 * https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
+-	 */
+-	err = getifaddrs(&ifap);
+-	if (err < 0) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ifa = ifap;
+-
+-	while (ifa) {
+-		if (!strncmp(nozzle->name, ifa->ifa_name, IFNAMSIZ)) {
+-			found = 1;
+-			break;
+-		}
+-		ifa=ifa->ifa_next;
+-	}
+-
+-	if (found) {
+-		ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
+-	} else {
+-		errno = EINVAL;
+-		err = -1;
+-	}
+-	freeifaddrs(ifap);
+-
+-	if (err) {
+-		goto out_clean;
+-	}
+-
+-#endif
+-	*ether_addr = strdup(mac);
+-	if (!*ether_addr) {
+-		savederrno = errno;
+-		err = -1;
+-	}
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ {
+ 	int savederrno = 0;
+@@ -499,36 +429,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_get_mtu(const nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _get_mtu(nozzle);
+-	savederrno = errno;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	savederrno = errno;
+-	return err;
+-}
+-
+ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -594,95 +494,6 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ 	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+ }
+ 
+-int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	if ((!nozzle) || (!ether_addr)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _get_mac(nozzle, ether_addr);
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if ((!nozzle) || (!ether_addr)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-#ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	memmove(ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &ifr);
+-	savederrno = errno;
+-#endif
+-#ifdef KNET_BSD
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	memmove(ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
+-	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &ifr);
+-	savederrno = errno;
+-#endif
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_reset_mac(nozzle_t nozzle)
+-{
+-	return nozzle_set_mac(nozzle, nozzle->default_mac);
+-}
+-
+ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ {
+ 	int err = 0, savederrno = 0;
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 0b399f5d..7fb772e6 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -82,76 +82,6 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _get_mac(const nozzle_t nozzle, char **ether_addr)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-	char mac[MACADDR_CHAR_MAX];
+-#ifdef KNET_BSD
+-	struct ifaddrs *ifap = NULL;
+-	struct ifaddrs *ifa;
+-	int found = 0;
+-#endif
+-
+-	memset(&mac, 0, MACADDR_CHAR_MAX);
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-#ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ether_ntoa_r((struct ether_addr *)ifr.ifr_hwaddr.sa_data, mac);
+-#endif
+-#ifdef KNET_BSD
+-	/*
+-	 * there is no ioctl to get the ether address of an interface on FreeBSD
+-	 * (not to be confused with hwaddr). Use workaround described here:
+-	 * https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
+-	 */
+-	err = getifaddrs(&ifap);
+-	if (err < 0) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ifa = ifap;
+-
+-	while (ifa) {
+-		if (!strncmp(nozzle->name, ifa->ifa_name, IFNAMSIZ)) {
+-			found = 1;
+-			break;
+-		}
+-		ifa=ifa->ifa_next;
+-	}
+-
+-	if (found) {
+-		ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
+-	} else {
+-		errno = EINVAL;
+-		err = -1;
+-	}
+-	freeifaddrs(ifap);
+-
+-	if (err) {
+-		goto out_clean;
+-	}
+-
+-#endif
+-	*ether_addr = strdup(mac);
+-	if (!*ether_addr) {
+-		savederrno = errno;
+-		err = -1;
+-	}
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -356,6 +286,77 @@ out_clean:
+ 	return err;
+ }
+ 
++static int get_iface_mac(const nozzle_t nozzle, char **ether_addr)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++	char mac[MACADDR_CHAR_MAX];
++#ifdef KNET_BSD
++	struct ifaddrs *ifap = NULL;
++	struct ifaddrs *ifa;
++	int found = 0;
++#endif
++
++	memset(&mac, 0, MACADDR_CHAR_MAX);
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++#ifdef KNET_LINUX
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ether_ntoa_r((struct ether_addr *)ifr.ifr_hwaddr.sa_data, mac);
++#endif
++#ifdef KNET_BSD
++	/*
++	 * there is no ioctl to get the ether address of an interface on FreeBSD
++	 * (not to be confused with hwaddr). Use workaround described here:
++	 * https://lists.freebsd.org/pipermail/freebsd-hackers/2004-June/007394.html
++	 */
++	err = getifaddrs(&ifap);
++	if (err < 0) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ifa = ifap;
++
++	while (ifa) {
++		if (!strncmp(nozzle->name, ifa->ifa_name, IFNAMSIZ)) {
++			found = 1;
++			break;
++		}
++		ifa=ifa->ifa_next;
++	}
++
++	if (found) {
++		ether_ntoa_r((struct ether_addr *)LLADDR((struct sockaddr_dl *)ifa->ifa_addr), mac);
++	} else {
++		errno = EINVAL;
++		err = -1;
++	}
++
++	freeifaddrs(ifap);
++
++	if (err) {
++		goto out_clean;
++	}
++
++#endif
++	*ether_addr = strdup(mac);
++	if (!*ether_addr) {
++		savederrno = errno;
++		err = -1;
++	}
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
+ /*
+  * public API
+  */
+@@ -509,7 +510,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		goto out_error;
+ 	}
+ 
+-	if (_get_mac(nozzle, &temp_mac) < 0) {
++	if (get_iface_mac(nozzle, &temp_mac) < 0) {
+ 		savederrno = errno;
+ 		goto out_error;
+ 	}
+@@ -661,95 +662,6 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ 	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+ }
+ 
+-int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	if (!ether_addr) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _get_mac(nozzle, ether_addr);
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if (!ether_addr) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-#ifdef KNET_LINUX
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	memmove(ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &ifr);
+-	savederrno = errno;
+-#endif
+-#ifdef KNET_BSD
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	memmove(ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
+-	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &ifr);
+-	savederrno = errno;
+-#endif
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_reset_mac(nozzle_t nozzle)
+-{
+-	return nozzle_set_mac(nozzle, nozzle->default_mac);
+-}
+-
+ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -1059,6 +971,94 @@ out_clean:
+ 	return err;
+ }
+ 
++int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr)
++{
++	int err = 0, savederrno = 0;
++
++	if (!ether_addr) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = get_iface_mac(nozzle, ether_addr);
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	if (!ether_addr) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++#ifdef KNET_LINUX
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	memmove(ifr.ifr_hwaddr.sa_data, ether_aton(ether_addr), ETH_ALEN);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFHWADDR, &ifr);
++	savederrno = errno;
++#endif
++#ifdef KNET_BSD
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFADDR, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	memmove(ifr.ifr_addr.sa_data, ether_aton(ether_addr), ETHER_ADDR_LEN);
++	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFLLADDR, &ifr);
++	savederrno = errno;
++#endif
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_reset_mac(nozzle_t nozzle)
++{
++	return nozzle_set_mac(nozzle, nozzle->default_mac);
++}
+ 
+ nozzle_t nozzle_get_handle_by_name(const char *devname)
+ {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0110-nozzle-move-ipv4-broadcast-to-internals.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0110-nozzle-move-ipv4-broadcast-to-internals.patch
new file mode 100644
index 000000000..8851bd0ad
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0110-nozzle-move-ipv4-broadcast-to-internals.patch
@@ -0,0 +1,155 @@ 
+From 2e3378df04691c060bb2d768f259808573eb09ff Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 13:28:33 +0100
+Subject: [PATCH] [nozzle] move ipv4 broadcast to internals
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 47 ++++++++++++++++++++++---------------------
+ libnozzle/internals.h |  2 ++
+ libnozzle/libnozzle.c | 28 +++-----------------------
+ 3 files changed, 29 insertions(+), 48 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 82427ae0..d168031e 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -18,6 +18,7 @@
+ #include <limits.h>
+ #include <stdio.h>
+ #include <stdint.h>
++#include <arpa/inet.h>
+ 
+ #include "libnozzle.h"
+ #include "internals.h"
+@@ -160,6 +161,29 @@ int run_updown(const nozzle_t nozzle, const char *action, char **error_string)
+ 	return err;
+ }
+ 
++char *generate_v4_broadcast(const char *ipaddr, const char *prefix)
++{
++	int prefix_len;
++	struct in_addr mask;
++	struct in_addr broadcast;
++	struct in_addr address;
++
++	prefix_len = atoi(prefix);
++
++	if ((prefix_len > 32) || (prefix_len < 0))
++		return NULL;
++
++	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
++		return NULL;
++
++	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
++
++	memset(&broadcast, 0, sizeof(broadcast));
++	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
++
++	return strdup(inet_ntoa(broadcast));
++}
++
+ #if 0
+ static void _close(nozzle_t nozzle)
+ {
+@@ -627,29 +651,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-static char *_get_v4_broadcast(const char *ipaddr, const char *prefix)
+-{
+-	int prefix_len;
+-	struct in_addr mask;
+-	struct in_addr broadcast;
+-	struct in_addr address;
+-
+-	prefix_len = atoi(prefix);
+-
+-	if ((prefix_len > 32) || (prefix_len < 0))
+-		return NULL;
+-
+-	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
+-		return NULL;
+-
+-	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
+-
+-	memset(&broadcast, 0, sizeof(broadcast));
+-	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
+-
+-	return strdup(inet_ntoa(broadcast));
+-}
+-
+ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 01ea3940..985019bb 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -63,4 +63,6 @@ struct nozzle_iface {
+ int execute_bin_sh_command(const char *command, char **error_string);
+ int run_updown(const nozzle_t nozzle, const char *action, char **error_string);
+ 
++char *generate_v4_broadcast(const char *ipaddr, const char *prefix);
++
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 7fb772e6..7f141ca2 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -19,7 +19,6 @@
+ #include <unistd.h>
+ #include <sys/ioctl.h>
+ #include <net/ethernet.h>
+-#include <arpa/inet.h>
+ #include <pthread.h>
+ #include <limits.h>
+ #include <stdio.h>
+@@ -119,29 +118,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-static char *_get_v4_broadcast(const char *ipaddr, const char *prefix)
+-{
+-	int prefix_len;
+-	struct in_addr mask;
+-	struct in_addr broadcast;
+-	struct in_addr address;
+-
+-	prefix_len = atoi(prefix);
+-
+-	if ((prefix_len > 32) || (prefix_len < 0))
+-		return NULL;
+-
+-	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
+-		return NULL;
+-
+-	mask.s_addr = htonl(~((1 << (32 - prefix_len)) - 1));
+-
+-	memset(&broadcast, 0, sizeof(broadcast));
+-	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
+-
+-	return strdup(inet_ntoa(broadcast));
+-}
+-
+ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+@@ -156,7 +132,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ #endif
+ 
+ 	if (!strchr(ipaddr, ':')) {
+-		broadcast = _get_v4_broadcast(ipaddr, prefix);
++		broadcast = generate_v4_broadcast(ipaddr, prefix);
+ 		if (!broadcast) {
+ 			errno = EINVAL;
+ 			return -1;
+@@ -239,6 +215,8 @@ static int _find_ip(nozzle_t nozzle,
+ 
+ /*
+  * internal helpers below should be completed
++ *
++ * keep all ioctl work within this file
+  */
+ 
+ static int is_valid_nozzle(const nozzle_t nozzle)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0111-nozzle-move-find_ip-to-internals.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0111-nozzle-move-find_ip-to-internals.patch
new file mode 100644
index 000000000..594893328
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0111-nozzle-move-find_ip-to-internals.patch
@@ -0,0 +1,152 @@ 
+From 67289ccce53a690828e8cf05b6acdbfa53291cee Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Dec 2017 14:09:17 +0100
+Subject: [PATCH] [nozzle] move find_ip to internals
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 52 +++++++++++++++++++++----------------------
+ libnozzle/internals.h |  4 ++++
+ libnozzle/libnozzle.c | 30 ++-----------------------
+ 3 files changed, 32 insertions(+), 54 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index d168031e..a1e41004 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -184,6 +184,32 @@ char *generate_v4_broadcast(const char *ipaddr, const char *prefix)
+ 	return strdup(inet_ntoa(broadcast));
+ }
+ 
++int find_ip(nozzle_t nozzle,
++	    const char *ipaddr, const char *prefix,
++	    struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
++{
++	struct nozzle_ip *local_ip, *local_ip_prev;
++	int found = 0;
++
++	local_ip = local_ip_prev = nozzle->ip;
++
++	while(local_ip) {
++		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
++			found = 1;
++			break;
++		}
++		local_ip_prev = local_ip;
++		local_ip = local_ip->next;
++	}
++
++	if (found) {
++		*ip = local_ip;
++		*ip_prev = local_ip_prev;
++	}
++
++	return found;
++}
++
+ #if 0
+ static void _close(nozzle_t nozzle)
+ {
+@@ -720,32 +746,6 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	return _execute_bin_sh(cmdline, error_string);
+ }
+ 
+-static int _find_ip(nozzle_t nozzle,
+-			const char *ipaddr, const char *prefix,
+-			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
+-{
+-	struct nozzle_ip *local_ip, *local_ip_prev;
+-	int found = 0;
+-
+-	local_ip = local_ip_prev = nozzle->ip;
+-
+-	while(local_ip) {
+-		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
+-			found = 1;
+-			break;
+-		}
+-		local_ip_prev = local_ip;
+-		local_ip = local_ip->next;
+-	}
+-
+-	if (found) {
+-		*ip = local_ip;
+-		*ip_prev = local_ip_prev;
+-	}
+-
+-	return found;
+-}
+-
+ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 985019bb..6a940ee9 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -63,6 +63,10 @@ struct nozzle_iface {
+ int execute_bin_sh_command(const char *command, char **error_string);
+ int run_updown(const nozzle_t nozzle, const char *action, char **error_string);
+ 
++int find_ip(nozzle_t nozzle,
++	    const char *ipaddr, const char *prefix,
++	    struct nozzle_ip **ip, struct nozzle_ip **ip_prev);
++
+ char *generate_v4_broadcast(const char *ipaddr, const char *prefix);
+ 
+ #endif
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 7f141ca2..30b5d4ce 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -187,32 +187,6 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 	return execute_bin_sh_command(cmdline, error_string);
+ }
+ 
+-static int _find_ip(nozzle_t nozzle,
+-			const char *ipaddr, const char *prefix,
+-			struct nozzle_ip **ip, struct nozzle_ip **ip_prev)
+-{
+-	struct nozzle_ip *local_ip, *local_ip_prev;
+-	int found = 0;
+-
+-	local_ip = local_ip_prev = nozzle->ip;
+-
+-	while(local_ip) {
+-		if ((!strcmp(local_ip->ipaddr, ipaddr)) && (!strcmp(local_ip->prefix, prefix))) {
+-			found = 1;
+-			break;
+-		}
+-		local_ip_prev = local_ip;
+-		local_ip = local_ip->next;
+-	}
+-
+-	if (found) {
+-		*ip = local_ip;
+-		*ip_prev = local_ip_prev;
+-	}
+-
+-	return found;
+-}
+-
+ /*
+  * internal helpers below should be completed
+  *
+@@ -750,7 +724,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		goto out_clean;
+ 	}
+ 
+-	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
++	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+ 	if (found) {
+ 		goto out_clean;
+ 	}
+@@ -829,7 +803,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		goto out_clean;
+ 	}
+ 
+-	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
++	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+ 	if (!found) {
+ 		goto out_clean;
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0112-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0112-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
new file mode 100644
index 000000000..098254a22
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0112-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
@@ -0,0 +1,220 @@ 
+From 37c6c225acc5e91773a24d066dfba5c2a0d2ec0e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 05:07:33 +0100
+Subject: [PATCH] [nozzle] decouple running pre-up.d/up.d/down.d/post-down.d
+ from interface status (part 1)
+
+provide the facility to do it via nozzle_run_updown but delegate the task to
+the application.
+
+This has the benefit of much better fine grained control over errors during those
+code paths.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 26 ---------------
+ libnozzle/internals.h |  1 -
+ libnozzle/libnozzle.c | 76 ++++++++++++++++++++++++++++++++++++++-----
+ libnozzle/libnozzle.h | 25 ++++++++++++++
+ 4 files changed, 93 insertions(+), 35 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index a1e41004..48815e4d 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -135,32 +135,6 @@ out_clean0:
+ 	return err;
+ }
+ 
+-int run_updown(const nozzle_t nozzle, const char *action, char **error_string)
+-{
+-	char command[PATH_MAX];
+-	struct stat sb;
+-	int err = 0;
+-
+-	if (!nozzle->hasupdown)
+-		return 0;
+-
+-	memset(command, 0, PATH_MAX);
+-
+-	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action, nozzle->name);
+-
+-	err = stat(command, &sb);
+-	if ((err < 0) && (errno == ENOENT))
+-		return 0;
+-
+-	err = execute_bin_sh_command(command, error_string);
+-	if ((!err) && (*error_string)) {
+-		free(*error_string);
+-		*error_string = NULL;
+-	}
+-
+-	return err;
+-}
+-
+ char *generate_v4_broadcast(const char *ipaddr, const char *prefix)
+ {
+ 	int prefix_len;
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 6a940ee9..f6c25a92 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -61,7 +61,6 @@ struct nozzle_iface {
+ #define ifname ifr.ifr_name
+ 
+ int execute_bin_sh_command(const char *command, char **error_string);
+-int run_updown(const nozzle_t nozzle, const char *action, char **error_string);
+ 
+ int find_ip(nozzle_t nozzle,
+ 	    const char *ipaddr, const char *prefix,
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 30b5d4ce..948e8363 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -99,8 +99,6 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 		goto out_clean;
+ 	}
+ 
+-	run_updown(nozzle, "down.d", error_down);
+-
+ 	ifr.ifr_flags &= ~IFF_UP;
+ 
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+@@ -109,8 +107,6 @@ static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 		goto out_clean;
+ 	}
+ 
+-	run_updown(nozzle, "post-down.d", error_postdown);
+-
+ 	nozzle->up = 0;
+ 
+ out_clean:
+@@ -650,8 +646,6 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		goto out_clean;
+ 	}
+ 
+-	run_updown(nozzle, "pre-up.d", error_preup);
+-
+ 	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+ 	if (err) {
+@@ -659,8 +653,6 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		goto out_clean;
+ 	}
+ 
+-	run_updown(nozzle, "up.d", error_up);
+-
+ 	nozzle->up = 1;
+ 
+ out_clean:
+@@ -894,6 +886,74 @@ out_clean:
+ 	return err;
+ }
+ 
++int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
++{
++	int err = 0, savederrno = 0;
++	char command[PATH_MAX];
++	const char *action_str = NULL;
++	struct stat sb;
++
++	if (action > NOZZLE_POSTDOWN) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!exec_string) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	if (!nozzle->hasupdown) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	switch(action) {
++		case NOZZLE_PREUP:
++			action_str = "pre-up.d";
++			break;
++		case NOZZLE_UP:
++			action_str = "up.d";
++			break;
++		case NOZZLE_DOWN:
++			action_str = "down.d";
++			break;
++		case NOZZLE_POSTDOWN:
++			action_str = "post-down.d";
++			break;
++	}
++
++	memset(command, 0, PATH_MAX);
++
++	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action_str, nozzle->name);
++
++	err = stat(command, &sb);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	err = execute_bin_sh_command(command, exec_string);
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno =  savederrno;
++	return err;
++}
++
+ /*
+  * functions below should be completed
+  */
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index dbbadf51..5d28154e 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -77,6 +77,31 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 
+ int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
+ 
++
++#define NOZZLE_PREUP    0
++#define NOZZLE_UP       1
++#define NOZZLE_DOWN     2
++#define NOZZLE_POSTDOWN 3
++
++/**
++ * nozzle_run_updown
++ * @brief execute updown commands associated with a nozzle device
++ *
++ * nozzle - pointer to the nozzle struct
++ *
++ * action - pre-up.d / up.d / down.d / post-down.d (see defines above)
++ *
++ * exec_string - pointers to string to record executing action stdout/stderr.
++ *               The string is malloc'ed, the caller needs to free the buffer.
++ *               If the script generates no output this string might be NULL.
++ *
++ * @return
++ * 0 on success
++ * -1 on error and errno is set.
++ */
++
++int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string);
++
+ /**
+  * nozzle_set_up
+  * @brief equivalent of ifconfig up, executes pre-up.d up.d if configured
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0113-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0113-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
new file mode 100644
index 000000000..1312a380b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0113-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
@@ -0,0 +1,249 @@ 
+From e9efb16f65e4e6ebd256695383bc7d630f33a18e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 05:25:57 +0100
+Subject: [PATCH] [nozzle] decouple running pre-up.d/up.d/down.d/post-down.d
+ from interface status (part 2)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c         | 15 +++----
+ libnozzle/libnozzle.h         | 15 +------
+ libnozzle/tests/nozzle_test.c | 79 +++++++++++++++++++----------------
+ 3 files changed, 51 insertions(+), 58 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 948e8363..95ab1132 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -81,7 +81,7 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
++static int _set_down(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+ 	struct ifreq ifr;
+@@ -522,7 +522,7 @@ int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+ 		prev->next = nozzle->next;
+ 	}
+ 
+-	_set_down(nozzle, error_down, error_postdown);
++	_set_down(nozzle);
+ 
+ 	ip = nozzle->ip;
+ 	while (ip) {
+@@ -661,7 +661,7 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
++int nozzle_set_down(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+ 
+@@ -677,13 +677,7 @@ int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+ 		goto out_clean;
+ 	}
+ 
+-	if ((nozzle->hasupdown) && ((!error_down) || (!error_postdown))) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _set_down(nozzle, error_down, error_postdown);
++	err = _set_down(nozzle);
+ 	savederrno = errno;
+ 
+ out_clean:
+@@ -947,6 +941,7 @@ int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
+ 	}
+ 
+ 	err = execute_bin_sh_command(command, exec_string);
++	savederrno = errno;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&config_mutex);
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 5d28154e..ce3b66a8 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -128,27 +128,16 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
+ 
+ /**
+  * nozzle_set_down
+- * @brief equivalent of ifconfig down, executes down.d post-down.d
++ * @brief equivalent of ifconfig down
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * error_down - pointer to a string pointer to record errors from executing down.d
+- *              when configured. The string is malloc'ed, the caller needs to free that
+- *              buffer.
+- *
+- * error_postdown - pointer to a string pointer to record errors from executing post-down.d
+- *                  when configured. The string is malloc'ed, the caller needs to free
+- *                  that buffer.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * error_down / error_postdown are set to NULL if execution of external scripts
+- * is sucessful
+- * error_down / error_postdown will contain strings recording the execution error.
+  */
+ 
+-int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown);
++int nozzle_set_down(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_add_ip
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index b83f62c4..b1cb72a3 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -860,22 +860,30 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_down);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
++	}
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+ 		error_down = NULL;
+ 	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	err = nozzle_set_down(nozzle);
+ 	if (err < 0) {
+ 		printf("Unable to put the interface down\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_postdown);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+@@ -939,22 +947,30 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_down);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
++	}
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+ 		error_down = NULL;
+ 	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	err = nozzle_set_down(nozzle);
+ 	if (err < 0) {
+ 		printf("Unable to put the interface down\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_postdown);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	nozzle_close(nozzle, &error_down, &error_postdown);
+ 	if (error_down) {
+@@ -999,22 +1015,30 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_set_down(nozzle, &error_down, &error_postdown);
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_down);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
++	}
+ 	if (error_down) {
+ 		printf("down output: %s\n", error_down);
+ 		free(error_down);
+ 		error_down = NULL;
+ 	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	err = nozzle_set_down(nozzle);
+ 	if (err < 0) {
+ 		printf("Unable to put the interface down\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_postdown);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
++	}
++	if (error_postdown) {
++		printf("postdown output: %s\n", error_down);
++		free(error_down);
++		error_down = NULL;
++	}
+ 
+ 	nozzle_close(nozzle, &error_down, &error_postdown);
+ 	if (error_down) {
+@@ -1031,6 +1055,7 @@ static int check_knet_up_down(void)
+ 	printf("Test ERROR conditions\n");
+ 
+ 	printf("Pass NULL to nozzle set_up\n");
++	err = 0;
+ 	errno = 0;
+ 	if ((nozzle_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_up sanity checks\n");
+@@ -1056,23 +1081,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Pass NULL to nozzle set_down\n");
+ 	errno = 0;
+-	if ((nozzle_set_down(NULL, &error_down, &error_postdown) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_down sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_down set_down\n");
+-	errno = 0;
+-	if ((nozzle_set_down(nozzle, NULL, &error_postdown) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_down sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_postdown set_down\n");
+-	errno = 0;
+-	if ((nozzle_set_down(nozzle, &error_down, NULL) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_down(NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_down sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0114-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0114-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
new file mode 100644
index 000000000..278ea2051
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0114-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
@@ -0,0 +1,359 @@ 
+From 2148307f4262615d02152a21011e57251b63343f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 05:32:05 +0100
+Subject: [PATCH] [nozzle] decouple running pre-up.d/up.d/down.d/post-down.d
+ from interface status (part 3)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c         |   2 +-
+ libnozzle/libnozzle.h         |  13 +--
+ libnozzle/tests/nozzle_test.c | 161 +++-------------------------------
+ 3 files changed, 16 insertions(+), 160 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 95ab1132..0b583d90 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -491,7 +491,7 @@ out_error:
+ 	return NULL;
+ }
+ 
+-int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
++int nozzle_close(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+ 	nozzle_t temp = lib_cfg.head;
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index ce3b66a8..562d3767 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -59,23 +59,12 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+  *
+  * nozzle - pointer to the nozzle struct to destroy
+  *
+- * error_down - pointers to string to record errors from executing down.d
+- *              when configured. The string is malloc'ed, the caller needs to free those
+- *              buffers.
+- *
+- * error_postdown - pointers to string to record errors from executing post-down.d
+- *                  when configured. The string is malloc'ed, the caller needs to free
+- *                  those buffers.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * error_down / error_postdown are set to NULL if execution of external scripts
+- * is sucessful
+- * error_down / error_postdown will contain strings recording the execution error.
+  */
+ 
+-int nozzle_close(nozzle_t nozzle, char **error_down, char **error_postdown);
++int nozzle_close(nozzle_t nozzle);
+ 
+ 
+ #define NOZZLE_PREUP    0
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index b1cb72a3..c79a1090 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -67,7 +67,6 @@ static int is_if_in_system(char *name)
+ static int test_iface(char *name, size_t size, const char *updownpath)
+ {
+ 	nozzle_t nozzle;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	nozzle=nozzle_open(name, size, updownpath);
+ 	if (!nozzle) {
+@@ -88,17 +87,7 @@ static int test_iface(char *name, size_t size, const char *updownpath)
+ 		printf("Found interface %s in nozzle db\n", name);
+ 	}
+ 
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-
+-	if (error_down) {
+-		printf("Error from error_down: %s\n", error_down);
+-		free(error_down);
+-	}
+-
+-	if (error_postdown) {
+-		printf("Error from error_down: %s\n", error_postdown);
+-		free(error_postdown);
+-	}
++	nozzle_close(nozzle);
+ 
+ 	if (is_if_in_system(name) == 0)
+ 		printf("Successfully removed interface %s from the system\n", name);
+@@ -200,7 +189,6 @@ static int check_knet_multi_eth(void)
+ 	int err=0;
+ 	nozzle_t nozzle1 = NULL;
+ 	nozzle_t nozzle2 = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing multiple knet interface instances\n");
+ 
+@@ -234,27 +222,11 @@ static int check_knet_multi_eth(void)
+ 	}
+ 
+ 	if (nozzle1) {
+-		nozzle_close(nozzle1, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle1);
+ 	}
+ 
+ 	if (nozzle2) {
+-		nozzle_close(nozzle2, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle2);
+ 	}
+ 
+ 	printf("Testing error conditions\n");
+@@ -285,27 +257,11 @@ static int check_knet_multi_eth(void)
+ 
+ out_clean:
+ 	if (nozzle1) {
+-		nozzle_close(nozzle1, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle1);
+ 	}
+ 
+ 	if (nozzle2) {
+-		nozzle_close(nozzle2, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle2);
+ 	}
+ 
+ 	return err;
+@@ -317,7 +273,6 @@ static int check_knet_mtu(void)
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+ 	nozzle_t nozzle;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 	char *error_string = NULL;
+ 
+ 	int current_mtu = 0;
+@@ -391,15 +346,7 @@ static int check_knet_mtu(void)
+ 
+ out_clean:
+ 	if (nozzle) {
+-		nozzle_close(nozzle, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle);
+ 	}
+ 
+ 	return err;
+@@ -413,7 +360,6 @@ static int check_knet_mtu_ipv6(void)
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing get/set MTU with IPv6 address\n");
+ 
+@@ -574,15 +520,7 @@ static int check_knet_mtu_ipv6(void)
+ 
+ out_clean:
+ 	if (nozzle) {
+-		nozzle_close(nozzle, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle);
+ 	}
+ 
+ 	return err;
+@@ -596,7 +534,6 @@ static int check_knet_mac(void)
+ 	nozzle_t nozzle;
+ 	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
+ 	struct ether_addr *cur_mac, *tmp_mac;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing get/set MAC\n");
+ 
+@@ -691,15 +628,7 @@ out_clean:
+ 		free(temp_mac);
+ 
+ 	if (nozzle) {
+-		nozzle_close(nozzle, &error_down, &error_postdown);
+-		if (error_down) {
+-			printf("Error from error_down: %s\n", error_down);
+-			free(error_down);
+-		}
+-		if (error_postdown) {
+-			printf("Error from error_down: %s\n", error_postdown);
+-			free(error_postdown);
+-		}
++		nozzle_close(nozzle);
+ 	}
+ 
+ 	return err;
+@@ -905,17 +834,7 @@ static int check_knet_up_down(void)
+ 		goto out_clean;
+ 	}
+ 
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	nozzle_close(nozzle);
+ 
+ 	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+ 
+@@ -972,17 +891,7 @@ static int check_knet_up_down(void)
+ 		error_down = NULL;
+ 	}
+ 
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	nozzle_close(nozzle);
+ 
+ 	printf("Testing interface pre-up/up/down/post-down\n");
+ 
+@@ -1040,17 +949,7 @@ static int check_knet_up_down(void)
+ 		error_down = NULL;
+ 	}
+ 
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	nozzle_close(nozzle);
+ 
+ 	printf("Test ERROR conditions\n");
+ 
+@@ -1088,17 +987,7 @@ static int check_knet_up_down(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -1110,7 +999,6 @@ static int check_knet_close_leak(void)
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing close leak (needs valgrind)\n");
+ 
+@@ -1151,17 +1039,7 @@ static int check_knet_close_leak(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
+@@ -1176,7 +1054,6 @@ static int check_knet_set_del_ip(void)
+ 	char *ip_list = NULL;
+ 	int ip_list_entries = 0, i, offset = 0;
+ 	char *error_string = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing interface add/remove ip\n");
+ 
+@@ -1405,17 +1282,7 @@ static int check_knet_set_del_ip(void)
+ 	}
+ 
+ out_clean:
+-	nozzle_close(nozzle, &error_down, &error_postdown);
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
++	nozzle_close(nozzle);
+ 
+ 	return err;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0115-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0115-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
new file mode 100644
index 000000000..b94cc5831
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0115-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch
@@ -0,0 +1,315 @@ 
+From 24e6b1bd700eb3d0f89812e253d43414d15870f2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 06:51:10 +0100
+Subject: [PATCH] [nozzle] decouple running pre-up.d/up.d/down.d/post-down.d
+ from interface status (part 4)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c         |   8 +-
+ libnozzle/libnozzle.h         |  15 +---
+ libnozzle/tests/nozzle_test.c | 146 ++++++++++++++--------------------
+ 3 files changed, 61 insertions(+), 108 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 0b583d90..afed9f9b 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -610,7 +610,7 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ 	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+ }
+ 
+-int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
++int nozzle_set_up(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+ 	struct ifreq ifr;
+@@ -627,12 +627,6 @@ int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+ 		goto out_clean;
+ 	}
+ 
+-	if ((nozzle->hasupdown) && ((!error_preup) || (!error_up))) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+ 	if (nozzle->up) {
+ 		goto out_clean;
+ 	}
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 562d3767..e4fc51a1 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -93,27 +93,16 @@ int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
+ 
+ /**
+  * nozzle_set_up
+- * @brief equivalent of ifconfig up, executes pre-up.d up.d if configured
++ * @brief equivalent of ifconfig up
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * error_preup - pointer to string pointer to record errors from executing pre-up.d
+- *               when configured. The string is malloc'ed, the caller needs to free that
+- *               buffer.
+- *
+- * error_up - pointer to string pointer to record errors from executing up.d
+- *            when configured. The string is malloc'ed, the caller needs to free that
+- *            buffer.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * error_preup / error_up are set to NULL if execution of external scripts
+- * is sucessful
+- * error_preup / error_up will contain strings recording the execution error.
+  */
+ 
+-int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up);
++int nozzle_set_up(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_set_down
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index c79a1090..2fa3566d 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -736,8 +736,6 @@ static int check_knet_up_down(void)
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_string = NULL;
+-	char *error_preup = NULL, *error_up = NULL;
+-	char *error_down = NULL, *error_postdown = NULL;
+ 
+ 	printf("Testing interface up/down\n");
+ 
+@@ -750,17 +748,7 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+-	if (error_preup) {
+-		printf("preup output: %s\n", error_preup);
+-		free(error_preup);
+-		error_preup = NULL;
+-	}
+-	if (error_up) {
+-		printf("up output: %s\n", error_up);
+-		free(error_up);
+-		error_up = NULL;
+-	}
++	err = nozzle_set_up(nozzle);
+ 	if (err < 0) {
+ 		printf("Unable to set interface up\n");
+ 		err = -1;
+@@ -789,30 +777,12 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_down);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
+-	}
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+ 	err = nozzle_set_down(nozzle);
+ 	if (err < 0) {
+ 		printf("Unable to put the interface down\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_postdown);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
+-	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
+-	}
+ 
+ 	memset(verifycmd, 0, sizeof(verifycmd));
+ 	snprintf(verifycmd, sizeof(verifycmd)-1,
+@@ -847,33 +817,41 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+-	if (error_preup) {
+-		printf("preup output: %s\n", error_preup);
+-		free(error_preup);
+-		error_preup = NULL;
++	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_PREUP error: %s\n", strerror(errno));
+ 	}
+-	if (error_up) {
+-		printf("up output: %s\n", error_up);
+-		free(error_up);
+-		error_up = NULL;
++	if (error_string) {
++		printf("preup output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
+ 	}
++	err = nozzle_set_up(nozzle);
+ 	if (err < 0) {
+-		printf("Unable to set interface up\n");
++		printf("Unable to put the interface up\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
++	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_UP error: %s\n", strerror(errno));
++	}
++	if (error_string) {
++		printf("up output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_down);
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+ 	if (err) {
+ 		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
+ 	}
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
++	if (error_string) {
++		printf("down output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
+ 	}
+ 	err = nozzle_set_down(nozzle);
+ 	if (err < 0) {
+@@ -881,14 +859,14 @@ static int check_knet_up_down(void)
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_postdown);
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+ 	if (err) {
+ 		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
+ 	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
++	if (error_string) {
++		printf("postdown output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
+ 	}
+ 
+ 	nozzle_close(nozzle);
+@@ -905,33 +883,41 @@ static int check_knet_up_down(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(nozzle, &error_preup, &error_up);
+-	if (error_preup) {
+-		printf("preup output: %s\n", error_preup);
+-		free(error_preup);
+-		error_preup = NULL;
++	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_PREUP error: %s\n", strerror(errno));
+ 	}
+-	if (error_up) {
+-		printf("up output: %s\n", error_up);
+-		free(error_up);
+-		error_up = NULL;
++	if (error_string) {
++		printf("preup output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
+ 	}
++	err = nozzle_set_up(nozzle);
+ 	if (err < 0) {
+-		printf("Unable to set interface up\n");
++		printf("Unable to put the interface up\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
++	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
++	if (err) {
++		printf("nozzle_run_updown NOZZLE_UP error: %s\n", strerror(errno));
++	}
++	if (error_string) {
++		printf("up output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
+ 
+ 	printf("Put the interface down\n");
+ 
+-	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_down);
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+ 	if (err) {
+ 		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
+ 	}
+-	if (error_down) {
+-		printf("down output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
++	if (error_string) {
++		printf("down output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
+ 	}
+ 	err = nozzle_set_down(nozzle);
+ 	if (err < 0) {
+@@ -939,14 +925,14 @@ static int check_knet_up_down(void)
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_postdown);
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+ 	if (err) {
+ 		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
+ 	}
+-	if (error_postdown) {
+-		printf("postdown output: %s\n", error_down);
+-		free(error_down);
+-		error_down = NULL;
++	if (error_string) {
++		printf("postdown output: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
+ 	}
+ 
+ 	nozzle_close(nozzle);
+@@ -956,23 +942,7 @@ static int check_knet_up_down(void)
+ 	printf("Pass NULL to nozzle set_up\n");
+ 	err = 0;
+ 	errno = 0;
+-	if ((nozzle_set_up(NULL, &error_preup, &error_up) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_up sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_preup set_up\n");
+-	errno = 0;
+-	if ((nozzle_set_up(nozzle, NULL, &error_up) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_up sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to error_up set_up\n");
+-	errno = 0;
+-	if ((nozzle_set_up(nozzle, &error_preup, NULL) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_up(NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_up sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0116-nozzle-move-set-up-and-down-to-the-stable-API-sectio.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0116-nozzle-move-set-up-and-down-to-the-stable-API-sectio.patch
new file mode 100644
index 000000000..e3dee63cf
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0116-nozzle-move-set-up-and-down-to-the-stable-API-sectio.patch
@@ -0,0 +1,402 @@ 
+From 930f7e9a681030d70054a26cc2e68b846b254633 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 07:01:11 +0100
+Subject: [PATCH] [nozzle] move set up and down to the stable API section
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 133 ---------------------------
+ libnozzle/libnozzle.c | 208 +++++++++++++++++++++---------------------
+ 2 files changed, 104 insertions(+), 237 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 48815e4d..f21784ff 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -518,139 +518,6 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ 	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+ }
+ 
+-int nozzle_set_up(nozzle_t nozzle, char **error_preup, char **error_up)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if ((nozzle->hasupdown) && ((!error_preup) || (!error_up))) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (nozzle->up) {
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	_exec_updown(nozzle, "pre-up.d", error_preup);
+-
+-	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	_exec_updown(nozzle, "up.d", error_up);
+-
+-	nozzle->up = 1;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-static int _set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if (!nozzle->up) {
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	_exec_updown(nozzle, "down.d", error_down);
+-
+-	ifr.ifr_flags &= ~IFF_UP;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	_exec_updown(nozzle, "post-down.d", error_postdown);
+-
+-	nozzle->up = 0;
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_set_down(nozzle_t nozzle, char **error_down, char **error_postdown)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	if (!nozzle) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if ((nozzle->hasupdown) && ((!error_down) || (!error_postdown))) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _set_down(nozzle, error_down, error_postdown);
+-	savederrno = errno;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index afed9f9b..0ea6e0c6 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -81,39 +81,6 @@ static void _close_cfg(void)
+ 	}
+ }
+ 
+-static int _set_down(nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if (!nozzle->up) {
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ifr.ifr_flags &= ~IFF_UP;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	nozzle->up = 0;
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+@@ -305,6 +272,39 @@ out_clean:
+ 	return err;
+ }
+ 
++static int set_iface_down(nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	if (!nozzle->up) {
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ifr.ifr_flags &= ~IFF_UP;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	nozzle->up = 0;
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
+ /*
+  * public API
+  */
+@@ -522,7 +522,7 @@ int nozzle_close(nozzle_t nozzle)
+ 		prev->next = nozzle->next;
+ 	}
+ 
+-	_set_down(nozzle);
++	set_iface_down(nozzle);
+ 
+ 	ip = nozzle->ip;
+ 	while (ip) {
+@@ -610,76 +610,6 @@ int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+ 	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+ }
+ 
+-int nozzle_set_up(nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (nozzle->up) {
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	nozzle->up = 1;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_set_down(nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = _set_down(nozzle);
+-	savederrno = errno;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -947,6 +877,76 @@ out_clean:
+  * functions below should be completed
+  */
+ 
++int nozzle_set_up(nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	if (nozzle->up) {
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ifr.ifr_flags |= IFF_UP | IFF_RUNNING;
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	nozzle->up = 1;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_set_down(nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = set_iface_down(nozzle);
++	savederrno = errno;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
+ int nozzle_get_mtu(const nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0117-nozzle-nozzle_open-and-nozzle_close-should-be-stable.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0117-nozzle-nozzle_open-and-nozzle_close-should-be-stable.patch
new file mode 100644
index 000000000..3e6e102ab
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0117-nozzle-nozzle_open-and-nozzle_close-should-be-stable.patch
@@ -0,0 +1,570 @@ 
+From 2183f046c26474e6280cbb15e073dbe9acaa6c62 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 07:13:16 +0100
+Subject: [PATCH] [nozzle] nozzle_open and nozzle_close should be stable now
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 528 +++++++++++++++++++++---------------------
+ 1 file changed, 260 insertions(+), 268 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 0ea6e0c6..6cd5c634 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -49,38 +49,6 @@ static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+  * internal helpers
+  */
+ 
+-static void _close(nozzle_t nozzle)
+-{
+-#ifdef KNET_BSD
+-	struct ifreq ifr;
+-#endif
+-
+-	if (!nozzle)
+-		return;
+-
+-	if (nozzle->fd)
+-		close(nozzle->fd);
+-
+-#ifdef KNET_BSD
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
+-#endif
+-
+-	free(nozzle);
+-
+-	return;
+-}
+-
+-static void _close_cfg(void)
+-{
+-	if (lib_cfg.head == NULL) {
+-		close(lib_cfg.ioctlfd);
+-		lib_init = 0;
+-	}
+-}
+-
+ static int _set_ip(nozzle_t nozzle, const char *command,
+ 		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+@@ -156,6 +124,40 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+  * keep all ioctl work within this file
+  */
+ 
++static void lib_fini(void)
++{
++	if (lib_cfg.head == NULL) {
++		close(lib_cfg.ioctlfd);
++		lib_init = 0;
++	}
++}
++
++static void destroy_iface(nozzle_t nozzle)
++{
++#ifdef KNET_BSD
++	struct ifreq ifr;
++#endif
++
++	if (!nozzle)
++		return;
++
++	if (nozzle->fd)
++		close(nozzle->fd);
++
++#ifdef KNET_BSD
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
++#endif
++
++	free(nozzle);
++
++	lib_fini();
++
++	return;
++}
++
+ static int is_valid_nozzle(const nozzle_t nozzle)
+ {
+ 	nozzle_t temp;
+@@ -309,242 +311,6 @@ out_clean:
+  * public API
+  */
+ 
+-nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+-{
+-	int savederrno = 0;
+-	nozzle_t nozzle = NULL;
+-	char *temp_mac = NULL;
+-#ifdef KNET_LINUX
+-	struct ifreq ifr;
+-#endif
+-#ifdef KNET_BSD
+-	uint16_t i;
+-	long int nozzlenum = 0;
+-	char curnozzle[IFNAMSIZ];
+-#endif
+-
+-	if (devname == NULL) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	if (devname_size < IFNAMSIZ) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	if (strlen(devname) > IFNAMSIZ) {
+-		errno = E2BIG;
+-		return NULL;
+-	}
+-
+-#ifdef KNET_BSD
+-	/*
+-	 * BSD does not support named devices like Linux
+-	 * but it is possible to force a nozzleX device number
+-	 * where X is 0 to 255.
+-	 */
+-	if (strlen(devname)) {
+-		if (strncmp(devname, "tap", 3)) {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-		errno = 0;
+-		nozzlenum = strtol(devname+3, NULL, 10);
+-		if (errno) {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-		if ((nozzlenum < 0) || (nozzlenum > 255)) {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-	}
+-#endif
+-
+-	if (updownpath) {
+-		/* only absolute paths */
+-		if (updownpath[0] != '/') {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-		if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
+-			errno = E2BIG;
+-			return NULL;
+-		}
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return NULL;
+-	}
+-
+-	if (!lib_init) {
+-		lib_cfg.head = NULL;
+-#ifdef KNET_LINUX
+-		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
+-#endif
+-#ifdef KNET_BSD
+-		lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+-#endif
+-		if (lib_cfg.ioctlfd < 0) {
+-			savederrno = errno;
+-			goto out_error;
+-		}
+-		lib_init = 1;
+-	}
+-
+-	nozzle = malloc(sizeof(struct nozzle_iface));
+-	if (!nozzle) {
+-		savederrno = ENOMEM;
+-		goto out_error;
+-	}
+-
+-	memset(nozzle, 0, sizeof(struct nozzle_iface));
+-
+-#ifdef KNET_BSD
+-	if (!strlen(devname)) {
+-		for (i = 0; i < 256; i++) {
+-			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
+-			nozzle->fd = open(curnozzle, O_RDWR);
+-			savederrno = errno;
+-			if (nozzle->fd > 0) {
+-				break;
+-			}
+-		}
+-		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
+-	} else {
+-		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
+-		nozzle->fd = open(curnozzle, O_RDWR);
+-		savederrno = errno;
+-		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
+-	}
+-	if (nozzle->fd < 0) {
+-		errno = EBUSY;
+-		goto out_error;
+-	}
+-	strncpy(devname, curnozzle, IFNAMSIZ);
+-	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
+-#endif
+-
+-#ifdef KNET_LINUX
+-	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, devname, IFNAMSIZ);
+-	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+-
+-	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
+-		errno = EBUSY;
+-		goto out_error;
+-	}
+-
+-	strncpy(devname, ifname, IFNAMSIZ);
+-	strncpy(nozzle->name, ifname, IFNAMSIZ);
+-#endif
+-
+-	nozzle->default_mtu = get_iface_mtu(nozzle);
+-	if (nozzle->default_mtu < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	if (get_iface_mac(nozzle, &temp_mac) < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	strncpy(nozzle->default_mac, temp_mac, 18);
+-	free(temp_mac);
+-
+-	if (updownpath) {
+-		int len = strlen(updownpath);
+-
+-		strcpy(nozzle->updownpath, updownpath);
+-		if (nozzle->updownpath[len-1] != '/') {
+-			nozzle->updownpath[len] = '/';
+-		}
+-		nozzle->hasupdown = 1;
+-	}
+-
+-	nozzle->next = lib_cfg.head;
+-	lib_cfg.head = nozzle;
+-
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return nozzle;
+-
+-out_error:
+-	_close(nozzle);
+-	_close_cfg();
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return NULL;
+-}
+-
+-int nozzle_close(nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-	nozzle_t temp = lib_cfg.head;
+-	nozzle_t prev = lib_cfg.head;
+-	struct nozzle_ip *ip, *ip_next;
+-	char *error_string = NULL;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	while ((temp) && (temp != nozzle)) {
+-		prev = temp;
+-		temp = temp->next;
+-	}
+-
+-	if (nozzle == prev) {
+-		lib_cfg.head = nozzle->next;
+-	} else {
+-		prev->next = nozzle->next;
+-	}
+-
+-	set_iface_down(nozzle);
+-
+-	ip = nozzle->ip;
+-	while (ip) {
+-		ip_next = ip->next;
+-		_set_ip(nozzle, "del", ip->ipaddr, ip->prefix, &error_string, 0);
+-		if (error_string) {
+-			free(error_string);
+-			error_string = NULL;
+-		}
+-		free(ip);
+-		ip = ip_next;
+-	}
+-
+-	_close(nozzle);
+-	_close_cfg();
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -877,6 +643,232 @@ out_clean:
+  * functions below should be completed
+  */
+ 
++nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
++{
++	int savederrno = 0;
++	nozzle_t nozzle = NULL;
++	char *temp_mac = NULL;
++#ifdef KNET_LINUX
++	struct ifreq ifr;
++#endif
++#ifdef KNET_BSD
++	uint16_t i;
++	long int nozzlenum = 0;
++	char curnozzle[IFNAMSIZ];
++#endif
++
++	if (devname == NULL) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	if (devname_size < IFNAMSIZ) {
++		errno = EINVAL;
++		return NULL;
++	}
++
++	if (strlen(devname) > IFNAMSIZ) {
++		errno = E2BIG;
++		return NULL;
++	}
++
++#ifdef KNET_BSD
++	/*
++	 * BSD does not support named devices like Linux
++	 * but it is possible to force a nozzleX device number
++	 * where X is 0 to 255.
++	 */
++	if (strlen(devname)) {
++		if (strncmp(devname, "tap", 3)) {
++			errno = EINVAL;
++			return NULL;
++		}
++		errno = 0;
++		nozzlenum = strtol(devname+3, NULL, 10);
++		if (errno) {
++			errno = EINVAL;
++			return NULL;
++		}
++		if ((nozzlenum < 0) || (nozzlenum > 255)) {
++			errno = EINVAL;
++			return NULL;
++		}
++	}
++#endif
++
++	if (updownpath) {
++		/* only absolute paths */
++		if (updownpath[0] != '/') {
++			errno = EINVAL;
++			return NULL;
++		}
++		if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
++			errno = E2BIG;
++			return NULL;
++		}
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return NULL;
++	}
++
++	if (!lib_init) {
++		lib_cfg.head = NULL;
++#ifdef KNET_LINUX
++		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
++#endif
++#ifdef KNET_BSD
++		lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
++#endif
++		if (lib_cfg.ioctlfd < 0) {
++			savederrno = errno;
++			goto out_error;
++		}
++		lib_init = 1;
++	}
++
++	nozzle = malloc(sizeof(struct nozzle_iface));
++	if (!nozzle) {
++		savederrno = ENOMEM;
++		goto out_error;
++	}
++
++	memset(nozzle, 0, sizeof(struct nozzle_iface));
++
++#ifdef KNET_BSD
++	if (!strlen(devname)) {
++		for (i = 0; i < 256; i++) {
++			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
++			nozzle->fd = open(curnozzle, O_RDWR);
++			savederrno = errno;
++			if (nozzle->fd > 0) {
++				break;
++			}
++		}
++		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
++	} else {
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
++		nozzle->fd = open(curnozzle, O_RDWR);
++		savederrno = errno;
++		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
++	}
++	if (nozzle->fd < 0) {
++		errno = EBUSY;
++		goto out_error;
++	}
++	strncpy(devname, curnozzle, IFNAMSIZ);
++	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
++#endif
++
++#ifdef KNET_LINUX
++	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, devname, IFNAMSIZ);
++	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
++
++	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
++		errno = EBUSY;
++		goto out_error;
++	}
++
++	strncpy(devname, ifname, IFNAMSIZ);
++	strncpy(nozzle->name, ifname, IFNAMSIZ);
++#endif
++
++	nozzle->default_mtu = get_iface_mtu(nozzle);
++	if (nozzle->default_mtu < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	if (get_iface_mac(nozzle, &temp_mac) < 0) {
++		savederrno = errno;
++		goto out_error;
++	}
++
++	strncpy(nozzle->default_mac, temp_mac, 18);
++	free(temp_mac);
++
++	if (updownpath) {
++		int len = strlen(updownpath);
++
++		strcpy(nozzle->updownpath, updownpath);
++		if (nozzle->updownpath[len-1] != '/') {
++			nozzle->updownpath[len] = '/';
++		}
++		nozzle->hasupdown = 1;
++	}
++
++	nozzle->next = lib_cfg.head;
++	lib_cfg.head = nozzle;
++
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return nozzle;
++
++out_error:
++	destroy_iface(nozzle);
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return NULL;
++}
++
++int nozzle_close(nozzle_t nozzle)
++{
++	int err = 0, savederrno = 0;
++	nozzle_t temp = lib_cfg.head;
++	nozzle_t prev = lib_cfg.head;
++	struct nozzle_ip *ip, *ip_next;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	while ((temp) && (temp != nozzle)) {
++		prev = temp;
++		temp = temp->next;
++	}
++
++	if (nozzle == prev) {
++		lib_cfg.head = nozzle->next;
++	} else {
++		prev->next = nozzle->next;
++	}
++
++	ip = nozzle->ip;
++	while (ip) {
++		ip_next = ip->next;
++		free(ip);
++		ip = ip_next;
++	}
++
++	destroy_iface(nozzle);
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
+ int nozzle_set_up(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0118-nozzle-fix-build-on-BSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0118-nozzle-fix-build-on-BSD.patch
new file mode 100644
index 000000000..9053b81c1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0118-nozzle-fix-build-on-BSD.patch
@@ -0,0 +1,23 @@ 
+From 362b7554e31d4e1c6a981b6cc3d86b132a8a0a9e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Dec 2017 07:29:40 +0100
+Subject: [PATCH] [nozzle] fix build on BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/nozzle_test.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 2fa3566d..c8d17518 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -17,6 +17,8 @@
+ #include <ifaddrs.h>
+ #include <stdint.h>
+ #include <limits.h>
++#include <sys/socket.h>
++#include <net/ethernet.h>
+ 
+ #ifdef KNET_LINUX
+ #include <linux/if_tun.h>
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0119-nozzle-propagate-errors-all-the-way.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0119-nozzle-propagate-errors-all-the-way.patch
new file mode 100644
index 000000000..bd4cd9cb0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0119-nozzle-propagate-errors-all-the-way.patch
@@ -0,0 +1,32 @@ 
+From 1fb6185149589ee6d1443a6138a22c098eaba84e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 26 Jan 2018 06:08:26 +0100
+Subject: [PATCH] [nozzle] propagate errors all the way
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 6cd5c634..404dc764 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -755,7 +755,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
+ 	}
+ 	if (nozzle->fd < 0) {
+-		errno = EBUSY;
++		savederrno = EBUSY;
+ 		goto out_error;
+ 	}
+ 	strncpy(devname, curnozzle, IFNAMSIZ);
+@@ -778,7 +778,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	}
+ 
+ 	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
+-		errno = EBUSY;
++		savederrno = EBUSY;
+ 		goto out_error;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0120-nozzle-fix-man-page-generation.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0120-nozzle-fix-man-page-generation.patch
new file mode 100644
index 000000000..d626238f7
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0120-nozzle-fix-man-page-generation.patch
@@ -0,0 +1,38 @@ 
+From 57e9341ce805f22928156aecdcf9e635ba8052c4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Jan 2018 07:37:56 +0100
+Subject: [PATCH] [nozzle] fix man page generation
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/man/Makefile.am | 15 +++++++--------
+ 1 file changed, 7 insertions(+), 8 deletions(-)
+
+diff --git a/libnozzle/man/Makefile.am b/libnozzle/man/Makefile.am
+index 49381eef..b41863ab 100644
+--- a/libnozzle/man/Makefile.am
++++ b/libnozzle/man/Makefile.am
+@@ -12,16 +12,15 @@ include $(top_srcdir)/build-aux/check.mk
+ 
+ dist_man_MANS =
+ 
+-update-man-pages: doxyfile.stamp
++$(MANS): doxyfile.stamp
+ 
+-doxyfile.stamp: Doxyfile
+-if MANPAGEUPDATES
++$(top_builddir)/build-aux/doxyxml: $(top_srcdir)/build-aux/doxyxml.c
++	$(MAKE) -C $(top_builddir)/build-aux doxyxml
++
++doxyfile.stamp: Doxyfile $(top_srcdir)/libnozzle/libnozzle.h $(top_builddir)/build-aux/doxyxml $(top_srcdir)/build-aux/doxyxml.c
+ 	$(DOXYGEN) Doxyfile
+-	$(DOXY2MAN) -o $(abs_srcdir) -s 3 --short-pkg @PACKAGE_NAME@ --pkg "Kronosnet Programmer's Manual" $(builddir)/xml/libnozzle_8h.xml
+-else
+-	@echo this system does not have doxy2man or doxygen installed. Unable to update man pages automatically.
+-endif
++	$(top_builddir)/build-aux/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" -d $(builddir)/xml/ libnozzle_8h.xml
+ 	touch doxyfile.stamp
+ 
+ clean-local:
+-	rm -rf doxyfile.stamp xml
++	rm -rf doxyfile.stamp xml *.3
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0121-nozzle-move-man-pages-to-top-level-dir.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0121-nozzle-move-man-pages-to-top-level-dir.patch
new file mode 100644
index 000000000..b2e52bf30
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0121-nozzle-move-man-pages-to-top-level-dir.patch
@@ -0,0 +1,141 @@ 
+From b8fde0f3fa84666d7daa3ed8fb029f3b8b8cb347 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 19 Feb 2018 14:34:04 +0100
+Subject: [PATCH] [nozzle] move man pages to top level dir
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac                                  |  3 +--
+ libnozzle/Makefile.am                         |  4 +--
+ libnozzle/man/Makefile.am                     | 26 -------------------
+ .../man/Doxyfile.in => man/Doxyfile-nozzle.in |  4 +--
+ man/Makefile.am                               | 15 +++++++++--
+ 5 files changed, 17 insertions(+), 35 deletions(-)
+ delete mode 100644 libnozzle/man/Makefile.am
+ rename libnozzle/man/Doxyfile.in => man/Doxyfile-nozzle.in (79%)
+
+diff --git a/configure.ac b/configure.ac
+index 686157e7..86faa743 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -501,8 +501,6 @@ AC_CONFIG_FILES([
+ 		libnozzle/Makefile
+ 		libnozzle/libnozzle.pc
+ 		libnozzle/tests/Makefile
+-		libnozzle/man/Doxyfile
+-		libnozzle/man/Makefile
+ 		kronosnetd/Makefile
+ 		kronosnetd/kronosnetd.logrotate
+ 		libknet/Makefile
+@@ -510,6 +508,7 @@ AC_CONFIG_FILES([
+ 		libknet/tests/Makefile
+ 		man/Makefile
+ 		man/Doxyfile-knet
++		man/Doxyfile-nozzle
+ 		poc-code/Makefile
+ 		poc-code/iov-hash/Makefile
+ 		poc-code/access-list/Makefile
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 57e97065..4982d94b 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -16,7 +16,7 @@ EXTRA_DIST		= $(SYMFILE)
+ 
+ if BUILD_LIBNOZZLE
+ 
+-SUBDIRS			= . tests man
++SUBDIRS			= . tests
+ 
+ libversion		= 1:0:0
+ 
+@@ -46,6 +46,4 @@ libnozzle_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 
+ libnozzle_la_LIBADD	= $(PTHREAD_LIBS)
+ 
+-dist_man_MANS		= man
+-
+ endif
+diff --git a/libnozzle/man/Makefile.am b/libnozzle/man/Makefile.am
+deleted file mode 100644
+index b41863ab..00000000
+--- a/libnozzle/man/Makefile.am
++++ /dev/null
+@@ -1,26 +0,0 @@
+-#
+-# Copyright (C) 2017 Red Hat, Inc.  All rights reserved.
+-#
+-# Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-MAINTAINERCLEANFILES	= Makefile.in
+-
+-include $(top_srcdir)/build-aux/check.mk
+-
+-dist_man_MANS =
+-
+-$(MANS): doxyfile.stamp
+-
+-$(top_builddir)/build-aux/doxyxml: $(top_srcdir)/build-aux/doxyxml.c
+-	$(MAKE) -C $(top_builddir)/build-aux doxyxml
+-
+-doxyfile.stamp: Doxyfile $(top_srcdir)/libnozzle/libnozzle.h $(top_builddir)/build-aux/doxyxml $(top_srcdir)/build-aux/doxyxml.c
+-	$(DOXYGEN) Doxyfile
+-	$(top_builddir)/build-aux/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" -d $(builddir)/xml/ libnozzle_8h.xml
+-	touch doxyfile.stamp
+-
+-clean-local:
+-	rm -rf doxyfile.stamp xml *.3
+diff --git a/libnozzle/man/Doxyfile.in b/man/Doxyfile-nozzle.in
+similarity index 79%
+rename from libnozzle/man/Doxyfile.in
+rename to man/Doxyfile-nozzle.in
+index 78b1f9b2..3695ee48 100644
+--- a/libnozzle/man/Doxyfile.in
++++ b/man/Doxyfile-nozzle.in
+@@ -8,8 +8,8 @@
+ #
+ PROJECT_NAME	       = @PACKAGE_NAME@
+ PROJECT_NUMBER         = @PACKAGE_VERSION@
+-INPUT                  = @srcdir@/../libnozzle.h
+-XML_OUTPUT             = @abs_builddir@/xml
++INPUT                  = @abs_top_srcdir@/libnozzle/libnozzle.h
++XML_OUTPUT             = @abs_builddir@/xml-nozzle
+ GENERATE_XML           = YES
+ XML_PROGRAMLISTING     = NO
+ AUTOLINK_SUPPORT       = NO
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 9f2741b1..29cd45e7 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -95,9 +95,13 @@ knet_man3_MANS = \
+ 		knet_send_sync.3 \
+ 		knet_strtoaddr.3
+ 
+-man3_MANS = $(knet_man3_MANS)
++if BUILD_LIBNOZZLE
++nozzle_man3_MANS =
++endif
++
++man3_MANS = $(knet_man3_MANS) $(nozzle_man3_MANS)
+ 
+-$(MANS): doxyfile-knet.stamp
++$(MANS): doxyfile-knet.stamp doxyfile-nozzle.stamp
+ 
+ doxyfile-knet.stamp: $(builddir)/doxyxml Doxyfile-knet $(top_srcdir)/libknet/libknet.h
+ 	$(DOXYGEN) Doxyfile-knet
+@@ -105,6 +109,13 @@ doxyfile-knet.stamp: $(builddir)/doxyxml Doxyfile-knet $(top_srcdir)/libknet/lib
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
+ 	touch doxyfile-knet.stamp
+ 
++doxyfile-nozzle.stamp: $(builddir)/doxyxml Doxyfile-nozzle $(top_srcdir)/libnozzle/libnozzle.h
++if BUILD_LIBNOZZLE
++	$(DOXYGEN) Doxyfile-nozzle
++	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
++endif
++	touch doxyfile-nozzle.stamp
++
+ endif
+ 
+ clean-local:
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0122-nozzle-enable-libnozzle-build-by-default.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0122-nozzle-enable-libnozzle-build-by-default.patch
new file mode 100644
index 000000000..46fb00547
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0122-nozzle-enable-libnozzle-build-by-default.patch
@@ -0,0 +1,23 @@ 
+From 73e5d0f4c3235df693aab92113a37ea6d41f794c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 22 Feb 2018 06:06:29 +0100
+Subject: [PATCH] [nozzle] enable libnozzle build by default
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 86faa743..3cb78af9 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -168,7 +168,7 @@ AM_CONDITIONAL([OVERRIDE_RPM_DEBUGINFO], [test x$override_rpm_debuginfo_option =
+ 
+ AC_ARG_ENABLE([libnozzle],
+ 	[AS_HELP_STRING([--enable-libnozzle],[libnozzle support])],,
+-	[ enable_libnozzle="no" ])
++	[ enable_libnozzle="yes" ])
+ 
+ if test "x$enable_kronosnetd" = xyes; then
+ 	enable_libnozzle=yes
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0123-nozzle-drop-duplicated-code.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0123-nozzle-drop-duplicated-code.patch
new file mode 100644
index 000000000..25cccf196
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0123-nozzle-drop-duplicated-code.patch
@@ -0,0 +1,616 @@ 
+From bb1a8b29c29776692b96415191437b24a8dbc685 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 22 Feb 2018 06:11:11 +0100
+Subject: [PATCH] [nozzle] drop duplicated code
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.c | 598 ------------------------------------------
+ 1 file changed, 598 deletions(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index f21784ff..437fe4a2 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -183,601 +183,3 @@ int find_ip(nozzle_t nozzle,
+ 
+ 	return found;
+ }
+-
+-#if 0
+-static void _close(nozzle_t nozzle)
+-{
+-#ifdef KNET_BSD
+-	struct ifreq ifr;
+-#endif
+-
+-	if (!nozzle)
+-		return;
+-
+-	if (nozzle->fd)
+-		close(nozzle->fd);
+-
+-#ifdef KNET_BSD
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
+-#endif
+-
+-	free(nozzle);
+-
+-	return;
+-}
+-
+-static void _close_cfg(void)
+-{
+-	if (lib_cfg.head == NULL) {
+-		close(lib_cfg.ioctlfd);
+-		lib_init = 0;
+-	}
+-}
+-
+-nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+-{
+-	int savederrno = 0;
+-	nozzle_t nozzle = NULL;
+-	char *temp_mac = NULL;
+-#ifdef KNET_LINUX
+-	struct ifreq ifr;
+-#endif
+-#ifdef KNET_BSD
+-	uint16_t i;
+-	long int nozzlenum = 0;
+-	char curnozzle[IFNAMSIZ];
+-#endif
+-
+-	if (devname == NULL) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	if (devname_size < IFNAMSIZ) {
+-		errno = EINVAL;
+-		return NULL;
+-	}
+-
+-	if (strlen(devname) > IFNAMSIZ) {
+-		errno = E2BIG;
+-		return NULL;
+-	}
+-
+-#ifdef KNET_BSD
+-	/*
+-	 * BSD does not support named devices like Linux
+-	 * but it is possible to force a nozzleX device number
+-	 * where X is 0 to 255.
+-	 */
+-	if (strlen(devname)) {
+-		if (strncmp(devname, "tap", 3)) {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-		errno = 0;
+-		nozzlenum = strtol(devname+3, NULL, 10);
+-		if (errno) {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-		if ((nozzlenum < 0) || (nozzlenum > 255)) {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-	}
+-#endif
+-
+-	if (updownpath) {
+-		/* only absolute paths */
+-		if (updownpath[0] != '/') {
+-			errno = EINVAL;
+-			return NULL;
+-		}
+-		if (strlen(updownpath) >= UPDOWN_PATH_MAX) {
+-			errno = E2BIG;
+-			return NULL;
+-		}
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return NULL;
+-	}
+-
+-	if (!lib_init) {
+-		lib_cfg.head = NULL;
+-#ifdef KNET_LINUX
+-		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
+-#endif
+-#ifdef KNET_BSD
+-		lib_cfg.ioctlfd = socket(AF_LOCAL, SOCK_DGRAM, 0);
+-#endif
+-		if (lib_cfg.ioctlfd < 0) {
+-			savederrno = errno;
+-			goto out_error;
+-		}
+-		lib_init = 1;
+-	}
+-
+-	nozzle = malloc(sizeof(struct nozzle_iface));
+-	if (!nozzle) {
+-		savederrno = ENOMEM;
+-		goto out_error;
+-	}
+-
+-	memset(nozzle, 0, sizeof(struct nozzle_iface));
+-
+-#ifdef KNET_BSD
+-	if (!strlen(devname)) {
+-		for (i = 0; i < 256; i++) {
+-			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
+-			nozzle->fd = open(curnozzle, O_RDWR);
+-			savederrno = errno;
+-			if (nozzle->fd > 0) {
+-				break;
+-			}
+-		}
+-		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
+-	} else {
+-		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
+-		nozzle->fd = open(curnozzle, O_RDWR);
+-		savederrno = errno;
+-		snprintf(curnozzle, sizeof(curnozzle) - 1, "%s", devname);
+-	}
+-	if (nozzle->fd < 0) {
+-		errno = EBUSY;
+-		goto out_error;
+-	}
+-	strncpy(devname, curnozzle, IFNAMSIZ);
+-	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
+-#endif
+-
+-#ifdef KNET_LINUX
+-	if ((nozzle->fd = open("/dev/net/tun", O_RDWR)) < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, devname, IFNAMSIZ);
+-	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+-
+-	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	if ((strlen(devname) > 0) && (strcmp(devname, ifname) != 0)) {
+-		errno = EBUSY;
+-		goto out_error;
+-	}
+-
+-	strncpy(devname, ifname, IFNAMSIZ);
+-	strncpy(nozzle->name, ifname, IFNAMSIZ);
+-#endif
+-
+-	nozzle->default_mtu = _get_mtu(nozzle);
+-	if (nozzle->default_mtu < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	if (_get_mac(nozzle, &temp_mac) < 0) {
+-		savederrno = errno;
+-		goto out_error;
+-	}
+-
+-	strncpy(nozzle->default_mac, temp_mac, 18);
+-	free(temp_mac);
+-
+-	if (updownpath) {
+-		int len = strlen(updownpath);
+-
+-		strcpy(nozzle->updownpath, updownpath);
+-		if (nozzle->updownpath[len-1] != '/') {
+-			nozzle->updownpath[len] = '/';
+-		}
+-		nozzle->hasupdown = 1;
+-	}
+-
+-	nozzle->next = lib_cfg.head;
+-	lib_cfg.head = nozzle;
+-
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return nozzle;
+-
+-out_error:
+-	_close(nozzle);
+-	_close_cfg();
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return NULL;
+-}
+-
+-int nozzle_close(nozzle_t nozzle,  char **error_down, char **error_postdown)
+-{
+-	int err = 0, savederrno = 0;
+-	nozzle_t temp = lib_cfg.head;
+-	nozzle_t prev = lib_cfg.head;
+-	struct nozzle_ip *ip, *ip_next;
+-	char *error_string = NULL;
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	while ((temp) && (temp != nozzle)) {
+-		prev = temp;
+-		temp = temp->next;
+-	}
+-
+-	if (nozzle == prev) {
+-		lib_cfg.head = nozzle->next;
+-	} else {
+-		prev->next = nozzle->next;
+-	}
+-
+-	_set_down(nozzle, error_down, error_postdown);
+-
+-	ip = nozzle->ip;
+-	while (ip) {
+-		ip_next = ip->next;
+-		_set_ip(nozzle, "del", ip->ipaddr, ip->prefix, &error_string, 0);
+-		if (error_string) {
+-			free(error_string);
+-			error_string = NULL;
+-		}
+-		free(ip);
+-		ip = ip_next;
+-	}
+-
+-	_close(nozzle);
+-	_close_cfg();
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+-{
+-	int err = 0, savederrno = 0;
+-	struct nozzle_ip *tmp_ip;
+-	struct ifreq ifr;
+-
+-	if ((!nozzle) || (!mtu) || (!error_string)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = nozzle->current_mtu = _get_mtu(nozzle);
+-	if (err < 0) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-	ifr.ifr_mtu = mtu;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
+-		tmp_ip = nozzle->ip;
+-		while(tmp_ip) {
+-			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(nozzle, "add", tmp_ip->ipaddr, tmp_ip->prefix, error_string, 0);
+-				if (err) {
+-					savederrno = errno;
+-					err = -1;
+-					goto out_clean;
+-				}
+-			}
+-			tmp_ip = tmp_ip->next;
+-		}
+-	}
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+-{
+-	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+-}
+-
+-static int _set_ip(nozzle_t nozzle, const char *command,
+-		      const char *ipaddr, const char *prefix,
+-		      char **error_string, int secondary)
+-{
+-	char *broadcast = NULL;
+-	char cmdline[4096];
+-#ifdef KNET_BSD
+-	char proto[6];
+-	int v4 = 1;
+-
+-	snprintf(proto, sizeof(proto), "inet");
+-#endif
+-
+-	if (!strchr(ipaddr, ':')) {
+-		broadcast = _get_v4_broadcast(ipaddr, prefix);
+-		if (!broadcast) {
+-			errno = EINVAL;
+-			return -1;
+-		}
+-	}
+-#ifdef KNET_BSD
+-	  else {
+-		v4 = 0;
+-		snprintf(proto, sizeof(proto), "inet6");
+-	}
+-#endif
+-
+-	memset(cmdline, 0, sizeof(cmdline));
+-
+-#ifdef KNET_LINUX
+-	if (broadcast) {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ip addr %s %s/%s dev %s broadcast %s",
+-			 command, ipaddr, prefix,
+-			 nozzle->name, broadcast);
+-	} else {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ip addr %s %s/%s dev %s",
+-			command, ipaddr, prefix,
+-			nozzle->name);
+-	}
+-#endif
+-#ifdef KNET_BSD
+-	if (!strcmp(command, "add")) {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ifconfig %s %s %s/%s",
+-			 nozzle->name, proto, ipaddr, prefix);
+-		if (broadcast) {
+-			snprintf(cmdline + strlen(cmdline),
+-				 sizeof(cmdline) - strlen(cmdline) -1,
+-				 " broadcast %s", broadcast);
+-		}
+-		if ((secondary) && (v4)) {
+-			snprintf(cmdline + strlen(cmdline),
+-				 sizeof(cmdline) - strlen(cmdline) -1,
+-				 " alias");
+-		}
+-	} else {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-				 "ifconfig %s %s %s/%s delete",
+-				 nozzle->name, proto, ipaddr, prefix);
+-	}
+-#endif
+-	if (broadcast) {
+-		free(broadcast);
+-	}
+-	return _execute_bin_sh(cmdline, error_string);
+-}
+-
+-int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+-{
+-	int err = 0, savederrno = 0;
+-	int found = 0;
+-	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+-	int secondary = 0;
+-
+-	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+-	if (found) {
+-		goto out_clean;
+-	}
+-
+-	ip = malloc(sizeof(struct nozzle_ip));
+-	if (!ip) {
+-		savederrno = errno;
+-		err = -1 ;
+-		goto out_clean;
+-	}
+-
+-	memset(ip, 0, sizeof(struct nozzle_ip));
+-	strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
+-	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
+-	if (!strchr(ip->ipaddr, ':')) {
+-		ip->domain = AF_INET;
+-	} else {
+-		ip->domain = AF_INET6;
+-	}
+-
+-	/*
+-	 * if user asks for an IPv6 address, but MTU < 1280
+-	 * store the IP and bring it up later if and when MTU > 1280
+-	 */
+-	if ((ip->domain == AF_INET6) && (_get_mtu(nozzle) < 1280)) {
+-		err = 0;
+-	} else {
+-		if (nozzle->ip) {
+-			secondary = 1;
+-		}
+-		err = _set_ip(nozzle, "add", ipaddr, prefix, error_string, secondary);
+-		savederrno = errno;
+-	}
+-
+-	if (err) {
+-		free(ip);
+-		goto out_clean;
+-	}
+-
+-	if (nozzle->ip) {
+-		ip_last = nozzle->ip;
+-		while (ip_last->next != NULL) {
+-			ip_last = ip_last->next;
+-		}
+-		ip_last->next = ip;
+-	} else {
+-		nozzle->ip = ip;
+-	}
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+-{
+-	int err = 0, savederrno = 0;
+-        int found = 0;
+-	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
+-
+-	if ((!nozzle) || (!ipaddr) || (!prefix) || (!error_string)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	found = _find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+-	if (!found) {
+-		goto out_clean;
+-	}
+-
+-	err = _set_ip(nozzle, "del", ipaddr, prefix, error_string, 0);
+-	savederrno = errno;
+-	if (!err) {
+-		if (ip == ip_prev) {
+-			nozzle->ip = ip->next;
+-		} else {
+-			ip_prev->next = ip->next;
+-		}
+-		free(ip);
+-	}
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+-{
+-	int err = 0, savederrno = 0;
+-	int found = 0;
+-	char *ip_list = NULL;
+-	int size = 0, offset = 0, len;
+-	struct nozzle_ip *ip = NULL;
+-
+-	if ((!nozzle) || (!ipaddr_list) || (!entries)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!_check(nozzle)) {
+-		errno = EINVAL;
+-		goto out_clean;
+-	}
+-
+-	ip = nozzle->ip;
+-
+-	while (ip) {
+-		found++;
+-		ip = ip->next;
+-	}
+-
+-	if (!found) {
+-		*ipaddr_list = NULL;
+-		*entries = 0;
+-		goto out_clean;
+-	}
+-
+-	size = found * (IPADDR_CHAR_MAX + PREFIX_CHAR_MAX + 2);
+-
+-	ip_list = malloc(size);
+-	if (!ip_list) {
+-		savederrno = errno;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(ip_list, 0, size);
+-
+-	ip = nozzle->ip;
+-
+-	while (ip) {
+-		len = strlen(ip->ipaddr);
+-		memmove(ip_list + offset, ip->ipaddr, len);
+-		offset = offset + len + 1;
+-		len = strlen(ip->prefix);
+-		memmove(ip_list + offset, ip->prefix, len);
+-		offset = offset + len + 1;
+-		ip = ip->next;
+-	}
+-
+-	*ipaddr_list = ip_list;
+-	*entries = found;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-#endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0124-nozzle-expand-buffers-to-deal-with-strncpy-and-Werro.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0124-nozzle-expand-buffers-to-deal-with-strncpy-and-Werro.patch
new file mode 100644
index 000000000..16eff75f1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0124-nozzle-expand-buffers-to-deal-with-strncpy-and-Werro.patch
@@ -0,0 +1,49 @@ 
+From 5b3401408f301b78a01f62c1315ed4cecad47fe1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 2 Mar 2018 05:44:30 +0100
+Subject: [PATCH] [nozzle] expand buffers to deal with strncpy and
+ -Werror=stringop-truncatio
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h | 6 +++---
+ libnozzle/libnozzle.c | 2 +-
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index f6c25a92..c41cd3de 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -21,8 +21,8 @@ struct nozzle_lib_config {
+ #define PREFIX_CHAR_MAX	    4
+ 
+ struct nozzle_ip {
+-	char ipaddr[IPADDR_CHAR_MAX];
+-	char prefix[PREFIX_CHAR_MAX];
++	char ipaddr[IPADDR_CHAR_MAX + 1];
++	char prefix[PREFIX_CHAR_MAX + 1];
+ 	int  domain;			/* AF_INET or AF_INET6 */
+ 	struct nozzle_ip *next;
+ };
+@@ -47,7 +47,7 @@ struct nozzle_iface {
+ 	/*
+ 	 * default MAC address assigned by the kernel at creation time
+ 	 */
+-	char default_mac[MACADDR_CHAR_MAX];
++	char default_mac[MACADDR_CHAR_MAX + 1];
+ 
+ 	int default_mtu;		/* MTU assigned by the kernel at creation time */
+ 	int current_mtu;		/* MTU configured by libnozzle user */
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 404dc764..4548f60b 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -769,7 +769,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	}
+ 
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, devname, IFNAMSIZ);
++	memmove(ifname, devname, IFNAMSIZ);
+ 	ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
+ 
+ 	if (ioctl(nozzle->fd, TUNSETIFF, &ifr) < 0) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0125-libnozzle-whitespace-cleanup.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0125-libnozzle-whitespace-cleanup.patch
new file mode 100644
index 000000000..985d12b31
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0125-libnozzle-whitespace-cleanup.patch
@@ -0,0 +1,55 @@ 
+From 02864b9bfe8de65d04a72e901eb279b2cb8918c6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 6 Aug 2018 10:37:27 +0200
+Subject: [PATCH] [libnozzle] whitespace cleanup
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.h         | 2 +-
+ libnozzle/tests/nozzle_test.c | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index e4fc51a1..e97b09c7 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -310,7 +310,7 @@ const char *nozzle_get_name_by_handle(const nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_fd
+- * @brief 
++ * @brief
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index c8d17518..0f5ba31a 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -337,7 +337,7 @@ static int check_knet_mtu(void)
+ 
+ 	printf("Passing empty struct to set_mtu\n");
+ 	if (nozzle_set_mtu(NULL, 1500, &error_string) == 0) {
+-		printf("Something is wrong in nozzle_set_mtu sanity checks\n"); 
++		printf("Something is wrong in nozzle_set_mtu sanity checks\n");
+ 		if (error_string) {
+ 			printf("error: %s\n", error_string);
+ 			free(error_string);
+@@ -687,7 +687,7 @@ static int check_nozzle_execute_bin_sh_command(void)
+ 		printf("Can we really execute grep -h successfully?!?\n");
+ 		err = -1;
+ 		goto out_clean;
+-	} 
++	}
+ 
+ 	printf("command that outputs to stderr\n");
+ 	err = execute_bin_sh_command("grep -h", &error_string);
+@@ -700,7 +700,7 @@ static int check_nozzle_execute_bin_sh_command(void)
+ 		printf("Can we really execute grep -h successfully?!?\n");
+ 		err = -1;
+ 		goto out_clean;
+-	} 
++	}
+ 
+ 	printf("empty command\n");
+ 	err = execute_bin_sh_command(NULL, &error_string);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0126-libnozzle-Use-libnl3.0-for-ip-address-management-on-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0126-libnozzle-Use-libnl3.0-for-ip-address-management-on-.patch
new file mode 100644
index 000000000..22c517d58
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0126-libnozzle-Use-libnl3.0-for-ip-address-management-on-.patch
@@ -0,0 +1,354 @@ 
+From b9eeab89404c25c6689bbb2e886b2d5776aae3c8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 7 Aug 2018 11:02:45 +0200
+Subject: [PATCH] [libnozzle] Use libnl3.0 for ip address management on Linux
+
+BSD will follow next using internal ioctls and drop usage of forking a shell
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac                |  10 ++-
+ kronosnet.spec.in           |   3 +
+ libnozzle/Makefile.am       |   4 +-
+ libnozzle/internals.h       |   7 ++
+ libnozzle/libnozzle.c       | 148 +++++++++++++++++++++++++++++-------
+ libnozzle/tests/Makefile.am |   4 +-
+ 6 files changed, 145 insertions(+), 31 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 3cb78af9..d0a5c539 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -275,7 +275,15 @@ if test "x$enable_man" = "xyes"; then
+ 	ac_cv_path_PKG_CONFIG="$saved_ac_cv_path_PKG_CONFIG"
+ fi
+ 
+-# checks (for kronosnetd)
++# checks for libnozzle
++if test "x$enable_libnozzle" = xyes; then
++	if `echo $host_os | grep -q linux`; then
++		PKG_CHECK_MODULES([libnl], [libnl-3.0])
++		PKG_CHECK_MODULES([libnlroute], [libnl-route-3.0])
++	fi
++fi
++
++# checks for kronosnetd
+ if test "x$enable_kronosnetd" = xyes; then
+ 	AC_CHECK_HEADERS([security/pam_appl.h],
+ 			 [AC_CHECK_LIB([pam], [pam_start],
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index d07103b4..9e9903aa 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -122,6 +122,9 @@ BuildRequires: /usr/include/bzlib.h
+ %if %{defined buildkronosnetd}
+ BuildRequires: pam-devel
+ %endif
++%if %{defined buildlibnozzle}
++BuildRequires: libnl3-devel
++%endif
+ %if %{defined buildautogen}
+ BuildRequires: autoconf
+ BuildRequires: automake
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 4982d94b..3a49d23b 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -36,7 +36,7 @@ lib_LTLIBRARIES		= libnozzle.la
+ 
+ libnozzle_la_SOURCES	= $(sources)
+ 
+-libnozzle_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS)
++libnozzle_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS) $(libnl_CFLAGS) $(libnlroute_CFLAGS)
+ 
+ EXTRA_libnozzle_la_DEPENDENCIES	= $(SYMFILE)
+ 
+@@ -44,6 +44,6 @@ libnozzle_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 			  -Wl,-version-script,$(srcdir)/$(SYMFILE) \
+ 			  -version-info $(libversion)
+ 
+-libnozzle_la_LIBADD	= $(PTHREAD_LIBS)
++libnozzle_la_LIBADD	= $(PTHREAD_LIBS) $(libnl_LIBS) $(libnlroute_LIBS)
+ 
+ endif
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index c41cd3de..c05d56de 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -10,11 +10,18 @@
+ #define __NOZZLE_INTERNALS_H__
+ 
+ #include "config.h"
++
++#ifdef KNET_LINUX
++#include <netlink/netlink.h>
++#endif
+ #include <net/if.h>
+ 
+ struct nozzle_lib_config {
+ 	struct nozzle_iface *head;
+ 	int ioctlfd;
++#ifdef KNET_LINUX
++	struct nl_sock *nlsock;
++#endif
+ };
+ 
+ #define IPADDR_CHAR_MAX   128
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 4548f60b..f190e9af 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -29,6 +29,9 @@
+ #ifdef KNET_LINUX
+ #include <linux/if_tun.h>
+ #include <netinet/ether.h>
++#include <netlink/netlink.h>
++#include <netlink/route/addr.h>
++#include <netlink/route/link.h>
+ #endif
+ #ifdef KNET_BSD
+ #include <net/if_dl.h>
+@@ -49,50 +52,130 @@ static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+  * internal helpers
+  */
+ 
+-static int _set_ip(nozzle_t nozzle, const char *command,
++#define IP_ADD 1
++#define IP_DEL 2
++
++static int _set_ip(nozzle_t nozzle, int command,
+ 		      const char *ipaddr, const char *prefix,
+ 		      char **error_string, int secondary)
+ {
++	int fam;
+ 	char *broadcast = NULL;
+-	char cmdline[4096];
++#ifdef KNET_LINUX
++	struct rtnl_addr *addr = NULL;
++	struct nl_addr *local_addr = NULL;
++	struct nl_addr *bcast_addr = NULL;
++	struct nl_cache *cache = NULL;
++	int ifindex;
++	int err = 0;
++#endif
+ #ifdef KNET_BSD
++	char cmdline[4096];
+ 	char proto[6];
+-	int v4 = 1;
+-
+-	snprintf(proto, sizeof(proto), "inet");
+ #endif
+ 
+ 	if (!strchr(ipaddr, ':')) {
++		fam = AF_INET;
+ 		broadcast = generate_v4_broadcast(ipaddr, prefix);
+ 		if (!broadcast) {
+ 			errno = EINVAL;
+ 			return -1;
+ 		}
++	} else {
++		fam = AF_INET6;
+ 	}
+-#ifdef KNET_BSD
+-	  else {
+-		v4 = 0;
+-		snprintf(proto, sizeof(proto), "inet6");
++
++#ifdef KNET_LINUX
++	addr = rtnl_addr_alloc();
++	if (!addr) {
++		errno = ENOMEM;
++		return -1;
+ 	}
+-#endif
+ 
+-	memset(cmdline, 0, sizeof(cmdline));
++	if (rtnl_link_alloc_cache(lib_cfg.nlsock, AF_UNSPEC, &cache) < 0) {
++		errno = ENOMEM;
++		err = -1;
++		goto out;
++	}
++
++	ifindex = rtnl_link_name2i(cache, nozzle->name);
++	if (ifindex == 0) {
++		errno = ENOENT;
++		err = -1;
++		goto out;
++	}
++
++	rtnl_addr_set_ifindex(addr, ifindex);
++
++	if (nl_addr_parse(ipaddr, fam, &local_addr) < 0) {
++		errno = EINVAL;
++		err = -1;
++		goto out;
++	}
++
++	if (rtnl_addr_set_local(addr, local_addr) < 0) {
++		errno = EINVAL;
++		err = -1;
++		goto out;
++	}
+ 
+-#ifdef KNET_LINUX
+ 	if (broadcast) {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ip addr %s %s/%s dev %s broadcast %s",
+-			 command, ipaddr, prefix,
+-			 nozzle->name, broadcast);
++		if (nl_addr_parse(broadcast, fam, &bcast_addr) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
++		}
++
++		if (rtnl_addr_set_broadcast(addr, bcast_addr) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
++		}
++	}
++
++	rtnl_addr_set_prefixlen(addr, atoi(prefix));
++
++	if (command == IP_ADD) {
++		if (rtnl_addr_add(lib_cfg.nlsock, addr, 0) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
++		}
+ 	} else {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ip addr %s %s/%s dev %s",
+-			command, ipaddr, prefix,
+-			nozzle->name);
++		if (rtnl_addr_delete(lib_cfg.nlsock, addr, 0) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
++		}
++	}
++out:
++	if (addr) {
++		rtnl_addr_put(addr);
++	}
++	if (local_addr) {
++		nl_addr_put(local_addr);
++	}
++	if (bcast_addr) {
++		nl_addr_put(bcast_addr);
++	}
++	if (cache) {
++		nl_cache_put(cache);
++	}
++	if (broadcast) {
++		free(broadcast);
+ 	}
++	return err;
+ #endif
+ #ifdef KNET_BSD
+-	if (!strcmp(command, "add")) {
++	memset(cmdline, 0, sizeof(cmdline));
++
++	if (fam == AF_INET) {
++		snprintf(proto, sizeof(proto), "inet");
++	} else {
++		snprintf(proto, sizeof(proto), "inet6");
++	}
++
++	if (command == IP_ADD) {
+ 		snprintf(cmdline, sizeof(cmdline)-1,
+ 			 "ifconfig %s %s %s/%s",
+ 			 nozzle->name, proto, ipaddr, prefix);
+@@ -101,7 +184,7 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 				 sizeof(cmdline) - strlen(cmdline) -1,
+ 				 " broadcast %s", broadcast);
+ 		}
+-		if ((secondary) && (v4)) {
++		if ((secondary) && (fam == AF_INET)) {
+ 			snprintf(cmdline + strlen(cmdline),
+ 				 sizeof(cmdline) - strlen(cmdline) -1,
+ 				 " alias");
+@@ -111,11 +194,11 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ 				 "ifconfig %s %s %s/%s delete",
+ 				 nozzle->name, proto, ipaddr, prefix);
+ 	}
+-#endif
+ 	if (broadcast) {
+ 		free(broadcast);
+ 	}
+ 	return execute_bin_sh_command(cmdline, error_string);
++#endif
+ }
+ 
+ /*
+@@ -127,6 +210,10 @@ static int _set_ip(nozzle_t nozzle, const char *command,
+ static void lib_fini(void)
+ {
+ 	if (lib_cfg.head == NULL) {
++#ifdef KNET_LINUX
++		nl_close(lib_cfg.nlsock);
++		nl_socket_free(lib_cfg.nlsock);
++#endif
+ 		close(lib_cfg.ioctlfd);
+ 		lib_init = 0;
+ 	}
+@@ -354,7 +441,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
+ 		tmp_ip = nozzle->ip;
+ 		while(tmp_ip) {
+ 			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(nozzle, "add", tmp_ip->ipaddr, tmp_ip->prefix, error_string, 0);
++				err = _set_ip(nozzle, IP_ADD, tmp_ip->ipaddr, tmp_ip->prefix, error_string, 0);
+ 				if (err) {
+ 					savederrno = errno;
+ 					err = -1;
+@@ -431,7 +518,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		if (nozzle->ip) {
+ 			secondary = 1;
+ 		}
+-		err = _set_ip(nozzle, "add", ipaddr, prefix, error_string, secondary);
++		err = _set_ip(nozzle, IP_ADD, ipaddr, prefix, error_string, secondary);
+ 		savederrno = errno;
+ 	}
+ 
+@@ -484,7 +571,7 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+ 		goto out_clean;
+ 	}
+ 
+-	err = _set_ip(nozzle, "del", ipaddr, prefix, error_string, 0);
++	err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, error_string, 0);
+ 	savederrno = errno;
+ 	if (!err) {
+ 		if (ip == ip_prev) {
+@@ -717,6 +804,15 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	if (!lib_init) {
+ 		lib_cfg.head = NULL;
+ #ifdef KNET_LINUX
++		lib_cfg.nlsock = nl_socket_alloc();
++		if (!lib_cfg.nlsock) {
++			savederrno = errno;
++			goto out_error;
++		}
++		if (nl_connect(lib_cfg.nlsock, NETLINK_ROUTE) < 0) {
++			savederrno = EBUSY;
++			goto out_error;
++		}
+ 		lib_cfg.ioctlfd = socket(AF_INET, SOCK_STREAM, 0);
+ #endif
+ #ifdef KNET_BSD
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index e02593df..78419d1c 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -32,9 +32,9 @@ nozzle_test_SOURCES	= nozzle_test.c \
+ nozzle_test_CPPFLAGS	= -I$(top_srcdir)/libnozzle \
+ 			  -DABSBUILDDIR=\"$(abs_builddir)\"
+ 
+-nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS)
++nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
+ 
+ nozzle_test_LDFLAGS	= $(top_builddir)/libnozzle/libnozzle.la \
+-			  $(PTHREAD_LIBS)
++			  $(PTHREAD_LIBS) $(libnl_LIBS)
+ 
+ endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0127-libnozzle-enable-libnl3-3.3-build-workaround.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0127-libnozzle-enable-libnl3-3.3-build-workaround.patch
new file mode 100644
index 000000000..d7d7943aa
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0127-libnozzle-enable-libnl3-3.3-build-workaround.patch
@@ -0,0 +1,46 @@ 
+From 5a4c58221463a95e40ba721623e4a9b3ef8849e2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 8 Aug 2018 07:48:37 +0200
+Subject: [PATCH] [libnozzle] enable libnl3 < 3.3 build workaround
+
+fixes build on opensuse-42
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac          | 4 +++-
+ libnozzle/libnozzle.c | 7 +++++++
+ 2 files changed, 10 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index d0a5c539..2a6608f1 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -279,7 +279,9 @@ fi
+ if test "x$enable_libnozzle" = xyes; then
+ 	if `echo $host_os | grep -q linux`; then
+ 		PKG_CHECK_MODULES([libnl], [libnl-3.0])
+-		PKG_CHECK_MODULES([libnlroute], [libnl-route-3.0])
++		PKG_CHECK_MODULES([libnlroute], [libnl-route-3.0 >= 3.3], [],
++			[PKG_CHECK_MODULES([libnlroute], [libnl-route-3.0 < 3.3],
++					   [AC_DEFINE_UNQUOTED([LIBNL3_WORKAROUND], [1], [Enable libnl < 3.3 build workaround])], [])])
+ 	fi
+ fi
+ 
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index f190e9af..10415ac5 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -28,6 +28,13 @@
+ 
+ #ifdef KNET_LINUX
+ #include <linux/if_tun.h>
++/*
++ * libnl3 < 3.3 includes kernel headers directly
++ * causing conflicts with net/if.h included above
++ */
++#ifdef LIBNL3_WORKAROUND
++#define _LINUX_IF_H 1
++#endif
+ #include <netinet/ether.h>
+ #include <netlink/netlink.h>
+ #include <netlink/route/addr.h>
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0128-tests-remove-debugging-sleep.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0128-tests-remove-debugging-sleep.patch
new file mode 100644
index 000000000..ad33e741b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0128-tests-remove-debugging-sleep.patch
@@ -0,0 +1,30 @@ 
+From d10be860ebb9b4d7dd049816fac8871034844828 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 28 Aug 2018 05:31:18 +0200
+Subject: [PATCH] [tests] remove debugging sleep()
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/nozzle_test.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 0f5ba31a..2800f48b 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -384,7 +384,6 @@ static int check_knet_mtu_ipv6(void)
+ 	if (err) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+-		sleep(30);
+ 		goto out_clean;
+ 	}
+ 
+@@ -579,7 +578,6 @@ static int check_knet_mac(void)
+ 	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
+ 		printf("Mac addresses are not the same?!\n");
+ 		err = -1;
+-		sleep(20);
+ 		goto out_clean;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0129-tests-properly-check-symbols-on-PPC64.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0129-tests-properly-check-symbols-on-PPC64.patch
new file mode 100644
index 000000000..73bcf6399
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0129-tests-properly-check-symbols-on-PPC64.patch
@@ -0,0 +1,26 @@ 
+From 3015f8cbc5b335897c2096e8062ef33ba3bb06f4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 28 Aug 2018 05:32:07 +0200
+Subject: [PATCH] [tests] properly check symbols on PPC64
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api-test-coverage | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index c68f862b..06a61439 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -12,7 +12,10 @@ builddir="$2"/libnozzle
+ 
+ headerapicalls="$(grep nozzle_ "$srcdir"/libnozzle.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
+ 
+-exportedapicalls="$(nm -B -D "$builddir"/.libs/libnozzle.so | grep ' T ' | awk '{print $3}')"
++# The PowerPC64 ELFv1 ABI defines the address of a function as that of a
++# function descriptor defined in .opd, a data (D) section.  Other ABIs
++# use the entry address of the function itself in the text (T) section.
++exportedapicalls="$(nm -B -D "$builddir"/.libs/libnozzle.so | grep ' [DT] ' | awk '{print $3}')"
+ 
+ echo "Checking for exported symbols NOT available in header file"
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0130-libtap-move-nozzle_run_updown-to-completed-section.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0130-libtap-move-nozzle_run_updown-to-completed-section.patch
new file mode 100644
index 000000000..65a3c510a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0130-libtap-move-nozzle_run_updown-to-completed-section.patch
@@ -0,0 +1,182 @@ 
+From e9591b22cd90dd6ffdf4f8a5627331eb49e813f3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 03:37:41 +0100
+Subject: [PATCH] [libtap] move nozzle_run_updown to completed section
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 138 +++++++++++++++++++++---------------------
+ libnozzle/libnozzle.h |   4 +-
+ 2 files changed, 72 insertions(+), 70 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 10415ac5..40d8253b 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -664,75 +664,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
+-{
+-	int err = 0, savederrno = 0;
+-	char command[PATH_MAX];
+-	const char *action_str = NULL;
+-	struct stat sb;
+-
+-	if (action > NOZZLE_POSTDOWN) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!exec_string) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (!nozzle->hasupdown) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	switch(action) {
+-		case NOZZLE_PREUP:
+-			action_str = "pre-up.d";
+-			break;
+-		case NOZZLE_UP:
+-			action_str = "up.d";
+-			break;
+-		case NOZZLE_DOWN:
+-			action_str = "down.d";
+-			break;
+-		case NOZZLE_POSTDOWN:
+-			action_str = "post-down.d";
+-			break;
+-	}
+-
+-	memset(command, 0, PATH_MAX);
+-
+-	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action_str, nozzle->name);
+-
+-	err = stat(command, &sb);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	err = execute_bin_sh_command(command, exec_string);
+-	savederrno = errno;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno =  savederrno;
+-	return err;
+-}
+-
+ /*
+  * functions below should be completed
+  */
+@@ -972,6 +903,75 @@ out_clean:
+ 	return err;
+ }
+ 
++int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
++{
++	int err = 0, savederrno = 0;
++	char command[PATH_MAX];
++	const char *action_str = NULL;
++	struct stat sb;
++
++	if (action > NOZZLE_POSTDOWN) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!exec_string) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	if (!nozzle->hasupdown) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	switch(action) {
++		case NOZZLE_PREUP:
++			action_str = "pre-up.d";
++			break;
++		case NOZZLE_UP:
++			action_str = "up.d";
++			break;
++		case NOZZLE_DOWN:
++			action_str = "down.d";
++			break;
++		case NOZZLE_POSTDOWN:
++			action_str = "post-down.d";
++			break;
++	}
++
++	memset(command, 0, PATH_MAX);
++
++	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action_str, nozzle->name);
++
++	err = stat(command, &sb);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	err = execute_bin_sh_command(command, exec_string);
++	savederrno = errno;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno =  savederrno;
++	return err;
++}
++
+ int nozzle_set_up(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index e97b09c7..6c3cb27a 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -74,7 +74,9 @@ int nozzle_close(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_run_updown
+- * @brief execute updown commands associated with a nozzle device
++ * @brief execute updown commands associated with a nozzle device. It is
++ *        the application responsibility to call helper scripts
++ *        before or after creating/destroying interfaces or IP addresses.
+  *
+  * nozzle - pointer to the nozzle struct
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0131-libnozzle-remove-error_string-requirement-from-many-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0131-libnozzle-remove-error_string-requirement-from-many-.patch
new file mode 100644
index 000000000..6417b7266
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0131-libnozzle-remove-error_string-requirement-from-many-.patch
@@ -0,0 +1,1087 @@ 
+From 74d278e88b01629111c9b3b9f03067f318bd7d5f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 04:04:56 +0100
+Subject: [PATCH] [libnozzle] remove error_string requirement from many API
+ calls and mark them as final
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c         | 666 +++++++++++++++++-----------------
+ libnozzle/libnozzle.h         |  30 +-
+ libnozzle/tests/nozzle_test.c | 110 +-----
+ 3 files changed, 356 insertions(+), 450 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 40d8253b..ba9409e4 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -59,171 +59,40 @@ static pthread_mutex_t config_mutex = PTHREAD_MUTEX_INITIALIZER;
+  * internal helpers
+  */
+ 
+-#define IP_ADD 1
+-#define IP_DEL 2
+-
+-static int _set_ip(nozzle_t nozzle, int command,
+-		      const char *ipaddr, const char *prefix,
+-		      char **error_string, int secondary)
++static void lib_fini(void)
+ {
+-	int fam;
+-	char *broadcast = NULL;
++	if (lib_cfg.head == NULL) {
+ #ifdef KNET_LINUX
+-	struct rtnl_addr *addr = NULL;
+-	struct nl_addr *local_addr = NULL;
+-	struct nl_addr *bcast_addr = NULL;
+-	struct nl_cache *cache = NULL;
+-	int ifindex;
+-	int err = 0;
+-#endif
+-#ifdef KNET_BSD
+-	char cmdline[4096];
+-	char proto[6];
++		nl_close(lib_cfg.nlsock);
++		nl_socket_free(lib_cfg.nlsock);
+ #endif
+-
+-	if (!strchr(ipaddr, ':')) {
+-		fam = AF_INET;
+-		broadcast = generate_v4_broadcast(ipaddr, prefix);
+-		if (!broadcast) {
+-			errno = EINVAL;
+-			return -1;
+-		}
+-	} else {
+-		fam = AF_INET6;
+-	}
+-
+-#ifdef KNET_LINUX
+-	addr = rtnl_addr_alloc();
+-	if (!addr) {
+-		errno = ENOMEM;
+-		return -1;
+-	}
+-
+-	if (rtnl_link_alloc_cache(lib_cfg.nlsock, AF_UNSPEC, &cache) < 0) {
+-		errno = ENOMEM;
+-		err = -1;
+-		goto out;
+-	}
+-
+-	ifindex = rtnl_link_name2i(cache, nozzle->name);
+-	if (ifindex == 0) {
+-		errno = ENOENT;
+-		err = -1;
+-		goto out;
++		close(lib_cfg.ioctlfd);
++		lib_init = 0;
+ 	}
++}
+ 
+-	rtnl_addr_set_ifindex(addr, ifindex);
+-
+-	if (nl_addr_parse(ipaddr, fam, &local_addr) < 0) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out;
+-	}
++static int is_valid_nozzle(const nozzle_t nozzle)
++{
++	nozzle_t temp;
+ 
+-	if (rtnl_addr_set_local(addr, local_addr) < 0) {
+-		errno = EINVAL;
+-		err = -1;
+-		goto out;
++	if (!nozzle) {
++		return 0;
+ 	}
+ 
+-	if (broadcast) {
+-		if (nl_addr_parse(broadcast, fam, &bcast_addr) < 0) {
+-			errno = EINVAL;
+-			err = -1;
+-			goto out;
+-		}
+-
+-		if (rtnl_addr_set_broadcast(addr, bcast_addr) < 0) {
+-			errno = EINVAL;
+-			err = -1;
+-			goto out;
+-		}
++	if (!lib_init) {
++		return 0;
+ 	}
+ 
+-	rtnl_addr_set_prefixlen(addr, atoi(prefix));
+-
+-	if (command == IP_ADD) {
+-		if (rtnl_addr_add(lib_cfg.nlsock, addr, 0) < 0) {
+-			errno = EINVAL;
+-			err = -1;
+-			goto out;
+-		}
+-	} else {
+-		if (rtnl_addr_delete(lib_cfg.nlsock, addr, 0) < 0) {
+-			errno = EINVAL;
+-			err = -1;
+-			goto out;
+-		}
+-	}
+-out:
+-	if (addr) {
+-		rtnl_addr_put(addr);
+-	}
+-	if (local_addr) {
+-		nl_addr_put(local_addr);
+-	}
+-	if (bcast_addr) {
+-		nl_addr_put(bcast_addr);
+-	}
+-	if (cache) {
+-		nl_cache_put(cache);
+-	}
+-	if (broadcast) {
+-		free(broadcast);
+-	}
+-	return err;
+-#endif
+-#ifdef KNET_BSD
+-	memset(cmdline, 0, sizeof(cmdline));
++	temp = lib_cfg.head;
+ 
+-	if (fam == AF_INET) {
+-		snprintf(proto, sizeof(proto), "inet");
+-	} else {
+-		snprintf(proto, sizeof(proto), "inet6");
+-	}
++	while (temp != NULL) {
++		if (nozzle == temp)
++			return 1;
+ 
+-	if (command == IP_ADD) {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-			 "ifconfig %s %s %s/%s",
+-			 nozzle->name, proto, ipaddr, prefix);
+-		if (broadcast) {
+-			snprintf(cmdline + strlen(cmdline),
+-				 sizeof(cmdline) - strlen(cmdline) -1,
+-				 " broadcast %s", broadcast);
+-		}
+-		if ((secondary) && (fam == AF_INET)) {
+-			snprintf(cmdline + strlen(cmdline),
+-				 sizeof(cmdline) - strlen(cmdline) -1,
+-				 " alias");
+-		}
+-	} else {
+-		snprintf(cmdline, sizeof(cmdline)-1,
+-				 "ifconfig %s %s %s/%s delete",
+-				 nozzle->name, proto, ipaddr, prefix);
+-	}
+-	if (broadcast) {
+-		free(broadcast);
++		temp = temp->next;
+ 	}
+-	return execute_bin_sh_command(cmdline, error_string);
+-#endif
+-}
+ 
+-/*
+- * internal helpers below should be completed
+- *
+- * keep all ioctl work within this file
+- */
+-
+-static void lib_fini(void)
+-{
+-	if (lib_cfg.head == NULL) {
+-#ifdef KNET_LINUX
+-		nl_close(lib_cfg.nlsock);
+-		nl_socket_free(lib_cfg.nlsock);
+-#endif
+-		close(lib_cfg.ioctlfd);
+-		lib_init = 0;
+-	}
++	return 0;
+ }
+ 
+ static void destroy_iface(nozzle_t nozzle)
+@@ -252,30 +121,6 @@ static void destroy_iface(nozzle_t nozzle)
+ 	return;
+ }
+ 
+-static int is_valid_nozzle(const nozzle_t nozzle)
+-{
+-	nozzle_t temp;
+-
+-	if (!nozzle) {
+-		return 0;
+-	}
+-
+-	if (!lib_init) {
+-		return 0;
+-	}
+-
+-	temp = lib_cfg.head;
+-
+-	while (temp != NULL) {
+-		if (nozzle == temp)
+-			return 1;
+-
+-		temp = temp->next;
+-	}
+-
+-	return 0;
+-}
+-
+ static int get_iface_mtu(const nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -401,200 +246,171 @@ out_clean:
+ 	return err;
+ }
+ 
+-/*
+- * public API
+- */
++#define IP_ADD 1
++#define IP_DEL 2
+ 
+-int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string)
++static int _set_ip(nozzle_t nozzle,
++		   int command,
++		   const char *ipaddr, const char *prefix,
++		   int secondary)
+ {
+-	int err = 0, savederrno = 0;
+-	struct nozzle_ip *tmp_ip;
+-	struct ifreq ifr;
++	int fam;
++	char *broadcast = NULL;
++	int err = 0;
++#ifdef KNET_LINUX
++	struct rtnl_addr *addr = NULL;
++	struct nl_addr *local_addr = NULL;
++	struct nl_addr *bcast_addr = NULL;
++	struct nl_cache *cache = NULL;
++	int ifindex;
++#endif
++#ifdef KNET_BSD
++	char cmdline[4096];
++	char proto[6];
++	char *error_string = NULL;
++#endif
+ 
+-	if ((!mtu) || (!error_string)) {
+-		errno = EINVAL;
+-		return -1;
++	if (!strchr(ipaddr, ':')) {
++		fam = AF_INET;
++		broadcast = generate_v4_broadcast(ipaddr, prefix);
++		if (!broadcast) {
++			errno = EINVAL;
++			return -1;
++		}
++	} else {
++		fam = AF_INET6;
+ 	}
+ 
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
++#ifdef KNET_LINUX
++	addr = rtnl_addr_alloc();
++	if (!addr) {
++		errno = ENOMEM;
+ 		return -1;
+ 	}
+ 
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
++	if (rtnl_link_alloc_cache(lib_cfg.nlsock, AF_UNSPEC, &cache) < 0) {
++		errno = ENOMEM;
+ 		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = nozzle->current_mtu = get_iface_mtu(nozzle);
+-	if (err < 0) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-	ifr.ifr_mtu = mtu;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
++		goto out;
+ 	}
+ 
+-	if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
+-		tmp_ip = nozzle->ip;
+-		while(tmp_ip) {
+-			if (tmp_ip->domain == AF_INET6) {
+-				err = _set_ip(nozzle, IP_ADD, tmp_ip->ipaddr, tmp_ip->prefix, error_string, 0);
+-				if (err) {
+-					savederrno = errno;
+-					err = -1;
+-					goto out_clean;
+-				}
+-			}
+-			tmp_ip = tmp_ip->next;
+-		}
++	ifindex = rtnl_link_name2i(cache, nozzle->name);
++	if (ifindex == 0) {
++		errno = ENOENT;
++		err = -1;
++		goto out;
+ 	}
+ 
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_reset_mtu(nozzle_t nozzle, char **error_string)
+-{
+-	return nozzle_set_mtu(nozzle, nozzle->default_mtu, error_string);
+-}
+-
+-int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+-{
+-	int err = 0, savederrno = 0;
+-	int found = 0;
+-	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
+-	int secondary = 0;
++	rtnl_addr_set_ifindex(addr, ifindex);
+ 
+-	if ((!ipaddr) || (!prefix) || (!error_string)) {
++	if (nl_addr_parse(ipaddr, fam, &local_addr) < 0) {
+ 		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+ 		err = -1;
+-		goto out_clean;
+-	}
+-
+-	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+-	if (found) {
+-		goto out_clean;
++		goto out;
+ 	}
+ 
+-	ip = malloc(sizeof(struct nozzle_ip));
+-	if (!ip) {
+-		savederrno = errno;
+-		err = -1 ;
+-		goto out_clean;
++	if (rtnl_addr_set_local(addr, local_addr) < 0) {
++		errno = EINVAL;
++		err = -1;
++		goto out;
+ 	}
+ 
+-	memset(ip, 0, sizeof(struct nozzle_ip));
+-	strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
+-	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
+-	if (!strchr(ip->ipaddr, ':')) {
+-		ip->domain = AF_INET;
+-	} else {
+-		ip->domain = AF_INET6;
+-	}
++	if (broadcast) {
++		if (nl_addr_parse(broadcast, fam, &bcast_addr) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
++		}
+ 
+-	/*
+-	 * if user asks for an IPv6 address, but MTU < 1280
+-	 * store the IP and bring it up later if and when MTU > 1280
+-	 */
+-	if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
+-		err = 0;
+-	} else {
+-		if (nozzle->ip) {
+-			secondary = 1;
++		if (rtnl_addr_set_broadcast(addr, bcast_addr) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
+ 		}
+-		err = _set_ip(nozzle, IP_ADD, ipaddr, prefix, error_string, secondary);
+-		savederrno = errno;
+ 	}
+ 
+-	if (err) {
+-		free(ip);
+-		goto out_clean;
+-	}
++	rtnl_addr_set_prefixlen(addr, atoi(prefix));
+ 
+-	if (nozzle->ip) {
+-		ip_last = nozzle->ip;
+-		while (ip_last->next != NULL) {
+-			ip_last = ip_last->next;
++	if (command == IP_ADD) {
++		if (rtnl_addr_add(lib_cfg.nlsock, addr, 0) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
+ 		}
+-		ip_last->next = ip;
+ 	} else {
+-		nozzle->ip = ip;
+-	}
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string)
+-{
+-	int err = 0, savederrno = 0;
+-        int found = 0;
+-	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
+-
+-	if ((!ipaddr) || (!prefix) || (!error_string)) {
+-		errno = EINVAL;
+-		return -1;
++		if (rtnl_addr_delete(lib_cfg.nlsock, addr, 0) < 0) {
++			errno = EINVAL;
++			err = -1;
++			goto out;
++		}
+ 	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
++out:
++	if (addr) {
++		rtnl_addr_put(addr);
+ 	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_clean;
++	if (local_addr) {
++		nl_addr_put(local_addr);
++	}
++	if (bcast_addr) {
++		nl_addr_put(bcast_addr);
++	}
++	if (cache) {
++		nl_cache_put(cache);
++	}
++	if (broadcast) {
++		free(broadcast);
+ 	}
++	return err;
++#endif
++#ifdef KNET_BSD
++	memset(cmdline, 0, sizeof(cmdline));
+ 
+-	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
+-	if (!found) {
+-		goto out_clean;
++	if (fam == AF_INET) {
++		snprintf(proto, sizeof(proto), "inet");
++	} else {
++		snprintf(proto, sizeof(proto), "inet6");
+ 	}
+ 
+-	err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, error_string, 0);
+-	savederrno = errno;
+-	if (!err) {
+-		if (ip == ip_prev) {
+-			nozzle->ip = ip->next;
+-		} else {
+-			ip_prev->next = ip->next;
++	if (command == IP_ADD) {
++		snprintf(cmdline, sizeof(cmdline)-1,
++			 "ifconfig %s %s %s/%s",
++			 nozzle->name, proto, ipaddr, prefix);
++		if (broadcast) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " broadcast %s", broadcast);
+ 		}
+-		free(ip);
++		if ((secondary) && (fam == AF_INET)) {
++			snprintf(cmdline + strlen(cmdline),
++				 sizeof(cmdline) - strlen(cmdline) -1,
++				 " alias");
++		}
++	} else {
++		snprintf(cmdline, sizeof(cmdline)-1,
++				 "ifconfig %s %s %s/%s delete",
++				 nozzle->name, proto, ipaddr, prefix);
++	}
++	if (broadcast) {
++		free(broadcast);
+ 	}
+ 
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
++	/*
++	 * temporary workaround as we port libnozzle to BSD ioctl
++	 * for IP address management
++	 */
++	err = execute_bin_sh_command(cmdline, error_string);
++	if (error_string) {
++		free(error_string);
++		error_string = NULL;
++	}
+ 	return err;
++#endif
+ }
+ 
++/*
++ * public API
++ */
++
+ int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -1235,3 +1051,193 @@ out_clean:
+ 	errno = savederrno;
+ 	return fd;
+ }
++
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
++{
++	int err = 0, savederrno = 0;
++	struct nozzle_ip *tmp_ip;
++	struct ifreq ifr;
++
++	if (!mtu) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	err = nozzle->current_mtu = get_iface_mtu(nozzle);
++	if (err < 0) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	ifr.ifr_mtu = mtu;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	if ((nozzle->current_mtu < 1280) && (mtu >= 1280)) {
++		tmp_ip = nozzle->ip;
++		while(tmp_ip) {
++			if (tmp_ip->domain == AF_INET6) {
++				err = _set_ip(nozzle, IP_ADD, tmp_ip->ipaddr, tmp_ip->prefix, 0);
++				if (err) {
++					savederrno = errno;
++					err = -1;
++					goto out_clean;
++				}
++			}
++			tmp_ip = tmp_ip->next;
++		}
++	}
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_reset_mtu(nozzle_t nozzle)
++{
++	return nozzle_set_mtu(nozzle, nozzle->default_mtu);
++}
++
++int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
++{
++	int err = 0, savederrno = 0;
++	int found = 0;
++	struct nozzle_ip *ip = NULL, *ip_prev = NULL, *ip_last = NULL;
++	int secondary = 0;
++
++	if ((!ipaddr) || (!prefix)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
++	if (found) {
++		goto out_clean;
++	}
++
++	ip = malloc(sizeof(struct nozzle_ip));
++	if (!ip) {
++		savederrno = errno;
++		err = -1 ;
++		goto out_clean;
++	}
++
++	memset(ip, 0, sizeof(struct nozzle_ip));
++	strncpy(ip->ipaddr, ipaddr, IPADDR_CHAR_MAX);
++	strncpy(ip->prefix, prefix, PREFIX_CHAR_MAX);
++	if (!strchr(ip->ipaddr, ':')) {
++		ip->domain = AF_INET;
++	} else {
++		ip->domain = AF_INET6;
++	}
++
++	/*
++	 * if user asks for an IPv6 address, but MTU < 1280
++	 * store the IP and bring it up later if and when MTU > 1280
++	 */
++	if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
++		err = 0;
++	} else {
++		if (nozzle->ip) {
++			secondary = 1;
++		}
++		err = _set_ip(nozzle, IP_ADD, ipaddr, prefix, secondary);
++		savederrno = errno;
++	}
++
++	if (err) {
++		free(ip);
++		goto out_clean;
++	}
++
++	if (nozzle->ip) {
++		ip_last = nozzle->ip;
++		while (ip_last->next != NULL) {
++			ip_last = ip_last->next;
++		}
++		ip_last->next = ip;
++	} else {
++		nozzle->ip = ip;
++	}
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
++
++int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
++{
++	int err = 0, savederrno = 0;
++        int found = 0;
++	struct nozzle_ip *ip = NULL, *ip_prev = NULL;
++
++	if ((!ipaddr) || (!prefix)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_clean;
++	}
++
++	found = find_ip(nozzle, ipaddr, prefix, &ip, &ip_prev);
++	if (!found) {
++		goto out_clean;
++	}
++
++	err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, 0);
++	savederrno = errno;
++	if (!err) {
++		if (ip == ip_prev) {
++			nozzle->ip = ip->next;
++		} else {
++			ip_prev->next = ip->next;
++		}
++		free(ip);
++	}
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 6c3cb27a..a3a06efa 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -132,17 +132,12 @@ int nozzle_set_down(nozzle_t nozzle);
+  *
+  * prefix - 24, 64 or any valid network prefix for the requested address.
+  *
+- * error_string - pointers to string to record errors from ipaddr2 (Linux) or ifconfig (BSD).
+- *                The string is malloc'ed, the caller needs to free this buffer.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- *  error_string is set to NULL on success
+- *  error_string will contain a string recording the execution error.
+  */
+ 
+-int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string);
++int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
+ 
+ /**
+  * nozzle_del_ip
+@@ -154,17 +149,12 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char
+  *
+  * prefix - 24, 64 or any valid network prefix for the requested address.
+  *
+- * error_string - pointers to string to record errors from ipaddr2 (Linux) or ifconfig (BSD).
+- *                The string is malloc'ed, the caller needs to free this buffer.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- *  error_string is set to NULL on success
+- *  error_string will contain a string recording the execution error.
+  */
+ 
+-int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix, char **error_string);
++int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
+ 
+ /**
+  * nozzle_get_ips
+@@ -209,18 +199,12 @@ int nozzle_get_mtu(const nozzle_t nozzle);
+  *
+  * mtu - new MTU value
+  *
+- * error_string - pointer to string to record errors from ipaddr2 (Linux) or ifconfig (BSD)
+- *                when re-instanting IPv6 address if MTU is becoming again > 1280.
+- *                The string is malloc'ed, the caller needs to free this buffer.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * error_string is set to NULL on success
+- * error_string will contain a string recording the execution error.
+  */
+ 
+-int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string);
++int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
+ 
+ /**
+  * nozzle_reset_mtu
+@@ -228,18 +212,12 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu, char **error_string);
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+- * error_string - pointer to string to record errors from ipaddr2 (Linux) or ifconfig (BSD)
+- *                when re-instanting IPv6 address if MTU is becoming again > 1280.
+- *                The string is malloc'ed, the caller needs to free this buffer.
+- *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * error_string is set to NULL on success
+- * error_string will contain a string recording the execution error.
+  */
+ 
+-int nozzle_reset_mtu(nozzle_t nozzle, char **error_string);
++int nozzle_reset_mtu(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_mac
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 2800f48b..a9ca16ac 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -275,7 +275,6 @@ static int check_knet_mtu(void)
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+ 	nozzle_t nozzle;
+-	char *error_string = NULL;
+ 
+ 	int current_mtu = 0;
+ 	int expected_mtu = 1500;
+@@ -304,12 +303,8 @@ static int check_knet_mtu(void)
+ 
+ 	printf("Setting MTU to 9000\n");
+ 	expected_mtu = 9000;
+-	if (nozzle_set_mtu(nozzle, expected_mtu, &error_string) < 0) {
++	if (nozzle_set_mtu(nozzle, expected_mtu) < 0) {
+ 		printf("Unable to set MTU to %d\n", expected_mtu);
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -336,12 +331,8 @@ static int check_knet_mtu(void)
+ 	}
+ 
+ 	printf("Passing empty struct to set_mtu\n");
+-	if (nozzle_set_mtu(NULL, 1500, &error_string) == 0) {
++	if (nozzle_set_mtu(NULL, 1500) == 0) {
+ 		printf("Something is wrong in nozzle_set_mtu sanity checks\n");
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -375,12 +366,7 @@ static int check_knet_mtu_ipv6(void)
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
+-	if (error_string) {
+-		printf("add ipv6 output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
+ 	if (err) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -408,12 +394,8 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Setting MTU to 1200\n");
+-	if (nozzle_set_mtu(nozzle, 1200, &error_string) < 0) {
++	if (nozzle_set_mtu(nozzle, 1200) < 0) {
+ 		printf("Unable to set MTU to 1200\n");
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -436,12 +418,7 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_2);
+-	err = nozzle_add_ip(nozzle, testipv6_2, "64", &error_string);
+-	if (error_string) {
+-		printf("add ipv6 output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv6_2, "64");
+ 	if (err < 0) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -469,12 +446,8 @@ static int check_knet_mtu_ipv6(void)
+ 	}
+ 
+ 	printf("Restoring MTU to default\n");
+-	if (nozzle_reset_mtu(nozzle, &error_string) < 0) {
++	if (nozzle_reset_mtu(nozzle) < 0) {
+ 		printf("Unable to reset mtu\n");
+-		if (error_string) {
+-			printf("error: %s\n", error_string);
+-			free(error_string);
+-		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+@@ -968,7 +941,6 @@ static int check_knet_close_leak(void)
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+ 	nozzle_t nozzle;
+-	char *error_string = NULL;
+ 
+ 	printf("Testing close leak (needs valgrind)\n");
+ 
+@@ -982,12 +954,7 @@ static int check_knet_close_leak(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
+ 	if (err < 0) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -996,12 +963,7 @@ static int check_knet_close_leak(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv4_2, "24");
+ 	if (err < 0) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -1037,12 +999,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
+ 	if (err < 0) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -1051,12 +1008,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/24\n", testipv4_2);
+ 
+-	err = nozzle_add_ip(nozzle, testipv4_2, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv4_2, "24");
+ 	if (err < 0) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -1065,12 +1017,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding duplicate ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("add ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
+ 	if (err < 0) {
+ 		printf("Unable to find IP address in libnozzle db\n");
+ 		err=-1;
+@@ -1123,12 +1070,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("del ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_del_ip(nozzle, testipv4_1, "24");
+ 	if (err < 0) {
+ 		printf("Unable to delete IP address\n");
+ 		err=-1;
+@@ -1137,12 +1079,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/24\n", testipv4_2);
+ 
+-	err = nozzle_del_ip(nozzle, testipv4_2, "24", &error_string);
+-	if (error_string) {
+-		printf("del ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_del_ip(nozzle, testipv4_2, "24");
+ 	if (err < 0) {
+ 		printf("Unable to delete IP address\n");
+ 		err=-1;
+@@ -1151,12 +1088,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting again ip: %s/24\n", testipv4_1);
+ 
+-	err = nozzle_del_ip(nozzle, testipv4_1, "24", &error_string);
+-	if (error_string) {
+-		printf("del ip output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_del_ip(nozzle, testipv4_1, "24");
+ 	if (err < 0) {
+ 		printf("Unable to delete IP address\n");
+ 		err=-1;
+@@ -1185,12 +1117,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Adding ip: %s/64\n", testipv6_1);
+ 
+-	err = nozzle_add_ip(nozzle, testipv6_1, "64", &error_string);
+-	if (error_string) {
+-		printf("add ipv6 output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
+ 	if (err < 0) {
+ 		printf("Unable to assign IP address\n");
+ 		err=-1;
+@@ -1219,12 +1146,7 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Deleting ip: %s/64\n", testipv6_1);
+ 
+-	err = nozzle_del_ip(nozzle, testipv6_1, "64", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
++	err = nozzle_del_ip(nozzle, testipv6_1, "64");
+ 	if (err) {
+ 		printf("Unable to delete IP address\n");
+ 		err=-1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0132-libnozzle-fix-build-on-BSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0132-libnozzle-fix-build-on-BSD.patch
new file mode 100644
index 000000000..dd6509bbe
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0132-libnozzle-fix-build-on-BSD.patch
@@ -0,0 +1,23 @@ 
+From 1c552a07fbdc839e2ee5e4826c9eee4904abc8a5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 04:15:50 +0100
+Subject: [PATCH] [libnozzle] fix build on BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index ba9409e4..6559426d 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -398,7 +398,7 @@ out:
+ 	 * temporary workaround as we port libnozzle to BSD ioctl
+ 	 * for IP address management
+ 	 */
+-	err = execute_bin_sh_command(cmdline, error_string);
++	err = execute_bin_sh_command(cmdline, &error_string);
+ 	if (error_string) {
+ 		free(error_string);
+ 		error_string = NULL;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0133-libnozzle-Update-copyright.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0133-libnozzle-Update-copyright.patch
new file mode 100644
index 000000000..41dea8d47
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0133-libnozzle-Update-copyright.patch
@@ -0,0 +1,23 @@ 
+From d2b5ccb517f1fc2756e2730a670ee55e5bcecd1e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 04:22:18 +0100
+Subject: [PATCH] [libnozzle] Update copyright
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index a3a06efa..eb2b93d2 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -16,7 +16,7 @@
+  *
+  * @file libnozzle.h
+  * @brief tap interfaces management API include file
+- * @copyright Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+  *
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0134-global-Update-copyright-across.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0134-global-Update-copyright-across.patch
new file mode 100644
index 000000000..99677e867
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0134-global-Update-copyright-across.patch
@@ -0,0 +1,97 @@ 
+From 976c7d7df8ad7b07c3f166856a921ea106f3fa0f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 04:28:24 +0100
+Subject: [PATCH] [global] Update copyright across
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/git-version-gen     | 2 +-
+ build-aux/update-copyright.sh | 2 +-
+ libnozzle/internals.c         | 2 +-
+ libnozzle/internals.h         | 2 +-
+ libnozzle/tests/Makefile.am   | 2 +-
+ libnozzle/tests/nozzle_test.c | 2 +-
+ man/Doxyfile-nozzle.in        | 2 +-
+ 7 files changed, 7 insertions(+), 7 deletions(-)
+
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index 693513e7..fc70e306 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -2,7 +2,7 @@
+ # Print a version string.
+ scriptversion=2018-08-31.20; # UTC
+ 
+-# Copyright (C) 2018 Red Hat, Inc.
++# Copyright (C) 2012-2018 Red Hat, Inc.
+ # Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ #
+ # This program is free software: you can redistribute it and/or modify
+diff --git a/build-aux/update-copyright.sh b/build-aux/update-copyright.sh
+index babb25a3..fd50f8ea 100755
+--- a/build-aux/update-copyright.sh
++++ b/build-aux/update-copyright.sh
+@@ -11,7 +11,7 @@
+ 
+ enddate=$(date +%Y)
+ 
+-input=$(grep -ril -e "Copyright.*Red Hat" |grep -v .swp |grep -v update-copyright)
++input=$(grep -ril -e "Copyright.*Red Hat" |grep -v .swp |grep -v update-copyright |grep -v doxyxml.c)
+ for i in $input; do
+ 	startdate=$(git log --follow "$i" | grep ^Date: | tail -n 1 | awk '{print $6}')
+ 	if [ "$startdate" != "$enddate" ]; then
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 437fe4a2..c294eb4e 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index c05d56de..56ee49ad 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 78419d1c..5cbb788a 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index a9ca16ac..cae35eaf 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2017 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/man/Doxyfile-nozzle.in b/man/Doxyfile-nozzle.in
+index 3695ee48..0fb6f333 100644
+--- a/man/Doxyfile-nozzle.in
++++ b/man/Doxyfile-nozzle.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0135-libnozzle-fix-whitespaces.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0135-libnozzle-fix-whitespaces.patch
new file mode 100644
index 000000000..d02b1b14a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0135-libnozzle-fix-whitespaces.patch
@@ -0,0 +1,27 @@ 
+From 6707a4373800a0ea8c92000ac326ff526950d4e4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 04:30:42 +0100
+Subject: [PATCH] [libnozzle] fix whitespaces
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index eb2b93d2..8e580d7a 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -126,9 +126,9 @@ int nozzle_set_down(nozzle_t nozzle);
+  * nozzle - pointer to the nozzle struct
+  *
+  * ipaddr - string containing either an IPv4 or an IPv6 address.
+- *           Please note that Linux will automatically remove any IPv6 addresses from an interface
+- *           with MTU < 1280. libnozzle will cache those IPs and re-instate them when MTU is > 1280.
+- *           MTU must be set via nozzle_set_mtu for IPv6 to be re-instated.
++ *          Please note that Linux will automatically remove any IPv6 addresses from an interface
++ *          with MTU < 1280. libnozzle will cache those IPs and re-instate them when MTU is > 1280.
++ *          MTU must be set via nozzle_set_mtu for IPv6 to be re-instated.
+  *
+  * prefix - 24, 64 or any valid network prefix for the requested address.
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0136-libnozzle-cleanup-nozzle_get_ips-public-API.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0136-libnozzle-cleanup-nozzle_get_ips-public-API.patch
new file mode 100644
index 000000000..1e29755f9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0136-libnozzle-cleanup-nozzle_get_ips-public-API.patch
@@ -0,0 +1,261 @@ 
+From 7f2a0bba0e28dd66242541d455b3218380a220a3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 06:42:11 +0100
+Subject: [PATCH] [libnozzle] cleanup nozzle_get_ips public API
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h         | 11 +---
+ libnozzle/libnozzle.c         | 99 +++++++++--------------------------
+ libnozzle/libnozzle.h         | 26 ++++++---
+ libnozzle/tests/nozzle_test.c | 25 ++++-----
+ 4 files changed, 57 insertions(+), 104 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 56ee49ad..f7bd2e1e 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -15,6 +15,7 @@
+ #include <netlink/netlink.h>
+ #endif
+ #include <net/if.h>
++#include "libnozzle.h"
+ 
+ struct nozzle_lib_config {
+ 	struct nozzle_iface *head;
+@@ -24,16 +25,6 @@ struct nozzle_lib_config {
+ #endif
+ };
+ 
+-#define IPADDR_CHAR_MAX   128
+-#define PREFIX_CHAR_MAX	    4
+-
+-struct nozzle_ip {
+-	char ipaddr[IPADDR_CHAR_MAX + 1];
+-	char prefix[PREFIX_CHAR_MAX + 1];
+-	int  domain;			/* AF_INET or AF_INET6 */
+-	struct nozzle_ip *next;
+-};
+-
+ #define MACADDR_CHAR_MAX   18
+ 
+ /*
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 6559426d..21c143c9 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -408,80 +408,7 @@ out:
+ }
+ 
+ /*
+- * public API
+- */
+-
+-int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries)
+-{
+-	int err = 0, savederrno = 0;
+-	int found = 0;
+-	char *ip_list = NULL;
+-	int size = 0, offset = 0, len;
+-	struct nozzle_ip *ip = NULL;
+-
+-	if ((!ipaddr_list) || (!entries)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&config_mutex);
+-	if (savederrno) {
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!is_valid_nozzle(nozzle)) {
+-		savederrno = EINVAL;
+-		goto out_clean;
+-	}
+-
+-	ip = nozzle->ip;
+-
+-	while (ip) {
+-		found++;
+-		ip = ip->next;
+-	}
+-
+-	if (!found) {
+-		*ipaddr_list = NULL;
+-		*entries = 0;
+-		goto out_clean;
+-	}
+-
+-	size = found * (IPADDR_CHAR_MAX + PREFIX_CHAR_MAX + 2);
+-
+-	ip_list = malloc(size);
+-	if (!ip_list) {
+-		savederrno = errno;
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(ip_list, 0, size);
+-
+-	ip = nozzle->ip;
+-
+-	while (ip) {
+-		len = strlen(ip->ipaddr);
+-		memmove(ip_list + offset, ip->ipaddr, len);
+-		offset = offset + len + 1;
+-		len = strlen(ip->prefix);
+-		memmove(ip_list + offset, ip->prefix, len);
+-		offset = offset + len + 1;
+-		ip = ip->next;
+-	}
+-
+-	*ipaddr_list = ip_list;
+-	*entries = found;
+-
+-out_clean:
+-	pthread_mutex_unlock(&config_mutex);
+-	errno = savederrno;
+-	return err;
+-}
+-
+-/*
+- * functions below should be completed
++ * Exported public API
+  */
+ 
+ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+@@ -1241,3 +1168,27 @@ out_clean:
+ 	errno = savederrno;
+ 	return err;
+ }
++
++int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip)
++{
++	int err = 0, savederrno = 0;
++
++	savederrno = pthread_mutex_lock(&config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!is_valid_nozzle(nozzle)) {
++		err = -1;
++		savederrno = EINVAL;
++		goto out_clean;
++	}
++
++	*nozzle_ip = nozzle->ip;
++
++out_clean:
++	pthread_mutex_unlock(&config_mutex);
++	errno = savederrno;
++	return err;
++}
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 8e580d7a..df3d9fb5 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -156,27 +156,37 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
+ 
+ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
+ 
++
++#define IPADDR_CHAR_MAX	128
++#define PREFIX_CHAR_MAX	  4
++
++struct nozzle_ip {
++	char ipaddr[IPADDR_CHAR_MAX + 1];
++	char prefix[PREFIX_CHAR_MAX + 1];
++	int  domain;	/* AF_INET or AF_INET6 */
++	struct nozzle_ip *next;
++};
++
+ /**
+  * nozzle_get_ips
+  * @brief retrive the list of all configured ips for a given interface
+  *
+- * TODO: change to use a ipaddr_list struct!
+- *
+  * nozzle - pointer to the nozzle struct
+  *
+- * ipaddr_list - list of strings containing either an IPv4 or an IPv6 address and their prefixes.
+- *
+- * entries - entries recorded.
++ * nozzle_ip - pointer to the head of a list of nozzle_ip structs.
++ *             The last IP will have next = NULL.
++ *             nozzle_ip can be NULL if there are no IP addresses
++ *             associated with this nozzle device.
++ *             *DO NOT* free those structs as they are used internally
++ *             for IP address tracking.
+  *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set.
+- * ipaddr_list is a malloc'ed buffer that the user needs to parse and free after use. ipaddr_list can
+- * be NULL if entries is 0.
+  *
+  */
+ 
+-int nozzle_get_ips(const nozzle_t nozzle, char **ipaddr_list, int *entries);
++int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip);
+ 
+ /**
+  * nozzle_get_mtu
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index cae35eaf..75deb438 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -981,10 +981,10 @@ static int check_knet_set_del_ip(void)
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+ 	char verifycmd[1024];
+-	int err=0;
++	int err = 0;
+ 	nozzle_t nozzle;
+-	char *ip_list = NULL;
+-	int ip_list_entries = 0, i, offset = 0;
++	struct nozzle_ip *ip_list = NULL, *ip_list_tmp = NULL;
++	int ip_list_entries = 0, i;
+ 	char *error_string = NULL;
+ 
+ 	printf("Testing interface add/remove ip\n");
+@@ -1048,26 +1048,27 @@ static int check_knet_set_del_ip(void)
+ 
+ 	printf("Get ip list from libnozzle:\n");
+ 
+-	if (nozzle_get_ips(nozzle, &ip_list, &ip_list_entries) < 0) {
++	if (nozzle_get_ips(nozzle, &ip_list) < 0) {
+ 		printf("Not enough mem?\n");
+ 		err=-1;
+ 		goto out_clean;
+ 	}
+ 
++	ip_list_tmp = ip_list;
++	ip_list_entries = 0;
++
++	while(ip_list_tmp) {
++		ip_list_entries++;
++		printf("Found IP %s %s in libnozzle db\n", ip_list_tmp->ipaddr, ip_list_tmp->prefix);
++		ip_list_tmp = ip_list_tmp->next;
++	}
++
+ 	if (ip_list_entries != 2) {
+ 		printf("Didn't get enough ip back from libnozzle?\n");
+ 		err=-1;
+ 		goto out_clean;
+ 	}
+ 
+-	for (i = 1; i <= ip_list_entries; i++) {
+-		printf("Found IP %s %s in libnozzle db\n", ip_list + offset, ip_list + offset + strlen(ip_list + offset) + 1);
+-		offset = offset + strlen(ip_list) + 1;
+-		offset = offset + strlen(ip_list + offset) + 1;
+-	}
+-
+-	free(ip_list);
+-
+ 	printf("Deleting ip: %s/24\n", testipv4_1);
+ 
+ 	err = nozzle_del_ip(nozzle, testipv4_1, "24");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0137-libnozzle-add-comment-about-BSD-ip_add-status.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0137-libnozzle-add-comment-about-BSD-ip_add-status.patch
new file mode 100644
index 000000000..ba436897c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0137-libnozzle-add-comment-about-BSD-ip_add-status.patch
@@ -0,0 +1,24 @@ 
+From 220593f3759dd0d8452aff365a2e54e0e0d35875 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 06:52:21 +0100
+Subject: [PATCH] [libnozzle] add comment about BSD ip_add status
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 21c143c9..b4d7da01 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -363,6 +363,9 @@ out:
+ 	return err;
+ #endif
+ #ifdef KNET_BSD
++	/*
++	 * TODO: port to use ioctl and such, drop shell forking here
++	 */
+ 	memset(cmdline, 0, sizeof(cmdline));
+ 
+ 	if (fam == AF_INET) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0138-libnozzle-re-instate-error-checking-in-nozzle_get_ip.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0138-libnozzle-re-instate-error-checking-in-nozzle_get_ip.patch
new file mode 100644
index 000000000..301e81f3d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0138-libnozzle-re-instate-error-checking-in-nozzle_get_ip.patch
@@ -0,0 +1,26 @@ 
+From 9fe14e203f1260eded0da60b3c6011bf1d5b3950 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 06:53:34 +0100
+Subject: [PATCH] [libnozzle] re-instate error checking in nozzle_get_ips
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index b4d7da01..4b4e07da 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1176,6 +1176,11 @@ int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip)
+ {
+ 	int err = 0, savederrno = 0;
+ 
++	if (!nozzle_ip) {
++		errno = EINVAL;
++		return -1;
++	}
++
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+ 		errno = savederrno;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0139-libnozzle-add-per-API-call-test-coverage-check.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0139-libnozzle-add-per-API-call-test-coverage-check.patch
new file mode 100644
index 000000000..af3643c02
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0139-libnozzle-add-per-API-call-test-coverage-check.patch
@@ -0,0 +1,58 @@ 
+From e8a26fbd1fc5494645819a3a5f3cce9f36826fef Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 06:57:39 +0100
+Subject: [PATCH] [libnozzle] add per-API call test coverage check
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api-test-coverage | 39 +++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index 06a61439..6320ac87 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -49,4 +49,43 @@ for i in $headerapicalls; do
+ 	fi
+ done
+ 
++echo "Checking for tests with memcheck exceptions"
++
++for i in $(grep -l is_memcheck "$srcdir"/*.c | grep -v test-common); do
++	echo "WARNING: $(basename $i) - has memcheck exception enabled"
++done
++
++echo "Checking for tests with helgrind exceptions"
++
++for i in $(grep -l is_helgrind "$srcdir"/*.c | grep -v test-common); do
++	echo "WARNING: $(basename $i) has helgrind exception enabled"
++done
++
++echo "Checking for api test coverage"
++
++numapicalls=0
++found=0
++missing=0
++
++for i in $headerapicalls; do
++	numapicalls=$((numapicalls + 1))
++	if [ -f $srcdir/api_${i}.c ]; then
++		found=$((found + 1))
++	else
++		missing=$((missing + 1))
++		echo "MISSING: $i"
++	fi
++done
++
++echo "Summary"
++echo "-------"
++echo "Found   : $found"
++echo "Missing : $missing"
++echo "Total   : $numapicalls"
++which bc > /dev/null 2>&1 && {
++	coverage=$(echo "scale=3; $found / $numapicalls * 100" | bc -l)
++	echo "Coverage: $coverage%"
++}
++exit 0
++
+ exit 0
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0140-libnozzle-fix-API-check-paths.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0140-libnozzle-fix-API-check-paths.patch
new file mode 100644
index 000000000..d78fc99d6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0140-libnozzle-fix-API-check-paths.patch
@@ -0,0 +1,34 @@ 
+From 042d73c7eca85c2f9ad9122f79d543cf4db4bdcb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 10:51:30 +0100
+Subject: [PATCH] [libnozzle] fix API check paths
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api-test-coverage | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index 6320ac87..f9acb8fa 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -7,15 +7,15 @@
+ # This software licensed under GPL-2.0+, LGPL-2.0+
+ #
+ 
+-srcdir="$1"/libnozzle
+-builddir="$2"/libnozzle
++srcdir="$1"/libnozzle/tests
++builddir="$2"/libnozzle/tests
+ 
+-headerapicalls="$(grep nozzle_ "$srcdir"/libnozzle.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
++headerapicalls="$(grep nozzle_ "$srcdir"/../libnozzle.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
+ 
+ # The PowerPC64 ELFv1 ABI defines the address of a function as that of a
+ # function descriptor defined in .opd, a data (D) section.  Other ABIs
+ # use the entry address of the function itself in the text (T) section.
+-exportedapicalls="$(nm -B -D "$builddir"/.libs/libnozzle.so | grep ' [DT] ' | awk '{print $3}')"
++exportedapicalls="$(nm -B -D "$builddir"/../.libs/libnozzle.so | grep ' [DT] ' | awk '{print $3}')"
+ 
+ echo "Checking for exported symbols NOT available in header file"
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0141-libnozzle-prepare-Makefile.am-to-explode-with-API-te.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0141-libnozzle-prepare-Makefile.am-to-explode-with-API-te.patch
new file mode 100644
index 000000000..e19c2304c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0141-libnozzle-prepare-Makefile.am-to-explode-with-API-te.patch
@@ -0,0 +1,82 @@ 
+From f576b14d5ec13b699f6da27389ab07ec6dad7726 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 4 Dec 2018 10:52:31 +0100
+Subject: [PATCH] [libnozzle] prepare Makefile.am to explode with API tests
+
+also fix nozzle_test for using global compiler flags
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am   | 20 ++++++++++----------
+ libnozzle/tests/nozzle_test.c |  6 +++---
+ 2 files changed, 13 insertions(+), 13 deletions(-)
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 5cbb788a..48ae874d 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -10,11 +10,15 @@ MAINTAINERCLEANFILES	= Makefile.in
+ 
+ include $(top_srcdir)/build-aux/check.mk
+ 
+-EXTRA_DIST		= tap_updown_bad tap_updown_good api-test-coverage
++EXTRA_DIST		= \
++			  tap_updown_bad \
++			  tap_updown_good \
++			  api-test-coverage
+ 
+ if BUILD_LIBNOZZLE
+ 
+-check_PROGRAMS		= nozzle_test
++check_PROGRAMS		= \
++			  nozzle_test
+ 
+ TESTS			= $(check_PROGRAMS)
+ 
+@@ -26,15 +30,11 @@ check-api-test-coverage:
+ 	chmod u+x $(top_srcdir)/libnozzle/tests/api-test-coverage
+ 	$(top_srcdir)/libnozzle/tests/api-test-coverage $(top_srcdir) $(top_builddir)
+ 
++AM_CPPFLAGS		= -I$(top_srcdir)/libnozzle -DABSBUILDDIR=\"$(abs_builddir)\"
++AM_CFLAGS		+= $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
++LIBS			+= $(top_builddir)/libnozzle/libnozzle.la $(PTHREAD_LIBS) $(libnl_LIBS)
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  ../internals.c
+ 
+-nozzle_test_CPPFLAGS	= -I$(top_srcdir)/libnozzle \
+-			  -DABSBUILDDIR=\"$(abs_builddir)\"
+-
+-nozzle_test_CFLAGS	= $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
+-
+-nozzle_test_LDFLAGS	= $(top_builddir)/libnozzle/libnozzle.la \
+-			  $(PTHREAD_LIBS) $(libnl_LIBS)
+-
+ endif
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 75deb438..2c8c9855 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -349,7 +349,7 @@ static int check_knet_mtu_ipv6(void)
+ {
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+-	char verifycmd[1024];
++	char verifycmd[2048];
+ 	int err=0;
+ 	nozzle_t nozzle;
+ 	char *error_string = NULL;
+@@ -980,11 +980,11 @@ static int check_knet_set_del_ip(void)
+ {
+ 	char device_name[IFNAMSIZ];
+ 	size_t size = IFNAMSIZ;
+-	char verifycmd[1024];
++	char verifycmd[2048];
+ 	int err = 0;
+ 	nozzle_t nozzle;
+ 	struct nozzle_ip *ip_list = NULL, *ip_list_tmp = NULL;
+-	int ip_list_entries = 0, i;
++	int ip_list_entries = 0;
+ 	char *error_string = NULL;
+ 
+ 	printf("Testing interface add/remove ip\n");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0142-libnozzle-add-api_nozzle_open-test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0142-libnozzle-add-api_nozzle_open-test.patch
new file mode 100644
index 000000000..ded460544
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0142-libnozzle-add-api_nozzle_open-test.patch
@@ -0,0 +1,498 @@ 
+From 05edee4dba124302f8833c7fdfdfb2d2ddbc771d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 10:17:51 +0100
+Subject: [PATCH] [libnozzle] add api_nozzle_open test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am       |  16 ++-
+ libnozzle/tests/api_nozzle_open.c | 148 ++++++++++++++++++++++++++++
+ libnozzle/tests/nozzle_test.c     | 155 +-----------------------------
+ libnozzle/tests/test-common.c     |  51 ++++++++++
+ libnozzle/tests/test-common.h     |  31 ++++++
+ 5 files changed, 246 insertions(+), 155 deletions(-)
+ create mode 100644 libnozzle/tests/api_nozzle_open.c
+ create mode 100644 libnozzle/tests/test-common.c
+ create mode 100644 libnozzle/tests/test-common.h
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 48ae874d..e9621c39 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -15,15 +15,22 @@ EXTRA_DIST		= \
+ 			  tap_updown_good \
+ 			  api-test-coverage
+ 
++noinst_HEADERS		= \
++			  test-common.h
++
+ if BUILD_LIBNOZZLE
+ 
+ check_PROGRAMS		= \
++			  api_nozzle_open_test \
+ 			  nozzle_test
+ 
+-TESTS			= $(check_PROGRAMS)
+-
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+ 
++noinst_SCRIPTS		= \
++			  api-test-coverage
++
++TESTS			= $(check_PROGRAMS)
++
+ check-local: check-api-test-coverage
+ 
+ check-api-test-coverage:
+@@ -34,7 +41,12 @@ AM_CPPFLAGS		= -I$(top_srcdir)/libnozzle -DABSBUILDDIR=\"$(abs_builddir)\"
+ AM_CFLAGS		+= $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
+ LIBS			+= $(top_builddir)/libnozzle/libnozzle.la $(PTHREAD_LIBS) $(libnl_LIBS)
+ 
++api_nozzle_open_test_SOURCES = api_nozzle_open.c \
++			       test-common.c \
++			       ../internals.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
++			  test-common.c \
+ 			  ../internals.c
+ 
+ endif
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+new file mode 100644
+index 00000000..43862124
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -0,0 +1,148 @@
++/*
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <errno.h>
++#include <limits.h>
++
++#include "test-common.h"
++
++/*
++ * use this one to randomize nozzle interface name
++ * for named creation test
++ */
++uint8_t randombyte = 0;
++
++static int test_iface(char *name, size_t size, const char *updownpath)
++{
++	nozzle_t nozzle;
++
++	nozzle=nozzle_open(name, size, updownpath);
++	if (!nozzle) {
++		printf("Unable to open nozzle.\n");
++		return -1;
++	}
++	printf("Created interface: %s\n", name);
++
++	if (is_if_in_system(name) > 0) {
++		printf("Found interface %s on the system\n", name);
++	} else {
++		printf("Unable to find interface %s on the system\n", name);
++	}
++
++	if (!nozzle_get_handle_by_name(name)) {
++		printf("Unable to find interface %s in nozzle db\n", name);
++	} else {
++		printf("Found interface %s in nozzle db\n", name);
++	}
++
++	nozzle_close(nozzle);
++
++	if (is_if_in_system(name) == 0)
++		printf("Successfully removed interface %s from the system\n", name);
++
++	return 0;
++}
++
++static int test(void)
++{
++	char device_name[2*IFNAMSIZ];
++	char fakepath[PATH_MAX];
++	size_t size = IFNAMSIZ;
++
++	memset(device_name, 0, sizeof(device_name));
++
++	printf("Creating random nozzle interface:\n");
++	if (test_iface(device_name, size,  NULL) < 0) {
++		printf("Unable to create random interface\n");
++		return -1;
++	}
++
++#ifdef KNET_LINUX
++	printf("Creating kronostest%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
++	if (test_iface(device_name, size, NULL) < 0) {
++		printf("Unable to create kronostest%u interface\n", randombyte);
++		return -1;
++	}
++#endif
++#ifdef KNET_BSD
++	printf("Creating tap%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
++	if (test_iface(device_name, size, NULL) < 0) {
++		printf("Unable to create tap%u interface\n", randombyte);
++		return -1;
++	}
++
++	printf("Creating kronostest%u nozzle interface:\n", randombyte);
++	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
++	if (test_iface(device_name, size, NULL) == 0) {
++		printf("BSD should not accept kronostest%u interface\n", randombyte);
++		return -1;
++	}
++#endif
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Testing dev == NULL\n");
++	errno=0;
++	if ((test_iface(NULL, size, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing size < IFNAMSIZ\n");
++	errno=0;
++	if ((test_iface(device_name, 1, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing device_name size > IFNAMSIZ\n");
++	errno=0;
++	strcpy(device_name, "abcdefghilmnopqrstuvwz");
++	if ((test_iface(device_name, IFNAMSIZ, NULL) >= 0) || (errno != E2BIG)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing updown path != abs\n");
++	errno=0;
++
++	memset(device_name, 0, IFNAMSIZ);
++	if ((test_iface(device_name, IFNAMSIZ, "foo")  >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	memset(fakepath, 0, PATH_MAX);
++	memset(fakepath, '/', PATH_MAX - 2);
++
++	printf("Testing updown path > PATH_MAX\n");
++	errno=0;
++
++	memset(device_name, 0, IFNAMSIZ);
++	if ((test_iface(device_name, IFNAMSIZ, fakepath)  >= 0) || (errno != E2BIG)) {
++		printf("Something is wrong in nozzle_open sanity checks\n");
++		return -1;
++	}
++
++	return 0;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 2c8c9855..be441e7b 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -12,9 +12,7 @@
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <unistd.h>
+-#include <sys/types.h>
+ #include <errno.h>
+-#include <ifaddrs.h>
+ #include <stdint.h>
+ #include <limits.h>
+ #include <sys/socket.h>
+@@ -28,8 +26,7 @@
+ #include <net/if_dl.h>
+ #endif
+ 
+-#include "libnozzle.h"
+-#include "internals.h"
++#include "test-common.h"
+ 
+ char testipv4_1[1024];
+ char testipv4_2[1024];
+@@ -41,148 +38,6 @@ char testipv6_2[1024];
+  */
+ uint8_t randombyte = 0;
+ 
+-static int is_if_in_system(char *name)
+-{
+-	struct ifaddrs *ifap = NULL;
+-	struct ifaddrs *ifa;
+-	int found = 0;
+-
+-	if (getifaddrs(&ifap) < 0) {
+-		printf("Unable to get interface list.\n");
+-		return -1;
+-	}
+-
+-	ifa = ifap;
+-
+-	while (ifa) {
+-		if (!strncmp(name, ifa->ifa_name, IFNAMSIZ)) {
+-			found = 1;
+-			break;
+-		}
+-		ifa=ifa->ifa_next;
+-	}
+-
+-	freeifaddrs(ifap);
+-	return found;
+-}
+-
+-static int test_iface(char *name, size_t size, const char *updownpath)
+-{
+-	nozzle_t nozzle;
+-
+-	nozzle=nozzle_open(name, size, updownpath);
+-	if (!nozzle) {
+-		printf("Unable to open knet.\n");
+-		return -1;
+-	}
+-	printf("Created interface: %s\n", name);
+-
+-	if (is_if_in_system(name) > 0) {
+-		printf("Found interface %s on the system\n", name);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", name);
+-	}
+-
+-	if (!nozzle_get_handle_by_name(name)) {
+-		printf("Unable to find interface %s in nozzle db\n", name);
+-	} else {
+-		printf("Found interface %s in nozzle db\n", name);
+-	}
+-
+-	nozzle_close(nozzle);
+-
+-	if (is_if_in_system(name) == 0)
+-		printf("Successfully removed interface %s from the system\n", name);
+-
+-	return 0;
+-}
+-
+-static int check_nozzle_open_close(void)
+-{
+-	char device_name[2*IFNAMSIZ];
+-	char fakepath[PATH_MAX];
+-	size_t size = IFNAMSIZ;
+-
+-	memset(device_name, 0, sizeof(device_name));
+-
+-	printf("Creating random nozzle interface:\n");
+-	if (test_iface(device_name, size,  NULL) < 0) {
+-		printf("Unable to create random interface\n");
+-		return -1;
+-	}
+-
+-#ifdef KNET_LINUX
+-	printf("Creating kronostest%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+-	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create kronostest%u interface\n", randombyte);
+-		return -1;
+-	}
+-#endif
+-#ifdef KNET_BSD
+-	printf("Creating tap%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "tap%u", randombyte);
+-	if (test_iface(device_name, size, NULL) < 0) {
+-		printf("Unable to create tap%u interface\n", randombyte);
+-		return -1;
+-	}
+-
+-	printf("Creating kronostest%u nozzle interface:\n", randombyte);
+-	snprintf(device_name, IFNAMSIZ, "kronostest%u", randombyte);
+-	if (test_iface(device_name, size, NULL) == 0) {
+-		printf("BSD should not accept kronostest%u interface\n", randombyte);
+-		return -1;
+-	}
+-#endif
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("Testing dev == NULL\n");
+-	errno=0;
+-	if ((test_iface(NULL, size, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	printf("Testing size < IFNAMSIZ\n");
+-	errno=0;
+-	if ((test_iface(device_name, 1, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	printf("Testing device_name size > IFNAMSIZ\n");
+-	errno=0;
+-	strcpy(device_name, "abcdefghilmnopqrstuvwz");
+-	if ((test_iface(device_name, IFNAMSIZ, NULL) >= 0) || (errno != E2BIG)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	printf("Testing updown path != abs\n");
+-	errno=0;
+-
+-	memset(device_name, 0, IFNAMSIZ);
+-	if ((test_iface(device_name, IFNAMSIZ, "foo")  >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	memset(fakepath, 0, PATH_MAX);
+-	memset(fakepath, '/', PATH_MAX - 2);
+-
+-	printf("Testing updown path > PATH_MAX\n");
+-	errno=0;
+-
+-	memset(device_name, 0, IFNAMSIZ);
+-	if ((test_iface(device_name, IFNAMSIZ, fakepath)  >= 0) || (errno != E2BIG)) {
+-		printf("Something is wrong in nozzle_open sanity checks\n");
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+ static int check_knet_multi_eth(void)
+ {
+ 	char device_name1[IFNAMSIZ];
+@@ -1238,16 +1093,10 @@ static void make_local_ips(void)
+ 
+ int main(void)
+ {
+-	if (geteuid() != 0) {
+-		printf("This test requires root privileges\n");
+-		exit(77);
+-	}
++	need_root();
+ 
+ 	make_local_ips();
+ 
+-	if (check_nozzle_open_close() < 0)
+-		return -1;
+-
+ 	if (check_knet_multi_eth() < 0)
+ 		return -1;
+ 
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+new file mode 100644
+index 00000000..f136b90b
+--- /dev/null
++++ b/libnozzle/tests/test-common.c
+@@ -0,0 +1,51 @@
++/*
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <sys/types.h>
++#include <ifaddrs.h>
++#include <limits.h>
++#include <unistd.h>
++#include <sys/types.h>
++
++#include "test-common.h"
++
++void need_root(void)
++{
++	if (geteuid() != 0) {
++		printf("This test requires root privileges\n");
++		exit(SKIP);
++	}
++}
++
++int is_if_in_system(char *name)
++{
++	struct ifaddrs *ifap = NULL;
++	struct ifaddrs *ifa;
++	int found = 0;
++
++	if (getifaddrs(&ifap) < 0) {
++		printf("Unable to get interface list.\n");
++		return -1;
++	}
++
++	ifa = ifap;
++
++	while (ifa) {
++		if (!strncmp(name, ifa->ifa_name, IFNAMSIZ)) {
++			found = 1;
++			break;
++		}
++		ifa=ifa->ifa_next;
++	}
++
++	freeifaddrs(ifap);
++	return found;
++}
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+new file mode 100644
+index 00000000..fdf0814b
+--- /dev/null
++++ b/libnozzle/tests/test-common.h
+@@ -0,0 +1,31 @@
++/*
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#ifndef __NOZZLE_TEST_COMMON_H__
++#define __NOZZLE_TEST_COMMON_H__
++
++#include "internals.h"
++#include "libnozzle.h"
++
++/*
++ * error codes from automake test-driver
++ */
++
++#define PASS	0
++#define SKIP	77
++#define ERROR	99
++#define FAIL	-1
++
++/*
++ * common facilities
++ */
++
++void need_root(void);
++int is_if_in_system(char *name);
++
++#endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0143-libnozzle-fix-test-suite-build-on-BSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0143-libnozzle-fix-test-suite-build-on-BSD.patch
new file mode 100644
index 000000000..06f91c81f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0143-libnozzle-fix-test-suite-build-on-BSD.patch
@@ -0,0 +1,22 @@ 
+From 782146d7fc35fe87851ea7061c52427cdc84989a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 10:22:49 +0100
+Subject: [PATCH] [libnozzle] fix test suite build on BSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api_nozzle_open.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index 43862124..edd6f99f 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -8,6 +8,7 @@
+ 
+ #include "config.h"
+ 
++#include <stdio.h>
+ #include <string.h>
+ #include <errno.h>
+ #include <limits.h>
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0144-libnozzle-add-api_nozzle_close_test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0144-libnozzle-add-api_nozzle_close_test.patch
new file mode 100644
index 000000000..33f90975a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0144-libnozzle-add-api_nozzle_close_test.patch
@@ -0,0 +1,473 @@ 
+From 1189ed1a2e61e7e263421a029b9cf5c6b87817d8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 10:56:23 +0100
+Subject: [PATCH] [libnozzle] add api_nozzle_close_test
+
+also, share more code in test-common, fix another BSD build issue
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am        |   7 +-
+ libnozzle/tests/api_nozzle_close.c | 130 +++++++++++++++++++++++++++++
+ libnozzle/tests/api_nozzle_open.c  |  38 +--------
+ libnozzle/tests/nozzle_test.c      |  71 ++--------------
+ libnozzle/tests/test-common.c      | 108 ++++++++++++++++++++++++
+ libnozzle/tests/test-common.h      |   5 ++
+ 6 files changed, 254 insertions(+), 105 deletions(-)
+ create mode 100644 libnozzle/tests/api_nozzle_close.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index e9621c39..2c9b754e 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -22,6 +22,7 @@ if BUILD_LIBNOZZLE
+ 
+ check_PROGRAMS		= \
+ 			  api_nozzle_open_test \
++			  api_nozzle_close_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -42,8 +43,10 @@ AM_CFLAGS		+= $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
+ LIBS			+= $(top_builddir)/libnozzle/libnozzle.la $(PTHREAD_LIBS) $(libnl_LIBS)
+ 
+ api_nozzle_open_test_SOURCES = api_nozzle_open.c \
+-			       test-common.c \
+-			       ../internals.c
++			       test-common.c
++
++api_nozzle_close_test_SOURCES = api_nozzle_close.c \
++			        test-common.c
+ 
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+new file mode 100644
+index 00000000..b954ec77
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++#include <net/ethernet.h>
++
++#ifdef KNET_LINUX
++#include <linux/if_tun.h>
++#include <netinet/ether.h>
++#endif
++#ifdef KNET_BSD
++#include <net/if_dl.h>
++#endif
++
++#include "test-common.h"
++
++char testipv4_1[IPBUFSIZE];
++char testipv4_2[IPBUFSIZE];
++char testipv6_1[IPBUFSIZE];
++char testipv6_2[IPBUFSIZE];
++
++static int test(void)
++{
++	char device_name[2*IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	nozzle_t nozzle;
++
++	memset(device_name, 0, sizeof(device_name));
++
++	/*
++	 * this test is duplicated from api_nozzle_open.c
++	 */
++	printf("Testing random nozzle interface:\n");
++	if (test_iface(device_name, size,  NULL) < 0) {
++		printf("Unable to create random interface\n");
++		return -1;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Testing nozzle_close with NULL nozzle\n");
++	if ((nozzle_close(NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_close sanity checks\n");
++		return -1;
++	}
++
++	printf("Testing nozzle_close with random bytes nozzle pointer\n");
++
++	nozzle = (nozzle_t)0x1;
++
++	if ((nozzle_close(nozzle) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_close sanity checks\n");
++		return -1;
++	}
++
++	return 0;
++}
++
++/*
++ * requires running the test suite with valgrind
++ */
++static int check_nozzle_close_leak(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++
++	printf("Testing close leak (needs valgrind)\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_2);
++
++	err = nozzle_add_ip(nozzle, testipv4_2, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle);
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
++
++	if (test() < 0)
++		return FAIL;
++
++	if (check_nozzle_close_leak() < 0)
++		return FAIL;
++
++	return 0;
++}
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index edd6f99f..80e1038c 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -15,48 +15,12 @@
+ 
+ #include "test-common.h"
+ 
+-/*
+- * use this one to randomize nozzle interface name
+- * for named creation test
+- */
+-uint8_t randombyte = 0;
+-
+-static int test_iface(char *name, size_t size, const char *updownpath)
+-{
+-	nozzle_t nozzle;
+-
+-	nozzle=nozzle_open(name, size, updownpath);
+-	if (!nozzle) {
+-		printf("Unable to open nozzle.\n");
+-		return -1;
+-	}
+-	printf("Created interface: %s\n", name);
+-
+-	if (is_if_in_system(name) > 0) {
+-		printf("Found interface %s on the system\n", name);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", name);
+-	}
+-
+-	if (!nozzle_get_handle_by_name(name)) {
+-		printf("Unable to find interface %s in nozzle db\n", name);
+-	} else {
+-		printf("Found interface %s in nozzle db\n", name);
+-	}
+-
+-	nozzle_close(nozzle);
+-
+-	if (is_if_in_system(name) == 0)
+-		printf("Successfully removed interface %s from the system\n", name);
+-
+-	return 0;
+-}
+-
+ static int test(void)
+ {
+ 	char device_name[2*IFNAMSIZ];
+ 	char fakepath[PATH_MAX];
+ 	size_t size = IFNAMSIZ;
++	uint8_t randombyte = get_random_byte();
+ 
+ 	memset(device_name, 0, sizeof(device_name));
+ 
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index be441e7b..d8ded315 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -28,15 +28,10 @@
+ 
+ #include "test-common.h"
+ 
+-char testipv4_1[1024];
+-char testipv4_2[1024];
+-char testipv6_1[1024];
+-char testipv6_2[1024];
+-/*
+- * use this one to randomize knet interface name
+- * for named creation test
+- */
+-uint8_t randombyte = 0;
++char testipv4_1[IPBUFSIZE];
++char testipv4_2[IPBUFSIZE];
++char testipv6_1[IPBUFSIZE];
++char testipv6_2[IPBUFSIZE];
+ 
+ static int check_knet_multi_eth(void)
+ {
+@@ -1035,67 +1030,11 @@ out_clean:
+ 	return err;
+ }
+ 
+-static void make_local_ips(void)
+-{
+-	pid_t mypid;
+-	uint8_t *pid;
+-	uint8_t i;
+-
+-	if (sizeof(pid_t) < 4) {
+-		printf("pid_t is smaller than 4 bytes?\n");
+-		exit(77);
+-	}
+-
+-	memset(testipv4_1, 0, sizeof(testipv4_1));
+-	memset(testipv4_2, 0, sizeof(testipv4_2));
+-	memset(testipv6_1, 0, sizeof(testipv6_1));
+-	memset(testipv6_2, 0, sizeof(testipv6_2));
+-
+-	mypid = getpid();
+-	pid = (uint8_t *)&mypid;
+-
+-	for (i = 0; i < sizeof(pid_t); i++) {
+-		if (pid[i] == 0) {
+-			pid[i] = 128;
+-		}
+-	}
+-
+-	randombyte = pid[1];
+-
+-	snprintf(testipv4_1,
+-		 sizeof(testipv4_1) - 1,
+-		 "127.%u.%u.%u",
+-		 pid[1],
+-		 pid[2],
+-		 pid[0]);
+-
+-	snprintf(testipv4_2,
+-		 sizeof(testipv4_2) - 1,
+-		 "127.%u.%d.%u",
+-		 pid[1],
+-		 pid[2]+1,
+-		 pid[0]);
+-
+-	snprintf(testipv6_1,
+-		 sizeof(testipv6_1) - 1,
+-		 "fd%x:%x%x::1",
+-		 pid[1],
+-		 pid[2],
+-		 pid[0]);
+-
+-	snprintf(testipv6_2,
+-		 sizeof(testipv6_2) - 1,
+-		 "fd%x:%x%x:1::1",
+-		 pid[1],
+-		 pid[2],
+-		 pid[0]);
+-}
+-
+ int main(void)
+ {
+ 	need_root();
+ 
+-	make_local_ips();
++	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+ 	if (check_knet_multi_eth() < 0)
+ 		return -1;
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index f136b90b..752f1707 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -14,6 +14,8 @@
+ #include <limits.h>
+ #include <unistd.h>
+ #include <sys/types.h>
++#include <stdio.h>
++#include <stdlib.h>
+ 
+ #include "test-common.h"
+ 
+@@ -25,6 +27,37 @@ void need_root(void)
+ 	}
+ }
+ 
++int test_iface(char *name, size_t size, const char *updownpath)
++{
++	nozzle_t nozzle;
++
++	nozzle=nozzle_open(name, size, updownpath);
++	if (!nozzle) {
++		printf("Unable to open nozzle.\n");
++		return -1;
++	}
++	printf("Created interface: %s\n", name);
++
++	if (is_if_in_system(name) > 0) {
++		printf("Found interface %s on the system\n", name);
++	} else {
++		printf("Unable to find interface %s on the system\n", name);
++	}
++
++	if (!nozzle_get_handle_by_name(name)) {
++		printf("Unable to find interface %s in nozzle db\n", name);
++	} else {
++		printf("Found interface %s in nozzle db\n", name);
++	}
++
++	nozzle_close(nozzle);
++
++	if (is_if_in_system(name) == 0)
++		printf("Successfully removed interface %s from the system\n", name);
++
++	return 0;
++}
++
+ int is_if_in_system(char *name)
+ {
+ 	struct ifaddrs *ifap = NULL;
+@@ -49,3 +82,78 @@ int is_if_in_system(char *name)
+ 	freeifaddrs(ifap);
+ 	return found;
+ }
++
++int get_random_byte(void)
++{
++	pid_t mypid;
++	uint8_t *pid;
++	uint8_t randombyte = 0;
++	uint8_t i;
++
++	if (sizeof(pid_t) < 4) {
++		printf("pid_t is smaller than 4 bytes?\n");
++		exit(77);
++	}
++
++	mypid = getpid();
++	pid = (uint8_t *)&mypid;
++
++	for (i = 0; i < sizeof(pid_t); i++) {
++		if (pid[i] == 0) {
++			pid[i] = 128;
++		}
++	}
++
++	randombyte = pid[1];
++
++	return randombyte;
++}
++
++void make_local_ips(char *testipv4_1, char *testipv4_2, char *testipv6_1, char *testipv6_2)
++{
++	pid_t mypid;
++	uint8_t *pid;
++	uint8_t i;
++
++	memset(testipv4_1, 0, IPBUFSIZE);
++	memset(testipv4_2, 0, IPBUFSIZE);
++	memset(testipv6_1, 0, IPBUFSIZE);
++	memset(testipv6_2, 0, IPBUFSIZE);
++
++	mypid = getpid();
++	pid = (uint8_t *)&mypid;
++
++	for (i = 0; i < sizeof(pid_t); i++) {
++		if (pid[i] == 0) {
++			pid[i] = 128;
++		}
++	}
++
++	snprintf(testipv4_1,
++		 IPBUFSIZE - 1,
++		 "127.%u.%u.%u",
++		 pid[1],
++		 pid[2],
++		 pid[0]);
++
++	snprintf(testipv4_2,
++		 IPBUFSIZE - 1,
++		 "127.%u.%d.%u",
++		 pid[1],
++		 pid[2]+1,
++		 pid[0]);
++
++	snprintf(testipv6_1,
++		 IPBUFSIZE - 1,
++		 "fd%x:%x%x::1",
++		 pid[1],
++		 pid[2],
++		 pid[0]);
++
++	snprintf(testipv6_2,
++		 IPBUFSIZE - 1,
++		 "fd%x:%x%x:1::1",
++		 pid[1],
++		 pid[2],
++		 pid[0]);
++}
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index fdf0814b..0bfce530 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -25,7 +25,12 @@
+  * common facilities
+  */
+ 
++#define IPBUFSIZE 1024
++
+ void need_root(void);
++int test_iface(char *name, size_t size, const char *updownpath);
+ int is_if_in_system(char *name);
++int get_random_byte(void);
++void make_local_ips(char *testipv4_1, char *testipv4_2, char *testipv6_1, char *testipv6_2);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0145-libnozzle-drop-redundant-check.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0145-libnozzle-drop-redundant-check.patch
new file mode 100644
index 000000000..ad23fe6a1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0145-libnozzle-drop-redundant-check.patch
@@ -0,0 +1,71 @@ 
+From 25ab40de70355c8048e2a3661f5bb6c90e0031bb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 11:04:39 +0100
+Subject: [PATCH] [libnozzle] drop redundant check
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/nozzle_test.c | 44 -----------------------------------
+ 1 file changed, 44 deletions(-)
+
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index d8ded315..42d84d67 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -785,47 +785,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int check_knet_close_leak(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-
+-	printf("Testing close leak (needs valgrind)\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24");
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_2);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_2, "24");
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	nozzle_close(nozzle);
+-
+-	return err;
+-}
+-
+ static int check_knet_set_del_ip(void)
+ {
+ 	char device_name[IFNAMSIZ];
+@@ -1057,8 +1016,5 @@ int main(void)
+ 	if (check_knet_set_del_ip() < 0)
+ 		return -1;
+ 
+-	if (check_knet_close_leak() < 0)
+-		return -1;
+-
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0146-libnozzle-drop-unnecessary-indirection-to-call-set_d.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0146-libnozzle-drop-unnecessary-indirection-to-call-set_d.patch
new file mode 100644
index 000000000..3027c6b89
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0146-libnozzle-drop-unnecessary-indirection-to-call-set_d.patch
@@ -0,0 +1,93 @@ 
+From 75ff140b038a4dc316874bb1bfd6443a741d5a2f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 11:26:14 +0100
+Subject: [PATCH] [libnozzle] drop unnecessary indirection to call set_down
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 58 +++++++++++++++++--------------------------
+ 1 file changed, 23 insertions(+), 35 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 4b4e07da..05bf0c4b 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -213,39 +213,6 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int set_iface_down(nozzle_t nozzle)
+-{
+-	int err = 0, savederrno = 0;
+-	struct ifreq ifr;
+-
+-	if (!nozzle->up) {
+-		goto out_clean;
+-	}
+-
+-	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	ifr.ifr_flags &= ~IFF_UP;
+-
+-	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
+-	if (err) {
+-		savederrno = errno;
+-		goto out_clean;
+-	}
+-
+-	nozzle->up = 0;
+-
+-out_clean:
+-	errno = savederrno;
+-	return err;
+-}
+-
+ #define IP_ADD 1
+ #define IP_DEL 2
+ 
+@@ -766,6 +733,7 @@ out_clean:
+ int nozzle_set_down(nozzle_t nozzle)
+ {
+ 	int err = 0, savederrno = 0;
++	struct ifreq ifr;
+ 
+ 	savederrno = pthread_mutex_lock(&config_mutex);
+ 	if (savederrno) {
+@@ -779,8 +747,28 @@ int nozzle_set_down(nozzle_t nozzle)
+ 		goto out_clean;
+ 	}
+ 
+-	err = set_iface_down(nozzle);
+-	savederrno = errno;
++	if (!nozzle->up) {
++		goto out_clean;
++	}
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifname, nozzle->name, IFNAMSIZ);
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	ifr.ifr_flags &= ~IFF_UP;
++
++	err = ioctl(lib_cfg.ioctlfd, SIOCSIFFLAGS, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	nozzle->up = 0;
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&config_mutex);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0147-libnozzle-add-api_nozzle_set_-up-down-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0147-libnozzle-add-api_nozzle_set_-up-down-tests.patch
new file mode 100644
index 000000000..c28ae69e3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0147-libnozzle-add-api_nozzle_set_-up-down-tests.patch
@@ -0,0 +1,278 @@ 
+From 3c8aa1cc81ee079646732fd3b787136217efbd00 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 11:27:32 +0100
+Subject: [PATCH] [libnozzle] add api_nozzle_set_(up|down) tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am           |  12 ++-
+ libnozzle/tests/api_nozzle_set_down.c | 119 ++++++++++++++++++++++++++
+ libnozzle/tests/api_nozzle_set_up.c   | 103 ++++++++++++++++++++++
+ 3 files changed, 233 insertions(+), 1 deletion(-)
+ create mode 100644 libnozzle/tests/api_nozzle_set_down.c
+ create mode 100644 libnozzle/tests/api_nozzle_set_up.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 2c9b754e..d677bd9b 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -23,6 +23,8 @@ if BUILD_LIBNOZZLE
+ check_PROGRAMS		= \
+ 			  api_nozzle_open_test \
+ 			  api_nozzle_close_test \
++			  api_nozzle_set_up_test \
++			  api_nozzle_set_down_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -46,7 +48,15 @@ api_nozzle_open_test_SOURCES = api_nozzle_open.c \
+ 			       test-common.c
+ 
+ api_nozzle_close_test_SOURCES = api_nozzle_close.c \
+-			        test-common.c
++				test-common.c
++
++api_nozzle_set_up_test_SOURCES = api_nozzle_set_up.c \
++				 test-common.c \
++				 ../internals.c
++
++api_nozzle_set_down_test_SOURCES = api_nozzle_set_down.c \
++				   test-common.c \
++				   ../internals.c
+ 
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+new file mode 100644
+index 00000000..da48d584
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -0,0 +1,119 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char verifycmd[1024];
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++
++	printf("Testing interface down\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Put the interface up\n");
++
++	err = nozzle_set_up(nozzle);
++	if (err < 0) {
++		printf("Unable to set interface up\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", nozzle->name);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to verify inteface UP\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Put the interface down\n");
++
++	err = nozzle_set_down(nozzle);
++	if (err < 0) {
++		printf("Unable to put the interface down\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", nozzle->name);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify inteface DOWN\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to nozzle set_down\n");
++	errno = 0;
++	if ((nozzle_set_down(NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_down sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle);
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+new file mode 100644
+index 00000000..7c8f81f1
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char verifycmd[1024];
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++
++	printf("Testing interface up/down\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Put the interface up\n");
++
++	err = nozzle_set_up(nozzle);
++	if (err < 0) {
++		printf("Unable to set interface up\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q UP", nozzle->name);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q UP", nozzle->name);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err < 0) {
++		printf("Unable to verify inteface UP\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Test ERROR conditions\n");
++
++	printf("Try to UP the same interface twice\n");
++	err = nozzle_set_up(nozzle);
++	if (err < 0) {
++		printf("Interface was already UP, spurious error received from nozzle_set_up");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to nozzle set_up\n");
++	err = 0;
++	errno = 0;
++	if ((nozzle_set_up(NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_up sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_set_down(nozzle);
++	nozzle_close(nozzle);
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0148-libnozzle-improve-set_down-test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0148-libnozzle-improve-set_down-test.patch
new file mode 100644
index 000000000..1ae56ec19
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0148-libnozzle-improve-set_down-test.patch
@@ -0,0 +1,28 @@ 
+From 8da535acde97796f5f1690d73ff59d222a982d1f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 12:51:01 +0100
+Subject: [PATCH] [libnozzle] improve set_down test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api_nozzle_set_down.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index da48d584..3921772b 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -94,6 +94,13 @@ static int test(void)
+ 		goto out_clean;
+ 	}
+ 
++	printf("Try to DOWN the same interface twice\n");
++	if (nozzle_set_down(nozzle) < 0) {
++		printf("Interface was already DOWN, spurious error received from nozzle_set_down\n");
++		err = -1;
++		goto out_clean;
++	}
++
+ 	printf("Pass NULL to nozzle set_down\n");
+ 	errno = 0;
+ 	if ((nozzle_set_down(NULL) >= 0) || (errno != EINVAL)) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0149-libnozzle-clean-up-code-in-set_up-test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0149-libnozzle-clean-up-code-in-set_up-test.patch
new file mode 100644
index 000000000..9a080543b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0149-libnozzle-clean-up-code-in-set_up-test.patch
@@ -0,0 +1,42 @@ 
+From e835e8d03921db6ed1291de6b8df40d45ccef5b9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Dec 2018 12:51:12 +0100
+Subject: [PATCH] [libnozzle] clean up code in set_up test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api_nozzle_set_up.c | 9 +++------
+ 1 file changed, 3 insertions(+), 6 deletions(-)
+
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index 7c8f81f1..258270d2 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -39,8 +39,7 @@ static int test(void)
+ 
+ 	printf("Put the interface up\n");
+ 
+-	err = nozzle_set_up(nozzle);
+-	if (err < 0) {
++	if (nozzle_set_up(nozzle) < 0) {
+ 		printf("Unable to set interface up\n");
+ 		err = -1;
+ 		goto out_clean;
+@@ -69,15 +68,13 @@ static int test(void)
+ 	printf("Test ERROR conditions\n");
+ 
+ 	printf("Try to UP the same interface twice\n");
+-	err = nozzle_set_up(nozzle);
+-	if (err < 0) {
+-		printf("Interface was already UP, spurious error received from nozzle_set_up");
++	if (nozzle_set_up(nozzle) < 0) {
++		printf("Interface was already UP, spurious error received from nozzle_set_up\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ 	printf("Pass NULL to nozzle set_up\n");
+-	err = 0;
+ 	errno = 0;
+ 	if ((nozzle_set_up(NULL) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_up sanity checks\n");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0150-libnozzle-move-multi-nozzle-device-test-to-api_nozzl.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0150-libnozzle-move-multi-nozzle-device-test-to-api_nozzl.patch
new file mode 100644
index 000000000..d0fa37bce
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0150-libnozzle-move-multi-nozzle-device-test-to-api_nozzl.patch
@@ -0,0 +1,224 @@ 
+From ed9e2cc98b536e99b0897c990613a9f046326443 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 6 Dec 2018 05:48:14 +0100
+Subject: [PATCH] [libnozzle] move multi nozzle device test to api_nozzle_open
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api_nozzle_open.c | 89 +++++++++++++++++++++++++++++++
+ libnozzle/tests/nozzle_test.c     | 89 -------------------------------
+ 2 files changed, 89 insertions(+), 89 deletions(-)
+
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index 80e1038c..19876987 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -15,6 +15,92 @@
+ 
+ #include "test-common.h"
+ 
++static int test_multi_eth(void)
++{
++	char device_name1[IFNAMSIZ];
++	char device_name2[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle1 = NULL;
++	nozzle_t nozzle2 = NULL;
++
++	printf("Testing multiple nozzle interface instances\n");
++
++	memset(device_name1, 0, size);
++	memset(device_name2, 0, size);
++
++	nozzle1 = nozzle_open(device_name1, size, NULL);
++	if (!nozzle1) {
++		printf("Unable to init %s\n", device_name1);
++		err = -1;
++		goto out_clean;
++	}
++
++	if (is_if_in_system(device_name1) > 0) {
++		printf("Found interface %s on the system\n", device_name1);
++	} else {
++		printf("Unable to find interface %s on the system\n", device_name1);
++	}
++
++	nozzle2 = nozzle_open(device_name2, size, NULL);
++	if (!nozzle2) {
++		printf("Unable to init %s\n", device_name2);
++		err = -1;
++		goto out_clean;
++	}
++
++	if (is_if_in_system(device_name2) > 0) {
++		printf("Found interface %s on the system\n", device_name2);
++	} else {
++		printf("Unable to find interface %s on the system\n", device_name2);
++	}
++
++	if (nozzle1) {
++		nozzle_close(nozzle1);
++	}
++
++	if (nozzle2) {
++		nozzle_close(nozzle2);
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Open same device twice\n");
++
++	memset(device_name1, 0, size);
++
++	nozzle1 = nozzle_open(device_name1, size, NULL);
++	if (!nozzle1) {
++		printf("Unable to init %s\n", device_name1);
++		err = -1;
++		goto out_clean;
++	}
++
++	if (is_if_in_system(device_name1) > 0) {
++		printf("Found interface %s on the system\n", device_name1);
++	} else {
++		printf("Unable to find interface %s on the system\n", device_name1);
++	}
++
++	nozzle2 = nozzle_open(device_name1, size, NULL);
++	if (nozzle2) {
++		printf("We were able to init 2 interfaces with the same name!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle1) {
++		nozzle_close(nozzle1);
++	}
++
++	if (nozzle2) {
++		nozzle_close(nozzle2);
++	}
++
++	return err;
++}
++
+ static int test(void)
+ {
+ 	char device_name[2*IFNAMSIZ];
+@@ -109,5 +195,8 @@ int main(void)
+ 	if (test() < 0)
+ 		return FAIL;
+ 
++	if (test_multi_eth() < 0)
++		return FAIL;
++
+ 	return PASS;
+ }
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 42d84d67..dbf50604 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -33,92 +33,6 @@ char testipv4_2[IPBUFSIZE];
+ char testipv6_1[IPBUFSIZE];
+ char testipv6_2[IPBUFSIZE];
+ 
+-static int check_knet_multi_eth(void)
+-{
+-	char device_name1[IFNAMSIZ];
+-	char device_name2[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle1 = NULL;
+-	nozzle_t nozzle2 = NULL;
+-
+-	printf("Testing multiple knet interface instances\n");
+-
+-	memset(device_name1, 0, size);
+-	memset(device_name2, 0, size);
+-
+-	nozzle1 = nozzle_open(device_name1, size, NULL);
+-	if (!nozzle1) {
+-		printf("Unable to init %s\n", device_name1);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (is_if_in_system(device_name1) > 0) {
+-		printf("Found interface %s on the system\n", device_name1);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", device_name1);
+-	}
+-
+-	nozzle2 = nozzle_open(device_name2, size, NULL);
+-	if (!nozzle2) {
+-		printf("Unable to init %s\n", device_name2);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (is_if_in_system(device_name2) > 0) {
+-		printf("Found interface %s on the system\n", device_name2);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", device_name2);
+-	}
+-
+-	if (nozzle1) {
+-		nozzle_close(nozzle1);
+-	}
+-
+-	if (nozzle2) {
+-		nozzle_close(nozzle2);
+-	}
+-
+-	printf("Testing error conditions\n");
+-
+-	printf("Open same device twice\n");
+-
+-	memset(device_name1, 0, size);
+-
+-	nozzle1 = nozzle_open(device_name1, size, NULL);
+-	if (!nozzle1) {
+-		printf("Unable to init %s\n", device_name1);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (is_if_in_system(device_name1) > 0) {
+-		printf("Found interface %s on the system\n", device_name1);
+-	} else {
+-		printf("Unable to find interface %s on the system\n", device_name1);
+-	}
+-
+-	nozzle2 = nozzle_open(device_name1, size, NULL);
+-	if (nozzle2) {
+-		printf("We were able to init 2 interfaces with the same name!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (nozzle1) {
+-		nozzle_close(nozzle1);
+-	}
+-
+-	if (nozzle2) {
+-		nozzle_close(nozzle2);
+-	}
+-
+-	return err;
+-}
+-
+ static int check_knet_mtu(void)
+ {
+ 	char device_name[IFNAMSIZ];
+@@ -995,9 +909,6 @@ int main(void)
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+-	if (check_knet_multi_eth() < 0)
+-		return -1;
+-
+ 	if (check_knet_mtu() < 0)
+ 		return -1;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0151-libnozzle-add-nozzle_get_mtu-nozzle_set_mtu-nozzle_r.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0151-libnozzle-add-nozzle_get_mtu-nozzle_set_mtu-nozzle_r.patch
new file mode 100644
index 000000000..e9230587d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0151-libnozzle-add-nozzle_get_mtu-nozzle_set_mtu-nozzle_r.patch
@@ -0,0 +1,718 @@ 
+From eca8adde8f5bf177f955da6f82575f527c3fbd2e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 6 Dec 2018 14:22:53 +0100
+Subject: [PATCH] [libnozzle] add nozzle_get_mtu / nozzle_set_mtu /
+ nozzle_reset_mtu tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am          |   9 +
+ libnozzle/tests/api-test-coverage    |   1 +
+ libnozzle/tests/api_nozzle_get_mtu.c |  98 +++++++++
+ libnozzle/tests/api_nozzle_set_mtu.c | 297 +++++++++++++++++++++++++++
+ libnozzle/tests/nozzle_test.c        | 237 ---------------------
+ 5 files changed, 405 insertions(+), 237 deletions(-)
+ create mode 100644 libnozzle/tests/api_nozzle_get_mtu.c
+ create mode 100644 libnozzle/tests/api_nozzle_set_mtu.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index d677bd9b..17bfc876 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -25,6 +25,8 @@ check_PROGRAMS		= \
+ 			  api_nozzle_close_test \
+ 			  api_nozzle_set_up_test \
+ 			  api_nozzle_set_down_test \
++			  api_nozzle_get_mtu_test \
++			  api_nozzle_set_mtu_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -58,6 +60,13 @@ api_nozzle_set_down_test_SOURCES = api_nozzle_set_down.c \
+ 				   test-common.c \
+ 				   ../internals.c
+ 
++api_nozzle_get_mtu_test_SOURCES = api_nozzle_get_mtu.c \
++				  test-common.c
++
++api_nozzle_set_mtu_test_SOURCES = api_nozzle_set_mtu.c \
++				  test-common.c \
++				  ../internals.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+ 			  ../internals.c
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index f9acb8fa..3d73b305 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -68,6 +68,7 @@ found=0
+ missing=0
+ 
+ for i in $headerapicalls; do
++	[ "$i" = nozzle_reset_mtu ] && i=nozzle_set_mtu # tested together
+ 	numapicalls=$((numapicalls + 1))
+ 	if [ -f $srcdir/api_${i}.c ]; then
+ 		found=$((found + 1))
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+new file mode 100644
+index 00000000..2c34ca39
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -0,0 +1,98 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++
++	int current_mtu = 0;
++	int expected_mtu = 1500;
++
++	printf("Testing get MTU\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Comparing default MTU\n");
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected default [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Setting MTU to 9000\n");
++	expected_mtu = 9000;
++	if (nozzle_set_mtu(nozzle, expected_mtu) < 0) {
++		printf("Unable to set MTU to %d\n", expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected value [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Passing empty struct to get_mtu\n");
++	if (nozzle_get_mtu(NULL) > 0) {
++		printf("Something is wrong in nozzle_get_mtu sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+new file mode 100644
+index 00000000..510b2d46
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -0,0 +1,297 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++
++#include "test-common.h"
++
++char testipv4_1[IPBUFSIZE];
++char testipv4_2[IPBUFSIZE];
++char testipv6_1[IPBUFSIZE];
++char testipv6_2[IPBUFSIZE];
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++
++	int current_mtu = 0;
++	int expected_mtu = 1500;
++
++	printf("Testing set MTU\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Comparing default MTU\n");
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected default [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Setting MTU to 9000\n");
++	expected_mtu = 9000;
++	if (nozzle_set_mtu(nozzle, expected_mtu) < 0) {
++		printf("Unable to set MTU to %d\n", expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected value [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Restoring MTU to default\n");
++	expected_mtu = 1500;
++	if (nozzle_reset_mtu(nozzle) < 0) {
++		printf("Unable to reset mtu\n");
++		err = -1;
++		goto out_clean;
++	}
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu < 0) {
++		printf("Unable to get MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (current_mtu != expected_mtu) {
++		printf("current mtu [%d] does not match expected value [%d]\n", current_mtu, expected_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Passing empty struct to set_mtu\n");
++	if (nozzle_set_mtu(NULL, 1500) == 0) {
++		printf("Something is wrong in nozzle_set_mtu sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Passing 0 mtu to set_mtu\n");
++	if (nozzle_set_mtu(nozzle, 0) == 0) {
++		printf("Something is wrong in nozzle_set_mtu sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++static int test_ipv6(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	char verifycmd[2048];
++	int err=0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++	int current_mtu = 0;
++
++	printf("Testing get/set MTU with IPv6 address\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
++	if (err) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Setting MTU to 1200\n");
++	if (nozzle_set_mtu(nozzle, 1200) < 0) {
++		printf("Unable to set MTU to 1200\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++#ifdef KNET_LINUX
++	if (!err) {
++#endif
++#ifdef KNET_BSD
++	if (err) {
++#endif
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_2);
++	err = nozzle_add_ip(nozzle, testipv6_2, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	printf("Restoring MTU to default\n");
++	if (nozzle_reset_mtu(nozzle) < 0) {
++		printf("Unable to reset mtu\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	current_mtu = nozzle_get_mtu(nozzle);
++	if (current_mtu != 1500) {
++		printf("current mtu [%d] does not match expected value [1500]\n", current_mtu);
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err=-1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
++
++	if (test() < 0)
++		return FAIL;
++
++	if (test_ipv6() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index dbf50604..9c9df994 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -33,237 +33,6 @@ char testipv4_2[IPBUFSIZE];
+ char testipv6_1[IPBUFSIZE];
+ char testipv6_2[IPBUFSIZE];
+ 
+-static int check_knet_mtu(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-
+-	int current_mtu = 0;
+-	int expected_mtu = 1500;
+-
+-	printf("Testing get/set MTU\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Comparing default MTU\n");
+-	current_mtu = nozzle_get_mtu(nozzle);
+-	if (current_mtu < 0) {
+-		printf("Unable to get MTU\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	if (current_mtu != expected_mtu) {
+-		printf("current mtu [%d] does not match expected default [%d]\n", current_mtu, expected_mtu);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Setting MTU to 9000\n");
+-	expected_mtu = 9000;
+-	if (nozzle_set_mtu(nozzle, expected_mtu) < 0) {
+-		printf("Unable to set MTU to %d\n", expected_mtu);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	current_mtu = nozzle_get_mtu(nozzle);
+-	if (current_mtu < 0) {
+-		printf("Unable to get MTU\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	if (current_mtu != expected_mtu) {
+-		printf("current mtu [%d] does not match expected value [%d]\n", current_mtu, expected_mtu);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("Passing empty struct to get_mtu\n");
+-	if (nozzle_get_mtu(NULL) > 0) {
+-		printf("Something is wrong in nozzle_get_mtu sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Passing empty struct to set_mtu\n");
+-	if (nozzle_set_mtu(NULL, 1500) == 0) {
+-		printf("Something is wrong in nozzle_set_mtu sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (nozzle) {
+-		nozzle_close(nozzle);
+-	}
+-
+-	return err;
+-}
+-
+-static int check_knet_mtu_ipv6(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	char verifycmd[2048];
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *error_string = NULL;
+-
+-	printf("Testing get/set MTU with IPv6 address\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Adding ip: %s/64\n", testipv6_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv6_1, "64");
+-	if (err) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Setting MTU to 1200\n");
+-	if (nozzle_set_mtu(nozzle, 1200) < 0) {
+-		printf("Unable to set MTU to 1200\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-#ifdef KNET_LINUX
+-	if (!err) {
+-#endif
+-#ifdef KNET_BSD
+-	if (err) {
+-#endif
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/64\n", testipv6_2);
+-	err = nozzle_add_ip(nozzle, testipv6_2, "64");
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Restoring MTU to default\n");
+-	if (nozzle_reset_mtu(nozzle) < 0) {
+-		printf("Unable to reset mtu\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_2);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_2);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (nozzle) {
+-		nozzle_close(nozzle);
+-	}
+-
+-	return err;
+-}
+-
+ static int check_knet_mac(void)
+ {
+ 	char device_name[IFNAMSIZ];
+@@ -909,12 +678,6 @@ int main(void)
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+-	if (check_knet_mtu() < 0)
+-		return -1;
+-
+-	if (check_knet_mtu_ipv6() < 0)
+-		return -1;
+-
+ 	if (check_knet_mac() < 0)
+ 		return -1;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0152-libnozzle-add-nozzle_get_mac-nozzle_set_mac-nozzle_r.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0152-libnozzle-add-nozzle_get_mac-nozzle_set_mac-nozzle_r.patch
new file mode 100644
index 000000000..eccf79a7f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0152-libnozzle-add-nozzle_get_mac-nozzle_set_mac-nozzle_r.patch
@@ -0,0 +1,503 @@ 
+From 14bd2be4aa73424a06c475778772444f72ec8946 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 7 Dec 2018 09:41:14 +0100
+Subject: [PATCH] [libnozzle] add nozzle_get_mac / nozzle_set_mac /
+ nozzle_reset_mac tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am          |   8 ++
+ libnozzle/tests/api-test-coverage    |   1 +
+ libnozzle/tests/api_nozzle_get_mac.c | 130 +++++++++++++++++++++
+ libnozzle/tests/api_nozzle_set_mac.c | 162 +++++++++++++++++++++++++++
+ libnozzle/tests/nozzle_test.c        | 119 --------------------
+ 5 files changed, 301 insertions(+), 119 deletions(-)
+ create mode 100644 libnozzle/tests/api_nozzle_get_mac.c
+ create mode 100644 libnozzle/tests/api_nozzle_set_mac.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 17bfc876..a9e2006f 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -27,6 +27,8 @@ check_PROGRAMS		= \
+ 			  api_nozzle_set_down_test \
+ 			  api_nozzle_get_mtu_test \
+ 			  api_nozzle_set_mtu_test \
++			  api_nozzle_get_mac_test \
++			  api_nozzle_set_mac_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -67,6 +69,12 @@ api_nozzle_set_mtu_test_SOURCES = api_nozzle_set_mtu.c \
+ 				  test-common.c \
+ 				  ../internals.c
+ 
++api_nozzle_get_mac_test_SOURCES = api_nozzle_get_mac.c \
++				  test-common.c
++
++api_nozzle_set_mac_test_SOURCES = api_nozzle_set_mac.c \
++				  test-common.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+ 			  ../internals.c
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index 3d73b305..eb7b5efe 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -69,6 +69,7 @@ missing=0
+ 
+ for i in $headerapicalls; do
+ 	[ "$i" = nozzle_reset_mtu ] && i=nozzle_set_mtu # tested together
++	[ "$i" = nozzle_reset_mac ] && i=nozzle_set_mac # tested together
+ 	numapicalls=$((numapicalls + 1))
+ 	if [ -f $srcdir/api_${i}.c ]; then
+ 		found=$((found + 1))
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+new file mode 100644
+index 00000000..9fc878ea
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -0,0 +1,130 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++#include <net/ethernet.h>
++
++#ifdef KNET_LINUX
++#include <linux/if_tun.h>
++#include <netinet/ether.h>
++#endif
++#ifdef KNET_BSD
++#include <net/if_dl.h>
++#endif
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
++	struct ether_addr *cur_mac, *tmp_mac;
++
++	printf("Testing get MAC\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Get current MAC\n");
++
++	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Current MAC: %s\n", current_mac);
++
++	printf("Setting MAC: 00:01:01:01:01:01\n");
++
++	if (nozzle_set_mac(nozzle, "00:01:01:01:01:01") < 0) {
++		printf("Unable to set current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (nozzle_get_mac(nozzle, &temp_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Current MAC: %s\n", temp_mac);
++
++	cur_mac = ether_aton(current_mac);
++	tmp_mac = ether_aton(temp_mac);
++
++	printf("Comparing MAC addresses\n");
++	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
++		printf("Mac addresses are not the same?!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Pass NULL to get_mac (pass1)\n");
++	errno = 0;
++	if ((nozzle_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_get_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to get_mac (pass2)\n");
++	errno = 0;
++	if ((nozzle_get_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_get_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (err_mac) {
++		printf("Something managed to set err_mac!\n");
++		err = -1;
++		free(err_mac);
++	}
++
++	if (current_mac)
++		free(current_mac);
++	if (temp_mac)
++		free(temp_mac);
++
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+new file mode 100644
+index 00000000..25249dc7
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -0,0 +1,162 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++#include <net/ethernet.h>
++
++#ifdef KNET_LINUX
++#include <linux/if_tun.h>
++#include <netinet/ether.h>
++#endif
++#ifdef KNET_BSD
++#include <net/if_dl.h>
++#endif
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	char *original_mac = NULL, *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
++	struct ether_addr *orig_mac, *cur_mac, *tmp_mac;
++
++	printf("Testing set MAC\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Get current MAC\n");
++
++	if (nozzle_get_mac(nozzle, &original_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++	orig_mac = ether_aton(original_mac);
++
++	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Current MAC: %s\n", current_mac);
++
++	printf("Setting MAC: 00:01:01:01:01:01\n");
++
++	if (nozzle_set_mac(nozzle, "00:01:01:01:01:01") < 0) {
++		printf("Unable to set current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (nozzle_get_mac(nozzle, &temp_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Current MAC: %s\n", temp_mac);
++
++	cur_mac = ether_aton(current_mac);
++	tmp_mac = ether_aton(temp_mac);
++
++	printf("Comparing MAC addresses\n");
++	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
++		printf("Mac addresses are not the same?!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing reset_mac\n");
++	if (nozzle_reset_mac(nozzle) < 0) {
++		printf("Unable to reset mac address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (current_mac)
++		free(current_mac);
++
++	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
++		printf("Unable to get current MAC address.\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	cur_mac = ether_aton(current_mac);
++	if (memcmp(cur_mac, orig_mac, sizeof(struct ether_addr))) {
++		printf("Mac addresses are not the same?!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Pass NULL to set_mac (pass1)\n");
++	errno = 0;
++	if ((nozzle_set_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Pass NULL to set_mac (pass2)\n");
++	errno = 0;
++	if ((nozzle_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
++		printf("Something is wrong in nozzle_set_mac sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (err_mac) {
++		printf("Something managed to set err_mac!\n");
++		err = -1;
++		free(err_mac);
++	}
++
++	if (current_mac)
++		free(current_mac);
++	if (temp_mac)
++		free(temp_mac);
++	if (original_mac)
++		free(original_mac);
++
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 9c9df994..8f4e90c5 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -16,15 +16,6 @@
+ #include <stdint.h>
+ #include <limits.h>
+ #include <sys/socket.h>
+-#include <net/ethernet.h>
+-
+-#ifdef KNET_LINUX
+-#include <linux/if_tun.h>
+-#include <netinet/ether.h>
+-#endif
+-#ifdef KNET_BSD
+-#include <net/if_dl.h>
+-#endif
+ 
+ #include "test-common.h"
+ 
+@@ -33,113 +24,6 @@ char testipv4_2[IPBUFSIZE];
+ char testipv6_1[IPBUFSIZE];
+ char testipv6_2[IPBUFSIZE];
+ 
+-static int check_knet_mac(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
+-	struct ether_addr *cur_mac, *tmp_mac;
+-
+-	printf("Testing get/set MAC\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Get current MAC\n");
+-
+-	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
+-		printf("Unable to get current MAC address.\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Current MAC: %s\n", current_mac);
+-
+-	printf("Setting MAC: 00:01:01:01:01:01\n");
+-
+-	if (nozzle_set_mac(nozzle, "00:01:01:01:01:01") < 0) {
+-		printf("Unable to set current MAC address.\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (nozzle_get_mac(nozzle, &temp_mac) < 0) {
+-		printf("Unable to get current MAC address.\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Current MAC: %s\n", temp_mac);
+-
+-	cur_mac = ether_aton(current_mac);
+-	tmp_mac = ether_aton(temp_mac);
+-
+-	printf("Comparing MAC addresses\n");
+-	if (memcmp(cur_mac, tmp_mac, sizeof(struct ether_addr))) {
+-		printf("Mac addresses are not the same?!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("Pass NULL to get_mac (pass1)\n");
+-	errno = 0;
+-	if ((nozzle_get_mac(NULL, &err_mac) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to get_mac (pass2)\n");
+-	errno = 0;
+-	if ((nozzle_get_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_get_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to set_mac (pass1)\n");
+-	errno = 0;
+-	if ((nozzle_set_mac(nozzle, NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to set_mac (pass2)\n");
+-	errno = 0;
+-	if ((nozzle_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (err_mac) {
+-		printf("Something managed to set err_mac!\n");
+-		err = -1;
+-		free(err_mac);
+-	}
+-
+-	if (current_mac)
+-		free(current_mac);
+-	if (temp_mac)
+-		free(temp_mac);
+-
+-	if (nozzle) {
+-		nozzle_close(nozzle);
+-	}
+-
+-	return err;
+-}
+-
+ static int check_nozzle_execute_bin_sh_command(void)
+ {
+ 	int err = 0;
+@@ -678,9 +562,6 @@ int main(void)
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+-	if (check_knet_mac() < 0)
+-		return -1;
+-
+ 	if (check_nozzle_execute_bin_sh_command() < 0)
+ 		return -1;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0153-libnozzle-add-nozzle_get_handle_by_name-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0153-libnozzle-add-nozzle_get_handle_by_name-tests.patch
new file mode 100644
index 000000000..aa9a68aeb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0153-libnozzle-add-nozzle_get_handle_by_name-tests.patch
@@ -0,0 +1,125 @@ 
+From 9471acfb63717db61c1cd3ca6cfeceaaf0b8c57d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 8 Dec 2018 07:08:28 +0100
+Subject: [PATCH] [libnozzle] add nozzle_get_handle_by_name tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am                   |  4 +
+ .../tests/api_nozzle_get_handle_by_name.c     | 85 +++++++++++++++++++
+ 2 files changed, 89 insertions(+)
+ create mode 100644 libnozzle/tests/api_nozzle_get_handle_by_name.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index a9e2006f..50d1f37a 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -29,6 +29,7 @@ check_PROGRAMS		= \
+ 			  api_nozzle_set_mtu_test \
+ 			  api_nozzle_get_mac_test \
+ 			  api_nozzle_set_mac_test \
++			  api_nozzle_get_handle_by_name_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -75,6 +76,9 @@ api_nozzle_get_mac_test_SOURCES = api_nozzle_get_mac.c \
+ api_nozzle_set_mac_test_SOURCES = api_nozzle_set_mac.c \
+ 				  test-common.c
+ 
++api_nozzle_get_handle_by_name_test_SOURCES = api_nozzle_get_handle_by_name.c \
++					     test-common.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+ 			  ../internals.c
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+new file mode 100644
+index 00000000..0abc1bab
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -0,0 +1,85 @@
++/*
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <limits.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[2*IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	nozzle_t nozzle, nozzle_tmp;
++	int err = 0;
++
++	printf("Testing get handle by name\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	nozzle_tmp = nozzle_get_handle_by_name(device_name);
++	if ((!nozzle_tmp) && (errno != ENOENT)) {
++		printf("Unable to get handle by name\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (nozzle != nozzle_tmp) {
++		printf("get handle by name returned wrong handle!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Testing with NULL device name\n");
++
++	nozzle_tmp = nozzle_get_handle_by_name(NULL);
++
++	if ((nozzle_tmp) || (errno != EINVAL)) {
++		printf("get handle by name returned wrong error\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing with device name longer than IFNAMSIZ\n");
++
++	nozzle_tmp = nozzle_get_handle_by_name("antanisupercazzolaunpotapioca");
++	if ((nozzle_tmp) || (errno != EINVAL)) {
++		printf("get handle by name returned wrong error\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0154-libnozzle-add-nozzle_get_name_by_handle-test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0154-libnozzle-add-nozzle_get_name_by_handle-test.patch
new file mode 100644
index 000000000..d1eccbda5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0154-libnozzle-add-nozzle_get_name_by_handle-test.patch
@@ -0,0 +1,114 @@ 
+From 8c3aba1992026f5a379b1e6264ba2fc86c1c2553 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 8 Dec 2018 07:19:22 +0100
+Subject: [PATCH] [libnozzle] add nozzle_get_name_by_handle test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am                   |  4 +
+ .../tests/api_nozzle_get_name_by_handle.c     | 74 +++++++++++++++++++
+ 2 files changed, 78 insertions(+)
+ create mode 100644 libnozzle/tests/api_nozzle_get_name_by_handle.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 50d1f37a..7e535b5e 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -30,6 +30,7 @@ check_PROGRAMS		= \
+ 			  api_nozzle_get_mac_test \
+ 			  api_nozzle_set_mac_test \
+ 			  api_nozzle_get_handle_by_name_test \
++			  api_nozzle_get_name_by_handle_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -79,6 +80,9 @@ api_nozzle_set_mac_test_SOURCES = api_nozzle_set_mac.c \
+ api_nozzle_get_handle_by_name_test_SOURCES = api_nozzle_get_handle_by_name.c \
+ 					     test-common.c
+ 
++api_nozzle_get_name_by_handle_test_SOURCES = api_nozzle_get_name_by_handle.c \
++					     test-common.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+ 			  ../internals.c
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+new file mode 100644
+index 00000000..8e85b832
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -0,0 +1,74 @@
++/*
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <stdio.h>
++#include <string.h>
++#include <errno.h>
++#include <limits.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[2*IFNAMSIZ];
++	const char *device_name_tmp;
++	size_t size = IFNAMSIZ;
++	nozzle_t nozzle;
++	int err = 0;
++
++	printf("Testing get name by handle\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	device_name_tmp = nozzle_get_name_by_handle(nozzle);
++	if ((!device_name_tmp) && (errno != ENOENT)) {
++		printf("Unable to get name by handle\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (strcmp(device_name, device_name_tmp)) {
++		printf("get name by handle returned different names for the same handle\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing error conditions\n");
++
++	device_name_tmp = nozzle_get_name_by_handle(NULL);
++	if ((device_name_tmp) || (errno != ENOENT)) {
++		printf("get name by handle returned wrong error\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0155-libnozzle-add-nozzle_get_fd-test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0155-libnozzle-add-nozzle_get_fd-test.patch
new file mode 100644
index 000000000..05a24623c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0155-libnozzle-add-nozzle_get_fd-test.patch
@@ -0,0 +1,117 @@ 
+From c4cb83f225cff68df8d068931abbbef3b745e961 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 10 Dec 2018 05:39:36 +0100
+Subject: [PATCH] [libnozzle] add nozzle_get_fd test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am         |  4 ++
+ libnozzle/tests/api_nozzle_get_fd.c | 77 +++++++++++++++++++++++++++++
+ 2 files changed, 81 insertions(+)
+ create mode 100644 libnozzle/tests/api_nozzle_get_fd.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 7e535b5e..95594e31 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -31,6 +31,7 @@ check_PROGRAMS		= \
+ 			  api_nozzle_set_mac_test \
+ 			  api_nozzle_get_handle_by_name_test \
+ 			  api_nozzle_get_name_by_handle_test \
++			  api_nozzle_get_fd_test \
+ 			  nozzle_test
+ 
+ noinst_PROGRAMS		= $(check_PROGRAMS)
+@@ -83,6 +84,9 @@ api_nozzle_get_handle_by_name_test_SOURCES = api_nozzle_get_handle_by_name.c \
+ api_nozzle_get_name_by_handle_test_SOURCES = api_nozzle_get_name_by_handle.c \
+ 					     test-common.c
+ 
++api_nozzle_get_fd_test_SOURCES = api_nozzle_get_fd.c \
++				 test-common.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+ 			  ../internals.c
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+new file mode 100644
+index 00000000..36481761
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -0,0 +1,77 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <fcntl.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle;
++	int fd;
++
++	printf("Testing get fd\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	fd = nozzle_get_fd(nozzle);
++	if (fd < 0) {
++		printf("Unable to get fd\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	if (fcntl(fd, F_GETFD) < 0) {
++		printf("Unable to get valid fd\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("Passing empty struct to get_fd\n");
++	if (nozzle_get_fd(NULL) > 0) {
++		printf("Something is wrong in nozzle_get_fd sanity checks\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0156-libnozzle-cleanup-tests-Makefile.am.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0156-libnozzle-cleanup-tests-Makefile.am.patch
new file mode 100644
index 000000000..e4c244e7c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0156-libnozzle-cleanup-tests-Makefile.am.patch
@@ -0,0 +1,49 @@ 
+From 77acd9ae9da689bafd1cda9424063a18155566f7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 10 Dec 2018 05:46:51 +0100
+Subject: [PATCH] [libnozzle] cleanup tests Makefile.am
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 95594e31..60450a48 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -20,7 +20,7 @@ noinst_HEADERS		= \
+ 
+ if BUILD_LIBNOZZLE
+ 
+-check_PROGRAMS		= \
++api_checks		= \
+ 			  api_nozzle_open_test \
+ 			  api_nozzle_close_test \
+ 			  api_nozzle_set_up_test \
+@@ -31,10 +31,23 @@ check_PROGRAMS		= \
+ 			  api_nozzle_set_mac_test \
+ 			  api_nozzle_get_handle_by_name_test \
+ 			  api_nozzle_get_name_by_handle_test \
+-			  api_nozzle_get_fd_test \
++			  api_nozzle_get_fd_test
++
++int_checks		= \
+ 			  nozzle_test
+ 
+-noinst_PROGRAMS		= $(check_PROGRAMS)
++fun_checks		=
++
++benchmarks		=
++
++check_PROGRAMS		= \
++			  $(api_checks) \
++			  $(int_checks) \
++			  $(fun_checks)
++
++noinst_PROGRAMS		= \
++			  $(benchmarks) \
++			  $(check_PROGRAMS)
+ 
+ noinst_SCRIPTS		= \
+ 			  api-test-coverage
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0157-libnozzle-add-internal-execute_bin_sh_command-test.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0157-libnozzle-add-internal-execute_bin_sh_command-test.patch
new file mode 100644
index 000000000..4118393a6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0157-libnozzle-add-internal-execute_bin_sh_command-test.patch
@@ -0,0 +1,281 @@ 
+From 7d32ba3a0bcb7e3a5349627fc203ce12e0500376 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 10 Dec 2018 05:59:53 +0100
+Subject: [PATCH] [libnozzle] add internal execute_bin_sh_command test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am                  |   5 +
+ libnozzle/tests/int_execute_bin_sh_command.c | 124 +++++++++++++++++++
+ libnozzle/tests/nozzle_test.c                |  97 ---------------
+ 3 files changed, 129 insertions(+), 97 deletions(-)
+ create mode 100644 libnozzle/tests/int_execute_bin_sh_command.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 60450a48..4a53ea44 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -34,6 +34,7 @@ api_checks		= \
+ 			  api_nozzle_get_fd_test
+ 
+ int_checks		= \
++			  int_execute_bin_sh_command_test \
+ 			  nozzle_test
+ 
+ fun_checks		=
+@@ -100,6 +101,10 @@ api_nozzle_get_name_by_handle_test_SOURCES = api_nozzle_get_name_by_handle.c \
+ api_nozzle_get_fd_test_SOURCES = api_nozzle_get_fd.c \
+ 				 test-common.c
+ 
++int_execute_bin_sh_command_test_SOURCES = int_execute_bin_sh_command.c \
++					  test-common.c \
++					  ../internals.c
++
+ nozzle_test_SOURCES	= nozzle_test.c \
+ 			  test-common.c \
+ 			  ../internals.c
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+new file mode 100644
+index 00000000..b1b0a42f
+--- /dev/null
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -0,0 +1,124 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	int err = 0;
++	char command[4096];
++	char *error_string = NULL;
++
++	memset(command, 0, sizeof(command));
++
++	printf("Testing execute_bin_sh_command\n");
++
++	printf("command true\n");
++
++	err = execute_bin_sh_command("true", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to execute true ?!?!\n");
++		goto out_clean;
++	}
++
++	printf("command false\n");
++
++	err = execute_bin_sh_command("false", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute false successfully?!?!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("command that outputs to stdout (enforcing redirect)\n");
++
++	err = execute_bin_sh_command("grep -h 2>&1", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute grep -h successfully?!?\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("command that outputs to stderr\n");
++	err = execute_bin_sh_command("grep -h", &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Can we really execute grep -h successfully?!?\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing ERROR conditions\n");
++
++	printf("empty command\n");
++	err = execute_bin_sh_command(NULL, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if ((!err) || (errno != EINVAL)) {
++		printf("execute_bin_sh_command returned incorrect error or incorrect errno!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("empty error\n");
++	err = execute_bin_sh_command("true", NULL);
++	if ((!err) || (errno != EINVAL)) {
++		printf("execute_bin_sh_command returned incorrect error or incorrect errno!\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	err = 0;
++
++out_clean:
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index 8f4e90c5..ad1ab79d 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -24,100 +24,6 @@ char testipv4_2[IPBUFSIZE];
+ char testipv6_1[IPBUFSIZE];
+ char testipv6_2[IPBUFSIZE];
+ 
+-static int check_nozzle_execute_bin_sh_command(void)
+-{
+-	int err = 0;
+-	char command[4096];
+-	char *error_string = NULL;
+-
+-	memset(command, 0, sizeof(command));
+-
+-	printf("Testing execute_bin_sh_command\n");
+-
+-	printf("command true\n");
+-
+-	err = execute_bin_sh_command("true", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to execute true ?!?!\n");
+-		goto out_clean;
+-	}
+-
+-	printf("Testing ERROR conditions\n");
+-
+-	printf("command false\n");
+-
+-	err = execute_bin_sh_command("false", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute false successfully?!?!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("command that outputs to stdout (enforcing redirect)\n");
+-
+-	err = execute_bin_sh_command("grep -h 2>&1", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute grep -h successfully?!?\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("command that outputs to stderr\n");
+-	err = execute_bin_sh_command("grep -h", &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute grep -h successfully?!?\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("empty command\n");
+-	err = execute_bin_sh_command(NULL, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Can we really execute (nil) successfully?!?!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("empty error\n");
+-	err = execute_bin_sh_command("true", NULL);
+-	if (!err) {
+-		printf("Check EINVAL filter for no error_string!\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = 0;
+-
+-out_clean:
+-
+-	return err;
+-}
+-
+ static int check_knet_up_down(void)
+ {
+ 	char verifycmd[1024];
+@@ -562,9 +468,6 @@ int main(void)
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+-	if (check_nozzle_execute_bin_sh_command() < 0)
+-		return -1;
+-
+ 	if (check_knet_up_down() < 0)
+ 		return -1;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0158-libnozzle-add-api_nozzle_run_updown-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0158-libnozzle-add-api_nozzle_run_updown-tests.patch
new file mode 100644
index 000000000..2b348d65a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0158-libnozzle-add-api_nozzle_run_updown-tests.patch
@@ -0,0 +1,912 @@ 
+From 377f991c51550575481b7fc37afa5c487bfdeb6a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 14 Dec 2018 11:59:11 +0100
+Subject: [PATCH] [libnozzle] add api_nozzle_run_updown tests
+
+and cleanup lots of craft around related to the old testing method
+for the same API
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c                         |  11 +-
+ libnozzle/libnozzle.h                         |   3 +-
+ libnozzle/tests/Makefile.am                   |  13 +-
+ libnozzle/tests/api_nozzle_run_updown.c       | 401 ++++++++++++++++++
+ libnozzle/tests/int_execute_bin_sh_command.c  |   3 -
+ ...ronostest => nozzle_run_updown_exit_false} |   0
+ ...kronostest => nozzle_run_updown_exit_true} |   0
+ libnozzle/tests/nozzle_test.c                 | 237 -----------
+ .../tap_updown_bad/post-down.d/kronostest     |  11 -
+ .../tests/tap_updown_bad/pre-up.d/kronostest  |  11 -
+ .../tests/tap_updown_bad/up.d/kronostest      |  11 -
+ .../tap_updown_good/post-down.d/kronostest    |  11 -
+ .../tests/tap_updown_good/pre-up.d/kronostest |  11 -
+ .../tests/tap_updown_good/up.d/kronostest     |  11 -
+ 14 files changed, 421 insertions(+), 313 deletions(-)
+ create mode 100644 libnozzle/tests/api_nozzle_run_updown.c
+ rename libnozzle/tests/{tap_updown_bad/down.d/kronostest => nozzle_run_updown_exit_false} (100%)
+ rename libnozzle/tests/{tap_updown_good/down.d/kronostest => nozzle_run_updown_exit_true} (100%)
+ delete mode 100755 libnozzle/tests/tap_updown_bad/post-down.d/kronostest
+ delete mode 100755 libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
+ delete mode 100755 libnozzle/tests/tap_updown_bad/up.d/kronostest
+ delete mode 100755 libnozzle/tests/tap_updown_good/post-down.d/kronostest
+ delete mode 100755 libnozzle/tests/tap_updown_good/pre-up.d/kronostest
+ delete mode 100755 libnozzle/tests/tap_updown_good/up.d/kronostest
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 05bf0c4b..f04f4161 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -668,7 +668,7 @@ int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
+ 
+ 	memset(command, 0, PATH_MAX);
+ 
+-	snprintf(command, PATH_MAX, "%s%s/%s", nozzle->updownpath, action_str, nozzle->name);
++	snprintf(command, PATH_MAX, "%s/%s/%s", nozzle->updownpath, action_str, nozzle->name);
+ 
+ 	err = stat(command, &sb);
+ 	if (err) {
+@@ -676,8 +676,15 @@ int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
+ 		goto out_clean;
+ 	}
+ 
++	/*
++	 * clear errno from previous calls as there is no errno
++	 * returned from execute_bin_sh_command
++	 */
++	savederrno = 0;
+ 	err = execute_bin_sh_command(command, exec_string);
+-	savederrno = errno;
++	if (err) {
++		err = -2;
++	}
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&config_mutex);
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index df3d9fb5..6baf09ee 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -88,7 +88,8 @@ int nozzle_close(nozzle_t nozzle);
+  *
+  * @return
+  * 0 on success
+- * -1 on error and errno is set.
++ * -1 on error and errno is set (sanity checks and internal calls.
++ * -2 on error from executing the shell scripts, and no errno is set.
+  */
+ 
+ int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string);
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 4a53ea44..64af8388 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -11,8 +11,8 @@ MAINTAINERCLEANFILES	= Makefile.in
+ include $(top_srcdir)/build-aux/check.mk
+ 
+ EXTRA_DIST		= \
+-			  tap_updown_bad \
+-			  tap_updown_good \
++			  nozzle_run_updown_exit_true \
++			  nozzle_run_updown_exit_false \
+ 			  api-test-coverage
+ 
+ noinst_HEADERS		= \
+@@ -31,7 +31,8 @@ api_checks		= \
+ 			  api_nozzle_set_mac_test \
+ 			  api_nozzle_get_handle_by_name_test \
+ 			  api_nozzle_get_name_by_handle_test \
+-			  api_nozzle_get_fd_test
++			  api_nozzle_get_fd_test \
++			  api_nozzle_run_updown_test
+ 
+ int_checks		= \
+ 			  int_execute_bin_sh_command_test \
+@@ -61,7 +62,7 @@ check-api-test-coverage:
+ 	chmod u+x $(top_srcdir)/libnozzle/tests/api-test-coverage
+ 	$(top_srcdir)/libnozzle/tests/api-test-coverage $(top_srcdir) $(top_builddir)
+ 
+-AM_CPPFLAGS		= -I$(top_srcdir)/libnozzle -DABSBUILDDIR=\"$(abs_builddir)\"
++AM_CPPFLAGS		= -I$(top_srcdir)/libnozzle -DABSBUILDDIR=\"$(abs_builddir)\" -DABSSRCDIR=\"$(abs_srcdir)\"
+ AM_CFLAGS		+= $(PTHREAD_CFLAGS) $(libnl_CFLAGS)
+ LIBS			+= $(top_builddir)/libnozzle/libnozzle.la $(PTHREAD_LIBS) $(libnl_LIBS)
+ 
+@@ -101,6 +102,10 @@ api_nozzle_get_name_by_handle_test_SOURCES = api_nozzle_get_name_by_handle.c \
+ api_nozzle_get_fd_test_SOURCES = api_nozzle_get_fd.c \
+ 				 test-common.c
+ 
++api_nozzle_run_updown_test_SOURCES = api_nozzle_run_updown.c \
++				     test-common.c \
++				     ../internals.c
++
+ int_execute_bin_sh_command_test_SOURCES = int_execute_bin_sh_command.c \
+ 					  test-common.c \
+ 					  ../internals.c
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+new file mode 100644
+index 00000000..89bf9095
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -0,0 +1,401 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++#include <sys/stat.h>
++#include <sys/types.h>
++
++#include "test-common.h"
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err=0;
++	nozzle_t nozzle = NULL;
++	char *error_string = NULL;
++	char *tmpdir = NULL;
++	char tmpdirsrc[PATH_MAX];
++	char tmpstr[PATH_MAX*2];
++	char srcfile[PATH_MAX];
++	char dstfile[PATH_MAX];
++
++	/*
++	 * create a tmp dir for storing up/down scripts.
++	 * we cannot create symlinks src dir
++	 */
++	strcpy(tmpdirsrc, ABSBUILDDIR "/nozzle_test_XXXXXX");
++
++	tmpdir = mkdtemp(tmpdirsrc);
++	if (!tmpdir) {
++		printf("Unable to create temporary directory %s for testing: %s\n", tmpdirsrc, strerror(errno));
++		return -1;
++	}
++
++	printf("Created temporary test dir: %s\n", tmpdir);
++
++	printf("Populating test dir...\n");
++
++	snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/pre-up.d", tmpdir);
++	if (mkdir(tmpstr, 0700) < 0) {
++		printf("Unable to create %s/pre-up.d: %s", tmpdir, strerror(errno));
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/up.d", tmpdir);
++	if (mkdir(tmpstr, 0700) < 0) {
++		printf("Unable to create %s/up.d: %s", tmpdir, strerror(errno));
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/down.d", tmpdir);
++	if (mkdir(tmpstr, 0700) < 0) {
++		printf("Unable to create %s/down.d: %s", tmpdir, strerror(errno));
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(tmpstr, sizeof(tmpstr) - 1, "%s/post-down.d", tmpdir);
++	if (mkdir(tmpstr, 0700) < 0) {
++		printf("Unable to create %s/post-down.d: %s", tmpdir, strerror(errno));
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Init nozzle device with no path\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		err = -1;
++		goto out_clean;
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_run_updown sanity check failed\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	nozzle_close(nozzle);
++
++	printf("Init nozzle device with path\n");
++
++	memset(device_name, 0, size);
++	nozzle = nozzle_open(device_name, size, tmpdir);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing invalid nozzle handle\n");
++
++	err = nozzle_run_updown(NULL, NOZZLE_POSTDOWN, &error_string);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_run_updown sanity check failed\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing invalid action\n");
++
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN + 1, &error_string);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_run_updown sanity check failed\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing invalid error string\n");
++
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN + 1, NULL);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_run_updown sanity check failed\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing interface pre-up/up/down/post-down (no scripts installed)\n");
++
++	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
++	if (!err) {
++		printf("nozzle_run_updown failed to detect lack of script in pre-up.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
++	if (!err) {
++		printf("nozzle_run_updown failed to detect lack of script in up.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
++	if (!err) {
++		printf("nozzle_run_updown failed to detect lack of script in down.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
++	if (!err) {
++		printf("nozzle_run_updown failed to detect lack of script in post-down.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	printf("Populating test dir with fail scripts\n");
++
++	snprintf(srcfile, sizeof(srcfile) - 1, "%s/nozzle_run_updown_exit_false", ABSSRCDIR);
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/pre-up.d/%s", tmpdir, device_name);
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/up.d/%s", tmpdir, device_name);
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/down.d/%s", tmpdir, device_name);
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/post-down.d/%s", tmpdir, device_name);
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing interface pre-up/up/down/post-down (FAIL scripts installed)\n");
++
++	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
++	if (err != -2) {
++		printf("nozzle_run_updown failed to detect script failure in pre-up.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
++	if (err != -2) {
++		printf("nozzle_run_updown failed to detect script failure in up.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
++	if (err != -2) {
++		printf("nozzle_run_updown failed to detect script failure in down.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
++	if (err != -2) {
++		printf("nozzle_run_updown failed to detect script failure in post-down.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	printf("Populating test dir with true scripts\n");
++
++	snprintf(srcfile, sizeof(srcfile) - 1, "%s/nozzle_run_updown_exit_true", ABSSRCDIR);
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/pre-up.d/%s", tmpdir, device_name);
++	if (unlink(dstfile) < 0) {
++		printf("unable to remove old symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/up.d/%s", tmpdir, device_name);
++	if (unlink(dstfile) < 0) {
++		printf("unable to remove old symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/down.d/%s", tmpdir, device_name);
++	if (unlink(dstfile) < 0) {
++		printf("unable to remove old symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	snprintf(dstfile, sizeof(dstfile) - 1, "%s/post-down.d/%s", tmpdir, device_name);
++	if (unlink(dstfile) < 0) {
++		printf("unable to remove old symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++	if (link(srcfile, dstfile) < 0) {
++		printf("unable to create symlink\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing interface pre-up/up/down/post-down (TRUE scripts installed)\n");
++
++	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
++	if (err) {
++		printf("nozzle_run_updown failed to execute true script in pre-up.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
++	if (err) {
++		printf("nozzle_run_updown failed to execute true script in up.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
++	if (err) {
++		printf("nozzle_run_updown failed to execite true script in down.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
++	if (err) {
++		printf("nozzle_run_updown failed to execute true script in post-down.d\n");
++		err = -1;
++		goto out_clean;
++	} else {
++		if (error_string) {
++			free(error_string);
++			error_string = NULL;
++		}
++	}
++
++
++out_clean:
++	if (tmpdir) {
++		snprintf(tmpstr, sizeof(tmpstr) - 1, "rm -rf %s", tmpdir);
++		printf("Removing temporary dir: %s\n", tmpstr);
++		err = execute_bin_sh_command(tmpstr, &error_string);
++		if (err) {
++			printf("Error removing directory: %s\n", error_string);
++		}
++		if (error_string) {
++			free(error_string);
++		}
++	}
++	if (nozzle) {
++		nozzle_close(nozzle);
++	}
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index b1b0a42f..c5a7e5d4 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -22,11 +22,8 @@
+ static int test(void)
+ {
+ 	int err = 0;
+-	char command[4096];
+ 	char *error_string = NULL;
+ 
+-	memset(command, 0, sizeof(command));
+-
+ 	printf("Testing execute_bin_sh_command\n");
+ 
+ 	printf("command true\n");
+diff --git a/libnozzle/tests/tap_updown_bad/down.d/kronostest b/libnozzle/tests/nozzle_run_updown_exit_false
+similarity index 100%
+rename from libnozzle/tests/tap_updown_bad/down.d/kronostest
+rename to libnozzle/tests/nozzle_run_updown_exit_false
+diff --git a/libnozzle/tests/tap_updown_good/down.d/kronostest b/libnozzle/tests/nozzle_run_updown_exit_true
+similarity index 100%
+rename from libnozzle/tests/tap_updown_good/down.d/kronostest
+rename to libnozzle/tests/nozzle_run_updown_exit_true
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+index ad1ab79d..475035d0 100644
+--- a/libnozzle/tests/nozzle_test.c
++++ b/libnozzle/tests/nozzle_test.c
+@@ -24,240 +24,6 @@ char testipv4_2[IPBUFSIZE];
+ char testipv6_1[IPBUFSIZE];
+ char testipv6_2[IPBUFSIZE];
+ 
+-static int check_knet_up_down(void)
+-{
+-	char verifycmd[1024];
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	int err=0;
+-	nozzle_t nozzle;
+-	char *error_string = NULL;
+-
+-	printf("Testing interface up/down\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Put the interface up\n");
+-
+-	err = nozzle_set_up(nozzle);
+-	if (err < 0) {
+-		printf("Unable to set interface up\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", nozzle->name);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", nozzle->name);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err < 0) {
+-		printf("Unable to verify inteface UP\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Put the interface down\n");
+-
+-	err = nozzle_set_down(nozzle);
+-	if (err < 0) {
+-		printf("Unable to put the interface down\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q UP", nozzle->name);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q UP", nozzle->name);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify inteface DOWN\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	nozzle_close(nozzle);
+-
+-	printf("Testing interface pre-up/up/down/post-down (exec errors)\n");
+-
+-	memset(device_name, 0, size);
+-	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_bad");
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Put the interface up\n");
+-
+-	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_PREUP error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("preup output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	err = nozzle_set_up(nozzle);
+-	if (err < 0) {
+-		printf("Unable to put the interface up\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_UP error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("up output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-
+-	printf("Put the interface down\n");
+-
+-	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("down output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	err = nozzle_set_down(nozzle);
+-	if (err < 0) {
+-		printf("Unable to put the interface down\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("postdown output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-
+-	nozzle_close(nozzle);
+-
+-	printf("Testing interface pre-up/up/down/post-down\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, ABSBUILDDIR "/nozzle_updown_good");
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Put the interface up\n");
+-
+-	err = nozzle_run_updown(nozzle, NOZZLE_PREUP, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_PREUP error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("preup output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	err = nozzle_set_up(nozzle);
+-	if (err < 0) {
+-		printf("Unable to put the interface up\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_UP, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_UP error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("up output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-
+-	printf("Put the interface down\n");
+-
+-	err = nozzle_run_updown(nozzle, NOZZLE_DOWN, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_DOWN error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("down output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	err = nozzle_set_down(nozzle);
+-	if (err < 0) {
+-		printf("Unable to put the interface down\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-	err = nozzle_run_updown(nozzle, NOZZLE_POSTDOWN, &error_string);
+-	if (err) {
+-		printf("nozzle_run_updown NOZZLE_POSTDOWN error: %s\n", strerror(errno));
+-	}
+-	if (error_string) {
+-		printf("postdown output: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-
+-	nozzle_close(nozzle);
+-
+-	printf("Test ERROR conditions\n");
+-
+-	printf("Pass NULL to nozzle set_up\n");
+-	err = 0;
+-	errno = 0;
+-	if ((nozzle_set_up(NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_up sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	printf("Pass NULL to nozzle set_down\n");
+-	errno = 0;
+-	if ((nozzle_set_down(NULL) >= 0) || (errno != EINVAL)) {
+-		printf("Something is wrong in nozzle_set_down sanity checks\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	nozzle_close(nozzle);
+-
+-	return err;
+-}
+-
+ static int check_knet_set_del_ip(void)
+ {
+ 	char device_name[IFNAMSIZ];
+@@ -468,9 +234,6 @@ int main(void)
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+-	if (check_knet_up_down() < 0)
+-		return -1;
+-
+ 	if (check_knet_set_del_ip() < 0)
+ 		return -1;
+ 
+diff --git a/libnozzle/tests/tap_updown_bad/post-down.d/kronostest b/libnozzle/tests/tap_updown_bad/post-down.d/kronostest
+deleted file mode 100755
+index 721ecb6e..00000000
+--- a/libnozzle/tests/tap_updown_bad/post-down.d/kronostest
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-exit 1
+diff --git a/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest b/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
+deleted file mode 100755
+index 721ecb6e..00000000
+--- a/libnozzle/tests/tap_updown_bad/pre-up.d/kronostest
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-exit 1
+diff --git a/libnozzle/tests/tap_updown_bad/up.d/kronostest b/libnozzle/tests/tap_updown_bad/up.d/kronostest
+deleted file mode 100755
+index 721ecb6e..00000000
+--- a/libnozzle/tests/tap_updown_bad/up.d/kronostest
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-exit 1
+diff --git a/libnozzle/tests/tap_updown_good/post-down.d/kronostest b/libnozzle/tests/tap_updown_good/post-down.d/kronostest
+deleted file mode 100755
+index 6e28da18..00000000
+--- a/libnozzle/tests/tap_updown_good/post-down.d/kronostest
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-exit 0
+diff --git a/libnozzle/tests/tap_updown_good/pre-up.d/kronostest b/libnozzle/tests/tap_updown_good/pre-up.d/kronostest
+deleted file mode 100755
+index 6e28da18..00000000
+--- a/libnozzle/tests/tap_updown_good/pre-up.d/kronostest
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-exit 0
+diff --git a/libnozzle/tests/tap_updown_good/up.d/kronostest b/libnozzle/tests/tap_updown_good/up.d/kronostest
+deleted file mode 100755
+index 6e28da18..00000000
+--- a/libnozzle/tests/tap_updown_good/up.d/kronostest
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-exit 0
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0159-libnozzle-add-nozzle_add_ip-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0159-libnozzle-add-nozzle_add_ip-tests.patch
new file mode 100644
index 000000000..caa044ed7
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0159-libnozzle-add-nozzle_add_ip-tests.patch
@@ -0,0 +1,336 @@ 
+From b4adc17559bb6050bf3dff9d3eb868109a2258d0 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 14 Dec 2018 17:35:50 +0100
+Subject: [PATCH] [libnozzle] add nozzle_add_ip tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am         |   7 +-
+ libnozzle/tests/api_nozzle_add_ip.c | 293 ++++++++++++++++++++++++++++
+ 2 files changed, 299 insertions(+), 1 deletion(-)
+ create mode 100644 libnozzle/tests/api_nozzle_add_ip.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 64af8388..ba050002 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -32,7 +32,8 @@ api_checks		= \
+ 			  api_nozzle_get_handle_by_name_test \
+ 			  api_nozzle_get_name_by_handle_test \
+ 			  api_nozzle_get_fd_test \
+-			  api_nozzle_run_updown_test
++			  api_nozzle_run_updown_test \
++			  api_nozzle_add_ip_test
+ 
+ int_checks		= \
+ 			  int_execute_bin_sh_command_test \
+@@ -106,6 +107,10 @@ api_nozzle_run_updown_test_SOURCES = api_nozzle_run_updown.c \
+ 				     test-common.c \
+ 				     ../internals.c
+ 
++api_nozzle_add_ip_test_SOURCES = api_nozzle_add_ip.c \
++				 test-common.c \
++				 ../internals.c
++
+ int_execute_bin_sh_command_test_SOURCES = int_execute_bin_sh_command.c \
+ 					  test-common.c \
+ 					  ../internals.c
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+new file mode 100644
+index 00000000..af8c5f03
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -0,0 +1,293 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++
++#include "test-common.h"
++
++char testipv4_1[IPBUFSIZE];
++char testipv4_2[IPBUFSIZE];
++char testipv6_1[IPBUFSIZE];
++char testipv6_2[IPBUFSIZE];
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	char verifycmd[2048];
++	int err = 0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++
++	printf("Testing interface add ip\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Testing invalid nozzle handle\n");
++	err = nozzle_add_ip(NULL, testipv4_1, "24");
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_add_ip accepted invalid nozzle handle\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing empty ip address\n");
++	err = nozzle_add_ip(nozzle, NULL, "24");
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_add_ip accepted invalid ip address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++
++	printf("Testing empty netmask\n");
++	err = nozzle_add_ip(nozzle, testipv4_1, NULL);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_add_ip accepted invalid netmask\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_2);
++
++	err = nozzle_add_ip(nozzle, testipv4_2, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding duplicate ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to find IP address in libnozzle db\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Checking ip: %s/24\n", testipv4_1);
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Checking ip: %s/24\n", testipv4_2);
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_2);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_2);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24\n", testipv4_1);
++
++	err = nozzle_del_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24\n", testipv4_2);
++
++	err = nozzle_del_ip(nozzle, testipv4_2, "24");
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64\n", testipv6_1);
++
++	err = nozzle_del_ip(nozzle, testipv6_1, "64");
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing adding an IPv6 address with mtu < 1280 and restore\n");
++	printf("Lowering interface MTU\n");
++
++	err = nozzle_set_mtu(nozzle, 1200);
++	if (err) {
++		printf("Unable to set MTU to 1200\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Resetting MTU\n");
++
++	err = nozzle_reset_mtu(nozzle);
++	if (err) {
++		printf("Unable to set reset MTU\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64\n", testipv6_1);
++
++	err = nozzle_del_ip(nozzle, testipv6_1, "64");
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle);
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0160-libnozzle-fix-del_ip-removal-of-Ipv6-addresses-when-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0160-libnozzle-fix-del_ip-removal-of-Ipv6-addresses-when-.patch
new file mode 100644
index 000000000..cd47090cb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0160-libnozzle-fix-del_ip-removal-of-Ipv6-addresses-when-.patch
@@ -0,0 +1,36 @@ 
+From 2b8bdaf260da5b3e2ef5190f8ee41fa1baae9cb0 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 14 Dec 2018 17:55:20 +0100
+Subject: [PATCH] [libnozzle] fix del_ip removal of Ipv6 addresses when MTU <
+ 1280
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index f04f4161..7c5ae6ec 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1150,8 +1150,18 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix)
+ 		goto out_clean;
+ 	}
+ 
+-	err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, 0);
+-	savederrno = errno;
++	/*
++	 * if user asks for an IPv6 address, but MTU < 1280
++	 * the IP might not be configured on the interface and we only need to
++	 * remove it from our internal database
++	 */
++	if ((ip->domain == AF_INET6) && (get_iface_mtu(nozzle) < 1280)) {
++		err = 0;
++	} else {
++		err = _set_ip(nozzle, IP_DEL, ipaddr, prefix, 0);
++		savederrno = errno;
++	}
++
+ 	if (!err) {
+ 		if (ip == ip_prev) {
+ 			nozzle->ip = ip->next;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0161-libnozzle-add-nozzle_del_ip-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0161-libnozzle-add-nozzle_del_ip-tests.patch
new file mode 100644
index 000000000..d0c26abbc
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0161-libnozzle-add-nozzle_del_ip-tests.patch
@@ -0,0 +1,309 @@ 
+From e6015d1a1a1cf49684f424f9376397c911729116 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 14 Dec 2018 17:55:59 +0100
+Subject: [PATCH] [libnozzle] add nozzle_del_ip tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am         |   7 +-
+ libnozzle/tests/api_nozzle_del_ip.c | 266 ++++++++++++++++++++++++++++
+ 2 files changed, 272 insertions(+), 1 deletion(-)
+ create mode 100644 libnozzle/tests/api_nozzle_del_ip.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index ba050002..7c8b256e 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -33,7 +33,8 @@ api_checks		= \
+ 			  api_nozzle_get_name_by_handle_test \
+ 			  api_nozzle_get_fd_test \
+ 			  api_nozzle_run_updown_test \
+-			  api_nozzle_add_ip_test
++			  api_nozzle_add_ip_test \
++			  api_nozzle_del_ip_test
+ 
+ int_checks		= \
+ 			  int_execute_bin_sh_command_test \
+@@ -111,6 +112,10 @@ api_nozzle_add_ip_test_SOURCES = api_nozzle_add_ip.c \
+ 				 test-common.c \
+ 				 ../internals.c
+ 
++api_nozzle_del_ip_test_SOURCES = api_nozzle_del_ip.c \
++				 test-common.c \
++				 ../internals.c
++
+ int_execute_bin_sh_command_test_SOURCES = int_execute_bin_sh_command.c \
+ 					  test-common.c \
+ 					  ../internals.c
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+new file mode 100644
+index 00000000..31e26c22
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -0,0 +1,266 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++
++#include "test-common.h"
++
++char testipv4_1[IPBUFSIZE];
++char testipv4_2[IPBUFSIZE];
++char testipv6_1[IPBUFSIZE];
++char testipv6_2[IPBUFSIZE];
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	char verifycmd[2048];
++	int err = 0;
++	nozzle_t nozzle;
++	char *error_string = NULL;
++
++	printf("Testing interface del ip\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Testing invalid nozzle handle\n");
++	err = nozzle_del_ip(NULL, testipv4_1, "24");
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_del_ip accepted invalid nozzle handle\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing empty ip address\n");
++	err = nozzle_del_ip(nozzle, NULL, "24");
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_del_ip accepted invalid ip address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++
++	printf("Testing empty netmask\n");
++	err = nozzle_del_ip(nozzle, testipv4_1, NULL);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_del_ip accepted invalid netmask\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Checking ip: %s/24\n", testipv4_1);
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24\n", testipv4_1);
++
++	err = nozzle_del_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Checking ip: %s/24\n", testipv4_1);
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24 again\n", testipv4_1);
++
++	err = nozzle_del_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64\n", testipv6_1);
++
++	err = nozzle_del_ip(nozzle, testipv6_1, "64");
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing deleting an IPv6 address with mtu < 1280 (in db, not on interface)\n");
++	printf("Lowering interface MTU\n");
++
++	err = nozzle_set_mtu(nozzle, 1200);
++	if (err) {
++		printf("Unable to set MTU to 1200\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	memset(verifycmd, 0, sizeof(verifycmd));
++	snprintf(verifycmd, sizeof(verifycmd)-1,
++#ifdef KNET_LINUX
++		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
++#endif
++#ifdef KNET_BSD
++		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
++#endif
++	err = execute_bin_sh_command(verifycmd, &error_string);
++	if (error_string) {
++		printf("Error string: %s\n", error_string);
++		free(error_string);
++		error_string = NULL;
++	}
++	if (!err) {
++		printf("Unable to verify IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64 with low mtu\n", testipv6_1);
++
++	err = nozzle_del_ip(nozzle, testipv6_1, "64");
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle);
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0162-libnozzle-add-nozzle_get_ips-tests-and-kill-nozzle_t.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0162-libnozzle-add-nozzle_get_ips-tests-and-kill-nozzle_t.patch
new file mode 100644
index 000000000..7c8d93df7
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0162-libnozzle-add-nozzle_get_ips-tests-and-kill-nozzle_t.patch
@@ -0,0 +1,484 @@ 
+From c8cc42d9a7f95c10c0b3dfc84003bf0c7aa0abb9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 15 Dec 2018 05:05:59 +0100
+Subject: [PATCH] [libnozzle] add nozzle_get_ips tests and kill nozzle_test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/Makefile.am          |  14 +-
+ libnozzle/tests/api_nozzle_get_ips.c | 182 ++++++++++++++++++++
+ libnozzle/tests/nozzle_test.c        | 241 ---------------------------
+ 3 files changed, 188 insertions(+), 249 deletions(-)
+ create mode 100644 libnozzle/tests/api_nozzle_get_ips.c
+ delete mode 100644 libnozzle/tests/nozzle_test.c
+
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 7c8b256e..9a732d52 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -34,11 +34,11 @@ api_checks		= \
+ 			  api_nozzle_get_fd_test \
+ 			  api_nozzle_run_updown_test \
+ 			  api_nozzle_add_ip_test \
+-			  api_nozzle_del_ip_test
++			  api_nozzle_del_ip_test \
++			  api_nozzle_get_ips_test
+ 
+ int_checks		= \
+-			  int_execute_bin_sh_command_test \
+-			  nozzle_test
++			  int_execute_bin_sh_command_test
+ 
+ fun_checks		=
+ 
+@@ -116,12 +116,10 @@ api_nozzle_del_ip_test_SOURCES = api_nozzle_del_ip.c \
+ 				 test-common.c \
+ 				 ../internals.c
+ 
++api_nozzle_get_ips_test_SOURCES = api_nozzle_get_ips.c \
++				  test-common.c
++
+ int_execute_bin_sh_command_test_SOURCES = int_execute_bin_sh_command.c \
+ 					  test-common.c \
+ 					  ../internals.c
+-
+-nozzle_test_SOURCES	= nozzle_test.c \
+-			  test-common.c \
+-			  ../internals.c
+-
+ endif
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+new file mode 100644
+index 00000000..e29885e6
+--- /dev/null
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -0,0 +1,182 @@
++/*
++ * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <string.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <unistd.h>
++#include <errno.h>
++#include <stdint.h>
++#include <limits.h>
++#include <sys/socket.h>
++
++#include "test-common.h"
++
++char testipv4_1[IPBUFSIZE];
++char testipv4_2[IPBUFSIZE];
++char testipv6_1[IPBUFSIZE];
++char testipv6_2[IPBUFSIZE];
++
++static int test(void)
++{
++	char device_name[IFNAMSIZ];
++	size_t size = IFNAMSIZ;
++	int err = 0;
++	nozzle_t nozzle;
++	struct nozzle_ip *ip_list = NULL, *ip_list_tmp = NULL;
++	int ip_list_entries = 0, ipv4_list_entries = 0, ipv6_list_entries = 0;
++
++	printf("Testing get ips\n");
++
++	memset(device_name, 0, size);
++
++	nozzle = nozzle_open(device_name, size, NULL);
++	if (!nozzle) {
++		printf("Unable to init %s\n", device_name);
++		return -1;
++	}
++
++	printf("Testing error conditions\n");
++
++	printf("Testing invalid nozzle\n");
++	err = nozzle_get_ips(NULL, &ip_list);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_get_ips accepted invalid nozzle\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Testing invalid ip list\n");
++	err = nozzle_get_ips(nozzle, NULL);
++	if ((!err) || (errno != EINVAL)) {
++		printf("nozzle_get_ips accepted invalid ip list\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_1);
++
++	err = nozzle_add_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/24\n", testipv4_2);
++
++	err = nozzle_add_ip(nozzle, testipv4_2, "24");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_1);
++
++	err = nozzle_add_ip(nozzle, testipv6_1, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Adding ip: %s/64\n", testipv6_2);
++
++	err = nozzle_add_ip(nozzle, testipv6_2, "64");
++	if (err < 0) {
++		printf("Unable to assign IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Get ip list from libnozzle:\n");
++
++	if (nozzle_get_ips(nozzle, &ip_list) < 0) {
++		printf("Not enough mem?\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	ip_list_tmp = ip_list;
++	ip_list_entries = 0;
++
++	while(ip_list_tmp) {
++		ip_list_entries++;
++		if (ip_list_tmp->domain == AF_INET) {
++			ipv4_list_entries++;
++		} else {
++			ipv6_list_entries++;
++		}
++		printf("Found IP %s %s in libnozzle db\n", ip_list_tmp->ipaddr, ip_list_tmp->prefix);
++		ip_list_tmp = ip_list_tmp->next;
++	}
++
++	if ((ip_list_entries != 4) ||
++	    (ipv4_list_entries != 2) ||
++	    (ipv6_list_entries != 2)) {
++		printf("Didn't get enough ip back from libnozzle?\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24\n", testipv4_1);
++
++	err = nozzle_del_ip(nozzle, testipv4_1, "24");
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/24\n", testipv4_2);
++
++	err = nozzle_del_ip(nozzle, testipv4_2, "24");
++	if (err < 0) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64\n", testipv6_1);
++
++	err = nozzle_del_ip(nozzle, testipv6_1, "64");
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++	printf("Deleting ip: %s/64\n", testipv6_2);
++
++	err = nozzle_del_ip(nozzle, testipv6_2, "64");
++	if (err) {
++		printf("Unable to delete IP address\n");
++		err = -1;
++		goto out_clean;
++	}
++
++out_clean:
++	nozzle_close(nozzle);
++
++	return err;
++}
++
++int main(void)
++{
++	need_root();
++
++	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
++
++	if (test() < 0)
++		return FAIL;
++
++	return PASS;
++}
+diff --git a/libnozzle/tests/nozzle_test.c b/libnozzle/tests/nozzle_test.c
+deleted file mode 100644
+index 475035d0..00000000
+--- a/libnozzle/tests/nozzle_test.c
++++ /dev/null
+@@ -1,241 +0,0 @@
+-/*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <string.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <unistd.h>
+-#include <errno.h>
+-#include <stdint.h>
+-#include <limits.h>
+-#include <sys/socket.h>
+-
+-#include "test-common.h"
+-
+-char testipv4_1[IPBUFSIZE];
+-char testipv4_2[IPBUFSIZE];
+-char testipv6_1[IPBUFSIZE];
+-char testipv6_2[IPBUFSIZE];
+-
+-static int check_knet_set_del_ip(void)
+-{
+-	char device_name[IFNAMSIZ];
+-	size_t size = IFNAMSIZ;
+-	char verifycmd[2048];
+-	int err = 0;
+-	nozzle_t nozzle;
+-	struct nozzle_ip *ip_list = NULL, *ip_list_tmp = NULL;
+-	int ip_list_entries = 0;
+-	char *error_string = NULL;
+-
+-	printf("Testing interface add/remove ip\n");
+-
+-	memset(device_name, 0, size);
+-
+-	nozzle = nozzle_open(device_name, size, NULL);
+-	if (!nozzle) {
+-		printf("Unable to init %s\n", device_name);
+-		return -1;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24");
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/24\n", testipv4_2);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_2, "24");
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding duplicate ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv4_1, "24");
+-	if (err < 0) {
+-		printf("Unable to find IP address in libnozzle db\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Checking ip: %s/24\n", testipv4_1);
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Get ip list from libnozzle:\n");
+-
+-	if (nozzle_get_ips(nozzle, &ip_list) < 0) {
+-		printf("Not enough mem?\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	ip_list_tmp = ip_list;
+-	ip_list_entries = 0;
+-
+-	while(ip_list_tmp) {
+-		ip_list_entries++;
+-		printf("Found IP %s %s in libnozzle db\n", ip_list_tmp->ipaddr, ip_list_tmp->prefix);
+-		ip_list_tmp = ip_list_tmp->next;
+-	}
+-
+-	if (ip_list_entries != 2) {
+-		printf("Didn't get enough ip back from libnozzle?\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_del_ip(nozzle, testipv4_1, "24");
+-	if (err < 0) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting ip: %s/24\n", testipv4_2);
+-
+-	err = nozzle_del_ip(nozzle, testipv4_2, "24");
+-	if (err < 0) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting again ip: %s/24\n", testipv4_1);
+-
+-	err = nozzle_del_ip(nozzle, testipv4_1, "24");
+-	if (err < 0) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/24", nozzle->name, testipv4_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv4_1);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Adding ip: %s/64\n", testipv6_1);
+-
+-	err = nozzle_add_ip(nozzle, testipv6_1, "64");
+-	if (err < 0) {
+-		printf("Unable to assign IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	printf("Deleting ip: %s/64\n", testipv6_1);
+-
+-	err = nozzle_del_ip(nozzle, testipv6_1, "64");
+-	if (err) {
+-		printf("Unable to delete IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-	memset(verifycmd, 0, sizeof(verifycmd));
+-	snprintf(verifycmd, sizeof(verifycmd)-1,
+-#ifdef KNET_LINUX
+-		 "ip addr show dev %s | grep -q %s/64", nozzle->name, testipv6_1);
+-#endif
+-#ifdef KNET_BSD
+-		 "ifconfig %s | grep -q %s", nozzle->name, testipv6_1);
+-#endif
+-	err = execute_bin_sh_command(verifycmd, &error_string);
+-	if (error_string) {
+-		printf("Error string: %s\n", error_string);
+-		free(error_string);
+-		error_string = NULL;
+-	}
+-	if (!err) {
+-		printf("Unable to verify IP address\n");
+-		err=-1;
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	nozzle_close(nozzle);
+-
+-	return err;
+-}
+-
+-int main(void)
+-{
+-	need_root();
+-
+-	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+-
+-	if (check_knet_set_del_ip() < 0)
+-		return -1;
+-
+-	return 0;
+-}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0163-global-fix-copyright-across.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0163-global-fix-copyright-across.patch
new file mode 100644
index 000000000..3c17f5a0f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0163-global-fix-copyright-across.patch
@@ -0,0 +1,141 @@ 
+From 25a982f29ec3df013f1976a4ef4ed7203639399d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 15 Dec 2018 05:06:46 +0100
+Subject: [PATCH] [global] fix copyright across
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api_nozzle_close.c           | 2 +-
+ libnozzle/tests/api_nozzle_get_fd.c          | 2 +-
+ libnozzle/tests/api_nozzle_get_ips.c         | 2 +-
+ libnozzle/tests/api_nozzle_get_mac.c         | 2 +-
+ libnozzle/tests/api_nozzle_get_mtu.c         | 2 +-
+ libnozzle/tests/api_nozzle_run_updown.c      | 2 +-
+ libnozzle/tests/api_nozzle_set_down.c        | 2 +-
+ libnozzle/tests/api_nozzle_set_mac.c         | 2 +-
+ libnozzle/tests/api_nozzle_set_mtu.c         | 2 +-
+ libnozzle/tests/api_nozzle_set_up.c          | 2 +-
+ libnozzle/tests/int_execute_bin_sh_command.c | 2 +-
+ 11 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index b954ec77..129b98c7 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index 36481761..d32da6aa 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index e29885e6..ce31cec5 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index 9fc878ea..81f31427 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 2c34ca39..2db1a527 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index 89bf9095..ad81c457 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index 3921772b..f477a4b2 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index 25249dc7..d7ea405d 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index 510b2d46..b26df345 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index 258270d2..687e6b6b 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index c5a7e5d4..a6a133ff 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0164-libnozzle-fix-variable-assignment-order.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0164-libnozzle-fix-variable-assignment-order.patch
new file mode 100644
index 000000000..ddfc4cd9c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0164-libnozzle-fix-variable-assignment-order.patch
@@ -0,0 +1,23 @@ 
+From ce49b0b68294381af7939d5237e2dcc1be5fe290 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 15 Dec 2018 12:20:57 +0100
+Subject: [PATCH] [libnozzle] fix variable assignment order
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 7c5ae6ec..903f36ae 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -804,7 +804,7 @@ int nozzle_get_mtu(const nozzle_t nozzle)
+ 
+ out_clean:
+ 	pthread_mutex_unlock(&config_mutex);
+-	savederrno = errno;
++	errno = savederrno;
+ 	return err;
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0165-Use-the-kernel-struct-size-for-SCTP-event-subscripti.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0165-Use-the-kernel-struct-size-for-SCTP-event-subscripti.patch
new file mode 100644
index 000000000..2928c90a4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0165-Use-the-kernel-struct-size-for-SCTP-event-subscripti.patch
@@ -0,0 +1,132 @@ 
+From 2fe1346a521f203728dfa4d1158788d57322e510 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 17 Dec 2018 12:21:47 +0100
+Subject: [PATCH] Use the kernel struct size for SCTP event subscription
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/transport_sctp.c | 81 +++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 71 insertions(+), 10 deletions(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 7a635338..46c6c102 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -37,6 +37,8 @@ typedef struct sctp_handle_info {
+ 	int listensockfd[2];
+ 	pthread_t connect_thread;
+ 	pthread_t listen_thread;
++	socklen_t event_subscribe_kernel_size;
++	char *event_subscribe_buffer;
+ } sctp_handle_info_t;
+ 
+ /*
+@@ -130,16 +132,11 @@ exit_error:
+ static int _enable_sctp_notifications(knet_handle_t knet_h, int sock, const char *type)
+ {
+ 	int err = 0, savederrno = 0;
+-	struct sctp_event_subscribe events;
+-
+-	memset(&events, 0, sizeof (events));
+-	events.sctp_data_io_event = 1;
+-	events.sctp_association_event = 1;
+-	events.sctp_send_failure_event = 1;
+-	events.sctp_address_event = 1;
+-	events.sctp_peer_error_event = 1;
+-	events.sctp_shutdown_event = 1;
+-	if (setsockopt(sock, IPPROTO_SCTP, SCTP_EVENTS, &events, sizeof (events)) < 0) {
++	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
++
++	if (setsockopt(sock, IPPROTO_SCTP, SCTP_EVENTS,
++		       handle_info->event_subscribe_buffer,
++		       handle_info->event_subscribe_kernel_size) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to enable %s events: %s",
+@@ -1303,12 +1300,70 @@ int sctp_transport_free(knet_handle_t knet_h)
+ 		close(handle_info->connect_epollfd);
+ 	}
+ 
++	free(handle_info->event_subscribe_buffer);
+ 	free(handle_info);
+ 	knet_h->transports[KNET_TRANSPORT_SCTP] = NULL;
+ 
+ 	return 0;
+ }
+ 
++static int _sctp_subscribe_init(knet_handle_t knet_h)
++{
++	int test_socket, savederrno;
++	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
++	char dummy_events[100];
++	struct sctp_event_subscribe *events;
++	/* Below we set the first 6 fields of this expanding struct.
++	 * SCTP_EVENTS is deprecated, but SCTP_EVENT is not available
++	 * on Linux; on the other hand, FreeBSD and old Linux does not
++	 * accept small transfers, so we can't simply use this minimum
++	 * everywhere.  Thus we query and store the native size. */
++	const unsigned int subscribe_min = 6;
++
++	test_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
++	if (test_socket < 0) {
++		savederrno = errno;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to create test socket: %s",
++			strerror(savederrno));
++		return savederrno;
++	}
++	handle_info->event_subscribe_kernel_size = sizeof dummy_events;
++	if (getsockopt(test_socket, IPPROTO_SCTP, SCTP_EVENTS, &dummy_events,
++		       &handle_info->event_subscribe_kernel_size)) {
++		close(test_socket);
++		savederrno = errno;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to query kernel size of struct sctp_event_subscribe: %s",
++			strerror(savederrno));
++		return savederrno;
++	}
++	close(test_socket);
++	if (handle_info->event_subscribe_kernel_size < subscribe_min) {
++		savederrno = ERANGE;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP,
++			"No kernel support for the necessary notifications: struct sctp_event_subscribe is %u bytes, %u needed",
++			handle_info->event_subscribe_kernel_size, subscribe_min);
++		return savederrno;
++	}
++	events = malloc(handle_info->event_subscribe_kernel_size);
++	if (!events) {
++		savederrno = errno;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP,
++			"Failed to allocate event subscribe buffer: %s", strerror(savederrno));
++		return savederrno;
++	}
++	memset(events, 0, handle_info->event_subscribe_kernel_size);
++	events->sctp_data_io_event = 1;
++	events->sctp_association_event = 1;
++	events->sctp_address_event = 1;
++	events->sctp_send_failure_event = 1;
++	events->sctp_peer_error_event = 1;
++	events->sctp_shutdown_event = 1;
++	handle_info->event_subscribe_buffer = (char *)events;
++	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Size of struct sctp_event_subscribe is %u in kernel, %zu in user space",
++		  handle_info->event_subscribe_kernel_size, sizeof(struct sctp_event_subscribe));
++	return 0;
++}
++
+ int sctp_transport_init(knet_handle_t knet_h)
+ {
+ 	int err = 0, savederrno = 0;
+@@ -1329,6 +1384,12 @@ int sctp_transport_init(knet_handle_t knet_h)
+ 
+ 	knet_h->transports[KNET_TRANSPORT_SCTP] = handle_info;
+ 
++	savederrno = _sctp_subscribe_init(knet_h);
++	if (savederrno) {
++		err = -1;
++		goto exit_fail;
++	}
++
+ 	knet_list_init(&handle_info->listen_links_list);
+ 	knet_list_init(&handle_info->connect_links_list);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0166-Tabify.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0166-Tabify.patch
new file mode 100644
index 000000000..c7b2dead0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0166-Tabify.patch
@@ -0,0 +1,31 @@ 
+From 174c416cba208a182b752a9268db11f916b0c5fd Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Mon, 17 Dec 2018 18:24:06 +0100
+Subject: [PATCH] Tabify
+
+---
+ libknet/transport_sctp.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 46c6c102..a22517ca 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1394,12 +1394,12 @@ int sctp_transport_init(knet_handle_t knet_h)
+ 	knet_list_init(&handle_info->connect_links_list);
+ 
+ 	handle_info->listen_epollfd = epoll_create(KNET_EPOLL_MAX_EVENTS + 1);
+-        if (handle_info->listen_epollfd < 0) {
+-                savederrno = errno;
++	if (handle_info->listen_epollfd < 0) {
++		savederrno = errno;
+ 		err = -1;
+-                log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to create epoll listen fd: %s",
+-                        strerror(savederrno));
+-                goto exit_fail;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to create epoll listen fd: %s",
++			strerror(savederrno));
++		goto exit_fail;
+         }
+ 
+ 	if (_fdset_cloexec(handle_info->listen_epollfd)) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0167-global-update-notes-to-package-maintainers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0167-global-update-notes-to-package-maintainers.patch
new file mode 100644
index 000000000..84ba98304
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0167-global-update-notes-to-package-maintainers.patch
@@ -0,0 +1,41 @@ 
+From 2c5560c8fd6491b1fda3205afece40ed6de63180 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 18 Dec 2018 12:34:51 +0100
+Subject: [PATCH] [global] update notes to package maintainers
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ NOTES_TO_PACKAGE_MAINTAINERS | 19 +++++++++++--------
+ 1 file changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/NOTES_TO_PACKAGE_MAINTAINERS b/NOTES_TO_PACKAGE_MAINTAINERS
+index eae9a9da..5acff702 100644
+--- a/NOTES_TO_PACKAGE_MAINTAINERS
++++ b/NOTES_TO_PACKAGE_MAINTAINERS
+@@ -8,15 +8,18 @@ DO NOT ship kronosnetd. It's an experimental piece of super
+ crappy code. IF you decide to ship it anyway, you get to
+ be also the upstream maintainer :-) you have been warned.
+ 
+-libnozzle is a simple commodity library used only by kronosnetd.
+-I don't mind to support it, but don't ship just for the fun of it.
+-It has no users, that I know of, outside of kronosnetd.
++libnozzle is a simple commodity library used only by kronosnetd
++and a future release of corosync. This is the first GA release
++for libnozzle, please allow space for minor screw ups.
+ 
+-libknet is still under heavy development. There might be more
+-onwire network changes that could make current version
+-incompatible with newer versions. Make sure to warn your users
+-about it. Plan is to release a stable version (1.0) when
+-we are confident that the current implementation is stable enough.
++libknet is the core of this project. It is considered stable
++and supported in the stable* branches and still under
++heavy development in master branch. Upstream does guarantee
++onwire and update compatibility between releases in the same
++major versions (aka 1.x will always be able to talk to 1.x+n).
++There is NO guarantee of onwire compatibility
++between major versions of knet (aka: 1.x might not be able to talk
++to 2.x).
+ 
+ libknet has a lot of build dependencies due to its modular
+ implementation. It does not, however, link with all those libraries
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0168-knet-fix-build-with-older-openssl-versions.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0168-knet-fix-build-with-older-openssl-versions.patch
new file mode 100644
index 000000000..ed3dc494a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0168-knet-fix-build-with-older-openssl-versions.patch
@@ -0,0 +1,25 @@ 
+From cb37d3de1e201b9cc5625ed97541dcf81044d375 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 18 Dec 2018 13:20:08 +0100
+Subject: [PATCH] [knet] fix build with older openssl versions
+
+spotted on freebsd-devel
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index ca06c451..1eb01b01 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -458,7 +458,7 @@ static int openssl_internal_lock_setup(void)
+ 		}
+ 	}
+ 
+-	CRYPTO_set_id_callback((unsigned long (*)(void))openssl_internal_thread_id);
++	CRYPTO_set_id_callback((void *)openssl_internal_thread_id);
+ 	CRYPTO_set_locking_callback((void *)&openssl_internal_locking_callback);
+ 
+ out:
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0169-Install-the-nozzle-man-pages.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0169-Install-the-nozzle-man-pages.patch
new file mode 100644
index 000000000..c74e31564
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0169-Install-the-nozzle-man-pages.patch
@@ -0,0 +1,39 @@ 
+From 6101a275cb6a862e9e35ffc5f25fce8dbdd72384 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Wed, 19 Dec 2018 11:16:57 +0100
+Subject: [PATCH] Install the nozzle man pages
+
+---
+ man/Makefile.am | 19 ++++++++++++++++++-
+ 1 file changed, 18 insertions(+), 1 deletion(-)
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 29cd45e7..75472c9c 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -96,7 +96,24 @@ knet_man3_MANS = \
+ 		knet_strtoaddr.3
+ 
+ if BUILD_LIBNOZZLE
+-nozzle_man3_MANS =
++nozzle_man3_MANS = \
++		nozzle_add_ip.3 \
++		nozzle_close.3 \
++		nozzle_del_ip.3 \
++		nozzle_get_fd.3 \
++		nozzle_get_handle_by_name.3 \
++		nozzle_get_ips.3 \
++		nozzle_get_mac.3 \
++		nozzle_get_mtu.3 \
++		nozzle_get_name_by_handle.3 \
++		nozzle_open.3 \
++		nozzle_reset_mac.3 \
++		nozzle_reset_mtu.3 \
++		nozzle_run_updown.3 \
++		nozzle_set_down.3 \
++		nozzle_set_mac.3 \
++		nozzle_set_mtu.3 \
++		nozzle_set_up.3
+ endif
+ 
+ man3_MANS = $(knet_man3_MANS) $(nozzle_man3_MANS)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0170-Fix-typos.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0170-Fix-typos.patch
new file mode 100644
index 000000000..86bab97a8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0170-Fix-typos.patch
@@ -0,0 +1,63 @@ 
+From 29feb7845b3a83bb7ddcf5eca13122a5d4e966f1 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Wed, 19 Dec 2018 11:52:37 +0100
+Subject: [PATCH] Fix typos
+
+---
+ libknet/tests/api_knet_host_get_name_by_host_id.c | 2 +-
+ libnozzle/libnozzle.h                             | 8 ++++----
+ 2 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/tests/api_knet_host_get_name_by_host_id.c b/libknet/tests/api_knet_host_get_name_by_host_id.c
+index 9b98b004..e08739c2 100644
+--- a/libknet/tests/api_knet_host_get_name_by_host_id.c
++++ b/libknet/tests/api_knet_host_get_name_by_host_id.c
+@@ -73,7 +73,7 @@ static void test(void)
+ 	}
+ 
+ 	if (knet_host_get_name_by_host_id(knet_h, 1, name) < 0) {
+-		printf("knet_host_get_name_by_host_id faild to retrive name: %s\n", strerror(errno));
++		printf("knet_host_get_name_by_host_id faild to retrieve name: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 6baf09ee..80214518 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -170,7 +170,7 @@ struct nozzle_ip {
+ 
+ /**
+  * nozzle_get_ips
+- * @brief retrive the list of all configured ips for a given interface
++ * @brief retrieve the list of all configured ips for a given interface
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+@@ -191,7 +191,7 @@ int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip);
+ 
+ /**
+  * nozzle_get_mtu
+- * @brief retrive mtu on a given nozzle interface
++ * @brief retrieve mtu on a given nozzle interface
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+@@ -232,7 +232,7 @@ int nozzle_reset_mtu(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_mac
+- * @brief retrive mac address on a given nozzle interface
++ * @brief retrieve mac address on a given nozzle interface
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+@@ -288,7 +288,7 @@ nozzle_t nozzle_get_handle_by_name(const char *devname);
+ 
+ /**
+  * nozzle_get_name_by_handle
+- * @brief retrive nozzle interface name by handle
++ * @brief retrieve nozzle interface name by handle
+  *
+  * nozzle - pointer to the nozzle struct
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0171-rpm-ship-libnozzle-man-pages.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0171-rpm-ship-libnozzle-man-pages.patch
new file mode 100644
index 000000000..06950bb0f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0171-rpm-ship-libnozzle-man-pages.patch
@@ -0,0 +1,22 @@ 
+From 6089aa8448f6ebd460327088cd55d81e87bb9294 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 19 Dec 2018 15:34:32 +0100
+Subject: [PATCH] [rpm] ship libnozzle man pages
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 9e9903aa..9caf13b9 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -340,6 +340,7 @@ Requires: pkgconfig
+ %{_libdir}/libnozzle.so
+ %{_includedir}/libnozzle.h
+ %{_libdir}/pkgconfig/libnozzle.pc
++%{_mandir}/man3/nozzle*.3.gz
+ %endif
+ 
+ %package -n libknet1
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0172-Fix-nozzle-man-dates-to-SOURCE_EPOCH-just-like-we-fi.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0172-Fix-nozzle-man-dates-to-SOURCE_EPOCH-just-like-we-fi.patch
new file mode 100644
index 000000000..331b501fe
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0172-Fix-nozzle-man-dates-to-SOURCE_EPOCH-just-like-we-fi.patch
@@ -0,0 +1,24 @@ 
+From 96d9bc6c616781b495298b8d76de4816ec31933b Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Wed, 26 Dec 2018 10:59:44 +0100
+Subject: [PATCH] Fix nozzle man dates to SOURCE_EPOCH, just like we fix the
+ libknet ones
+
+---
+ man/Makefile.am | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 75472c9c..c48bf71e 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -129,7 +129,8 @@ doxyfile-knet.stamp: $(builddir)/doxyxml Doxyfile-knet $(top_srcdir)/libknet/lib
+ doxyfile-nozzle.stamp: $(builddir)/doxyxml Doxyfile-nozzle $(top_srcdir)/libnozzle/libnozzle.h
+ if BUILD_LIBNOZZLE
+ 	$(DOXYGEN) Doxyfile-nozzle
+-	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
++	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
++		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
+ endif
+ 	touch doxyfile-nozzle.stamp
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0173-Skip-SCTP-event-initialization-if-the-protocol-is-no.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0173-Skip-SCTP-event-initialization-if-the-protocol-is-no.patch
new file mode 100644
index 000000000..c04a99fc1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0173-Skip-SCTP-event-initialization-if-the-protocol-is-no.patch
@@ -0,0 +1,28 @@ 
+From e45e1dd15e5845031b8e772a7cc32aec19d7c63a Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Sun, 23 Dec 2018 23:09:55 +0100
+Subject: [PATCH] Skip SCTP event initialization if the protocol is not
+ supported
+
+We may not want to actually use SCTP after all, and if we do, we won't
+get to use the uninitialized subscribe struct anyway.  Thus aborting
+handle initialization is premature here.
+---
+ libknet/transport_sctp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index a22517ca..409ac6a7 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1322,6 +1322,10 @@ static int _sctp_subscribe_init(knet_handle_t knet_h)
+ 
+ 	test_socket = socket(PF_INET, SOCK_STREAM, IPPROTO_SCTP);
+ 	if (test_socket < 0) {
++		if (errno == EPROTONOSUPPORT) {
++			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP not supported, skipping initialization");
++			return 0;
++		}
+ 		savederrno = errno;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to create test socket: %s",
+ 			strerror(savederrno));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0174-libknet-expose-API-version-in-libknet.h-to-make-it-e.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0174-libknet-expose-API-version-in-libknet.h-to-make-it-e.patch
new file mode 100644
index 000000000..b53a91766
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0174-libknet-expose-API-version-in-libknet.h-to-make-it-e.patch
@@ -0,0 +1,24 @@ 
+From 5f3ca86c509785760d915aba9e3fe3b3e3d7adb1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 3 Jan 2019 09:59:16 +0100
+Subject: [PATCH] [libknet] expose API version in libknet.h to make it easier
+ for applications to add conditional builds
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index d4591e87..a5ce7fc7 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -24,6 +24,8 @@
+  * Kronosnet is an advanced VPN system for High Availability applications.
+  */
+ 
++#define KNET_API_VER 1
++
+ /*
+  * libknet limits
+  */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0175-build-enable-all-compilers-warnings-at-once.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0175-build-enable-all-compilers-warnings-at-once.patch
new file mode 100644
index 000000000..655f645f5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0175-build-enable-all-compilers-warnings-at-once.patch
@@ -0,0 +1,110 @@ 
+From 77b89737526b7277e8fefba94e76990ec7d120a9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 3 Jan 2019 16:06:31 +0100
+Subject: [PATCH] [build] enable all compilers warnings at once
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac | 81 ++++------------------------------------------------
+ 1 file changed, 6 insertions(+), 75 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 2a6608f1..87045433 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -175,23 +175,6 @@ if test "x$enable_kronosnetd" = xyes; then
+ fi
+ AM_CONDITIONAL([BUILD_LIBNOZZLE], [test x$enable_libnozzle = xyes])
+ 
+-## local helper functions
+-# this function checks if CC support options passed as
+-# args. Global CPPFLAGS are ignored during this test.
+-cc_supports_flag() {
+-	saveCPPFLAGS="$CPPFLAGS"
+-	CPPFLAGS="$@"
+-	if echo $CC | grep -q clang; then
+-		CPPFLAGS="-Werror $CPPFLAGS"
+-	fi
+-	AC_MSG_CHECKING([whether $CC supports "$@"])
+-	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+-			  [RC=0; AC_MSG_RESULT([yes])],
+-			  [RC=1; AC_MSG_RESULT([no])])
+-	CPPFLAGS="$saveCPPFLAGS"
+-	return $RC
+-}
+-
+ # Checks for libraries.
+ AX_PTHREAD(,[AC_MSG_ERROR([POSIX threads support is required])])
+ saved_LIBS="$LIBS"
+@@ -404,65 +387,13 @@ else
+ 	GDB_FLAGS="-g"
+ fi
+ 
+-# extra warnings
+-EXTRA_WARNINGS=""
+-
+-WARNLIST="
+-	all
+-	extra
+-	unused
+-	shadow
+-	missing-prototypes
+-	missing-declarations
+-	suggest-attribute=noreturn
+-	suggest-attribute=format
+-	property-attribute-mismatch
+-	strict-prototypes
+-	declaration-after-statement
+-	pointer-arith
+-	write-strings
+-	cast-align
+-	bad-function-cast
+-	missing-format-attribute
+-	float-equal
+-	format=2
+-	format-signedness
+-	format-security
+-	format-nonliteral
+-	no-long-long
+-	unsigned-char
+-	gnu89-inline
+-	no-strict-aliasing
+-	error
+-	address
+-	cpp
+-	overflow
+-	parentheses
+-	sequence-point
+-	switch
+-	shift-overflow
+-	shift-overflow=2
+-	overlength-strings
+-	retundent-decls
+-	init-self
+-	uninitialized
+-	unused-but-set-variable
+-	unused-const-variable
+-	unused-function
+-	unused-result
+-	unused-value
+-	unused-variable
+-	unknown-pragmas
+-	no-unused-parameter
+-	"
+-
+-for j in $WARNLIST; do
+-	if cc_supports_flag -W$j; then
+-		EXTRA_WARNINGS="$EXTRA_WARNINGS -W$j";
+-	fi
+-done
++DEFAULT_CFLAGS="-Werror -Wall -Wextra"
++
++# manual overrides
++# generates too much noise for stub APIs
++UNWANTED_CFLAGS="-Wno-unused-parameter"
+ 
+-AC_SUBST([AM_CFLAGS],["$OPT_CFLAGS $GDB_FLAGS $EXTRA_WARNINGS"])
++AC_SUBST([AM_CFLAGS],["$OPT_CFLAGS $GDB_FLAGS $DEFAULT_CFLAGS $UNWANTED_CFLAGS"])
+ 
+ AX_PROG_DATE
+ AS_IF([test "$ax_cv_prog_date_gnu_date:$ax_cv_prog_date_gnu_utc" = yes:yes],
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0176-libknet-allow-better-handling-of-internal-threads.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0176-libknet-allow-better-handling-of-internal-threads.patch
new file mode 100644
index 000000000..c9be096a8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0176-libknet-allow-better-handling-of-internal-threads.patch
@@ -0,0 +1,273 @@ 
+From 691bce617f5dd214565b3e4cc58784e1f8696df5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 7 Jan 2019 09:54:31 +0100
+Subject: [PATCH] [libknet] allow better handling of internal threads
+
+while playing around adding some dynamic internal threads, i did
+hit a limitation with allocating a dynamic THREAD_MAX value based
+on OS availability of certain features.
+
+this patch changes from dynamic to static allocation of threads, that
+can always be increased if necessary without breaking anything.
+
+simplify thread numbering and conditionals on OS features
+
+improve debugging of thread status by adding a 2 phase thread registration
+process:
+
+- register a thread before starting it with THREAD_REGISTERED before pthread_create
+- set a thread status as started with THREAD_STARTED
+
+any failure in between can now be detected in debugging logs.
+
+Note for developers: all threads *MUST* be registered/started before
+wait_all_threads_status check in handle.c.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c             |  7 ++++++-
+ libknet/threads_common.c     | 17 ++++++++---------
+ libknet/threads_common.h     | 15 ++++++++-------
+ libknet/threads_dsthandler.c |  2 +-
+ libknet/threads_heartbeat.c  |  2 +-
+ libknet/threads_pmtud.c      |  2 +-
+ libknet/threads_rx.c         |  2 +-
+ libknet/threads_tx.c         |  2 +-
+ libknet/transport_sctp.c     |  6 ++++--
+ 9 files changed, 31 insertions(+), 24 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 71bcb569..5dab0cf0 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -454,6 +454,7 @@ static int _start_threads(knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
+ 
++	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&knet_h->pmtud_link_handler_thread, 0,
+ 				    _handle_pmtud_link_thread, (void *) knet_h);
+ 	if (savederrno) {
+@@ -462,6 +463,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_DST_LINK, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&knet_h->dst_link_handler_thread, 0,
+ 				    _handle_dst_link_handler_thread, (void *) knet_h);
+ 	if (savederrno) {
+@@ -470,6 +472,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&knet_h->send_to_links_thread, 0,
+ 				    _handle_send_to_links_thread, (void *) knet_h);
+ 	if (savederrno) {
+@@ -478,6 +481,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&knet_h->recv_from_links_thread, 0,
+ 				    _handle_recv_from_links_thread, (void *) knet_h);
+ 	if (savederrno) {
+@@ -486,6 +490,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_HB, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&knet_h->heartbt_thread, 0,
+ 				    _handle_heartbt_thread, (void *) knet_h);
+ 	if (savederrno) {
+@@ -697,7 +702,7 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 		goto exit_fail;
+ 	}
+ 
+-	wait_all_threads_status(knet_h, KNET_THREAD_RUNNING);
++	wait_all_threads_status(knet_h, KNET_THREAD_STARTED);
+ 
+ 	errno = 0;
+ 	return knet_h;
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index fc10a029..6f0ce4a4 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -64,7 +64,7 @@ int get_global_wrlock(knet_handle_t knet_h)
+ 	return pthread_rwlock_wrlock(&knet_h->global_rwlock);
+ }
+ 
+-static struct pretty_names thread_names[] =
++static struct pretty_names thread_names[KNET_THREAD_MAX] =
+ {
+ 	{ "TX", KNET_THREAD_TX },
+ 	{ "RX", KNET_THREAD_RX },
+@@ -79,16 +79,12 @@ static struct pretty_names thread_names[] =
+ 
+ static struct pretty_names thread_status[] =
+ {
+-	{ "stopped", KNET_THREAD_STOPPED },
+-	{ "running", KNET_THREAD_RUNNING }
++	{ "unregistered", KNET_THREAD_UNREGISTERED },
++	{ "registered", KNET_THREAD_REGISTERED },
++	{ "started", KNET_THREAD_STARTED },
++	{ "stopped", KNET_THREAD_STOPPED }
+ };
+ 
+-/*
+- * this seems overloaded at the moment but
+- * we might want to expand status checks
+- * to include "starting" and "stopping"
+- */
+-
+ static const char *get_thread_status_name(uint8_t status)
+ {
+ 	unsigned int i;
+@@ -143,6 +139,9 @@ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status)
+ 		found = 1;
+ 
+ 		for (i = 0; i < KNET_THREAD_MAX; i++) {
++			if (knet_h->threads_status[i] == KNET_THREAD_UNREGISTERED) {
++				continue;
++			}
+ 			log_debug(knet_h, KNET_SUB_HANDLE, "Checking thread: %s status: %s req: %s",
+ 					get_thread_name(i),
+ 					get_thread_status_name(knet_h->threads_status[i]),
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 78e1cf02..1314c017 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -14,22 +14,23 @@
+ 
+ #define KNET_THREADS_TIMERES 200000
+ 
+-#define KNET_THREAD_STOPPED	0
+-#define KNET_THREAD_RUNNING	1
+-#define KNET_THREAD_STATUS_MAX	KNET_THREAD_RUNNING + 1
++#define KNET_THREAD_UNREGISTERED	0 /* thread does not exist */
++#define KNET_THREAD_REGISTERED		1 /* thread has been registered before  pthread_create invocation.
++					     make sure threads are registered before calling wait_all_thread_status */
++#define KNET_THREAD_STARTED		2 /* thread has reported to be running */
++#define KNET_THREAD_STOPPED		3 /* thread has returned */
++#define KNET_THREAD_STATUS_MAX	KNET_THREAD_STOPPED + 1
+ 
+ #define KNET_THREAD_TX		0
+ #define KNET_THREAD_RX		1
+ #define KNET_THREAD_HB		2
+ #define KNET_THREAD_PMTUD	3
+ #define KNET_THREAD_DST_LINK	4
+-#ifndef HAVE_NETINET_SCTP_H
+-#define KNET_THREAD_MAX		KNET_THREAD_DST_LINK + 1
+-#else
++#ifdef HAVE_NETINET_SCTP_H
+ #define KNET_THREAD_SCTP_LISTEN	5
+ #define KNET_THREAD_SCTP_CONN	6
+-#define KNET_THREAD_MAX		KNET_THREAD_SCTP_CONN + 1
+ #endif
++#define KNET_THREAD_MAX		32
+ 
+ #define timespec_diff(start, end, diff) \
+ do { \
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 529ff153..74e7ef07 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -53,7 +53,7 @@ void *_handle_dst_link_handler_thread(void *data)
+ 	knet_handle_t knet_h = (knet_handle_t) data;
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 
+-	set_thread_status(knet_h, KNET_THREAD_DST_LINK, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_DST_LINK, KNET_THREAD_STARTED);
+ 
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		if (epoll_wait(knet_h->dst_link_handler_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000) >= 1)
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index c3838129..12aaa767 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -186,7 +186,7 @@ void *_handle_heartbt_thread(void *data)
+ 	knet_handle_t knet_h = (knet_handle_t) data;
+ 	int i = 1;
+ 
+-	set_thread_status(knet_h, KNET_THREAD_HB, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_HB, KNET_THREAD_STARTED);
+ 
+ 	/* preparing ping buffer */
+ 	knet_h->pingbuf->kh_version = KNET_HEADER_VERSION;
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 820f273c..442a3465 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -479,7 +479,7 @@ void *_handle_pmtud_link_thread(void *data)
+ 	int link_has_mtu;
+ 	int force_run = 0;
+ 
+-	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_STARTED);
+ 
+ 	knet_h->data_mtu = KNET_PMTUD_MIN_MTU_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
+ 
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 2aa1164a..d2767e17 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -814,7 +814,7 @@ void *_handle_recv_from_links_thread(void *data)
+ 	struct knet_mmsghdr msg[PCKT_RX_BUFS];
+ 	struct iovec iov_in[PCKT_RX_BUFS];
+ 
+-	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_STARTED);
+ 
+ 	memset(&msg, 0, sizeof(msg));
+ 
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index f73592ab..1048bf60 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -678,7 +678,7 @@ void *_handle_send_to_links_thread(void *data)
+ 	struct msghdr msg;
+ 	struct sockaddr_storage address;
+ 
+-	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_STARTED);
+ 
+ 	memset(&iov_in, 0, sizeof(iov_in));
+ 	iov_in.iov_base = (void *)knet_h->recv_from_sock_buf->khp_data_userdata;
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 409ac6a7..83fc359c 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -626,7 +626,7 @@ static void *_sctp_connect_thread(void *data)
+ 	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 
+-	set_thread_status(knet_h, KNET_THREAD_SCTP_CONN, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_SCTP_CONN, KNET_THREAD_STARTED);
+ 
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		nev = epoll_wait(handle_info->connect_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
+@@ -871,7 +871,7 @@ static void *_sctp_listen_thread(void *data)
+ 	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 
+-	set_thread_status(knet_h, KNET_THREAD_SCTP_LISTEN, KNET_THREAD_RUNNING);
++	set_thread_status(knet_h, KNET_THREAD_SCTP_LISTEN, KNET_THREAD_STARTED);
+ 
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		nev = epoll_wait(handle_info->listen_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
+@@ -1472,6 +1472,7 @@ int sctp_transport_init(knet_handle_t knet_h)
+ 	/*
+ 	 * Start connect & listener threads
+ 	 */
++	set_thread_status(knet_h, KNET_THREAD_SCTP_LISTEN, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&handle_info->listen_thread, 0, _sctp_listen_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		err = -1;
+@@ -1480,6 +1481,7 @@ int sctp_transport_init(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	set_thread_status(knet_h, KNET_THREAD_SCTP_CONN, KNET_THREAD_REGISTERED);
+ 	savederrno = pthread_create(&handle_info->connect_thread, 0, _sctp_connect_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		err = -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0177-common-fix-not-reporting-a-true-dlinfo-error-cause.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0177-common-fix-not-reporting-a-true-dlinfo-error-cause.patch
new file mode 100644
index 000000000..946f8336d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0177-common-fix-not-reporting-a-true-dlinfo-error-cause.patch
@@ -0,0 +1,28 @@ 
+From a9cdd3cb65a9683954a6925f53b9ba4f5d8cd251 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Jan=20Pokorn=C3=BD?= <jpokorny@redhat.com>
+Date: Thu, 24 Jan 2019 14:54:24 +0100
+Subject: [PATCH] [common] fix not reporting a true dlinfo error cause
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This was automatically caught with GCC 9
+("'%s' directive argument is null").
+
+Signed-off-by: Jan Pokorný <jpokorny@redhat.com>
+---
+ libknet/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libknet/common.c b/libknet/common.c
+index 957b8ab3..52563dde 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -82,6 +82,7 @@ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags
+ 		/*
+ 		 * should we dlclose and return error?
+ 		 */
++		error = dlerror();
+ 		log_warn(knet_h, KNET_SUB_COMMON, "unable to dlinfo %s: %s",
+ 			 libname, error);
+ 	} else {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0178-man-add-test-to-make-sure-all-generated-man-pages-ar.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0178-man-add-test-to-make-sure-all-generated-man-pages-ar.patch
new file mode 100644
index 000000000..5a5a502eb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0178-man-add-test-to-make-sure-all-generated-man-pages-ar.patch
@@ -0,0 +1,87 @@ 
+From b1e0bb2d1f91bbb34aa2483e0e89e51f27e97591 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 28 Feb 2019 10:39:20 +0100
+Subject: [PATCH] [man] add test to make sure all generated man pages are being
+ shipped / installed
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/Makefile.am              | 17 +++++++++++++++--
+ man/api-to-man-page-coverage | 33 +++++++++++++++++++++++++++++++++
+ 2 files changed, 48 insertions(+), 2 deletions(-)
+ create mode 100755 man/api-to-man-page-coverage
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index c48bf71e..ddec3f5e 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -11,7 +11,9 @@ MAINTAINERCLEANFILES	= Makefile.in
+ 
+ include $(top_srcdir)/build-aux/check.mk
+ 
+-EXTRA_DIST	= kronosnetd.8 knet-keygen.8
++EXTRA_DIST	= \
++		  kronosnetd.8 knet-keygen.8 \
++		  api-to-man-page-coverage
+ 
+ # Avoid Automake warnings about overriding these user variables.
+ # Programs in this directory are used during the build only.
+@@ -132,7 +134,18 @@ if BUILD_LIBNOZZLE
+ 	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
+ endif
+-	touch doxyfile-nozzle.stamp
++
++noinst_SCRIPTS	= api-to-man-page-coverage
++
++check-local: check-api-to-man-page-coverage-libknet check-api-to-man-page-coverage-libnozzle
++
++check-api-to-man-page-coverage-libnozzle:
++if BUILD_LIBNOZZLE
++	$(srcdir)/api-to-man-page-coverage $(top_srcdir) nozzle
++endif
++
++check-api-to-man-page-coverage-libknet:
++	$(srcdir)/api-to-man-page-coverage $(top_srcdir) knet
+ 
+ endif
+ 
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+new file mode 100755
+index 00000000..5b82bef8
+--- /dev/null
++++ b/man/api-to-man-page-coverage
+@@ -0,0 +1,33 @@
++#!/bin/sh
++#
++# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+, LGPL-2.0+
++#
++
++err=0
++srcdir="$1"
++target="$2"
++
++headerapicalls="$(grep ${target}_ "$srcdir"/lib${target}/lib${target}.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
++manpages="$(grep ${target}_ "$srcdir"/man/Makefile.am |grep -v man3 |grep -v xml | sed -e 's/\.3.*//g')"
++
++echo "Checking for symbols in header file NOT distributed as manpages"
++
++for i in $headerapicalls; do
++	found=0
++	for x in $manpages; do
++		if [ "$x" = "$i" ]; then
++			found=1
++			break;
++		fi
++	done
++	if [ "$found" = 0 ]; then
++		echo "API man page $i not found not found in $srcdir/man/Makefile.am"
++		err=1
++	fi
++done
++
++exit $err
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0179-doxyxml-Don-t-crash-if-there-s-no-doxygen-stanza-for.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0179-doxyxml-Don-t-crash-if-there-s-no-doxygen-stanza-for.patch
new file mode 100644
index 000000000..7eba8f0f5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0179-doxyxml-Don-t-crash-if-there-s-no-doxygen-stanza-for.patch
@@ -0,0 +1,28 @@ 
+From 8ac356264011add00c621a8f2ed7e9775ef54245 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 28 Feb 2019 13:47:36 +0000
+Subject: [PATCH] doxyxml: Don't crash if there's no doxygen stanza for a
+ function
+
+---
+ man/doxyxml.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 9f493b26..0caaf9b0 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -703,6 +703,13 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		}
+ 
+ 		if (kind && strcmp(kind, "function") == 0) {
++
++			/* Make sure function has a doxygen description */
++			if (!detailed) {
++				fprintf(stderr, "No doxygen description for function '%s' - please fix this\n", name);
++				exit(1);
++			}
++
+ 			if (print_man) {
+ 				print_manpage(name, def, brief, args, detailed, &params_list, returntext);
+ 			}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0180-tests-fix-knet_bench-help-text.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0180-tests-fix-knet_bench-help-text.patch
new file mode 100644
index 000000000..086ff0f19
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0180-tests-fix-knet_bench-help-text.patch
@@ -0,0 +1,23 @@ 
+From 81d536324ca1d03acab9e0be62cb666927c07c80 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 13 Feb 2019 08:20:19 +0100
+Subject: [PATCH] [tests] fix knet_bench help text
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/knet_bench.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index 9a4948cd..2871feb8 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -86,7 +86,7 @@ static void print_help(void)
+ 	printf(" -P [UDP|SCTP]                             (default: UDP) protocol (transport) to use for all links\n");
+ 	printf(" -t [nodeid]                               This nodeid (required)\n");
+ 	printf(" -n [nodeid],[proto]/[link1_ip],[link2_..] Other nodes information (at least one required)\n");
+-	printf("                                           Example: -t 1,192.168.8.1,SCTP/3ffe::8:1,UDP/172...\n");
++	printf("                                           Example: -n 1,192.168.8.1,SCTP/3ffe::8:1,UDP/172...\n");
+ 	printf("                                           can be repeated up to %d and should contain also the localnode info\n", MAX_NODES);
+ 	printf(" -b [port]                                 baseport (default: 50000)\n");
+ 	printf(" -l                                        enable global listener on 0.0.0.0/:: (default: off, incompatible with -o)\n");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0181-man-fix-libnozzle-man-page-generation-target.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0181-man-fix-libnozzle-man-page-generation-target.patch
new file mode 100644
index 000000000..f9b0cced5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0181-man-fix-libnozzle-man-page-generation-target.patch
@@ -0,0 +1,22 @@ 
+From e4682ee9338ee053bba09eecfe73b48e1da579ec Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 5 Mar 2019 04:27:21 +0100
+Subject: [PATCH] [man] fix libnozzle man page generation target
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/Makefile.am | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index ddec3f5e..33076872 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -134,6 +134,7 @@ if BUILD_LIBNOZZLE
+ 	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
+ endif
++	touch doxyfile-nozzle.stamp
+ 
+ noinst_SCRIPTS	= api-to-man-page-coverage
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0182-tests-add-ability-to-create-ipv6-sockets.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0182-tests-add-ability-to-create-ipv6-sockets.patch
new file mode 100644
index 000000000..115d492b9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0182-tests-add-ability-to-create-ipv6-sockets.patch
@@ -0,0 +1,59 @@ 
+From 7bb9adf535852bd3a013ea18beeb0a5a5adfad57 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 5 Mar 2019 07:04:57 +0100
+Subject: [PATCH] [tests] add ability to create ipv6 sockets
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 15 ++++++++++++++-
+ libknet/tests/test-common.h |  1 +
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 91759ab5..729915f5 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -431,7 +431,7 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 	return 0;
+ }
+ 
+-int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset)
++static int _make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset, int family)
+ {
+ 	uint32_t port;
+ 	char portstr[32];
+@@ -448,9 +448,22 @@ int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset)
+ 	memset(lo, 0, sizeof(struct sockaddr_storage));
+ 	printf("Using port %u\n", port);
+ 
++	if (family == AF_INET6) {
++		return knet_strtoaddr("::1", portstr, lo, sizeof(struct sockaddr_storage));
++	}
+ 	return knet_strtoaddr("127.0.0.1", portstr, lo, sizeof(struct sockaddr_storage));
+ }
+ 
++int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset)
++{
++	return _make_local_sockaddr(lo, offset, AF_INET);
++}
++
++int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset)
++{
++	return _make_local_sockaddr(lo, offset, AF_INET6);
++}
++
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std)
+ {
+ 	int i = 0;
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 8f641610..6a0de762 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -68,6 +68,7 @@ void flush_logs(int logfd, FILE *std);
+ int start_logthread(int logfd, FILE *std);
+ int stop_logthread(void);
+ int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset);
++int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset);
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std);
+ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0183-man-fix-man-page-build-dependency-for-BSD-Make.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0183-man-fix-man-page-build-dependency-for-BSD-Make.patch
new file mode 100644
index 000000000..6aa0daa01
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0183-man-fix-man-page-build-dependency-for-BSD-Make.patch
@@ -0,0 +1,30 @@ 
+From b5071bcad30cbb0c614554955e34be0239d27b97 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 6 Mar 2019 13:29:01 +0100
+Subject: [PATCH] [man] fix man page build dependency for BSD Make
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/Makefile.am | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 33076872..9fa426d4 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -122,13 +122,13 @@ man3_MANS = $(knet_man3_MANS) $(nozzle_man3_MANS)
+ 
+ $(MANS): doxyfile-knet.stamp doxyfile-nozzle.stamp
+ 
+-doxyfile-knet.stamp: $(builddir)/doxyxml Doxyfile-knet $(top_srcdir)/libknet/libknet.h
++doxyfile-knet.stamp: $(noinst_PROGRAMS) Doxyfile-knet $(top_srcdir)/libknet/libknet.h
+ 	$(DOXYGEN) Doxyfile-knet
+ 	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
+ 	touch doxyfile-knet.stamp
+ 
+-doxyfile-nozzle.stamp: $(builddir)/doxyxml Doxyfile-nozzle $(top_srcdir)/libnozzle/libnozzle.h
++doxyfile-nozzle.stamp: $(noinst_PROGRAMS) Doxyfile-nozzle $(top_srcdir)/libnozzle/libnozzle.h
+ if BUILD_LIBNOZZLE
+ 	$(DOXYGEN) Doxyfile-nozzle
+ 	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0184-transport-don-t-specify-destination-address-for-conn.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0184-transport-don-t-specify-destination-address-for-conn.patch
new file mode 100644
index 000000000..bbc56c499
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0184-transport-don-t-specify-destination-address-for-conn.patch
@@ -0,0 +1,279 @@ 
+From 1f779e477a1eec21248b49b7cfdd065b65858b9d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 11 Mar 2019 05:30:33 +0100
+Subject: [PATCH] =?UTF-8?q?[transport]=20don=C2=B4t=20specify=20destinatio?=
+ =?UTF-8?q?n=20address=20for=20connection=20oriented=20protocols?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+some implementations of sendto/sendmsg expects dst_addr / msg_name to be
+empty for connection oriented protocols such as SCTP (spotted on FreeBSD).
+
+Make sure to clear or not pass those information on connection oriented protocol.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h           | 13 +++++++++++++
+ libknet/tests/api_knet_send.c | 12 +++++++++---
+ libknet/tests/knet_bench.c    |  2 +-
+ libknet/threads_heartbeat.c   |  9 ++++++---
+ libknet/threads_pmtud.c       |  9 ++++++---
+ libknet/threads_rx.c          | 18 ++++++++++++------
+ libknet/threads_tx.c          |  1 +
+ libknet/transport_common.c    |  6 +++++-
+ libknet/transport_common.h    |  2 +-
+ libknet/transports.c          | 13 +++++++++----
+ libknet/transports.h          |  1 +
+ 11 files changed, 64 insertions(+), 22 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 3e4bbfaf..20f7e105 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -255,6 +255,12 @@ extern pthread_rwlock_t shlib_rwlock;       /* global shared lib load lock */
+  *       for every protocol.
+  */
+ 
++/*
++ * make it easier to map values in transports.c
++ */
++#define TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED 0
++#define TRANSPORT_PROTO_IS_CONNECTION_ORIENTED  1
++
+ typedef struct knet_transport_ops {
+ /*
+  * transport generic information
+@@ -263,6 +269,13 @@ typedef struct knet_transport_ops {
+ 	const uint8_t transport_id;
+ 	const uint8_t built_in;
+ 
++/*
++ * connection oriented protocols like SCTP
++ * don´t need dst_addr in sendto calls and
++ * on some OSes are considered EINVAL.
++ */
++	uint8_t transport_is_connection_oriented;
++
+ 	uint32_t transport_mtu_overhead;
+ /*
+  * transport init must allocate the new transport
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index e7f84565..3dfb6d0b 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -33,7 +33,7 @@ static void sock_notify(void *pvt_data,
+ 	return;
+ }
+ 
+-static void test(void)
++static void test(uint8_t transport)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+@@ -172,7 +172,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (knet_link_set_config(knet_h, 1, 0, transport, &lo, &lo, 0) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -314,7 +314,13 @@ static void test(void)
+ 
+ int main(int argc, char *argv[])
+ {
+-	test();
++	printf("Testing with UDP\n");
++	test(KNET_TRANSPORT_UDP);
++
++#ifdef HAVE_NETINET_SCTP_H
++	printf("Testing with SCTP\n");
++	test(KNET_TRANSPORT_SCTP);
++#endif
+ 
+ 	return PASS;
+ }
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index 2871feb8..f60b5b1b 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -814,7 +814,7 @@ static int send_messages(struct knet_mmsghdr *msg, int msgs_to_send)
+ 
+ retry:
+ 	errno = 0;
+-	sent_msgs = _sendmmsg(datafd, &msg[0], msgs_to_send, MSG_NOSIGNAL);
++	sent_msgs = _sendmmsg(datafd, 0, &msg[0], msgs_to_send, MSG_NOSIGNAL);
+ 
+ 	if (sent_msgs < 0) {
+ 		if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 12aaa767..4685ee8f 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -85,9 +85,12 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		}
+ 
+ retry:
+-		len = sendto(dst_link->outsock, outbuf, outlen,
+-			MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) &dst_link->dst_addr,
+-			sizeof(struct sockaddr_storage));
++		if (transport_get_connection_oriented(knet_h, dst_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
++				     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
++		} else {
++			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++		}
+ 		savederrno = errno;
+ 
+ 		dst_link->ping_last = clock_now;
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 442a3465..33bee5ea 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -172,9 +172,12 @@ restart:
+ 		return -1;
+ 	}
+ retry:
+-	len = sendto(dst_link->outsock, outbuf, data_len,
+-			MSG_DONTWAIT | MSG_NOSIGNAL, (struct sockaddr *) &dst_link->dst_addr,
+-			sizeof(struct sockaddr_storage));
++	if (transport_get_connection_oriented(knet_h, dst_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++		len = sendto(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL,
++			     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
++	} else {
++		len = sendto(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++	}
+ 	savederrno = errno;
+ 
+ 	/*
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index d2767e17..4877b729 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -577,9 +577,12 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		}
+ 
+ retry_pong:
+-		len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+-				(struct sockaddr *) &src_link->dst_addr,
+-				sizeof(struct sockaddr_storage));
++		if (transport_get_connection_oriented(knet_h, src_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
++				     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
++		} else {
++			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++		}
+ 		savederrno = errno;
+ 		if (len != outlen) {
+ 			err = transport_tx_sock_error(knet_h, src_link->transport_type, src_link->outsock, len, savederrno);
+@@ -670,9 +673,12 @@ retry_pong:
+ 			goto out_pmtud;
+ 		}
+ retry_pmtud:
+-		len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+-				(struct sockaddr *) &src_link->dst_addr,
+-				sizeof(struct sockaddr_storage));
++		if (transport_get_connection_oriented(knet_h, src_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
++				     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
++		} else {
++			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++		}
+ 		savederrno = errno;
+ 		if (len != outlen) {
+ 			err = transport_tx_sock_error(knet_h, src_link->transport_type, src_link->outsock, len, savederrno);
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 1048bf60..da986140 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -68,6 +68,7 @@ retry:
+ 		cur = &msg[prev_sent];
+ 
+ 		sent_msgs = _sendmmsg(dst_host->link[dst_host->active_links[link_idx]].outsock,
++				      transport_get_connection_oriented(knet_h, dst_host->link[dst_host->active_links[link_idx]].transport_type),
+ 				      &cur[0], msgs_to_send - prev_sent, MSG_DONTWAIT | MSG_NOSIGNAL);
+ 		savederrno = errno;
+ 
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 6df50027..cd344932 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -54,12 +54,16 @@ int _recvmmsg(int sockfd, struct knet_mmsghdr *msgvec, unsigned int vlen, unsign
+ 	return ((i > 0) ? (int)i : err);
+ }
+ 
+-int _sendmmsg(int sockfd, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags)
++int _sendmmsg(int sockfd, int connection_oriented, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags)
+ {
+ 	int savederrno = 0, err = 0;
+ 	unsigned int i;
+ 
+ 	for (i = 0; i < vlen; i++) {
++		if (connection_oriented == TRANSPORT_PROTO_IS_CONNECTION_ORIENTED) {
++			msgvec[i].msg_hdr.msg_name = NULL;
++			msgvec[i].msg_hdr.msg_namelen = 0;
++		}
+ 		err = sendmsg(sockfd, &msgvec[i].msg_hdr, flags);
+ 		savederrno = errno;
+ 		if (err < 0) {
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 61af9bb4..295d2b26 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -18,7 +18,7 @@ void _close_socketpair(knet_handle_t knet_h, int *sock);
+ int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t data_type, void *data);
+ int _is_valid_fd(knet_handle_t knet_h, int sockfd);
+ 
+-int _sendmmsg(int sockfd, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags);
++int _sendmmsg(int sockfd, int connection_oriented, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags);
+ int _recvmmsg(int sockfd, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags);
+ 
+ #endif
+diff --git a/libknet/transports.c b/libknet/transports.c
+index b685212f..b8713700 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -27,14 +27,14 @@
+ #include "transport_sctp.h"
+ #include "threads_common.h"
+ 
+-#define empty_module 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
++#define empty_module 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+-	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
++	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+-				       1, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
++				       1, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
+ #else
+ empty_module
+ #endif
+@@ -118,6 +118,11 @@ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, st
+ 	return transport_modules_cmd[transport].transport_rx_is_data(knet_h, sockfd, msg);
+ }
+ 
++int transport_get_connection_oriented(knet_handle_t knet_h, uint8_t transport)
++{
++	return transport_modules_cmd[transport].transport_is_connection_oriented;
++}
++
+ /*
+  * public api
+  */
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 0419451d..ec1158b5 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -18,5 +18,6 @@ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_lin
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_tx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, struct knet_mmsghdr *msg);
++int transport_get_connection_oriented(knet_handle_t knet_h, uint8_t transport);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0185-host-increase-log-level-for-currently-used-links.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0185-host-increase-log-level-for-currently-used-links.patch
new file mode 100644
index 000000000..cc4a3f1d5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0185-host-increase-log-level-for-currently-used-links.patch
@@ -0,0 +1,34 @@ 
+From 99462c076153bed4f673712cc6aa12cb85f9e63e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 11 Mar 2019 06:30:17 +0100
+Subject: [PATCH] [host] increase log level for currently used links
+
+bug reported on IRC by yuanren
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index 00e2298e..184ca203 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -680,12 +680,12 @@ int _host_dstcache_update_sync(knet_handle_t knet_h, struct knet_host *host)
+ 	}
+ 
+ 	if (host->link_handler_policy == KNET_LINK_POLICY_PASSIVE) {
+-		log_debug(knet_h, KNET_SUB_HOST, "host: %u (passive) best link: %u (pri: %u)",
+-			  host->host_id, host->link[host->active_links[0]].link_id,
+-			  host->link[host->active_links[0]].priority);
++		log_info(knet_h, KNET_SUB_HOST, "host: %u (passive) best link: %u (pri: %u)",
++			 host->host_id, host->link[host->active_links[0]].link_id,
++			 host->link[host->active_links[0]].priority);
+ 	} else {
+-		log_debug(knet_h, KNET_SUB_HOST, "host: %u has %u active links",
+-			  host->host_id, host->active_link_entries);
++		log_info(knet_h, KNET_SUB_HOST, "host: %u has %u active links",
++			 host->host_id, host->active_link_entries);
+ 	}
+ 
+ 	/* no active links, we can clean the circular buffers and indexes */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0186-tests-allow-shipping-of-the-test-suite.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0186-tests-allow-shipping-of-the-test-suite.patch
new file mode 100644
index 000000000..f2f574504
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0186-tests-allow-shipping-of-the-test-suite.patch
@@ -0,0 +1,152 @@ 
+From a8da1a6b3d33c8e734ca7ff06c9fb7cb62e7f805 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Mar 2019 19:28:19 +0100
+Subject: [PATCH] [tests] allow shipping of the test suite
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ Makefile.am                 |  5 +++++
+ configure.ac                | 11 +++++++++++
+ kronosnet.spec.in           | 22 ++++++++++++++++++++++
+ libknet/tests/Makefile.am   |  5 +++++
+ libnozzle/tests/Makefile.am |  5 +++++
+ 5 files changed, 48 insertions(+)
+
+diff --git a/Makefile.am b/Makefile.am
+index 047127d5..263584f3 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -167,6 +167,11 @@ if BUILD_MAN
+ 	sed -i -e "s#@buildman@#bcond_without#g" $@-t
+ else
+ 	sed -i -e "s#@buildman@#bcond_with#g" $@-t
++endif
++if INSTALL_TESTS
++	sed -i -e "s#@installtests@#bcond_without#g" $@-t
++else
++	sed -i -e "s#@installtests@#bcond_with#g" $@-t
+ endif
+ 	sed -i -e "s#@defaultadmgroup@#$(DEFAULTADMGROUP)#g" $@-t
+ 	chmod a-w $@-t
+diff --git a/configure.ac b/configure.ac
+index 87045433..d358abce 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -144,6 +144,11 @@ KNET_OPTION_DEFINES([bzip2],[compress],[
+ 				[AC_MSG_ERROR(["missing required bzlib.h"])])])
+ ])
+ 
++AC_ARG_ENABLE([install-tests],
++	[AS_HELP_STRING([--enable-install-tests],[install tests])],,
++	[ enable_install_tests="no" ])
++AM_CONDITIONAL([INSTALL_TESTS], [test x$enable_install_tests = xyes])
++
+ AC_ARG_ENABLE([poc],
+ 	[AS_HELP_STRING([--enable-poc],[enable building poc code])],,
+ 	[ enable_poc="no" ])
+@@ -294,6 +299,11 @@ fi
+ AC_ARG_ENABLE([debug],
+ 	[AS_HELP_STRING([--enable-debug],[enable debug build])])
+ 
++AC_ARG_WITH([testdir],
++	[AS_HELP_STRING([--with-testdir=DIR],[path to /usr/lib../kronosnet/tests/ dir where to install the test suite])],
++	[ TESTDIR="$withval" ],
++	[ TESTDIR="$libdir/kronosnet/tests" ])
++
+ AC_ARG_WITH([initdefaultdir],
+ 	[AS_HELP_STRING([--with-initdefaultdir=DIR],[path to /etc/sysconfig or /etc/default dir])],
+ 	[ INITDEFAULTDIR="$withval" ],
+@@ -333,6 +343,7 @@ DEFAULT_CONFIG_DIR=${sysconfdir}/kronosnet
+ 
+ ## do subst
+ 
++AC_SUBST([TESTDIR])
+ AC_SUBST([DEFAULT_CONFIG_DIR])
+ AC_SUBST([INITDEFAULTDIR])
+ AC_SUBST([INITDDIR])
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 9caf13b9..bb6f073a 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -30,6 +30,7 @@
+ %@rpmdebuginfo@ rpmdebuginfo
+ %@overriderpmdebuginfo@ overriderpmdebuginfo
+ %@buildman@ buildman
++%@installtests@ installtests
+ 
+ %if %{with overriderpmdebuginfo}
+ %undefine _enable_debug_packages
+@@ -72,6 +73,9 @@
+ %if %{with buildman}
+ %global buildmanpages 1
+ %endif
++%if %{with installtests}
++%global installtestsuite 1
++%endif
+ 
+ # main (empty) package
+ # http://www.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html
+@@ -140,6 +144,11 @@ BuildRequires: libtool
+ %endif
+ 
+ %{configure} \
++%if %{defined installtestsuite}
++	--enable-install-tests \
++%else
++	--disable-install-tests \
++%endif
+ %if %{defined buildmanpages}
+ 	--enable-man \
+ %else
+@@ -531,6 +540,19 @@ Requires: libknet1-crypto-plugins-all
+ 
+ %files -n libknet1-plugins-all
+ 
++%if %{with installtests}
++%package -n kronosnet-tests
++Group: System Environment/Libraries
++Summary: kronosnet test suite
++
++%description -n kronosnet-tests
++ this package contains all the libknet and libnozzle test suite
++
++%files -n kronosnet-tests
++%defattr(-,root,root,-)
++%{_libdir}/kronosnet/tests/*
++%endif
++
+ %if %{with rpmdebuginfo}
+ %debug_package
+ %endif
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 02eef6c1..f5fcedb9 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -51,6 +51,11 @@ noinst_SCRIPTS		= \
+ 
+ TESTS			= $(check_PROGRAMS)
+ 
++if INSTALL_TESTS
++testsuitedir		= $(TESTDIR)
++testsuite_PROGRAMS	= $(noinst_PROGRAMS)
++endif
++
+ check-local: check-api-test-coverage
+ 
+ check-api-test-coverage:
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 9a732d52..c7adbe4c 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -58,6 +58,11 @@ noinst_SCRIPTS		= \
+ 
+ TESTS			= $(check_PROGRAMS)
+ 
++if INSTALL_TESTS
++testsuitedir		= $(TESTDIR)
++testsuite_PROGRAMS	= $(noinst_PROGRAMS)
++endif
++
+ check-local: check-api-test-coverage
+ 
+ check-api-test-coverage:
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0187-manpages-Document-enums-206.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0187-manpages-Document-enums-206.patch
new file mode 100644
index 000000000..ac70cf54e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0187-manpages-Document-enums-206.patch
@@ -0,0 +1,184 @@ 
+From 991487ddff8e6c817d8c18d5883a5b742fca3171 Mon Sep 17 00:00:00 2001
+From: Chrissie Caulfield <ccaulfie@redhat.com>
+Date: Tue, 12 Mar 2019 13:55:25 +0000
+Subject: [PATCH] manpages: Document enums (#206)
+
+And also fix a bug in structure printing that caused it to print the wrong name for a struct.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/doxyxml.c | 79 ++++++++++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 68 insertions(+), 11 deletions(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 0caaf9b0..b4b49a9e 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+@@ -61,6 +61,7 @@ struct param_info {
+ };
+ 
+ struct struct_info {
++	enum {STRUCTINFO_STRUCT, STRUCTINFO_ENUM} kind;
+ 	char *structname;
+ 	struct qb_list_head params_list; /* our params */
+ 	struct qb_list_head list;
+@@ -245,6 +246,18 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 	return strdup(buffer);
+ }
+ 
++static void read_structname(xmlNode *cur_node, void *arg)
++{
++	struct struct_info *si=arg;
++	xmlNode *this_tag;
++
++	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
++		if (strcmp((char*)this_tag->name, "compoundname") == 0) {
++			si->structname = strdup((char*)this_tag->children->content);
++		}
++	}
++}
++
+ /* Called from traverse_node() */
+ static void read_struct(xmlNode *cur_node, void *arg)
+ {
+@@ -272,7 +285,7 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ 		pi = malloc(sizeof(struct param_info));
+ 		if (pi) {
+ 			snprintf(fullname, sizeof(fullname), "%s%s", name, args);
+-			pi->paramtype = strdup(type);
++			pi->paramtype = type?strdup(type):strdup("");
+ 			pi->paramname = strdup(fullname);
+ 			pi->paramdesc = NULL;
+ 			qb_list_add_tail(&pi->list, &si->params_list);
+@@ -304,9 +317,10 @@ static int read_structure_from_xml(char *refid, char *name)
+ 
+ 	si = malloc(sizeof(struct struct_info));
+ 	if (si) {
++		si->kind = STRUCTINFO_STRUCT;
+ 		qb_list_init(&si->params_list);
+-		si->structname = strdup(name);
+ 		traverse_node(rootdoc, "memberdef", read_struct, si);
++		traverse_node(rootdoc, "compounddef", read_structname, si);
+ 		ret = 0;
+ 		qb_map_put(structures_map, refid, si);
+ 	}
+@@ -315,12 +329,13 @@ static int read_structure_from_xml(char *refid, char *name)
+ 	return ret;
+ }
+ 
+-/* Reformat pointer params so they look nicer */
++
+ static void print_param(FILE *manfile, struct param_info *pi, int field_width, int bold, const char *delimiter)
+ {
+ 	char asterisk = ' ';
+ 	char *type = pi->paramtype;
+ 
++	/* Reformat pointer params so they look nicer */
+ 	if (pi->paramtype[strlen(pi->paramtype)-1] == '*') {
+ 		asterisk='*';
+ 		type = strdup(pi->paramtype);
+@@ -359,7 +374,13 @@ static void print_structure(FILE *manfile, char *refid, char *name)
+ 			}
+ 		}
+ 
+-		fprintf(manfile, "struct %s {\n", si->structname);
++		if (si->kind == STRUCTINFO_STRUCT) {
++			fprintf(manfile, "struct %s {\n", si->structname);
++		} else if (si->kind == STRUCTINFO_ENUM) {
++			fprintf(manfile, "enum %s {\n", si->structname);
++		} else {
++			fprintf(manfile, "%s {\n", si->structname);
++		}
+ 
+ 		qb_list_for_each(iter, &si->params_list) {
+ 			pi = qb_list_entry(iter, struct param_info, list);
+@@ -393,7 +414,8 @@ char *get_texttree(int *type, xmlNode *cur_node, char **returntext)
+ }
+ 
+ /* The text output is VERY basic and just a check that it's working really */
+-static void print_text(char *name, char *def, char *brief, char *args, char *detailed, struct qb_list_head *param_list, char *returntext)
++static void print_text(char *name, char *def, char *brief, char *args, char *detailed,
++		       struct qb_list_head *param_list, char *returntext)
+ {
+ 	printf(" ------------------ %s --------------------\n", name);
+ 	printf("NAME\n");
+@@ -430,7 +452,8 @@ static void man_print_long_string(FILE *manfile, char *text)
+ 	}
+ }
+ 
+-static void print_manpage(char *name, char *def, char *brief, char *args, char *detailed, struct qb_list_head *param_map, char *returntext)
++static void print_manpage(char *name, char *def, char *brief, char *args, char *detailed,
++			  struct qb_list_head *param_map, char *returntext)
+ {
+ 	char manfilename[PATH_MAX];
+ 	char gendate[64];
+@@ -640,6 +663,41 @@ static void collect_functions(xmlNode *cur_node, void *arg)
+ 	}
+ }
+ 
++/* Same as traverse_members, but to collect enums. The behave like structures for,
++   but, for some reason, are in the main XML file rather than their own */
++static void collect_enums(xmlNode *cur_node, void *arg)
++{
++	xmlNode *this_tag;
++	struct struct_info *si;
++	char *kind;
++	char *refid = NULL;
++	char *name = NULL;
++
++	if (cur_node->name && strcmp((char *)cur_node->name, "memberdef") == 0) {
++
++		kind = get_attr(cur_node, "kind");
++		if (kind && strcmp(kind, "enum") == 0) {
++			refid = get_attr(cur_node, "id");
++
++			for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
++				if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0) {
++					name = strdup((char *)this_tag->children->content);
++				}
++			}
++
++			si = malloc(sizeof(struct struct_info));
++			if (si) {
++				si->kind = STRUCTINFO_ENUM;
++				qb_list_init(&si->params_list);
++				si->structname = strdup(name);
++				traverse_node(cur_node, "enumvalue", read_struct, si);
++				qb_map_put(structures_map, refid, si);
++			}
++
++		}
++
++	}
++}
+ 
+ static void traverse_members(xmlNode *cur_node, void *arg)
+ {
+@@ -698,10 +756,6 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 			}
+ 		}
+ 
+-		if (kind && strcmp(kind, "typedef") == 0) {
+-			/* Collect typedefs? */
+-		}
+-
+ 		if (kind && strcmp(kind, "function") == 0) {
+ 
+ 			/* Make sure function has a doxygen description */
+@@ -856,6 +910,9 @@ int main(int argc, char *argv[])
+ 	/* Collect functions */
+ 	traverse_node(rootdoc, "memberdef", collect_functions, NULL);
+ 
++	/* Collect enums */
++	traverse_node(rootdoc, "memberdef", collect_enums, NULL);
++
+ 	/* print pages */
+ 	traverse_node(rootdoc, "memberdef", traverse_members, NULL);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0188-tests-test-rpm-should-match-currently-installed-vers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0188-tests-test-rpm-should-match-currently-installed-vers.patch
new file mode 100644
index 000000000..fb2306a84
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0188-tests-test-rpm-should-match-currently-installed-vers.patch
@@ -0,0 +1,23 @@ 
+From ee92f8c0f186d0aaa1d1f5811208eff3ea69749d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 15 Mar 2019 07:00:47 +0100
+Subject: [PATCH] [tests] test rpm should match currently installed version of
+ libknet
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index bb6f073a..a6468822 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -544,6 +544,7 @@ Requires: libknet1-crypto-plugins-all
+ %package -n kronosnet-tests
+ Group: System Environment/Libraries
+ Summary: kronosnet test suite
++Requires: libknet1 = %{version}-%{release}
+ 
+ %description -n kronosnet-tests
+  this package contains all the libknet and libnozzle test suite
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0189-transports-fix-usage-after-free-of-transport-info-me.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0189-transports-fix-usage-after-free-of-transport-info-me.patch
new file mode 100644
index 000000000..df00b44ed
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0189-transports-fix-usage-after-free-of-transport-info-me.patch
@@ -0,0 +1,51 @@ 
+From 54c6f18226032bf69d035cf3ce6df1e7309f8aff Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 24 Mar 2019 07:29:57 +0100
+Subject: [PATCH] [transports] fix usage after free of transport info memory
+
+spotted while implementing functional testing for rekey.
+
+when configuring multiple hosts (3+) with 1 link sharing
+the same listener, but NOT enabling the link, if the user
+attempts to shutdown knet_h, the first call to knet_link_clear_config
+will not recognize that the listener is still in use by another
+link and will release all resources.
+At the time of invoking clear_config on the second link, transport_clear_config
+will access already freed memory, or alternatively, a call to
+link_enable would cause a crash because the listener does no
+longer exist.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 3 +--
+ libknet/transport_udp.c  | 3 +--
+ 2 files changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 83fc359c..5bf898c6 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1043,8 +1043,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 
+ 			link_info = host->link[link_idx].transport_link;
+ 			if ((link_info) &&
+-			    (link_info->listener == info) &&
+-			    (host->link[link_idx].status.enabled == 1)) {
++			    (link_info->listener == info)) {
+ 				found = 1;
+ 				break;
+ 			}
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 31445023..3b7b8d1b 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -186,8 +186,7 @@ int udp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_l
+ 			if (&host->link[link_idx] == kn_link)
+ 				continue;
+ 
+-			if ((host->link[link_idx].transport_link == info) &&
+-			    (host->link[link_idx].status.enabled == 1)) {
++			if (host->link[link_idx].transport_link == info) {
+ 				found = 1;
+ 				break;
+ 			}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0190-link-Check-address-families-on-a-link-always-match.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0190-link-Check-address-families-on-a-link-always-match.patch
new file mode 100644
index 000000000..2e43a8cad
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0190-link-Check-address-families-on-a-link-always-match.patch
@@ -0,0 +1,70 @@ 
+From a9c36a6914a5ff5837d67ded938a03baa1be5d56 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Tue, 26 Mar 2019 13:44:25 +0100
+Subject: [PATCH] link: Check address families on a link always match
+
+We can't create a link with a source address of a different
+address family than the destination as all sends will fail.
+---
+ libknet/links.c                          |  6 ++++++
+ libknet/tests/api_knet_link_set_config.c | 23 +++++++++++++++++++++++
+ 2 files changed, 29 insertions(+)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index ba28dbd9..e68b2c81 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -99,6 +99,12 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		return -1;
+ 	}
+ 
++	if (dst_addr && (src_addr->ss_family != dst_addr->ss_family)) {
++		log_err(knet_h, KNET_SUB_LINK, "Source address family does not match destination address family");
++		errno = EINVAL;
++		return -1;
++	}
++
+ 	if (transport >= KNET_MAX_TRANSPORTS) {
+ 		errno = EINVAL;
+ 		return -1;
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index 670869ef..a821948f 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -111,6 +111,24 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_link_set_config with conflicting address families\n");
++
++	if (make_local_sockaddr6(&dst, 1) < 0) {
++		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) == 0) {
++		printf("knet_link_set_config accepted invalid address families: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
+ 	printf("Test knet_link_set_config with dynamic dst_addr\n");
+ 
+ 	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, NULL, 0) < 0) {
+@@ -212,6 +230,11 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with static dst_addr\n");
+ 
++	if (make_local_sockaddr(&dst, 1) < 0) {
++		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
+ 	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0191-global-update-copyright-across-the-board.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0191-global-update-copyright-across-the-board.patch
new file mode 100644
index 000000000..639c67741
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0191-global-update-copyright-across-the-board.patch
@@ -0,0 +1,2443 @@ 
+From ae39d1f2a350c179b389a832e8e2bd4133eba9ac Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 26 Mar 2019 15:08:14 +0100
+Subject: [PATCH] [global] update copyright across the board
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ COPYRIGHT                                                     | 2 +-
+ Makefile.am                                                   | 2 +-
+ README                                                        | 2 +-
+ autogen.sh                                                    | 2 +-
+ build-aux/check.mk                                            | 2 +-
+ build-aux/git-version-gen                                     | 2 +-
+ build-aux/release.mk                                          | 2 +-
+ configure.ac                                                  | 2 +-
+ init/Makefile.am                                              | 2 +-
+ init/kronosnetd.default                                       | 2 +-
+ init/kronosnetd.in                                            | 2 +-
+ init/kronosnetd.service.in                                    | 2 +-
+ kronosnet.spec.in                                             | 2 +-
+ kronosnetd/Makefile.am                                        | 2 +-
+ kronosnetd/cfg.c                                              | 2 +-
+ kronosnetd/cfg.h                                              | 2 +-
+ kronosnetd/etherfilter.c                                      | 2 +-
+ kronosnetd/etherfilter.h                                      | 2 +-
+ kronosnetd/keygen.c                                           | 2 +-
+ kronosnetd/kronosnetd.logrotate.in                            | 2 +-
+ kronosnetd/logging.c                                          | 2 +-
+ kronosnetd/logging.h                                          | 2 +-
+ kronosnetd/main.c                                             | 2 +-
+ kronosnetd/vty.c                                              | 2 +-
+ kronosnetd/vty.h                                              | 2 +-
+ kronosnetd/vty_auth.c                                         | 2 +-
+ kronosnetd/vty_auth.h                                         | 2 +-
+ kronosnetd/vty_cli.c                                          | 2 +-
+ kronosnetd/vty_cli.h                                          | 2 +-
+ kronosnetd/vty_cli_cmds.c                                     | 2 +-
+ kronosnetd/vty_cli_cmds.h                                     | 2 +-
+ kronosnetd/vty_utils.c                                        | 2 +-
+ kronosnetd/vty_utils.h                                        | 2 +-
+ libknet/Makefile.am                                           | 2 +-
+ libknet/common.c                                              | 2 +-
+ libknet/common.h                                              | 2 +-
+ libknet/compat.c                                              | 2 +-
+ libknet/compat.h                                              | 2 +-
+ libknet/compress.c                                            | 2 +-
+ libknet/compress.h                                            | 2 +-
+ libknet/compress_bzip2.c                                      | 2 +-
+ libknet/compress_lz4.c                                        | 2 +-
+ libknet/compress_lz4hc.c                                      | 2 +-
+ libknet/compress_lzma.c                                       | 2 +-
+ libknet/compress_lzo2.c                                       | 2 +-
+ libknet/compress_model.h                                      | 2 +-
+ libknet/compress_zlib.c                                       | 2 +-
+ libknet/crypto.c                                              | 2 +-
+ libknet/crypto.h                                              | 2 +-
+ libknet/crypto_model.h                                        | 2 +-
+ libknet/crypto_nss.c                                          | 2 +-
+ libknet/crypto_openssl.c                                      | 2 +-
+ libknet/handle.c                                              | 2 +-
+ libknet/host.c                                                | 2 +-
+ libknet/host.h                                                | 2 +-
+ libknet/internals.h                                           | 2 +-
+ libknet/libknet.h                                             | 4 ++--
+ libknet/libknet.pc.in                                         | 2 +-
+ libknet/libknet_exported_syms                                 | 2 +-
+ libknet/links.c                                               | 2 +-
+ libknet/links.h                                               | 2 +-
+ libknet/logging.c                                             | 2 +-
+ libknet/logging.h                                             | 2 +-
+ libknet/netutils.c                                            | 2 +-
+ libknet/netutils.h                                            | 2 +-
+ libknet/onwire.h                                              | 2 +-
+ libknet/tests/Makefile.am                                     | 2 +-
+ libknet/tests/api-check.mk                                    | 2 +-
+ libknet/tests/api-test-coverage                               | 2 +-
+ libknet/tests/api_knet_addrtostr.c                            | 2 +-
+ libknet/tests/api_knet_get_compress_list.c                    | 2 +-
+ libknet/tests/api_knet_get_crypto_list.c                      | 2 +-
+ libknet/tests/api_knet_get_transport_id_by_name.c             | 2 +-
+ libknet/tests/api_knet_get_transport_list.c                   | 2 +-
+ libknet/tests/api_knet_get_transport_name_by_id.c             | 2 +-
+ libknet/tests/api_knet_handle_add_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_clear_stats.c                   | 2 +-
+ libknet/tests/api_knet_handle_compress.c                      | 2 +-
+ libknet/tests/api_knet_handle_crypto.c                        | 2 +-
+ libknet/tests/api_knet_handle_enable_filter.c                 | 2 +-
+ libknet/tests/api_knet_handle_enable_pmtud_notify.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_sock_notify.c            | 2 +-
+ libknet/tests/api_knet_handle_free.c                          | 2 +-
+ libknet/tests/api_knet_handle_get_channel.c                   | 2 +-
+ libknet/tests/api_knet_handle_get_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_get_stats.c                     | 2 +-
+ .../tests/api_knet_handle_get_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_new.c                           | 2 +-
+ libknet/tests/api_knet_handle_new_limit.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_get.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_getfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_pmtud_setfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_remove_datafd.c                 | 2 +-
+ .../tests/api_knet_handle_set_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_setfwd.c                        | 2 +-
+ libknet/tests/api_knet_host_add.c                             | 2 +-
+ libknet/tests/api_knet_host_enable_status_change_notify.c     | 2 +-
+ libknet/tests/api_knet_host_get_host_list.c                   | 2 +-
+ libknet/tests/api_knet_host_get_id_by_host_name.c             | 2 +-
+ libknet/tests/api_knet_host_get_name_by_host_id.c             | 2 +-
+ libknet/tests/api_knet_host_get_policy.c                      | 2 +-
+ libknet/tests/api_knet_host_get_status.c                      | 2 +-
+ libknet/tests/api_knet_host_remove.c                          | 2 +-
+ libknet/tests/api_knet_host_set_name.c                        | 2 +-
+ libknet/tests/api_knet_host_set_policy.c                      | 2 +-
+ libknet/tests/api_knet_link_clear_config.c                    | 2 +-
+ libknet/tests/api_knet_link_get_config.c                      | 2 +-
+ libknet/tests/api_knet_link_get_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_get_link_list.c                   | 2 +-
+ libknet/tests/api_knet_link_get_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_get_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_get_priority.c                    | 2 +-
+ libknet/tests/api_knet_link_get_status.c                      | 2 +-
+ libknet/tests/api_knet_link_set_config.c                      | 2 +-
+ libknet/tests/api_knet_link_set_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_set_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_set_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_set_priority.c                    | 2 +-
+ libknet/tests/api_knet_log_get_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_id.c                  | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_name.c                | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_id.c                 | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_name.c               | 2 +-
+ libknet/tests/api_knet_log_set_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_recv.c                                 | 2 +-
+ libknet/tests/api_knet_send.c                                 | 2 +-
+ libknet/tests/api_knet_send_compress.c                        | 2 +-
+ libknet/tests/api_knet_send_crypto.c                          | 2 +-
+ libknet/tests/api_knet_send_loopback.c                        | 2 +-
+ libknet/tests/api_knet_send_sync.c                            | 2 +-
+ libknet/tests/api_knet_strtoaddr.c                            | 2 +-
+ libknet/tests/int_timediff.c                                  | 2 +-
+ libknet/tests/knet_bench.c                                    | 2 +-
+ libknet/tests/pckt_test.c                                     | 2 +-
+ libknet/tests/test-common.c                                   | 2 +-
+ libknet/tests/test-common.h                                   | 2 +-
+ libknet/threads_common.c                                      | 2 +-
+ libknet/threads_common.h                                      | 2 +-
+ libknet/threads_dsthandler.c                                  | 2 +-
+ libknet/threads_dsthandler.h                                  | 2 +-
+ libknet/threads_heartbeat.c                                   | 2 +-
+ libknet/threads_heartbeat.h                                   | 2 +-
+ libknet/threads_pmtud.c                                       | 2 +-
+ libknet/threads_pmtud.h                                       | 2 +-
+ libknet/threads_rx.c                                          | 2 +-
+ libknet/threads_rx.h                                          | 2 +-
+ libknet/threads_tx.c                                          | 2 +-
+ libknet/threads_tx.h                                          | 2 +-
+ libknet/transport_common.c                                    | 2 +-
+ libknet/transport_common.h                                    | 2 +-
+ libknet/transport_loopback.c                                  | 2 +-
+ libknet/transport_loopback.h                                  | 2 +-
+ libknet/transport_sctp.c                                      | 2 +-
+ libknet/transport_sctp.h                                      | 2 +-
+ libknet/transport_udp.c                                       | 2 +-
+ libknet/transport_udp.h                                       | 2 +-
+ libknet/transports.c                                          | 2 +-
+ libknet/transports.h                                          | 2 +-
+ libnozzle/Makefile.am                                         | 2 +-
+ libnozzle/internals.c                                         | 2 +-
+ libnozzle/internals.h                                         | 2 +-
+ libnozzle/libnozzle.c                                         | 2 +-
+ libnozzle/libnozzle.h                                         | 4 ++--
+ libnozzle/libnozzle.pc.in                                     | 2 +-
+ libnozzle/libnozzle_exported_syms                             | 2 +-
+ libnozzle/tests/Makefile.am                                   | 2 +-
+ libnozzle/tests/api-test-coverage                             | 2 +-
+ libnozzle/tests/api_nozzle_add_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_close.c                            | 2 +-
+ libnozzle/tests/api_nozzle_del_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_fd.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_handle_by_name.c               | 2 +-
+ libnozzle/tests/api_nozzle_get_ips.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_name_by_handle.c               | 2 +-
+ libnozzle/tests/api_nozzle_open.c                             | 2 +-
+ libnozzle/tests/api_nozzle_run_updown.c                       | 2 +-
+ libnozzle/tests/api_nozzle_set_down.c                         | 2 +-
+ libnozzle/tests/api_nozzle_set_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_up.c                           | 2 +-
+ libnozzle/tests/int_execute_bin_sh_command.c                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_false                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_true                   | 2 +-
+ libnozzle/tests/test-common.c                                 | 2 +-
+ libnozzle/tests/test-common.h                                 | 2 +-
+ man/Doxyfile-knet.in                                          | 2 +-
+ man/Doxyfile-nozzle.in                                        | 2 +-
+ man/Makefile.am                                               | 2 +-
+ man/api-to-man-page-coverage                                  | 2 +-
+ man/knet-keygen.8                                             | 2 +-
+ man/kronosnetd.8                                              | 2 +-
+ poc-code/Makefile.am                                          | 2 +-
+ poc-code/access-list/Makefile.am                              | 2 +-
+ poc-code/access-list/ipcheck.c                                | 2 +-
+ poc-code/access-list/ipcheck.h                                | 2 +-
+ poc-code/access-list/test_ipcheck.c                           | 2 +-
+ poc-code/iov-hash/Makefile.am                                 | 2 +-
+ poc-code/iov-hash/main.c                                      | 2 +-
+ 200 files changed, 202 insertions(+), 202 deletions(-)
+
+diff --git a/COPYRIGHT b/COPYRIGHT
+index de03ceda..da386c75 100644
+--- a/COPYRIGHT
++++ b/COPYRIGHT
+@@ -1,4 +1,4 @@
+-Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ 
+ Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+          Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/Makefile.am b/Makefile.am
+index 263584f3..24a13a64 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/README b/README
+index a50f27fd..7b5e7ce6 100644
+--- a/README
++++ b/README
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/autogen.sh b/autogen.sh
+index c67a4206..8fb1e58a 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index 58370bba..6da44177 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index fc70e306..cb0b2894 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -2,7 +2,7 @@
+ # Print a version string.
+ scriptversion=2018-08-31.20; # UTC
+ 
+-# Copyright (C) 2012-2018 Red Hat, Inc.
++# Copyright (C) 2012-2019 Red Hat, Inc.
+ # Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ #
+ # This program is free software: you can redistribute it and/or modify
+diff --git a/build-aux/release.mk b/build-aux/release.mk
+index 3783ae12..de3599df 100644
+--- a/build-aux/release.mk
++++ b/build-aux/release.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/configure.ac b/configure.ac
+index d358abce..9df68314 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/init/Makefile.am b/init/Makefile.am
+index 7837ce37..4d59a9e8 100644
+--- a/init/Makefile.am
++++ b/init/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/init/kronosnetd.default b/init/kronosnetd.default
+index 4ac9e6b5..ed946480 100644
+--- a/init/kronosnetd.default
++++ b/init/kronosnetd.default
+@@ -1,6 +1,6 @@
+ # kronosnetd startup options (see man kronosnetd.8)
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/init/kronosnetd.in b/init/kronosnetd.in
+index 02d9232c..1823a3b2 100644
+--- a/init/kronosnetd.in
++++ b/init/kronosnetd.in
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/init/kronosnetd.service.in b/init/kronosnetd.service.in
+index ab6fd5af..4d2a32ab 100644
+--- a/init/kronosnetd.service.in
++++ b/init/kronosnetd.service.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index a6468822..2d4d059f 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -1,7 +1,7 @@
+ ###############################################################################
+ ###############################################################################
+ ##
+-##  Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++##  Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ ##
+ ##  This copyrighted material is made available to anyone wishing to use,
+ ##  modify, copy, or redistribute it subject to the terms and conditions
+diff --git a/kronosnetd/Makefile.am b/kronosnetd/Makefile.am
+index 9dfb2445..0b6f673b 100644
+--- a/kronosnetd/Makefile.am
++++ b/kronosnetd/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/kronosnetd/cfg.c b/kronosnetd/cfg.c
+index d2663926..69d209a1 100644
+--- a/kronosnetd/cfg.c
++++ b/kronosnetd/cfg.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/cfg.h b/kronosnetd/cfg.h
+index b884ffb4..0260bff6 100644
+--- a/kronosnetd/cfg.h
++++ b/kronosnetd/cfg.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/etherfilter.c b/kronosnetd/etherfilter.c
+index 5a16c311..8542061c 100644
+--- a/kronosnetd/etherfilter.c
++++ b/kronosnetd/etherfilter.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/etherfilter.h b/kronosnetd/etherfilter.h
+index 16ce615a..d805dd6d 100644
+--- a/kronosnetd/etherfilter.h
++++ b/kronosnetd/etherfilter.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/keygen.c b/kronosnetd/keygen.c
+index 24e00a2f..eb914734 100644
+--- a/kronosnetd/keygen.c
++++ b/kronosnetd/keygen.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/kronosnetd.logrotate.in b/kronosnetd/kronosnetd.logrotate.in
+index 75d1086d..4ed1fd2a 100644
+--- a/kronosnetd/kronosnetd.logrotate.in
++++ b/kronosnetd/kronosnetd.logrotate.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/kronosnetd/logging.c b/kronosnetd/logging.c
+index 6e7bfc51..b3ef0d11 100644
+--- a/kronosnetd/logging.c
++++ b/kronosnetd/logging.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/logging.h b/kronosnetd/logging.h
+index b8d88ad6..e4d5ce28 100644
+--- a/kronosnetd/logging.h
++++ b/kronosnetd/logging.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/main.c b/kronosnetd/main.c
+index 2ea9c92c..c1a8c2b1 100644
+--- a/kronosnetd/main.c
++++ b/kronosnetd/main.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty.c b/kronosnetd/vty.c
+index efd2ea0c..d624bf4b 100644
+--- a/kronosnetd/vty.c
++++ b/kronosnetd/vty.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty.h b/kronosnetd/vty.h
+index 7778f76b..86bd8212 100644
+--- a/kronosnetd/vty.h
++++ b/kronosnetd/vty.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty_auth.c b/kronosnetd/vty_auth.c
+index 9cf89888..cf997f92 100644
+--- a/kronosnetd/vty_auth.c
++++ b/kronosnetd/vty_auth.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_auth.h b/kronosnetd/vty_auth.h
+index f0d64be9..c42989b7 100644
+--- a/kronosnetd/vty_auth.h
++++ b/kronosnetd/vty_auth.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_cli.c b/kronosnetd/vty_cli.c
+index b1a40d59..68ff0dad 100644
+--- a/kronosnetd/vty_cli.c
++++ b/kronosnetd/vty_cli.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty_cli.h b/kronosnetd/vty_cli.h
+index 81110a11..9bbdcc70 100644
+--- a/kronosnetd/vty_cli.h
++++ b/kronosnetd/vty_cli.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_cli_cmds.c b/kronosnetd/vty_cli_cmds.c
+index bf795e6e..18b11a0c 100644
+--- a/kronosnetd/vty_cli_cmds.c
++++ b/kronosnetd/vty_cli_cmds.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty_cli_cmds.h b/kronosnetd/vty_cli_cmds.h
+index 077305ae..ac07573f 100644
+--- a/kronosnetd/vty_cli_cmds.h
++++ b/kronosnetd/vty_cli_cmds.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_utils.c b/kronosnetd/vty_utils.c
+index 52117cce..3c5cc865 100644
+--- a/kronosnetd/vty_utils.c
++++ b/kronosnetd/vty_utils.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_utils.h b/kronosnetd/vty_utils.h
+index c494d4d4..07e339be 100644
+--- a/kronosnetd/vty_utils.h
++++ b/kronosnetd/vty_utils.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index b0a20569..906fd011 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/common.c b/libknet/common.c
+index 52563dde..c908e23f 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/common.h b/libknet/common.h
+index 7e41efd9..ddea7fcd 100644
+--- a/libknet/common.h
++++ b/libknet/common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/compat.c b/libknet/compat.c
+index 105c6e86..a60bca28 100644
+--- a/libknet/compat.c
++++ b/libknet/compat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compat.h b/libknet/compat.h
+index aa528c6c..e9af804d 100644
+--- a/libknet/compat.h
++++ b/libknet/compat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 8af7beff..278ff443 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress.h b/libknet/compress.h
+index c19a5091..47edddfb 100644
+--- a/libknet/compress.h
++++ b/libknet/compress.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c
+index 5b47e1c9..521e2069 100644
+--- a/libknet/compress_bzip2.c
++++ b/libknet/compress_bzip2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c
+index 263428a3..22b926fd 100644
+--- a/libknet/compress_lz4.c
++++ b/libknet/compress_lz4.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c
+index da40fbc9..9a69ab4c 100644
+--- a/libknet/compress_lz4hc.c
++++ b/libknet/compress_lz4hc.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
+index cd037403..e9ba2e30 100644
+--- a/libknet/compress_lzma.c
++++ b/libknet/compress_lzma.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c
+index be6eb900..e66d3dca 100644
+--- a/libknet/compress_lzo2.c
++++ b/libknet/compress_lzo2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_model.h b/libknet/compress_model.h
+index 5d6a640e..909f5a1d 100644
+--- a/libknet/compress_model.h
++++ b/libknet/compress_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c
+index 3f86ac14..8807bb47 100644
+--- a/libknet/compress_zlib.c
++++ b/libknet/compress_zlib.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 172bac7b..419f9ccc 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index b7e3aa60..707de327 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index c0c7a9e5..f11299a6 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index ae2d2b01..35afa0f9 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 1eb01b01..03d10147 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 5dab0cf0..b7aa2fd4 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.c b/libknet/host.c
+index 184ca203..480db733 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.h b/libknet/host.h
+index 1531c002..4336b17d 100644
+--- a/libknet/host.h
++++ b/libknet/host.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 20f7e105..57da5b4d 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index a5ce7fc7..36fefa5f 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+@@ -19,7 +19,7 @@
+ /**
+  * @file libknet.h
+  * @brief kronosnet API include file
+- * @copyright Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Kronosnet is an advanced VPN system for High Availability applications.
+  */
+diff --git a/libknet/libknet.pc.in b/libknet/libknet.pc.in
+index c7841412..bb7b25c7 100644
+--- a/libknet/libknet.pc.in
++++ b/libknet/libknet.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Federico Simoncelli <fsimon@kronosnet.org>
+ #
+diff --git a/libknet/libknet_exported_syms b/libknet/libknet_exported_syms
+index e5a29777..d8a55e22 100644
+--- a/libknet/libknet_exported_syms
++++ b/libknet/libknet_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libknet.so
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/links.c b/libknet/links.c
+index e68b2c81..010aeb69 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links.h b/libknet/links.h
+index 50936cc5..7c0250d2 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 14c6eff5..98bcfd14 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/logging.h b/libknet/logging.h
+index acf177bf..bdcd85e8 100644
+--- a/libknet/logging.h
++++ b/libknet/logging.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index f30054ba..72bc659e 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index 7e1cfbc2..bdc605e2 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index 5301ad20..ea45bfb4 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index f5fcedb9..c00e6247 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index bc4b8855..7beba539 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-test-coverage b/libknet/tests/api-test-coverage
+index 52cfb0e1..bf0ccc3f 100755
+--- a/libknet/tests/api-test-coverage
++++ b/libknet/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index 71fc2cfe..9adbf311 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/api_knet_get_compress_list.c b/libknet/tests/api_knet_get_compress_list.c
+index 2e4e58d5..230e2037 100644
+--- a/libknet/tests/api_knet_get_compress_list.c
++++ b/libknet/tests/api_knet_get_compress_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_crypto_list.c b/libknet/tests/api_knet_get_crypto_list.c
+index 7b9fd70e..4121aa40 100644
+--- a/libknet/tests/api_knet_get_crypto_list.c
++++ b/libknet/tests/api_knet_get_crypto_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_id_by_name.c b/libknet/tests/api_knet_get_transport_id_by_name.c
+index 97d8a6c3..973814f1 100644
+--- a/libknet/tests/api_knet_get_transport_id_by_name.c
++++ b/libknet/tests/api_knet_get_transport_id_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_list.c b/libknet/tests/api_knet_get_transport_list.c
+index 0c2fa938..c7489017 100644
+--- a/libknet/tests/api_knet_get_transport_list.c
++++ b/libknet/tests/api_knet_get_transport_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_name_by_id.c b/libknet/tests/api_knet_get_transport_name_by_id.c
+index 7f5fa46b..a797cec9 100644
+--- a/libknet/tests/api_knet_get_transport_name_by_id.c
++++ b/libknet/tests/api_knet_get_transport_name_by_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_add_datafd.c b/libknet/tests/api_knet_handle_add_datafd.c
+index 310cf92d..7159399e 100644
+--- a/libknet/tests/api_knet_handle_add_datafd.c
++++ b/libknet/tests/api_knet_handle_add_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index ff25613d..8e64235c 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 76a0ce67..1525e6a3 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index 97ff354e..1805909b 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_filter.c b/libknet/tests/api_knet_handle_enable_filter.c
+index 800dc494..63b2166f 100644
+--- a/libknet/tests/api_knet_handle_enable_filter.c
++++ b/libknet/tests/api_knet_handle_enable_filter.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_pmtud_notify.c b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+index 4bd371e7..726c2cc1 100644
+--- a/libknet/tests/api_knet_handle_enable_pmtud_notify.c
++++ b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_sock_notify.c b/libknet/tests/api_knet_handle_enable_sock_notify.c
+index b003fabf..9c906009 100644
+--- a/libknet/tests/api_knet_handle_enable_sock_notify.c
++++ b/libknet/tests/api_knet_handle_enable_sock_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_free.c b/libknet/tests/api_knet_handle_free.c
+index 0212af97..75319fc9 100644
+--- a/libknet/tests/api_knet_handle_free.c
++++ b/libknet/tests/api_knet_handle_free.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_channel.c b/libknet/tests/api_knet_handle_get_channel.c
+index e81b44c3..3ade3024 100644
+--- a/libknet/tests/api_knet_handle_get_channel.c
++++ b/libknet/tests/api_knet_handle_get_channel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_datafd.c b/libknet/tests/api_knet_handle_get_datafd.c
+index c08d257c..8838b696 100644
+--- a/libknet/tests/api_knet_handle_get_datafd.c
++++ b/libknet/tests/api_knet_handle_get_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_stats.c b/libknet/tests/api_knet_handle_get_stats.c
+index c34244f6..e8a83b4c 100644
+--- a/libknet/tests/api_knet_handle_get_stats.c
++++ b/libknet/tests/api_knet_handle_get_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+index d38a29c9..7a43823f 100644
+--- a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_new.c b/libknet/tests/api_knet_handle_new.c
+index f3c546f4..b7af5664 100644
+--- a/libknet/tests/api_knet_handle_new.c
++++ b/libknet/tests/api_knet_handle_new.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_new_limit.c b/libknet/tests/api_knet_handle_new_limit.c
+index 36d1c087..d51db975 100644
+--- a/libknet/tests/api_knet_handle_new_limit.c
++++ b/libknet/tests/api_knet_handle_new_limit.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_get.c b/libknet/tests/api_knet_handle_pmtud_get.c
+index e2ba0312..a1b1d12f 100644
+--- a/libknet/tests/api_knet_handle_pmtud_get.c
++++ b/libknet/tests/api_knet_handle_pmtud_get.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_getfreq.c b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+index be42c3fc..5c5c7e0d 100644
+--- a/libknet/tests/api_knet_handle_pmtud_getfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_setfreq.c b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+index bce326ba..b4eebdad 100644
+--- a/libknet/tests/api_knet_handle_pmtud_setfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_remove_datafd.c b/libknet/tests/api_knet_handle_remove_datafd.c
+index c9ed7492..08a42abf 100644
+--- a/libknet/tests/api_knet_handle_remove_datafd.c
++++ b/libknet/tests/api_knet_handle_remove_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+index 69cc24ba..80bbacbd 100644
+--- a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_setfwd.c b/libknet/tests/api_knet_handle_setfwd.c
+index b29e1edf..96580759 100644
+--- a/libknet/tests/api_knet_handle_setfwd.c
++++ b/libknet/tests/api_knet_handle_setfwd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_add.c b/libknet/tests/api_knet_host_add.c
+index 773f477b..762d0dfa 100644
+--- a/libknet/tests/api_knet_host_add.c
++++ b/libknet/tests/api_knet_host_add.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_enable_status_change_notify.c b/libknet/tests/api_knet_host_enable_status_change_notify.c
+index 07611e57..96d133d1 100644
+--- a/libknet/tests/api_knet_host_enable_status_change_notify.c
++++ b/libknet/tests/api_knet_host_enable_status_change_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_host_list.c b/libknet/tests/api_knet_host_get_host_list.c
+index f4fde73a..76fb23bf 100644
+--- a/libknet/tests/api_knet_host_get_host_list.c
++++ b/libknet/tests/api_knet_host_get_host_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_id_by_host_name.c b/libknet/tests/api_knet_host_get_id_by_host_name.c
+index 7939a164..81ad504a 100644
+--- a/libknet/tests/api_knet_host_get_id_by_host_name.c
++++ b/libknet/tests/api_knet_host_get_id_by_host_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_name_by_host_id.c b/libknet/tests/api_knet_host_get_name_by_host_id.c
+index e08739c2..d239821c 100644
+--- a/libknet/tests/api_knet_host_get_name_by_host_id.c
++++ b/libknet/tests/api_knet_host_get_name_by_host_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_policy.c b/libknet/tests/api_knet_host_get_policy.c
+index ea545161..3160503a 100644
+--- a/libknet/tests/api_knet_host_get_policy.c
++++ b/libknet/tests/api_knet_host_get_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_status.c b/libknet/tests/api_knet_host_get_status.c
+index 3afc1cbd..b13c57a5 100644
+--- a/libknet/tests/api_knet_host_get_status.c
++++ b/libknet/tests/api_knet_host_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_remove.c b/libknet/tests/api_knet_host_remove.c
+index b808c2f4..12d1f8f9 100644
+--- a/libknet/tests/api_knet_host_remove.c
++++ b/libknet/tests/api_knet_host_remove.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_set_name.c b/libknet/tests/api_knet_host_set_name.c
+index 065b79a6..88d6ce91 100644
+--- a/libknet/tests/api_knet_host_set_name.c
++++ b/libknet/tests/api_knet_host_set_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_set_policy.c b/libknet/tests/api_knet_host_set_policy.c
+index 0572fba8..41102d20 100644
+--- a/libknet/tests/api_knet_host_set_policy.c
++++ b/libknet/tests/api_knet_host_set_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_clear_config.c b/libknet/tests/api_knet_link_clear_config.c
+index 3c9ca6c8..8d7800d2 100644
+--- a/libknet/tests/api_knet_link_clear_config.c
++++ b/libknet/tests/api_knet_link_clear_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_config.c b/libknet/tests/api_knet_link_get_config.c
+index 22daa9c8..111b4069 100644
+--- a/libknet/tests/api_knet_link_get_config.c
++++ b/libknet/tests/api_knet_link_get_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_enable.c b/libknet/tests/api_knet_link_get_enable.c
+index 135aa2c5..410c017f 100644
+--- a/libknet/tests/api_knet_link_get_enable.c
++++ b/libknet/tests/api_knet_link_get_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_link_list.c b/libknet/tests/api_knet_link_get_link_list.c
+index 890533c5..e3dd73ef 100644
+--- a/libknet/tests/api_knet_link_get_link_list.c
++++ b/libknet/tests/api_knet_link_get_link_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_ping_timers.c b/libknet/tests/api_knet_link_get_ping_timers.c
+index b388afae..5f0e9b1a 100644
+--- a/libknet/tests/api_knet_link_get_ping_timers.c
++++ b/libknet/tests/api_knet_link_get_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_pong_count.c b/libknet/tests/api_knet_link_get_pong_count.c
+index 76d6e6c1..bbc993d2 100644
+--- a/libknet/tests/api_knet_link_get_pong_count.c
++++ b/libknet/tests/api_knet_link_get_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_priority.c b/libknet/tests/api_knet_link_get_priority.c
+index 0a1743b8..29d7d2ea 100644
+--- a/libknet/tests/api_knet_link_get_priority.c
++++ b/libknet/tests/api_knet_link_get_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_status.c b/libknet/tests/api_knet_link_get_status.c
+index aff8a378..fe567343 100644
+--- a/libknet/tests/api_knet_link_get_status.c
++++ b/libknet/tests/api_knet_link_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index a821948f..8679428c 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_enable.c b/libknet/tests/api_knet_link_set_enable.c
+index 45e45053..f48f1c0a 100644
+--- a/libknet/tests/api_knet_link_set_enable.c
++++ b/libknet/tests/api_knet_link_set_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_ping_timers.c b/libknet/tests/api_knet_link_set_ping_timers.c
+index d6fa129c..d823a819 100644
+--- a/libknet/tests/api_knet_link_set_ping_timers.c
++++ b/libknet/tests/api_knet_link_set_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_pong_count.c b/libknet/tests/api_knet_link_set_pong_count.c
+index 60aee529..70fc57f3 100644
+--- a/libknet/tests/api_knet_link_set_pong_count.c
++++ b/libknet/tests/api_knet_link_set_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_priority.c b/libknet/tests/api_knet_link_set_priority.c
+index 2d5c79ae..a89392ec 100644
+--- a/libknet/tests/api_knet_link_set_priority.c
++++ b/libknet/tests/api_knet_link_set_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel.c b/libknet/tests/api_knet_log_get_loglevel.c
+index 57aadb9f..4a62ead6 100644
+--- a/libknet/tests/api_knet_log_get_loglevel.c
++++ b/libknet/tests/api_knet_log_get_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_id.c b/libknet/tests/api_knet_log_get_loglevel_id.c
+index 13173d47..1053dff5 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_id.c
++++ b/libknet/tests/api_knet_log_get_loglevel_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_name.c b/libknet/tests/api_knet_log_get_loglevel_name.c
+index 408007f3..317ebb10 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_name.c
++++ b/libknet/tests/api_knet_log_get_loglevel_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_id.c b/libknet/tests/api_knet_log_get_subsystem_id.c
+index 3039f9fd..0b47805c 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_id.c
++++ b/libknet/tests/api_knet_log_get_subsystem_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_name.c b/libknet/tests/api_knet_log_get_subsystem_name.c
+index f10c888e..1b11fe6b 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_name.c
++++ b/libknet/tests/api_knet_log_get_subsystem_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_set_loglevel.c b/libknet/tests/api_knet_log_set_loglevel.c
+index a343f2dc..e729113c 100644
+--- a/libknet/tests/api_knet_log_set_loglevel.c
++++ b/libknet/tests/api_knet_log_set_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_recv.c b/libknet/tests/api_knet_recv.c
+index a7fb266d..6e23353d 100644
+--- a/libknet/tests/api_knet_recv.c
++++ b/libknet/tests/api_knet_recv.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 3dfb6d0b..f2412015 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index e17061ed..6de46746 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index dfcc92ef..f2ca3662 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 369c15f3..16a46244 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 57a1ec9a..f2718c95 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index 08786034..57a8a0a1 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/int_timediff.c b/libknet/tests/int_timediff.c
+index 0006b625..12735d8f 100644
+--- a/libknet/tests/int_timediff.c
++++ b/libknet/tests/int_timediff.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index f60b5b1b..b208b3ea 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/pckt_test.c b/libknet/tests/pckt_test.c
+index 5e1d87d0..56cf0181 100644
+--- a/libknet/tests/pckt_test.c
++++ b/libknet/tests/pckt_test.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 729915f5..d0ea1ef8 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 6a0de762..8742f8d1 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 6f0ce4a4..b6012a23 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 1314c017..79aaed25 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 74e7ef07..2633188a 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.h b/libknet/threads_dsthandler.h
+index 6a29bf23..0c968ffe 100644
+--- a/libknet/threads_dsthandler.h
++++ b/libknet/threads_dsthandler.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 4685ee8f..5d4189f6 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.h b/libknet/threads_heartbeat.h
+index 87d5b583..2fcc9a05 100644
+--- a/libknet/threads_heartbeat.h
++++ b/libknet/threads_heartbeat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 33bee5ea..63504d67 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.h b/libknet/threads_pmtud.h
+index 23d16042..2cdcdbc6 100644
+--- a/libknet/threads_pmtud.h
++++ b/libknet/threads_pmtud.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 4877b729..8435d138 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.h b/libknet/threads_rx.h
+index d5cccd09..ff8bd6e8 100644
+--- a/libknet/threads_rx.h
++++ b/libknet/threads_rx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index da986140..fa911dcb 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.h b/libknet/threads_tx.h
+index 72bdd217..7c4b2c09 100644
+--- a/libknet/threads_tx.h
++++ b/libknet/threads_tx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index cd344932..3c3c439a 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 295d2b26..778af8b0 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index 834a5cc1..bf48bb93 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index 70dc7aac..3d072e8b 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 5bf898c6..cb64a325 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index 753cf2ac..f27bcf1e 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 3b7b8d1b..acfbab47 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index 01c27e64..bbb6ec95 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.c b/libknet/transports.c
+index b8713700..b6f3b646 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.h b/libknet/transports.h
+index ec1158b5..d58b7a39 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 3a49d23b..2ffbd086 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index c294eb4e..6e683463 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index f7bd2e1e..853e14e7 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 903f36ae..4e5a2d40 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 80214518..82ca74d2 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -16,7 +16,7 @@
+  *
+  * @file libnozzle.h
+  * @brief tap interfaces management API include file
+- * @copyright Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+diff --git a/libnozzle/libnozzle.pc.in b/libnozzle/libnozzle.pc.in
+index 901e3af5..d6b2a151 100644
+--- a/libnozzle/libnozzle.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/libnozzle_exported_syms b/libnozzle/libnozzle_exported_syms
+index 6745c9ba..934b2049 100644
+--- a/libnozzle/libnozzle_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libnozzle.so
+ #
+-# Copyright (C) 2011-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2011-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index c7adbe4c..b9e16ae4 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index eb7b5efe..cd99edf9 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+index af8c5f03..bb81ba73 100644
+--- a/libnozzle/tests/api_nozzle_add_ip.c
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index 129b98c7..f1cbc771 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+index 31e26c22..0178bb06 100644
+--- a/libnozzle/tests/api_nozzle_del_ip.c
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index d32da6aa..9b29faf8 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+index 0abc1bab..83c39bbb 100644
+--- a/libnozzle/tests/api_nozzle_get_handle_by_name.c
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index ce31cec5..c41024f7 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index 81f31427..1318ba59 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 2db1a527..07b05ee8 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index 8e85b832..5b8152b1 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index 19876987..ee153160 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index ad81c457..a078ad7c 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index f477a4b2..90623ba1 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index d7ea405d..dba7d49e 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index b26df345..fc8ee1c8 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index 687e6b6b..d8de39d7 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index a6a133ff..87531c0e 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_false b/libnozzle/tests/nozzle_run_updown_exit_false
+index 721ecb6e..3f03ff61 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_false
++++ b/libnozzle/tests/nozzle_run_updown_exit_false
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_true b/libnozzle/tests/nozzle_run_updown_exit_true
+index 6e28da18..bbdcdd69 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_true
++++ b/libnozzle/tests/nozzle_run_updown_exit_true
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2010-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index 752f1707..c84aac1e 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index 0bfce530..4562ea2d 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/man/Doxyfile-knet.in b/man/Doxyfile-knet.in
+index 50d78bd5..f78e3136 100644
+--- a/man/Doxyfile-knet.in
++++ b/man/Doxyfile-knet.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Doxyfile-nozzle.in b/man/Doxyfile-nozzle.in
+index 0fb6f333..2855e50b 100644
+--- a/man/Doxyfile-nozzle.in
++++ b/man/Doxyfile-nozzle.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 9fa426d4..6c15f0d0 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+index 5b82bef8..92e60a5a 100755
+--- a/man/api-to-man-page-coverage
++++ b/man/api-to-man-page-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/man/knet-keygen.8 b/man/knet-keygen.8
+index fdc364af..67ecf1f4 100644
+--- a/man/knet-keygen.8
++++ b/man/knet-keygen.8
+@@ -1,5 +1,5 @@
+ .\"/*
+-.\" * Copyright (C) 2012-2018 Red Hat, Inc.
++.\" * Copyright (C) 2012-2019 Red Hat, Inc.
+ .\" *
+ .\" * All rights reserved.
+ .\" *
+diff --git a/man/kronosnetd.8 b/man/kronosnetd.8
+index d70a1ca9..5661e1c7 100644
+--- a/man/kronosnetd.8
++++ b/man/kronosnetd.8
+@@ -1,5 +1,5 @@
+ .\"/*
+-.\" * Copyright (C) 2012-2018 Red Hat, Inc.
++.\" * Copyright (C) 2012-2019 Red Hat, Inc.
+ .\" *
+ .\" * All rights reserved.
+ .\" *
+diff --git a/poc-code/Makefile.am b/poc-code/Makefile.am
+index a6edfe55..e1b1a735 100644
+--- a/poc-code/Makefile.am
++++ b/poc-code/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/poc-code/access-list/Makefile.am b/poc-code/access-list/Makefile.am
+index 4a89125f..80c49c29 100644
+--- a/poc-code/access-list/Makefile.am
++++ b/poc-code/access-list/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/poc-code/access-list/ipcheck.c b/poc-code/access-list/ipcheck.c
+index 6e7940ca..9774a469 100644
+--- a/poc-code/access-list/ipcheck.c
++++ b/poc-code/access-list/ipcheck.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/poc-code/access-list/ipcheck.h b/poc-code/access-list/ipcheck.h
+index 4a644165..eca45669 100644
+--- a/poc-code/access-list/ipcheck.h
++++ b/poc-code/access-list/ipcheck.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/poc-code/access-list/test_ipcheck.c b/poc-code/access-list/test_ipcheck.c
+index 9c197e8d..46a750b7 100644
+--- a/poc-code/access-list/test_ipcheck.c
++++ b/poc-code/access-list/test_ipcheck.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/poc-code/iov-hash/Makefile.am b/poc-code/iov-hash/Makefile.am
+index 493719f2..a41ed99e 100644
+--- a/poc-code/iov-hash/Makefile.am
++++ b/poc-code/iov-hash/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/poc-code/iov-hash/main.c b/poc-code/iov-hash/main.c
+index 58c70125..61d2e12c 100644
+--- a/poc-code/iov-hash/main.c
++++ b/poc-code/iov-hash/main.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0192-build-add-another-exception-to-valgrind-nss-combo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0192-build-add-another-exception-to-valgrind-nss-combo.patch
new file mode 100644
index 000000000..48a89a924
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0192-build-add-another-exception-to-valgrind-nss-combo.patch
@@ -0,0 +1,35 @@ 
+From 8baa4c5d48084d929c4d8e47ed28c143b9d19469 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 29 Jan 2019 05:33:51 +0100
+Subject: [PATCH] [build] add another exception to valgrind nss combo
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 8b3f95f3..e0f49d06 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -588,3 +588,20 @@
+    obj:/usr/lib64/libnss3.so
+    obj:/usr/lib64/libnss3.so
+ }
++{
++   nss internal leak (3.41) non recurring (spotted on f29)
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:*
++   obj:/usr/lib64/libnss3.so
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0193-reduce-minimum-crypto-key-size-to-1024bit.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0193-reduce-minimum-crypto-key-size-to-1024bit.patch
new file mode 100644
index 000000000..4dd1d40bd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0193-reduce-minimum-crypto-key-size-to-1024bit.patch
@@ -0,0 +1,35 @@ 
+From 4849342798ad18ed335967d56d661ff5b00a1ae5 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Fabian=20Gr=C3=BCnbichler?= <f.gruenbichler@proxmox.com>
+Date: Wed, 3 Apr 2019 14:28:50 +0200
+Subject: [PATCH] reduce minimum crypto key size to 1024bit
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Since the key is used for AES/3DES and HMAC operations only, this is
+safe. AES/3DES use keys in the 128- to 256-bit range, HMAC with
+MD5/SHA1/SHA2 should use keys with a minimum of 128- to 512-bit (in both
+cases, depending on the actual algorithm used).
+
+This reduction also keeps knet compatible with existing Corosync 2.x
+keyfiles, which are 1024-bit.
+
+Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
+---
+ libknet/libknet.h | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 36fefa5f..0331b1f8 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -587,8 +587,7 @@ int knet_handle_pmtud_get(knet_handle_t knet_h,
+ 				unsigned int *data_mtu);
+ 
+ 
+-
+-#define KNET_MIN_KEY_LEN  256
++#define KNET_MIN_KEY_LEN  128
+ #define KNET_MAX_KEY_LEN 4096
+ 
+ struct knet_handle_crypto_cfg {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0194-crypto-remove-libnss-3des-support.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0194-crypto-remove-libnss-3des-support.patch
new file mode 100644
index 000000000..c4cebacca
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0194-crypto-remove-libnss-3des-support.patch
@@ -0,0 +1,74 @@ 
+From 103c13f71c3453e3afc8d8675d2e759678e454c4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 11 Apr 2019 13:36:56 +0200
+Subject: [PATCH] [crypto] remove libnss 3des support
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_nss.c | 14 ++++----------
+ libknet/libknet.h    |  2 +-
+ 2 files changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 35afa0f9..a17ff628 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -64,32 +64,28 @@ enum nsscrypto_crypt_t {
+ 	CRYPTO_CIPHER_TYPE_NONE = 0,
+ 	CRYPTO_CIPHER_TYPE_AES256 = 1,
+ 	CRYPTO_CIPHER_TYPE_AES192 = 2,
+-	CRYPTO_CIPHER_TYPE_AES128 = 3,
+-	CRYPTO_CIPHER_TYPE_3DES = 4
++	CRYPTO_CIPHER_TYPE_AES128 = 3
+ };
+ 
+ CK_MECHANISM_TYPE cipher_to_nss[] = {
+ 	0,				/* CRYPTO_CIPHER_TYPE_NONE */
+ 	CKM_AES_CBC_PAD,		/* CRYPTO_CIPHER_TYPE_AES256 */
+ 	CKM_AES_CBC_PAD,		/* CRYPTO_CIPHER_TYPE_AES192 */
+-	CKM_AES_CBC_PAD,		/* CRYPTO_CIPHER_TYPE_AES128 */
+-	CKM_DES3_CBC_PAD 		/* CRYPTO_CIPHER_TYPE_3DES */
++	CKM_AES_CBC_PAD			/* CRYPTO_CIPHER_TYPE_AES128 */
+ };
+ 
+ size_t nsscipher_key_len[] = {
+ 	0,				/* CRYPTO_CIPHER_TYPE_NONE */
+ 	AES_256_KEY_LENGTH,		/* CRYPTO_CIPHER_TYPE_AES256 */
+ 	AES_192_KEY_LENGTH,		/* CRYPTO_CIPHER_TYPE_AES192 */
+-	AES_128_KEY_LENGTH,		/* CRYPTO_CIPHER_TYPE_AES128 */
+-	24				/* CRYPTO_CIPHER_TYPE_3DES */
++	AES_128_KEY_LENGTH		/* CRYPTO_CIPHER_TYPE_AES128 */
+ };
+ 
+ size_t nsscypher_block_len[] = {
+ 	0,				/* CRYPTO_CIPHER_TYPE_NONE */
+ 	AES_BLOCK_SIZE,			/* CRYPTO_CIPHER_TYPE_AES256 */
+ 	AES_BLOCK_SIZE,			/* CRYPTO_CIPHER_TYPE_AES192 */
+-	AES_BLOCK_SIZE,			/* CRYPTO_CIPHER_TYPE_AES128 */
+-	0				/* CRYPTO_CIPHER_TYPE_3DES */
++	AES_BLOCK_SIZE			/* CRYPTO_CIPHER_TYPE_AES128 */
+ };
+ 
+ /*
+@@ -155,8 +151,6 @@ static int nssstring_to_crypto_cipher_type(const char* crypto_cipher_type)
+ 		return CRYPTO_CIPHER_TYPE_AES192;
+ 	} else if (strcmp(crypto_cipher_type, "aes128") == 0) {
+ 		return CRYPTO_CIPHER_TYPE_AES128;
+-	} else if (strcmp(crypto_cipher_type, "3des") == 0) {
+-		return CRYPTO_CIPHER_TYPE_3DES;
+ 	}
+ 	return -1;
+ }
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 0331b1f8..d0c90e41 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -617,7 +617,7 @@ struct knet_handle_crypto_cfg {
+  *                         It can be set to "none" to disable
+  *                         encryption.
+  *                         Currently supported by "nss" model:
+- *                         "3des", "aes128", "aes192" and "aes256".
++ *                         "aes128", "aes192" and "aes256".
+  *                         "openssl" model supports more modes and it strictly
+  *                         depends on the openssl build. See: EVP_get_cipherbyname
+  *                         openssl API call for details.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0195-man-Tidy-manpages-215.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0195-man-Tidy-manpages-215.patch
new file mode 100644
index 000000000..74ee1c3fd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0195-man-Tidy-manpages-215.patch
@@ -0,0 +1,296 @@ 
+From e04d92406ae51abe0b6cc58d1de0b1017abdf370 Mon Sep 17 00:00:00 2001
+From: Chrissie Caulfield <ccaulfie@redhat.com>
+Date: Tue, 16 Apr 2019 14:46:01 +0100
+Subject: [PATCH] man: Tidy manpages (#215)
+
+* man: Tidy manpages for libnozzle
+
+doxygen works in mysterious ways, adding a blank line before
+@brief makes the lines following that much tidier.
+
+So now instead of
+
+nozzle_close nozzle - pointer to the nozzle struct to destroy
+
+we get:
+
+nozzle_close
+
+       nozzle - pointer to the nozzle struct to destroy
+
+* doxyxml: Cope with pointers-to-pointers passed as params
+
+Double pointers showed as ' * *name' when they should be '  **name'.
+
+Also tidy STRUCTURES display so that they are not indented too much,
+
+* man: Similar @brief fixes for libknet.h
+
+* doxyxml: Tidy descriptions of functions as parameters
+
+If a complex function pointer was passed as a parameter then doxyxml
+tryied to line up all the other parameters with it - making a mess
+by having lots of blank space between the type and the name.
+
+Now we enforce a maximum type length (a line-ish) so that shorter
+tyopes will line up OK and the really long ones will be left to their
+own devices.
+---
+ libknet/libknet.h     |  3 +++
+ libnozzle/libnozzle.h | 24 +++++++++++++++++++++---
+ man/doxyxml.c         | 30 ++++++++++++++++++++----------
+ 3 files changed, 44 insertions(+), 13 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index d0c90e41..181724a1 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -275,6 +275,7 @@ int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel);
+ 
+ /**
+  * knet_handle_remove_datafd
++ *
+  * @brief Remove a file descriptor from knet
+  *
+  * knet_h   - pointer to knet_handle_t
+@@ -293,6 +294,7 @@ int knet_handle_remove_datafd(knet_handle_t knet_h, int datafd);
+ 
+ /**
+  * knet_handle_get_channel
++ *
+  * @brief Get the channel associated with a file descriptor
+  *
+  * knet_h  - pointer to knet_handle_t
+@@ -313,6 +315,7 @@ int knet_handle_get_channel(knet_handle_t knet_h, const int datafd, int8_t *chan
+ 
+ /**
+  * knet_handle_get_datafd
++ *
+  * @brief Get the file descriptor associated with a channel
+  *
+  * knet_h   - pointer to knet_handle_t
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 82ca74d2..b8ab7d69 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -25,6 +25,7 @@ typedef struct nozzle_iface *nozzle_t;
+ 
+ /**
+  * nozzle_open
++ *
+  * @brief create a new tap device on the system.
+  *
+  * devname - pointer to device name of at least size IFNAMSIZ.
+@@ -55,6 +56,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 
+ /**
+  * nozzle_close
++ *
+  * @brief deconfigure and destroy a nozzle device
+  *
+  * nozzle - pointer to the nozzle struct to destroy
+@@ -74,9 +76,8 @@ int nozzle_close(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_run_updown
+- * @brief execute updown commands associated with a nozzle device. It is
+- *        the application responsibility to call helper scripts
+- *        before or after creating/destroying interfaces or IP addresses.
++ *
++ * @brief execute updown commands associated with a nozzle device.
+  *
+  * nozzle - pointer to the nozzle struct
+  *
+@@ -86,6 +87,9 @@ int nozzle_close(nozzle_t nozzle);
+  *               The string is malloc'ed, the caller needs to free the buffer.
+  *               If the script generates no output this string might be NULL.
+  *
++ * It is the application responsibility to call helper scripts
++ * before or after creating/destroying interfaces or IP addresses.
++ *
+  * @return
+  * 0 on success
+  * -1 on error and errno is set (sanity checks and internal calls.
+@@ -96,6 +100,7 @@ int nozzle_run_updown(const nozzle_t nozzle, uint8_t action, char **exec_string)
+ 
+ /**
+  * nozzle_set_up
++ *
+  * @brief equivalent of ifconfig up
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -109,6 +114,7 @@ int nozzle_set_up(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_set_down
++ *
+  * @brief equivalent of ifconfig down
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -122,6 +128,7 @@ int nozzle_set_down(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_add_ip
++ *
+  * @brief equivalent of ip addr or ifconfig <ipaddress/prefix>
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -142,6 +149,7 @@ int nozzle_add_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
+ 
+ /**
+  * nozzle_del_ip
++ *
+  * @brief equivalent of ip addr del or ifconfig del <ipaddress/prefix>
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -170,6 +178,7 @@ struct nozzle_ip {
+ 
+ /**
+  * nozzle_get_ips
++ *
+  * @brief retrieve the list of all configured ips for a given interface
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -191,6 +200,7 @@ int nozzle_get_ips(const nozzle_t nozzle, struct nozzle_ip **nozzle_ip);
+ 
+ /**
+  * nozzle_get_mtu
++ *
+  * @brief retrieve mtu on a given nozzle interface
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -204,6 +214,7 @@ int nozzle_get_mtu(const nozzle_t nozzle);
+ 
+ /**
+  * nozzle_set_mtu
++ *
+  * @brief set mtu on a given nozzle interface
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -219,6 +230,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu);
+ 
+ /**
+  * nozzle_reset_mtu
++ *
+  * @brief reset mtu on a given nozzle interface to the system default
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -232,6 +244,7 @@ int nozzle_reset_mtu(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_mac
++ *
+  * @brief retrieve mac address on a given nozzle interface
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -247,6 +260,7 @@ int nozzle_get_mac(const nozzle_t nozzle, char **ether_addr);
+ 
+ /**
+  * nozzle_set_mac
++ *
+  * @brief set mac address on a given nozzle interface
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -262,6 +276,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr);
+ 
+ /**
+  * nozzle_reset_mac
++ *
+  * @brief reset mac address on a given nozzle interface to system default
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -275,6 +290,7 @@ int nozzle_reset_mac(nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_handle_by_name
++ *
+  * @brief find a nozzle handle by device name
+  *
+  * devname - string containing the name of the interface
+@@ -288,6 +304,7 @@ nozzle_t nozzle_get_handle_by_name(const char *devname);
+ 
+ /**
+  * nozzle_get_name_by_handle
++ *
+  * @brief retrieve nozzle interface name by handle
+  *
+  * nozzle - pointer to the nozzle struct
+@@ -301,6 +318,7 @@ const char *nozzle_get_name_by_handle(const nozzle_t nozzle);
+ 
+ /**
+  * nozzle_get_fd
++ *
+  * @brief
+  *
+  * nozzle - pointer to the nozzle struct
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index b4b49a9e..b623711d 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -34,6 +34,14 @@
+ #define XML_DIR "../man/xml-knet"
+ #define XML_FILE "libknet_8h.xml"
+ 
++/*
++ * This isn't a maximum size, it just defines how long a parameter
++ * type can get before we decide it's not worth lining everything up to.
++ * it's mainly to stop function pointer types (which can get VERY long because
++ * of all *their* parameters) making everything else 'line-up' over separate lines
++ */
++#define LINE_LENGTH 80
++
+ static int print_ascii = 1;
+ static int print_man = 0;
+ static int print_params = 0;
+@@ -332,19 +340,25 @@ static int read_structure_from_xml(char *refid, char *name)
+ 
+ static void print_param(FILE *manfile, struct param_info *pi, int field_width, int bold, const char *delimiter)
+ {
+-	char asterisk = ' ';
++	char *asterisks = "  ";
+ 	char *type = pi->paramtype;
+ 
+ 	/* Reformat pointer params so they look nicer */
+ 	if (pi->paramtype[strlen(pi->paramtype)-1] == '*') {
+-		asterisk='*';
++		asterisks=" *";
+ 		type = strdup(pi->paramtype);
+ 		type[strlen(type)-1] = '\0';
++
++		/* Cope with double pointers */
++		if (pi->paramtype[strlen(type)-1] == '*') {
++			asterisks="**";
++			type[strlen(type)-1] = '\0';
++		}
+ 	}
+ 
+-	fprintf(manfile, "    %s%-*s%c%s\\fI%s\\fP%s\n",
++	fprintf(manfile, "    %s%-*s%s%s\\fI%s\\fP%s\n",
+ 		bold?"\\fB":"", field_width, type,
+-		asterisk, bold?"\\fP":"", pi->paramname, delimiter);
++		asterisks, bold?"\\fP":"", pi->paramname, delimiter);
+ 
+ 	if (type != pi->paramtype) {
+ 		free(type);
+@@ -504,7 +518,8 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	qb_list_for_each(iter, &params_list) {
+ 		pi = qb_list_entry(iter, struct param_info, list);
+ 
+-		if (strlen(pi->paramtype) > max_param_type_len) {
++		if ((strlen(pi->paramtype) < LINE_LENGTH) &&
++		    (strlen(pi->paramtype) > max_param_type_len)) {
+ 			max_param_type_len = strlen(pi->paramtype);
+ 		}
+ 		if (strlen(pi->paramname) > max_param_name_len) {
+@@ -559,11 +574,6 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 
+ 		map_iter = qb_map_iter_create(used_structures_map);
+ 		for (p = qb_map_iter_next(map_iter, &data); p; p = qb_map_iter_next(map_iter, &data)) {
+-			fprintf(manfile, ".SS \"\"\n");
+-			fprintf(manfile, ".PP\n");
+-			fprintf(manfile, ".sp\n");
+-			fprintf(manfile, ".sp\n");
+-			fprintf(manfile, ".RS\n");
+ 			fprintf(manfile, ".nf\n");
+ 			fprintf(manfile, "\\fB\n");
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0196-man-Tidy-more-man-pages.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0196-man-Tidy-more-man-pages.patch
new file mode 100644
index 000000000..2f0e11a9d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0196-man-Tidy-more-man-pages.patch
@@ -0,0 +1,46 @@ 
+From 93ba25274642f3768b98bd53ba9d96d23500bc9e Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 29 Apr 2019 15:16:27 +0100
+Subject: [PATCH] man: Tidy more man pages
+
+Followup to previous 'tidy'
+---
+ libknet/libknet.h | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 181724a1..7b5a9e33 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -151,6 +151,7 @@ knet_handle_t knet_handle_new(knet_node_id_t host_id,
+ 
+ /**
+  * knet_handle_free
++ *
+  * @brief Destroy a knet handle, free all resources
+  *
+  * knet_h   - pointer to knet_handle_t
+@@ -165,6 +166,7 @@ int knet_handle_free(knet_handle_t knet_h);
+ 
+ /**
+  * knet_handle_enable_sock_notify
++ *
+  * @brief Register a callback to receive socket events
+  *
+  * knet_h   - pointer to knet_handle_t
+@@ -336,6 +338,7 @@ int knet_handle_get_datafd(knet_handle_t knet_h, const int8_t channel, int *data
+ 
+ /**
+  * knet_recv
++ *
+  * @brief Receive data from knet nodes
+  *
+  * knet_h   - pointer to knet_handle_t
+@@ -358,6 +361,7 @@ ssize_t knet_recv(knet_handle_t knet_h,
+ 
+ /**
+  * knet_send
++ *
+  * @brief Send data to knet nodes
+  *
+  * knet_h   - pointer to knet_handle_t
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0197-man-fix-knet_host_set_policy-parameters-order.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0197-man-fix-knet_host_set_policy-parameters-order.patch
new file mode 100644
index 000000000..41e54156f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0197-man-fix-knet_host_set_policy-parameters-order.patch
@@ -0,0 +1,27 @@ 
+From e770dd981df9dddf10b16b9b00a3535151d54eeb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Apr 2019 05:06:47 +0200
+Subject: [PATCH] [man] fix knet_host_set_policy parameters order
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 7b5a9e33..7c0c4403 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1027,10 +1027,10 @@ int knet_host_get_host_list(knet_handle_t knet_h,
+ /**
+  * knet_host_set_policy
+  *
+- * knet_h   - pointer to knet_handle_t
+- *
+  * @brief Set the switching policy for a host's links
+  *
++ * knet_h   - pointer to knet_handle_t
++ *
+  * host_id  - see knet_host_add(3)
+  *
+  * policy   - there are currently 3 kind of simple switching policies
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0198-tests-add-man-page-check-to-verify-doxy-header-order.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0198-tests-add-man-page-check-to-verify-doxy-header-order.patch
new file mode 100644
index 000000000..f96dbb718
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0198-tests-add-man-page-check-to-verify-doxy-header-order.patch
@@ -0,0 +1,37 @@ 
+From db9805cd08b2c254ee1553978be6176bf99aa466 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Apr 2019 05:42:16 +0200
+Subject: [PATCH] [tests] add man page check to verify doxy header order and
+ definitions
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/api-to-man-page-coverage | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+index 92e60a5a..b9dc18f4 100755
+--- a/man/api-to-man-page-coverage
++++ b/man/api-to-man-page-coverage
+@@ -14,6 +14,21 @@ target="$2"
+ headerapicalls="$(grep ${target}_ "$srcdir"/lib${target}/lib${target}.h | grep -v "^ \*" | grep -v ^struct | grep -v "^[[:space:]]" | grep -v typedef | sed -e 's/(.*//g' -e 's/^const //g' -e 's/\*//g' | awk '{print $2}')"
+ manpages="$(grep ${target}_ "$srcdir"/man/Makefile.am |grep -v man3 |grep -v xml | sed -e 's/\.3.*//g')"
+ 
++echo "Checking for header format errors"
++
++for i in $headerapicalls; do
++	echo "Checking $i"
++	header="$(grep " \* ${i}$" "$srcdir"/lib${target}/lib${target}.h -A2)"
++	brief="$(echo "$header" | tail -n 1 |grep "@brief")"
++	if [ -z "$brief" ]; then
++		echo "Error found in $i doxy header section"
++		echo "$header"
++		echo ""
++		echo "$brief"
++		exit 1
++	fi
++done
++
+ echo "Checking for symbols in header file NOT distributed as manpages"
+ 
+ for i in $headerapicalls; do
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0199-man-fix-libknet.h-for-errors-detected-by-newly-added.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0199-man-fix-libknet.h-for-errors-detected-by-newly-added.patch
new file mode 100644
index 000000000..57291f473
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0199-man-fix-libknet.h-for-errors-detected-by-newly-added.patch
@@ -0,0 +1,41 @@ 
+From 9821c91256e51ec81386299914c8d48400e8df84 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Apr 2019 05:42:48 +0200
+Subject: [PATCH] [man] fix libknet.h for errors detected by newly added test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 7c0c4403..c7f44d7c 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1144,7 +1144,7 @@ struct knet_host_status {
+ };
+ 
+ /**
+- * knet_host_status_get
++ * knet_host_get_status
+  *
+  * @brief Get the status of a host
+  *
+@@ -1939,7 +1939,7 @@ struct knet_log_msg {
+ };
+ 
+ /**
+- * knet_log_set_log_level
++ * knet_log_set_loglevel
+  *
+  * @brief Set the logging level for a subsystem
+  *
+@@ -1962,7 +1962,7 @@ int knet_log_set_loglevel(knet_handle_t knet_h, uint8_t subsystem,
+ 			  uint8_t level);
+ 
+ /**
+- * knet_log_get_log_level
++ * knet_log_get_loglevel
+  *
+  * @brief Get the logging level for a subsystem
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0200-udp-use-defines-vs-hardcoded-numbers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0200-udp-use-defines-vs-hardcoded-numbers.patch
new file mode 100644
index 000000000..b2991bef7
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0200-udp-use-defines-vs-hardcoded-numbers.patch
@@ -0,0 +1,36 @@ 
+From d5144fb7f32b0f37f1b973615358b7f308416c93 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 1 May 2019 06:39:53 +0200
+Subject: [PATCH] [udp] use defines vs hardcoded numbers
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_udp.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index acfbab47..3decb66b 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -325,8 +325,8 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 				sock_err = (struct sock_extended_err*)(void *)CMSG_DATA(cmsg);
+ 				if (sock_err) {
+ 					switch (sock_err->ee_origin) {
+-						case 0: /* no origin */
+-						case 1: /* local source (EMSGSIZE) */
++						case SO_EE_ORIGIN_NONE: /* no origin */
++						case SO_EE_ORIGIN_LOCAL: /* local source (EMSGSIZE) */
+ 							if (sock_err->ee_errno == EMSGSIZE) {
+ 								if (pthread_mutex_lock(&knet_h->kmtu_mutex) != 0) {
+ 									log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Unable to get mutex lock");
+@@ -358,8 +358,8 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 							 * those errors are way too noisy
+ 							 */
+ 							break;
+-						case 2: /* ICMP */
+-						case 3: /* ICMP6 */
++						case SO_EE_ORIGIN_ICMP:  /* ICMP */
++						case SO_EE_ORIGIN_ICMP6: /* ICMP6 */
+ 							origin = (struct sockaddr_storage *)(void *)SO_EE_OFFENDER(sock_err);
+ 							if (knet_addrtostr(origin, sizeof(origin),
+ 									   addr_str, KNET_MAX_HOST_LEN,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0201-udp-improve-error-message-decoding-from-ICMP-errors.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0201-udp-improve-error-message-decoding-from-ICMP-errors.patch
new file mode 100644
index 000000000..6d512685f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0201-udp-improve-error-message-decoding-from-ICMP-errors.patch
@@ -0,0 +1,38 @@ 
+From 2aa544fd708b74ac446deb9a31308600d93426aa Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 1 May 2019 06:51:19 +0200
+Subject: [PATCH] [udp] improve error message decoding from ICMP errors
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_udp.c | 10 +++++++++-
+ 1 file changed, 9 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 3decb66b..e4f6fdb9 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -296,6 +296,8 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 	struct sockaddr_storage *origin;
+ 	char addr_str[KNET_MAX_HOST_LEN];
+ 	char port_str[KNET_MAX_PORT_LEN];
++	char addr_remote_str[KNET_MAX_HOST_LEN];
++	char port_remote_str[KNET_MAX_PORT_LEN];
+ 
+ 	iov.iov_base = &icmph;
+ 	iov.iov_len = sizeof(icmph);
+@@ -367,7 +369,13 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 								log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from unknown source: %s", strerror(sock_err->ee_errno));
+ 
+ 							} else {
+-								log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from %s: %s", addr_str, strerror(sock_err->ee_errno));
++								if (knet_addrtostr(&remote, sizeof(remote),
++									       addr_remote_str, KNET_MAX_HOST_LEN,
++									       port_remote_str, KNET_MAX_PORT_LEN) < 0) {
++									log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from %s: %s destination unknown", addr_str, strerror(sock_err->ee_errno));
++								} else {
++									log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from %s: %s %s", addr_str, strerror(sock_err->ee_errno), addr_remote_str);
++								}
+ 							}
+ 							break;
+ 					}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0202-acl-move-poc-code-into-libknet-dir-and-rename-to-lin.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0202-acl-move-poc-code-into-libknet-dir-and-rename-to-lin.patch
new file mode 100644
index 000000000..1070bdbcc
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0202-acl-move-poc-code-into-libknet-dir-and-rename-to-lin.patch
@@ -0,0 +1,196 @@ 
+From 7f5154d60fff8abab8ae5d53decb3b9b62b58d59 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 5 Jan 2019 09:04:38 +0100
+Subject: [PATCH] [acl] move poc-code into libknet dir and rename to
+ links_acl.*
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+code is not integrated yet and test suite can´t run standalone
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac                                  |  1 -
+ libknet/Makefile.am                           |  2 ++
+ .../ipcheck.c => libknet/links_acl.c          |  2 +-
+ .../ipcheck.h => libknet/links_acl.h          |  0
+ libknet/tests/Makefile.am                     |  8 ++++++-
+ .../tests/int_links_acl.c                     |  6 ++---
+ .../tests/int_links_acl.txt                   |  0
+ poc-code/Makefile.am                          |  2 +-
+ poc-code/access-list/.gitignore               |  1 -
+ poc-code/access-list/Makefile.am              | 22 -------------------
+ 10 files changed, 14 insertions(+), 30 deletions(-)
+ rename poc-code/access-list/ipcheck.c => libknet/links_acl.c (99%)
+ rename poc-code/access-list/ipcheck.h => libknet/links_acl.h (100%)
+ rename poc-code/access-list/test_ipcheck.c => libknet/tests/int_links_acl.c (96%)
+ rename poc-code/access-list/test_ipcheck.txt => libknet/tests/int_links_acl.txt (100%)
+ delete mode 100644 poc-code/access-list/.gitignore
+ delete mode 100644 poc-code/access-list/Makefile.am
+
+diff --git a/configure.ac b/configure.ac
+index 9df68314..30c57f00 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -463,7 +463,6 @@ AC_CONFIG_FILES([
+ 		man/Doxyfile-nozzle
+ 		poc-code/Makefile
+ 		poc-code/iov-hash/Makefile
+-		poc-code/access-list/Makefile
+ 		])
+ 
+ if test "x$VERSION" = "xUNKNOWN"; then
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 906fd011..4ea42d9e 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -31,6 +31,7 @@ sources			= \
+ 			  handle.c \
+ 			  host.c \
+ 			  links.c \
++			  links_acl.c \
+ 			  logging.c \
+ 			  netutils.c \
+ 			  threads_common.c \
+@@ -61,6 +62,7 @@ noinst_HEADERS		= \
+ 			  host.h \
+ 			  internals.h \
+ 			  links.h \
++			  links_acl.h \
+ 			  logging.h \
+ 			  netutils.h \
+ 			  onwire.h \
+diff --git a/poc-code/access-list/ipcheck.c b/libknet/links_acl.c
+similarity index 99%
+rename from poc-code/access-list/ipcheck.c
+rename to libknet/links_acl.c
+index 9774a469..e7b56026 100644
+--- a/poc-code/access-list/ipcheck.c
++++ b/libknet/links_acl.c
+@@ -11,7 +11,7 @@
+ #include <stdint.h>
+ #include <string.h>
+ #include <malloc.h>
+-#include "ipcheck.h"
++#include "links_acl.h"
+ 
+ struct ip_match_entry {
+ 	ipcheck_type_t type;
+diff --git a/poc-code/access-list/ipcheck.h b/libknet/links_acl.h
+similarity index 100%
+rename from poc-code/access-list/ipcheck.h
+rename to libknet/links_acl.h
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index c00e6247..f74cb046 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -13,7 +13,8 @@ include $(top_srcdir)/libknet/tests/api-check.mk
+ 
+ EXTRA_DIST		= \
+ 			  api-test-coverage \
+-			  api-check.mk
++			  api-check.mk \
++			  int_links_acl.txt
+ 
+ AM_CPPFLAGS		= -I$(top_srcdir)/libknet
+ AM_CFLAGS		+= $(PTHREAD_CFLAGS)
+@@ -40,9 +41,11 @@ fun_checks		=
+ benchmarks		= \
+ 			  knet_bench_test
+ 
++# int_links_acl_test can´t run yet standalone
+ noinst_PROGRAMS		= \
+ 			  api_knet_handle_new_limit_test \
+ 			  pckt_test \
++			  int_links_acl_test \
+ 			  $(benchmarks) \
+ 			  $(check_PROGRAMS)
+ 
+@@ -64,6 +67,9 @@ check-api-test-coverage:
+ 
+ pckt_test_SOURCES	= pckt_test.c
+ 
++int_links_acl_test_SOURCES = int_links_acl.c \
++			     ../links_acl.c
++
+ int_timediff_test_SOURCES = int_timediff.c
+ 
+ knet_bench_test_SOURCES	= knet_bench.c \
+diff --git a/poc-code/access-list/test_ipcheck.c b/libknet/tests/int_links_acl.c
+similarity index 96%
+rename from poc-code/access-list/test_ipcheck.c
+rename to libknet/tests/int_links_acl.c
+index 46a750b7..27ac545a 100644
+--- a/poc-code/access-list/test_ipcheck.c
++++ b/libknet/tests/int_links_acl.c
+@@ -14,7 +14,7 @@
+ #include <string.h>
+ #include <netdb.h>
+ #include <malloc.h>
+-#include "ipcheck.h"
++#include "links_acl.h"
+ 
+ /* This is a test program .. remember! */
+ #define BUFLEN 1024
+@@ -103,9 +103,9 @@ static int load_file(void)
+ 
+ 	ipcheck_clear();
+ 
+-	filterfile = fopen("test_ipcheck.txt", "r");
++	filterfile = fopen("int_links_acl.txt", "r");
+ 	if (!filterfile) {
+-		fprintf(stderr, "Cannot open test_ipcheck.txt\n");
++		fprintf(stderr, "Cannot open int_links_acl.txt\n");
+ 		return 1;
+ 	}
+ 
+diff --git a/poc-code/access-list/test_ipcheck.txt b/libknet/tests/int_links_acl.txt
+similarity index 100%
+rename from poc-code/access-list/test_ipcheck.txt
+rename to libknet/tests/int_links_acl.txt
+diff --git a/poc-code/Makefile.am b/poc-code/Makefile.am
+index e1b1a735..15d12f78 100644
+--- a/poc-code/Makefile.am
++++ b/poc-code/Makefile.am
+@@ -10,4 +10,4 @@ MAINTAINERCLEANFILES	= Makefile.in
+ 
+ include $(top_srcdir)/build-aux/check.mk
+ 
+-SUBDIRS			= access-list iov-hash
++SUBDIRS			= iov-hash
+diff --git a/poc-code/access-list/.gitignore b/poc-code/access-list/.gitignore
+deleted file mode 100644
+index 955474ba..00000000
+--- a/poc-code/access-list/.gitignore
++++ /dev/null
+@@ -1 +0,0 @@
+-test_ipcheck
+diff --git a/poc-code/access-list/Makefile.am b/poc-code/access-list/Makefile.am
+deleted file mode 100644
+index 80c49c29..00000000
+--- a/poc-code/access-list/Makefile.am
++++ /dev/null
+@@ -1,22 +0,0 @@
+-#
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+, LGPL-2.0+
+-#
+-
+-MAINTAINERCLEANFILES	= Makefile.in
+-
+-include $(top_srcdir)/build-aux/check.mk
+-
+-# override global LIBS that pulls in lots of craft we don't need here
+-LIBS			=
+-
+-EXTRA_DIST		= test_ipcheck.txt
+-
+-noinst_PROGRAMS		= test_ipcheck
+-
+-noinst_HEADERS		= ipcheck.h
+-
+-test_ipcheck_SOURCES	= ipcheck.c test_ipcheck.c
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0203-acl-add-knet_handle_enable_access_lists-api-call.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0203-acl-add-knet_handle_enable_access_lists-api-call.patch
new file mode 100644
index 000000000..cc27d187a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0203-acl-add-knet_handle_enable_access_lists-api-call.patch
@@ -0,0 +1,235 @@ 
+From f432f20015e14a6f80b0fcfe84d6978c4b2484bc Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 8 Feb 2019 14:29:50 +0100
+Subject: [PATCH] [acl] add knet_handle_enable_access_lists api call
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c                              |  36 +++++++
+ libknet/internals.h                           |   1 +
+ libknet/libknet.h                             |  22 ++++
+ libknet/tests/api-check.mk                    |   4 +
+ .../api_knet_handle_enable_access_lists.c     | 100 ++++++++++++++++++
+ 5 files changed, 163 insertions(+)
+ create mode 100644 libknet/tests/api_knet_handle_enable_access_lists.c
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index b7aa2fd4..6cd49f51 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1186,6 +1186,42 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled)
+ 	return 0;
+ }
+ 
++int knet_handle_enable_access_lists(knet_handle_t knet_h, unsigned int enabled)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (enabled > 1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->use_access_lists = enabled;
++
++	if (enabled) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Links access lists are enabled");
++	} else {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Links access lists are disabled");
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
+ int knet_handle_pmtud_getfreq(knet_handle_t knet_h, unsigned int *interval)
+ {
+ 	int savederrno = 0;
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 57da5b4d..d33646f7 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -158,6 +158,7 @@ struct knet_handle {
+ 	int send_to_links_epollfd;
+ 	int recv_from_links_epollfd;
+ 	int dst_link_handler_epollfd;
++	uint8_t use_access_lists; /* set to 0 for disable, 1 for enable */
+ 	unsigned int pmtud_interval;
+ 	unsigned int data_mtu;	/* contains the max data size that we can send onwire
+ 				 * without frags */
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index c7f44d7c..4283afe5 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -502,6 +502,28 @@ int knet_handle_enable_filter(knet_handle_t knet_h,
+ 
+ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled);
+ 
++/**
++ * knet_handle_enable_access_lists
++ *
++ * @brief Start packet forwarding
++ *
++ * knet_h   - pointer to knet_handle_t
++ *
++ * enable   - set to 1 to use ip access lists, 0 to disable ip access_lists.
++ *
++ * @return
++ * knet_handle_enable_access_lists returns
++ * 0 on success
++ * -1 on error and errno is set.
++ *
++ * By default access lists usage is off, but default internal access lists
++ * will be populated regardless, but not enforced. TODO add long explanation
++ * on internal access lists for point to point connections vs global
++ * listeners etc.
++ */
++
++int knet_handle_enable_access_lists(knet_handle_t knet_h, unsigned int enabled);
++
+ #define KNET_PMTUD_DEFAULT_INTERVAL 60
+ 
+ /**
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 7beba539..247ed582 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -12,6 +12,7 @@ api_checks		= \
+ 			  api_knet_handle_compress_test \
+ 			  api_knet_handle_crypto_test \
+ 			  api_knet_handle_setfwd_test \
++			  api_knet_handle_enable_access_lists_test \
+ 			  api_knet_handle_enable_filter_test \
+ 			  api_knet_handle_enable_sock_notify_test \
+ 			  api_knet_handle_add_datafd_test \
+@@ -87,6 +88,9 @@ api_knet_handle_crypto_test_SOURCES = api_knet_handle_crypto.c \
+ api_knet_handle_setfwd_test_SOURCES = api_knet_handle_setfwd.c \
+ 				      test-common.c
+ 
++api_knet_handle_enable_access_lists_test_SOURCES = api_knet_handle_enable_access_lists.c \
++						   test-common.c
++
+ api_knet_handle_enable_filter_test_SOURCES = api_knet_handle_enable_filter.c \
+ 					     test-common.c
+ 
+diff --git a/libknet/tests/api_knet_handle_enable_access_lists.c b/libknet/tests/api_knet_handle_enable_access_lists.c
+new file mode 100644
+index 00000000..fc3bcc19
+--- /dev/null
++++ b/libknet/tests/api_knet_handle_enable_access_lists.c
+@@ -0,0 +1,100 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "libknet.h"
++#include "internals.h"
++
++#include "test-common.h"
++
++static void test(void)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++
++	printf("Test knet_handle_enable_access_lists with invalid knet_h\n");
++
++	if ((!knet_handle_enable_access_lists(NULL, 0)) || (errno != EINVAL)) {
++		printf("knet_handle_enable_access_lists accepted invalid knet_h parameter\n");
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	printf("Test knet_handle_enable_access_lists with invalid param (2) \n");
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	if ((!knet_handle_enable_access_lists(knet_h, 2)) || (errno != EINVAL)) {
++		printf("knet_handle_enable_access_lists accepted invalid param for enabled: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_enable_access_lists with valid param (1) \n");
++
++	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
++		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->use_access_lists != 1) {
++		printf("knet_handle_enable_access_lists failed to set correct value");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_enable_access_lists with valid param (0) \n");
++
++	if (knet_handle_enable_access_lists(knet_h, 0) < 0) {
++		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->use_access_lists != 0) {
++		printf("knet_handle_enable_access_lists failed to set correct value");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0204-transports-add-information-about-the-nature-of-the-t.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0204-transports-add-information-about-the-nature-of-the-t.patch
new file mode 100644
index 000000000..d79041793
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0204-transports-add-information-about-the-nature-of-the-t.patch
@@ -0,0 +1,115 @@ 
+From 9d6ea9dda2e9d0892588518ee5e83ae4d2d29e0d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 10 Feb 2019 08:52:22 +0100
+Subject: [PATCH] [transports] add information about the nature of the
+ transport and supported access lists
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h  | 31 +++++++++++++++++++++++++++++++
+ libknet/transports.c | 18 ++++++++++++++----
+ libknet/transports.h |  2 ++
+ 3 files changed, 47 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index d33646f7..106b49db 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -256,6 +256,34 @@ extern pthread_rwlock_t shlib_rwlock;       /* global shared lib load lock */
+  *       for every protocol.
+  */
+ 
++/*
++ * for now knet supports only IP protocols (udp/sctp)
++ * in future there might be others like ARP
++ * or TIPC.
++ * keep this around as transport information
++ * to use for access lists and other operations
++ */
++
++typedef enum {
++	LOOPBACK,
++	IP_PROTO
++} transport_proto;
++
++/*
++ * some transports like SCTP can filter incoming
++ * connections before knet has to process
++ * any packets.
++ * GENERIC_ACL -> packet has to be read and filterted
++ * PROTO_ACL -> transport provides filtering at lower levels
++ *              and packet does not need to be processed
++ */
++
++typedef enum {
++	USE_NO_ACL,
++	USE_GENERIC_ACL,
++	USE_PROTO_ACL
++} transport_acl;
++
+ /*
+  * make it easier to map values in transports.c
+  */
+@@ -270,6 +298,9 @@ typedef struct knet_transport_ops {
+ 	const uint8_t transport_id;
+ 	const uint8_t built_in;
+ 
++	transport_proto transport_protocol;
++	transport_acl transport_acl_type;
++
+ /*
+  * connection oriented protocols like SCTP
+  * don´t need dst_addr in sendto calls and
+diff --git a/libknet/transports.c b/libknet/transports.c
+index b6f3b646..ffebe001 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -27,14 +27,14 @@
+ #include "transport_sctp.h"
+ #include "threads_common.h"
+ 
+-#define empty_module 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
++#define empty_module -1, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+-	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
++	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+-				       1, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
++				       1, IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
+ #else
+ empty_module
+ #endif
+@@ -118,6 +118,16 @@ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, st
+ 	return transport_modules_cmd[transport].transport_rx_is_data(knet_h, sockfd, msg);
+ }
+ 
++int transport_get_proto(knet_handle_t knet_h, uint8_t transport)
++{
++	return transport_modules_cmd[transport].transport_protocol;
++}
++
++int transport_get_acl_type(knet_handle_t knet_h, uint8_t transport)
++{
++	return transport_modules_cmd[transport].transport_acl_type;
++}
++
+ int transport_get_connection_oriented(knet_handle_t knet_h, uint8_t transport)
+ {
+ 	return transport_modules_cmd[transport].transport_is_connection_oriented;
+diff --git a/libknet/transports.h b/libknet/transports.h
+index d58b7a39..6338140e 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -18,6 +18,8 @@ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_lin
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_tx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, struct knet_mmsghdr *msg);
++int transport_get_proto(knet_handle_t knet_h, uint8_t transport);
++int transport_get_acl_type(knet_handle_t knet_h, uint8_t transport);
+ int transport_get_connection_oriented(knet_handle_t knet_h, uint8_t transport);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0205-access-lists-make-code-more-generic-to-accept-more-t.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0205-access-lists-make-code-more-generic-to-accept-more-t.patch
new file mode 100644
index 000000000..3792e85f4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0205-access-lists-make-code-more-generic-to-accept-more-t.patch
@@ -0,0 +1,436 @@ 
+From 73bb55a8f5990b521f9e60ef58cb64b7392b7172 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 12 Feb 2019 07:21:20 +0100
+Subject: [PATCH] [access lists] make code more generic to accept more than IP
+ protocol and start to bind it to each fd
+
+access lists are unique per file descriptor, each fd can have its own protocol and list.
+
+remane around ipcheck* with check* to be more generic.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h           |  24 +++++++
+ libknet/links_acl.c           | 114 ++++++++++++++++------------------
+ libknet/links_acl.h           |  18 ++++--
+ libknet/tests/int_links_acl.c |  46 +++++++++-----
+ 4 files changed, 120 insertions(+), 82 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 106b49db..78e718d0 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -129,11 +129,35 @@ struct knet_sock {
+ 			  * and socket has been removed from epoll */
+ };
+ 
++/*
++ * access lists
++ */
++
++typedef enum {
++	CHECK_TYPE_ADDRESS,
++	CHECK_TYPE_MASK,
++	CHECK_TYPE_RANGE
++} check_type_t;
++
++typedef	enum {
++	CHECK_ACCEPT,
++	CHECK_REJECT
++} check_acceptreject_t;
++
++struct acl_match_entry {
++	check_type_t type;
++	check_acceptreject_t acceptreject;
++	struct sockaddr_storage addr1; /* Actual IP address, mask top or low IP */
++	struct sockaddr_storage addr2; /* high IP address or address bitmask */
++	struct acl_match_entry *next;
++};
++
+ struct knet_fd_trackers {
+ 	uint8_t transport; /* transport type (UDP/SCTP...) */
+ 	uint8_t data_type; /* internal use for transport to define what data are associated
+ 			    * to this fd */
+ 	void *data;	   /* pointer to the data */
++	struct acl_match_entry *match_entry;
+ };
+ 
+ #define KNET_MAX_FDS KNET_MAX_HOST * KNET_MAX_LINK * 4
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index e7b56026..fe84088a 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -11,26 +11,17 @@
+ #include <stdint.h>
+ #include <string.h>
+ #include <malloc.h>
+-#include "links_acl.h"
+-
+-struct ip_match_entry {
+-	ipcheck_type_t type;
+-	ipcheck_acceptreject_t acceptreject;
+-	struct sockaddr_storage addr1; /* Actual IP address, mask top or low IP */
+-	struct sockaddr_storage addr2; /* high IP address or address bitmask */
+-	struct ip_match_entry *next;
+-};
+ 
+-
+-/* Lists of things to match against. These are dummy structs to provide a quick list head */
+-static struct ip_match_entry match_entry_head_v4;
+-static struct ip_match_entry match_entry_head_v6;
++#include "internals.h"
++#include "logging.h"
++#include "transports.h"
++#include "links_acl.h"
+ 
+ /*
+  * IPv4 See if the address we have matches the current match entry
+- *
+  */
+-static int ip_matches_v4(struct sockaddr_storage *checkip, struct ip_match_entry *match_entry)
++
++static int ip_matches_v4(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
+ {
+ 	struct sockaddr_in *ip_to_check;
+ 	struct sockaddr_in *match1;
+@@ -41,16 +32,16 @@ static int ip_matches_v4(struct sockaddr_storage *checkip, struct ip_match_entry
+ 	match2 = (struct sockaddr_in *)&match_entry->addr2;
+ 
+ 	switch(match_entry->type) {
+-	case IPCHECK_TYPE_ADDRESS:
++	case CHECK_TYPE_ADDRESS:
+ 		if (ip_to_check->sin_addr.s_addr == match1->sin_addr.s_addr)
+ 			return 1;
+ 		break;
+-	case IPCHECK_TYPE_MASK:
++	case CHECK_TYPE_MASK:
+ 		if ((ip_to_check->sin_addr.s_addr & match2->sin_addr.s_addr) ==
+ 		    match1->sin_addr.s_addr)
+ 			return 1;
+ 		break;
+-	case IPCHECK_TYPE_RANGE:
++	case CHECK_TYPE_RANGE:
+ 		if ((ntohl(ip_to_check->sin_addr.s_addr) >= ntohl(match1->sin_addr.s_addr)) &&
+ 		    (ntohl(ip_to_check->sin_addr.s_addr) <= ntohl(match2->sin_addr.s_addr)))
+ 			return 1;
+@@ -60,7 +51,10 @@ static int ip_matches_v4(struct sockaddr_storage *checkip, struct ip_match_entry
+ 	return 0;
+ }
+ 
+-/* Compare two IPv6 addresses */
++/*
++ * Compare two IPv6 addresses
++ */
++
+ static int ip6addr_cmp(struct in6_addr *a, struct in6_addr *b)
+ {
+ 	uint64_t a_high, a_low;
+@@ -89,9 +83,9 @@ static int ip6addr_cmp(struct in6_addr *a, struct in6_addr *b)
+ 
+ /*
+  * IPv6 See if the address we have matches the current match entry
+- *
+  */
+-static int ip_matches_v6(struct sockaddr_storage *checkip, struct ip_match_entry *match_entry)
++
++static int ip_matches_v6(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
+ {
+ 	struct sockaddr_in6 *ip_to_check;
+ 	struct sockaddr_in6 *match1;
+@@ -103,12 +97,12 @@ static int ip_matches_v6(struct sockaddr_storage *checkip, struct ip_match_entry
+ 	match2 = (struct sockaddr_in6 *)&match_entry->addr2;
+ 
+ 	switch(match_entry->type) {
+-	case IPCHECK_TYPE_ADDRESS:
++	case CHECK_TYPE_ADDRESS:
+ 		if (!memcmp(ip_to_check->sin6_addr.s6_addr32, match1->sin6_addr.s6_addr32, sizeof(struct in6_addr)))
+ 			return 1;
+ 		break;
+ 
+-	case IPCHECK_TYPE_MASK:
++	case CHECK_TYPE_MASK:
+ 		/*
+ 		 * Note that this little loop will quit early if there is a non-match so the
+ 		 * comparison might look backwards compared to the IPv4 one
+@@ -119,7 +113,7 @@ static int ip_matches_v6(struct sockaddr_storage *checkip, struct ip_match_entry
+ 				return 0;
+ 		}
+ 		return 1;
+-	case IPCHECK_TYPE_RANGE:
++	case CHECK_TYPE_RANGE:
+ 		if ((ip6addr_cmp(&ip_to_check->sin6_addr, &match1->sin6_addr) >= 0) &&
+ 		    (ip6addr_cmp(&ip_to_check->sin6_addr, &match2->sin6_addr) <= 0))
+ 			return 1;
+@@ -129,24 +123,20 @@ static int ip_matches_v6(struct sockaddr_storage *checkip, struct ip_match_entry
+ }
+ 
+ 
+-/*
+- * YOU ARE HERE
+- */
+-int ipcheck_validate(struct sockaddr_storage *checkip)
++int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip)
+ {
+-	struct ip_match_entry *match_entry;
+-	int (*match_fn)(struct sockaddr_storage *checkip, struct ip_match_entry *match_entry);
++	struct acl_match_entry *match_entry = *match_entry_head;
++	int (*match_fn)(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry);
+ 
+ 	if (checkip->ss_family == AF_INET){
+-		match_entry = match_entry_head_v4.next;
+ 		match_fn = ip_matches_v4;
+ 	} else {
+-		match_entry = match_entry_head_v6.next;
+ 		match_fn = ip_matches_v6;
+ 	}
++
+ 	while (match_entry) {
+ 		if (match_fn(checkip, match_entry)) {
+-			if (match_entry->acceptreject == IPCHECK_ACCEPT)
++			if (match_entry->acceptreject == CHECK_ACCEPT)
+ 				return 1;
+ 			else
+ 				return 0;
+@@ -157,47 +147,42 @@ int ipcheck_validate(struct sockaddr_storage *checkip)
+ }
+ 
+ /*
+- * Routines to manuipulate the lists
++ * Routines to manuipulate access lists
+  */
+ 
+-void ipcheck_clear(void)
++void ipcheck_clear(struct acl_match_entry **match_entry_head)
+ {
+-	struct ip_match_entry *match_entry;
+-	struct ip_match_entry *next_match_entry;
++	struct acl_match_entry *next_match_entry;
++	struct acl_match_entry *match_entry = *match_entry_head;
+ 
+-	match_entry = match_entry_head_v4.next;
+-	while (match_entry) {
+-		next_match_entry = match_entry->next;
+-		free(match_entry);
+-		match_entry = next_match_entry;
+-	}
+-
+-	match_entry = match_entry_head_v6.next;
+ 	while (match_entry) {
+ 		next_match_entry = match_entry->next;
+ 		free(match_entry);
+ 		match_entry = next_match_entry;
+ 	}
++	*match_entry_head = NULL;
+ }
+ 
+-int ipcheck_addip(struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		  ipcheck_type_t type, ipcheck_acceptreject_t acceptreject)
++int ipcheck_addip(struct acl_match_entry **match_entry_head,
++		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	struct ip_match_entry *match_entry;
+-	struct ip_match_entry *new_match_entry;
++	struct acl_match_entry *new_match_entry;
++	struct acl_match_entry *match_entry = *match_entry_head;
+ 
+-	if (type == IPCHECK_TYPE_RANGE &&
+-	    (ip1->ss_family != ip2->ss_family))
++	if (!ip1) {
+ 		return -1;
++	}
+ 
+-	if (ip1->ss_family == AF_INET){
+-		match_entry = &match_entry_head_v4;
+-	} else {
+-		match_entry = &match_entry_head_v6;
++	if ((type != CHECK_TYPE_ADDRESS) && (!ip2)) {
++		return -1;
+ 	}
+ 
++	if (type == CHECK_TYPE_RANGE &&
++	    (ip1->ss_family != ip2->ss_family))
++		return -1;
+ 
+-	new_match_entry = malloc(sizeof(struct ip_match_entry));
++	new_match_entry = malloc(sizeof(struct acl_match_entry));
+ 	if (!new_match_entry)
+ 		return -1;
+ 
+@@ -207,12 +192,19 @@ int ipcheck_addip(struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	new_match_entry->acceptreject = acceptreject;
+ 	new_match_entry->next = NULL;
+ 
+-	/* Find the end of the list */
+-	/* is this OK, or should we use a doubly-linked list or bulk-load API call? */
+-	while (match_entry->next) {
+-		match_entry = match_entry->next;
++	if (match_entry) {
++		/* Find the end of the list */
++		/* is this OK, or should we use a doubly-linked list or bulk-load API call? */
++		while (match_entry->next) {
++			match_entry = match_entry->next;
++		}
++		match_entry->next = new_match_entry;
++	} else {
++		/*
++		 * first entry in the list
++		 */
++		*match_entry_head = new_match_entry;
+ 	}
+-	match_entry->next = new_match_entry;
+ 
+ 	return 0;
+ }
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index eca45669..26b0f36a 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -6,11 +6,17 @@
+  * This software licensed under GPL-2.0+, LGPL-2.0+
+  */
+ 
+-typedef enum {IPCHECK_TYPE_ADDRESS, IPCHECK_TYPE_MASK, IPCHECK_TYPE_RANGE} ipcheck_type_t;
+-typedef	enum {IPCHECK_ACCEPT, IPCHECK_REJECT} ipcheck_acceptreject_t;
++#ifndef __KNET_LINKS_ACL_H__
++#define __KNET_LINKS_ACL_H__
+ 
+-int ipcheck_validate(struct sockaddr_storage *checkip);
++#include "internals.h"
+ 
+-void ipcheck_clear(void);
+-int ipcheck_addip(struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		  ipcheck_type_t type, ipcheck_acceptreject_t acceptreject);
++int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
++
++void ipcheck_clear(struct acl_match_entry **match_entry_head);
++
++int ipcheck_addip(struct acl_match_entry **match_entry_head,
++		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  check_type_t type, check_acceptreject_t acceptreject);
++
++#endif
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+index 27ac545a..1e7f426d 100644
+--- a/libknet/tests/int_links_acl.c
++++ b/libknet/tests/int_links_acl.c
+@@ -14,8 +14,13 @@
+ #include <string.h>
+ #include <netdb.h>
+ #include <malloc.h>
++
++#include "internals.h"
+ #include "links_acl.h"
+ 
++static struct acl_match_entry *match_entry_v4;
++static struct acl_match_entry *match_entry_v6;
++
+ /* This is a test program .. remember! */
+ #define BUFLEN 1024
+ 
+@@ -31,7 +36,7 @@ static int get_ipaddress(char *buf, struct sockaddr_storage *addr)
+ 	res = getaddrinfo(buf, NULL, &hints, &info);
+ 	if (!res) {
+ 		memmove(addr, info->ai_addr, info->ai_addrlen);
+-		free(info);
++		freeaddrinfo(info);
+ 	}
+ 	return res;
+ }
+@@ -96,12 +101,13 @@ static int load_file(void)
+ 	char filebuf[BUFLEN];
+ 	int line = 0;
+ 	int ret;
+-	ipcheck_type_t type;
+-	ipcheck_acceptreject_t acceptreject;
++	check_type_t type;
++	check_acceptreject_t acceptreject;
+ 	struct sockaddr_storage addr1;
+ 	struct sockaddr_storage addr2;
+ 
+-	ipcheck_clear();
++	ipcheck_clear(&match_entry_v4);
++	ipcheck_clear(&match_entry_v6);
+ 
+ 	filterfile = fopen("int_links_acl.txt", "r");
+ 	if (!filterfile) {
+@@ -118,10 +124,10 @@ static int load_file(void)
+ 		 */
+ 		switch(filebuf[0] & 0x5F) {
+ 		case 'A':
+-			acceptreject = IPCHECK_ACCEPT;
++			acceptreject = CHECK_ACCEPT;
+ 			break;
+ 		case 'R':
+-			acceptreject = IPCHECK_REJECT;
++			acceptreject = CHECK_REJECT;
+ 			break;
+ 		default:
+ 			fprintf(stderr, "Unknown record type on line %d: %s\n", line, filebuf);
+@@ -136,15 +142,15 @@ static int load_file(void)
+ 		 */
+ 		switch(filebuf[1] & 0x5F) {
+ 		case 'A':
+-			type = IPCHECK_TYPE_ADDRESS;
++			type = CHECK_TYPE_ADDRESS;
+ 			ret = read_address(filebuf+2, &addr1);
+ 			break;
+ 		case 'M':
+-			type = IPCHECK_TYPE_MASK;
++			type = CHECK_TYPE_MASK;
+ 			ret = read_mask(filebuf+2, &addr1, &addr2);
+ 			break;
+ 		case 'R':
+-			type = IPCHECK_TYPE_RANGE;
++			type = CHECK_TYPE_RANGE;
+ 			ret = read_range(filebuf+2, &addr1, &addr2);
+ 			break;
+ 		default:
+@@ -156,7 +162,11 @@ static int load_file(void)
+ 			fprintf(stderr, "Failed to parse address on line %d: %s\n", line, filebuf);
+ 		}
+ 		else {
+-			ipcheck_addip(&addr1, &addr2, type, acceptreject);
++			if (addr1.ss_family == AF_INET) {
++				ipcheck_addip(&match_entry_v4, &addr1, &addr2, type, acceptreject);
++			} else {
++				ipcheck_addip(&match_entry_v6, &addr1, &addr2, type, acceptreject);
++			}
+ 		}
+ 	next_record: {} /* empty statement to mollify the compiler */
+ 	}
+@@ -168,6 +178,7 @@ static int load_file(void)
+ int main(int argc, char *argv[])
+ {
+ 	struct sockaddr_storage saddr;
++	struct acl_match_entry *match_entry;
+ 	int ret;
+ 	int i;
+ 
+@@ -178,16 +189,21 @@ int main(int argc, char *argv[])
+ 		ret = get_ipaddress(argv[i], &saddr);
+ 		if (ret) {
+ 			fprintf(stderr, "Cannot parse address %s\n", argv[i]);
+-		}
+-		else {
+-			if (ipcheck_validate(&saddr)) {
+-				printf("%s is VALID\n", argv[i]);
++		} else {
++			if (saddr.ss_family == AF_INET) {
++				match_entry = match_entry_v4;
++			} else {
++				match_entry = match_entry_v6;
+ 			}
+-			else {
++			if (ipcheck_validate(&match_entry, &saddr)) {
++				printf("%s is VALID\n", argv[i]);
++			} else {
+ 				printf("%s is not allowed\n", argv[i]);
+ 			}
+ 		}
+ 	}
+ 
++	ipcheck_clear(&match_entry_v4);
++	ipcheck_clear(&match_entry_v6);
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0206-handle-properly-initialize-fd-tracker-buffers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0206-handle-properly-initialize-fd-tracker-buffers.patch
new file mode 100644
index 000000000..febfa4e2a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0206-handle-properly-initialize-fd-tracker-buffers.patch
@@ -0,0 +1,26 @@ 
+From f1d9f3eec9eb8552594c8efe9e018be39b66fda1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 13 Feb 2019 09:14:45 +0100
+Subject: [PATCH] [handle] properly initialize fd tracker buffers
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 6cd49f51..0a2f75ae 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -309,7 +309,10 @@ static int _init_buffers(knet_handle_t knet_h)
+ 	}
+ 	memset(knet_h->send_to_links_buf_compress, 0, KNET_DATABUFSIZE_COMPRESS);
+ 
+-	memset(knet_h->knet_transport_fd_tracker, KNET_MAX_TRANSPORTS, sizeof(knet_h->knet_transport_fd_tracker));
++	memset(knet_h->knet_transport_fd_tracker, 0, sizeof(knet_h->knet_transport_fd_tracker));
++	for (i = 0; i < KNET_MAX_FDS; i++) {
++		knet_h->knet_transport_fd_tracker[i].transport = KNET_MAX_TRANSPORTS;
++	}
+ 
+ 	return 0;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0207-access-lists-automatically-add-and-remove-point-to-p.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0207-access-lists-automatically-add-and-remove-point-to-p.patch
new file mode 100644
index 000000000..6ed6aceb4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0207-access-lists-automatically-add-and-remove-point-to-p.patch
@@ -0,0 +1,283 @@ 
+From 472aaef6dcecce63b1fdaac609caefcddd6abf53 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 14 Feb 2019 06:32:42 +0100
+Subject: [PATCH] [access lists] automatically add and remove point to point
+ access lists
+
+those are not used just yet.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c               | 96 +++++++++++++++++++++++++++++++++++
+ libknet/links_acl.c           | 62 +++++++++++++++++++++-
+ libknet/links_acl.h           |  7 ++-
+ libknet/tests/int_links_acl.c |  8 +--
+ 4 files changed, 166 insertions(+), 7 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 010aeb69..6c75c359 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -20,6 +20,56 @@
+ #include "transports.h"
+ #include "host.h"
+ #include "threads_common.h"
++#include "links_acl.h"
++
++static void _link_del_all_acl(knet_handle_t knet_h, int sock)
++{
++	check_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
++}
++
++static int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
++{
++	int err = -1;
++
++	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
++		case LOOPBACK:
++			/*
++			 * loopback does not require access lists
++			 */
++			err = 0;
++			break;
++		case IP_PROTO:
++			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
++					    &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++			break;
++		default:
++			break;
++	}
++
++	return err;
++}
++
++static int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
++{
++	int err = -1;
++
++	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
++		case LOOPBACK:
++			/*
++			 * loopback does not require access lists
++			 */
++			err = 0;
++			break;
++		case IP_PROTO:
++			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
++					   &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++			break;
++		default:
++			break;
++	}
++
++	return err;
++}
+ 
+ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 		 unsigned int enabled, unsigned int connected)
+@@ -234,6 +284,21 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		err = -1;
+ 		goto exit_unlock;
+ 	}
++
++	/*
++	 * we can only configure default access lists if we know both endpoints
++	 */
++	if (link->dynamic == KNET_LINK_STATIC) {
++		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u",
++			  host_id, link_id);
++		if (_link_add_default_acl(knet_h, link) < 0) {
++			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
++			savederrno = errno;
++			err = -1;
++			goto exit_unlock;
++		}
++	}
++
+ 	link->configured = 1;
+ 	log_debug(knet_h, KNET_SUB_LINK, "host: %u link: %u is configured",
+ 		  host_id, link_id);
+@@ -351,6 +416,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	int savederrno = 0, err = 0;
+ 	struct knet_host *host;
+ 	struct knet_link *link;
++	int sock;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -397,6 +463,28 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 		goto exit_unlock;
+ 	}
+ 
++	/*
++	 * remove well known access lists here.
++	 * After the transport has done clearing the config,
++	 * then we can remove any leftover access lists if the link
++	 * is no longer in use.
++	 */
++	if (link->dynamic == KNET_LINK_STATIC) {
++		if (_link_rm_default_acl(knet_h, link) < 0) {
++			err = -1;
++			savederrno = EBUSY;
++			log_err(knet_h, KNET_SUB_LINK, "Host %u link %u: unable to remove default access list",
++				host_id, link_id);
++			goto exit_unlock;
++		}
++	}
++
++	/*
++	 * cache it for later as we don't know if the transport
++	 * will clear link info during clear_config.
++	 */
++	sock = link->outsock;
++
+ 	if ((transport_link_clear_config(knet_h, link) < 0)  &&
+ 	    (errno != EBUSY)) {
+ 		savederrno = errno;
+@@ -404,6 +492,14 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 		goto exit_unlock;
+ 	}
+ 
++	/*
++	 * remove any other access lists when the socket is no
++	 * longer in use by the transport.
++	 */
++	if (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS) {
++		_link_del_all_acl(knet_h, sock);
++	}
++
+ 	memset(link, 0, sizeof(struct knet_link));
+ 	link->link_id = link_id;
+ 
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index fe84088a..2ad3e90e 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -150,7 +150,7 @@ int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_
+  * Routines to manuipulate access lists
+  */
+ 
+-void ipcheck_clear(struct acl_match_entry **match_entry_head)
++void check_rmall(struct acl_match_entry **match_entry_head)
+ {
+ 	struct acl_match_entry *next_match_entry;
+ 	struct acl_match_entry *match_entry = *match_entry_head;
+@@ -163,6 +163,62 @@ void ipcheck_clear(struct acl_match_entry **match_entry_head)
+ 	*match_entry_head = NULL;
+ }
+ 
++static struct acl_match_entry *ipcheck_findmatch(struct acl_match_entry **match_entry_head,
++						 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++						 check_type_t type, check_acceptreject_t acceptreject)
++{
++	struct acl_match_entry *match_entry = *match_entry_head;
++
++	while (match_entry) {
++		if ((!memcmp(&match_entry->addr1, ip1, sizeof(struct sockaddr_storage))) &&
++		    (!memcmp(&match_entry->addr2, ip2, sizeof(struct sockaddr_storage))) &&
++		    (match_entry->type == type) &&
++		    (match_entry->acceptreject == acceptreject)) {
++			return match_entry;
++		}
++		match_entry = match_entry->next;
++	}
++
++	return NULL;
++}
++
++int ipcheck_rmip(struct acl_match_entry **match_entry_head,
++		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		 check_type_t type, check_acceptreject_t acceptreject)
++{
++	struct acl_match_entry *next_match_entry = NULL;
++	struct acl_match_entry *rm_match_entry;
++	struct acl_match_entry *match_entry = *match_entry_head;
++
++	rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
++	if (!rm_match_entry) {
++		return -1;
++	}
++
++	while (match_entry) {
++		next_match_entry = match_entry->next;
++		/*
++		 * we are removing the list head, be careful
++		 */
++		if (rm_match_entry == match_entry) {
++			*match_entry_head = next_match_entry;
++			free(match_entry);
++			break;
++		}
++		/*
++		 * the next one is the one we need to remove
++		 */
++		if (rm_match_entry == next_match_entry) {
++			match_entry->next = next_match_entry->next;
++			free(next_match_entry);
++			break;
++		}
++		match_entry = next_match_entry;
++	}
++
++	return 0;
++}
++
+ int ipcheck_addip(struct acl_match_entry **match_entry_head,
+ 		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 		  check_type_t type, check_acceptreject_t acceptreject)
+@@ -182,6 +238,10 @@ int ipcheck_addip(struct acl_match_entry **match_entry_head,
+ 	    (ip1->ss_family != ip2->ss_family))
+ 		return -1;
+ 
++	if (ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject) != NULL) {
++		return -1;
++	}
++
+ 	new_match_entry = malloc(sizeof(struct acl_match_entry));
+ 	if (!new_match_entry)
+ 		return -1;
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 26b0f36a..f4713d6c 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -13,10 +13,13 @@
+ 
+ int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
+ 
+-void ipcheck_clear(struct acl_match_entry **match_entry_head);
+-
+ int ipcheck_addip(struct acl_match_entry **match_entry_head,
+ 		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 		  check_type_t type, check_acceptreject_t acceptreject);
+ 
++int ipcheck_rmip(struct acl_match_entry **match_entry_head,
++		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  check_type_t type, check_acceptreject_t acceptreject);
++
++void check_rmall(struct acl_match_entry **match_entry_head);
+ #endif
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+index 1e7f426d..129aabe9 100644
+--- a/libknet/tests/int_links_acl.c
++++ b/libknet/tests/int_links_acl.c
+@@ -106,8 +106,8 @@ static int load_file(void)
+ 	struct sockaddr_storage addr1;
+ 	struct sockaddr_storage addr2;
+ 
+-	ipcheck_clear(&match_entry_v4);
+-	ipcheck_clear(&match_entry_v6);
++	check_rmall(&match_entry_v4);
++	check_rmall(&match_entry_v6);
+ 
+ 	filterfile = fopen("int_links_acl.txt", "r");
+ 	if (!filterfile) {
+@@ -203,7 +203,7 @@ int main(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	ipcheck_clear(&match_entry_v4);
+-	ipcheck_clear(&match_entry_v6);
++	check_rmall(&match_entry_v4);
++	check_rmall(&match_entry_v6);
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0208-access-lists-add-tests-for-default-access-lists.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0208-access-lists-add-tests-for-default-access-lists.patch
new file mode 100644
index 000000000..0f091e643
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0208-access-lists-add-tests-for-default-access-lists.patch
@@ -0,0 +1,63 @@ 
+From ec928b98d395e6891fb5e957ee9545b298aea0e8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 14 Feb 2019 06:47:41 +0100
+Subject: [PATCH] [access lists] add tests for default access lists
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_link_set_config.c | 28 ++++++++++++++++++++++++
+ 1 file changed, 28 insertions(+)
+
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index 8679428c..5fed9be2 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -24,6 +24,8 @@
+ static void test(void)
+ {
+ 	knet_handle_t knet_h;
++	struct knet_host *host;
++	struct knet_link *link;
+ 	int logfds[2];
+ 	char src_portstr[32];
+ 	char dst_portstr[32];
+@@ -140,6 +142,19 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
++	host = knet_h->host_index[1];
++	link = &host->link[0];
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].match_entry) {
++		printf("found access lists for dynamic dst_addr!\n");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(struct knet_link_status)) < 0) {
+ 		printf("Unable to get link status: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
+@@ -244,6 +259,19 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
++	host = knet_h->host_index[1];
++	link = &host->link[0];
++
++	if (!knet_h->knet_transport_fd_tracker[link->outsock].match_entry) {
++		printf("Unable to find default access lists for static dst_addr!\n");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(struct knet_link_status)) < 0) {
+ 		printf("Unable to get link status: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0209-access-lists-allow-knet_bench-to-enable-disable-acce.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0209-access-lists-allow-knet_bench-to-enable-disable-acce.patch
new file mode 100644
index 000000000..357922811
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0209-access-lists-allow-knet_bench-to-enable-disable-acce.patch
@@ -0,0 +1,62 @@ 
+From a615d82265bc30f8174b832a1d1e4ebc271e5be7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 14 Feb 2019 07:23:09 +0100
+Subject: [PATCH] [access lists] allow knet_bench to enable/disable access
+ lists
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/knet_bench.c | 12 +++++++++++-
+ 1 file changed, 11 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index b208b3ea..00cd58be 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -46,6 +46,7 @@ static int wait_for_perf_rx = 0;
+ static char *compresscfg = NULL;
+ static char *cryptocfg = NULL;
+ static int machine_output = 0;
++static int use_access_lists = 0;
+ 
+ static int bench_shutdown_in_progress = 0;
+ static pthread_mutex_t shutdown_mutex = PTHREAD_MUTEX_INITIALIZER;
+@@ -78,6 +79,7 @@ static void print_help(void)
+ 	printf("knet_bench usage:\n");
+ 	printf(" -h                                        print this help (no really)\n");
+ 	printf(" -d                                        enable debug logs (default INFO)\n");
++	printf(" -f                                        enable use of access lists (default: off)\n");
+ 	printf(" -c [implementation]:[crypto]:[hashing]    crypto configuration. (default disabled)\n");
+ 	printf("                                           Example: -c nss:aes128:sha1\n");
+ 	printf(" -z [implementation]:[level]:[threshold]   compress configuration. (default disabled)\n");
+@@ -248,7 +250,7 @@ static void setup_knet(int argc, char *argv[])
+ 
+ 	memset(nodes, 0, sizeof(nodes));
+ 
+-	while ((rv = getopt(argc, argv, "aCT:S:s:ldom:wb:t:n:c:p:X::P:z:h")) != EOF) {
++	while ((rv = getopt(argc, argv, "aCT:S:s:ldfom:wb:t:n:c:p:X::P:z:h")) != EOF) {
+ 		switch(rv) {
+ 			case 'h':
+ 				print_help();
+@@ -260,6 +262,9 @@ static void setup_knet(int argc, char *argv[])
+ 			case 'd':
+ 				debug = KNET_LOG_DEBUG;
+ 				break;
++			case 'f':
++				use_access_lists = 1;
++				break;
+ 			case 'c':
+ 				if (cryptocfg) {
+ 					printf("Error: -c can only be specified once\n");
+@@ -456,6 +461,11 @@ static void setup_knet(int argc, char *argv[])
+ 		exit(FAIL);
+ 	}
+ 
++	if (knet_handle_enable_access_lists(knet_h, use_access_lists) < 0) {
++		printf("Unable to knet_handle_enable_access_lists: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
+ 	if (cryptocfg) {
+ 		memset(&knet_handle_crypto_cfg, 0, sizeof(knet_handle_crypto_cfg));
+ 		cryptomodel = strtok(cryptocfg, ":");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0210-access-lists-enable-access-lists-for-GENERIC_ACL-pro.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0210-access-lists-enable-access-lists-for-GENERIC_ACL-pro.patch
new file mode 100644
index 000000000..e8d3b1ab8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0210-access-lists-enable-access-lists-for-GENERIC_ACL-pro.patch
@@ -0,0 +1,80 @@ 
+From 63c358f26911a89187f23b6fd6c407cd890d2616 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 15 Feb 2019 10:57:45 +0100
+Subject: [PATCH] [access lists] enable access lists for GENERIC_ACL protocols
+ (udp for example)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 44 ++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 8435d138..833938d9 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -20,6 +20,7 @@
+ #include "crypto.h"
+ #include "host.h"
+ #include "links.h"
++#include "links_acl.h"
+ #include "logging.h"
+ #include "transports.h"
+ #include "transport_common.h"
+@@ -720,6 +721,27 @@ out_pmtud:
+ 	}
+ }
+ 
++/*
++ * return 0 to reject and 1 to accept a packet
++ */
++static int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, const struct knet_mmsghdr *msg)
++{
++	switch(transport_get_proto(knet_h, knet_h->knet_transport_fd_tracker[sockfd].transport)) {
++		case LOOPBACK:
++			return 1;
++			break;
++		case IP_PROTO:
++			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sockfd].match_entry, msg->msg_hdr.msg_name);
++			break;
++		default:
++			break;
++	}
++	/*
++	 * reject by default
++	 */
++	return 0;
++}
++
+ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg)
+ {
+ 	int err, savederrno;
+@@ -802,6 +824,28 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 				goto exit_unlock;
+ 				break;
+ 			case 2: /* packet is data and should be parsed as such */
++				/*
++				 * processing incoming packets vs access lists
++				 */
++				if ((knet_h->use_access_lists) &&
++				    (transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL)) {
++					if (!_generic_filter_packet_by_acl(knet_h, sockfd, &msg[i])) {
++						char src_ipaddr[KNET_MAX_HOST_LEN];
++						char src_port[KNET_MAX_PORT_LEN];
++
++						memset(src_ipaddr, 0, KNET_MAX_HOST_LEN);
++						memset(src_port, 0, KNET_MAX_PORT_LEN);
++						knet_addrtostr(msg->msg_hdr.msg_name, sockaddr_len(msg->msg_hdr.msg_name),
++							       src_ipaddr, KNET_MAX_HOST_LEN,
++							       src_port, KNET_MAX_PORT_LEN);
++
++						log_debug(knet_h, KNET_SUB_RX, "Packet rejected from %s/%s", src_ipaddr, src_port);
++						/*
++						 * continue processing the other packets
++						 */
++						continue;
++					}
++				}
+ 				_parse_recv_from_links(knet_h, sockfd, &msg[i]);
+ 				break;
+ 		}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0211-access-lists-enable-generic-access-lists-only-for-pr.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0211-access-lists-enable-generic-access-lists-only-for-pr.patch
new file mode 100644
index 000000000..329a2e312
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0211-access-lists-enable-generic-access-lists-only-for-pr.patch
@@ -0,0 +1,55 @@ 
+From 15c9c9fea7ad72b6fb0397d60a473b664df0931d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 17 Feb 2019 07:32:59 +0100
+Subject: [PATCH] [access lists] enable generic access lists only for protocols
+ that use them
+
+protocols such as SCTP that use their own access list tracking will
+need to setup access lists in transport_link_set/clear_config
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 15 ++++++++++-----
+ 1 file changed, 10 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 6c75c359..85b50e51 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -287,10 +287,13 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ 	/*
+ 	 * we can only configure default access lists if we know both endpoints
++	 * and the protocol uses GENERIC_ACL, otherwise the protocol has
++	 * to setup their own access lists above in transport_link_set_config.
+ 	 */
+-	if (link->dynamic == KNET_LINK_STATIC) {
+-		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u",
+-			  host_id, link_id);
++	if ((transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL) &&
++	    (link->dynamic == KNET_LINK_STATIC)) {
++		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u socket: %d",
++			  host_id, link_id, link->outsock);
+ 		if (_link_add_default_acl(knet_h, link) < 0) {
+ 			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+ 			savederrno = errno;
+@@ -469,7 +472,8 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * then we can remove any leftover access lists if the link
+ 	 * is no longer in use.
+ 	 */
+-	if (link->dynamic == KNET_LINK_STATIC) {
++	if ((transport_get_acl_type(knet_h, link->transport_type) == USE_GENERIC_ACL) &&
++	    (link->dynamic == KNET_LINK_STATIC)) {
+ 		if (_link_rm_default_acl(knet_h, link) < 0) {
+ 			err = -1;
+ 			savederrno = EBUSY;
+@@ -496,7 +500,8 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * remove any other access lists when the socket is no
+ 	 * longer in use by the transport.
+ 	 */
+-	if (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS) {
++	if ((transport_get_acl_type(knet_h, link->transport_type) == USE_GENERIC_ACL) &&
++	    (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS)) {
+ 		_link_del_all_acl(knet_h, sock);
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0212-access-lists-add-access-lists-support-to-sctp.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0212-access-lists-add-access-lists-support-to-sctp.patch
new file mode 100644
index 000000000..c0198f7ac
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0212-access-lists-add-access-lists-support-to-sctp.patch
@@ -0,0 +1,96 @@ 
+From 2e901aed2cf61dabf1c0509401d778db5fd241c1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 17 Feb 2019 07:49:13 +0100
+Subject: [PATCH] [access lists] add access lists support to sctp
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 33 +++++++++++++++++++++++++++++++++
+ 1 file changed, 33 insertions(+)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index cb64a325..0d69a331 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -19,6 +19,7 @@
+ #include "compat.h"
+ #include "host.h"
+ #include "links.h"
++#include "links_acl.h"
+ #include "logging.h"
+ #include "common.h"
+ #include "transport_common.h"
+@@ -728,6 +729,15 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Incoming: received connection from: %s port: %s",
+ 						addr_str, port_str);
++	if (knet_h->use_access_lists) {
++		if (!ipcheck_validate(&knet_h->knet_transport_fd_tracker[listen_sock].match_entry, &ss)) {
++			savederrno = EINVAL;
++			err = -1;
++			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Connection rejected from %s/%s", addr_str, port_str);
++			close(new_fd);
++			goto exit_error;
++		}
++	}
+ 
+ 	/*
+ 	 * Keep a track of all accepted FDs
+@@ -936,6 +946,11 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	 */
+ 	knet_list_for_each_entry(info, &handle_info->listen_links_list, list) {
+ 		if (memcmp(&info->src_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
++			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[info->listen_sock].match_entry,
++					    &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++			if (err) {
++				return NULL;
++			}
+ 			return info;
+ 		}
+ 	}
+@@ -990,6 +1005,15 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 		goto exit_error;
+ 	}
+ 
++	if (ipcheck_addip(&knet_h->knet_transport_fd_tracker[listen_sock].match_entry,
++			  &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
++		savederrno = errno;
++		err = -1;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to configure default access lists: %s",
++			strerror(savederrno));
++		goto exit_error;
++	}
++
+ 	memset(&ev, 0, sizeof(struct epoll_event));
+ 	ev.events = EPOLLIN;
+ 	ev.data.fd = listen_sock;
+@@ -1012,6 +1036,8 @@ exit_error:
+ 		if (info->on_listener_epoll) {
+ 			epoll_ctl(handle_info->listen_epollfd, EPOLL_CTL_DEL, listen_sock, &ev);
+ 		}
++		ipcheck_rmip(&knet_h->knet_transport_fd_tracker[listen_sock].match_entry,
++			     &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ 		if (listen_sock >= 0) {
+ 			close(listen_sock);
+ 		}
+@@ -1050,6 +1076,11 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		}
+ 	}
+ 
++	if (ipcheck_rmip(&knet_h->knet_transport_fd_tracker[info->listen_sock].match_entry,
++			 &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
++		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove default access lists for %d", info->listen_sock);
++	}
++
+ 	if (found) {
+ 		this_link_info->listener = NULL;
+ 		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP listener socket %d still in use", info->listen_sock);
+@@ -1080,6 +1111,8 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		goto exit_error;
+ 	}
+ 
++	check_rmall(&knet_h->knet_transport_fd_tracker[info->listen_sock].match_entry);
++
+ 	close(info->listen_sock);
+ 
+ 	for (i=0; i< MAX_ACCEPTED_SOCKS; i++) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0213-access-lists-fix-build-on-freebsd.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0213-access-lists-fix-build-on-freebsd.patch
new file mode 100644
index 000000000..e3f1c2579
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0213-access-lists-fix-build-on-freebsd.patch
@@ -0,0 +1,54 @@ 
+From c6cb9a9c26d99ed824003c422ebf5e90db8c768f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 17 Feb 2019 09:49:06 +0100
+Subject: [PATCH] [access lists] fix build on freebsd
+
+don't use malloc.h, obsoleted by stdlib.h
+define s6_addr32 that's only available in kernel space
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c           | 11 ++++++++++-
+ libknet/tests/int_links_acl.c |  1 -
+ 2 files changed, 10 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 2ad3e90e..854f273d 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -10,13 +10,22 @@
+ #include <netinet/in.h>
+ #include <stdint.h>
+ #include <string.h>
+-#include <malloc.h>
++#include <stdlib.h>
+ 
+ #include "internals.h"
+ #include "logging.h"
+ #include "transports.h"
+ #include "links_acl.h"
+ 
++/*
++ * s6_addr32 is not defined in BSD userland, only kernel.
++ * definition is the same as linux and it works fine for
++ * what we need.
++ */
++#ifndef s6_addr32
++#define s6_addr32 __u6_addr.__u6_addr32
++#endif
++
+ /*
+  * IPv4 See if the address we have matches the current match entry
+  */
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+index 129aabe9..133cd5aa 100644
+--- a/libknet/tests/int_links_acl.c
++++ b/libknet/tests/int_links_acl.c
+@@ -13,7 +13,6 @@
+ #include <stdlib.h>
+ #include <string.h>
+ #include <netdb.h>
+-#include <malloc.h>
+ 
+ #include "internals.h"
+ #include "links_acl.h"
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0214-access-lists-move-all-acl-wrappers-to-links_acl-and-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0214-access-lists-move-all-acl-wrappers-to-links_acl-and-.patch
new file mode 100644
index 000000000..fd2e13b07
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0214-access-lists-move-all-acl-wrappers-to-links_acl-and-.patch
@@ -0,0 +1,1025 @@ 
+From c0475d3af9c54b4f59c30a3bc9ef1f839d83c040 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 04:53:23 +0100
+Subject: [PATCH] [access lists] move all acl wrappers to links_acl* and split
+ links_acl_ip to their own files
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am           |   2 +
+ libknet/links.c               |  53 +-----
+ libknet/links_acl.c           | 322 ++++++++++------------------------
+ libknet/links_acl.h           |  20 +--
+ libknet/links_acl_ip.c        | 277 +++++++++++++++++++++++++++++
+ libknet/links_acl_ip.h        |  25 +++
+ libknet/tests/Makefile.am     |  12 +-
+ libknet/tests/int_links_acl.c |   9 +-
+ libknet/threads_rx.c          |  25 +--
+ libknet/transport_sctp.c      |  24 +--
+ 10 files changed, 438 insertions(+), 331 deletions(-)
+ create mode 100644 libknet/links_acl_ip.c
+ create mode 100644 libknet/links_acl_ip.h
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 4ea42d9e..b60427ce 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -32,6 +32,7 @@ sources			= \
+ 			  host.c \
+ 			  links.c \
+ 			  links_acl.c \
++			  links_acl_ip.c \
+ 			  logging.c \
+ 			  netutils.c \
+ 			  threads_common.c \
+@@ -63,6 +64,7 @@ noinst_HEADERS		= \
+ 			  internals.h \
+ 			  links.h \
+ 			  links_acl.h \
++			  links_acl_ip.h \
+ 			  logging.h \
+ 			  netutils.h \
+ 			  onwire.h \
+diff --git a/libknet/links.c b/libknet/links.c
+index 85b50e51..07ef26ee 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -22,55 +22,6 @@
+ #include "threads_common.h"
+ #include "links_acl.h"
+ 
+-static void _link_del_all_acl(knet_handle_t knet_h, int sock)
+-{
+-	check_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
+-}
+-
+-static int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+-{
+-	int err = -1;
+-
+-	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
+-		case LOOPBACK:
+-			/*
+-			 * loopback does not require access lists
+-			 */
+-			err = 0;
+-			break;
+-		case IP_PROTO:
+-			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+-					    &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-			break;
+-		default:
+-			break;
+-	}
+-
+-	return err;
+-}
+-
+-static int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+-{
+-	int err = -1;
+-
+-	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
+-		case LOOPBACK:
+-			/*
+-			 * loopback does not require access lists
+-			 */
+-			err = 0;
+-			break;
+-		case IP_PROTO:
+-			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+-					   &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-			break;
+-		default:
+-			break;
+-	}
+-
+-	return err;
+-}
+-
+ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 		 unsigned int enabled, unsigned int connected)
+ {
+@@ -420,6 +371,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 	int sock;
++	uint8_t transport;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -488,6 +440,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * will clear link info during clear_config.
+ 	 */
+ 	sock = link->outsock;
++	transport = link->transport_type;
+ 
+ 	if ((transport_link_clear_config(knet_h, link) < 0)  &&
+ 	    (errno != EBUSY)) {
+@@ -502,7 +455,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 */
+ 	if ((transport_get_acl_type(knet_h, link->transport_type) == USE_GENERIC_ACL) &&
+ 	    (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS)) {
+-		_link_del_all_acl(knet_h, sock);
++		check_rmall(knet_h, sock, transport);
+ 	}
+ 
+ 	memset(link, 0, sizeof(struct knet_link));
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 854f273d..34bcce3b 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -6,8 +6,6 @@
+  * This software licensed under GPL-2.0+, LGPL-2.0+
+  */
+ 
+-#include <sys/socket.h>
+-#include <netinet/in.h>
+ #include <stdint.h>
+ #include <string.h>
+ #include <stdlib.h>
+@@ -15,265 +13,125 @@
+ #include "internals.h"
+ #include "logging.h"
+ #include "transports.h"
++#include "transport_common.h"
+ #include "links_acl.h"
++#include "links_acl_ip.h"
+ 
+-/*
+- * s6_addr32 is not defined in BSD userland, only kernel.
+- * definition is the same as linux and it works fine for
+- * what we need.
+- */
+-#ifndef s6_addr32
+-#define s6_addr32 __u6_addr.__u6_addr32
+-#endif
+-
+-/*
+- * IPv4 See if the address we have matches the current match entry
+- */
+-
+-static int ip_matches_v4(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
+-{
+-	struct sockaddr_in *ip_to_check;
+-	struct sockaddr_in *match1;
+-	struct sockaddr_in *match2;
+-
+-	ip_to_check = (struct sockaddr_in *)checkip;
+-	match1 = (struct sockaddr_in *)&match_entry->addr1;
+-	match2 = (struct sockaddr_in *)&match_entry->addr2;
+-
+-	switch(match_entry->type) {
+-	case CHECK_TYPE_ADDRESS:
+-		if (ip_to_check->sin_addr.s_addr == match1->sin_addr.s_addr)
+-			return 1;
+-		break;
+-	case CHECK_TYPE_MASK:
+-		if ((ip_to_check->sin_addr.s_addr & match2->sin_addr.s_addr) ==
+-		    match1->sin_addr.s_addr)
+-			return 1;
+-		break;
+-	case CHECK_TYPE_RANGE:
+-		if ((ntohl(ip_to_check->sin_addr.s_addr) >= ntohl(match1->sin_addr.s_addr)) &&
+-		    (ntohl(ip_to_check->sin_addr.s_addr) <= ntohl(match2->sin_addr.s_addr)))
+-			return 1;
+-		break;
+-
+-	}
+-	return 0;
+-}
+-
+-/*
+- * Compare two IPv6 addresses
+- */
+-
+-static int ip6addr_cmp(struct in6_addr *a, struct in6_addr *b)
++int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
++	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	      check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	uint64_t a_high, a_low;
+-	uint64_t b_high, b_low;
++	int err = -1;
+ 
+-	/* Not sure why '&' doesn't work below, so I used '+' instead which is effectively
+-	   the same thing because the bottom 32bits are always zero and the value unsigned */
+-	a_high = ((uint64_t)htonl(a->s6_addr32[0]) << 32) + (uint64_t)htonl(a->s6_addr32[1]);
+-	a_low  = ((uint64_t)htonl(a->s6_addr32[2]) << 32) + (uint64_t)htonl(a->s6_addr32[3]);
+-
+-	b_high = ((uint64_t)htonl(b->s6_addr32[0]) << 32) + (uint64_t)htonl(b->s6_addr32[1]);
+-	b_low  = ((uint64_t)htonl(b->s6_addr32[2]) << 32) + (uint64_t)htonl(b->s6_addr32[3]);
+-
+-	if (a_high > b_high)
+-		return 1;
+-	if (a_high < b_high)
+-		return -1;
+-
+-	if (a_low > b_low)
+-		return 1;
+-	if (a_low < b_low)
+-		return -1;
+-
+-	return 0;
+-}
+-
+-/*
+- * IPv6 See if the address we have matches the current match entry
+- */
+-
+-static int ip_matches_v6(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
+-{
+-	struct sockaddr_in6 *ip_to_check;
+-	struct sockaddr_in6 *match1;
+-	struct sockaddr_in6 *match2;
+-	int i;
+-
+-	ip_to_check = (struct sockaddr_in6 *)checkip;
+-	match1 = (struct sockaddr_in6 *)&match_entry->addr1;
+-	match2 = (struct sockaddr_in6 *)&match_entry->addr2;
+-
+-	switch(match_entry->type) {
+-	case CHECK_TYPE_ADDRESS:
+-		if (!memcmp(ip_to_check->sin6_addr.s6_addr32, match1->sin6_addr.s6_addr32, sizeof(struct in6_addr)))
+-			return 1;
+-		break;
+-
+-	case CHECK_TYPE_MASK:
+-		/*
+-		 * Note that this little loop will quit early if there is a non-match so the
+-		 * comparison might look backwards compared to the IPv4 one
+-		 */
+-		for (i=sizeof(struct in6_addr)/4-1; i>=0; i--) {
+-			if ((ip_to_check->sin6_addr.s6_addr32[i] & match2->sin6_addr.s6_addr32[i]) !=
+-			    match1->sin6_addr.s6_addr32[i])
+-				return 0;
+-		}
+-		return 1;
+-	case CHECK_TYPE_RANGE:
+-		if ((ip6addr_cmp(&ip_to_check->sin6_addr, &match1->sin6_addr) >= 0) &&
+-		    (ip6addr_cmp(&ip_to_check->sin6_addr, &match2->sin6_addr) <= 0))
+-			return 1;
+-		break;
++	switch(transport_get_proto(knet_h, transport)) {
++		case LOOPBACK:
++			err = 0;
++			break;
++		case IP_PROTO:
++			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
++					    ip1, ip2, type, acceptreject);
++			break;
++		default:
++			break;
+ 	}
+-	return 0;
++	return err;
+ }
+ 
+-
+-int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip)
++int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
++	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	     check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	struct acl_match_entry *match_entry = *match_entry_head;
+-	int (*match_fn)(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry);
++	int err = -1;
+ 
+-	if (checkip->ss_family == AF_INET){
+-		match_fn = ip_matches_v4;
+-	} else {
+-		match_fn = ip_matches_v6;
+-	}
+-
+-	while (match_entry) {
+-		if (match_fn(checkip, match_entry)) {
+-			if (match_entry->acceptreject == CHECK_ACCEPT)
+-				return 1;
+-			else
+-				return 0;
+-		}
+-		match_entry = match_entry->next;
++	switch(transport_get_proto(knet_h, transport)) {
++		case LOOPBACK:
++			err = 0;
++			break;
++		case IP_PROTO:
++			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
++					   ip1, ip2, type, acceptreject);
++			break;
++		default:
++			break;
+ 	}
+-	return 0; /* Default reject */
++	return err;
+ }
+ 
+-/*
+- * Routines to manuipulate access lists
+- */
+-
+-void check_rmall(struct acl_match_entry **match_entry_head)
++void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ {
+-	struct acl_match_entry *next_match_entry;
+-	struct acl_match_entry *match_entry = *match_entry_head;
+-
+-	while (match_entry) {
+-		next_match_entry = match_entry->next;
+-		free(match_entry);
+-		match_entry = next_match_entry;
++	switch(transport_get_proto(knet_h, transport)) {
++		case LOOPBACK:
++			return;
++			break;
++		case IP_PROTO:
++			ipcheck_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
++			break;
++		default:
++			break;
+ 	}
+-	*match_entry_head = NULL;
+ }
+ 
+-static struct acl_match_entry *ipcheck_findmatch(struct acl_match_entry **match_entry_head,
+-						 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-						 check_type_t type, check_acceptreject_t acceptreject)
++int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+ {
+-	struct acl_match_entry *match_entry = *match_entry_head;
+-
+-	while (match_entry) {
+-		if ((!memcmp(&match_entry->addr1, ip1, sizeof(struct sockaddr_storage))) &&
+-		    (!memcmp(&match_entry->addr2, ip2, sizeof(struct sockaddr_storage))) &&
+-		    (match_entry->type == type) &&
+-		    (match_entry->acceptreject == acceptreject)) {
+-			return match_entry;
+-		}
+-		match_entry = match_entry->next;
++	int err = -1;
++
++	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
++		case LOOPBACK:
++			/*
++			 * loopback does not require access lists
++			 */
++			err = 0;
++			break;
++		case IP_PROTO:
++			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
++					    &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++			break;
++		default:
++			break;
+ 	}
+ 
+-	return NULL;
++	return err;
+ }
+ 
+-int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+-		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		 check_type_t type, check_acceptreject_t acceptreject)
++int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+ {
+-	struct acl_match_entry *next_match_entry = NULL;
+-	struct acl_match_entry *rm_match_entry;
+-	struct acl_match_entry *match_entry = *match_entry_head;
+-
+-	rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
+-	if (!rm_match_entry) {
+-		return -1;
+-	}
+-
+-	while (match_entry) {
+-		next_match_entry = match_entry->next;
+-		/*
+-		 * we are removing the list head, be careful
+-		 */
+-		if (rm_match_entry == match_entry) {
+-			*match_entry_head = next_match_entry;
+-			free(match_entry);
++	int err = -1;
++
++	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
++		case LOOPBACK:
++			/*
++			 * loopback does not require access lists
++			 */
++			err = 0;
++			break;
++		case IP_PROTO:
++			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
++					   &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ 			break;
+-		}
+-		/*
+-		 * the next one is the one we need to remove
+-		 */
+-		if (rm_match_entry == next_match_entry) {
+-			match_entry->next = next_match_entry->next;
+-			free(next_match_entry);
++		default:
+ 			break;
+-		}
+-		match_entry = next_match_entry;
+ 	}
+ 
+-	return 0;
++	return err;
+ }
+ 
+-int ipcheck_addip(struct acl_match_entry **match_entry_head,
+-		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		  check_type_t type, check_acceptreject_t acceptreject)
++/*
++ *  * return 0 to reject and 1 to accept a packet
++ *   */
++int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip)
+ {
+-	struct acl_match_entry *new_match_entry;
+-	struct acl_match_entry *match_entry = *match_entry_head;
+-
+-	if (!ip1) {
+-		return -1;
+-	}
+-
+-	if ((type != CHECK_TYPE_ADDRESS) && (!ip2)) {
+-		return -1;
+-	}
+-
+-	if (type == CHECK_TYPE_RANGE &&
+-	    (ip1->ss_family != ip2->ss_family))
+-		return -1;
+-
+-	if (ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject) != NULL) {
+-		return -1;
+-	}
+-
+-	new_match_entry = malloc(sizeof(struct acl_match_entry));
+-	if (!new_match_entry)
+-		return -1;
+-
+-	memmove(&new_match_entry->addr1, ip1, sizeof(struct sockaddr_storage));
+-	memmove(&new_match_entry->addr2, ip2, sizeof(struct sockaddr_storage));
+-	new_match_entry->type = type;
+-	new_match_entry->acceptreject = acceptreject;
+-	new_match_entry->next = NULL;
+-
+-	if (match_entry) {
+-		/* Find the end of the list */
+-		/* is this OK, or should we use a doubly-linked list or bulk-load API call? */
+-		while (match_entry->next) {
+-			match_entry = match_entry->next;
+-		}
+-		match_entry->next = new_match_entry;
+-	} else {
+-		/*
+-		 * first entry in the list
+-		 */
+-		*match_entry_head = new_match_entry;
++	switch(transport_get_proto(knet_h, knet_h->knet_transport_fd_tracker[sockfd].transport)) {
++		case LOOPBACK:
++			return 1;
++			break;
++		case IP_PROTO:
++			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sockfd].match_entry, checkip);
++			break;
++		default:
++			break;
+ 	}
+-
++	/*
++	 * reject by default
++	 */
+ 	return 0;
+ }
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index f4713d6c..9a20754f 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -11,15 +11,15 @@
+ 
+ #include "internals.h"
+ 
+-int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
++int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
++	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	      check_type_t type, check_acceptreject_t acceptreject);
++int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
++	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	     check_type_t type, check_acceptreject_t acceptreject);
++void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport);
++int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link);
++int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link);
++int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip);
+ 
+-int ipcheck_addip(struct acl_match_entry **match_entry_head,
+-		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		  check_type_t type, check_acceptreject_t acceptreject);
+-
+-int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+-		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		  check_type_t type, check_acceptreject_t acceptreject);
+-
+-void check_rmall(struct acl_match_entry **match_entry_head);
+ #endif
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+new file mode 100644
+index 00000000..edc3ae10
+--- /dev/null
++++ b/libknet/links_acl_ip.c
+@@ -0,0 +1,277 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Christine Caulfield <ccaulfie@redhat.com>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <stdint.h>
++#include <string.h>
++#include <stdlib.h>
++
++#include "internals.h"
++#include "logging.h"
++#include "transports.h"
++#include "links_acl_ip.h"
++
++/*
++ * s6_addr32 is not defined in BSD userland, only kernel.
++ * definition is the same as linux and it works fine for
++ * what we need.
++ */
++#ifndef s6_addr32
++#define s6_addr32 __u6_addr.__u6_addr32
++#endif
++
++/*
++ * IPv4 See if the address we have matches the current match entry
++ */
++
++static int ip_matches_v4(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
++{
++	struct sockaddr_in *ip_to_check;
++	struct sockaddr_in *match1;
++	struct sockaddr_in *match2;
++
++	ip_to_check = (struct sockaddr_in *)checkip;
++	match1 = (struct sockaddr_in *)&match_entry->addr1;
++	match2 = (struct sockaddr_in *)&match_entry->addr2;
++
++	switch(match_entry->type) {
++	case CHECK_TYPE_ADDRESS:
++		if (ip_to_check->sin_addr.s_addr == match1->sin_addr.s_addr)
++			return 1;
++		break;
++	case CHECK_TYPE_MASK:
++		if ((ip_to_check->sin_addr.s_addr & match2->sin_addr.s_addr) ==
++		    match1->sin_addr.s_addr)
++			return 1;
++		break;
++	case CHECK_TYPE_RANGE:
++		if ((ntohl(ip_to_check->sin_addr.s_addr) >= ntohl(match1->sin_addr.s_addr)) &&
++		    (ntohl(ip_to_check->sin_addr.s_addr) <= ntohl(match2->sin_addr.s_addr)))
++			return 1;
++		break;
++
++	}
++	return 0;
++}
++
++/*
++ * Compare two IPv6 addresses
++ */
++
++static int ip6addr_cmp(struct in6_addr *a, struct in6_addr *b)
++{
++	uint64_t a_high, a_low;
++	uint64_t b_high, b_low;
++
++	a_high = ((uint64_t)htonl(a->s6_addr32[0]) << 32) | (uint64_t)htonl(a->s6_addr32[1]);
++	a_low  = ((uint64_t)htonl(a->s6_addr32[2]) << 32) | (uint64_t)htonl(a->s6_addr32[3]);
++
++	b_high = ((uint64_t)htonl(b->s6_addr32[0]) << 32) | (uint64_t)htonl(b->s6_addr32[1]);
++	b_low  = ((uint64_t)htonl(b->s6_addr32[2]) << 32) | (uint64_t)htonl(b->s6_addr32[3]);
++
++	if (a_high > b_high)
++		return 1;
++	if (a_high < b_high)
++		return -1;
++
++	if (a_low > b_low)
++		return 1;
++	if (a_low < b_low)
++		return -1;
++
++	return 0;
++}
++
++/*
++ * IPv6 See if the address we have matches the current match entry
++ */
++
++static int ip_matches_v6(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
++{
++	struct sockaddr_in6 *ip_to_check;
++	struct sockaddr_in6 *match1;
++	struct sockaddr_in6 *match2;
++	int i;
++
++	ip_to_check = (struct sockaddr_in6 *)checkip;
++	match1 = (struct sockaddr_in6 *)&match_entry->addr1;
++	match2 = (struct sockaddr_in6 *)&match_entry->addr2;
++
++	switch(match_entry->type) {
++	case CHECK_TYPE_ADDRESS:
++		if (!memcmp(ip_to_check->sin6_addr.s6_addr32, match1->sin6_addr.s6_addr32, sizeof(struct in6_addr)))
++			return 1;
++		break;
++
++	case CHECK_TYPE_MASK:
++		/*
++		 * Note that this little loop will quit early if there is a non-match so the
++		 * comparison might look backwards compared to the IPv4 one
++		 */
++		for (i=sizeof(struct in6_addr)/4-1; i>=0; i--) {
++			if ((ip_to_check->sin6_addr.s6_addr32[i] & match2->sin6_addr.s6_addr32[i]) !=
++			    match1->sin6_addr.s6_addr32[i])
++				return 0;
++		}
++		return 1;
++	case CHECK_TYPE_RANGE:
++		if ((ip6addr_cmp(&ip_to_check->sin6_addr, &match1->sin6_addr) >= 0) &&
++		    (ip6addr_cmp(&ip_to_check->sin6_addr, &match2->sin6_addr) <= 0))
++			return 1;
++		break;
++	}
++	return 0;
++}
++
++
++int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip)
++{
++	struct acl_match_entry *match_entry = *match_entry_head;
++	int (*match_fn)(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry);
++
++	if (checkip->ss_family == AF_INET){
++		match_fn = ip_matches_v4;
++	} else {
++		match_fn = ip_matches_v6;
++	}
++
++	while (match_entry) {
++		if (match_fn(checkip, match_entry)) {
++			if (match_entry->acceptreject == CHECK_ACCEPT)
++				return 1;
++			else
++				return 0;
++		}
++		match_entry = match_entry->next;
++	}
++	return 0; /* Default reject */
++}
++
++/*
++ * Routines to manuipulate access lists
++ */
++
++void ipcheck_rmall(struct acl_match_entry **match_entry_head)
++{
++	struct acl_match_entry *next_match_entry;
++	struct acl_match_entry *match_entry = *match_entry_head;
++
++	while (match_entry) {
++		next_match_entry = match_entry->next;
++		free(match_entry);
++		match_entry = next_match_entry;
++	}
++	*match_entry_head = NULL;
++}
++
++static struct acl_match_entry *ipcheck_findmatch(struct acl_match_entry **match_entry_head,
++						 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++						 check_type_t type, check_acceptreject_t acceptreject)
++{
++	struct acl_match_entry *match_entry = *match_entry_head;
++
++	while (match_entry) {
++		if ((!memcmp(&match_entry->addr1, ip1, sizeof(struct sockaddr_storage))) &&
++		    (!memcmp(&match_entry->addr2, ip2, sizeof(struct sockaddr_storage))) &&
++		    (match_entry->type == type) &&
++		    (match_entry->acceptreject == acceptreject)) {
++			return match_entry;
++		}
++		match_entry = match_entry->next;
++	}
++
++	return NULL;
++}
++
++int ipcheck_rmip(struct acl_match_entry **match_entry_head,
++		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		 check_type_t type, check_acceptreject_t acceptreject)
++{
++	struct acl_match_entry *next_match_entry = NULL;
++	struct acl_match_entry *rm_match_entry;
++	struct acl_match_entry *match_entry = *match_entry_head;
++
++	rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
++	if (!rm_match_entry) {
++		return -1;
++	}
++
++	while (match_entry) {
++		next_match_entry = match_entry->next;
++		/*
++		 * we are removing the list head, be careful
++		 */
++		if (rm_match_entry == match_entry) {
++			*match_entry_head = next_match_entry;
++			free(match_entry);
++			break;
++		}
++		/*
++		 * the next one is the one we need to remove
++		 */
++		if (rm_match_entry == next_match_entry) {
++			match_entry->next = next_match_entry->next;
++			free(next_match_entry);
++			break;
++		}
++		match_entry = next_match_entry;
++	}
++
++	return 0;
++}
++
++int ipcheck_addip(struct acl_match_entry **match_entry_head,
++		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  check_type_t type, check_acceptreject_t acceptreject)
++{
++	struct acl_match_entry *new_match_entry;
++	struct acl_match_entry *match_entry = *match_entry_head;
++
++	if (!ip1) {
++		return -1;
++	}
++
++	if ((type != CHECK_TYPE_ADDRESS) && (!ip2)) {
++		return -1;
++	}
++
++	if (type == CHECK_TYPE_RANGE &&
++	    (ip1->ss_family != ip2->ss_family))
++		return -1;
++
++	if (ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject) != NULL) {
++		return -1;
++	}
++
++	new_match_entry = malloc(sizeof(struct acl_match_entry));
++	if (!new_match_entry)
++		return -1;
++
++	memmove(&new_match_entry->addr1, ip1, sizeof(struct sockaddr_storage));
++	memmove(&new_match_entry->addr2, ip2, sizeof(struct sockaddr_storage));
++	new_match_entry->type = type;
++	new_match_entry->acceptreject = acceptreject;
++	new_match_entry->next = NULL;
++
++	if (match_entry) {
++		/* Find the end of the list */
++		/* is this OK, or should we use a doubly-linked list or bulk-load API call? */
++		while (match_entry->next) {
++			match_entry = match_entry->next;
++		}
++		match_entry->next = new_match_entry;
++	} else {
++		/*
++		 * first entry in the list
++		 */
++		*match_entry_head = new_match_entry;
++	}
++
++	return 0;
++}
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+new file mode 100644
+index 00000000..575b5ff8
+--- /dev/null
++++ b/libknet/links_acl_ip.h
+@@ -0,0 +1,25 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Christine Caulfield <ccaulfie@redhat.com>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#ifndef __KNET_LINKS_ACL_IP_H__
++#define __KNET_LINKS_ACL_IP_H__
++
++#include "internals.h"
++
++int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
++
++int ipcheck_addip(struct acl_match_entry **match_entry_head,
++		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  check_type_t type, check_acceptreject_t acceptreject);
++
++int ipcheck_rmip(struct acl_match_entry **match_entry_head,
++		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  check_type_t type, check_acceptreject_t acceptreject);
++
++void ipcheck_rmall(struct acl_match_entry **match_entry_head);
++#endif
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index f74cb046..d46553a5 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -68,7 +68,17 @@ check-api-test-coverage:
+ pckt_test_SOURCES	= pckt_test.c
+ 
+ int_links_acl_test_SOURCES = int_links_acl.c \
+-			     ../links_acl.c
++			     ../common.c \
++			     ../logging.c \
++			     ../netutils.c \
++			     ../threads_common.c \
++			     ../transports.c \
++			     ../transport_common.c \
++			     ../transport_loopback.c \
++			     ../transport_sctp.c \
++			     ../transport_udp.c \
++			     ../links_acl.c \
++			     ../links_acl_ip.c
+ 
+ int_timediff_test_SOURCES = int_timediff.c
+ 
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+index 133cd5aa..8d9f4e06 100644
+--- a/libknet/tests/int_links_acl.c
++++ b/libknet/tests/int_links_acl.c
+@@ -16,6 +16,7 @@
+ 
+ #include "internals.h"
+ #include "links_acl.h"
++#include "links_acl_ip.h"
+ 
+ static struct acl_match_entry *match_entry_v4;
+ static struct acl_match_entry *match_entry_v6;
+@@ -105,8 +106,8 @@ static int load_file(void)
+ 	struct sockaddr_storage addr1;
+ 	struct sockaddr_storage addr2;
+ 
+-	check_rmall(&match_entry_v4);
+-	check_rmall(&match_entry_v6);
++	ipcheck_rmall(&match_entry_v4);
++	ipcheck_rmall(&match_entry_v6);
+ 
+ 	filterfile = fopen("int_links_acl.txt", "r");
+ 	if (!filterfile) {
+@@ -202,7 +203,7 @@ int main(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	check_rmall(&match_entry_v4);
+-	check_rmall(&match_entry_v6);
++	ipcheck_rmall(&match_entry_v4);
++	ipcheck_rmall(&match_entry_v6);
+ 	return 0;
+ }
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 833938d9..06a0168c 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -721,27 +721,6 @@ out_pmtud:
+ 	}
+ }
+ 
+-/*
+- * return 0 to reject and 1 to accept a packet
+- */
+-static int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, const struct knet_mmsghdr *msg)
+-{
+-	switch(transport_get_proto(knet_h, knet_h->knet_transport_fd_tracker[sockfd].transport)) {
+-		case LOOPBACK:
+-			return 1;
+-			break;
+-		case IP_PROTO:
+-			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sockfd].match_entry, msg->msg_hdr.msg_name);
+-			break;
+-		default:
+-			break;
+-	}
+-	/*
+-	 * reject by default
+-	 */
+-	return 0;
+-}
+-
+ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg)
+ {
+ 	int err, savederrno;
+@@ -829,13 +808,13 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 				 */
+ 				if ((knet_h->use_access_lists) &&
+ 				    (transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL)) {
+-					if (!_generic_filter_packet_by_acl(knet_h, sockfd, &msg[i])) {
++					if (!_generic_filter_packet_by_acl(knet_h, sockfd, msg[i].msg_hdr.msg_name)) {
+ 						char src_ipaddr[KNET_MAX_HOST_LEN];
+ 						char src_port[KNET_MAX_PORT_LEN];
+ 
+ 						memset(src_ipaddr, 0, KNET_MAX_HOST_LEN);
+ 						memset(src_port, 0, KNET_MAX_PORT_LEN);
+-						knet_addrtostr(msg->msg_hdr.msg_name, sockaddr_len(msg->msg_hdr.msg_name),
++						knet_addrtostr(msg[i].msg_hdr.msg_name, sockaddr_len(msg[i].msg_hdr.msg_name),
+ 							       src_ipaddr, KNET_MAX_HOST_LEN,
+ 							       src_port, KNET_MAX_PORT_LEN);
+ 
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 0d69a331..ce3e98ef 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -20,6 +20,7 @@
+ #include "host.h"
+ #include "links.h"
+ #include "links_acl.h"
++#include "links_acl_ip.h"
+ #include "logging.h"
+ #include "common.h"
+ #include "transport_common.h"
+@@ -730,12 +731,13 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Incoming: received connection from: %s port: %s",
+ 						addr_str, port_str);
+ 	if (knet_h->use_access_lists) {
+-		if (!ipcheck_validate(&knet_h->knet_transport_fd_tracker[listen_sock].match_entry, &ss)) {
++		if (!_generic_filter_packet_by_acl(knet_h, listen_sock, &ss)) {
+ 			savederrno = EINVAL;
+ 			err = -1;
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Connection rejected from %s/%s", addr_str, port_str);
+ 			close(new_fd);
+-			goto exit_error;
++			errno = savederrno;
++			return;
+ 		}
+ 	}
+ 
+@@ -946,8 +948,8 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	 */
+ 	knet_list_for_each_entry(info, &handle_info->listen_links_list, list) {
+ 		if (memcmp(&info->src_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
+-			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[info->listen_sock].match_entry,
+-					    &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++			err = check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
++					&kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ 			if (err) {
+ 				return NULL;
+ 			}
+@@ -1005,8 +1007,8 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 		goto exit_error;
+ 	}
+ 
+-	if (ipcheck_addip(&knet_h->knet_transport_fd_tracker[listen_sock].match_entry,
+-			  &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
++	if (check_add(knet_h, listen_sock, KNET_TRANSPORT_SCTP,
++		      &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to configure default access lists: %s",
+@@ -1036,8 +1038,8 @@ exit_error:
+ 		if (info->on_listener_epoll) {
+ 			epoll_ctl(handle_info->listen_epollfd, EPOLL_CTL_DEL, listen_sock, &ev);
+ 		}
+-		ipcheck_rmip(&knet_h->knet_transport_fd_tracker[listen_sock].match_entry,
+-			     &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++		check_rm(knet_h, listen_sock, KNET_TRANSPORT_SCTP,
++			 &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ 		if (listen_sock >= 0) {
+ 			close(listen_sock);
+ 		}
+@@ -1076,8 +1078,8 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		}
+ 	}
+ 
+-	if (ipcheck_rmip(&knet_h->knet_transport_fd_tracker[info->listen_sock].match_entry,
+-			 &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
++	if (check_rm(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
++		     &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
+ 		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove default access lists for %d", info->listen_sock);
+ 	}
+ 
+@@ -1111,7 +1113,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		goto exit_error;
+ 	}
+ 
+-	check_rmall(&knet_h->knet_transport_fd_tracker[info->listen_sock].match_entry);
++	check_rmall(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP);
+ 
+ 	close(info->listen_sock);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0215-access-lists-move-access-lists-structs-and-data-type.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0215-access-lists-move-access-lists-structs-and-data-type.patch
new file mode 100644
index 000000000..bb35f8962
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0215-access-lists-move-access-lists-structs-and-data-type.patch
@@ -0,0 +1,168 @@ 
+From 8c1c764b5104156203a996813d8107b741ff0493 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 05:04:20 +0100
+Subject: [PATCH] [access lists] move access lists structs and data types to
+ links_acl.*
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h    | 25 +------------------------
+ libknet/links_acl.c    | 12 ++++++------
+ libknet/links_acl.h    | 19 +++++++++++++++++++
+ libknet/links_acl_ip.c |  1 +
+ libknet/links_acl_ip.h |  1 +
+ 5 files changed, 28 insertions(+), 30 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 78e718d0..0d6ee3f7 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -129,35 +129,12 @@ struct knet_sock {
+ 			  * and socket has been removed from epoll */
+ };
+ 
+-/*
+- * access lists
+- */
+-
+-typedef enum {
+-	CHECK_TYPE_ADDRESS,
+-	CHECK_TYPE_MASK,
+-	CHECK_TYPE_RANGE
+-} check_type_t;
+-
+-typedef	enum {
+-	CHECK_ACCEPT,
+-	CHECK_REJECT
+-} check_acceptreject_t;
+-
+-struct acl_match_entry {
+-	check_type_t type;
+-	check_acceptreject_t acceptreject;
+-	struct sockaddr_storage addr1; /* Actual IP address, mask top or low IP */
+-	struct sockaddr_storage addr2; /* high IP address or address bitmask */
+-	struct acl_match_entry *next;
+-};
+-
+ struct knet_fd_trackers {
+ 	uint8_t transport; /* transport type (UDP/SCTP...) */
+ 	uint8_t data_type; /* internal use for transport to define what data are associated
+ 			    * to this fd */
+ 	void *data;	   /* pointer to the data */
+-	struct acl_match_entry *match_entry;
++	void *match_entry; /* pointer to access list match_entry list head */
+ };
+ 
+ #define KNET_MAX_FDS KNET_MAX_HOST * KNET_MAX_LINK * 4
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 34bcce3b..32763de4 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -28,7 +28,7 @@ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
++			err = ipcheck_addip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry,
+ 					    ip1, ip2, type, acceptreject);
+ 			break;
+ 		default:
+@@ -48,7 +48,7 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
++			err = ipcheck_rmip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry,
+ 					   ip1, ip2, type, acceptreject);
+ 			break;
+ 		default:
+@@ -64,7 +64,7 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ 			return;
+ 			break;
+ 		case IP_PROTO:
+-			ipcheck_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
++			ipcheck_rmall((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry);
+ 			break;
+ 		default:
+ 			break;
+@@ -83,7 +83,7 @@ int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
++			err = ipcheck_addip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+ 					    &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ 			break;
+ 		default:
+@@ -105,7 +105,7 @@ int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
++			err = ipcheck_rmip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+ 					   &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ 			break;
+ 		default:
+@@ -125,7 +125,7 @@ int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct socka
+ 			return 1;
+ 			break;
+ 		case IP_PROTO:
+-			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sockfd].match_entry, checkip);
++			return ipcheck_validate((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sockfd].match_entry, checkip);
+ 			break;
+ 		default:
+ 			break;
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 9a20754f..020ec05a 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -11,6 +11,25 @@
+ 
+ #include "internals.h"
+ 
++typedef enum {
++	CHECK_TYPE_ADDRESS,
++	CHECK_TYPE_MASK,
++	CHECK_TYPE_RANGE
++} check_type_t;
++
++typedef enum {
++	CHECK_ACCEPT,
++	CHECK_REJECT
++} check_acceptreject_t;
++
++struct acl_match_entry {
++	check_type_t type;
++	check_acceptreject_t acceptreject;
++	struct sockaddr_storage addr1; /* Actual IP address, mask top or low IP */
++	struct sockaddr_storage addr2; /* high IP address or address bitmask */
++	struct acl_match_entry *next;
++};
++
+ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	      check_type_t type, check_acceptreject_t acceptreject);
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index edc3ae10..2aef14ba 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -15,6 +15,7 @@
+ #include "internals.h"
+ #include "logging.h"
+ #include "transports.h"
++#include "links_acl.h"
+ #include "links_acl_ip.h"
+ 
+ /*
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index 575b5ff8..9e21e00f 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -10,6 +10,7 @@
+ #define __KNET_LINKS_ACL_IP_H__
+ 
+ #include "internals.h"
++#include "links_acl.h"
+ 
+ int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0216-access-lists-more-use-of-generic-wrappers-and-remove.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0216-access-lists-more-use-of-generic-wrappers-and-remove.patch
new file mode 100644
index 000000000..f78aa6d3e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0216-access-lists-more-use-of-generic-wrappers-and-remove.patch
@@ -0,0 +1,73 @@ 
+From fe2ed121dc6a64154c98ec00471b47e80e7c74e8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 05:17:57 +0100
+Subject: [PATCH] [access lists] more use of generic wrappers and remove
+ duplicate code
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c | 44 ++++++--------------------------------------
+ 1 file changed, 6 insertions(+), 38 deletions(-)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 32763de4..85a792dc 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -73,51 +73,19 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ 
+ int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+ {
+-	int err = -1;
+-
+-	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
+-		case LOOPBACK:
+-			/*
+-			 * loopback does not require access lists
+-			 */
+-			err = 0;
+-			break;
+-		case IP_PROTO:
+-			err = ipcheck_addip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+-					    &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-			break;
+-		default:
+-			break;
+-	}
+-
+-	return err;
++	return check_add(knet_h, kh_link->outsock, kh_link->transport_type,
++			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ }
+ 
+ int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+ {
+-	int err = -1;
+-
+-	switch(transport_get_proto(knet_h, kh_link->transport_type)) {
+-		case LOOPBACK:
+-			/*
+-			 * loopback does not require access lists
+-			 */
+-			err = 0;
+-			break;
+-		case IP_PROTO:
+-			err = ipcheck_rmip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[kh_link->outsock].match_entry,
+-					   &kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-			break;
+-		default:
+-			break;
+-	}
+-
+-	return err;
++	return check_rm(knet_h, kh_link->outsock, kh_link->transport_type,
++			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+ }
+ 
+ /*
+- *  * return 0 to reject and 1 to accept a packet
+- *   */
++ * return 0 to reject and 1 to accept a packet
++ */
+ int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip)
+ {
+ 	switch(transport_get_proto(knet_h, knet_h->knet_transport_fd_tracker[sockfd].transport)) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0217-access-lists-cleanup-API-a-bit.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0217-access-lists-cleanup-API-a-bit.patch
new file mode 100644
index 000000000..5bb9d5a66
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0217-access-lists-cleanup-API-a-bit.patch
@@ -0,0 +1,98 @@ 
+From 48c523e45d3281370a92f5e29498580afade2974 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 05:21:29 +0100
+Subject: [PATCH] [access lists] cleanup API a bit
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c      | 26 +++++++++++++-------------
+ libknet/links_acl.h      |  3 ++-
+ libknet/threads_rx.c     |  2 +-
+ libknet/transport_sctp.c |  2 +-
+ 4 files changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 85a792dc..520a934c 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -71,22 +71,10 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ 	}
+ }
+ 
+-int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+-{
+-	return check_add(knet_h, kh_link->outsock, kh_link->transport_type,
+-			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-}
+-
+-int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+-{
+-	return check_rm(knet_h, kh_link->outsock, kh_link->transport_type,
+-			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-}
+-
+ /*
+  * return 0 to reject and 1 to accept a packet
+  */
+-int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip)
++int check_validate(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip)
+ {
+ 	switch(transport_get_proto(knet_h, knet_h->knet_transport_fd_tracker[sockfd].transport)) {
+ 		case LOOPBACK:
+@@ -103,3 +91,15 @@ int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct socka
+ 	 */
+ 	return 0;
+ }
++
++int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
++{
++	return check_add(knet_h, kh_link->outsock, kh_link->transport_type,
++			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++}
++
++int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
++{
++	return check_rm(knet_h, kh_link->outsock, kh_link->transport_type,
++			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++}
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 020ec05a..0ad50e62 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -37,8 +37,9 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	     check_type_t type, check_acceptreject_t acceptreject);
+ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport);
++int check_validate(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip);
++
+ int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link);
+ int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link);
+-int _generic_filter_packet_by_acl(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip);
+ 
+ #endif
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 06a0168c..5fa51c49 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -808,7 +808,7 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 				 */
+ 				if ((knet_h->use_access_lists) &&
+ 				    (transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL)) {
+-					if (!_generic_filter_packet_by_acl(knet_h, sockfd, msg[i].msg_hdr.msg_name)) {
++					if (!check_validate(knet_h, sockfd, msg[i].msg_hdr.msg_name)) {
+ 						char src_ipaddr[KNET_MAX_HOST_LEN];
+ 						char src_port[KNET_MAX_PORT_LEN];
+ 
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index ce3e98ef..50a237b7 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -731,7 +731,7 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Incoming: received connection from: %s port: %s",
+ 						addr_str, port_str);
+ 	if (knet_h->use_access_lists) {
+-		if (!_generic_filter_packet_by_acl(knet_h, listen_sock, &ss)) {
++		if (!check_validate(knet_h, listen_sock, &ss)) {
+ 			savederrno = EINVAL;
+ 			err = -1;
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Connection rejected from %s/%s", addr_str, port_str);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0218-access-lists-remove-2-unnecessary-wrappers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0218-access-lists-remove-2-unnecessary-wrappers.patch
new file mode 100644
index 000000000..e3437e054
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0218-access-lists-remove-2-unnecessary-wrappers.patch
@@ -0,0 +1,70 @@ 
+From 54f25e5d7dac597c2d4081e4e6269dcbd7b618bf Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 05:29:07 +0100
+Subject: [PATCH] [access lists] remove 2 unnecessary wrappers
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c     |  8 ++++++--
+ libknet/links_acl.c | 12 ------------
+ libknet/links_acl.h |  3 ---
+ 3 files changed, 6 insertions(+), 17 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 07ef26ee..1693df61 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -245,7 +245,9 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+ 		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u socket: %d",
+ 			  host_id, link_id, link->outsock);
+-		if (_link_add_default_acl(knet_h, link) < 0) {
++		if (check_add(knet_h, link->outsock, transport,
++			      &link->dst_addr, &link->dst_addr,
++			      CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+ 			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+ 			savederrno = errno;
+ 			err = -1;
+@@ -426,7 +428,9 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 */
+ 	if ((transport_get_acl_type(knet_h, link->transport_type) == USE_GENERIC_ACL) &&
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+-		if (_link_rm_default_acl(knet_h, link) < 0) {
++		if (check_rm(knet_h, link->outsock, link->transport_type,
++			     &link->dst_addr, &link->dst_addr,
++			     CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+ 			err = -1;
+ 			savederrno = EBUSY;
+ 			log_err(knet_h, KNET_SUB_LINK, "Host %u link %u: unable to remove default access list",
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 520a934c..93cc5af5 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -91,15 +91,3 @@ int check_validate(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *ch
+ 	 */
+ 	return 0;
+ }
+-
+-int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+-{
+-	return check_add(knet_h, kh_link->outsock, kh_link->transport_type,
+-			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-}
+-
+-int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link)
+-{
+-	return check_rm(knet_h, kh_link->outsock, kh_link->transport_type,
+-			&kh_link->dst_addr, &kh_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-}
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 0ad50e62..b0837536 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -39,7 +39,4 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport);
+ int check_validate(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip);
+ 
+-int _link_add_default_acl(knet_handle_t knet_h, struct knet_link *kh_link);
+-int _link_rm_default_acl(knet_handle_t knet_h, struct knet_link *kh_link);
+-
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0219-links-rename-transport_type-to-transport-to-avoid-co.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0219-links-rename-transport_type-to-transport-to-avoid-co.patch
new file mode 100644
index 000000000..f2ea452d0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0219-links-rename-transport_type-to-transport-to-avoid-co.patch
@@ -0,0 +1,196 @@ 
+From e381a1d162fb7666ff93461e74489c4e7bd16754 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 05:31:42 +0100
+Subject: [PATCH] [links] rename transport_type to transport to avoid confusion
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h         |  2 +-
+ libknet/links.c             | 10 +++++-----
+ libknet/threads_heartbeat.c |  6 +++---
+ libknet/threads_pmtud.c     |  4 ++--
+ libknet/threads_rx.c        |  4 ++--
+ libknet/threads_tx.c        |  4 ++--
+ libknet/transports.c        |  6 +++---
+ 7 files changed, 18 insertions(+), 18 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 0d6ee3f7..2135fb82 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -62,7 +62,7 @@ struct knet_link {
+ 	struct knet_link_status status;
+ 	/* internals */
+ 	uint8_t link_id;
+-	uint8_t transport_type;                 /* #defined constant from API */
++	uint8_t transport;                      /* #defined constant from API */
+ 	knet_transport_link_t transport_link;   /* link_info_t from transport */
+ 	int outsock;
+ 	unsigned int configured:1;		/* set to 1 if src/dst have been configured transport initialized on this link*/
+diff --git a/libknet/links.c b/libknet/links.c
+index 1693df61..dd64a15a 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -351,7 +351,7 @@ int knet_link_get_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ 	memmove(src_addr, &link->src_addr, sizeof(struct sockaddr_storage));
+ 
+-	*transport = link->transport_type;
++	*transport = link->transport;
+ 	*flags = link->flags;
+ 
+ 	if (link->dynamic == KNET_LINK_STATIC) {
+@@ -426,9 +426,9 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * then we can remove any leftover access lists if the link
+ 	 * is no longer in use.
+ 	 */
+-	if ((transport_get_acl_type(knet_h, link->transport_type) == USE_GENERIC_ACL) &&
++	if ((transport_get_acl_type(knet_h, link->transport) == USE_GENERIC_ACL) &&
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+-		if (check_rm(knet_h, link->outsock, link->transport_type,
++		if (check_rm(knet_h, link->outsock, link->transport,
+ 			     &link->dst_addr, &link->dst_addr,
+ 			     CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+ 			err = -1;
+@@ -444,7 +444,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * will clear link info during clear_config.
+ 	 */
+ 	sock = link->outsock;
+-	transport = link->transport_type;
++	transport = link->transport;
+ 
+ 	if ((transport_link_clear_config(knet_h, link) < 0)  &&
+ 	    (errno != EBUSY)) {
+@@ -457,7 +457,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * remove any other access lists when the socket is no
+ 	 * longer in use by the transport.
+ 	 */
+-	if ((transport_get_acl_type(knet_h, link->transport_type) == USE_GENERIC_ACL) &&
++	if ((transport_get_acl_type(knet_h, link->transport) == USE_GENERIC_ACL) &&
+ 	    (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS)) {
+ 		check_rmall(knet_h, sock, transport);
+ 	}
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 5d4189f6..413b5b73 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -98,7 +98,7 @@ retry:
+ 		dst_link->status.stats.tx_ping_bytes += outlen;
+ 
+ 		if (len != outlen) {
+-			err = transport_tx_sock_error(knet_h, dst_link->transport_type, dst_link->outsock, len, savederrno);
++			err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
+ 			switch(err) {
+ 				case -1: /* unrecoverable error */
+ 					log_debug(knet_h, KNET_SUB_HEARTBEAT,
+@@ -140,7 +140,7 @@ void _send_pings(knet_handle_t knet_h, int timed)
+ 	for (dst_host = knet_h->host_head; dst_host != NULL; dst_host = dst_host->next) {
+ 		for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) {
+ 			if ((dst_host->link[link_idx].status.enabled != 1) ||
+-			    (dst_host->link[link_idx].transport_type == KNET_TRANSPORT_LOOPBACK ) ||
++			    (dst_host->link[link_idx].transport == KNET_TRANSPORT_LOOPBACK ) ||
+ 			    ((dst_host->link[link_idx].dynamic == KNET_LINK_DYNIP) &&
+ 			     (dst_host->link[link_idx].status.dynconnected != 1)))
+ 				continue;
+@@ -166,7 +166,7 @@ static void _adjust_pong_timeouts(knet_handle_t knet_h)
+ 	for (dst_host = knet_h->host_head; dst_host != NULL; dst_host = dst_host->next) {
+ 		for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) {
+ 			if ((dst_host->link[link_idx].status.enabled != 1) ||
+-			    (dst_host->link[link_idx].transport_type == KNET_TRANSPORT_LOOPBACK ) ||
++			    (dst_host->link[link_idx].transport == KNET_TRANSPORT_LOOPBACK ) ||
+ 			    ((dst_host->link[link_idx].dynamic == KNET_LINK_DYNIP) &&
+ 			     (dst_host->link[link_idx].status.dynconnected != 1)))
+ 				continue;
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 63504d67..1a845400 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -196,7 +196,7 @@ retry:
+ 
+ 	kernel_mtu = 0;
+ 
+-	err = transport_tx_sock_error(knet_h, dst_link->transport_type, dst_link->outsock, len, savederrno);
++	err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
+ 	switch(err) {
+ 		case -1: /* unrecoverable error */
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "Unable to send pmtu packet (sendto): %d %s", savederrno, strerror(savederrno));
+@@ -523,7 +523,7 @@ void *_handle_pmtud_link_thread(void *data)
+ 
+ 				if ((dst_link->status.enabled != 1) ||
+ 				    (dst_link->status.connected != 1) ||
+-				    (dst_host->link[link_idx].transport_type == KNET_TRANSPORT_LOOPBACK) ||
++				    (dst_host->link[link_idx].transport == KNET_TRANSPORT_LOOPBACK) ||
+ 				    (!dst_link->last_ping_size) ||
+ 				    ((dst_link->dynamic == KNET_LINK_DYNIP) &&
+ 				     (dst_link->status.dynconnected != 1)))
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 5fa51c49..4670829e 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -586,7 +586,7 @@ retry_pong:
+ 		}
+ 		savederrno = errno;
+ 		if (len != outlen) {
+-			err = transport_tx_sock_error(knet_h, src_link->transport_type, src_link->outsock, len, savederrno);
++			err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
+ 			switch(err) {
+ 				case -1: /* unrecoverable error */
+ 					log_debug(knet_h, KNET_SUB_RX,
+@@ -682,7 +682,7 @@ retry_pmtud:
+ 		}
+ 		savederrno = errno;
+ 		if (len != outlen) {
+-			err = transport_tx_sock_error(knet_h, src_link->transport_type, src_link->outsock, len, savederrno);
++			err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
+ 			switch(err) {
+ 				case -1: /* unrecoverable error */
+ 					log_debug(knet_h, KNET_SUB_RX,
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index fa911dcb..b904e12c 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -48,7 +48,7 @@ static int _dispatch_to_links(knet_handle_t knet_h, struct knet_host *dst_host,
+ 
+ 		cur_link = &dst_host->link[dst_host->active_links[link_idx]];
+ 
+-		if (cur_link->transport_type == KNET_TRANSPORT_LOOPBACK) {
++		if (cur_link->transport == KNET_TRANSPORT_LOOPBACK) {
+ 			continue;
+ 		}
+ 
+@@ -72,7 +72,7 @@ retry:
+ 				      &cur[0], msgs_to_send - prev_sent, MSG_DONTWAIT | MSG_NOSIGNAL);
+ 		savederrno = errno;
+ 
+-		err = transport_tx_sock_error(knet_h, dst_host->link[dst_host->active_links[link_idx]].transport_type, dst_host->link[dst_host->active_links[link_idx]].outsock, sent_msgs, savederrno);
++		err = transport_tx_sock_error(knet_h, dst_host->link[dst_host->active_links[link_idx]].transport, dst_host->link[dst_host->active_links[link_idx]].outsock, sent_msgs, savederrno);
+ 		switch(err) {
+ 			case -1: /* unrecoverable error */
+ 				cur_link->status.stats.tx_data_errors++;
+diff --git a/libknet/transports.c b/libknet/transports.c
+index ffebe001..69ea091a 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -88,19 +88,19 @@ int transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_link, u
+ 		return -1;
+ 	}
+ 	kn_link->transport_connected = 0;
+-	kn_link->transport_type = transport;
++	kn_link->transport = transport;
+ 	kn_link->proto_overhead = transport_modules_cmd[transport].transport_mtu_overhead;
+ 	return transport_modules_cmd[transport].transport_link_set_config(knet_h, kn_link);
+ }
+ 
+ int transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+-	return transport_modules_cmd[kn_link->transport_type].transport_link_clear_config(knet_h, kn_link);
++	return transport_modules_cmd[kn_link->transport].transport_link_clear_config(knet_h, kn_link);
+ }
+ 
+ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link)
+ {
+-	return transport_modules_cmd[kn_link->transport_type].transport_link_dyn_connect(knet_h, sockfd, kn_link);
++	return transport_modules_cmd[kn_link->transport].transport_link_dyn_connect(knet_h, sockfd, kn_link);
+ }
+ 
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0220-links-rename-tranport_type-to-transport-to-avoid-con.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0220-links-rename-tranport_type-to-transport-to-avoid-con.patch
new file mode 100644
index 000000000..94f891682
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0220-links-rename-tranport_type-to-transport-to-avoid-con.patch
@@ -0,0 +1,78 @@ 
+From 1e313c21e562d6a0e0c8a45b457178964e406595 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 9 May 2019 15:44:41 +0200
+Subject: [PATCH] [links] rename tranport_type to transport to avoid confusion
+ (part 2)
+
+complements be9d053efafc822cabd696914d53b5dfe25fb4fd due to early
+cherry-pick of 7033ddab505a0cf3655115fe5037579b7c882a8c
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_heartbeat.c | 2 +-
+ libknet/threads_pmtud.c     | 2 +-
+ libknet/threads_rx.c        | 4 ++--
+ libknet/threads_tx.c        | 2 +-
+ 4 files changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 413b5b73..8def9b8b 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -85,7 +85,7 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		}
+ 
+ retry:
+-		if (transport_get_connection_oriented(knet_h, dst_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++		if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
+ 				     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
+ 		} else {
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 1a845400..00505574 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -172,7 +172,7 @@ restart:
+ 		return -1;
+ 	}
+ retry:
+-	if (transport_get_connection_oriented(knet_h, dst_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++	if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 		len = sendto(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL,
+ 			     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
+ 	} else {
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 4670829e..6417261a 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -578,7 +578,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		}
+ 
+ retry_pong:
+-		if (transport_get_connection_oriented(knet_h, src_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++		if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+ 				     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
+ 		} else {
+@@ -674,7 +674,7 @@ retry_pong:
+ 			goto out_pmtud;
+ 		}
+ retry_pmtud:
+-		if (transport_get_connection_oriented(knet_h, src_link->transport_type) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++		if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+ 				     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
+ 		} else {
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index b904e12c..e987eb13 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -68,7 +68,7 @@ retry:
+ 		cur = &msg[prev_sent];
+ 
+ 		sent_msgs = _sendmmsg(dst_host->link[dst_host->active_links[link_idx]].outsock,
+-				      transport_get_connection_oriented(knet_h, dst_host->link[dst_host->active_links[link_idx]].transport_type),
++				      transport_get_connection_oriented(knet_h, dst_host->link[dst_host->active_links[link_idx]].transport),
+ 				      &cur[0], msgs_to_send - prev_sent, MSG_DONTWAIT | MSG_NOSIGNAL);
+ 		savederrno = errno;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0221-access-lists-make-internal-API-consistent.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0221-access-lists-make-internal-API-consistent.patch
new file mode 100644
index 000000000..49f022937
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0221-access-lists-make-internal-API-consistent.patch
@@ -0,0 +1,73 @@ 
+From e4e2cfabe7796953a34f4c22cece1f52c371fea1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 06:53:48 +0100
+Subject: [PATCH] [access lists] make internal API consistent
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c      | 6 +++---
+ libknet/links_acl.h      | 2 +-
+ libknet/threads_rx.c     | 2 +-
+ libknet/transport_sctp.c | 2 +-
+ 4 files changed, 6 insertions(+), 6 deletions(-)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 93cc5af5..8592f1f1 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -74,14 +74,14 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ /*
+  * return 0 to reject and 1 to accept a packet
+  */
+-int check_validate(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip)
++int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct sockaddr_storage *checkip)
+ {
+-	switch(transport_get_proto(knet_h, knet_h->knet_transport_fd_tracker[sockfd].transport)) {
++	switch(transport_get_proto(knet_h, transport)) {
+ 		case LOOPBACK:
+ 			return 1;
+ 			break;
+ 		case IP_PROTO:
+-			return ipcheck_validate((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sockfd].match_entry, checkip);
++			return ipcheck_validate((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry, checkip);
+ 			break;
+ 		default:
+ 			break;
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index b0837536..f8714037 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -37,6 +37,6 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	     check_type_t type, check_acceptreject_t acceptreject);
+ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport);
+-int check_validate(knet_handle_t knet_h, int sockfd, struct sockaddr_storage *checkip);
++int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct sockaddr_storage *checkip);
+ 
+ #endif
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 6417261a..ae39b38e 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -808,7 +808,7 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 				 */
+ 				if ((knet_h->use_access_lists) &&
+ 				    (transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL)) {
+-					if (!check_validate(knet_h, sockfd, msg[i].msg_hdr.msg_name)) {
++					if (!check_validate(knet_h, sockfd, transport, msg[i].msg_hdr.msg_name)) {
+ 						char src_ipaddr[KNET_MAX_HOST_LEN];
+ 						char src_port[KNET_MAX_PORT_LEN];
+ 
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 50a237b7..ff7903ce 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -731,7 +731,7 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Incoming: received connection from: %s port: %s",
+ 						addr_str, port_str);
+ 	if (knet_h->use_access_lists) {
+-		if (!check_validate(knet_h, listen_sock, &ss)) {
++		if (!check_validate(knet_h, listen_sock, KNET_TRANSPORT_SCTP, &ss)) {
+ 			savederrno = EINVAL;
+ 			err = -1;
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Connection rejected from %s/%s", addr_str, port_str);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0222-access-lists-fix-build-on-BSD-and-add-some-include-f.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0222-access-lists-fix-build-on-BSD-and-add-some-include-f.patch
new file mode 100644
index 000000000..10cd8cff0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0222-access-lists-fix-build-on-BSD-and-add-some-include-f.patch
@@ -0,0 +1,65 @@ 
+From 090753fd4154ca67e8b4f127ec9d7df36b7b5df7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Feb 2019 07:08:29 +0100
+Subject: [PATCH] [access lists] fix build on BSD and add some include files
+ around
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c           | 2 ++
+ libknet/links_acl_ip.c        | 2 ++
+ libknet/tests/Makefile.am     | 1 +
+ libknet/tests/int_links_acl.c | 2 ++
+ 4 files changed, 7 insertions(+)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 8592f1f1..cfcc1fd2 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -6,6 +6,8 @@
+  * This software licensed under GPL-2.0+, LGPL-2.0+
+  */
+ 
++#include "config.h"
++
+ #include <stdint.h>
+ #include <string.h>
+ #include <stdlib.h>
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 2aef14ba..ffd18a47 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -6,6 +6,8 @@
+  * This software licensed under GPL-2.0+, LGPL-2.0+
+  */
+ 
++#include "config.h"
++
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <stdint.h>
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index d46553a5..2f222939 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -69,6 +69,7 @@ pckt_test_SOURCES	= pckt_test.c
+ 
+ int_links_acl_test_SOURCES = int_links_acl.c \
+ 			     ../common.c \
++			     ../compat.c \
+ 			     ../logging.c \
+ 			     ../netutils.c \
+ 			     ../threads_common.c \
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+index 8d9f4e06..05bd829f 100644
+--- a/libknet/tests/int_links_acl.c
++++ b/libknet/tests/int_links_acl.c
+@@ -6,6 +6,8 @@
+  * This software licensed under GPL-2.0+, LGPL-2.0+
+  */
+ 
++#include "config.h"
++
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0223-access-lists-add-errno-around-and-start-using-them.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0223-access-lists-add-errno-around-and-start-using-them.patch
new file mode 100644
index 000000000..173a16c6b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0223-access-lists-add-errno-around-and-start-using-them.patch
@@ -0,0 +1,195 @@ 
+From 4786df1f612aaf7f0c4636641d6638f6d8ac4624 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 26 Feb 2019 10:43:04 +0100
+Subject: [PATCH] [access lists] add errno around and start using them
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c          | 14 +++++++-------
+ libknet/links_acl.c      |  9 +++++++++
+ libknet/links_acl_ip.c   | 12 ++++++++++--
+ libknet/transport_sctp.c | 16 +++++++---------
+ 4 files changed, 33 insertions(+), 18 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index dd64a15a..1d21d05b 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -245,9 +245,9 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+ 		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u socket: %d",
+ 			  host_id, link_id, link->outsock);
+-		if (check_add(knet_h, link->outsock, transport,
+-			      &link->dst_addr, &link->dst_addr,
+-			      CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		if ((check_add(knet_h, link->outsock, transport,
++			       &link->dst_addr, &link->dst_addr,
++			       CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+ 			savederrno = errno;
+ 			err = -1;
+@@ -428,11 +428,11 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 */
+ 	if ((transport_get_acl_type(knet_h, link->transport) == USE_GENERIC_ACL) &&
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+-		if (check_rm(knet_h, link->outsock, link->transport,
+-			     &link->dst_addr, &link->dst_addr,
+-			     CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		if ((check_rm(knet_h, link->outsock, link->transport,
++			      &link->dst_addr, &link->dst_addr,
++			      CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != ENOENT)) {
+ 			err = -1;
+-			savederrno = EBUSY;
++			savederrno = errno;
+ 			log_err(knet_h, KNET_SUB_LINK, "Host %u link %u: unable to remove default access list",
+ 				host_id, link_id);
+ 			goto exit_unlock;
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index cfcc1fd2..7605fe97 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -8,6 +8,7 @@
+ 
+ #include "config.h"
+ 
++#include <errno.h>
+ #include <stdint.h>
+ #include <string.h>
+ #include <stdlib.h>
+@@ -19,6 +20,11 @@
+ #include "links_acl.h"
+ #include "links_acl_ip.h"
+ 
++/*
++ * all those functions will return errno from the
++ * protocol specific functions
++ */
++
+ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	      check_type_t type, check_acceptreject_t acceptreject)
+@@ -27,6 +33,7 @@ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 
+ 	switch(transport_get_proto(knet_h, transport)) {
+ 		case LOOPBACK:
++			errno = 0;
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+@@ -47,6 +54,7 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 
+ 	switch(transport_get_proto(knet_h, transport)) {
+ 		case LOOPBACK:
++			errno = 0;
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+@@ -80,6 +88,7 @@ int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct soc
+ {
+ 	switch(transport_get_proto(knet_h, transport)) {
+ 		case LOOPBACK:
++			errno = 0;
+ 			return 1;
+ 			break;
+ 		case IP_PROTO:
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index ffd18a47..58c7b285 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -8,6 +8,7 @@
+ 
+ #include "config.h"
+ 
++#include <errno.h>
+ #include <sys/socket.h>
+ #include <netinet/in.h>
+ #include <stdint.h>
+@@ -202,6 +203,7 @@ int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+ 
+ 	rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
+ 	if (!rm_match_entry) {
++		errno = ENOENT;
+ 		return -1;
+ 	}
+ 
+@@ -237,24 +239,30 @@ int ipcheck_addip(struct acl_match_entry **match_entry_head,
+ 	struct acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	if (!ip1) {
++		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+ 	if ((type != CHECK_TYPE_ADDRESS) && (!ip2)) {
++		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+ 	if (type == CHECK_TYPE_RANGE &&
+-	    (ip1->ss_family != ip2->ss_family))
++	    (ip1->ss_family != ip2->ss_family)) {
++		errno = EINVAL;
+ 		return -1;
++	}
+ 
+ 	if (ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject) != NULL) {
++		errno = EEXIST;
+ 		return -1;
+ 	}
+ 
+ 	new_match_entry = malloc(sizeof(struct acl_match_entry));
+-	if (!new_match_entry)
++	if (!new_match_entry) {
+ 		return -1;
++	}
+ 
+ 	memmove(&new_match_entry->addr1, ip1, sizeof(struct sockaddr_storage));
+ 	memmove(&new_match_entry->addr2, ip2, sizeof(struct sockaddr_storage));
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index ff7903ce..aa0de9d5 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -948,9 +948,8 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	 */
+ 	knet_list_for_each_entry(info, &handle_info->listen_links_list, list) {
+ 		if (memcmp(&info->src_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
+-			err = check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
+-					&kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
+-			if (err) {
++			if ((check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
++				       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 				return NULL;
+ 			}
+ 			return info;
+@@ -1007,8 +1006,8 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 		goto exit_error;
+ 	}
+ 
+-	if (check_add(knet_h, listen_sock, KNET_TRANSPORT_SCTP,
+-		      &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
++	if ((check_add(knet_h, listen_sock, KNET_TRANSPORT_SCTP,
++		       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to configure default access lists: %s",
+@@ -1038,8 +1037,7 @@ exit_error:
+ 		if (info->on_listener_epoll) {
+ 			epoll_ctl(handle_info->listen_epollfd, EPOLL_CTL_DEL, listen_sock, &ev);
+ 		}
+-		check_rm(knet_h, listen_sock, KNET_TRANSPORT_SCTP,
+-			 &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT);
++		check_rmall(knet_h, listen_sock, KNET_TRANSPORT_SCTP);
+ 		if (listen_sock >= 0) {
+ 			close(listen_sock);
+ 		}
+@@ -1078,8 +1076,8 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		}
+ 	}
+ 
+-	if (check_rm(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
+-		     &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) {
++	if ((check_rm(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
++		      &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != ENOENT)) {
+ 		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove default access lists for %d", info->listen_sock);
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0224-access-lists-confine-access-lists-data-structs-withi.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0224-access-lists-confine-access-lists-data-structs-withi.patch
new file mode 100644
index 000000000..9a26a632e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0224-access-lists-confine-access-lists-data-structs-withi.patch
@@ -0,0 +1,226 @@ 
+From 75417e3cadae687be1679be8590fa31378f0a464 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 26 Feb 2019 11:37:49 +0100
+Subject: [PATCH] [access lists] confine access lists data structs within the
+ protocol itself
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c    |  8 +++----
+ libknet/links_acl.h    |  8 -------
+ libknet/links_acl_ip.c | 48 ++++++++++++++++++++++++++----------------
+ libknet/links_acl_ip.h | 13 ++++++------
+ 4 files changed, 41 insertions(+), 36 deletions(-)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 7605fe97..b1d7ab42 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -37,7 +37,7 @@ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_addip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry,
++			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
+ 					    ip1, ip2, type, acceptreject);
+ 			break;
+ 		default:
+@@ -58,7 +58,7 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_rmip((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry,
++			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
+ 					   ip1, ip2, type, acceptreject);
+ 			break;
+ 		default:
+@@ -74,7 +74,7 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ 			return;
+ 			break;
+ 		case IP_PROTO:
+-			ipcheck_rmall((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry);
++			ipcheck_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
+ 			break;
+ 		default:
+ 			break;
+@@ -92,7 +92,7 @@ int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct soc
+ 			return 1;
+ 			break;
+ 		case IP_PROTO:
+-			return ipcheck_validate((struct acl_match_entry **)&knet_h->knet_transport_fd_tracker[sock].match_entry, checkip);
++			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sock].match_entry, checkip);
+ 			break;
+ 		default:
+ 			break;
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index f8714037..84ae6b9c 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -22,14 +22,6 @@ typedef enum {
+ 	CHECK_REJECT
+ } check_acceptreject_t;
+ 
+-struct acl_match_entry {
+-	check_type_t type;
+-	check_acceptreject_t acceptreject;
+-	struct sockaddr_storage addr1; /* Actual IP address, mask top or low IP */
+-	struct sockaddr_storage addr2; /* high IP address or address bitmask */
+-	struct acl_match_entry *next;
+-};
+-
+ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	      check_type_t type, check_acceptreject_t acceptreject);
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 58c7b285..e72a382f 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -21,6 +21,14 @@
+ #include "links_acl.h"
+ #include "links_acl_ip.h"
+ 
++struct ip_acl_match_entry {
++	check_type_t type;
++	check_acceptreject_t acceptreject;
++	struct sockaddr_storage addr1; /* Actual IP address, mask top or low IP */
++	struct sockaddr_storage addr2; /* high IP address or address bitmask */
++	struct ip_acl_match_entry *next;
++};
++
+ /*
+  * s6_addr32 is not defined in BSD userland, only kernel.
+  * definition is the same as linux and it works fine for
+@@ -34,7 +42,7 @@
+  * IPv4 See if the address we have matches the current match entry
+  */
+ 
+-static int ip_matches_v4(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
++static int ip_matches_v4(struct sockaddr_storage *checkip, struct ip_acl_match_entry *match_entry)
+ {
+ 	struct sockaddr_in *ip_to_check;
+ 	struct sockaddr_in *match1;
+@@ -96,7 +104,7 @@ static int ip6addr_cmp(struct in6_addr *a, struct in6_addr *b)
+  * IPv6 See if the address we have matches the current match entry
+  */
+ 
+-static int ip_matches_v6(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry)
++static int ip_matches_v6(struct sockaddr_storage *checkip, struct ip_acl_match_entry *match_entry)
+ {
+ 	struct sockaddr_in6 *ip_to_check;
+ 	struct sockaddr_in6 *match1;
+@@ -134,10 +142,11 @@ static int ip_matches_v6(struct sockaddr_storage *checkip, struct acl_match_entr
+ }
+ 
+ 
+-int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip)
++int ipcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip)
+ {
+-	struct acl_match_entry *match_entry = *match_entry_head;
+-	int (*match_fn)(struct sockaddr_storage *checkip, struct acl_match_entry *match_entry);
++	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
++	struct ip_acl_match_entry *match_entry = *match_entry_head;
++	int (*match_fn)(struct sockaddr_storage *checkip, struct ip_acl_match_entry *match_entry);
+ 
+ 	if (checkip->ss_family == AF_INET){
+ 		match_fn = ip_matches_v4;
+@@ -161,10 +170,11 @@ int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_
+  * Routines to manuipulate access lists
+  */
+ 
+-void ipcheck_rmall(struct acl_match_entry **match_entry_head)
++void ipcheck_rmall(void *fd_tracker_match_entry_head)
+ {
+-	struct acl_match_entry *next_match_entry;
+-	struct acl_match_entry *match_entry = *match_entry_head;
++	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
++	struct ip_acl_match_entry *next_match_entry;
++	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	while (match_entry) {
+ 		next_match_entry = match_entry->next;
+@@ -174,11 +184,11 @@ void ipcheck_rmall(struct acl_match_entry **match_entry_head)
+ 	*match_entry_head = NULL;
+ }
+ 
+-static struct acl_match_entry *ipcheck_findmatch(struct acl_match_entry **match_entry_head,
++static struct ip_acl_match_entry *ipcheck_findmatch(struct ip_acl_match_entry **match_entry_head,
+ 						 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 						 check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	struct acl_match_entry *match_entry = *match_entry_head;
++	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	while (match_entry) {
+ 		if ((!memcmp(&match_entry->addr1, ip1, sizeof(struct sockaddr_storage))) &&
+@@ -193,13 +203,14 @@ static struct acl_match_entry *ipcheck_findmatch(struct acl_match_entry **match_
+ 	return NULL;
+ }
+ 
+-int ipcheck_rmip(struct acl_match_entry **match_entry_head,
++int ipcheck_rmip(void *fd_tracker_match_entry_head,
+ 		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 		 check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	struct acl_match_entry *next_match_entry = NULL;
+-	struct acl_match_entry *rm_match_entry;
+-	struct acl_match_entry *match_entry = *match_entry_head;
++	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
++	struct ip_acl_match_entry *next_match_entry = NULL;
++	struct ip_acl_match_entry *rm_match_entry;
++	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
+ 	if (!rm_match_entry) {
+@@ -231,12 +242,13 @@ int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+ 	return 0;
+ }
+ 
+-int ipcheck_addip(struct acl_match_entry **match_entry_head,
++int ipcheck_addip(void *fd_tracker_match_entry_head,
+ 		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 		  check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	struct acl_match_entry *new_match_entry;
+-	struct acl_match_entry *match_entry = *match_entry_head;
++	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
++	struct ip_acl_match_entry *new_match_entry;
++	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	if (!ip1) {
+ 		errno = EINVAL;
+@@ -259,7 +271,7 @@ int ipcheck_addip(struct acl_match_entry **match_entry_head,
+ 		return -1;
+ 	}
+ 
+-	new_match_entry = malloc(sizeof(struct acl_match_entry));
++	new_match_entry = malloc(sizeof(struct ip_acl_match_entry));
+ 	if (!new_match_entry) {
+ 		return -1;
+ 	}
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index 9e21e00f..c475db9c 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -12,15 +12,16 @@
+ #include "internals.h"
+ #include "links_acl.h"
+ 
+-int ipcheck_validate(struct acl_match_entry **match_entry_head, struct sockaddr_storage *checkip);
++int ipcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+-int ipcheck_addip(struct acl_match_entry **match_entry_head,
++int ipcheck_addip(void *fd_tracker_match_entry_head,
+ 		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 		  check_type_t type, check_acceptreject_t acceptreject);
+ 
+-int ipcheck_rmip(struct acl_match_entry **match_entry_head,
+-		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+-		  check_type_t type, check_acceptreject_t acceptreject);
++int ipcheck_rmip(void *fd_tracker_match_entry_head,
++		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		 check_type_t type, check_acceptreject_t acceptreject);
++
++void ipcheck_rmall(void *fd_tracker_match_entry_head);
+ 
+-void ipcheck_rmall(struct acl_match_entry **match_entry_head);
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0225-access-lists-use-better-name-for-fd_tracker-structur.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0225-access-lists-use-better-name-for-fd_tracker-structur.patch
new file mode 100644
index 000000000..9ebe9dad2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0225-access-lists-use-better-name-for-fd_tracker-structur.patch
@@ -0,0 +1,95 @@ 
+From 29ea7b4179aef2d6ce401c1dcd498aeba556eceb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 26 Feb 2019 12:12:09 +0100
+Subject: [PATCH] [access lists] use better name for fd_tracker structure
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h                      | 10 +++++-----
+ libknet/links_acl.c                      |  8 ++++----
+ libknet/tests/api_knet_link_set_config.c |  4 ++--
+ 3 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 2135fb82..27eea2a7 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -130,11 +130,11 @@ struct knet_sock {
+ };
+ 
+ struct knet_fd_trackers {
+-	uint8_t transport; /* transport type (UDP/SCTP...) */
+-	uint8_t data_type; /* internal use for transport to define what data are associated
+-			    * to this fd */
+-	void *data;	   /* pointer to the data */
+-	void *match_entry; /* pointer to access list match_entry list head */
++	uint8_t transport;		    /* transport type (UDP/SCTP...) */
++	uint8_t data_type;		    /* internal use for transport to define what data are associated
++					     * to this fd */
++	void *data;			    /* pointer to the data */
++	void *access_list_match_entry_head; /* pointer to access list match_entry list head */
+ };
+ 
+ #define KNET_MAX_FDS KNET_MAX_HOST * KNET_MAX_LINK * 4
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index b1d7ab42..f2c772d9 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -37,7 +37,7 @@ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
++			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
+ 					    ip1, ip2, type, acceptreject);
+ 			break;
+ 		default:
+@@ -58,7 +58,7 @@ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 			err = 0;
+ 			break;
+ 		case IP_PROTO:
+-			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[sock].match_entry,
++			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
+ 					   ip1, ip2, type, acceptreject);
+ 			break;
+ 		default:
+@@ -74,7 +74,7 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ 			return;
+ 			break;
+ 		case IP_PROTO:
+-			ipcheck_rmall(&knet_h->knet_transport_fd_tracker[sock].match_entry);
++			ipcheck_rmall(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head);
+ 			break;
+ 		default:
+ 			break;
+@@ -92,7 +92,7 @@ int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct soc
+ 			return 1;
+ 			break;
+ 		case IP_PROTO:
+-			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sock].match_entry, checkip);
++			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head, checkip);
+ 			break;
+ 		default:
+ 			break;
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index 5fed9be2..b96c6287 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -145,7 +145,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].match_entry) {
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
+ 		printf("found access lists for dynamic dst_addr!\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -262,7 +262,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (!knet_h->knet_transport_fd_tracker[link->outsock].match_entry) {
++	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
+ 		printf("Unable to find default access lists for static dst_addr!\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0226-access-lists-use-arrays-to-access-per-protocol-funct.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0226-access-lists-use-arrays-to-access-per-protocol-funct.patch
new file mode 100644
index 000000000..88700bb05
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0226-access-lists-use-arrays-to-access-per-protocol-funct.patch
@@ -0,0 +1,309 @@ 
+From d6c6b9846431fb0d713cd971489107d8b581aaa3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 26 Feb 2019 13:34:11 +0100
+Subject: [PATCH] [access lists] use arrays to access per-protocol functions
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am          |  2 +
+ libknet/internals.h          |  8 ++--
+ libknet/links_acl.c          | 71 ++++++++----------------------------
+ libknet/links_acl.h          | 16 ++++++++
+ libknet/links_acl_loopback.c | 41 +++++++++++++++++++++
+ libknet/links_acl_loopback.h | 27 ++++++++++++++
+ libknet/tests/Makefile.am    |  3 +-
+ libknet/transports.c         |  6 +--
+ 8 files changed, 110 insertions(+), 64 deletions(-)
+ create mode 100644 libknet/links_acl_loopback.c
+ create mode 100644 libknet/links_acl_loopback.h
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index b60427ce..0be4fffc 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -33,6 +33,7 @@ sources			= \
+ 			  links.c \
+ 			  links_acl.c \
+ 			  links_acl_ip.c \
++			  links_acl_loopback.c \
+ 			  logging.c \
+ 			  netutils.c \
+ 			  threads_common.c \
+@@ -65,6 +66,7 @@ noinst_HEADERS		= \
+ 			  links.h \
+ 			  links_acl.h \
+ 			  links_acl_ip.h \
++			  links_acl_loopback.h \
+ 			  logging.h \
+ 			  netutils.h \
+ 			  onwire.h \
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 27eea2a7..d4826741 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -265,10 +265,8 @@ extern pthread_rwlock_t shlib_rwlock;       /* global shared lib load lock */
+  * to use for access lists and other operations
+  */
+ 
+-typedef enum {
+-	LOOPBACK,
+-	IP_PROTO
+-} transport_proto;
++#define TRANSPORT_PROTO_LOOPBACK 0
++#define TRANSPORT_PROTO_IP_PROTO 1
+ 
+ /*
+  * some transports like SCTP can filter incoming
+@@ -299,7 +297,7 @@ typedef struct knet_transport_ops {
+ 	const uint8_t transport_id;
+ 	const uint8_t built_in;
+ 
+-	transport_proto transport_protocol;
++	uint8_t transport_protocol;
+ 	transport_acl transport_acl_type;
+ 
+ /*
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index f2c772d9..a941dde0 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -19,6 +19,12 @@
+ #include "transport_common.h"
+ #include "links_acl.h"
+ #include "links_acl_ip.h"
++#include "links_acl_loopback.h"
++
++static check_ops_t proto_check_modules_cmds[] = {
++	{ TRANSPORT_PROTO_LOOPBACK, loopbackcheck_validate, loopbackcheck_add, loopbackcheck_rm, loopbackcheck_rmall },
++	{ TRANSPORT_PROTO_IP_PROTO, ipcheck_validate, ipcheck_addip, ipcheck_rmip, ipcheck_rmall }
++};
+ 
+ /*
+  * all those functions will return errno from the
+@@ -29,56 +35,24 @@ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	      check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	int err = -1;
+-
+-	switch(transport_get_proto(knet_h, transport)) {
+-		case LOOPBACK:
+-			errno = 0;
+-			err = 0;
+-			break;
+-		case IP_PROTO:
+-			err = ipcheck_addip(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
+-					    ip1, ip2, type, acceptreject);
+-			break;
+-		default:
+-			break;
+-	}
+-	return err;
++	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_add(
++			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
++			ip1, ip2, type, acceptreject);
+ }
+ 
+ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	     check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	int err = -1;
+-
+-	switch(transport_get_proto(knet_h, transport)) {
+-		case LOOPBACK:
+-			errno = 0;
+-			err = 0;
+-			break;
+-		case IP_PROTO:
+-			err = ipcheck_rmip(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
+-					   ip1, ip2, type, acceptreject);
+-			break;
+-		default:
+-			break;
+-	}
+-	return err;
++	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_rm(
++			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
++			ip1, ip2, type, acceptreject);
+ }
+ 
+ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+ {
+-	switch(transport_get_proto(knet_h, transport)) {
+-		case LOOPBACK:
+-			return;
+-			break;
+-		case IP_PROTO:
+-			ipcheck_rmall(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head);
+-			break;
+-		default:
+-			break;
+-	}
++	proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_rmall(
++		&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head);
+ }
+ 
+ /*
+@@ -86,19 +60,6 @@ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+  */
+ int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct sockaddr_storage *checkip)
+ {
+-	switch(transport_get_proto(knet_h, transport)) {
+-		case LOOPBACK:
+-			errno = 0;
+-			return 1;
+-			break;
+-		case IP_PROTO:
+-			return ipcheck_validate(&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head, checkip);
+-			break;
+-		default:
+-			break;
+-	}
+-	/*
+-	 * reject by default
+-	 */
+-	return 0;
++	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_validate(
++			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head, checkip);
+ }
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 84ae6b9c..cc4fdaf5 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -22,6 +22,22 @@ typedef enum {
+ 	CHECK_REJECT
+ } check_acceptreject_t;
+ 
++typedef struct {
++	uint8_t				transport_proto;
++
++	int (*protocheck_validate)	(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
++
++	int (*protocheck_add)		(void *fd_tracker_match_entry_head,
++					 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++					 check_type_t type, check_acceptreject_t acceptreject);
++
++	int (*protocheck_rm)		(void *fd_tracker_match_entry_head,
++					 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++					 check_type_t type, check_acceptreject_t acceptreject);
++
++	void (*protocheck_rmall)	(void *fd_tracker_match_entry_head);
++} check_ops_t;
++
+ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+ 	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
+ 	      check_type_t type, check_acceptreject_t acceptreject);
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+new file mode 100644
+index 00000000..42559f3f
+--- /dev/null
++++ b/libknet/links_acl_loopback.c
+@@ -0,0 +1,41 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Christine Caulfield <ccaulfie@redhat.com>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++
++#include "internals.h"
++#include "logging.h"
++#include "transports.h"
++#include "links_acl.h"
++#include "links_acl_loopback.h"
++
++int loopbackcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip)
++{
++	return 1;
++}
++
++void loopbackcheck_rmall(void *fd_tracker_match_entry_head)
++{
++	return;
++}
++
++int loopbackcheck_rm(void *fd_tracker_match_entry_head,
++		     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		     check_type_t type, check_acceptreject_t acceptreject)
++{
++	return 0;
++}
++
++int loopbackcheck_add(void *fd_tracker_match_entry_head,
++		      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		      check_type_t type, check_acceptreject_t acceptreject)
++{
++	return 0;
++}
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+new file mode 100644
+index 00000000..0f862228
+--- /dev/null
++++ b/libknet/links_acl_loopback.h
+@@ -0,0 +1,27 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Christine Caulfield <ccaulfie@redhat.com>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#ifndef __KNET_LINKS_ACL_LOOPBACK_H__
++#define __KNET_LINKS_ACL_LOOPBACK_H__
++
++#include "internals.h"
++#include "links_acl.h"
++
++int loopbackcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
++
++int loopbackcheck_add(void *fd_tracker_match_entry_head,
++		      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		      check_type_t type, check_acceptreject_t acceptreject);
++
++int loopbackcheck_rm(void *fd_tracker_match_entry_head,
++		     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		     check_type_t type, check_acceptreject_t acceptreject);
++
++void loopbackcheck_rmall(void *fd_tracker_match_entry_head);
++
++#endif
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 2f222939..eae5c803 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -79,7 +79,8 @@ int_links_acl_test_SOURCES = int_links_acl.c \
+ 			     ../transport_sctp.c \
+ 			     ../transport_udp.c \
+ 			     ../links_acl.c \
+-			     ../links_acl_ip.c
++			     ../links_acl_ip.c \
++			     ../links_acl_loopback.c
+ 
+ int_timediff_test_SOURCES = int_timediff.c
+ 
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 69ea091a..6ded6759 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -30,11 +30,11 @@
+ #define empty_module -1, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+-	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
++	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+-				       1, IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
++				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
+ #else
+ empty_module
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0227-access-lists-rename-ip1-2-to-ss1-2-to-keep-it-more-g.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0227-access-lists-rename-ip1-2-to-ss1-2-to-keep-it-more-g.patch
new file mode 100644
index 000000000..d8d5e9d3d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0227-access-lists-rename-ip1-2-to-ss1-2-to-keep-it-more-g.patch
@@ -0,0 +1,219 @@ 
+From 456adb3c1caff513ee5a27c8efbb73c9aa18b1c5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 28 Feb 2019 08:22:43 +0100
+Subject: [PATCH] [access lists] rename ip1/2 to ss1/2 to keep it more generic
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl.c          |  8 ++++----
+ libknet/links_acl.h          |  8 ++++----
+ libknet/links_acl_ip.c       | 24 ++++++++++++------------
+ libknet/links_acl_ip.h       |  4 ++--
+ libknet/links_acl_loopback.c |  4 ++--
+ libknet/links_acl_loopback.h |  4 ++--
+ 6 files changed, 26 insertions(+), 26 deletions(-)
+
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index a941dde0..0b1fcd04 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -32,21 +32,21 @@ static check_ops_t proto_check_modules_cmds[] = {
+  */
+ 
+ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+-	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	      check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_add(
+ 			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
+-			ip1, ip2, type, acceptreject);
++			ss1, ss2, type, acceptreject);
+ }
+ 
+ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+-	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	     struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	     check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_rm(
+ 			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
+-			ip1, ip2, type, acceptreject);
++			ss1, ss2, type, acceptreject);
+ }
+ 
+ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index cc4fdaf5..a64faa1d 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -28,21 +28,21 @@ typedef struct {
+ 	int (*protocheck_validate)	(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+ 	int (*protocheck_add)		(void *fd_tracker_match_entry_head,
+-					 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++					 struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 					 check_type_t type, check_acceptreject_t acceptreject);
+ 
+ 	int (*protocheck_rm)		(void *fd_tracker_match_entry_head,
+-					 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++					 struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 					 check_type_t type, check_acceptreject_t acceptreject);
+ 
+ 	void (*protocheck_rmall)	(void *fd_tracker_match_entry_head);
+ } check_ops_t;
+ 
+ int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
+-	      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	      check_type_t type, check_acceptreject_t acceptreject);
+ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+-	     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++	     struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	     check_type_t type, check_acceptreject_t acceptreject);
+ void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport);
+ int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct sockaddr_storage *checkip);
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index e72a382f..2682a709 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -185,14 +185,14 @@ void ipcheck_rmall(void *fd_tracker_match_entry_head)
+ }
+ 
+ static struct ip_acl_match_entry *ipcheck_findmatch(struct ip_acl_match_entry **match_entry_head,
+-						 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++						 struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 						 check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	while (match_entry) {
+-		if ((!memcmp(&match_entry->addr1, ip1, sizeof(struct sockaddr_storage))) &&
+-		    (!memcmp(&match_entry->addr2, ip2, sizeof(struct sockaddr_storage))) &&
++		if ((!memcmp(&match_entry->addr1, ss1, sizeof(struct sockaddr_storage))) &&
++		    (!memcmp(&match_entry->addr2, ss2, sizeof(struct sockaddr_storage))) &&
+ 		    (match_entry->type == type) &&
+ 		    (match_entry->acceptreject == acceptreject)) {
+ 			return match_entry;
+@@ -204,7 +204,7 @@ static struct ip_acl_match_entry *ipcheck_findmatch(struct ip_acl_match_entry **
+ }
+ 
+ int ipcheck_rmip(void *fd_tracker_match_entry_head,
+-		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		 struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		 check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
+@@ -212,7 +212,7 @@ int ipcheck_rmip(void *fd_tracker_match_entry_head,
+ 	struct ip_acl_match_entry *rm_match_entry;
+ 	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+-	rm_match_entry = ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject);
++	rm_match_entry = ipcheck_findmatch(match_entry_head, ss1, ss2, type, acceptreject);
+ 	if (!rm_match_entry) {
+ 		errno = ENOENT;
+ 		return -1;
+@@ -243,30 +243,30 @@ int ipcheck_rmip(void *fd_tracker_match_entry_head,
+ }
+ 
+ int ipcheck_addip(void *fd_tracker_match_entry_head,
+-		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		  check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
+ 	struct ip_acl_match_entry *new_match_entry;
+ 	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+-	if (!ip1) {
++	if (!ss1) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+-	if ((type != CHECK_TYPE_ADDRESS) && (!ip2)) {
++	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+ 	if (type == CHECK_TYPE_RANGE &&
+-	    (ip1->ss_family != ip2->ss_family)) {
++	    (ss1->ss_family != ss2->ss_family)) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+ 
+-	if (ipcheck_findmatch(match_entry_head, ip1, ip2, type, acceptreject) != NULL) {
++	if (ipcheck_findmatch(match_entry_head, ss1, ss2, type, acceptreject) != NULL) {
+ 		errno = EEXIST;
+ 		return -1;
+ 	}
+@@ -276,8 +276,8 @@ int ipcheck_addip(void *fd_tracker_match_entry_head,
+ 		return -1;
+ 	}
+ 
+-	memmove(&new_match_entry->addr1, ip1, sizeof(struct sockaddr_storage));
+-	memmove(&new_match_entry->addr2, ip2, sizeof(struct sockaddr_storage));
++	memmove(&new_match_entry->addr1, ss1, sizeof(struct sockaddr_storage));
++	memmove(&new_match_entry->addr2, ss2, sizeof(struct sockaddr_storage));
+ 	new_match_entry->type = type;
+ 	new_match_entry->acceptreject = acceptreject;
+ 	new_match_entry->next = NULL;
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index c475db9c..e069b99d 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -15,11 +15,11 @@
+ int ipcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+ int ipcheck_addip(void *fd_tracker_match_entry_head,
+-		  struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		  struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		  check_type_t type, check_acceptreject_t acceptreject);
+ 
+ int ipcheck_rmip(void *fd_tracker_match_entry_head,
+-		 struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		 struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		 check_type_t type, check_acceptreject_t acceptreject);
+ 
+ void ipcheck_rmall(void *fd_tracker_match_entry_head);
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index 42559f3f..bb691307 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -27,14 +27,14 @@ void loopbackcheck_rmall(void *fd_tracker_match_entry_head)
+ }
+ 
+ int loopbackcheck_rm(void *fd_tracker_match_entry_head,
+-		     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		     struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		     check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	return 0;
+ }
+ 
+ int loopbackcheck_add(void *fd_tracker_match_entry_head,
+-		      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		      check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	return 0;
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index 0f862228..73a97049 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -15,11 +15,11 @@
+ int loopbackcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+ int loopbackcheck_add(void *fd_tracker_match_entry_head,
+-		      struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		      check_type_t type, check_acceptreject_t acceptreject);
+ 
+ int loopbackcheck_rm(void *fd_tracker_match_entry_head,
+-		     struct sockaddr_storage *ip1, struct sockaddr_storage *ip2,
++		     struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		     check_type_t type, check_acceptreject_t acceptreject);
+ 
+ void loopbackcheck_rmall(void *fd_tracker_match_entry_head);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0228-transports-access-list-add-internal-API-to-gather-wh.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0228-transports-access-list-add-internal-API-to-gather-wh.patch
new file mode 100644
index 000000000..32f7091c2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0228-transports-access-list-add-internal-API-to-gather-wh.patch
@@ -0,0 +1,161 @@ 
+From f6fa4f64f4408adbe638e021f101f7dffa93789c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 28 Feb 2019 14:55:27 +0100
+Subject: [PATCH] [transports / access list] add internal API to gather which
+ fd to use for access lists given a certain link struct
+
+this is required for the external API that has to be transport indepedent
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h          |  6 ++++++
+ libknet/transport_loopback.c |  5 +++++
+ libknet/transport_loopback.h |  1 +
+ libknet/transport_sctp.c     |  7 +++++++
+ libknet/transport_sctp.h     |  1 +
+ libknet/transport_udp.c      |  5 +++++
+ libknet/transport_udp.h      |  1 +
+ libknet/transports.c         | 13 +++++++++----
+ libknet/transports.h         |  1 +
+ 9 files changed, 36 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index d4826741..8976a8cc 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -338,6 +338,12 @@ typedef struct knet_transport_ops {
+  */
+ 	int (*transport_link_dyn_connect)(knet_handle_t knet_h, int sockfd, struct knet_link *link);
+ 
++
++/*
++ * return the fd to use for access lists
++ */
++	int (*transport_link_get_acl_fd)(knet_handle_t knet_h, struct knet_link *link);
++
+ /*
+  * per transport error handling of recvmmsg
+  * (see _handle_recv_from_links comments for details)
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index bf48bb93..54129d77 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -73,3 +73,8 @@ int loopback_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct
+ {
+ 	return 0;
+ }
++
++int loopback_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	return 0;
++}
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index 3d072e8b..6ce3ed3f 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -23,5 +23,6 @@ int loopback_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_
+ int loopback_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno);
+ int loopback_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int loopback_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
++int loopback_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index aa0de9d5..819bc9aa 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1537,4 +1537,11 @@ int sctp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct kne
+ 	kn_link->transport_connected = 1;
+ 	return 0;
+ }
++
++int sctp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	sctp_connect_link_info_t *this_link_info = kn_link->transport_link;
++	sctp_listen_link_info_t *info = this_link_info->listener;
++	return info->listen_sock;
++}
+ #endif
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index f27bcf1e..83a638bc 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -31,6 +31,7 @@ int sctp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno);
+ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int sctp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
++int sctp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+ 
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index e4f6fdb9..e243a913 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -438,3 +438,8 @@ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet
+ 	kn_link->status.dynconnected = 1;
+ 	return 0;
+ }
++
++int udp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	return kn_link->outsock;
++}
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index bbb6ec95..6de18e3f 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -23,5 +23,6 @@ int udp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno);
+ int udp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
++int udp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 6ded6759..5181db90 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -27,14 +27,14 @@
+ #include "transport_sctp.h"
+ #include "threads_common.h"
+ 
+-#define empty_module -1, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
++#define empty_module -1, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+-	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
++	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED,KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+-				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
++				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
+ #else
+ empty_module
+ #endif
+@@ -103,6 +103,11 @@ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_lin
+ 	return transport_modules_cmd[kn_link->transport].transport_link_dyn_connect(knet_h, sockfd, kn_link);
+ }
+ 
++int transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	return transport_modules_cmd[kn_link->transport].transport_link_get_acl_fd(knet_h, kn_link);
++}
++
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno)
+ {
+ 	return transport_modules_cmd[transport].transport_rx_sock_error(knet_h, sockfd, recv_err, recv_errno);
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 6338140e..38f69bac 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -15,6 +15,7 @@ void stop_all_transports(knet_handle_t knet_h);
+ int transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_link, uint8_t transport);
+ int transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_link);
+ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
++int transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_tx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, struct knet_mmsghdr *msg);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0229-access-lists-add-documentation-for-enable_access_lis.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0229-access-lists-add-documentation-for-enable_access_lis.patch
new file mode 100644
index 000000000..297affe6c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0229-access-lists-add-documentation-for-enable_access_lis.patch
@@ -0,0 +1,58 @@ 
+From 64bebc962578cc70ac25f73919ab46242c4db579 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 2 Mar 2019 07:49:19 +0100
+Subject: [PATCH] [access lists] add documentation for enable_access_list
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 28 ++++++++++++++++++++++------
+ 1 file changed, 22 insertions(+), 6 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 4283afe5..03bbd97d 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -505,21 +505,37 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled);
+ /**
+  * knet_handle_enable_access_lists
+  *
+- * @brief Start packet forwarding
++ * @brief Enable or disable usage of access lists (default: off)
+  *
+  * knet_h   - pointer to knet_handle_t
+  *
+- * enable   - set to 1 to use ip access lists, 0 to disable ip access_lists.
++ * enable   - set to 1 to use access lists, 0 to disable access_lists.
+  *
+  * @return
+  * knet_handle_enable_access_lists returns
+  * 0 on success
+  * -1 on error and errno is set.
+  *
+- * By default access lists usage is off, but default internal access lists
+- * will be populated regardless, but not enforced. TODO add long explanation
+- * on internal access lists for point to point connections vs global
+- * listeners etc.
++ * access lists are bound to links. There are 2 types of links:
++ * 1) point to point, where both source and destinations are well known
++ *    at configuration time.
++ * 2) open links, where only the source is known at configuration time.
++ *
++ * knet will automatically generate access lists for point to point links.
++ *
++ * For open links, knet provides 3 API calls to manipulate access lists:
++ * knet_link_add_acl, knet_link_rm_acl and knet_link_clear_acl.
++ * Those API calls will work only and exclusively on open links as they
++ * provide no use for point to point links.
++ *
++ * knet will not enforce any access list unless specifically enabled by
++ * knet_handle_enable_access_lists.
++ *
++ * From a security / programming perspective we recommend to:
++ * - create the knet handle
++ * - enable access lists
++ * - configure hosts and links
++ * - configure access lists for open links
+  */
+ 
+ int knet_handle_enable_access_lists(knet_handle_t knet_h, unsigned int enabled);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0230-access-lists-add-external-API-calls-to-manage-access.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0230-access-lists-add-external-API-calls-to-manage-access.patch
new file mode 100644
index 000000000..ff031a13d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0230-access-lists-add-external-API-calls-to-manage-access.patch
@@ -0,0 +1,746 @@ 
+From 71fc50b8789ec69e45e9e6e09234885ceb313d55 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 4 Mar 2019 13:07:04 +0100
+Subject: [PATCH] [access lists] add external API calls to manage access lists
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h             | 157 ++++++++++++++++-
+ libknet/links.c               | 306 +++++++++++++++++++++++++++++++++-
+ libknet/links_acl.c           |   4 +-
+ libknet/links_acl.h           |  15 +-
+ libknet/links_acl_ip.c        |  49 +++---
+ libknet/links_acl_ip.h        |   2 +-
+ libknet/links_acl_loopback.c  |   2 +-
+ libknet/links_acl_loopback.h  |   2 +-
+ libknet/tests/int_links_acl.c |   4 +-
+ libknet/transport_sctp.c      |   4 +-
+ man/Makefile.am               |   7 +-
+ 11 files changed, 504 insertions(+), 48 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 03bbd97d..d616e116 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -524,12 +524,12 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled);
+  * knet will automatically generate access lists for point to point links.
+  *
+  * For open links, knet provides 3 API calls to manipulate access lists:
+- * knet_link_add_acl, knet_link_rm_acl and knet_link_clear_acl.
++ * knet_link_add_acl(3), knet_link_rm_acl(3) and knet_link_clear_acl(3).
+  * Those API calls will work only and exclusively on open links as they
+  * provide no use for point to point links.
+  *
+  * knet will not enforce any access list unless specifically enabled by
+- * knet_handle_enable_access_lists.
++ * knet_handle_enable_access_lists(3).
+  *
+  * From a security / programming perspective we recommend to:
+  * - create the knet handle
+@@ -1477,6 +1477,159 @@ int knet_link_get_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id);
+ 
++/*
++ * access lists management for open links
++ * see also knet_handle_enable_access_lists(3)
++ */
++
++/*
++ * CHECK_TYPE_ADDRESS is the equivalent of a single entry / IP address.
++ *                    for example: 10.1.9.3/32
++ *                    and the entry is stored in ss1. ss2 can be NULL.
++ *
++ * CHECK_TYPE_MASK    is used to configure network/netmask.
++ *                    for example: 192.168.0.0/24
++ *                    the network is stored in ss1 and the netmask in ss2.
++ *
++ * CHECK_TYPE_RANGE   defines a value / range of ip addresses.
++ *                    for example: 172.16.0.1-172.16.0.10
++ *                    the start is stored in ss1 and the end in ss2.
++ *
++ * Please be aware that the above examples refers only to IP based protocols.
++ * Other protocols might use ss1 and ss2 in slightly different ways.
++ * At the moment knet only supports IP based protocol and that might change
++ * in the future.
++ */
++
++typedef enum {
++	CHECK_TYPE_ADDRESS,
++	CHECK_TYPE_MASK,
++	CHECK_TYPE_RANGE
++} check_type_t;
++
++/*
++ * accept or reject incoming packets defined in the access list entry
++ */
++
++typedef enum {
++	CHECK_ACCEPT,
++	CHECK_REJECT
++} check_acceptreject_t;
++
++/**
++ * knet_link_add_acl
++ *
++ * @brief Add access list entry to an open link
++ *
++ * knet_h    - pointer to knet_handle_t
++ *
++ * host_id   - see knet_host_add(3)
++ *
++ * link_id   - see knet_link_set_config(3)
++ *
++ * ss1 / ss2 / type / acceptreject - see typedef definitions for details
++ *
++ * IMPORTANT: the order in which access lists are added is critical and it
++ *            is left to the user to add them in the right order. knet
++ *            will do no attempt to logically sort them.
++ *
++ *            For example:
++ *            1 - accept from 10.0.0.0/8
++ *            2 - reject from 10.0.0.1/32
++ *
++ *            is not the same as:
++ *
++ *            1 - reject from 10.0.0.1/32
++ *            2 - accept from 10.0.0.0/8
++ *
++ *            In the first example, rule number 2 will never match because
++ *            packets from 10.0.0.1 will be accepted by rule number 1.
++ *
++ * @return
++ * knet_link_add_acl
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
++int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++		      struct sockaddr_storage *ss1,
++		      struct sockaddr_storage *ss2,
++		      check_type_t type, check_acceptreject_t acceptreject);
++
++/**
++ * knet_link_insert_acl
++ *
++ * @brief Insert access list entry to an open link at given index
++ *
++ * knet_h    - pointer to knet_handle_t
++ *
++ * host_id   - see knet_host_add(3)
++ *
++ * link_id   - see knet_link_set_config(3)
++ *
++ * index     - insert at position "index" where 0 is the first entry and -1
++ *             append to the current list.
++ *
++ * ss1 / ss2 / type / acceptreject - see typedef definitions for details
++ *
++ * @return
++ * knet_link_insert_acl
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
++int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++			 int index,
++			 struct sockaddr_storage *ss1,
++			 struct sockaddr_storage *ss2,
++			 check_type_t type, check_acceptreject_t acceptreject);
++
++/**
++ * knet_link_rm_acl
++ *
++ * @brief Remove access list entry from an open link
++ *
++ * knet_h    - pointer to knet_handle_t
++ *
++ * host_id   - see knet_host_add(3)
++ *
++ * link_id   - see knet_link_set_config(3)
++ *
++ * ss1 / ss2 / type / acceptreject - see typedef definitions for details
++ *
++ * IMPORTANT: the data passed to this API call must match exactly the ones used
++ *            in knet_link_add_acl(3).
++ *
++ * @return
++ * knet_link_rm_acl
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
++int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++		     struct sockaddr_storage *ss1,
++		     struct sockaddr_storage *ss2,
++		     check_type_t type, check_acceptreject_t acceptreject);
++
++/**
++ * knet_link_clear_acl
++ *
++ * @brief Remove all access list entries from an open link
++ *
++ * knet_h    - pointer to knet_handle_t
++ *
++ * host_id   - see knet_host_add(3)
++ *
++ * link_id   - see knet_link_set_config(3)
++ *
++ * @return
++ * knet_link_clear_acl
++ * 0 on success.
++ * -1 on error and errno is set.
++ */
++
++int knet_link_clear_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id);
++
+ /**
+  * knet_link_set_enable
+  *
+diff --git a/libknet/links.c b/libknet/links.c
+index 1d21d05b..0f020065 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -245,7 +245,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+ 		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u socket: %d",
+ 			  host_id, link_id, link->outsock);
+-		if ((check_add(knet_h, link->outsock, transport,
++		if ((check_add(knet_h, link->outsock, transport, -1,
+ 			       &link->dst_addr, &link->dst_addr,
+ 			       CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+@@ -1148,3 +1148,307 @@ exit_unlock:
+ 	errno = err ? savederrno : 0;
+ 	return err;
+ }
++
++int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++		      struct sockaddr_storage *ss1,
++		      struct sockaddr_storage *ss2,
++		      check_type_t type, check_acceptreject_t acceptreject)
++{
++	int savederrno = 0, err = 0;
++	struct knet_host *host;
++	struct knet_link *link;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!ss1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((type == CHECK_TYPE_RANGE) &&
++	    (ss1->ss_family != ss2->ss_family)) {
++			errno = EINVAL;
++			return -1;
++	}
++
++	if (link_id >= KNET_MAX_LINK) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	host = knet_h->host_index[host_id];
++	if (!host) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "Unable to find host %u: %s",
++			host_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	link = &host->link[link_id];
++
++	if (!link->configured) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is not configured: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	if (link->dynamic != KNET_LINK_DYNIP) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is a point to point connection: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	err = check_add(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport, -1,
++			ss1, ss2, type, acceptreject);
++	savederrno = errno;
++
++exit_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = savederrno;
++	return err;
++}
++
++int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++			 int index,
++			 struct sockaddr_storage *ss1,
++			 struct sockaddr_storage *ss2,
++			 check_type_t type, check_acceptreject_t acceptreject)
++{
++	int savederrno = 0, err = 0;
++	struct knet_host *host;
++	struct knet_link *link;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!ss1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((type == CHECK_TYPE_RANGE) &&
++	    (ss1->ss_family != ss2->ss_family)) {
++			errno = EINVAL;
++			return -1;
++	}
++
++	if (link_id >= KNET_MAX_LINK) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	host = knet_h->host_index[host_id];
++	if (!host) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "Unable to find host %u: %s",
++			host_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	link = &host->link[link_id];
++
++	if (!link->configured) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is not configured: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	if (link->dynamic != KNET_LINK_DYNIP) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is a point to point connection: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	err = check_add(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport, index,
++			ss1, ss2, type, acceptreject);
++	savederrno = errno;
++
++exit_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = savederrno;
++	return err;
++}
++
++int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++		     struct sockaddr_storage *ss1,
++		     struct sockaddr_storage *ss2,
++		     check_type_t type, check_acceptreject_t acceptreject)
++{
++	int savederrno = 0, err = 0;
++	struct knet_host *host;
++	struct knet_link *link;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!ss1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((type == CHECK_TYPE_RANGE) &&
++	    (ss1->ss_family != ss2->ss_family)) {
++			errno = EINVAL;
++			return -1;
++	}
++
++	if (link_id >= KNET_MAX_LINK) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	host = knet_h->host_index[host_id];
++	if (!host) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "Unable to find host %u: %s",
++			host_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	link = &host->link[link_id];
++
++	if (!link->configured) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is not configured: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	if (link->dynamic != KNET_LINK_DYNIP) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is a point to point connection: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	err = check_rm(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport,
++		       ss1, ss2, type, acceptreject);
++	savederrno = errno;
++
++exit_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = savederrno;
++	return err;
++}
++
++int knet_link_clear_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id)
++{
++	int savederrno = 0, err = 0;
++	struct knet_host *host;
++	struct knet_link *link;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (link_id >= KNET_MAX_LINK) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	host = knet_h->host_index[host_id];
++	if (!host) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "Unable to find host %u: %s",
++			host_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	link = &host->link[link_id];
++
++	if (!link->configured) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is not configured: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	if (link->dynamic != KNET_LINK_DYNIP) {
++		err = -1;
++		savederrno = EINVAL;
++		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is a point to point connection: %s",
++			host_id, link_id, strerror(savederrno));
++		goto exit_unlock;
++	}
++
++	check_rmall(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport);
++
++exit_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = savederrno;
++	return err;
++}
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 0b1fcd04..776408a7 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -31,12 +31,12 @@ static check_ops_t proto_check_modules_cmds[] = {
+  * protocol specific functions
+  */
+ 
+-int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
++int check_add(knet_handle_t knet_h, int sock, uint8_t transport, int index,
+ 	      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	      check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_add(
+-			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
++			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head, index,
+ 			ss1, ss2, type, acceptreject);
+ }
+ 
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index a64faa1d..60f78125 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -11,23 +11,12 @@
+ 
+ #include "internals.h"
+ 
+-typedef enum {
+-	CHECK_TYPE_ADDRESS,
+-	CHECK_TYPE_MASK,
+-	CHECK_TYPE_RANGE
+-} check_type_t;
+-
+-typedef enum {
+-	CHECK_ACCEPT,
+-	CHECK_REJECT
+-} check_acceptreject_t;
+-
+ typedef struct {
+ 	uint8_t				transport_proto;
+ 
+ 	int (*protocheck_validate)	(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+-	int (*protocheck_add)		(void *fd_tracker_match_entry_head,
++	int (*protocheck_add)		(void *fd_tracker_match_entry_head, int index,
+ 					 struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 					 check_type_t type, check_acceptreject_t acceptreject);
+ 
+@@ -38,7 +27,7 @@ typedef struct {
+ 	void (*protocheck_rmall)	(void *fd_tracker_match_entry_head);
+ } check_ops_t;
+ 
+-int check_add(knet_handle_t knet_h, int sock, uint8_t transport,
++int check_add(knet_handle_t knet_h, int sock, uint8_t transport, int index,
+ 	      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	      check_type_t type, check_acceptreject_t acceptreject);
+ int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 2682a709..642027be 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -242,29 +242,14 @@ int ipcheck_rmip(void *fd_tracker_match_entry_head,
+ 	return 0;
+ }
+ 
+-int ipcheck_addip(void *fd_tracker_match_entry_head,
++int ipcheck_addip(void *fd_tracker_match_entry_head, int index,
+ 		  struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		  check_type_t type, check_acceptreject_t acceptreject)
+ {
+ 	struct ip_acl_match_entry **match_entry_head = (struct ip_acl_match_entry **)fd_tracker_match_entry_head;
+ 	struct ip_acl_match_entry *new_match_entry;
+ 	struct ip_acl_match_entry *match_entry = *match_entry_head;
+-
+-	if (!ss1) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (type == CHECK_TYPE_RANGE &&
+-	    (ss1->ss_family != ss2->ss_family)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
++	int i = 0;
+ 
+ 	if (ipcheck_findmatch(match_entry_head, ss1, ss2, type, acceptreject) != NULL) {
+ 		errno = EEXIST;
+@@ -283,12 +268,32 @@ int ipcheck_addip(void *fd_tracker_match_entry_head,
+ 	new_match_entry->next = NULL;
+ 
+ 	if (match_entry) {
+-		/* Find the end of the list */
+-		/* is this OK, or should we use a doubly-linked list or bulk-load API call? */
+-		while (match_entry->next) {
+-			match_entry = match_entry->next;
++		/*
++		 * special case for index 0, since we need to update
++		 * the head of the list
++		 */
++		if (index == 0) {
++			*match_entry_head = new_match_entry;
++			new_match_entry->next = match_entry;
++		} else {
++			/*
++			 * find the end of the list or stop at "index"
++			 */
++			while ((match_entry->next) || (i < index)) {
++				match_entry = match_entry->next;
++				i++;
++			}
++			/*
++			 * insert if there are more entries in the list
++			 */
++			if (match_entry->next) {
++				new_match_entry->next = match_entry->next;
++			}
++			/*
++			 * add if we are at the end
++			 */
++			match_entry->next = new_match_entry;
+ 		}
+-		match_entry->next = new_match_entry;
+ 	} else {
+ 		/*
+ 		 * first entry in the list
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index e069b99d..fac58e21 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -14,7 +14,7 @@
+ 
+ int ipcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+-int ipcheck_addip(void *fd_tracker_match_entry_head,
++int ipcheck_addip(void *fd_tracker_match_entry_head, int index,
+ 		  struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		  check_type_t type, check_acceptreject_t acceptreject);
+ 
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index bb691307..97f8198f 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -33,7 +33,7 @@ int loopbackcheck_rm(void *fd_tracker_match_entry_head,
+ 	return 0;
+ }
+ 
+-int loopbackcheck_add(void *fd_tracker_match_entry_head,
++int loopbackcheck_add(void *fd_tracker_match_entry_head, int index,
+ 		      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		      check_type_t type, check_acceptreject_t acceptreject)
+ {
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index 73a97049..e75c4a4d 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -14,7 +14,7 @@
+ 
+ int loopbackcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage *checkip);
+ 
+-int loopbackcheck_add(void *fd_tracker_match_entry_head,
++int loopbackcheck_add(void *fd_tracker_match_entry_head, int index,
+ 		      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 		      check_type_t type, check_acceptreject_t acceptreject);
+ 
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+index 05bd829f..15e8e076 100644
+--- a/libknet/tests/int_links_acl.c
++++ b/libknet/tests/int_links_acl.c
+@@ -165,9 +165,9 @@ static int load_file(void)
+ 		}
+ 		else {
+ 			if (addr1.ss_family == AF_INET) {
+-				ipcheck_addip(&match_entry_v4, &addr1, &addr2, type, acceptreject);
++				ipcheck_addip(&match_entry_v4, -1, &addr1, &addr2, type, acceptreject);
+ 			} else {
+-				ipcheck_addip(&match_entry_v6, &addr1, &addr2, type, acceptreject);
++				ipcheck_addip(&match_entry_v6, -1, &addr1, &addr2, type, acceptreject);
+ 			}
+ 		}
+ 	next_record: {} /* empty statement to mollify the compiler */
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 819bc9aa..bdfc98d1 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -948,7 +948,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	 */
+ 	knet_list_for_each_entry(info, &handle_info->listen_links_list, list) {
+ 		if (memcmp(&info->src_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
+-			if ((check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
++			if ((check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP, -1,
+ 				       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 				return NULL;
+ 			}
+@@ -1006,7 +1006,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 		goto exit_error;
+ 	}
+ 
+-	if ((check_add(knet_h, listen_sock, KNET_TRANSPORT_SCTP,
++	if ((check_add(knet_h, listen_sock, KNET_TRANSPORT_SCTP, -1,
+ 		       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 		savederrno = errno;
+ 		err = -1;
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 6c15f0d0..0ad12f62 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -95,7 +95,12 @@ knet_man3_MANS = \
+ 		knet_recv.3 \
+ 		knet_send.3 \
+ 		knet_send_sync.3 \
+-		knet_strtoaddr.3
++		knet_strtoaddr.3 \
++		knet_handle_enable_access_lists.3 \
++		knet_link_add_acl.3 \
++		knet_link_insert_acl.3 \
++		knet_link_rm_acl.3 \
++		knet_link_clear_acl.3
+ 
+ if BUILD_LIBNOZZLE
+ nozzle_man3_MANS = \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0231-access-lists-test-implicit-access-lists-management-f.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0231-access-lists-test-implicit-access-lists-management-f.patch
new file mode 100644
index 000000000..1ab3f6444
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0231-access-lists-test-implicit-access-lists-management-f.patch
@@ -0,0 +1,50 @@ 
+From 4811e7c4ac2ccdabc25734aa14ec4609b2963602 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 5 Mar 2019 05:16:29 +0100
+Subject: [PATCH] [access lists] test implicit access lists management for UDP,
+ SCTP and LOOPBACK
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_send.c          | 8 ++++++++
+ libknet/tests/api_knet_send_loopback.c | 8 ++++++++
+ 2 files changed, 16 insertions(+)
+
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index f2412015..6c255b92 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -145,6 +145,14 @@ static void test(uint8_t transport)
+ 
+ 	printf("Test knet_send with valid data\n");
+ 
++	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
++		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+ 		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 16a46244..0cfd29f7 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -168,6 +168,14 @@ static void test(void)
+ 	flush_logs(logfds[0], stdout);
+ 	printf("Test knet_send with valid data\n");
+ 
++	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
++		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+ 		printf("Failed to clear existing UDP link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0232-access-lists-improve-checks-on-various-data-types.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0232-access-lists-improve-checks-on-various-data-types.patch
new file mode 100644
index 000000000..c605a6280
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0232-access-lists-improve-checks-on-various-data-types.patch
@@ -0,0 +1,74 @@ 
+From 1fe5d71b0ad1e7647afd83c08035258f9532bb4f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 6 Mar 2019 09:43:10 +0100
+Subject: [PATCH] [access lists] improve checks on various data types
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 39 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 39 insertions(+)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 0f020065..038a8a42 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1168,6 +1168,19 @@ int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link
+ 		return -1;
+ 	}
+ 
++	if ((type != CHECK_TYPE_ADDRESS) &&
++	    (type != CHECK_TYPE_MASK) &&
++	    (type != CHECK_TYPE_RANGE)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((acceptreject != CHECK_ACCEPT) &&
++	    (acceptreject != CHECK_REJECT)) {
++		errno = EINVAL;
++		return -1;
++	}
++
+ 	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
+ 		errno = EINVAL;
+ 		return -1;
+@@ -1250,6 +1263,19 @@ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		return -1;
+ 	}
+ 
++	if ((type != CHECK_TYPE_ADDRESS) &&
++	    (type != CHECK_TYPE_MASK) &&
++	    (type != CHECK_TYPE_RANGE)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((acceptreject != CHECK_ACCEPT) &&
++	    (acceptreject != CHECK_REJECT)) {
++		errno = EINVAL;
++		return -1;
++	}
++
+ 	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
+ 		errno = EINVAL;
+ 		return -1;
+@@ -1331,6 +1357,19 @@ int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_
+ 		return -1;
+ 	}
+ 
++	if ((type != CHECK_TYPE_ADDRESS) &&
++	    (type != CHECK_TYPE_MASK) &&
++	    (type != CHECK_TYPE_RANGE)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((acceptreject != CHECK_ACCEPT) &&
++	    (acceptreject != CHECK_REJECT)) {
++		errno = EINVAL;
++		return -1;
++	}
++
+ 	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
+ 		errno = EINVAL;
+ 		return -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0233-access-lists-add-public-API-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0233-access-lists-add-public-API-tests.patch
new file mode 100644
index 000000000..e65f3427b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0233-access-lists-add-public-API-tests.patch
@@ -0,0 +1,1019 @@ 
+From 4ebc9fb21323e103fad0421b3ad558fd97a45765 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 6 Mar 2019 13:08:34 +0100
+Subject: [PATCH] [access lists] add public API tests
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api-check.mk               |  18 +-
+ libknet/tests/api_knet_link_add_acl.c    | 246 ++++++++++++++++++++++
+ libknet/tests/api_knet_link_clear_acl.c  | 196 +++++++++++++++++
+ libknet/tests/api_knet_link_insert_acl.c | 246 ++++++++++++++++++++++
+ libknet/tests/api_knet_link_rm_acl.c     | 256 +++++++++++++++++++++++
+ 5 files changed, 961 insertions(+), 1 deletion(-)
+ create mode 100644 libknet/tests/api_knet_link_add_acl.c
+ create mode 100644 libknet/tests/api_knet_link_clear_acl.c
+ create mode 100644 libknet/tests/api_knet_link_insert_acl.c
+ create mode 100644 libknet/tests/api_knet_link_rm_acl.c
+
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 247ed582..427c3880 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -68,7 +68,11 @@ api_checks		= \
+ 			  api_knet_link_set_enable_test \
+ 			  api_knet_link_get_enable_test \
+ 			  api_knet_link_get_link_list_test \
+-			  api_knet_link_get_status_test
++			  api_knet_link_get_status_test \
++			  api_knet_link_add_acl_test \
++			  api_knet_link_insert_acl_test \
++			  api_knet_link_rm_acl_test \
++			  api_knet_link_clear_acl_test
+ 
+ api_knet_handle_new_test_SOURCES = api_knet_handle_new.c \
+ 				   test-common.c
+@@ -256,3 +260,15 @@ api_knet_link_get_link_list_test_SOURCES = api_knet_link_get_link_list.c \
+ 
+ api_knet_link_get_status_test_SOURCES = api_knet_link_get_status.c \
+ 					test-common.c
++
++api_knet_link_add_acl_test_SOURCES = api_knet_link_add_acl.c \
++				     test-common.c
++
++api_knet_link_insert_acl_test_SOURCES = api_knet_link_insert_acl.c \
++					test-common.c
++
++api_knet_link_rm_acl_test_SOURCES = api_knet_link_rm_acl.c \
++				    test-common.c
++
++api_knet_link_clear_acl_test_SOURCES = api_knet_link_clear_acl.c \
++				       test-common.c
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+new file mode 100644
+index 00000000..b0181652
+--- /dev/null
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -0,0 +1,246 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "netutils.h"
++#include "test-common.h"
++
++static void test(void)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	struct knet_host *host;
++	struct knet_link *link;
++	struct sockaddr_storage lo, lo6;
++
++	if (make_local_sockaddr(&lo, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	if (make_local_sockaddr6(&lo6, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	printf("Test knet_link_add_acl incorrect knet_h\n");
++
++	if ((!knet_link_add_acl(NULL, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	printf("Test knet_link_add_acl with unconfigured host\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with unconfigured link\n");
++
++	if (knet_host_add(knet_h, 1) < 0) {
++		printf("knet_host_add failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with invalid link\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, KNET_MAX_LINK, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with invalid ss1\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted invalid ss1 or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with invalid ss2\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted invalid ss2 or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with non matching families\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted non matching families or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with wrong check_type\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with wrong acceptreject\n");
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_add_acl with point to point link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_add_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_link_clear_config(knet_h, 1, 0);
++
++	printf("Test knet_link_add_acl with dynamic link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	host = knet_h->host_index[1];
++	link = &host->link[0];
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list not empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		printf("knet_link_add_acl did not accept dynamic link error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++	knet_link_clear_config(knet_h, 1, 0);
++	knet_host_remove(knet_h, 1);
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+new file mode 100644
+index 00000000..78b7d79e
+--- /dev/null
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -0,0 +1,196 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "netutils.h"
++#include "test-common.h"
++
++static void test(void)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	struct knet_host *host;
++	struct knet_link *link;
++	struct sockaddr_storage lo;
++
++	if (make_local_sockaddr(&lo, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	printf("Test knet_link_clear_acl incorrect knet_h\n");
++
++	if ((!knet_link_clear_acl(NULL, 1, 0)) || (errno != EINVAL)) {
++		printf("knet_link_clear_acl accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	printf("Test knet_link_clear_acl with unconfigured host\n");
++
++	if ((!knet_link_clear_acl(knet_h, 1, 0)) || (errno != EINVAL)) {
++		printf("knet_link_clear_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_clear_acl with unconfigured link\n");
++
++	if (knet_host_add(knet_h, 1) < 0) {
++		printf("knet_host_add failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_clear_acl(knet_h, 1, 0)) || (errno != EINVAL)) {
++		printf("knet_link_clear_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_clear_acl with invalid link\n");
++
++	if ((!knet_link_clear_acl(knet_h, 1, KNET_MAX_LINK)) || (errno != EINVAL)) {
++		printf("knet_link_clear_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_clear_acl with point to point link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_clear_acl(knet_h, 1, 0)) || (errno != EINVAL)) {
++		printf("knet_link_clear_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_link_clear_config(knet_h, 1, 0);
++
++	printf("Test knet_link_clear_acl with dynamic link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	host = knet_h->host_index[1];
++	link = &host->link[0];
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list NOT empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		printf("knet_link_clear_acl did not accept dynamic link error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_clear_acl(knet_h, 1, 0) < 0) {
++		printf("knet_link_clear_acl failed to clear. error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list NOT empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++	knet_link_clear_config(knet_h, 1, 0);
++	knet_host_remove(knet_h, 1);
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+new file mode 100644
+index 00000000..547f92bb
+--- /dev/null
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -0,0 +1,246 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "netutils.h"
++#include "test-common.h"
++
++static void test(void)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	struct knet_host *host;
++	struct knet_link *link;
++	struct sockaddr_storage lo, lo6;
++
++	if (make_local_sockaddr(&lo, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	if (make_local_sockaddr6(&lo6, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	printf("Test knet_link_insert_acl incorrect knet_h\n");
++
++	if ((!knet_link_insert_acl(NULL, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	printf("Test knet_link_insert_acl with unconfigured host\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with unconfigured link\n");
++
++	if (knet_host_add(knet_h, 1) < 0) {
++		printf("knet_host_add failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with invalid link\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, KNET_MAX_LINK, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with invalid ss1\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted invalid ss1 or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with invalid ss2\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted invalid ss2 or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with non matching families\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted non matching families or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with wrong check_type\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with wrong acceptreject\n");
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_insert_acl with point to point link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_insert_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_link_clear_config(knet_h, 1, 0);
++
++	printf("Test knet_link_insert_acl with dynamic link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	host = knet_h->host_index[1];
++	link = &host->link[0];
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list not empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		printf("knet_link_insert_acl did not accept dynamic link error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++	knet_link_clear_config(knet_h, 1, 0);
++	knet_host_remove(knet_h, 1);
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+new file mode 100644
+index 00000000..49a82d97
+--- /dev/null
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -0,0 +1,256 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "netutils.h"
++#include "test-common.h"
++
++static void test(void)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	struct knet_host *host;
++	struct knet_link *link;
++	struct sockaddr_storage lo, lo6;
++
++	if (make_local_sockaddr(&lo, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	if (make_local_sockaddr6(&lo6, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	printf("Test knet_link_rm_acl incorrect knet_h\n");
++
++	if ((!knet_link_rm_acl(NULL, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	printf("Test knet_link_rm_acl with unconfigured host\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with unconfigured link\n");
++
++	if (knet_host_add(knet_h, 1) < 0) {
++		printf("knet_host_add failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with invalid link\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, KNET_MAX_LINK, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with invalid ss1\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted invalid ss1 or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with invalid ss2\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted invalid ss2 or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with non matching families\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted non matching families or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with wrong check_type\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with wrong acceptreject\n");
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_link_rm_acl with point to point link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
++		printf("knet_link_rm_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_link_clear_config(knet_h, 1, 0);
++
++	printf("Test knet_link_rm_acl with dynamic link\n");
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	host = knet_h->host_index[1];
++	link = &host->link[0];
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list not empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		printf("Failed to add an access list: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		printf("knet_link_rm_acl did not accept dynamic link error: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++		printf("match list NOT empty!");
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++	knet_link_clear_config(knet_h, 1, 0);
++	knet_host_remove(knet_h, 1);
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0234-acl-Fix-English-in-commments.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0234-acl-Fix-English-in-commments.patch
new file mode 100644
index 000000000..00a993c7c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0234-acl-Fix-English-in-commments.patch
@@ -0,0 +1,106 @@ 
+From a3773969b3659e874072dcb76677cf0a9bd3509c Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 7 Mar 2019 10:04:41 +0000
+Subject: [PATCH] acl: Fix English in commments
+
+---
+ libknet/internals.h |  2 +-
+ libknet/libknet.h   | 27 ++++++++++++++-------------
+ 2 files changed, 15 insertions(+), 14 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 8976a8cc..12f613cb 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -132,7 +132,7 @@ struct knet_sock {
+ struct knet_fd_trackers {
+ 	uint8_t transport;		    /* transport type (UDP/SCTP...) */
+ 	uint8_t data_type;		    /* internal use for transport to define what data are associated
+-					     * to this fd */
++					     * with this fd */
+ 	void *data;			    /* pointer to the data */
+ 	void *access_list_match_entry_head; /* pointer to access list match_entry list head */
+ };
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index d616e116..50ed70dd 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -523,15 +523,16 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled);
+  *
+  * knet will automatically generate access lists for point to point links.
+  *
+- * For open links, knet provides 3 API calls to manipulate access lists:
+- * knet_link_add_acl(3), knet_link_rm_acl(3) and knet_link_clear_acl(3).
+- * Those API calls will work only and exclusively on open links as they
+- * provide no use for point to point links.
++ * For open links, knet provides 4 API calls to manipulate access lists:
++ * knet_link_add_acl(3), knet_link_rm_acl(3), knet_link_insert_acl(3)
++ * and knet_link_clear_acl(3).
++ * Those API calls will work exclusively on open links as they
++ * are of no use on point to point links.
+  *
+  * knet will not enforce any access list unless specifically enabled by
+  * knet_handle_enable_access_lists(3).
+  *
+- * From a security / programming perspective we recommend to:
++ * From a security / programming perspective we recommend:
+  * - create the knet handle
+  * - enable access lists
+  * - configure hosts and links
+@@ -1478,13 +1479,13 @@ int knet_link_get_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id);
+ 
+ /*
+- * access lists management for open links
++ * Access lists management for open links
+  * see also knet_handle_enable_access_lists(3)
+  */
+ 
+ /*
+  * CHECK_TYPE_ADDRESS is the equivalent of a single entry / IP address.
+- *                    for example: 10.1.9.3/32
++ *                    for example: 10.1.9.3
+  *                    and the entry is stored in ss1. ss2 can be NULL.
+  *
+  * CHECK_TYPE_MASK    is used to configure network/netmask.
+@@ -1495,9 +1496,9 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+  *                    for example: 172.16.0.1-172.16.0.10
+  *                    the start is stored in ss1 and the end in ss2.
+  *
+- * Please be aware that the above examples refers only to IP based protocols.
++ * Please be aware that the above examples refer only to IP based protocols.
+  * Other protocols might use ss1 and ss2 in slightly different ways.
+- * At the moment knet only supports IP based protocol and that might change
++ * At the moment knet only supports IP based protocol, though that might change
+  * in the future.
+  */
+ 
+@@ -1531,7 +1532,7 @@ typedef enum {
+  *
+  * IMPORTANT: the order in which access lists are added is critical and it
+  *            is left to the user to add them in the right order. knet
+- *            will do no attempt to logically sort them.
++ *            will not attempt to logically sort them.
+  *
+  *            For example:
+  *            1 - accept from 10.0.0.0/8
+@@ -1568,7 +1569,7 @@ int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link
+  * link_id   - see knet_link_set_config(3)
+  *
+  * index     - insert at position "index" where 0 is the first entry and -1
+- *             append to the current list.
++ *             appends to the current list.
+  *
+  * ss1 / ss2 / type / acceptreject - see typedef definitions for details
+  *
+@@ -1597,8 +1598,8 @@ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+  *
+  * ss1 / ss2 / type / acceptreject - see typedef definitions for details
+  *
+- * IMPORTANT: the data passed to this API call must match exactly the ones used
+- *            in knet_link_add_acl(3).
++ * IMPORTANT: the data passed to this API call must match exactly that passed
++ *            to knet_link_add_acl(3).
+  *
+  * @return
+  * knet_link_rm_acl
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0235-access-lists-add-more-extensive-test-for-links_acl_i.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0235-access-lists-add-more-extensive-test-for-links_acl_i.patch
new file mode 100644
index 000000000..7e3288eef
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0235-access-lists-add-more-extensive-test-for-links_acl_i.patch
@@ -0,0 +1,717 @@ 
+From ce09710b031c54dca6288b44a60997e37c37f4da Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Mar 2019 15:31:28 +0100
+Subject: [PATCH] [access lists] add more extensive test for links_acl_ip
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/Makefile.am        |  33 ++-
+ libknet/tests/int_links_acl.c    | 211 ----------------
+ libknet/tests/int_links_acl.txt  |   8 -
+ libknet/tests/int_links_acl_ip.c | 399 +++++++++++++++++++++++++++++++
+ 4 files changed, 415 insertions(+), 236 deletions(-)
+ delete mode 100644 libknet/tests/int_links_acl.c
+ delete mode 100644 libknet/tests/int_links_acl.txt
+ create mode 100644 libknet/tests/int_links_acl_ip.c
+
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index eae5c803..3e74ea8e 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -13,8 +13,7 @@ include $(top_srcdir)/libknet/tests/api-check.mk
+ 
+ EXTRA_DIST		= \
+ 			  api-test-coverage \
+-			  api-check.mk \
+-			  int_links_acl.txt
++			  api-check.mk
+ 
+ AM_CPPFLAGS		= -I$(top_srcdir)/libknet
+ AM_CFLAGS		+= $(PTHREAD_CFLAGS)
+@@ -34,6 +33,7 @@ check_PROGRAMS		= \
+ 			  $(fun_checks)
+ 
+ int_checks		= \
++			  int_links_acl_ip_test \
+ 			  int_timediff_test
+ 
+ fun_checks		=
+@@ -45,7 +45,6 @@ benchmarks		= \
+ noinst_PROGRAMS		= \
+ 			  api_knet_handle_new_limit_test \
+ 			  pckt_test \
+-			  int_links_acl_test \
+ 			  $(benchmarks) \
+ 			  $(check_PROGRAMS)
+ 
+@@ -67,20 +66,20 @@ check-api-test-coverage:
+ 
+ pckt_test_SOURCES	= pckt_test.c
+ 
+-int_links_acl_test_SOURCES = int_links_acl.c \
+-			     ../common.c \
+-			     ../compat.c \
+-			     ../logging.c \
+-			     ../netutils.c \
+-			     ../threads_common.c \
+-			     ../transports.c \
+-			     ../transport_common.c \
+-			     ../transport_loopback.c \
+-			     ../transport_sctp.c \
+-			     ../transport_udp.c \
+-			     ../links_acl.c \
+-			     ../links_acl_ip.c \
+-			     ../links_acl_loopback.c
++int_links_acl_ip_test_SOURCES = int_links_acl_ip.c \
++				../common.c \
++				../compat.c \
++				../logging.c \
++				../netutils.c \
++				../threads_common.c \
++				../transports.c \
++				../transport_common.c \
++				../transport_loopback.c \
++				../transport_sctp.c \
++				../transport_udp.c \
++				../links_acl.c \
++				../links_acl_ip.c \
++				../links_acl_loopback.c
+ 
+ int_timediff_test_SOURCES = int_timediff.c
+ 
+diff --git a/libknet/tests/int_links_acl.c b/libknet/tests/int_links_acl.c
+deleted file mode 100644
+index 15e8e076..00000000
+--- a/libknet/tests/int_links_acl.c
++++ /dev/null
+@@ -1,211 +0,0 @@
+-/*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Christine Caulfield <ccaulfie@redhat.com>
+- *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <netinet/in.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#include <netdb.h>
+-
+-#include "internals.h"
+-#include "links_acl.h"
+-#include "links_acl_ip.h"
+-
+-static struct acl_match_entry *match_entry_v4;
+-static struct acl_match_entry *match_entry_v6;
+-
+-/* This is a test program .. remember! */
+-#define BUFLEN 1024
+-
+-static int get_ipaddress(char *buf, struct sockaddr_storage *addr)
+-{
+-	struct addrinfo *info;
+-	struct addrinfo hints;
+-	int res;
+-
+-	memset(&hints, 0, sizeof(hints));
+-	hints.ai_family = AF_UNSPEC;
+-
+-	res = getaddrinfo(buf, NULL, &hints, &info);
+-	if (!res) {
+-		memmove(addr, info->ai_addr, info->ai_addrlen);
+-		freeaddrinfo(info);
+-	}
+-	return res;
+-}
+-
+-static int read_address(char *buf, struct sockaddr_storage *addr)
+-{
+-	return get_ipaddress(buf, addr);
+-}
+-
+-static int read_mask(char *buf, struct sockaddr_storage *addr, struct sockaddr_storage *addr2)
+-{
+-	char tmpbuf[BUFLEN];
+-	char *slash;
+-	int ret;
+-
+-	slash = strchr(buf, '/');
+-	if (!slash)
+-		return 1;
+-
+-	strncpy(tmpbuf, buf, slash-buf);
+-	tmpbuf[slash-buf] = '\0';
+-
+-	ret = get_ipaddress(tmpbuf, addr);
+-        if (ret)
+-		return ret;
+-
+-	ret = get_ipaddress(slash+1, addr2);
+-        if (ret)
+-		return ret;
+-
+-	return 0;
+-}
+-
+-static int read_range(char *buf, struct sockaddr_storage *addr1, struct sockaddr_storage *addr2)
+-{
+-	char tmpbuf[BUFLEN];
+-	char *hyphen;
+-	int ret;
+-
+-	hyphen = strchr(buf, '-');
+-	if (!hyphen)
+-		return 1;
+-
+-	strncpy(tmpbuf, buf, hyphen-buf);
+-	tmpbuf[hyphen-buf] = '\0';
+-
+-	ret = get_ipaddress(tmpbuf, addr1);
+-        if (ret)
+-		return ret;
+-
+-	ret = get_ipaddress(hyphen+1, addr2);
+-        if (ret)
+-		return ret;
+-
+-	return 0;
+-}
+-
+-
+-static int load_file(void)
+-{
+-	FILE *filterfile;
+-	char filebuf[BUFLEN];
+-	int line = 0;
+-	int ret;
+-	check_type_t type;
+-	check_acceptreject_t acceptreject;
+-	struct sockaddr_storage addr1;
+-	struct sockaddr_storage addr2;
+-
+-	ipcheck_rmall(&match_entry_v4);
+-	ipcheck_rmall(&match_entry_v6);
+-
+-	filterfile = fopen("int_links_acl.txt", "r");
+-	if (!filterfile) {
+-		fprintf(stderr, "Cannot open int_links_acl.txt\n");
+-		return 1;
+-	}
+-
+-	while (fgets(filebuf, sizeof(filebuf), filterfile)) {
+-		filebuf[strlen(filebuf)-1] = '\0'; /* remove trailing LF */
+-		line++;
+-
+-		/*
+-		 * First char is A (accept) or R (Reject)
+-		 */
+-		switch(filebuf[0] & 0x5F) {
+-		case 'A':
+-			acceptreject = CHECK_ACCEPT;
+-			break;
+-		case 'R':
+-			acceptreject = CHECK_REJECT;
+-			break;
+-		default:
+-			fprintf(stderr, "Unknown record type on line %d: %s\n", line, filebuf);
+-			goto next_record;
+-		}
+-
+-		/*
+-		 * Second char is the filter type:
+-		 * A Address
+-		 * M Mask
+-		 * R Range
+-		 */
+-		switch(filebuf[1] & 0x5F) {
+-		case 'A':
+-			type = CHECK_TYPE_ADDRESS;
+-			ret = read_address(filebuf+2, &addr1);
+-			break;
+-		case 'M':
+-			type = CHECK_TYPE_MASK;
+-			ret = read_mask(filebuf+2, &addr1, &addr2);
+-			break;
+-		case 'R':
+-			type = CHECK_TYPE_RANGE;
+-			ret = read_range(filebuf+2, &addr1, &addr2);
+-			break;
+-		default:
+-			fprintf(stderr, "Unknown filter type on line %d: %s\n", line, filebuf);
+-			goto next_record;
+-			break;
+-		}
+-		if (ret) {
+-			fprintf(stderr, "Failed to parse address on line %d: %s\n", line, filebuf);
+-		}
+-		else {
+-			if (addr1.ss_family == AF_INET) {
+-				ipcheck_addip(&match_entry_v4, -1, &addr1, &addr2, type, acceptreject);
+-			} else {
+-				ipcheck_addip(&match_entry_v6, -1, &addr1, &addr2, type, acceptreject);
+-			}
+-		}
+-	next_record: {} /* empty statement to mollify the compiler */
+-	}
+-	fclose(filterfile);
+-
+-	return 0;
+-}
+-
+-int main(int argc, char *argv[])
+-{
+-	struct sockaddr_storage saddr;
+-	struct acl_match_entry *match_entry;
+-	int ret;
+-	int i;
+-
+-	if (load_file())
+-		return 1;
+-
+-	for (i=1; i<argc; i++) {
+-		ret = get_ipaddress(argv[i], &saddr);
+-		if (ret) {
+-			fprintf(stderr, "Cannot parse address %s\n", argv[i]);
+-		} else {
+-			if (saddr.ss_family == AF_INET) {
+-				match_entry = match_entry_v4;
+-			} else {
+-				match_entry = match_entry_v6;
+-			}
+-			if (ipcheck_validate(&match_entry, &saddr)) {
+-				printf("%s is VALID\n", argv[i]);
+-			} else {
+-				printf("%s is not allowed\n", argv[i]);
+-			}
+-		}
+-	}
+-
+-	ipcheck_rmall(&match_entry_v4);
+-	ipcheck_rmall(&match_entry_v6);
+-	return 0;
+-}
+diff --git a/libknet/tests/int_links_acl.txt b/libknet/tests/int_links_acl.txt
+deleted file mode 100644
+index 5776d54f..00000000
+--- a/libknet/tests/int_links_acl.txt
++++ /dev/null
+@@ -1,8 +0,0 @@
+-AA192.168.1.1
+-AA192.168.1.2
+-RA192.168.0.3
+-AR192.168.0.0-192.168.0.250
+-AM192.168.2.0/255.255.255.0
+-AM1740::0/FFF0::0
+-RA1000::666
+-AR1000::1-2000::7FF
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+new file mode 100644
+index 00000000..a7d2aed8
+--- /dev/null
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -0,0 +1,399 @@
++/*
++ * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Christine Caulfield <ccaulfie@redhat.com>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <sys/types.h>
++#include <sys/socket.h>
++#include <netinet/in.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <netdb.h>
++#include <errno.h>
++
++#include "internals.h"
++#include "links_acl.h"
++#include "links_acl_ip.h"
++
++#include "test-common.h"
++
++static struct acl_match_entry *match_entry_v4;
++static struct acl_match_entry *match_entry_v6;
++
++/* This is a test program .. remember! */
++#define BUFLEN 1024
++
++static int get_ipaddress(const char *buf, struct sockaddr_storage *addr)
++{
++	struct addrinfo *info;
++	struct addrinfo hints;
++
++	memset(&hints, 0, sizeof(hints));
++	hints.ai_family = AF_UNSPEC;
++
++	if (getaddrinfo(buf, NULL, &hints, &info)) {
++		return -1;
++	}
++
++	memmove(addr, info->ai_addr, info->ai_addrlen);
++	freeaddrinfo(info);
++	return 0;
++}
++
++static int read_2ip(const char *buf, const char *delim, struct sockaddr_storage *addr, struct sockaddr_storage *addr2)
++{
++	char tmpbuf[BUFLEN];
++	char *deli;
++
++	deli = strstr(buf, delim);
++	if (!deli) {
++		return -1;
++	}
++
++	strncpy(tmpbuf, buf, deli-buf);
++	tmpbuf[deli-buf] = '\0';
++
++	if (get_ipaddress(tmpbuf, addr)) {
++		return -1;
++	}
++
++	if (get_ipaddress(deli+1, addr2)) {
++		return -1;
++	}
++
++	return 0;
++}
++
++/*
++ * be aware that ordering is important
++ * so we can test all the rules with few
++ * ipcheck_validate calls
++ */
++
++const char *rules[100] = {
++	/*
++	 * ipv4
++	 */
++	"RA192.168.0.3",		/* reject address */
++	"AA192.168.0.1",		/* accept address */
++	"RR192.168.0.10-192.168.0.20",	/* reject range */
++	"AR192.168.0.0-192.168.0.255",	/* accept range */
++	"RM192.168.2.0/255.255.255.0",	/* reject mask */
++	"AM192.168.2.0/255.255.254.0",	/* accept mask */
++	/*
++	 * ipv6
++	 */
++	"RA3ffe::3",
++	"AA3ffe::1",
++	"RR3ffe::10-3ffe::20",
++	"AR3ffe::0-3ffe::ff",
++	"RM3ffe:1::0/ffff:ffff:ffff:ffff:ffff:ffff:ffff:0",
++	"AM3ffe:1::0/ffff:ffff:ffff:ffff::0"
++};
++
++static int _ipcheck_addip(void *fd_tracker_match_entry_head,
++			  struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
++			  check_type_t type, check_acceptreject_t acceptreject)
++{
++	return ipcheck_addip(fd_tracker_match_entry_head, -1, ss1, ss2, type, acceptreject);
++}
++
++static int default_rules(int load)
++{
++	int ret;
++	check_type_t type;
++	check_acceptreject_t acceptreject;
++	struct sockaddr_storage addr1;
++	struct sockaddr_storage addr2;
++	int i = 0;
++	int (*loadfn)(void *fd_tracker_match_entry_head, struct sockaddr_storage *ss1, struct sockaddr_storage *ss2, check_type_t type, check_acceptreject_t acceptreject);
++
++	if (load) {
++		loadfn = _ipcheck_addip;
++	} else {
++		loadfn = ipcheck_rmip;
++	}
++
++	while (rules[i] != NULL) {
++		printf("Parsing rule: %s\n", rules[i]);
++		memset(&addr1, 0, sizeof(struct sockaddr_storage));
++		memset(&addr2, 0, sizeof(struct sockaddr_storage));
++		/*
++		 * First char is A (accept) or R (Reject)
++		 */
++		switch(rules[i][0] & 0x5F) {
++			case 'A':
++				acceptreject = CHECK_ACCEPT;
++				break;
++			case 'R':
++				acceptreject = CHECK_REJECT;
++				break;
++			default:
++				fprintf(stderr, "Unknown record type on line %d: %s\n", i, rules[i]);
++				goto next_record;
++		}
++
++		/*
++		 * Second char is the filter type:
++		 * A Address
++		 * M Mask
++		 * R Range
++		 */
++		switch(rules[i][1] & 0x5F) {
++			case 'A':
++				type = CHECK_TYPE_ADDRESS;
++				ret = get_ipaddress(rules[i]+2, &addr1);
++				break;
++			case 'M':
++				type = CHECK_TYPE_MASK;
++				ret = read_2ip(rules[i]+2, "/", &addr1, &addr2);
++				break;
++			case 'R':
++				type = CHECK_TYPE_RANGE;
++				ret = read_2ip(rules[i]+2, "-", &addr1, &addr2);
++				break;
++			default:
++				fprintf(stderr, "Unknown filter type on line %d: %s\n", i, rules[i]);
++				goto next_record;
++				break;
++		}
++
++		if (ret) {
++			fprintf(stderr, "Failed to parse address on line %d: %s\n", i, rules[i]);
++			return -1;
++		} else {
++			if (addr1.ss_family == AF_INET) {
++				if (loadfn(&match_entry_v4, &addr1, &addr2, type, acceptreject) < 0) {
++					fprintf(stderr, "Failed to add/rm address on line %d: %s (errno: %s)\n", i, rules[i], strerror(errno));
++					return -1;
++				}
++			} else {
++				if (loadfn(&match_entry_v6, &addr1, &addr2, type, acceptreject) < 0) {
++					fprintf(stderr, "Failed to add/rm address on line %d: %s (errno: %s)\n", i, rules[i], strerror(errno));
++					return -1;
++				}
++			}
++		}
++
++	next_record:
++		i++;
++	}
++
++	return 0;
++}
++
++const char *tests[100] = {
++	/*
++	 * ipv4
++	 */
++	"R192.168.0.3",		/* reject address */
++	"A192.168.0.1",		/* accept address */
++	"R192.168.0.11",	/* reject range */
++	"A192.168.0.8",		/* accept range */
++	"R192.168.2.1",		/* reject mask */
++	"A192.168.3.1",		/* accept mask */
++	/*
++	 * ipv6
++	 */
++	"R3ffe::3",
++	"A3ffe::1",
++	"R3ffe::11",
++	"A3ffe::8",
++	"R3ffe:1::1",
++	"A3ffe:1::1:1"
++};
++
++const char *after_insert_tests[100] = {
++	/*
++	 * ipv4
++	 */
++	"R192.168.0.3",		/* reject address */
++	"A192.168.0.1",		/* accept address */
++	"R192.168.0.11",	/* reject range */
++	"A192.168.0.8",		/* accept range */
++	"A192.168.2.1",		/* reject mask */
++	"A192.168.3.1",		/* accept mask */
++	/*
++	 * ipv6
++	 */
++	"R3ffe::3",
++	"A3ffe::1",
++	"R3ffe::11",
++	"A3ffe::8",
++	"A3ffe:1::1",
++	"A3ffe:1::1:1"
++};
++
++int test(void)
++{
++	int i = 0;
++	int expected;
++	struct sockaddr_storage saddr;
++	struct acl_match_entry *match_entry;
++
++	/*
++	 * default tests
++	 */
++	while (tests[i] != NULL) {
++		/*
++		 * First char is A (accept) or R (Reject)
++		 */
++		switch(tests[i][0] & 0x5F) {
++			case 'A':
++				expected = 1;
++				break;
++			case 'R':
++				expected = 0;
++				break;
++			default:
++				fprintf(stderr, "Unknown record type on line %d: %s\n", i, tests[i]);
++				return FAIL;
++				break;
++		}
++
++		if (get_ipaddress(tests[i]+1, &saddr)) {
++				fprintf(stderr, "Cannot parse address %s\n", tests[i]+1);
++				return FAIL;
++		}
++
++		if (saddr.ss_family == AF_INET) {
++			match_entry = match_entry_v4;
++		} else {
++			match_entry = match_entry_v6;
++		}
++
++		if (ipcheck_validate(&match_entry, &saddr) != expected) {
++			fprintf(stderr, "Failed to check access list for ip: %s\n", tests[i]);
++			return FAIL;
++		}
++		i++;
++	}
++
++	/*
++	 * insert tests
++	 */
++
++	if (get_ipaddress("192.168.2.1", &saddr)) {
++		fprintf(stderr, "Cannot parse address 192.168.2.1\n");
++		return FAIL;
++	}
++
++	if (ipcheck_addip(&match_entry_v4, 3, &saddr, &saddr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		fprintf(stderr, "Unable to insert address in position 3 192.168.2.1\n");
++		return FAIL;
++	}
++
++	if (get_ipaddress("3ffe:1::1", &saddr)) {
++		fprintf(stderr, "Cannot parse address 3ffe:1::1\n");
++		return FAIL;
++	}
++
++	if (ipcheck_addip(&match_entry_v6, 3, &saddr, &saddr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
++		fprintf(stderr, "Unable to insert address in position 3 3ffe:1::1\n");
++		return FAIL;
++	}
++
++	while (after_insert_tests[i] != NULL) {
++		/*
++		 * First char is A (accept) or R (Reject)
++		 */
++		switch(after_insert_tests[i][0] & 0x5F) {
++			case 'A':
++				expected = 1;
++				break;
++			case 'R':
++				expected = 0;
++				break;
++			default:
++				fprintf(stderr, "Unknown record type on line %d: %s\n", i, after_insert_tests[i]);
++				return FAIL;
++				break;
++		}
++
++		if (get_ipaddress(after_insert_tests[i]+1, &saddr)) {
++				fprintf(stderr, "Cannot parse address %s\n", after_insert_tests[i]+1);
++				return FAIL;
++		}
++
++		if (saddr.ss_family == AF_INET) {
++			match_entry = match_entry_v4;
++		} else {
++			match_entry = match_entry_v6;
++		}
++
++		if (ipcheck_validate(&match_entry, &saddr) != expected) {
++			fprintf(stderr, "Failed to check access list for ip: %s\n", after_insert_tests[i]);
++			return FAIL;
++		}
++		i++;
++	}
++	return PASS;
++}
++
++int main(int argc, char *argv[])
++{
++	struct sockaddr_storage saddr;
++	struct acl_match_entry *match_entry;
++	int ret = PASS;
++	int i;
++
++	if (default_rules(1) < 0) {
++		return -1;
++	}
++
++	if (argc > 1) {
++		/*
++		 * run manual check against default access lists
++		 */
++		for (i=1; i<argc; i++) {
++			if (get_ipaddress(argv[i], &saddr)) {
++				fprintf(stderr, "Cannot parse address %s\n", argv[i]);
++				ret = FAIL;
++				goto out;
++			} else {
++				if (saddr.ss_family == AF_INET) {
++					match_entry = match_entry_v4;
++				} else {
++					match_entry = match_entry_v6;
++				}
++				if (ipcheck_validate(&match_entry, &saddr)) {
++					printf("%s is VALID\n", argv[i]);
++					ret = PASS;
++				} else {
++					printf("%s is not allowed\n", argv[i]);
++					ret = FAIL;
++				}
++			}
++		}
++	} else {
++		/*
++		 * run automatic tests
++		 */
++		ret = test();
++	}
++
++	/*
++	 * test memory leaks with ipcheck_rmip
++	 */
++	if (default_rules(0) < 0) {
++		return FAIL;
++	}
++
++	/*
++	 * test memory leaks with ipcheck_rmall
++	 */
++	if (default_rules(1) < 0) {
++		return FAIL;
++	}
++out:
++	ipcheck_rmall(&match_entry_v4);
++	ipcheck_rmall(&match_entry_v6);
++
++	return ret;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0236-logging-fix-log-target-of-recently-added-API-calls.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0236-logging-fix-log-target-of-recently-added-API-calls.patch
new file mode 100644
index 000000000..412446e40
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0236-logging-fix-log-target-of-recently-added-API-calls.patch
@@ -0,0 +1,52 @@ 
+From 9082472c1f75c78f61fd00989cb9730b0c58cd67 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 9 Mar 2019 07:03:25 +0100
+Subject: [PATCH] [logging] fix log target of recently added API calls
+
+spotted during sctp testing
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 038a8a42..8011a6dc 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1199,7 +1199,7 @@ int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link
+ 
+ 	savederrno = get_global_wrlock(knet_h);
+ 	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++		log_err(knet_h, KNET_SUB_LINK, "Unable to get write lock: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
+ 		return -1;
+@@ -1294,7 +1294,7 @@ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ 	savederrno = get_global_wrlock(knet_h);
+ 	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++		log_err(knet_h, KNET_SUB_LINK, "Unable to get write lock: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
+ 		return -1;
+@@ -1388,7 +1388,7 @@ int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_
+ 
+ 	savederrno = get_global_wrlock(knet_h);
+ 	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++		log_err(knet_h, KNET_SUB_LINK, "Unable to get write lock: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
+ 		return -1;
+@@ -1450,7 +1450,7 @@ int knet_link_clear_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t li
+ 
+ 	savederrno = get_global_wrlock(knet_h);
+ 	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HOST, "Unable to get write lock: %s",
++		log_err(knet_h, KNET_SUB_LINK, "Unable to get write lock: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
+ 		return -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0237-tests-remove-stray-comment.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0237-tests-remove-stray-comment.patch
new file mode 100644
index 000000000..c011f02c1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0237-tests-remove-stray-comment.patch
@@ -0,0 +1,22 @@ 
+From b0a6b164b28653f5042bca80538bb15e656069ab Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 7 Mar 2019 18:42:20 +0100
+Subject: [PATCH] [tests] remove stray comment
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/Makefile.am | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 3e74ea8e..015587cf 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -41,7 +41,6 @@ fun_checks		=
+ benchmarks		= \
+ 			  knet_bench_test
+ 
+-# int_links_acl_test can´t run yet standalone
+ noinst_PROGRAMS		= \
+ 			  api_knet_handle_new_limit_test \
+ 			  pckt_test \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0238-manpages-Document-enums-206.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0238-manpages-Document-enums-206.patch
new file mode 100644
index 000000000..a7e14823b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0238-manpages-Document-enums-206.patch
@@ -0,0 +1,38 @@ 
+From 7f26fef5be3a5ebe2f1049ec4b8b9b787164d7c4 Mon Sep 17 00:00:00 2001
+From: Chrissie Caulfield <ccaulfie@redhat.com>
+Date: Tue, 12 Mar 2019 13:55:25 +0000
+Subject: [PATCH] manpages: Document enums (#206)
+
+And also fix a bug in structure printing that caused it to print the wrong name for a struct.
+---
+ libknet/libknet.h | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 50ed70dd..d16eb5d4 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1483,7 +1483,10 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+  * see also knet_handle_enable_access_lists(3)
+  */
+ 
+-/*
++/**
++ * check_type_t
++ * @brief address type enum for knet access lists
++ *
+  * CHECK_TYPE_ADDRESS is the equivalent of a single entry / IP address.
+  *                    for example: 10.1.9.3
+  *                    and the entry is stored in ss1. ss2 can be NULL.
+@@ -1508,7 +1511,10 @@ typedef enum {
+ 	CHECK_TYPE_RANGE
+ } check_type_t;
+ 
+-/*
++/**
++ * check_acceptreject_t
++ * @brief enum for accept/reject in knet access lists
++ *
+  * accept or reject incoming packets defined in the access list entry
+  */
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0239-compress-add-support-for-libzstd.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0239-compress-add-support-for-libzstd.patch
new file mode 100644
index 000000000..30e3c5009
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0239-compress-add-support-for-libzstd.patch
@@ -0,0 +1,342 @@ 
+From f56e8f4c6ce7a815d13af984ed072fcbb5335332 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 10 Apr 2019 08:40:50 +0200
+Subject: [PATCH] [compress] add support for libzstd
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ Makefile.am             |   5 ++
+ configure.ac            |   2 +
+ kronosnet.spec.in       |  29 ++++++++
+ libknet/Makefile.am     |   7 ++
+ libknet/compress.c      |   1 +
+ libknet/compress_zstd.c | 160 ++++++++++++++++++++++++++++++++++++++++
+ libknet/libknet.h       |   1 +
+ libknet/logging.c       |   1 +
+ 8 files changed, 206 insertions(+)
+ create mode 100644 libknet/compress_zstd.c
+
+diff --git a/Makefile.am b/Makefile.am
+index 24a13a64..82cb1f5b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -138,6 +138,11 @@ if BUILD_COMPRESS_BZIP2
+ else
+ 	sed -i -e "s#@bzip2@#bcond_with#g" $@-t
+ endif
++if BUILD_COMPRESS_ZSTD
++	sed -i -e "s#@zstd@#bcond_without#g" $@-t
++else
++	sed -i -e "s#@zstd@#bcond_with#g" $@-t
++endif
+ if BUILD_KRONOSNETD
+ 	sed -i -e "s#@kronosnetd@#bcond_without#g" $@-t
+ else
+diff --git a/configure.ac b/configure.ac
+index 30c57f00..501053e1 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -124,6 +124,8 @@ AC_ARG_ENABLE([compress-all],
+ 	[AS_HELP_STRING([--disable-compress-all],[disable libknet all compress modules support])],,
+ 	[ enable_compress_all="yes" ])
+ 
++KNET_OPTION_DEFINES([zstd],[compress],[PKG_CHECK_MODULES([libzstd], [libzstd])])
++
+ KNET_OPTION_DEFINES([zlib],[compress],[PKG_CHECK_MODULES([zlib], [zlib])])
+ KNET_OPTION_DEFINES([lz4],[compress],[PKG_CHECK_MODULES([liblz4], [liblz4])])
+ KNET_OPTION_DEFINES([lzo2],[compress],[
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 2d4d059f..442f3ae3 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -24,6 +24,7 @@
+ %@lzo2@ lzo2
+ %@lzma@ lzma
+ %@bzip2@ bzip2
++%@zstd@ zstd
+ %@kronosnetd@ kronosnetd
+ %@libnozzle@ libnozzle
+ %@runautogen@ runautogen
+@@ -60,6 +61,9 @@
+ %if %{with bzip2}
+ %global buildcompressbzip2 1
+ %endif
++%if %{with zstd}
++%global buildcompresszstd 1
++%endif
+ %if %{with libnozzle}
+ %global buildlibnozzle 1
+ %endif
+@@ -123,6 +127,9 @@ BuildRequires: xz-devel
+ %if %{defined buildcompressbzip2}
+ BuildRequires: /usr/include/bzlib.h
+ %endif
++%if %{defined buildcompresszstd}
++BuildRequires: libzstd-devel
++%endif
+ %if %{defined buildkronosnetd}
+ BuildRequires: pam-devel
+ %endif
+@@ -194,6 +201,11 @@ BuildRequires: libtool
+ %else
+ 	--disable-compress-bzip2 \
+ %endif
++%if %{defined buildcompresszstd}
++	--enable-compress-zstd \
++%else
++	--disable-compress-zstd \
++%endif
+ %if %{defined buildkronosnetd}
+ 	--enable-kronosnetd \
+ %endif
+@@ -490,6 +502,20 @@ Requires: libknet1 = %{version}-%{release}
+ %{_libdir}/kronosnet/compress_bzip2.so
+ %endif
+ 
++%if %{defined buildcompresszstd}
++%package -n libknet1-compress-zstd-plugin
++Group: System Environment/Libraries
++Summary: libknet1 zstd support
++Requires: libknet1 = %{version}-%{release}
++
++%description -n libknet1-compress-zstd-plugin
++ zstd compression support for libknet1.
++
++%files -n libknet1-compress-zstd-plugin
++%defattr(-,root,root,-)
++%{_libdir}/kronosnet/compress_zstd.so
++%endif
++
+ %package -n libknet1-crypto-plugins-all
+ Group: System Environment/Libraries
+ Summary: libknet1 crypto plugins meta package
+@@ -523,6 +549,9 @@ Requires: libknet1-compress-lzma-plugin
+ %if %{defined buildcompressbzip2}
+ Requires: libknet1-compress-bzip2-plugin
+ %endif
++%if %{defined buildcompresszstd}
++Requires: libknet1-compress-zstd-plugin
++%endif
+ 
+ %description -n libknet1-compress-plugins-all
+  meta package to install all of libknet1 compress plugins
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 0be4fffc..90ddfbad 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -103,6 +103,13 @@ pkglib_LTLIBRARIES	=
+ # MODULE_LDFLAGS would mean a target-specific variable for Automake
+ MODULELDFLAGS		= $(AM_LDFLAGS) -module -avoid-version -export-dynamic
+ 
++if BUILD_COMPRESS_ZSTD
++pkglib_LTLIBRARIES	+= compress_zstd.la
++compress_zstd_la_LDFLAGS = $(MODULELDFLAGS)
++compress_zstd_la_CFLAGS	= $(AM_CFLAGS) $(libzstd_CFLAGS)
++compress_zstd_la_LIBADD	= $(libzstd_LIBS)
++endif
++
+ if BUILD_COMPRESS_ZLIB
+ pkglib_LTLIBRARIES	+= compress_zlib.la
+ compress_zlib_la_LDFLAGS = $(MODULELDFLAGS)
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 278ff443..7eab454b 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -40,6 +40,7 @@ static compress_model_t compress_modules_cmds[] = {
+ 	{ "lzo2" , 4, WITH_COMPRESS_LZO2 , 0, NULL },
+ 	{ "lzma" , 5, WITH_COMPRESS_LZMA , 0, NULL },
+ 	{ "bzip2", 6, WITH_COMPRESS_BZIP2, 0, NULL },
++	{ "zstd" , 7, WITH_COMPRESS_ZSTD, 0, NULL },
+ 	{ NULL, 255, 0, 0, NULL }
+ };
+ 
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+new file mode 100644
+index 00000000..6f9b499e
+--- /dev/null
++++ b/libknet/compress_zstd.c
+@@ -0,0 +1,160 @@
++/*
++ * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+, LGPL-2.0+
++ */
++#define KNET_MODULE
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdlib.h>
++#include <string.h>
++#include <zstd.h>
++
++#include "logging.h"
++#include "compress_model.h"
++
++struct zstd_ctx {
++	ZSTD_CCtx* cctx;
++	ZSTD_DCtx* dctx;
++};
++
++static int zstd_is_init(
++	knet_handle_t knet_h,
++	int method_idx)
++{
++	if (knet_h->compress_int_data[method_idx]) {
++		return 1;
++	}
++	return 0;
++}
++
++static void zstd_fini(
++	knet_handle_t knet_h,
++	int method_idx)
++{
++	struct zstd_ctx *zstd_ctx = knet_h->compress_int_data[knet_h->compress_model];
++
++	if (zstd_ctx) {
++		if (zstd_ctx->cctx) {
++			ZSTD_freeCCtx(zstd_ctx->cctx);
++		}
++		if (zstd_ctx->dctx) {
++			ZSTD_freeDCtx(zstd_ctx->dctx);
++		}
++		free(knet_h->compress_int_data[method_idx]);
++		knet_h->compress_int_data[method_idx] = NULL;
++	}
++	return;
++}
++
++static int zstd_init(
++	knet_handle_t knet_h,
++	int method_idx)
++{
++	struct zstd_ctx *zstd_ctx;
++	int err = 0;
++
++	if (!knet_h->compress_int_data[method_idx]) {
++		zstd_ctx = malloc(sizeof(struct zstd_ctx));
++		if (!zstd_ctx) {
++			errno = ENOMEM;
++			return -1;
++		}
++		memset(zstd_ctx, 0, sizeof(struct zstd_ctx));
++
++		zstd_ctx->cctx = ZSTD_createCCtx();
++		if (!zstd_ctx->cctx) {
++			log_err(knet_h, KNET_SUB_ZSTDCOMP, "Unable to create compression context");
++			err = -1;
++			goto out_err;
++		}
++
++		zstd_ctx->dctx = ZSTD_createDCtx();
++		if (!zstd_ctx->dctx) {
++			log_err(knet_h, KNET_SUB_ZSTDCOMP, "Unable to create decompression context");
++			err = -1;
++			goto out_err;
++		}
++
++		knet_h->compress_int_data[method_idx] = zstd_ctx;
++	}
++
++out_err:
++	if (err) {
++		zstd_fini(knet_h, method_idx);
++	}
++	return err;
++}
++
++static int zstd_compress(
++	knet_handle_t knet_h,
++	const unsigned char *buf_in,
++	const ssize_t buf_in_len,
++	unsigned char *buf_out,
++	ssize_t *buf_out_len)
++{
++	struct zstd_ctx *zstd_ctx = knet_h->compress_int_data[knet_h->compress_model];
++	size_t compress_size;
++
++	compress_size = ZSTD_compressCCtx(zstd_ctx->cctx,
++					  buf_out, *buf_out_len,
++					  buf_in, buf_in_len,
++					  knet_h->compress_level);
++
++	if (ZSTD_isError(compress_size)) {
++		log_err(knet_h, KNET_SUB_ZSTDCOMP, "error compressing packet: %s", ZSTD_getErrorName(compress_size));
++		/*
++		 * ZSTD has lots of internal errors that are not easy to map
++		 * to standard errnos. Use a generic one for now
++		 */
++		errno = EINVAL;
++		return -1;
++	}
++
++	*buf_out_len = compress_size;
++
++	return 0;
++}
++
++static int zstd_decompress(
++	knet_handle_t knet_h,
++	const unsigned char *buf_in,
++	const ssize_t buf_in_len,
++	unsigned char *buf_out,
++	ssize_t *buf_out_len)
++{
++	struct zstd_ctx *zstd_ctx = knet_h->compress_int_data[knet_h->compress_model];
++	size_t decompress_size;
++
++	decompress_size = ZSTD_decompressDCtx(zstd_ctx->dctx,
++					      buf_out, *buf_out_len,
++					      buf_in, buf_in_len);
++
++	if (ZSTD_isError(decompress_size)) {
++		log_err(knet_h, KNET_SUB_ZSTDCOMP, "error decompressing packet: %s", ZSTD_getErrorName(decompress_size));
++		/*
++		 * ZSTD has lots of internal errors that are not easy to map
++		 * to standard errnos. Use a generic one for now
++		 */
++		errno = EINVAL;
++		return -1;
++	}
++
++	*buf_out_len = decompress_size;
++
++	return 0;
++}
++
++compress_ops_t compress_model = {
++	KNET_COMPRESS_MODEL_ABI,
++	zstd_is_init,
++	zstd_init,
++	zstd_fini,
++	NULL,
++	zstd_compress,
++	zstd_decompress
++};
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index d16eb5d4..3098eabc 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -2053,6 +2053,7 @@ int knet_link_get_status(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ #define KNET_SUB_LZO2COMP      73 /* compress_lzo.c */
+ #define KNET_SUB_LZMACOMP      74 /* compress_lzma.c */
+ #define KNET_SUB_BZIP2COMP     75 /* compress_bzip2.c */
++#define KNET_SUB_ZSTDCOMP      76 /* compress_zstd.c */
+ 
+ #define KNET_SUB_UNKNOWN       UINT8_MAX - 1
+ #define KNET_MAX_SUBSYSTEMS    UINT8_MAX
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 98bcfd14..5c912572 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -47,6 +47,7 @@ static struct pretty_names subsystem_names[] =
+ 	{ "lzo2comp", KNET_SUB_LZO2COMP },
+ 	{ "lzmacomp", KNET_SUB_LZMACOMP },
+ 	{ "bzip2comp", KNET_SUB_BZIP2COMP },
++	{ "zstdcomp", KNET_SUB_ZSTDCOMP },
+ 	{ "unknown", KNET_SUB_UNKNOWN }		/* unknown MUST always be last in this array */
+ };
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0240-tests-hide-an-arm-internal-memory-leak-non-recurring.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0240-tests-hide-an-arm-internal-memory-leak-non-recurring.patch
new file mode 100644
index 000000000..e6056068e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0240-tests-hide-an-arm-internal-memory-leak-non-recurring.patch
@@ -0,0 +1,25 @@ 
+From 6ac5d960b83cfb471107b69040eaf7f3a868ee07 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 11 Apr 2019 09:30:27 +0200
+Subject: [PATCH] [tests] hide an arm internal memory leak (non-recurring)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index e0f49d06..a34ab934 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -605,3 +605,10 @@
+    obj:*
+    obj:/usr/lib64/libnss3.so
+ }
++{
++   arm internal memory leak
++   Memcheck:Leak
++   match-leak-kinds: definite
++   fun:malloc
++   fun:dl_open_worker
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0241-tests-improve-wait-for-packet-implementation-to-flus.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0241-tests-improve-wait-for-packet-implementation-to-flus.patch
new file mode 100644
index 000000000..b3015d8e8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0241-tests-improve-wait-for-packet-implementation-to-flus.patch
@@ -0,0 +1,135 @@ 
+From 6bed741aacc4f191ab66f261f5aa6bb15743bffe Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 11 Apr 2019 09:31:00 +0200
+Subject: [PATCH] [tests] improve wait for packet implementation to flush logs
+ during wait
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_handle_clear_stats.c | 2 +-
+ libknet/tests/api_knet_send.c               | 2 +-
+ libknet/tests/api_knet_send_compress.c      | 2 +-
+ libknet/tests/api_knet_send_crypto.c        | 2 +-
+ libknet/tests/api_knet_send_loopback.c      | 4 ++--
+ libknet/tests/test-common.c                 | 7 ++++---
+ libknet/tests/test-common.h                 | 2 +-
+ 7 files changed, 11 insertions(+), 10 deletions(-)
+
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index 8e64235c..07f059a2 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -160,7 +160,7 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (wait_for_packet(knet_h, 10, datafd)) {
++	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 6c255b92..57994fbc 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -246,7 +246,7 @@ static void test(uint8_t transport)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (wait_for_packet(knet_h, 10, datafd)) {
++	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index 6de46746..b03f4e73 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -170,7 +170,7 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (wait_for_packet(knet_h, 10, datafd)) {
++	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index f2ca3662..e33a808a 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -171,7 +171,7 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (wait_for_packet(knet_h, 10, datafd)) {
++	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 0cfd29f7..2feca685 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -251,7 +251,7 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (wait_for_packet(knet_h, 10, datafd)) {
++	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+@@ -352,7 +352,7 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (wait_for_packet(knet_h, 10, datafd)) {
++	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index d0ea1ef8..a4ff2974 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -485,7 +485,7 @@ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd
+ 	return -1;
+ }
+ 
+-int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd)
++int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd, int logfd, FILE *std)
+ {
+ 	fd_set rfds;
+ 	struct timeval tv;
+@@ -500,7 +500,7 @@ try_again:
+ 	FD_ZERO(&rfds);
+ 	FD_SET(datafd, &rfds);
+ 
+-	tv.tv_sec = seconds;
++	tv.tv_sec = 1;
+ 	tv.tv_usec = 0;
+ 
+ 	err = select(datafd+1, &rfds, NULL, NULL, &tv);
+@@ -509,7 +509,8 @@ try_again:
+ 	 * pick an arbitrary 10 times loop (multiplied by waiting seconds)
+ 	 * before failing.
+ 	 */
+-	if ((!err) && (i < 10)) {
++	if ((!err) && (i < seconds)) {
++		flush_logs(logfd, std);
+ 		i++;
+ 		goto try_again;
+ 	}
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 8742f8d1..a498a098 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -70,6 +70,6 @@ int stop_logthread(void);
+ int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset);
+ int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset);
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std);
+-int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd);
++int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd, int logfd, FILE *std);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0242-man-fix-libknet.h-for-errors-detected-by-newly-added.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0242-man-fix-libknet.h-for-errors-detected-by-newly-added.patch
new file mode 100644
index 000000000..a4853bdba
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0242-man-fix-libknet.h-for-errors-detected-by-newly-added.patch
@@ -0,0 +1,50 @@ 
+From b3a562fc43ca13bad29d0ac1055092770cc754c8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Apr 2019 05:42:48 +0200
+Subject: [PATCH] [man] fix libknet.h for errors detected by newly added test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 3098eabc..183c92d3 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1553,7 +1553,7 @@ typedef enum {
+  *            packets from 10.0.0.1 will be accepted by rule number 1.
+  *
+  * @return
+- * knet_link_add_acl
++ * knet_link_add_acl returns
+  * 0 on success.
+  * -1 on error and errno is set.
+  */
+@@ -1580,7 +1580,7 @@ int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link
+  * ss1 / ss2 / type / acceptreject - see typedef definitions for details
+  *
+  * @return
+- * knet_link_insert_acl
++ * knet_link_insert_acl returns
+  * 0 on success.
+  * -1 on error and errno is set.
+  */
+@@ -1608,7 +1608,7 @@ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+  *            to knet_link_add_acl(3).
+  *
+  * @return
+- * knet_link_rm_acl
++ * knet_link_rm_acl returns
+  * 0 on success.
+  * -1 on error and errno is set.
+  */
+@@ -1630,7 +1630,7 @@ int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_
+  * link_id   - see knet_link_set_config(3)
+  *
+  * @return
+- * knet_link_clear_acl
++ * knet_link_clear_acl returns
+  * 0 on success.
+  * -1 on error and errno is set.
+  */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0243-global-update-copyright-across-the-board.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0243-global-update-copyright-across-the-board.patch
new file mode 100644
index 000000000..df7badd3e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0243-global-update-copyright-across-the-board.patch
@@ -0,0 +1,129 @@ 
+From ff9ef75611fa9ccd099a28e0fdf74e74fd1b062d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 26 Mar 2019 13:45:52 +0100
+Subject: [PATCH] [global] update copyright across the board
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl_ip.c                              | 2 +-
+ libknet/links_acl_ip.h                              | 2 +-
+ libknet/links_acl_loopback.c                        | 2 +-
+ libknet/links_acl_loopback.h                        | 2 +-
+ libknet/tests/api_knet_handle_enable_access_lists.c | 2 +-
+ libknet/tests/api_knet_link_add_acl.c               | 2 +-
+ libknet/tests/api_knet_link_clear_acl.c             | 2 +-
+ libknet/tests/api_knet_link_insert_acl.c            | 2 +-
+ libknet/tests/api_knet_link_rm_acl.c                | 2 +-
+ libknet/tests/int_links_acl_ip.c                    | 2 +-
+ 10 files changed, 10 insertions(+), 10 deletions(-)
+
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 642027be..9310f212 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index fac58e21..b33ffb1e 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index 97f8198f..044a51cb 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index e75c4a4d..b51d2bfd 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_access_lists.c b/libknet/tests/api_knet_handle_enable_access_lists.c
+index fc3bcc19..d08f175e 100644
+--- a/libknet/tests/api_knet_handle_enable_access_lists.c
++++ b/libknet/tests/api_knet_handle_enable_access_lists.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index b0181652..ff7a2e21 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index 78b7d79e..234a76b6 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index 547f92bb..79d04dfc 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index 49a82d97..d132c541 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+index a7d2aed8..93dff638 100644
+--- a/libknet/tests/int_links_acl_ip.c
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2018 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0244-build-bump-soname-to-indicate-new-API-calls.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0244-build-bump-soname-to-indicate-new-API-calls.patch
new file mode 100644
index 000000000..94cb6f0c0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0244-build-bump-soname-to-indicate-new-API-calls.patch
@@ -0,0 +1,23 @@ 
+From 6dff495666d39a3631f98a8eb5bf912a89137957 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 9 May 2019 16:36:07 +0200
+Subject: [PATCH] [build] bump soname to indicate new API calls
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 90ddfbad..8adcc40b 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -18,7 +18,7 @@ EXTRA_DIST		= $(SYMFILE)
+ SUBDIRS			= . tests
+ 
+ # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+-libversion		= 2:0:1
++libversion		= 3:0:2
+ 
+ # override global LIBS that pulls in lots of craft we don't need here
+ LIBS			=
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0245-spec-fix-upstream-URLs-to-point-to-https-and-officia.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0245-spec-fix-upstream-URLs-to-point-to-https-and-officia.patch
new file mode 100644
index 000000000..525df9a76
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0245-spec-fix-upstream-URLs-to-point-to-https-and-officia.patch
@@ -0,0 +1,31 @@ 
+From 2d9b9e4ef6847736607ed4f61d25d6eb9bb36ed3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 12 May 2019 06:59:00 +0200
+Subject: [PATCH] [spec] fix upstream URLs to point to https and official
+ release repo
+
+Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1708616
+
+also to be noted, the Source0: line is different from upstream and Fedora
+because upstream can handle tarballs during development
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 442f3ae3..e430ad28 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -90,8 +90,8 @@ Version: @version@
+ Release: 1%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}
+ License: GPLv2+ and LGPLv2+
+ Group: System Environment/Base
+-URL: https://github.com/kronosnet/kronosnet/
+-Source0: https://github.com/kronosnet/kronosnet/archive/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz
++URL: https://kronosnet.org
++Source0: https://kronosnet.org/releases/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz
+ 
+ ## Setup/build bits
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0246-spec-use-distro-conditionals-to-determine-BuildRequi.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0246-spec-use-distro-conditionals-to-determine-BuildRequi.patch
new file mode 100644
index 000000000..97a56b940
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0246-spec-use-distro-conditionals-to-determine-BuildRequi.patch
@@ -0,0 +1,59 @@ 
+From 4e545469700943410a1f016cbd2774b3f5cc1c63 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 25 Feb 2018 08:42:55 +0100
+Subject: [PATCH] [spec] use distro conditionals to determine BuildRequires
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index e430ad28..3b597d01 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -107,16 +107,28 @@ BuildRequires: libqb-devel libxml2-devel doxygen
+ BuildRequires: lksctp-tools-devel
+ %endif
+ %if %{defined buildcryptonss}
+-BuildRequires: /usr/include/nss3/nss.h /usr/include/nspr4/nspr.h
++%if 0%{?suse_version}
++BuildRequires: mozilla-nss-devel
++%else
++BuildRequires: nss-devel
++%endif
+ %endif
+ %if %{defined buildcryptoopenssl}
+-BuildRequires: /usr/include/openssl/conf.h
++%if 0%{?suse_version}
++BuildRequires: libopenssl-devel
++%else
++BuildRequires: openssl-devel
++%endif
+ %endif
+ %if %{defined buildcompresszlib}
+ BuildRequires: zlib-devel
+ %endif
+ %if %{defined buildcompresslz4}
+-BuildRequires: /usr/include/lz4hc.h
++%if 0%{?suse_version}
++BuildRequires: liblz4-devel
++%else
++BuildRequires: lz4-devel
++%endif
+ %endif
+ %if %{defined buildcompresslzo2}
+ BuildRequires: lzo-devel
+@@ -125,7 +137,11 @@ BuildRequires: lzo-devel
+ BuildRequires: xz-devel
+ %endif
+ %if %{defined buildcompressbzip2}
+-BuildRequires: /usr/include/bzlib.h
++%if 0%{?suse_version}
++BuildRequires: libbz2-devel
++%else
++BuildRequires: bzip2-devel
++%endif
+ %endif
+ %if %{defined buildcompresszstd}
+ BuildRequires: libzstd-devel
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0247-spec-be-more-strict-about-plugins-version-and-archit.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0247-spec-be-more-strict-about-plugins-version-and-archit.patch
new file mode 100644
index 000000000..3dbc498db
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0247-spec-be-more-strict-about-plugins-version-and-archit.patch
@@ -0,0 +1,167 @@ 
+From 2f4996455611a0026000da4187791c85d8b97f26 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 25 Feb 2018 09:08:10 +0100
+Subject: [PATCH] [spec] be more strict about plugins version and architecture
+ depedencies
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 42 +++++++++++++++++++++---------------------
+ 1 file changed, 21 insertions(+), 21 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 3b597d01..de316560 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -363,7 +363,7 @@ Summary: Simple userland wrapper around kernel tap devices
+ %package -n libnozzle1-devel
+ Group: Development/Libraries
+ Summary: Simple userland wrapper around kernel tap devices (developer files)
+-Requires: libnozzle1 = %{version}-%{release}
++Requires: libnozzle1%{_isa} = %{version}-%{release}
+ Requires: pkgconfig
+ 
+ %description -n libnozzle1-devel
+@@ -402,7 +402,7 @@ Summary: Kronosnet core switching implementation
+ %package -n libknet1-devel
+ Group: Development/Libraries
+ Summary: Kronosnet core switching implementation (developer files)
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ Requires: pkgconfig
+ 
+ %description -n libknet1-devel
+@@ -424,7 +424,7 @@ Requires: pkgconfig
+ %package -n libknet1-crypto-nss-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 nss support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-crypto-nss-plugin
+  NSS crypto support for libknet1.
+@@ -438,7 +438,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-crypto-openssl-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 openssl support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-crypto-openssl-plugin
+  OpenSSL crypto support for libknet1.
+@@ -452,7 +452,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-compress-zlib-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 zlib support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-zlib-plugin
+  zlib compression support for libknet1.
+@@ -465,7 +465,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-compress-lz4-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 lz4 and lz4hc support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-lz4-plugin
+  lz4 and lz4hc compression support for libknet1.
+@@ -480,7 +480,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-compress-lzo2-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 lzo2 support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-lzo2-plugin
+  lzo2 compression support for libknet1.
+@@ -494,7 +494,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-compress-lzma-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 lzma support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-lzma-plugin
+  lzma compression support for libknet1.
+@@ -508,7 +508,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-compress-bzip2-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 bzip2 support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-bzip2-plugin
+  bzip2 compression support for libknet1.
+@@ -522,7 +522,7 @@ Requires: libknet1 = %{version}-%{release}
+ %package -n libknet1-compress-zstd-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 zstd support
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-zstd-plugin
+  zstd compression support for libknet1.
+@@ -536,10 +536,10 @@ Requires: libknet1 = %{version}-%{release}
+ Group: System Environment/Libraries
+ Summary: libknet1 crypto plugins meta package
+ %if %{defined buildcryptonss}
+-Requires: libknet1-crypto-nss-plugin
++Requires: libknet1-crypto-nss-plugin%{_isa} = %{version}-%{release}
+ %endif
+ %if %{defined buildcryptoopenssl}
+-Requires: libknet1-crypto-openssl-plugin
++Requires: libknet1-crypto-openssl-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
+ %description -n libknet1-crypto-plugins-all
+@@ -551,22 +551,22 @@ Requires: libknet1-crypto-openssl-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 compress plugins meta package
+ %if %{defined buildcompresszlib}
+-Requires: libknet1-compress-zlib-plugin
++Requires: libknet1-compress-zlib-plugin%{_isa} = %{version}-%{release}
+ %endif
+ %if %{defined buildcompresslz4}
+-Requires: libknet1-compress-lz4-plugin
++Requires: libknet1-compress-lz4-plugin%{_isa} = %{version}-%{release}
+ %endif
+ %if %{defined buildcompresslzo2}
+-Requires: libknet1-compress-lzo2-plugin
++Requires: libknet1-compress-lzo2-plugin%{_isa} = %{version}-%{release}
+ %endif
+ %if %{defined buildcompresslzma}
+-Requires: libknet1-compress-lzma-plugin
++Requires: libknet1-compress-lzma-plugin%{_isa} = %{version}-%{release}
+ %endif
+ %if %{defined buildcompressbzip2}
+-Requires: libknet1-compress-bzip2-plugin
++Requires: libknet1-compress-bzip2-plugin%{_isa} = %{version}-%{release}
+ %endif
+ %if %{defined buildcompresszstd}
+-Requires: libknet1-compress-zstd-plugin
++Requires: libknet1-compress-zstd-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
+ %description -n libknet1-compress-plugins-all
+@@ -577,8 +577,8 @@ Requires: libknet1-compress-zstd-plugin
+ %package -n libknet1-plugins-all
+ Group: System Environment/Libraries
+ Summary: libknet1 plugins meta package
+-Requires: libknet1-compress-plugins-all
+-Requires: libknet1-crypto-plugins-all
++Requires: libknet1-compress-plugins-all%{_isa} = %{version}-%{release}
++Requires: libknet1-crypto-plugins-all%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-plugins-all
+  meta package to install all of libknet1 plugins
+@@ -589,7 +589,7 @@ Requires: libknet1-crypto-plugins-all
+ %package -n kronosnet-tests
+ Group: System Environment/Libraries
+ Summary: kronosnet test suite
+-Requires: libknet1 = %{version}-%{release}
++Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n kronosnet-tests
+  this package contains all the libknet and libnozzle test suite
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0248-spec-clean-up-useless-conditionals-and-defines.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0248-spec-clean-up-useless-conditionals-and-defines.patch
new file mode 100644
index 000000000..eb65586b9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0248-spec-clean-up-useless-conditionals-and-defines.patch
@@ -0,0 +1,376 @@ 
+From 7a541004591bf1d28c95b2668d8f6e507dcce892 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 12 May 2019 07:22:41 +0200
+Subject: [PATCH] [spec] clean up useless conditionals and defines
+
+fix a couple of minor conditionals in the process
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 144 +++++++++++++++++-----------------------------
+ 1 file changed, 52 insertions(+), 92 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index de316560..b5632ae3 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -37,50 +37,6 @@
+ %undefine _enable_debug_packages
+ %endif
+ 
+-%if %{with sctp}
+-%global buildsctp 1
+-%endif
+-%if %{with nss}
+-%global buildcryptonss 1
+-%endif
+-%if %{with openssl}
+-%global buildcryptoopenssl 1
+-%endif
+-%if %{with zlib}
+-%global buildcompresszlib 1
+-%endif
+-%if %{with lz4}
+-%global buildcompresslz4 1
+-%endif
+-%if %{with lzo2}
+-%global buildcompresslzo2 1
+-%endif
+-%if %{with lzma}
+-%global buildcompresslzma 1
+-%endif
+-%if %{with bzip2}
+-%global buildcompressbzip2 1
+-%endif
+-%if %{with zstd}
+-%global buildcompresszstd 1
+-%endif
+-%if %{with libnozzle}
+-%global buildlibnozzle 1
+-%endif
+-%if %{with kronosnetd}
+-%global buildlibnozzle 1
+-%global buildkronosnetd 1
+-%endif
+-%if %{with runautogen}
+-%global buildautogen 1
+-%endif
+-%if %{with buildman}
+-%global buildmanpages 1
+-%endif
+-%if %{with installtests}
+-%global installtestsuite 1
+-%endif
+-
+ # main (empty) package
+ # http://www.rpm.org/max-rpm/s1-rpm-subpack-spec-file-changes.html
+ 
+@@ -100,62 +56,60 @@ BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+ # Build dependencies
+ BuildRequires: gcc
+ # required to build man pages
+-%if %{defined buildmanpages}
++%if %{with buildman}
+ BuildRequires: libqb-devel libxml2-devel doxygen
+ %endif
+-%if %{defined buildsctp}
++%if %{with sctp}
+ BuildRequires: lksctp-tools-devel
+ %endif
+-%if %{defined buildcryptonss}
++%if %{with nss}
+ %if 0%{?suse_version}
+ BuildRequires: mozilla-nss-devel
+ %else
+ BuildRequires: nss-devel
+ %endif
+ %endif
+-%if %{defined buildcryptoopenssl}
++%if %{with openssl}
+ %if 0%{?suse_version}
+ BuildRequires: libopenssl-devel
+ %else
+ BuildRequires: openssl-devel
+ %endif
+ %endif
+-%if %{defined buildcompresszlib}
++%if %{with zlib}
+ BuildRequires: zlib-devel
+ %endif
+-%if %{defined buildcompresslz4}
++%if %{with lz4}
+ %if 0%{?suse_version}
+ BuildRequires: liblz4-devel
+ %else
+ BuildRequires: lz4-devel
+ %endif
+ %endif
+-%if %{defined buildcompresslzo2}
++%if %{with lzo2}
+ BuildRequires: lzo-devel
+ %endif
+-%if %{defined buildcompresslzma}
++%if %{with lzma}
+ BuildRequires: xz-devel
+ %endif
+-%if %{defined buildcompressbzip2}
++%if %{with bzip2}
+ %if 0%{?suse_version}
+ BuildRequires: libbz2-devel
+ %else
+ BuildRequires: bzip2-devel
+ %endif
+ %endif
+-%if %{defined buildcompresszstd}
++%if %{with zstd}
+ BuildRequires: libzstd-devel
+ %endif
+-%if %{defined buildkronosnetd}
++%if %{with kronosnetd}
+ BuildRequires: pam-devel
+ %endif
+-%if %{defined buildlibnozzle}
++%if %{with libnozzle}
+ BuildRequires: libnl3-devel
+ %endif
+-%if %{defined buildautogen}
+-BuildRequires: autoconf
+-BuildRequires: automake
+-BuildRequires: libtool
++%if %{with runautogen}
++BuildRequires: autoconf automake libtool
+ %endif
+ 
+ %prep
+@@ -167,66 +121,70 @@ BuildRequires: libtool
+ %endif
+ 
+ %{configure} \
+-%if %{defined installtestsuite}
++%if %{with installtests}
+ 	--enable-install-tests \
+ %else
+ 	--disable-install-tests \
+ %endif
+-%if %{defined buildmanpages}
++%if %{with buildman}
+ 	--enable-man \
+ %else
+ 	--disable-man \
+ %endif
+-%if %{defined buildsctp}
++%if %{with sctp}
+ 	--enable-libknet-sctp \
+ %else
+ 	--disable-libknet-sctp \
+ %endif
+-%if %{defined buildcryptonss}
++%if %{with nss}
+ 	--enable-crypto-nss \
+ %else
+ 	--disable-crypto-nss \
+ %endif
+-%if %{defined buildcryptoopenssl}
++%if %{with openssl}
+ 	--enable-crypto-openssl \
+ %else
+ 	--disable-crypto-openssl \
+ %endif
+-%if %{defined buildcompresszlib}
++%if %{with zlib}
+ 	--enable-compress-zlib \
+ %else
+ 	--disable-compress-zlib \
+ %endif
+-%if %{defined buildcompresslz4}
++%if %{with lz4}
+ 	--enable-compress-lz4 \
+ %else
+ 	--disable-compress-lz4 \
+ %endif
+-%if %{defined buildcompresslzo2}
++%if %{with lzo2}
+ 	--enable-compress-lzo2 \
+ %else
+ 	--disable-compress-lzo2 \
+ %endif
+-%if %{defined buildcompresslzma}
++%if %{with lzma}
+ 	--enable-compress-lzma \
+ %else
+ 	--disable-compress-lzma \
+ %endif
+-%if %{defined buildcompressbzip2}
++%if %{with bzip2}
+ 	--enable-compress-bzip2 \
+ %else
+ 	--disable-compress-bzip2 \
+ %endif
+-%if %{defined buildcompresszstd}
++%if %{with zstd}
+ 	--enable-compress-zstd \
+ %else
+ 	--disable-compress-zstd \
+ %endif
+-%if %{defined buildkronosnetd}
++%if %{with kronosnetd}
+ 	--enable-kronosnetd \
++%else
++	--disable-kronosnetd \
+ %endif
+-%if %{defined buildlibnozzle}
++%if %{with libnozzle}
+ 	--enable-libnozzle \
++%else
++	--disable-libnozzle \
+ %endif
+ 	--with-initdefaultdir=%{_sysconfdir}/sysconfig/ \
+ %if %{defined _unitdir}
+@@ -266,7 +224,7 @@ rm -rf %{buildroot}
+ %description
+ kronosnet source
+ 
+-%if %{defined buildkronosnetd}
++%if %{with kronosnetd}
+ ## Runtime and subpackages section
+ %package -n kronosnetd
+ Group: System Environment/Base
+@@ -341,7 +299,7 @@ fi
+ %{_mandir}/man8/*
+ %endif
+ 
+-%if %{defined buildlibnozzle}
++%if %{with libnozzle}
+ %package -n libnozzle1
+ Group: System Environment/Libraries
+ Summary: Simple userland wrapper around kernel tap devices
+@@ -377,8 +335,10 @@ Requires: pkgconfig
+ %{_libdir}/libnozzle.so
+ %{_includedir}/libnozzle.h
+ %{_libdir}/pkgconfig/libnozzle.pc
++%if %{with buildman}
+ %{_mandir}/man3/nozzle*.3.gz
+ %endif
++%endif
+ 
+ %package -n libknet1
+ Group: System Environment/Libraries
+@@ -416,11 +376,11 @@ Requires: pkgconfig
+ %{_libdir}/libknet.so
+ %{_includedir}/libknet.h
+ %{_libdir}/pkgconfig/libknet.pc
+-%if %{defined buildmanpages}
++%if %{with buildman}
+ %{_mandir}/man3/knet*.3.gz
+ %endif
+ 
+-%if %{defined buildcryptonss}
++%if %{with nss}
+ %package -n libknet1-crypto-nss-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 nss support
+@@ -434,7 +394,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %{_libdir}/kronosnet/crypto_nss.so
+ %endif
+ 
+-%if %{defined buildcryptoopenssl}
++%if %{with openssl}
+ %package -n libknet1-crypto-openssl-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 openssl support
+@@ -448,7 +408,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %{_libdir}/kronosnet/crypto_openssl.so
+ %endif
+ 
+-%if %{defined buildcompresszlib}
++%if %{with zlib}
+ %package -n libknet1-compress-zlib-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 zlib support
+@@ -461,7 +421,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_zlib.so
+ %endif
+-%if %{defined buildcompresslz4}
++%if %{with lz4}
+ %package -n libknet1-compress-lz4-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 lz4 and lz4hc support
+@@ -476,7 +436,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %{_libdir}/kronosnet/compress_lz4hc.so
+ %endif
+ 
+-%if %{defined buildcompresslzo2}
++%if %{with lzo2}
+ %package -n libknet1-compress-lzo2-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 lzo2 support
+@@ -490,7 +450,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %{_libdir}/kronosnet/compress_lzo2.so
+ %endif
+ 
+-%if %{defined buildcompresslzma}
++%if %{with lzma}
+ %package -n libknet1-compress-lzma-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 lzma support
+@@ -504,7 +464,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %{_libdir}/kronosnet/compress_lzma.so
+ %endif
+ 
+-%if %{defined buildcompressbzip2}
++%if %{with bzip2}
+ %package -n libknet1-compress-bzip2-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 bzip2 support
+@@ -518,7 +478,7 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %{_libdir}/kronosnet/compress_bzip2.so
+ %endif
+ 
+-%if %{defined buildcompresszstd}
++%if %{with zstd}
+ %package -n libknet1-compress-zstd-plugin
+ Group: System Environment/Libraries
+ Summary: libknet1 zstd support
+@@ -535,10 +495,10 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %package -n libknet1-crypto-plugins-all
+ Group: System Environment/Libraries
+ Summary: libknet1 crypto plugins meta package
+-%if %{defined buildcryptonss}
++%if %{with nss}
+ Requires: libknet1-crypto-nss-plugin%{_isa} = %{version}-%{release}
+ %endif
+-%if %{defined buildcryptoopenssl}
++%if %{with openssl}
+ Requires: libknet1-crypto-openssl-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
+@@ -550,22 +510,22 @@ Requires: libknet1-crypto-openssl-plugin%{_isa} = %{version}-%{release}
+ %package -n libknet1-compress-plugins-all
+ Group: System Environment/Libraries
+ Summary: libknet1 compress plugins meta package
+-%if %{defined buildcompresszlib}
++%if %{with zlib}
+ Requires: libknet1-compress-zlib-plugin%{_isa} = %{version}-%{release}
+ %endif
+-%if %{defined buildcompresslz4}
++%if %{with lz4}
+ Requires: libknet1-compress-lz4-plugin%{_isa} = %{version}-%{release}
+ %endif
+-%if %{defined buildcompresslzo2}
++%if %{with lzo2}
+ Requires: libknet1-compress-lzo2-plugin%{_isa} = %{version}-%{release}
+ %endif
+-%if %{defined buildcompresslzma}
++%if %{with lzma}
+ Requires: libknet1-compress-lzma-plugin%{_isa} = %{version}-%{release}
+ %endif
+-%if %{defined buildcompressbzip2}
++%if %{with bzip2}
+ Requires: libknet1-compress-bzip2-plugin%{_isa} = %{version}-%{release}
+ %endif
+-%if %{defined buildcompresszstd}
++%if %{with zstd}
+ Requires: libknet1-compress-zstd-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0249-spec-reconciliate-fedora-spec-file-into-upstream-spe.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0249-spec-reconciliate-fedora-spec-file-into-upstream-spe.patch
new file mode 100644
index 000000000..26b693f23
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0249-spec-reconciliate-fedora-spec-file-into-upstream-spe.patch
@@ -0,0 +1,375 @@ 
+From b80d8874d5dd05f7abae5aa45c8afd50cecea7b6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 13 May 2019 06:02:06 +0200
+Subject: [PATCH] [spec] reconciliate fedora spec file into upstream spec file
+ (part 1)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 130 +++++++++++++++++++---------------------------
+ 1 file changed, 52 insertions(+), 78 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index b5632ae3..a6c87a0d 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -45,14 +45,9 @@ Summary: Multipoint-to-Multipoint VPN daemon
+ Version: @version@
+ Release: 1%{?numcomm:.%{numcomm}}%{?alphatag:.%{alphatag}}%{?dirty:.%{dirty}}%{?dist}
+ License: GPLv2+ and LGPLv2+
+-Group: System Environment/Base
+ URL: https://kronosnet.org
+ Source0: https://kronosnet.org/releases/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz
+ 
+-## Setup/build bits
+-
+-BuildRoot: %(mktemp -ud %{_tmppath}/%{name}-%{version}-%{release}-XXXXXX)
+-
+ # Build dependencies
+ BuildRequires: gcc
+ # required to build man pages
+@@ -117,7 +112,7 @@ BuildRequires: autoconf automake libtool
+ 
+ %build
+ %if %{with runautogen}
+-    ./autogen.sh
++./autogen.sh
+ %endif
+ 
+ %{configure} \
+@@ -217,18 +212,15 @@ find %{buildroot} -name "*.service" -exec rm {} \;
+ # remove docs
+ rm -rf %{buildroot}/usr/share/doc/kronosnet
+ 
+-%clean
+-rm -rf %{buildroot}
+-
+ # main empty package
+ %description
+-kronosnet source
++ The kronosnet source
+ 
+ %if %{with kronosnetd}
+ ## Runtime and subpackages section
+ %package -n kronosnetd
+-Group: System Environment/Base
+ Summary: Multipoint-to-Multipoint VPN daemon
++License: GPLv2+
+ %if %{defined _unitdir}
+ # Needed for systemd unit
+ Requires(post):   systemd-sysv
+@@ -239,8 +231,8 @@ Requires(postun): systemd-units
+ Requires(post): chkconfig
+ Requires(preun): chkconfig, initscripts
+ %endif
+-Requires(post): shadow-utils
+-Requires(preun): shadow-utils
++Requires(post):   shadow-utils
++Requires(preun):  shadow-utils
+ Requires: pam, /etc/pam.d/passwd
+ 
+ %description -n kronosnetd
+@@ -263,7 +255,7 @@ Requires: pam, /etc/pam.d/passwd
+ %else
+ /sbin/chkconfig --add kronosnetd
+ %endif
+-/usr/sbin/groupadd --force --system @defaultadmgroup@
++getent group @defaultadmgroup@ >/dev/null || groupadd --force --system @defaultadmgroup@
+ 
+ %preun -n kronosnetd
+ %if %{defined _unitdir}
+@@ -283,8 +275,7 @@ fi
+ %endif
+ 
+ %files -n kronosnetd
+-%defattr(-,root,root,-)
+-%doc COPYING.* COPYRIGHT 
++%license COPYING.* COPYRIGHT
+ %dir %{_sysconfdir}/kronosnet
+ %dir %{_sysconfdir}/kronosnet/*
+ %config(noreplace) %{_sysconfdir}/sysconfig/kronosnetd
+@@ -301,8 +292,8 @@ fi
+ 
+ %if %{with libnozzle}
+ %package -n libnozzle1
+-Group: System Environment/Libraries
+ Summary: Simple userland wrapper around kernel tap devices
++License: LGPLv2+
+ 
+ %description -n libnozzle1
+  This is an over-engineered commodity library to manage a pool
+@@ -310,17 +301,14 @@ Summary: Simple userland wrapper around kernel tap devices
+  pre-up.d/up.d/down.d/post-down.d infrastructure.
+ 
+ %files -n libnozzle1
+-%defattr(-,root,root,-)
+-%doc COPYING.* COPYRIGHT
++%license COPYING.* COPYRIGHT
+ %{_libdir}/libnozzle.so.*
+ 
+-%post -n libnozzle1 -p /sbin/ldconfig
+-
+-%postun -n libnozzle1 -p /sbin/ldconfig
++%ldconfig_scriptlets -n libnozzle1
+ 
+ %package -n libnozzle1-devel
+-Group: Development/Libraries
+ Summary: Simple userland wrapper around kernel tap devices (developer files)
++License: LGPLv2+
+ Requires: libnozzle1%{_isa} = %{version}-%{release}
+ Requires: pkgconfig
+ 
+@@ -330,8 +318,7 @@ Requires: pkgconfig
+  pre-up.d/up.d/down.d/post-down.d infrastructure.
+ 
+ %files -n libnozzle1-devel
+-%defattr(-,root,root,-)
+-%doc COPYING.* COPYRIGHT
++%license COPYING.* COPYRIGHT
+ %{_libdir}/libnozzle.so
+ %{_includedir}/libnozzle.h
+ %{_libdir}/pkgconfig/libnozzle.pc
+@@ -341,8 +328,8 @@ Requires: pkgconfig
+ %endif
+ 
+ %package -n libknet1
+-Group: System Environment/Libraries
+ Summary: Kronosnet core switching implementation
++License: LGPLv2+
+ 
+ %description -n libknet1
+  The whole kronosnet core is implemented in this library.
+@@ -350,18 +337,14 @@ Summary: Kronosnet core switching implementation
+  information.
+ 
+ %files -n libknet1
+-%defattr(-,root,root,-)
+-%doc COPYING.* COPYRIGHT
++%license COPYING.* COPYRIGHT
+ %{_libdir}/libknet.so.*
+ %dir %{_libdir}/kronosnet
+-
+-%post -n libknet1 -p /sbin/ldconfig
+-
+-%postun -n libknet1 -p /sbin/ldconfig
++%ldconfig_scriptlets -n libknet1
+ 
+ %package -n libknet1-devel
+-Group: Development/Libraries
+ Summary: Kronosnet core switching implementation (developer files)
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ Requires: pkgconfig
+ 
+@@ -371,8 +354,7 @@ Requires: pkgconfig
+  information. 
+ 
+ %files -n libknet1-devel
+-%defattr(-,root,root,-)
+-%doc COPYING.* COPYRIGHT
++%license COPYING.* COPYRIGHT
+ %{_libdir}/libknet.so
+ %{_includedir}/libknet.h
+ %{_libdir}/pkgconfig/libknet.pc
+@@ -382,119 +364,112 @@ Requires: pkgconfig
+ 
+ %if %{with nss}
+ %package -n libknet1-crypto-nss-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 nss support
++Summary: Provides libknet1 nss support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-crypto-nss-plugin
+- NSS crypto support for libknet1.
++ Provides NSS crypto support for libknet1.
+ 
+ %files -n libknet1-crypto-nss-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/crypto_nss.so
+ %endif
+ 
+ %if %{with openssl}
+ %package -n libknet1-crypto-openssl-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 openssl support
++Summary: Provides libknet1 openssl support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-crypto-openssl-plugin
+- OpenSSL crypto support for libknet1.
++ Provides OpenSSL crypto support for libknet1.
+ 
+ %files -n libknet1-crypto-openssl-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/crypto_openssl.so
+ %endif
+ 
+ %if %{with zlib}
+ %package -n libknet1-compress-zlib-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 zlib support
++Summary: Provides libknet1 zlib support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-zlib-plugin
+- zlib compression support for libknet1.
++ Provides zlib compression support for libknet1.
+ 
+ %files -n libknet1-compress-zlib-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_zlib.so
+ %endif
++
+ %if %{with lz4}
+ %package -n libknet1-compress-lz4-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 lz4 and lz4hc support
++Summary: Provides libknet1 lz4 and lz4hc support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-lz4-plugin
+- lz4 and lz4hc compression support for libknet1.
++ Provides lz4 and lz4hc compression support for libknet1.
+ 
+ %files -n libknet1-compress-lz4-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_lz4.so
+ %{_libdir}/kronosnet/compress_lz4hc.so
+ %endif
+ 
+ %if %{with lzo2}
+ %package -n libknet1-compress-lzo2-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 lzo2 support
++Summary: Provides libknet1 lzo2 support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-lzo2-plugin
+- lzo2 compression support for libknet1.
++ Provides lzo2 compression support for libknet1.
+ 
+ %files -n libknet1-compress-lzo2-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_lzo2.so
+ %endif
+ 
+ %if %{with lzma}
+ %package -n libknet1-compress-lzma-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 lzma support
++Summary: Provides libknet1 lzma support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-lzma-plugin
+- lzma compression support for libknet1.
++ Provides lzma compression support for libknet1.
+ 
+ %files -n libknet1-compress-lzma-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_lzma.so
+ %endif
+ 
+ %if %{with bzip2}
+ %package -n libknet1-compress-bzip2-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 bzip2 support
++Summary: Provides libknet1 bzip2 support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-bzip2-plugin
+- bzip2 compression support for libknet1.
++ Provides bzip2 compression support for libknet1.
+ 
+ %files -n libknet1-compress-bzip2-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_bzip2.so
+ %endif
+ 
+ %if %{with zstd}
+ %package -n libknet1-compress-zstd-plugin
+-Group: System Environment/Libraries
+-Summary: libknet1 zstd support
++Summary: Provides libknet1 zstd support
++License: LGPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-compress-zstd-plugin
+- zstd compression support for libknet1.
++ Provides zstd compression support for libknet1.
+ 
+ %files -n libknet1-compress-zstd-plugin
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/compress_zstd.so
+ %endif
+ 
+ %package -n libknet1-crypto-plugins-all
+-Group: System Environment/Libraries
+-Summary: libknet1 crypto plugins meta package
++Summary: Provides libknet1 crypto plugins meta package
++License: LGPLv2+
+ %if %{with nss}
+ Requires: libknet1-crypto-nss-plugin%{_isa} = %{version}-%{release}
+ %endif
+@@ -503,13 +478,13 @@ Requires: libknet1-crypto-openssl-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
+ %description -n libknet1-crypto-plugins-all
+- meta package to install all of libknet1 crypto plugins
++ Provides meta package to install all of libknet1 crypto plugins
+ 
+ %files -n libknet1-crypto-plugins-all
+ 
+ %package -n libknet1-compress-plugins-all
+-Group: System Environment/Libraries
+-Summary: libknet1 compress plugins meta package
++Summary: Provides libknet1 compress plugins meta package
++License: LGPLv2+
+ %if %{with zlib}
+ Requires: libknet1-compress-zlib-plugin%{_isa} = %{version}-%{release}
+ %endif
+@@ -530,32 +505,31 @@ Requires: libknet1-compress-zstd-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
+ %description -n libknet1-compress-plugins-all
+- meta package to install all of libknet1 compress plugins
++ Provides meta package to install all of libknet1 compress plugins
+ 
+ %files -n libknet1-compress-plugins-all
+ 
+ %package -n libknet1-plugins-all
+-Group: System Environment/Libraries
+ Summary: libknet1 plugins meta package
++License: LGPLv2+
+ Requires: libknet1-compress-plugins-all%{_isa} = %{version}-%{release}
+ Requires: libknet1-crypto-plugins-all%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-plugins-all
+- meta package to install all of libknet1 plugins
++ Provides meta package to install all of libknet1 plugins
+ 
+ %files -n libknet1-plugins-all
+ 
+ %if %{with installtests}
+ %package -n kronosnet-tests
+-Group: System Environment/Libraries
+ Summary: kronosnet test suite
++License: GPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
+ %description -n kronosnet-tests
+- this package contains all the libknet and libnozzle test suite
++ This package contains all the libknet and libnozzle test suite.
+ 
+ %files -n kronosnet-tests
+-%defattr(-,root,root,-)
+ %{_libdir}/kronosnet/tests/*
+ %endif
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0250-spec-fix-a-bunch-of-rpmlint-errors.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0250-spec-fix-a-bunch-of-rpmlint-errors.patch
new file mode 100644
index 000000000..8c5e26f01
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0250-spec-fix-a-bunch-of-rpmlint-errors.patch
@@ -0,0 +1,51 @@ 
+From cb6232ad72eafb4ee83480ab30e0f7cbb9e0b675 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 13 May 2019 06:55:36 +0200
+Subject: [PATCH] [spec] fix a bunch of rpmlint errors
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index a6c87a0d..ddc3af0e 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -340,6 +340,7 @@ License: LGPLv2+
+ %license COPYING.* COPYRIGHT
+ %{_libdir}/libknet.so.*
+ %dir %{_libdir}/kronosnet
++
+ %ldconfig_scriptlets -n libknet1
+ 
+ %package -n libknet1-devel
+@@ -505,24 +506,24 @@ Requires: libknet1-compress-zstd-plugin%{_isa} = %{version}-%{release}
+ %endif
+ 
+ %description -n libknet1-compress-plugins-all
+- Provides meta package to install all of libknet1 compress plugins
++ Meta package to install all of libknet1 compress plugins
+ 
+ %files -n libknet1-compress-plugins-all
+ 
+ %package -n libknet1-plugins-all
+-Summary: libknet1 plugins meta package
++Summary: Provides libknet1 plugins meta package
+ License: LGPLv2+
+ Requires: libknet1-compress-plugins-all%{_isa} = %{version}-%{release}
+ Requires: libknet1-crypto-plugins-all%{_isa} = %{version}-%{release}
+ 
+ %description -n libknet1-plugins-all
+- Provides meta package to install all of libknet1 plugins
++ Meta package to install all of libknet1 plugins
+ 
+ %files -n libknet1-plugins-all
+ 
+ %if %{with installtests}
+ %package -n kronosnet-tests
+-Summary: kronosnet test suite
++Summary: Provides kronosnet test suite
+ License: GPLv2+
+ Requires: libknet1%{_isa} = %{version}-%{release}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0251-spec-drop-support-for-init-scripts.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0251-spec-drop-support-for-init-scripts.patch
new file mode 100644
index 000000000..d88bfa2fb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0251-spec-drop-support-for-init-scripts.patch
@@ -0,0 +1,108 @@ 
+From 4af45b41bf58fd0f8d25e5aef5fd334254ae2587 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 14 May 2019 05:53:12 +0200
+Subject: [PATCH] [spec] drop support for init scripts
+
+no rpm distros left that support old fashion init scripts
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 46 ++--------------------------------------------
+ 1 file changed, 2 insertions(+), 44 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index ddc3af0e..8c601258 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -182,11 +182,7 @@ BuildRequires: autoconf automake libtool
+ 	--disable-libnozzle \
+ %endif
+ 	--with-initdefaultdir=%{_sysconfdir}/sysconfig/ \
+-%if %{defined _unitdir}
+ 	--with-systemddir=%{_unitdir}
+-%else
+-	--with-initddir=%{_sysconfdir}/rc.d/init.d/
+-%endif
+ 
+ make %{_smp_mflags}
+ 
+@@ -200,14 +196,8 @@ find %{buildroot} -name "*.a" -exec rm {} \;
+ # remove libtools leftovers
+ find %{buildroot} -name "*.la" -exec rm {} \;
+ 
+-# handle systemd vs init script
+-%if %{defined _unitdir}
+ # remove init scripts
+ rm -rf %{buildroot}/etc/init.d
+-%else
+-# remove systemd specific bits
+-find %{buildroot} -name "*.service" -exec rm {} \;
+-%endif
+ 
+ # remove docs
+ rm -rf %{buildroot}/usr/share/doc/kronosnet
+@@ -221,16 +211,10 @@ rm -rf %{buildroot}/usr/share/doc/kronosnet
+ %package -n kronosnetd
+ Summary: Multipoint-to-Multipoint VPN daemon
+ License: GPLv2+
+-%if %{defined _unitdir}
+-# Needed for systemd unit
+ Requires(post):   systemd-sysv
+ Requires(post):   systemd-units
+ Requires(preun):  systemd-units
+ Requires(postun): systemd-units
+-%else
+-Requires(post): chkconfig
+-Requires(preun): chkconfig, initscripts
+-%endif
+ Requires(post):   shadow-utils
+ Requires(preun):  shadow-utils
+ Requires: pam, /etc/pam.d/passwd
+@@ -246,33 +230,11 @@ Requires: pam, /etc/pam.d/passwd
+  or service disruption.
+ 
+ %post -n kronosnetd
+-%if %{defined _unitdir}
+- %if 0%{?systemd_post:1}
+-  %systemd_post kronosnetd.service
+- %else
+-  /bin/systemctl daemon-reload >/dev/null 2>&1 || :
+- %endif
+-%else
+-/sbin/chkconfig --add kronosnetd
+-%endif
++%systemd_post kronosnetd.service
+ getent group @defaultadmgroup@ >/dev/null || groupadd --force --system @defaultadmgroup@
+ 
+ %preun -n kronosnetd
+-%if %{defined _unitdir}
+- %if 0%{?systemd_preun:1}
+-  %systemd_preun kronosnetd.service
+- %else
+-if [ "$1" -eq 0 ]; then
+-	/bin/systemctl --no-reload disable kronosnetd.service
+-	/bin/systemctl stop kronosnetd.service >/dev/null 2>&1
+-fi
+-%endif
+-%else
+-if [ "$1" = 0 ]; then
+-	/sbin/service kronosnetd stop >/dev/null 2>&1
+-	/sbin/chkconfig --del kronosnetd
+-fi
+-%endif
++%systemd_preun kronosnetd.service
+ 
+ %files -n kronosnetd
+ %license COPYING.* COPYRIGHT
+@@ -281,11 +243,7 @@ fi
+ %config(noreplace) %{_sysconfdir}/sysconfig/kronosnetd
+ %config(noreplace) %{_sysconfdir}/pam.d/kronosnetd
+ %config(noreplace) %{_sysconfdir}/logrotate.d/kronosnetd
+-%if %{defined _unitdir}
+ %{_unitdir}/kronosnetd.service
+-%else
+-%config(noreplace) %{_sysconfdir}/rc.d/init.d/kronosnetd
+-%endif
+ %{_sbindir}/*
+ %{_mandir}/man8/*
+ %endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0252-spec-use-ldconfig_scriptlets-only-when-defined.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0252-spec-use-ldconfig_scriptlets-only-when-defined.patch
new file mode 100644
index 000000000..ac9df48cd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0252-spec-use-ldconfig_scriptlets-only-when-defined.patch
@@ -0,0 +1,40 @@ 
+From a2214c0a90f3443f75c17dca1cc23ab8d6f69815 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 14 May 2019 06:57:36 +0200
+Subject: [PATCH] [spec] use ldconfig_scriptlets only when defined
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 8c601258..094090b0 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -262,7 +262,12 @@ License: LGPLv2+
+ %license COPYING.* COPYRIGHT
+ %{_libdir}/libnozzle.so.*
+ 
++%if 0%{?ldconfig_scriptlets}
+ %ldconfig_scriptlets -n libnozzle1
++%else
++%post -n libnozzle1 -p /sbin/ldconfig
++%postun -n libnozzle1 -p /sbin/ldconfig
++%endif
+ 
+ %package -n libnozzle1-devel
+ Summary: Simple userland wrapper around kernel tap devices (developer files)
+@@ -299,7 +304,12 @@ License: LGPLv2+
+ %{_libdir}/libknet.so.*
+ %dir %{_libdir}/kronosnet
+ 
++%if 0%{?ldconfig_scriptlets}
+ %ldconfig_scriptlets -n libknet1
++%else
++%post -n libknet1 -p /sbin/ldconfig
++%postun -n libknet1 -p /sbin/ldconfig
++%endif
+ 
+ %package -n libknet1-devel
+ Summary: Kronosnet core switching implementation (developer files)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0253-misc-some-coverity-fixes.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0253-misc-some-coverity-fixes.patch
new file mode 100644
index 000000000..7b0101179
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0253-misc-some-coverity-fixes.patch
@@ -0,0 +1,223 @@ 
+From b13365bc6f53516d9bfb5556087a17a6f7723e48 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 17 May 2019 08:44:08 +0100
+Subject: [PATCH] misc: some coverity fixes
+
+In rough order of seriousness:
+
+1. Fix clock_gettime() in pmtud so that it's always called, as
+   variable 'clock_now' is always read.
+2. Allow space for trailing NUL in libnozzle device names
+3. Fix api_nozzle_run_updown_test so it can run out of the build tree
+4. Disallow a 0 length prefix in libnozzle
+5. Fix potential use of NULL pointer on doxyxml
+6. Free 'name' in doxyxml as it's *not* in the map any more
+7. Fix dead code in libknet API functions left by code changes
+---
+ libknet/handle.c                        | 13 ++++---------
+ libknet/host.c                          |  5 ++---
+ libknet/threads_pmtud.c                 | 10 +++++-----
+ libnozzle/internals.c                   |  2 +-
+ libnozzle/libnozzle.c                   |  3 ++-
+ libnozzle/tests/api_nozzle_run_updown.c |  9 +++++++--
+ man/doxyxml.c                           | 20 ++++++++++----------
+ 7 files changed, 31 insertions(+), 31 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 0a2f75ae..268d6106 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -785,7 +785,7 @@ int knet_handle_enable_sock_notify(knet_handle_t knet_h,
+ 						int error,
+ 						int errorno))
+ {
+-	int savederrno = 0, err = 0;
++	int savederrno = 0;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -811,8 +811,7 @@ int knet_handle_enable_sock_notify(knet_handle_t knet_h,
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
+-	errno = err ? savederrno : 0;
+-	return err;
++	return 0;
+ }
+ 
+ int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel)
+@@ -1576,7 +1575,6 @@ out_unlock:
+ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats, size_t struct_size)
+ {
+ 	int savederrno = 0;
+-	int err = 0;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -1616,14 +1614,12 @@ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats,
+ 	stats->size = sizeof(struct knet_handle_stats);
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
++	return 0;
+ }
+ 
+ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+ {
+ 	int savederrno = 0;
+-	int err = 0;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -1651,7 +1647,6 @@ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+ 	}
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
++	return 0;
+ }
+ 
+diff --git a/libknet/host.c b/libknet/host.c
+index 480db733..66826c1a 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -331,7 +331,7 @@ int knet_host_get_id_by_host_name(knet_handle_t knet_h, const char *name,
+ int knet_host_get_host_list(knet_handle_t knet_h,
+ 			    knet_node_id_t *host_ids, size_t *host_ids_entries)
+ {
+-	int savederrno = 0, err = 0;
++	int savederrno = 0;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -355,8 +355,7 @@ int knet_host_get_host_list(knet_handle_t knet_h,
+ 	*host_ids_entries = knet_h->host_ids_entries;
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
++	return 0;
+ }
+ 
+ int knet_host_set_policy(knet_handle_t knet_h, knet_node_id_t host_id,
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 00505574..c5a2b276 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -380,14 +380,14 @@ static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host,
+ 	struct timespec clock_now;
+ 	unsigned long long diff_pmtud, interval;
+ 
++	if (clock_gettime(CLOCK_MONOTONIC, &clock_now) != 0) {
++		log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get monotonic clock");
++		return 0;
++	}
++
+ 	if (!force_run) {
+ 		interval = knet_h->pmtud_interval * 1000000000llu; /* nanoseconds */
+ 
+-		if (clock_gettime(CLOCK_MONOTONIC, &clock_now) != 0) {
+-			log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get monotonic clock");
+-			return 0;
+-		}
+-
+ 		timespec_diff(dst_link->pmtud_last, clock_now, &diff_pmtud);
+ 
+ 		if (diff_pmtud < interval) {
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 6e683463..f056e3bf 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -144,7 +144,7 @@ char *generate_v4_broadcast(const char *ipaddr, const char *prefix)
+ 
+ 	prefix_len = atoi(prefix);
+ 
+-	if ((prefix_len > 32) || (prefix_len < 0))
++	if ((prefix_len > 32) || (prefix_len <= 0))
+ 		return NULL;
+ 
+ 	if (inet_pton(AF_INET, ipaddr, &address) <= 0)
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 4e5a2d40..b6e95666 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -405,7 +405,8 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		return NULL;
+ 	}
+ 
+-	if (strlen(devname) > IFNAMSIZ) {
++	/* Need to allow space for trailing NUL */
++	if (strlen(devname) >= IFNAMSIZ) {
+ 		errno = E2BIG;
+ 		return NULL;
+ 	}
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index a078ad7c..c80216a2 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -29,16 +29,21 @@ static int test(void)
+ 	nozzle_t nozzle = NULL;
+ 	char *error_string = NULL;
+ 	char *tmpdir = NULL;
+-	char tmpdirsrc[PATH_MAX];
++	char tmpdirsrc[PATH_MAX*2];
+ 	char tmpstr[PATH_MAX*2];
+ 	char srcfile[PATH_MAX];
+ 	char dstfile[PATH_MAX];
++	char current_dir[PATH_MAX];
+ 
+ 	/*
+ 	 * create a tmp dir for storing up/down scripts.
+ 	 * we cannot create symlinks src dir
+ 	 */
+-	strcpy(tmpdirsrc, ABSBUILDDIR "/nozzle_test_XXXXXX");
++	if (getcwd(current_dir, sizeof(current_dir)) == NULL) {
++		printf("Unable to get current working directory: %s\n", strerror(errno));
++		return -1;
++	}
++	snprintf(tmpdirsrc, sizeof(tmpdirsrc)-1, "%s/nozzle_test_XXXXXX", current_dir);
+ 
+ 	tmpdir = mkdtemp(tmpdirsrc);
+ 	if (!tmpdir) {
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index b623711d..7d9a60c7 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -695,17 +695,17 @@ static void collect_enums(xmlNode *cur_node, void *arg)
+ 				}
+ 			}
+ 
+-			si = malloc(sizeof(struct struct_info));
+-			if (si) {
+-				si->kind = STRUCTINFO_ENUM;
+-				qb_list_init(&si->params_list);
+-				si->structname = strdup(name);
+-				traverse_node(cur_node, "enumvalue", read_struct, si);
+-				qb_map_put(structures_map, refid, si);
++			if (name) {
++				si = malloc(sizeof(struct struct_info));
++				if (si) {
++					si->kind = STRUCTINFO_ENUM;
++					qb_list_init(&si->params_list);
++					si->structname = strdup(name);
++					traverse_node(cur_node, "enumvalue", read_struct, si);
++					qb_map_put(structures_map, refid, si);
++				}
+ 			}
+-
+ 		}
+-
+ 	}
+ }
+ 
+@@ -786,7 +786,7 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		free(kind);
+ 		free(def);
+ 		free(args);
+-//		free(name); /* don't free, it's in the map */
++		free(name);
+ 	}
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0254-misc-Fix-more-covscan-warnings.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0254-misc-Fix-more-covscan-warnings.patch
new file mode 100644
index 000000000..3d9b6996e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0254-misc-Fix-more-covscan-warnings.patch
@@ -0,0 +1,191 @@ 
+From bd850d501c2f95d0e848864554bcbf575184dbee Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 24 May 2019 10:09:47 +0100
+Subject: [PATCH] misc: Fix more covscan warnings
+
+The only serious bug here is in transport_udp.c
+(see bottom of patch), the rest are mostly detail.
+
+covscan still reports a lot of errors against doxyxml, most of
+which are because it doesn't understand the libqb hashtables.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/common.c           | 2 +-
+ libknet/compress.c         | 6 +++---
+ libknet/crypto.c           | 1 -
+ libknet/crypto_nss.c       | 2 +-
+ libknet/handle.c           | 1 -
+ libknet/threads_pmtud.c    | 1 -
+ libknet/threads_rx.c       | 1 -
+ libknet/threads_tx.c       | 1 -
+ libknet/transport_common.c | 4 ++--
+ libknet/transport_sctp.c   | 2 +-
+ libknet/transport_udp.c    | 3 ++-
+ 11 files changed, 10 insertions(+), 14 deletions(-)
+
+diff --git a/libknet/common.c b/libknet/common.c
+index c908e23f..be46f23e 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -101,7 +101,7 @@ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags
+ 		}
+ 
+ 		if (S_ISLNK(sb.st_mode)) {
+-			if (readlink(path, link, sizeof(link)) < 0) {
++			if (readlink(path, link, sizeof(link)-1) < 0) {
+ 				log_debug(knet_h, KNET_SUB_COMMON, "Unable to readlink %s: %s", path, strerror(errno));
+ 				goto out;
+ 			}
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 7eab454b..864828f3 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -359,11 +359,11 @@ void compress_fini(
+ 	}
+ 
+ 	while (compress_modules_cmds[idx].model_name != NULL) {
+-		if ((compress_modules_cmds[idx].built_in == 1) &&
++		if ((idx < KNET_MAX_COMPRESS_METHODS) && /* check idx first so we don't read bad data */
++		    (compress_modules_cmds[idx].built_in == 1) &&
+ 		    (compress_modules_cmds[idx].loaded == 1) &&
+ 		    (compress_modules_cmds[idx].model_id > 0) &&
+-		    (knet_h->compress_int_data[idx] != NULL) &&
+-		    (idx < KNET_MAX_COMPRESS_METHODS)) {
++		    (knet_h->compress_int_data[idx] != NULL)) {
+ 			if ((all) || (compress_modules_cmds[idx].model_id == knet_h->compress_model)) {
+ 				if (compress_modules_cmds[idx].ops->fini != NULL) {
+ 					compress_modules_cmds[idx].ops->fini(knet_h, idx);
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 419f9ccc..41d67c95 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -129,7 +129,6 @@ int crypto_init(
+ 
+ 	if (!knet_h->crypto_instance) {
+ 		log_err(knet_h, KNET_SUB_CRYPTO, "Unable to allocate memory for crypto instance");
+-		pthread_rwlock_unlock(&shlib_rwlock);
+ 		savederrno = ENOMEM;
+ 		goto out_err;
+ 	}
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index a17ff628..640b560f 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -761,7 +761,7 @@ static int nsscrypto_init(
+ 	knet_h->crypto_instance->model_instance = malloc(sizeof(struct nsscrypto_instance));
+ 	if (!knet_h->crypto_instance->model_instance) {
+ 		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to allocate memory for nss model instance");
+-		savederrno = ENOMEM;
++		errno = ENOMEM;
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 268d6106..fd26beab 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1649,4 +1649,3 @@ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	return 0;
+ }
+-
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index c5a2b276..b4ee632d 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -44,7 +44,6 @@ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_
+ 
+ 	mutex_retry_limit = 0;
+ 	failsafe = 0;
+-	pad_len = 0;
+ 
+ 	dst_link->last_bad_mtu = 0;
+ 
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index ae39b38e..626cbc4c 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -499,7 +499,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		} else { /* HOSTINFO */
+ 			knet_hostinfo = (struct knet_hostinfo *)inbuf->khp_data_userdata;
+ 			if (knet_hostinfo->khi_bcast == KNET_HOSTINFO_UCAST) {
+-				bcast = 0;
+ 				knet_hostinfo->khi_dst_node_id = ntohs(knet_hostinfo->khi_dst_node_id);
+ 			}
+ 			if (!_seq_num_lookup(src_host, inbuf->khp_data_seq_num, 0, 0)) {
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index e987eb13..80969067 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -42,7 +42,6 @@ static int _dispatch_to_links(knet_handle_t knet_h, struct knet_host *dst_host,
+ 	struct knet_link *cur_link;
+ 
+ 	for (link_idx = 0; link_idx < dst_host->active_link_entries; link_idx++) {
+-		sent_msgs = 0;
+ 		prev_sent = 0;
+ 		progress = 1;
+ 
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 3c3c439a..fe40ad88 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -405,7 +405,7 @@ int _is_valid_fd(knet_handle_t knet_h, int sockfd)
+ 		return -1;
+ 	}
+ 
+-	if (sockfd > KNET_MAX_FDS) {
++	if (sockfd >= KNET_MAX_FDS) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+@@ -430,7 +430,7 @@ int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t
+ 		return -1;
+ 	}
+ 
+-	if (sockfd > KNET_MAX_FDS) {
++	if (sockfd >= KNET_MAX_FDS) {
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index bdfc98d1..2c1cdcc9 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -733,7 +733,6 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 	if (knet_h->use_access_lists) {
+ 		if (!check_validate(knet_h, listen_sock, KNET_TRANSPORT_SCTP, &ss)) {
+ 			savederrno = EINVAL;
+-			err = -1;
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Connection rejected from %s/%s", addr_str, port_str);
+ 			close(new_fd);
+ 			errno = savederrno;
+@@ -871,6 +870,7 @@ static void _handle_listen_sctp_errors(knet_handle_t knet_h)
+ 			info->accepted_socks[i] = -1;
+ 			free(accept_info);
+ 			close(sockfd);
++			break; /* Keeps covscan happy */
+ 		}
+ 	}
+ }
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index e243a913..3fd69ee4 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -71,6 +71,7 @@ int udp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_lin
+ 		err = -1;
+ 		goto exit_error;
+ 	}
++	memset(info, 0, sizeof(udp_link_info_t));
+ 
+ 	sock = socket(kn_link->src_addr.ss_family, SOCK_DGRAM, 0);
+ 	if (sock < 0) {
+@@ -363,7 +364,7 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 						case SO_EE_ORIGIN_ICMP:  /* ICMP */
+ 						case SO_EE_ORIGIN_ICMP6: /* ICMP6 */
+ 							origin = (struct sockaddr_storage *)(void *)SO_EE_OFFENDER(sock_err);
+-							if (knet_addrtostr(origin, sizeof(origin),
++							if (knet_addrtostr(origin, sizeof(*origin),
+ 									   addr_str, KNET_MAX_HOST_LEN,
+ 									   port_str, KNET_MAX_PORT_LEN) < 0) {
+ 								log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from unknown source: %s", strerror(sock_err->ee_errno));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0255-crypto-make-sure-to-clear-all-security-info-on-crypt.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0255-crypto-make-sure-to-clear-all-security-info-on-crypt.patch
new file mode 100644
index 000000000..da94f9861
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0255-crypto-make-sure-to-clear-all-security-info-on-crypt.patch
@@ -0,0 +1,51 @@ 
+From 3cb7e3f9d53dd88ac8b7f72cf670282ad618f04f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 27 May 2019 12:25:55 +0200
+Subject: [PATCH] [crypto] make sure to clear all security info on crypto_fini
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto.c         | 4 ++++
+ libknet/crypto_nss.c     | 1 -
+ libknet/crypto_openssl.c | 1 -
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 41d67c95..5d39048c 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -178,6 +178,10 @@ void crypto_fini(
+ 			crypto_modules_cmds[model].ops->fini(knet_h);
+ 		}
+ 		free(knet_h->crypto_instance);
++		knet_h->sec_header_size = 0;
++		knet_h->sec_block_size = 0;
++		knet_h->sec_hash_size = 0;
++		knet_h->sec_salt_size = 0;
+ 		knet_h->crypto_instance = NULL;
+ 	}
+ 
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 640b560f..cc838275 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -740,7 +740,6 @@ static void nsscrypto_fini(
+ 		}
+ 		free(nsscrypto_instance);
+ 		knet_h->crypto_instance->model_instance = NULL;
+-		knet_h->sec_header_size = 0;
+ 	}
+ 
+ 	return;
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 03d10147..73058ccf 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -485,7 +485,6 @@ static void opensslcrypto_fini(
+ 		}
+ 		free(opensslcrypto_instance);
+ 		knet_h->crypto_instance->model_instance = NULL;
+-		knet_h->sec_header_size = 0;
+ 	}
+ 
+ 	return;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0256-PMTUd-create-common-shared-code-to-trigger-PMTUd-rer.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0256-PMTUd-create-common-shared-code-to-trigger-PMTUd-rer.patch
new file mode 100644
index 000000000..b41a2dcc6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0256-PMTUd-create-common-shared-code-to-trigger-PMTUd-rer.patch
@@ -0,0 +1,79 @@ 
+From 1375cf0f70a78ddbfbdf47227711a1d467a8a8c9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 27 May 2019 12:37:15 +0200
+Subject: [PATCH] [PMTUd] create common/shared code to trigger PMTUd rerun
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_common.c | 20 ++++++++++++++++++++
+ libknet/threads_common.h |  1 +
+ libknet/transport_udp.c  | 17 +----------------
+ 3 files changed, 22 insertions(+), 16 deletions(-)
+
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index b6012a23..61ffd826 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -156,3 +156,23 @@ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status)
+ 
+ 	return 0;
+ }
++
++void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem)
++{
++	/*
++	 * we can only try to take a lock here. This part of the code
++	 * can be invoked by any thread, including PMTUd that is already
++	 * holding a lock at that stage.
++	 * If PMTUd is holding the lock, most likely it is already running
++	 * and we don't need to notify it back.
++	 */
++	if (!pthread_mutex_trylock(&knet_h->pmtud_mutex)) {
++		if (!knet_h->pmtud_running) {
++			if (!knet_h->pmtud_forcerun) {
++				log_debug(knet_h, subsystem, "Notifying PMTUd to rerun");
++				knet_h->pmtud_forcerun = 1;
++			}
++		}
++		pthread_mutex_unlock(&knet_h->pmtud_mutex);
++	}
++}
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 79aaed25..19336ce7 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -45,5 +45,6 @@ int shutdown_in_progress(knet_handle_t knet_h);
+ int get_global_wrlock(knet_handle_t knet_h);
+ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status);
+ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status);
++void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem);
+ 
+ #endif
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 3fd69ee4..232dbcb0 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -340,22 +340,7 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 									pthread_mutex_unlock(&knet_h->kmtu_mutex);
+ 								}
+ 
+-								/*
+-								 * we can only try to take a lock here. This part of the code
+-								 * can be invoked by any thread, including PMTUd that is already
+-								 * holding a lock at that stage.
+-								 * If PMTUd is holding the lock, most likely it is already running
+-								 * and we don't need to notify it back.
+-								 */
+-								if (!pthread_mutex_trylock(&knet_h->pmtud_mutex)) {
+-									if (!knet_h->pmtud_running) {
+-										if (!knet_h->pmtud_forcerun) {
+-											log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Notifying PMTUd to rerun");
+-											knet_h->pmtud_forcerun = 1;
+-										}
+-									}
+-									pthread_mutex_unlock(&knet_h->pmtud_mutex);
+-								}
++								force_pmtud_run(knet_h, KNET_SUB_TRANSP_UDP);
+ 							}
+ 							/*
+ 							 * those errors are way too noisy
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0257-crypto-make-sure-to-trigger-a-PMTUd-rerun-on-each-go.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0257-crypto-make-sure-to-trigger-a-PMTUd-rerun-on-each-go.patch
new file mode 100644
index 000000000..b43c31f12
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0257-crypto-make-sure-to-trigger-a-PMTUd-rerun-on-each-go.patch
@@ -0,0 +1,25 @@ 
+From 161c313309e63e121e888587585c0826b3b39173 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 27 May 2019 12:42:33 +0200
+Subject: [PATCH] [crypto] make sure to trigger a PMTUd rerun on each good
+ crypto config change
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index fd26beab..7009cc34 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1408,6 +1408,9 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 	}
+ 
+ exit_unlock:
++	if (!err) {
++		force_pmtud_run(knet_h, KNET_SUB_CRYPTO);
++	}
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	errno = err ? savederrno : 0;
+ 	return err;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0258-crypto-rework-knet_handle_crypto-external-API-to-be-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0258-crypto-rework-knet_handle_crypto-external-API-to-be-.patch
new file mode 100644
index 000000000..cc62e5a89
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0258-crypto-rework-knet_handle_crypto-external-API-to-be-.patch
@@ -0,0 +1,599 @@ 
+From d5c11951948bef53ba64a6686e76439364cc062d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 28 May 2019 05:24:47 +0200
+Subject: [PATCH] [crypto] rework knet_handle_crypto external API to be more
+ solid
+
+the API was rather weak and could potentially leave traffic uncrypted
+in case of certain, corner case, failures.
+
+this patch is a subset of a bigger rework of the crypto layer that
+will in future allow runtime reconfiguration without traffic disruption
+of the crypto config.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto.c                       | 63 +++++++++++------
+ libknet/crypto_model.h                 | 10 ++-
+ libknet/crypto_nss.c                   | 56 ++++++++-------
+ libknet/crypto_openssl.c               | 30 ++++----
+ libknet/handle.c                       |  3 +-
+ libknet/libknet.h                      |  4 +-
+ libknet/tests/api_knet_handle_crypto.c | 96 +++++++++++++++++++++++++-
+ 7 files changed, 190 insertions(+), 72 deletions(-)
+
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 5d39048c..6c340f5c 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -80,8 +80,11 @@ int crypto_init(
+ 	knet_handle_t knet_h,
+ 	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
+ {
+-	int savederrno = 0;
++	int err = 0, savederrno = 0;
+ 	int model = 0;
++	struct crypto_instance *current = NULL, *new = NULL;
++
++	current = knet_h->crypto_instance;
+ 
+ 	model = crypto_get_model(knet_handle_crypto_cfg->crypto_model);
+ 	if (model < 0) {
+@@ -105,16 +108,18 @@ int crypto_init(
+ 		crypto_modules_cmds[model].ops = load_module (knet_h, "crypto", crypto_modules_cmds[model].model_name);
+ 		if (!crypto_modules_cmds[model].ops) {
+ 			savederrno = errno;
++			err = -1;
+ 			log_err(knet_h, KNET_SUB_CRYPTO, "Unable to load %s lib", crypto_modules_cmds[model].model_name);
+-			goto out_err;
++			goto out;
+ 		}
+ 		if (crypto_modules_cmds[model].ops->abi_ver != KNET_CRYPTO_MODEL_ABI) {
++			savederrno = EINVAL;
++			err = -1;
+ 			log_err(knet_h, KNET_SUB_CRYPTO,
+ 				"ABI mismatch loading module %s. knet ver: %d, module ver: %d",
+ 				crypto_modules_cmds[model].model_name, KNET_CRYPTO_MODEL_ABI,
+ 				crypto_modules_cmds[model].ops->abi_ver);
+-			savederrno = EINVAL;
+-			goto out_err;
++			goto out;
+ 		}
+ 		crypto_modules_cmds[model].loaded = 1;
+ 	}
+@@ -125,12 +130,13 @@ int crypto_init(
+ 		  knet_handle_crypto_cfg->crypto_cipher_type,
+ 		  knet_handle_crypto_cfg->crypto_hash_type);
+ 
+-	knet_h->crypto_instance = malloc(sizeof(struct crypto_instance));
++	new = malloc(sizeof(struct crypto_instance));
+ 
+-	if (!knet_h->crypto_instance) {
+-		log_err(knet_h, KNET_SUB_CRYPTO, "Unable to allocate memory for crypto instance");
++	if (!new) {
+ 		savederrno = ENOMEM;
+-		goto out_err;
++		err = -1;
++		log_err(knet_h, KNET_SUB_CRYPTO, "Unable to allocate memory for crypto instance");
++		goto out;
+ 	}
+ 
+ 	/*
+@@ -138,32 +144,44 @@ int crypto_init(
+ 	 * it will clean everything by itself.
+ 	 * crypto_modules_cmds.ops->fini is not invoked on error.
+ 	 */
+-	knet_h->crypto_instance->model = model;
+-	if (crypto_modules_cmds[knet_h->crypto_instance->model].ops->init(knet_h, knet_handle_crypto_cfg)) {
++	new->model = model;
++	if (crypto_modules_cmds[model].ops->init(knet_h, new, knet_handle_crypto_cfg)) {
+ 		savederrno = errno;
+-		goto out_err;
++		err = -1;
++		goto out;
+ 	}
+ 
+ 	log_debug(knet_h, KNET_SUB_CRYPTO, "security network overhead: %zu", knet_h->sec_header_size);
+-	pthread_rwlock_unlock(&shlib_rwlock);
+-	return 0;
+ 
+-out_err:
+-	if (knet_h->crypto_instance) {
+-		free(knet_h->crypto_instance);
+-		knet_h->crypto_instance = NULL;
++out:
++	if (!err) {
++		knet_h->crypto_instance = new;
++		knet_h->sec_header_size = new->sec_header_size;
++		knet_h->sec_block_size = new->sec_block_size;
++		knet_h->sec_hash_size = new->sec_hash_size;
++		knet_h->sec_salt_size = new->sec_salt_size;
++
++		if (current) {
++			if (crypto_modules_cmds[current->model].ops->fini != NULL) {
++				crypto_modules_cmds[current->model].ops->fini(knet_h, current);
++			}
++			free(current);
++		}
++	} else {
++		if (new) {
++			free(new);
++		}
+ 	}
+ 
+ 	pthread_rwlock_unlock(&shlib_rwlock);
+-	errno = savederrno;
+-	return -1;
++	errno = err ? savederrno : 0;
++	return err;
+ }
+ 
+ void crypto_fini(
+ 	knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
+-	int model = 0;
+ 
+ 	savederrno = pthread_rwlock_wrlock(&shlib_rwlock);
+ 	if (savederrno) {
+@@ -173,9 +191,8 @@ void crypto_fini(
+ 	}
+ 
+ 	if (knet_h->crypto_instance) {
+-		model = knet_h->crypto_instance->model;
+-		if (crypto_modules_cmds[model].ops->fini != NULL) {
+-			crypto_modules_cmds[model].ops->fini(knet_h);
++		if (crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini != NULL) {
++			crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini(knet_h, knet_h->crypto_instance);
+ 		}
+ 		free(knet_h->crypto_instance);
+ 		knet_h->sec_header_size = 0;
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index f11299a6..9bb4f17a 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -14,9 +14,13 @@
+ struct crypto_instance {
+ 	int	model;
+ 	void	*model_instance;
++	size_t	sec_header_size;
++	size_t	sec_block_size;
++	size_t	sec_hash_size;
++	size_t	sec_salt_size;
+ };
+ 
+-#define KNET_CRYPTO_MODEL_ABI 1
++#define KNET_CRYPTO_MODEL_ABI 2
+ 
+ /*
+  * see compress_model.h for explanation of the various lib related functions
+@@ -24,8 +28,10 @@ struct crypto_instance {
+ typedef struct {
+ 	uint8_t abi_ver;
+ 	int (*init)	(knet_handle_t knet_h,
++			 struct crypto_instance *crypto_instance,
+ 			 struct knet_handle_crypto_cfg *knet_handle_crypto_cfg);
+-	void (*fini)	(knet_handle_t knet_h);
++	void (*fini)	(knet_handle_t knet_h,
++			 struct crypto_instance *crypto_instance);
+ 	int (*crypt)	(knet_handle_t knet_h,
+ 			 const unsigned char *buf_in,
+ 			 const ssize_t buf_in_len,
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index cc838275..5c3a4374 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -155,9 +155,11 @@ static int nssstring_to_crypto_cipher_type(const char* crypto_cipher_type)
+ 	return -1;
+ }
+ 
+-static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h, enum sym_key_type key_type)
++static PK11SymKey *nssimport_symmetric_key(knet_handle_t knet_h,
++					   struct crypto_instance *crypto_instance,
++					   enum sym_key_type key_type)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 	SECItem key_item;
+ 	PK11SlotInfo *slot;
+ 	PK11SymKey *res_key;
+@@ -323,15 +325,15 @@ exit_res_key:
+ 	return (res_key);
+ }
+ 
+-static int init_nss_crypto(knet_handle_t knet_h)
++static int init_nss_crypto(knet_handle_t knet_h, struct crypto_instance *crypto_instance)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 
+ 	if (!cipher_to_nss[instance->crypto_cipher_type]) {
+ 		return 0;
+ 	}
+ 
+-	instance->nss_sym_key = nssimport_symmetric_key(knet_h, SYM_KEY_TYPE_CRYPT);
++	instance->nss_sym_key = nssimport_symmetric_key(knet_h, crypto_instance, SYM_KEY_TYPE_CRYPT);
+ 	if (instance->nss_sym_key == NULL) {
+ 		errno = ENXIO; /* NSS reported error */
+ 		return -1;
+@@ -512,15 +514,15 @@ static int nssstring_to_crypto_hash_type(const char* crypto_hash_type)
+ 	return -1;
+ }
+ 
+-static int init_nss_hash(knet_handle_t knet_h)
++static int init_nss_hash(knet_handle_t knet_h, struct crypto_instance *crypto_instance)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 
+ 	if (!hash_to_nss[instance->crypto_hash_type]) {
+ 		return 0;
+ 	}
+ 
+-	instance->nss_sym_key_sign = nssimport_symmetric_key(knet_h, SYM_KEY_TYPE_HASH);
++	instance->nss_sym_key_sign = nssimport_symmetric_key(knet_h, crypto_instance, SYM_KEY_TYPE_HASH);
+ 	if (instance->nss_sym_key_sign == NULL) {
+ 		errno = ENXIO; /* NSS reported error */
+ 		return -1;
+@@ -594,7 +596,7 @@ out:
+  * global/glue nss functions
+  */
+ 
+-static int init_nss(knet_handle_t knet_h)
++static int init_nss(knet_handle_t knet_h, struct crypto_instance *crypto_instance)
+ {
+ 	static int at_exit_registered = 0;
+ 
+@@ -617,11 +619,11 @@ static int init_nss(knet_handle_t knet_h)
+ 		nss_db_is_init = 1;
+ 	}
+ 
+-	if (init_nss_crypto(knet_h) < 0) {
++	if (init_nss_crypto(knet_h, crypto_instance) < 0) {
+ 		return -1;
+ 	}
+ 
+-	if (init_nss_hash(knet_h) < 0) {
++	if (init_nss_hash(knet_h, crypto_instance) < 0) {
+ 		return -1;
+ 	}
+ 
+@@ -725,9 +727,10 @@ static int nsscrypto_authenticate_and_decrypt (
+ }
+ 
+ static void nsscrypto_fini(
+-	knet_handle_t knet_h)
++	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance)
+ {
+-	struct nsscrypto_instance *nsscrypto_instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *nsscrypto_instance = crypto_instance->model_instance;
+ 
+ 	if (nsscrypto_instance) {
+ 		if (nsscrypto_instance->nss_sym_key) {
+@@ -739,7 +742,7 @@ static void nsscrypto_fini(
+ 			nsscrypto_instance->nss_sym_key_sign = NULL;
+ 		}
+ 		free(nsscrypto_instance);
+-		knet_h->crypto_instance->model_instance = NULL;
++		crypto_instance->model_instance = NULL;
+ 	}
+ 
+ 	return;
+@@ -747,6 +750,7 @@ static void nsscrypto_fini(
+ 
+ static int nsscrypto_init(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
+ {
+ 	struct nsscrypto_instance *nsscrypto_instance = NULL;
+@@ -757,14 +761,14 @@ static int nsscrypto_init(
+ 		  knet_handle_crypto_cfg->crypto_cipher_type,
+ 		  knet_handle_crypto_cfg->crypto_hash_type);
+ 
+-	knet_h->crypto_instance->model_instance = malloc(sizeof(struct nsscrypto_instance));
+-	if (!knet_h->crypto_instance->model_instance) {
++	crypto_instance->model_instance = malloc(sizeof(struct nsscrypto_instance));
++	if (!crypto_instance->model_instance) {
+ 		log_err(knet_h, KNET_SUB_NSSCRYPTO, "Unable to allocate memory for nss model instance");
+ 		errno = ENOMEM;
+ 		return -1;
+ 	}
+ 
+-	nsscrypto_instance = knet_h->crypto_instance->model_instance;
++	nsscrypto_instance = crypto_instance->model_instance;
+ 
+ 	memset(nsscrypto_instance, 0, sizeof(struct nsscrypto_instance));
+ 
+@@ -792,16 +796,16 @@ static int nsscrypto_init(
+ 	nsscrypto_instance->private_key = knet_handle_crypto_cfg->private_key;
+ 	nsscrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len;
+ 
+-	if (init_nss(knet_h) < 0) {
++	if (init_nss(knet_h, crypto_instance) < 0) {
+ 		savederrno = errno;
+ 		goto out_err;
+ 	}
+ 
+-	knet_h->sec_header_size = 0;
++	crypto_instance->sec_header_size = 0;
+ 
+ 	if (nsscrypto_instance->crypto_hash_type > 0) {
+-		knet_h->sec_header_size += nsshash_len[nsscrypto_instance->crypto_hash_type];
+-		knet_h->sec_hash_size = nsshash_len[nsscrypto_instance->crypto_hash_type];
++		crypto_instance->sec_header_size += nsshash_len[nsscrypto_instance->crypto_hash_type];
++		crypto_instance->sec_hash_size = nsshash_len[nsscrypto_instance->crypto_hash_type];
+ 	}
+ 
+ 	if (nsscrypto_instance->crypto_cipher_type > 0) {
+@@ -817,16 +821,16 @@ static int nsscrypto_init(
+ 			}
+ 		}
+ 
+-		knet_h->sec_header_size += (block_size * 2);
+-		knet_h->sec_header_size += SALT_SIZE;
+-		knet_h->sec_salt_size = SALT_SIZE;
+-		knet_h->sec_block_size = block_size;
++		crypto_instance->sec_header_size += (block_size * 2);
++		crypto_instance->sec_header_size += SALT_SIZE;
++		crypto_instance->sec_salt_size = SALT_SIZE;
++		crypto_instance->sec_block_size = block_size;
+ 	}
+ 
+ 	return 0;
+ 
+ out_err:
+-	nsscrypto_fini(knet_h);
++	nsscrypto_fini(knet_h, crypto_instance);
+ 	errno = savederrno;
+ 	return -1;
+ }
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 73058ccf..5c7a74a1 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -471,9 +471,10 @@ out:
+ #endif
+ 
+ static void opensslcrypto_fini(
+-	knet_handle_t knet_h)
++	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance)
+ {
+-	struct opensslcrypto_instance *opensslcrypto_instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *opensslcrypto_instance = crypto_instance->model_instance;
+ 
+ 	if (opensslcrypto_instance) {
+ #ifdef BUILDCRYPTOOPENSSL10
+@@ -484,7 +485,7 @@ static void opensslcrypto_fini(
+ 			opensslcrypto_instance->private_key = NULL;
+ 		}
+ 		free(opensslcrypto_instance);
+-		knet_h->crypto_instance->model_instance = NULL;
++		crypto_instance->model_instance = NULL;
+ 	}
+ 
+ 	return;
+@@ -492,6 +493,7 @@ static void opensslcrypto_fini(
+ 
+ static int opensslcrypto_init(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
+ {
+ 	static int openssl_is_init = 0;
+@@ -527,14 +529,14 @@ static int opensslcrypto_init(
+ 	}
+ #endif
+ 
+-	knet_h->crypto_instance->model_instance = malloc(sizeof(struct opensslcrypto_instance));
+-	if (!knet_h->crypto_instance->model_instance) {
++	crypto_instance->model_instance = malloc(sizeof(struct opensslcrypto_instance));
++	if (!crypto_instance->model_instance) {
+ 		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate memory for openssl model instance");
+ 		errno = ENOMEM;
+ 		return -1;
+ 	}
+ 
+-	opensslcrypto_instance = knet_h->crypto_instance->model_instance;
++	opensslcrypto_instance = crypto_instance->model_instance;
+ 
+ 	memset(opensslcrypto_instance, 0, sizeof(struct opensslcrypto_instance));
+ 
+@@ -576,11 +578,11 @@ static int opensslcrypto_init(
+ 	memmove(opensslcrypto_instance->private_key, knet_handle_crypto_cfg->private_key, knet_handle_crypto_cfg->private_key_len);
+ 	opensslcrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len;
+ 
+-	knet_h->sec_header_size = 0;
++	crypto_instance->sec_header_size = 0;
+ 
+ 	if (opensslcrypto_instance->crypto_hash_type) {
+-		knet_h->sec_hash_size = EVP_MD_size(opensslcrypto_instance->crypto_hash_type);
+-		knet_h->sec_header_size += knet_h->sec_hash_size;
++		crypto_instance->sec_hash_size = EVP_MD_size(opensslcrypto_instance->crypto_hash_type);
++		crypto_instance->sec_header_size += crypto_instance->sec_hash_size;
+ 	}
+ 
+ 	if (opensslcrypto_instance->crypto_cipher_type) {
+@@ -588,16 +590,16 @@ static int opensslcrypto_init(
+ 
+ 		block_size = EVP_CIPHER_block_size(opensslcrypto_instance->crypto_cipher_type);
+ 
+-		knet_h->sec_header_size += (block_size * 2);
+-		knet_h->sec_header_size += SALT_SIZE;
+-		knet_h->sec_salt_size = SALT_SIZE;
+-		knet_h->sec_block_size = block_size;
++		crypto_instance->sec_header_size += (block_size * 2);
++		crypto_instance->sec_header_size += SALT_SIZE;
++		crypto_instance->sec_salt_size = SALT_SIZE;
++		crypto_instance->sec_block_size = block_size;
+ 	}
+ 
+ 	return 0;
+ 
+ out_err:
+-	opensslcrypto_fini(knet_h);
++	opensslcrypto_fini(knet_h, crypto_instance);
+ 
+ 	errno = savederrno;
+ 	return -1;
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 7009cc34..e95c6c14 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1374,11 +1374,10 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 		return -1;
+ 	}
+ 
+-	crypto_fini(knet_h);
+-
+ 	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) || 
+ 	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
+ 	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
++		crypto_fini(knet_h);
+ 		log_debug(knet_h, KNET_SUB_CRYPTO, "crypto is not enabled");
+ 		err = 0;
+ 		goto exit_unlock;
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 183c92d3..85c06cc1 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -700,9 +700,7 @@ struct knet_handle_crypto_cfg {
+  *              1) failure to obtain locking
+  *              2) errors to initializing the crypto level.
+  *   This can happen even in subsequent calls to knet_handle_crypto.
+- *   A failure in crypto init, might leave your traffic unencrypted!
+- *   It's best to stop data forwarding (see knet_handle_setfwd(3)), change crypto config,
+- *   start forward again.
++ *   A failure in crypto init will restore the previous crypto configuration.
+  *
+  * @return
+  * knet_handle_crypto returns:
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index 1805909b..9dbf5bc0 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -17,13 +17,15 @@
+ #include "libknet.h"
+ 
+ #include "internals.h"
++#include "crypto_model.h"
+ #include "test-common.h"
+ 
+-static void test(const char *model)
++static void test(const char *model, const char *model2)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
++	struct crypto_instance *current = NULL;
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 
+@@ -152,6 +154,96 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_handle_crypto reconfig with %s/aes128/sha1 and normal key\n", model2);
++
++	current = knet_h->crypto_instance;
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
++		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (current == knet_h->crypto_instance) {
++		printf("knet_handle_crypto failed to install new correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto reconfig with %s/aes128/sha1 and normal key\n", model);
++
++	current = knet_h->crypto_instance;
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
++		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (current == knet_h->crypto_instance) {
++		printf("knet_handle_crypto failed to install new correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto reconfig with %s/aes129/sha1 and normal key\n", model);
++
++	current = knet_h->crypto_instance;
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes129", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (!knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
++		printf("knet_handle_crypto failed to detect incorrect config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (current != knet_h->crypto_instance) {
++		printf("knet_handle_crypto failed to restore correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
+ 	printf("Test knet_handle_crypto with %s/aes128/none and normal key\n", model);
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+@@ -233,7 +325,7 @@ int main(int argc, char *argv[])
+ 	}
+ 
+ 	for (i=0; i < crypto_list_entries; i++) {
+-		test(crypto_list[i].name);
++		test(crypto_list[i].name, crypto_list[0].name);
+ 	}
+ 
+ 	return PASS;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0259-PMTUd-extend-internal-rerun-API-to-allow-full-PMTUd-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0259-PMTUd-extend-internal-rerun-API-to-allow-full-PMTUd-.patch
new file mode 100644
index 000000000..dfc306544
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0259-PMTUd-extend-internal-rerun-API-to-allow-full-PMTUd-.patch
@@ -0,0 +1,74 @@ 
+From 99dbda2630556bf9cd861ea846e405af275a6d1f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 28 May 2019 05:35:24 +0200
+Subject: [PATCH] [PMTUd] extend internal rerun API to allow full PMTUd reset
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c         |  2 +-
+ libknet/threads_common.c | 11 ++++++++++-
+ libknet/threads_common.h |  2 +-
+ libknet/transport_udp.c  |  2 +-
+ 4 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index e95c6c14..251d3320 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1408,7 +1408,7 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 
+ exit_unlock:
+ 	if (!err) {
+-		force_pmtud_run(knet_h, KNET_SUB_CRYPTO);
++		force_pmtud_run(knet_h, KNET_SUB_CRYPTO, 1);
+ 	}
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	errno = err ? savederrno : 0;
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 61ffd826..53a6f9fb 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -157,8 +157,17 @@ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status)
+ 	return 0;
+ }
+ 
+-void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem)
++void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu)
+ {
++	if (reset_mtu) {
++		log_debug(knet_h, subsystem, "PMTUd has been reset to default");
++		knet_h->data_mtu = KNET_PMTUD_MIN_MTU_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
++		if (knet_h->pmtud_notify_fn) {
++			knet_h->pmtud_notify_fn(knet_h->pmtud_notify_fn_private_data,
++						knet_h->data_mtu);
++		}
++	}
++
+ 	/*
+ 	 * we can only try to take a lock here. This part of the code
+ 	 * can be invoked by any thread, including PMTUd that is already
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 19336ce7..cff76917 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -45,6 +45,6 @@ int shutdown_in_progress(knet_handle_t knet_h);
+ int get_global_wrlock(knet_handle_t knet_h);
+ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status);
+ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status);
+-void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem);
++void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu);
+ 
+ #endif
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 232dbcb0..15374389 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -340,7 +340,7 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 									pthread_mutex_unlock(&knet_h->kmtu_mutex);
+ 								}
+ 
+-								force_pmtud_run(knet_h, KNET_SUB_TRANSP_UDP);
++								force_pmtud_run(knet_h, KNET_SUB_TRANSP_UDP, 0);
+ 							}
+ 							/*
+ 							 * those errors are way too noisy
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0260-crypto-fix-openssl1.0-initialization-code.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0260-crypto-fix-openssl1.0-initialization-code.patch
new file mode 100644
index 000000000..1feca5c6f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0260-crypto-fix-openssl1.0-initialization-code.patch
@@ -0,0 +1,98 @@ 
+From 43c3d8a74b8a28c95d68cef9df9886160c3cf344 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 28 May 2019 06:14:29 +0200
+Subject: [PATCH] [crypto] fix openssl1.0 initialization code
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 28 ++++++++++++++++------------
+ 1 file changed, 16 insertions(+), 12 deletions(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 5c7a74a1..26acea8b 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -12,6 +12,7 @@
+ #include <string.h>
+ #include <errno.h>
+ #include <dlfcn.h>
++#include <stdlib.h>
+ #include <openssl/conf.h>
+ #include <openssl/evp.h>
+ #include <openssl/hmac.h>
+@@ -43,6 +44,8 @@ struct opensslcrypto_instance {
+ 	const EVP_MD *crypto_hash_type;
+ };
+ 
++static int openssl_is_init = 0;
++
+ /*
+  * crypt/decrypt functions openssl1.0
+  */
+@@ -438,6 +441,11 @@ static void openssl_internal_lock_cleanup(void)
+ 	return;
+ }
+ 
++static void openssl_atexit_handler(void)
++{
++	openssl_internal_lock_cleanup();
++}
++
+ static int openssl_internal_lock_setup(void)
+ {
+ 	int savederrno = 0, err = 0;
+@@ -461,6 +469,9 @@ static int openssl_internal_lock_setup(void)
+ 	CRYPTO_set_id_callback((void *)openssl_internal_thread_id);
+ 	CRYPTO_set_locking_callback((void *)&openssl_internal_locking_callback);
+ 
++	if (atexit(openssl_atexit_handler)) {
++		err = -1;
++	}
+ out:
+ 	if (err) {
+ 		openssl_internal_lock_cleanup();
+@@ -477,9 +488,6 @@ static void opensslcrypto_fini(
+ 	struct opensslcrypto_instance *opensslcrypto_instance = crypto_instance->model_instance;
+ 
+ 	if (opensslcrypto_instance) {
+-#ifdef BUILDCRYPTOOPENSSL10
+-		openssl_internal_lock_cleanup();
+-#endif
+ 		if (opensslcrypto_instance->private_key) {
+ 			free(opensslcrypto_instance->private_key);
+ 			opensslcrypto_instance->private_key = NULL;
+@@ -496,7 +504,6 @@ static int opensslcrypto_init(
+ 	struct crypto_instance *crypto_instance,
+ 	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
+ {
+-	static int openssl_is_init = 0;
+ 	struct opensslcrypto_instance *opensslcrypto_instance = NULL;
+ 	int savederrno;
+ 
+@@ -509,6 +516,11 @@ static int opensslcrypto_init(
+ #ifdef BUILDCRYPTOOPENSSL10
+ 		ERR_load_crypto_strings();
+ 		OPENSSL_add_all_algorithms_noconf();
++		if (openssl_internal_lock_setup() < 0) {
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to init openssl");
++			errno = EAGAIN;
++			return -1;
++		}
+ #endif
+ #ifdef BUILDCRYPTOOPENSSL11
+ 		if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+@@ -521,14 +533,6 @@ static int opensslcrypto_init(
+ 		openssl_is_init = 1;
+ 	}
+ 
+-#ifdef BUILDCRYPTOOPENSSL10
+-	if (openssl_internal_lock_setup() < 0) {
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to init openssl");
+-		errno = EAGAIN;
+-		return -1;
+-	}
+-#endif
+-
+ 	crypto_instance->model_instance = malloc(sizeof(struct opensslcrypto_instance));
+ 	if (!crypto_instance->model_instance) {
+ 		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate memory for openssl model instance");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0261-transports-fix-incorrect-merge-when-cherry-picking-7.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0261-transports-fix-incorrect-merge-when-cherry-picking-7.patch
new file mode 100644
index 000000000..36062ce2c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0261-transports-fix-incorrect-merge-when-cherry-picking-7.patch
@@ -0,0 +1,29 @@ 
+From f62c9a39a13759f1ce6f19dcbe15794ddac8e7f3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 3 Jun 2019 18:13:04 +0200
+Subject: [PATCH] [transports] fix incorrect merge when cherry-picking
+ 7033ddab505a0cf3655115fe5037579b7c882a8c
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transports.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 5181db90..51712df3 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -27,11 +27,11 @@
+ #include "transport_sctp.h"
+ #include "threads_common.h"
+ 
+-#define empty_module -1, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
++#define empty_module 0, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+ 	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED,KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+ 				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0262-crypto-openssl-error-strings-release.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0262-crypto-openssl-error-strings-release.patch
new file mode 100644
index 000000000..346302186
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0262-crypto-openssl-error-strings-release.patch
@@ -0,0 +1,28 @@ 
+From 16ecc0f9b8c5b5a55cc88248c5cba8595db76860 Mon Sep 17 00:00:00 2001
+From: yuan ren <yren@suse.com>
+Date: Thu, 6 Jun 2019 13:46:01 +0800
+Subject: [PATCH] [crypto]openssl error strings release
+
+In versions prior to OpenSSL 1.1.0, ERR_free_strings() releases
+any resources created by ERR_load_crypto_strings.
+
+Signed-off-by: yuan ren <yren@suse.com>
+---
+ libknet/crypto_openssl.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 26acea8b..615a9e58 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -496,6 +496,10 @@ static void opensslcrypto_fini(
+ 		crypto_instance->model_instance = NULL;
+ 	}
+ 
++#ifdef BUILDCRYPTOOPENSSL10
++	ERR_free_strings();
++#endif
++
+ 	return;
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0263-crypto-openssl-drop-calls-to-RAND_seed-as-they-don-t.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0263-crypto-openssl-drop-calls-to-RAND_seed-as-they-don-t.patch
new file mode 100644
index 000000000..362ee557b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0263-crypto-openssl-drop-calls-to-RAND_seed-as-they-don-t.patch
@@ -0,0 +1,68 @@ 
+From e5092989c724d7363dcca6ac5386b02c608a006c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 11 Jun 2019 09:26:02 +0200
+Subject: [PATCH] =?UTF-8?q?[crypto]=20openssl:=20drop=20calls=20to=20RAND?=
+ =?UTF-8?q?=5Fseed=20as=20they=20don=C2=B4t=20really=20help=20RNG?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930061#12 for reference
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 20 --------------------
+ 1 file changed, 20 deletions(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 615a9e58..999ed93e 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -69,11 +69,6 @@ static int encrypt_openssl(
+ 
+ 	EVP_CIPHER_CTX_init(&ctx);
+ 
+-	/*
+-	 * contribute to PRNG for each packet we send/receive
+-	 */
+-	RAND_seed((unsigned char *)iov[iovcnt - 1].iov_base, iov[iovcnt - 1].iov_len);
+-
+ 	if (!RAND_bytes(salt, SALT_SIZE)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+ 		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to get random salt data: %s", sslerr);
+@@ -130,11 +125,6 @@ static int decrypt_openssl (
+ 
+ 	EVP_CIPHER_CTX_init(&ctx);
+ 
+-	/*
+-	 * contribute to PRNG for each packet we send/receive
+-	 */
+-	RAND_seed(buf_in, buf_in_len);
+-
+ 	/*
+ 	 * add warning re keylength
+ 	 */
+@@ -181,11 +171,6 @@ static int encrypt_openssl(
+ 
+ 	ctx = EVP_CIPHER_CTX_new();
+ 
+-	/*
+-	 * contribute to PRNG for each packet we send/receive
+-	 */
+-	RAND_seed((unsigned char *)iov[iovcnt - 1].iov_base, iov[iovcnt - 1].iov_len);
+-
+ 	if (!RAND_bytes(salt, SALT_SIZE)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+ 		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to get random salt data: %s", sslerr);
+@@ -248,11 +233,6 @@ static int decrypt_openssl (
+ 
+ 	ctx = EVP_CIPHER_CTX_new();
+ 
+-	/*
+-	 * contribute to PRNG for each packet we send/receive
+-	 */
+-	RAND_seed(buf_in, buf_in_len);
+-
+ 	/*
+ 	 * add warning re keylength
+ 	 */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0264-crypto-hide-errors-generated-by-openssl-1.1.1c.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0264-crypto-hide-errors-generated-by-openssl-1.1.1c.patch
new file mode 100644
index 000000000..47d418ad8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0264-crypto-hide-errors-generated-by-openssl-1.1.1c.patch
@@ -0,0 +1,137 @@ 
+From 06b4ecb1c009da64281f01308c27c756dc85f8fb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 11 Jun 2019 11:54:08 +0200
+Subject: [PATCH] [crypto] hide errors generated by openssl 1.1.1c
+
+see also:
+https://github.com/kronosnet/kronosnet/issues/226
+https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=930061#12
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 115 ++++++++++++++++++++++++++
+ 1 file changed, 115 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index a34ab934..92eabbac 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -612,3 +612,118 @@
+    fun:malloc
+    fun:dl_open_worker
+ }
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Cond
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_instantiate
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_get0_public
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++}
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Cond
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_instantiate
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_get0_public
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++}
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Cond
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   fun:RAND_DRBG_bytes
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++   fun:clone
++}
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Cond
++   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   fun:RAND_DRBG_bytes
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++   fun:clone
++}
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Param
++   socketcall.sendto(msg)
++   fun:sendto
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++   fun:clone
++}
++{
++
++   openssl 1.1.1c missing fix from master
++   Memcheck:Param
++   socketcall.sendto(msg)
++   fun:sendto
++   fun:_parse_recv_from_links
++   fun:_handle_recv_from_links
++   fun:_handle_recv_from_links_thread
++   fun:start_thread
++   fun:clone
++}
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Param
++   socketcall.sendto(msg)
++   fun:sendto
++   fun:_handle_check_link_pmtud
++   fun:_handle_check_pmtud
++   fun:_handle_pmtud_link_thread
++   fun:start_thread
++   fun:clone
++}
++{
++   openssl 1.1.1c missing fix from master
++   Memcheck:Param
++   sendmsg(msg.msg_iov[0])
++   fun:__libc_sendmsg
++   fun:sendmsg
++   fun:_sendmmsg
++   fun:_dispatch_to_links
++   fun:_parse_recv_from_sock
++   fun:_handle_send_to_links
++   fun:_handle_send_to_links_thread
++   fun:start_thread
++   fun:clone
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0265-doc-fix-a-merge-oversight-from-541d7faf9068d10e12b42.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0265-doc-fix-a-merge-oversight-from-541d7faf9068d10e12b42.patch
new file mode 100644
index 000000000..8ffaf111f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0265-doc-fix-a-merge-oversight-from-541d7faf9068d10e12b42.patch
@@ -0,0 +1,23 @@ 
+From 26477e3af9fc2d577f7eedf7c5d413f38728fb78 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 11 Jun 2019 16:09:54 +0200
+Subject: [PATCH] [doc] fix a merge oversight from
+ 541d7faf9068d10e12b4278c35825ce1353db081
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/libknet.h | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 85c06cc1..907213f2 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1511,6 +1511,7 @@ typedef enum {
+ 
+ /**
+  * check_acceptreject_t
++ *
+  * @brief enum for accept/reject in knet access lists
+  *
+  * accept or reject incoming packets defined in the access list entry
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0266-global-clarify-license-entry-per-file-to-match-READM.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0266-global-clarify-license-entry-per-file-to-match-READM.patch
new file mode 100644
index 000000000..013f46040
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0266-global-clarify-license-entry-per-file-to-match-READM.patch
@@ -0,0 +1,2929 @@ 
+From 137fa9a01dcf2d19c1d9efb0608cbf7fe8a4fb28 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 12 Jun 2019 05:21:24 +0200
+Subject: [PATCH] [global] clarify license entry per file to match
+ README.licence
+
+libraries code: LGPL-2.0+
+binaries code and other files: GPL-2.0+
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ Makefile.am                                                   | 2 +-
+ README                                                        | 2 +-
+ autogen.sh                                                    | 2 +-
+ build-aux/check.mk                                            | 2 +-
+ build-aux/release.mk                                          | 2 +-
+ build-aux/update-copyright.sh                                 | 4 ++--
+ configure.ac                                                  | 2 +-
+ init/Makefile.am                                              | 2 +-
+ init/kronosnetd.default                                       | 2 +-
+ init/kronosnetd.in                                            | 2 +-
+ init/kronosnetd.service.in                                    | 2 +-
+ kronosnetd/Makefile.am                                        | 2 +-
+ kronosnetd/cfg.c                                              | 2 +-
+ kronosnetd/cfg.h                                              | 2 +-
+ kronosnetd/etherfilter.c                                      | 2 +-
+ kronosnetd/etherfilter.h                                      | 2 +-
+ kronosnetd/keygen.c                                           | 2 +-
+ kronosnetd/kronosnetd.logrotate.in                            | 2 +-
+ kronosnetd/logging.c                                          | 2 +-
+ kronosnetd/logging.h                                          | 2 +-
+ kronosnetd/main.c                                             | 2 +-
+ kronosnetd/vty.c                                              | 2 +-
+ kronosnetd/vty.h                                              | 2 +-
+ kronosnetd/vty_auth.c                                         | 2 +-
+ kronosnetd/vty_auth.h                                         | 2 +-
+ kronosnetd/vty_cli.c                                          | 2 +-
+ kronosnetd/vty_cli.h                                          | 2 +-
+ kronosnetd/vty_cli_cmds.c                                     | 2 +-
+ kronosnetd/vty_cli_cmds.h                                     | 2 +-
+ kronosnetd/vty_utils.c                                        | 2 +-
+ kronosnetd/vty_utils.h                                        | 2 +-
+ libknet/Makefile.am                                           | 2 +-
+ libknet/common.c                                              | 2 +-
+ libknet/common.h                                              | 2 +-
+ libknet/compat.c                                              | 2 +-
+ libknet/compat.h                                              | 2 +-
+ libknet/compress.c                                            | 2 +-
+ libknet/compress.h                                            | 2 +-
+ libknet/compress_bzip2.c                                      | 2 +-
+ libknet/compress_lz4.c                                        | 2 +-
+ libknet/compress_lz4hc.c                                      | 2 +-
+ libknet/compress_lzma.c                                       | 2 +-
+ libknet/compress_lzo2.c                                       | 2 +-
+ libknet/compress_model.h                                      | 2 +-
+ libknet/compress_zlib.c                                       | 2 +-
+ libknet/compress_zstd.c                                       | 2 +-
+ libknet/crypto.c                                              | 2 +-
+ libknet/crypto.h                                              | 2 +-
+ libknet/crypto_model.h                                        | 2 +-
+ libknet/crypto_nss.c                                          | 2 +-
+ libknet/crypto_openssl.c                                      | 2 +-
+ libknet/handle.c                                              | 2 +-
+ libknet/host.c                                                | 2 +-
+ libknet/host.h                                                | 2 +-
+ libknet/internals.h                                           | 2 +-
+ libknet/libknet.h                                             | 2 +-
+ libknet/libknet.pc.in                                         | 2 +-
+ libknet/libknet_exported_syms                                 | 2 +-
+ libknet/links.c                                               | 2 +-
+ libknet/links.h                                               | 2 +-
+ libknet/links_acl.c                                           | 2 +-
+ libknet/links_acl.h                                           | 2 +-
+ libknet/links_acl_ip.c                                        | 2 +-
+ libknet/links_acl_ip.h                                        | 2 +-
+ libknet/links_acl_loopback.c                                  | 2 +-
+ libknet/links_acl_loopback.h                                  | 2 +-
+ libknet/logging.c                                             | 2 +-
+ libknet/logging.h                                             | 2 +-
+ libknet/netutils.c                                            | 2 +-
+ libknet/netutils.h                                            | 2 +-
+ libknet/onwire.h                                              | 2 +-
+ libknet/tests/Makefile.am                                     | 2 +-
+ libknet/tests/api-check.mk                                    | 2 +-
+ libknet/tests/api-test-coverage                               | 2 +-
+ libknet/tests/api_knet_addrtostr.c                            | 2 +-
+ libknet/tests/api_knet_get_compress_list.c                    | 2 +-
+ libknet/tests/api_knet_get_crypto_list.c                      | 2 +-
+ libknet/tests/api_knet_get_transport_id_by_name.c             | 2 +-
+ libknet/tests/api_knet_get_transport_list.c                   | 2 +-
+ libknet/tests/api_knet_get_transport_name_by_id.c             | 2 +-
+ libknet/tests/api_knet_handle_add_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_clear_stats.c                   | 2 +-
+ libknet/tests/api_knet_handle_compress.c                      | 2 +-
+ libknet/tests/api_knet_handle_crypto.c                        | 2 +-
+ libknet/tests/api_knet_handle_enable_access_lists.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_filter.c                 | 2 +-
+ libknet/tests/api_knet_handle_enable_pmtud_notify.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_sock_notify.c            | 2 +-
+ libknet/tests/api_knet_handle_free.c                          | 2 +-
+ libknet/tests/api_knet_handle_get_channel.c                   | 2 +-
+ libknet/tests/api_knet_handle_get_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_get_stats.c                     | 2 +-
+ .../tests/api_knet_handle_get_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_new.c                           | 2 +-
+ libknet/tests/api_knet_handle_new_limit.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_get.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_getfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_pmtud_setfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_remove_datafd.c                 | 2 +-
+ .../tests/api_knet_handle_set_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_setfwd.c                        | 2 +-
+ libknet/tests/api_knet_host_add.c                             | 2 +-
+ libknet/tests/api_knet_host_enable_status_change_notify.c     | 2 +-
+ libknet/tests/api_knet_host_get_host_list.c                   | 2 +-
+ libknet/tests/api_knet_host_get_id_by_host_name.c             | 2 +-
+ libknet/tests/api_knet_host_get_name_by_host_id.c             | 2 +-
+ libknet/tests/api_knet_host_get_policy.c                      | 2 +-
+ libknet/tests/api_knet_host_get_status.c                      | 2 +-
+ libknet/tests/api_knet_host_remove.c                          | 2 +-
+ libknet/tests/api_knet_host_set_name.c                        | 2 +-
+ libknet/tests/api_knet_host_set_policy.c                      | 2 +-
+ libknet/tests/api_knet_link_add_acl.c                         | 2 +-
+ libknet/tests/api_knet_link_clear_acl.c                       | 2 +-
+ libknet/tests/api_knet_link_clear_config.c                    | 2 +-
+ libknet/tests/api_knet_link_get_config.c                      | 2 +-
+ libknet/tests/api_knet_link_get_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_get_link_list.c                   | 2 +-
+ libknet/tests/api_knet_link_get_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_get_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_get_priority.c                    | 2 +-
+ libknet/tests/api_knet_link_get_status.c                      | 2 +-
+ libknet/tests/api_knet_link_insert_acl.c                      | 2 +-
+ libknet/tests/api_knet_link_rm_acl.c                          | 2 +-
+ libknet/tests/api_knet_link_set_config.c                      | 2 +-
+ libknet/tests/api_knet_link_set_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_set_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_set_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_set_priority.c                    | 2 +-
+ libknet/tests/api_knet_log_get_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_id.c                  | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_name.c                | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_id.c                 | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_name.c               | 2 +-
+ libknet/tests/api_knet_log_set_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_recv.c                                 | 2 +-
+ libknet/tests/api_knet_send.c                                 | 2 +-
+ libknet/tests/api_knet_send_compress.c                        | 2 +-
+ libknet/tests/api_knet_send_crypto.c                          | 2 +-
+ libknet/tests/api_knet_send_loopback.c                        | 2 +-
+ libknet/tests/api_knet_send_sync.c                            | 2 +-
+ libknet/tests/api_knet_strtoaddr.c                            | 2 +-
+ libknet/tests/int_links_acl_ip.c                              | 2 +-
+ libknet/tests/int_timediff.c                                  | 2 +-
+ libknet/tests/knet_bench.c                                    | 2 +-
+ libknet/tests/pckt_test.c                                     | 2 +-
+ libknet/tests/test-common.c                                   | 2 +-
+ libknet/tests/test-common.h                                   | 2 +-
+ libknet/threads_common.c                                      | 2 +-
+ libknet/threads_common.h                                      | 2 +-
+ libknet/threads_dsthandler.c                                  | 2 +-
+ libknet/threads_dsthandler.h                                  | 2 +-
+ libknet/threads_heartbeat.c                                   | 2 +-
+ libknet/threads_heartbeat.h                                   | 2 +-
+ libknet/threads_pmtud.c                                       | 2 +-
+ libknet/threads_pmtud.h                                       | 2 +-
+ libknet/threads_rx.c                                          | 2 +-
+ libknet/threads_rx.h                                          | 2 +-
+ libknet/threads_tx.c                                          | 2 +-
+ libknet/threads_tx.h                                          | 2 +-
+ libknet/transport_common.c                                    | 2 +-
+ libknet/transport_common.h                                    | 2 +-
+ libknet/transport_loopback.c                                  | 2 +-
+ libknet/transport_loopback.h                                  | 2 +-
+ libknet/transport_sctp.c                                      | 2 +-
+ libknet/transport_sctp.h                                      | 2 +-
+ libknet/transport_udp.c                                       | 2 +-
+ libknet/transport_udp.h                                       | 2 +-
+ libknet/transports.c                                          | 2 +-
+ libknet/transports.h                                          | 2 +-
+ libnozzle/Makefile.am                                         | 2 +-
+ libnozzle/internals.c                                         | 2 +-
+ libnozzle/internals.h                                         | 2 +-
+ libnozzle/libnozzle.c                                         | 2 +-
+ libnozzle/libnozzle.h                                         | 2 +-
+ libnozzle/libnozzle.pc.in                                     | 2 +-
+ libnozzle/libnozzle_exported_syms                             | 2 +-
+ libnozzle/tests/Makefile.am                                   | 2 +-
+ libnozzle/tests/api-test-coverage                             | 2 +-
+ libnozzle/tests/api_nozzle_add_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_close.c                            | 2 +-
+ libnozzle/tests/api_nozzle_del_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_fd.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_handle_by_name.c               | 2 +-
+ libnozzle/tests/api_nozzle_get_ips.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_name_by_handle.c               | 2 +-
+ libnozzle/tests/api_nozzle_open.c                             | 2 +-
+ libnozzle/tests/api_nozzle_run_updown.c                       | 2 +-
+ libnozzle/tests/api_nozzle_set_down.c                         | 2 +-
+ libnozzle/tests/api_nozzle_set_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_up.c                           | 2 +-
+ libnozzle/tests/int_execute_bin_sh_command.c                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_false                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_true                   | 2 +-
+ libnozzle/tests/test-common.c                                 | 2 +-
+ libnozzle/tests/test-common.h                                 | 2 +-
+ man/Doxyfile-knet.in                                          | 2 +-
+ man/Doxyfile-nozzle.in                                        | 2 +-
+ man/Makefile.am                                               | 2 +-
+ man/api-to-man-page-coverage                                  | 2 +-
+ man/doxyxml.c                                                 | 2 +-
+ man/knet-keygen.8                                             | 2 +-
+ man/kronosnetd.8                                              | 2 +-
+ poc-code/Makefile.am                                          | 2 +-
+ poc-code/iov-hash/Makefile.am                                 | 2 +-
+ poc-code/iov-hash/main.c                                      | 2 +-
+ 208 files changed, 209 insertions(+), 209 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 82cb1f5b..dc5f8a5e 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in aclocal.m4 configure depcomp \
+diff --git a/README b/README
+index 7b5e7ce6..f8f3ea6f 100644
+--- a/README
++++ b/README
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ Upstream resources
+diff --git a/autogen.sh b/autogen.sh
+index 8fb1e58a..92e9483b 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ # Run this to generate all the initial makefiles, etc.
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index 6da44177..f42e5528 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ VALGRIND = $(VALGRIND_EXEC) -q --error-exitcode=127 --gen-suppressions=all
+diff --git a/build-aux/release.mk b/build-aux/release.mk
+index de3599df..003125d2 100644
+--- a/build-aux/release.mk
++++ b/build-aux/release.mk
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ # to build official release tarballs, handle tagging and publish.
+diff --git a/build-aux/update-copyright.sh b/build-aux/update-copyright.sh
+index fd50f8ea..62c449c8 100755
+--- a/build-aux/update-copyright.sh
++++ b/build-aux/update-copyright.sh
+@@ -1,10 +1,10 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2017 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ # script to update copyright dates across the tree
+diff --git a/configure.ac b/configure.ac
+index 501053e1..e9625922 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -4,7 +4,7 @@
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ #                                               -*- Autoconf -*-
+diff --git a/init/Makefile.am b/init/Makefile.am
+index 4d59a9e8..fe0d9b0b 100644
+--- a/init/Makefile.am
++++ b/init/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/init/kronosnetd.default b/init/kronosnetd.default
+index ed946480..9f6755c4 100644
+--- a/init/kronosnetd.default
++++ b/init/kronosnetd.default
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ 
+diff --git a/init/kronosnetd.in b/init/kronosnetd.in
+index 1823a3b2..1da32733 100644
+--- a/init/kronosnetd.in
++++ b/init/kronosnetd.in
+@@ -5,7 +5,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ # chkconfig: - 20 80
+diff --git a/init/kronosnetd.service.in b/init/kronosnetd.service.in
+index 4d2a32ab..cfc80f79 100644
+--- a/init/kronosnetd.service.in
++++ b/init/kronosnetd.service.in
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ [Unit]
+diff --git a/kronosnetd/Makefile.am b/kronosnetd/Makefile.am
+index 0b6f673b..5ce8fa5e 100644
+--- a/kronosnetd/Makefile.am
++++ b/kronosnetd/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in kronostnetd.logrotate
+diff --git a/kronosnetd/cfg.c b/kronosnetd/cfg.c
+index 69d209a1..406532a8 100644
+--- a/kronosnetd/cfg.c
++++ b/kronosnetd/cfg.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/cfg.h b/kronosnetd/cfg.h
+index 0260bff6..56fa4d50 100644
+--- a/kronosnetd/cfg.h
++++ b/kronosnetd/cfg.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_CFG_H__
+diff --git a/kronosnetd/etherfilter.c b/kronosnetd/etherfilter.c
+index 8542061c..5f0d9fb4 100644
+--- a/kronosnetd/etherfilter.c
++++ b/kronosnetd/etherfilter.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/etherfilter.h b/kronosnetd/etherfilter.h
+index d805dd6d..63e18b6c 100644
+--- a/kronosnetd/etherfilter.h
++++ b/kronosnetd/etherfilter.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_ETHERFILTER_H__
+diff --git a/kronosnetd/keygen.c b/kronosnetd/keygen.c
+index eb914734..42706ad5 100644
+--- a/kronosnetd/keygen.c
++++ b/kronosnetd/keygen.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/kronosnetd.logrotate.in b/kronosnetd/kronosnetd.logrotate.in
+index 4ed1fd2a..a8a6969b 100644
+--- a/kronosnetd/kronosnetd.logrotate.in
++++ b/kronosnetd/kronosnetd.logrotate.in
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ @LOGDIR@kronosnetd.log {
+diff --git a/kronosnetd/logging.c b/kronosnetd/logging.c
+index b3ef0d11..9c141cd8 100644
+--- a/kronosnetd/logging.c
++++ b/kronosnetd/logging.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/logging.h b/kronosnetd/logging.h
+index e4d5ce28..1bc12b93 100644
+--- a/kronosnetd/logging.h
++++ b/kronosnetd/logging.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_LOGGING_H__
+diff --git a/kronosnetd/main.c b/kronosnetd/main.c
+index c1a8c2b1..ec43871b 100644
+--- a/kronosnetd/main.c
++++ b/kronosnetd/main.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/vty.c b/kronosnetd/vty.c
+index d624bf4b..2c5d4d30 100644
+--- a/kronosnetd/vty.c
++++ b/kronosnetd/vty.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/vty.h b/kronosnetd/vty.h
+index 86bd8212..3c3e6e04 100644
+--- a/kronosnetd/vty.h
++++ b/kronosnetd/vty.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_VTY_H__
+diff --git a/kronosnetd/vty_auth.c b/kronosnetd/vty_auth.c
+index cf997f92..30e0929d 100644
+--- a/kronosnetd/vty_auth.c
++++ b/kronosnetd/vty_auth.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/vty_auth.h b/kronosnetd/vty_auth.h
+index c42989b7..58d75cbf 100644
+--- a/kronosnetd/vty_auth.h
++++ b/kronosnetd/vty_auth.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_VTY_AUTH_H__
+diff --git a/kronosnetd/vty_cli.c b/kronosnetd/vty_cli.c
+index 68ff0dad..95e4c8f4 100644
+--- a/kronosnetd/vty_cli.c
++++ b/kronosnetd/vty_cli.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/vty_cli.h b/kronosnetd/vty_cli.h
+index 9bbdcc70..0d7e515f 100644
+--- a/kronosnetd/vty_cli.h
++++ b/kronosnetd/vty_cli.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_VTY_CLI_H__
+diff --git a/kronosnetd/vty_cli_cmds.c b/kronosnetd/vty_cli_cmds.c
+index 18b11a0c..e5ad4965 100644
+--- a/kronosnetd/vty_cli_cmds.c
++++ b/kronosnetd/vty_cli_cmds.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/vty_cli_cmds.h b/kronosnetd/vty_cli_cmds.h
+index ac07573f..ba40ddf0 100644
+--- a/kronosnetd/vty_cli_cmds.h
++++ b/kronosnetd/vty_cli_cmds.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_VTY_CLI_CMDS_H__
+diff --git a/kronosnetd/vty_utils.c b/kronosnetd/vty_utils.c
+index 3c5cc865..2cf51176 100644
+--- a/kronosnetd/vty_utils.c
++++ b/kronosnetd/vty_utils.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/kronosnetd/vty_utils.h b/kronosnetd/vty_utils.h
+index 07e339be..7ac318a2 100644
+--- a/kronosnetd/vty_utils.h
++++ b/kronosnetd/vty_utils.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNETD_VTY_UTILS_H__
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 8adcc40b..d0807327 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -4,7 +4,7 @@
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/libknet/common.c b/libknet/common.c
+index be46f23e..30e537e5 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/common.h b/libknet/common.h
+index ddea7fcd..6128b160 100644
+--- a/libknet/common.h
++++ b/libknet/common.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "internals.h"
+diff --git a/libknet/compat.c b/libknet/compat.c
+index a60bca28..e808f332 100644
+--- a/libknet/compat.c
++++ b/libknet/compat.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Jan Friesse <jfriesse@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/compat.h b/libknet/compat.h
+index e9af804d..903fdfb3 100644
+--- a/libknet/compat.h
++++ b/libknet/compat.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Jan Friesse <jfriesse@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_COMPAT_H__
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 864828f3..24755c77 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/compress.h b/libknet/compress.h
+index 47edddfb..d43a9d5f 100644
+--- a/libknet/compress.h
++++ b/libknet/compress.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_COMPRESS_H__
+diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c
+index 521e2069..5a972fff 100644
+--- a/libknet/compress_bzip2.c
++++ b/libknet/compress_bzip2.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c
+index 22b926fd..60aa1966 100644
+--- a/libknet/compress_lz4.c
++++ b/libknet/compress_lz4.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c
+index 9a69ab4c..781bf12f 100644
+--- a/libknet/compress_lz4hc.c
++++ b/libknet/compress_lz4hc.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
+index e9ba2e30..7fdd1782 100644
+--- a/libknet/compress_lzma.c
++++ b/libknet/compress_lzma.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c
+index e66d3dca..12066ed9 100644
+--- a/libknet/compress_lzo2.c
++++ b/libknet/compress_lzo2.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/compress_model.h b/libknet/compress_model.h
+index 909f5a1d..e69e4915 100644
+--- a/libknet/compress_model.h
++++ b/libknet/compress_model.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_COMPRESS_MODEL_H__
+diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c
+index 8807bb47..2fb12f51 100644
+--- a/libknet/compress_zlib.c
++++ b/libknet/compress_zlib.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index 6f9b499e..f76ea5f8 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 6c340f5c..9f05fbaf 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index 707de327..f80cb43e 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_CRYPTO_H__
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index 9bb4f17a..70f6238f 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_CRYPTO_MODEL_H__
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 5c3a4374..330b40cc 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 999ed93e..0cbc6f57 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
+ 
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 251d3320..4835e991 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/host.c b/libknet/host.c
+index 66826c1a..abb1f894 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/host.h b/libknet/host.h
+index 4336b17d..307b6e77 100644
+--- a/libknet/host.h
++++ b/libknet/host.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_HOST_H__
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 12f613cb..3f105a15 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_INTERNALS_H__
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 907213f2..acd1c86b 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __LIBKNET_H__
+diff --git a/libknet/libknet.pc.in b/libknet/libknet.pc.in
+index bb7b25c7..021b2c44 100644
+--- a/libknet/libknet.pc.in
++++ b/libknet/libknet.pc.in
+@@ -3,7 +3,7 @@
+ #
+ # Author: Federico Simoncelli <fsimon@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under LGPL-2.0+
+ #
+ 
+ prefix=@prefix@
+diff --git a/libknet/libknet_exported_syms b/libknet/libknet_exported_syms
+index d8a55e22..1d8bddbb 100644
+--- a/libknet/libknet_exported_syms
++++ b/libknet/libknet_exported_syms
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under LGPL-2.0+
+ #
+ 
+ LIBKNET {
+diff --git a/libknet/links.c b/libknet/links.c
+index 8011a6dc..4ec308ce 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/links.h b/libknet/links.h
+index 7c0250d2..e14958de 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_LINK_H__
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 776408a7..eb77e7be 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 60f78125..4617c9b2 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_LINKS_ACL_H__
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 9310f212..e479bbdb 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index b33ffb1e..f566c1e9 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_LINKS_ACL_IP_H__
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index 044a51cb..0a0adec7 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index b51d2bfd..d10764cf 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_LINKS_ACL_LOOPBACK_H__
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 5c912572..2efee1b9 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/logging.h b/libknet/logging.h
+index bdcd85e8..01dcaf14 100644
+--- a/libknet/logging.h
++++ b/libknet/logging.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_LOGGING_H__
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index 72bc659e..e37f4fe8 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index bdc605e2..b293115e 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_NETUTILS_H__
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index ea45bfb4..9815bc38 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_ONWIRE_H__
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 015587cf..33465962 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 427c3880..102ec52a 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -3,7 +3,7 @@
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ api_checks		= \
+diff --git a/libknet/tests/api-test-coverage b/libknet/tests/api-test-coverage
+index bf0ccc3f..e988ab17 100755
+--- a/libknet/tests/api-test-coverage
++++ b/libknet/tests/api-test-coverage
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ srcdir="$1"/libknet/tests
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index 9adbf311..9cdf5021 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_get_compress_list.c b/libknet/tests/api_knet_get_compress_list.c
+index 230e2037..53e4192d 100644
+--- a/libknet/tests/api_knet_get_compress_list.c
++++ b/libknet/tests/api_knet_get_compress_list.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_get_crypto_list.c b/libknet/tests/api_knet_get_crypto_list.c
+index 4121aa40..760adab5 100644
+--- a/libknet/tests/api_knet_get_crypto_list.c
++++ b/libknet/tests/api_knet_get_crypto_list.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_get_transport_id_by_name.c b/libknet/tests/api_knet_get_transport_id_by_name.c
+index 973814f1..9bcd673e 100644
+--- a/libknet/tests/api_knet_get_transport_id_by_name.c
++++ b/libknet/tests/api_knet_get_transport_id_by_name.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_get_transport_list.c b/libknet/tests/api_knet_get_transport_list.c
+index c7489017..9ab5c103 100644
+--- a/libknet/tests/api_knet_get_transport_list.c
++++ b/libknet/tests/api_knet_get_transport_list.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_get_transport_name_by_id.c b/libknet/tests/api_knet_get_transport_name_by_id.c
+index a797cec9..3233a1d8 100644
+--- a/libknet/tests/api_knet_get_transport_name_by_id.c
++++ b/libknet/tests/api_knet_get_transport_name_by_id.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_add_datafd.c b/libknet/tests/api_knet_handle_add_datafd.c
+index 7159399e..30887976 100644
+--- a/libknet/tests/api_knet_handle_add_datafd.c
++++ b/libknet/tests/api_knet_handle_add_datafd.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index 07f059a2..0867b13c 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 1525e6a3..40b6f397 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index 9dbf5bc0..1eed96e7 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_enable_access_lists.c b/libknet/tests/api_knet_handle_enable_access_lists.c
+index d08f175e..be54bc44 100644
+--- a/libknet/tests/api_knet_handle_enable_access_lists.c
++++ b/libknet/tests/api_knet_handle_enable_access_lists.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_enable_filter.c b/libknet/tests/api_knet_handle_enable_filter.c
+index 63b2166f..e518b426 100644
+--- a/libknet/tests/api_knet_handle_enable_filter.c
++++ b/libknet/tests/api_knet_handle_enable_filter.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_enable_pmtud_notify.c b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+index 726c2cc1..f11abc38 100644
+--- a/libknet/tests/api_knet_handle_enable_pmtud_notify.c
++++ b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_enable_sock_notify.c b/libknet/tests/api_knet_handle_enable_sock_notify.c
+index 9c906009..adefb5a2 100644
+--- a/libknet/tests/api_knet_handle_enable_sock_notify.c
++++ b/libknet/tests/api_knet_handle_enable_sock_notify.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_free.c b/libknet/tests/api_knet_handle_free.c
+index 75319fc9..53b6dc62 100644
+--- a/libknet/tests/api_knet_handle_free.c
++++ b/libknet/tests/api_knet_handle_free.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_get_channel.c b/libknet/tests/api_knet_handle_get_channel.c
+index 3ade3024..0196136f 100644
+--- a/libknet/tests/api_knet_handle_get_channel.c
++++ b/libknet/tests/api_knet_handle_get_channel.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_get_datafd.c b/libknet/tests/api_knet_handle_get_datafd.c
+index 8838b696..57aedf59 100644
+--- a/libknet/tests/api_knet_handle_get_datafd.c
++++ b/libknet/tests/api_knet_handle_get_datafd.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_get_stats.c b/libknet/tests/api_knet_handle_get_stats.c
+index e8a83b4c..38a0c971 100644
+--- a/libknet/tests/api_knet_handle_get_stats.c
++++ b/libknet/tests/api_knet_handle_get_stats.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+index 7a43823f..f013a5bf 100644
+--- a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_new.c b/libknet/tests/api_knet_handle_new.c
+index b7af5664..9559d4a3 100644
+--- a/libknet/tests/api_knet_handle_new.c
++++ b/libknet/tests/api_knet_handle_new.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_new_limit.c b/libknet/tests/api_knet_handle_new_limit.c
+index d51db975..fc3bdcda 100644
+--- a/libknet/tests/api_knet_handle_new_limit.c
++++ b/libknet/tests/api_knet_handle_new_limit.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_pmtud_get.c b/libknet/tests/api_knet_handle_pmtud_get.c
+index a1b1d12f..803a2888 100644
+--- a/libknet/tests/api_knet_handle_pmtud_get.c
++++ b/libknet/tests/api_knet_handle_pmtud_get.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_pmtud_getfreq.c b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+index 5c5c7e0d..23e32393 100644
+--- a/libknet/tests/api_knet_handle_pmtud_getfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_pmtud_setfreq.c b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+index b4eebdad..2a720c30 100644
+--- a/libknet/tests/api_knet_handle_pmtud_setfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_remove_datafd.c b/libknet/tests/api_knet_handle_remove_datafd.c
+index 08a42abf..ace5df7f 100644
+--- a/libknet/tests/api_knet_handle_remove_datafd.c
++++ b/libknet/tests/api_knet_handle_remove_datafd.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+index 80bbacbd..c5615598 100644
+--- a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_handle_setfwd.c b/libknet/tests/api_knet_handle_setfwd.c
+index 96580759..21a5c9fd 100644
+--- a/libknet/tests/api_knet_handle_setfwd.c
++++ b/libknet/tests/api_knet_handle_setfwd.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_add.c b/libknet/tests/api_knet_host_add.c
+index 762d0dfa..65104f59 100644
+--- a/libknet/tests/api_knet_host_add.c
++++ b/libknet/tests/api_knet_host_add.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_enable_status_change_notify.c b/libknet/tests/api_knet_host_enable_status_change_notify.c
+index 96d133d1..b0467a5b 100644
+--- a/libknet/tests/api_knet_host_enable_status_change_notify.c
++++ b/libknet/tests/api_knet_host_enable_status_change_notify.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_get_host_list.c b/libknet/tests/api_knet_host_get_host_list.c
+index 76fb23bf..fc573bbe 100644
+--- a/libknet/tests/api_knet_host_get_host_list.c
++++ b/libknet/tests/api_knet_host_get_host_list.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_get_id_by_host_name.c b/libknet/tests/api_knet_host_get_id_by_host_name.c
+index 81ad504a..745dbfa7 100644
+--- a/libknet/tests/api_knet_host_get_id_by_host_name.c
++++ b/libknet/tests/api_knet_host_get_id_by_host_name.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_get_name_by_host_id.c b/libknet/tests/api_knet_host_get_name_by_host_id.c
+index d239821c..46045251 100644
+--- a/libknet/tests/api_knet_host_get_name_by_host_id.c
++++ b/libknet/tests/api_knet_host_get_name_by_host_id.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_get_policy.c b/libknet/tests/api_knet_host_get_policy.c
+index 3160503a..8511815e 100644
+--- a/libknet/tests/api_knet_host_get_policy.c
++++ b/libknet/tests/api_knet_host_get_policy.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_get_status.c b/libknet/tests/api_knet_host_get_status.c
+index b13c57a5..3b46f0c6 100644
+--- a/libknet/tests/api_knet_host_get_status.c
++++ b/libknet/tests/api_knet_host_get_status.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_remove.c b/libknet/tests/api_knet_host_remove.c
+index 12d1f8f9..36dd47c8 100644
+--- a/libknet/tests/api_knet_host_remove.c
++++ b/libknet/tests/api_knet_host_remove.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_set_name.c b/libknet/tests/api_knet_host_set_name.c
+index 88d6ce91..c899d339 100644
+--- a/libknet/tests/api_knet_host_set_name.c
++++ b/libknet/tests/api_knet_host_set_name.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_host_set_policy.c b/libknet/tests/api_knet_host_set_policy.c
+index 41102d20..25831149 100644
+--- a/libknet/tests/api_knet_host_set_policy.c
++++ b/libknet/tests/api_knet_host_set_policy.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index ff7a2e21..52d6022c 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index 234a76b6..3516b4d2 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_clear_config.c b/libknet/tests/api_knet_link_clear_config.c
+index 8d7800d2..ff9c4739 100644
+--- a/libknet/tests/api_knet_link_clear_config.c
++++ b/libknet/tests/api_knet_link_clear_config.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_config.c b/libknet/tests/api_knet_link_get_config.c
+index 111b4069..60a56fd6 100644
+--- a/libknet/tests/api_knet_link_get_config.c
++++ b/libknet/tests/api_knet_link_get_config.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_enable.c b/libknet/tests/api_knet_link_get_enable.c
+index 410c017f..b0e13489 100644
+--- a/libknet/tests/api_knet_link_get_enable.c
++++ b/libknet/tests/api_knet_link_get_enable.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_link_list.c b/libknet/tests/api_knet_link_get_link_list.c
+index e3dd73ef..6114f839 100644
+--- a/libknet/tests/api_knet_link_get_link_list.c
++++ b/libknet/tests/api_knet_link_get_link_list.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_ping_timers.c b/libknet/tests/api_knet_link_get_ping_timers.c
+index 5f0e9b1a..414619f0 100644
+--- a/libknet/tests/api_knet_link_get_ping_timers.c
++++ b/libknet/tests/api_knet_link_get_ping_timers.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_pong_count.c b/libknet/tests/api_knet_link_get_pong_count.c
+index bbc993d2..e032b963 100644
+--- a/libknet/tests/api_knet_link_get_pong_count.c
++++ b/libknet/tests/api_knet_link_get_pong_count.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_priority.c b/libknet/tests/api_knet_link_get_priority.c
+index 29d7d2ea..80538fea 100644
+--- a/libknet/tests/api_knet_link_get_priority.c
++++ b/libknet/tests/api_knet_link_get_priority.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_get_status.c b/libknet/tests/api_knet_link_get_status.c
+index fe567343..5139692c 100644
+--- a/libknet/tests/api_knet_link_get_status.c
++++ b/libknet/tests/api_knet_link_get_status.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index 79d04dfc..2f55c16f 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index d132c541..7217a4f5 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index b96c6287..c43a4de7 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_set_enable.c b/libknet/tests/api_knet_link_set_enable.c
+index f48f1c0a..17e6e031 100644
+--- a/libknet/tests/api_knet_link_set_enable.c
++++ b/libknet/tests/api_knet_link_set_enable.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_set_ping_timers.c b/libknet/tests/api_knet_link_set_ping_timers.c
+index d823a819..46170f6e 100644
+--- a/libknet/tests/api_knet_link_set_ping_timers.c
++++ b/libknet/tests/api_knet_link_set_ping_timers.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_set_pong_count.c b/libknet/tests/api_knet_link_set_pong_count.c
+index 70fc57f3..b8974e3a 100644
+--- a/libknet/tests/api_knet_link_set_pong_count.c
++++ b/libknet/tests/api_knet_link_set_pong_count.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_link_set_priority.c b/libknet/tests/api_knet_link_set_priority.c
+index a89392ec..aac0ea20 100644
+--- a/libknet/tests/api_knet_link_set_priority.c
++++ b/libknet/tests/api_knet_link_set_priority.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_log_get_loglevel.c b/libknet/tests/api_knet_log_get_loglevel.c
+index 4a62ead6..4d4a52cb 100644
+--- a/libknet/tests/api_knet_log_get_loglevel.c
++++ b/libknet/tests/api_knet_log_get_loglevel.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_log_get_loglevel_id.c b/libknet/tests/api_knet_log_get_loglevel_id.c
+index 1053dff5..379ba717 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_id.c
++++ b/libknet/tests/api_knet_log_get_loglevel_id.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_log_get_loglevel_name.c b/libknet/tests/api_knet_log_get_loglevel_name.c
+index 317ebb10..ef19af28 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_name.c
++++ b/libknet/tests/api_knet_log_get_loglevel_name.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_log_get_subsystem_id.c b/libknet/tests/api_knet_log_get_subsystem_id.c
+index 0b47805c..cff9e8aa 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_id.c
++++ b/libknet/tests/api_knet_log_get_subsystem_id.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_log_get_subsystem_name.c b/libknet/tests/api_knet_log_get_subsystem_name.c
+index 1b11fe6b..03847305 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_name.c
++++ b/libknet/tests/api_knet_log_get_subsystem_name.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_log_set_loglevel.c b/libknet/tests/api_knet_log_set_loglevel.c
+index e729113c..7a9232a4 100644
+--- a/libknet/tests/api_knet_log_set_loglevel.c
++++ b/libknet/tests/api_knet_log_set_loglevel.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_recv.c b/libknet/tests/api_knet_recv.c
+index 6e23353d..99bd7bc0 100644
+--- a/libknet/tests/api_knet_recv.c
++++ b/libknet/tests/api_knet_recv.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 57994fbc..60161340 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index b03f4e73..6d5f4457 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index e33a808a..11de8576 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 2feca685..741b51d3 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index f2718c95..96cb716a 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index 57a8a0a1..a0be1da9 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+index 93dff638..41e7d592 100644
+--- a/libknet/tests/int_links_acl_ip.c
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/int_timediff.c b/libknet/tests/int_timediff.c
+index 12735d8f..a878a319 100644
+--- a/libknet/tests/int_timediff.c
++++ b/libknet/tests/int_timediff.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index 00cd58be..dfe5238e 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/pckt_test.c b/libknet/tests/pckt_test.c
+index 56cf0181..f3e21007 100644
+--- a/libknet/tests/pckt_test.c
++++ b/libknet/tests/pckt_test.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include <stdio.h>
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index a4ff2974..cd3f6c44 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index a498a098..f1375ab8 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __KNET_TEST_COMMON_H__
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 53a6f9fb..1f3e1e35 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index cff76917..596de147 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_THREADS_COMMON_H__
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 2633188a..07761079 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/threads_dsthandler.h b/libknet/threads_dsthandler.h
+index 0c968ffe..db9117c9 100644
+--- a/libknet/threads_dsthandler.h
++++ b/libknet/threads_dsthandler.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_THREADS_DSTHANDLER_H__
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 8def9b8b..8f8a7ecb 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/threads_heartbeat.h b/libknet/threads_heartbeat.h
+index 2fcc9a05..b2580d10 100644
+--- a/libknet/threads_heartbeat.h
++++ b/libknet/threads_heartbeat.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_THREADS_HEARTBEAT_H__
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index b4ee632d..603f5951 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/threads_pmtud.h b/libknet/threads_pmtud.h
+index 2cdcdbc6..5ed31555 100644
+--- a/libknet/threads_pmtud.h
++++ b/libknet/threads_pmtud.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_THREADS_PMTUD_H__
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 626cbc4c..b2a5dad9 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/threads_rx.h b/libknet/threads_rx.h
+index ff8bd6e8..b88c0982 100644
+--- a/libknet/threads_rx.h
++++ b/libknet/threads_rx.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_THREADS_RX_H__
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 80969067..32d65d54 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/threads_tx.h b/libknet/threads_tx.h
+index 7c4b2c09..28c49585 100644
+--- a/libknet/threads_tx.h
++++ b/libknet/threads_tx.h
+@@ -4,7 +4,7 @@
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_THREADS_TX_H__
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index fe40ad88..72866438 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 778af8b0..0ca21d05 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_TRANSPORT_COMMON_H__
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index 54129d77..17253f54 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index 6ce3ed3f..a848ff81 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 2c1cdcc9..d97d6f98 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index 83a638bc..0b8f320c 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 15374389..53d2ba0b 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index 6de18e3f..1dec8635 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 51712df3..93119c58 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 38f69bac..3a29ce61 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __KNET_TRANSPORTS_H__
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 2ffbd086..8ac438ad 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index f056e3bf..53c0cdbd 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 853e14e7..c9192a81 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __NOZZLE_INTERNALS_H__
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index b6e95666..15863ecf 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index b8ab7d69..ad7c4749 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under LGPL-2.0+
+  */
+ 
+ #ifndef __LIBNOZZLE_H__
+diff --git a/libnozzle/libnozzle.pc.in b/libnozzle/libnozzle.pc.in
+index d6b2a151..9df09187 100644
+--- a/libnozzle/libnozzle.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under LGPL-2.0+
+ #
+ 
+ prefix=@prefix@
+diff --git a/libnozzle/libnozzle_exported_syms b/libnozzle/libnozzle_exported_syms
+index 934b2049..f6f62d21 100644
+--- a/libnozzle/libnozzle_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under LGPL-2.0+
+ #
+ 
+ LIBNOZZLE {
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index b9e16ae4..cdc42a3b 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index cd99edf9..4049ad94 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ srcdir="$1"/libnozzle/tests
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+index bb81ba73..a9d76c65 100644
+--- a/libnozzle/tests/api_nozzle_add_ip.c
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index f1cbc771..7ba17c44 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+index 0178bb06..625484f9 100644
+--- a/libnozzle/tests/api_nozzle_del_ip.c
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index 9b29faf8..5dc5b4c1 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+index 83c39bbb..1fa5a0a1 100644
+--- a/libnozzle/tests/api_nozzle_get_handle_by_name.c
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index c41024f7..446a79ad 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index 1318ba59..f4c72cc9 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 07b05ee8..1b1f85ef 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index 5b8152b1..0fe9eb4f 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index ee153160..413f2c24 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index c80216a2..1536b5b2 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index 90623ba1..9466bdb9 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index dba7d49e..244e866f 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index fc8ee1c8..ce4ccbbe 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index d8de39d7..d258b6a6 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index 87531c0e..97422a2d 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_false b/libnozzle/tests/nozzle_run_updown_exit_false
+index 3f03ff61..795456a7 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_false
++++ b/libnozzle/tests/nozzle_run_updown_exit_false
+@@ -5,7 +5,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ exit 1
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_true b/libnozzle/tests/nozzle_run_updown_exit_true
+index bbdcdd69..7b6e3552 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_true
++++ b/libnozzle/tests/nozzle_run_updown_exit_true
+@@ -5,7 +5,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ exit 0
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index c84aac1e..b36be79c 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #include "config.h"
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index 4562ea2d..fcfafefa 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -3,7 +3,7 @@
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ #ifndef __NOZZLE_TEST_COMMON_H__
+diff --git a/man/Doxyfile-knet.in b/man/Doxyfile-knet.in
+index f78e3136..4750c9a5 100644
+--- a/man/Doxyfile-knet.in
++++ b/man/Doxyfile-knet.in
+@@ -4,7 +4,7 @@
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ PROJECT_NAME	       = @PACKAGE_NAME@
+ PROJECT_NUMBER         = @PACKAGE_VERSION@
+diff --git a/man/Doxyfile-nozzle.in b/man/Doxyfile-nozzle.in
+index 2855e50b..793d49d4 100644
+--- a/man/Doxyfile-nozzle.in
++++ b/man/Doxyfile-nozzle.in
+@@ -4,7 +4,7 @@
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ PROJECT_NAME	       = @PACKAGE_NAME@
+ PROJECT_NUMBER         = @PACKAGE_VERSION@
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 0ad12f62..a473e900 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -4,7 +4,7 @@
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+index b9dc18f4..a1f54a39 100755
+--- a/man/api-to-man-page-coverage
++++ b/man/api-to-man-page-coverage
+@@ -4,7 +4,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ err=0
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 7d9a60c7..2f289767 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ 
+diff --git a/man/knet-keygen.8 b/man/knet-keygen.8
+index 67ecf1f4..96109c6e 100644
+--- a/man/knet-keygen.8
++++ b/man/knet-keygen.8
+@@ -5,7 +5,7 @@
+ .\" *
+ .\" * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ .\" *
+-.\" * This software licensed under GPL-2.0+, LGPL-2.0+
++.\" * This software licensed under GPL-2.0+
+ .\" */
+ .TH "KRONOSNETD" "8" "November 2012" "kronosnetd key generator." "System Administration Utilities"
+ 
+diff --git a/man/kronosnetd.8 b/man/kronosnetd.8
+index 5661e1c7..f4480be0 100644
+--- a/man/kronosnetd.8
++++ b/man/kronosnetd.8
+@@ -5,7 +5,7 @@
+ .\" *
+ .\" * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ .\" *
+-.\" * This software licensed under GPL-2.0+, LGPL-2.0+
++.\" * This software licensed under GPL-2.0+
+ .\" */
+ .TH "KRONOSNETD" "8" "November 2012" "kronosnetd Usage:" "System Administration Utilities"
+ 
+diff --git a/poc-code/Makefile.am b/poc-code/Makefile.am
+index 15d12f78..ddbea085 100644
+--- a/poc-code/Makefile.am
++++ b/poc-code/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/poc-code/iov-hash/Makefile.am b/poc-code/iov-hash/Makefile.am
+index a41ed99e..acd6b51f 100644
+--- a/poc-code/iov-hash/Makefile.am
++++ b/poc-code/iov-hash/Makefile.am
+@@ -3,7 +3,7 @@
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+-# This software licensed under GPL-2.0+, LGPL-2.0+
++# This software licensed under GPL-2.0+
+ #
+ 
+ MAINTAINERCLEANFILES	= Makefile.in
+diff --git a/poc-code/iov-hash/main.c b/poc-code/iov-hash/main.c
+index 61d2e12c..fa407a26 100644
+--- a/poc-code/iov-hash/main.c
++++ b/poc-code/iov-hash/main.c
+@@ -3,7 +3,7 @@
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+- * This software licensed under GPL-2.0+, LGPL-2.0+
++ * This software licensed under GPL-2.0+
+  */
+ 
+ /* Example code to illustrate DES enccryption/decryption using NSS.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0267-global-update-copyrights.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0267-global-update-copyrights.patch
new file mode 100644
index 000000000..a3bb5758e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0267-global-update-copyrights.patch
@@ -0,0 +1,21 @@ 
+From 794d29ff640250f04f839ba5d6afa8b46fba9567 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 12 Jun 2019 05:23:47 +0200
+Subject: [PATCH] [global] update copyrights
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/compress_zstd.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index f76ea5f8..e234f8d6 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0268-tests-ignore-libnss-errors-from-OpenSuse-15.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0268-tests-ignore-libnss-errors-from-OpenSuse-15.patch
new file mode 100644
index 000000000..10a1a0442
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0268-tests-ignore-libnss-errors-from-OpenSuse-15.patch
@@ -0,0 +1,50 @@ 
+From 76deb833d6ec6f8655d280254563bc5bf0e58e01 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 16 Jun 2019 07:41:49 +0200
+Subject: [PATCH] [tests] ignore libnss errors from OpenSuse 15
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 32 +++++++++++++++++++++++++++
+ 1 file changed, 32 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 92eabbac..0cdea0b4 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -727,3 +727,35 @@
+    fun:start_thread
+    fun:clone
+ }
++{
++   Opensuse 15 libnss
++   Memcheck:Cond
++   fun:__memcmp_sse4_1
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:FIPS_selftest
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:FIPS_mode_set
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:call_init.part.0
++   fun:_dl_init
++   fun:dl_open_worker
++   fun:_dl_catch_error
++   fun:_dl_open
++   fun:dlopen_doit
++}
++{
++   Opensuse 15 libnss
++   Memcheck:Cond
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:FIPS_mode_set
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:call_init.part.0
++   fun:_dl_init
++   fun:dl_open_worker
++   fun:_dl_catch_error
++   fun:_dl_open
++   fun:dlopen_doit
++   fun:_dl_catch_error
++   fun:_dlerror_run
++   fun:dlopen@@GLIBC_2.2.5
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0269-tests-ignore-libnss-errors-from-OpenSuse-Tumbleweed.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0269-tests-ignore-libnss-errors-from-OpenSuse-Tumbleweed.patch
new file mode 100644
index 000000000..0e6d9fece
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0269-tests-ignore-libnss-errors-from-OpenSuse-Tumbleweed.patch
@@ -0,0 +1,98 @@ 
+From d12414cbf9bfd286b33ed0cd7de4e92ca936327b Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 25 Jun 2019 13:30:23 +0200
+Subject: [PATCH] [tests] ignore libnss errors from OpenSuse Tumbleweed
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 80 +++++++++++++++++++++++++++
+ 1 file changed, 80 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 0cdea0b4..b877a59f 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -759,3 +759,83 @@
+    fun:_dlerror_run
+    fun:dlopen@@GLIBC_2.2.5
+ }
++{
++   Opensuse tumbleweed libnss
++   Memcheck:Cond
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_instantiate
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_get0_public
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++}
++{
++   Opensuse tumbleweed libnss
++   Memcheck:Cond
++   obj:/usr/lib64/libcrypto.so.1.1
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_instantiate
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_get0_public
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++}
++{
++   Opensuse tumbleweed libnss
++   Memcheck:Cond
++   obj:/usr/lib64/libcrypto.so.1.1
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   fun:RAND_DRBG_bytes
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++   fun:clone
++}
++{
++   Opensuse tumbleweed libnss
++   Memcheck:Cond
++   obj:/usr/lib64/libcrypto.so.1.1
++   fun:RAND_DRBG_generate
++   fun:RAND_DRBG_bytes
++   fun:encrypt_openssl
++   fun:opensslcrypto_encrypt_and_signv
++   fun:opensslcrypto_encrypt_and_sign
++   fun:_handle_check_each
++   fun:_send_pings
++   fun:_handle_heartbt_thread
++   fun:start_thread
++   fun:clone
++}
++{
++   Opensuse tumbleweed libnss
++   Memcheck:Param
++   sendmsg(msg.msg_iov[0])
++   fun:sendmsg
++   fun:_sendmmsg
++   fun:_dispatch_to_links
++   fun:_parse_recv_from_sock
++   fun:_handle_send_to_links
++   fun:_handle_send_to_links_thread
++   fun:start_thread
++   fun:clone
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0270-threads-allow-knet_handle_setfwd-to-flush-socket-que.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0270-threads-allow-knet_handle_setfwd-to-flush-socket-que.patch
new file mode 100644
index 000000000..470516d2f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0270-threads-allow-knet_handle_setfwd-to-flush-socket-que.patch
@@ -0,0 +1,449 @@ 
+From 8d4a1bf6cce75c5610105029346791266bc21ff9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 27 Jun 2019 10:55:23 +0200
+Subject: [PATCH] [threads] allow knet_handle_setfwd to flush socket queues
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c                       | 47 +++++++++++++++++--
+ libknet/internals.h                    |  1 +
+ libknet/tests/api_knet_send.c          | 11 +++++
+ libknet/tests/api_knet_send_compress.c | 13 ++++++
+ libknet/tests/api_knet_send_crypto.c   | 11 +++++
+ libknet/tests/api_knet_send_loopback.c | 33 ++++++++++++++
+ libknet/tests/api_knet_send_sync.c     | 11 +++++
+ libknet/tests/test-common.c            |  5 +++
+ libknet/threads_common.c               | 62 ++++++++++++++++++++++++++
+ libknet/threads_common.h               |  6 +++
+ libknet/threads_rx.c                   |  9 ++++
+ libknet/threads_tx.c                   | 35 +++++++++++++++
+ 12 files changed, 241 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 4835e991..10382480 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1174,16 +1174,57 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled)
+ 		return -1;
+ 	}
+ 
+-	knet_h->enabled = enabled;
+-
+ 	if (enabled) {
++		knet_h->enabled = enabled;
+ 		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is enabled");
+ 	} else {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is disabled");
++		/*
++		 * notify TX and RX threads to flush the queues
++		 */
++		if (set_thread_flush_queue(knet_h, KNET_THREAD_TX, KNET_THREAD_QUEUE_FLUSH) < 0) {
++			log_debug(knet_h, KNET_SUB_HANDLE, "Unable to request queue flushing for TX thread");
++		}
++		if (set_thread_flush_queue(knet_h, KNET_THREAD_RX, KNET_THREAD_QUEUE_FLUSH) < 0) {
++			log_debug(knet_h, KNET_SUB_HANDLE, "Unable to request queue flushing for RX thread");
++		}
+ 	}
+ 
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 
++	/*
++	 * when disabling data forward, we need to give time to TX and RX
++	 * to flush the queues.
++	 *
++	 * the TX thread is the main leader here. When there is no more
++	 * data in the TX queue, we will also close traffic for RX.
++	 */
++	if (!enabled) {
++		/*
++		 * this usleep might be unnecessary, but wait_all_threads_flush_queue
++		 * adds extra locking delay.
++		 *
++		 * allow all threads to run free without extra locking interference
++		 * and then we switch to a more active wait in case the scheduler
++		 * has decided to delay one thread or another
++		 */
++		usleep(KNET_THREADS_TIMERES * 2);
++		wait_all_threads_flush_queue(knet_h);
++
++		/*
++		 * all threads have done flushing the queue, we can stop data forwarding
++		 */
++		savederrno = get_global_wrlock(knet_h);
++		if (savederrno) {
++			log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++				strerror(savederrno));
++			errno = savederrno;
++			return -1;
++		}
++		knet_h->enabled = enabled;
++		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is disabled");
++		pthread_rwlock_unlock(&knet_h->global_rwlock);
++	}
++
+ 	errno = 0;
+ 	return 0;
+ }
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 3f105a15..47ef904f 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -178,6 +178,7 @@ struct knet_handle {
+ 	struct knet_header *pingbuf;
+ 	struct knet_header *pmtudbuf;
+ 	uint8_t threads_status[KNET_THREAD_MAX];
++	uint8_t threads_flush_queue[KNET_THREAD_MAX];
+ 	pthread_mutex_t threads_status_mutex;
+ 	pthread_t send_to_links_thread;
+ 	pthread_t recv_from_links_thread;
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 60161340..50469ee3 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -246,6 +246,17 @@ static void test(uint8_t transport)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index 6d5f4457..bbb357a4 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -170,6 +170,19 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
+ 	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index 11de8576..3e53e039 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -171,6 +171,17 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 741b51d3..6c0054c2 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -251,6 +251,17 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+@@ -317,6 +328,17 @@ static void test(void)
+ 
+ 	printf("Test knet_send with only localhost\n");
+ 
++	if (knet_handle_setfwd(knet_h, 1) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
+ 		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+@@ -352,6 +374,17 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+ 		printf("Error waiting for packet: %s\n", strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 96cb716a..007e4f59 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -375,6 +375,17 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	knet_link_set_enable(knet_h, 1, 0, 0);
+ 	knet_link_clear_config(knet_h, 1, 0);
+ 	knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index cd3f6c44..a7d6c5cc 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -395,6 +395,11 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 		return -1;
+ 	}
+ 
++	if (knet_handle_setfwd(knet_h, 0) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		return -1;
++	}
++
+ 	if (knet_host_get_host_list(knet_h, host_ids, &host_ids_entries) < 0) {
+ 		printf("knet_host_get_host_list failed: %s\n", strerror(errno));
+ 		return -1;
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 1f3e1e35..0c914c15 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -109,6 +109,68 @@ static const char *get_thread_name(uint8_t thread_id)
+ 	return "unknown";
+ }
+ 
++int get_thread_flush_queue(knet_handle_t knet_h, uint8_t thread_id)
++{
++	uint8_t flush;
++
++	if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock");
++		return -1;
++	}
++
++	flush = knet_h->threads_flush_queue[thread_id];
++
++	pthread_mutex_unlock(&knet_h->threads_status_mutex);
++	return flush;
++}
++
++int set_thread_flush_queue(knet_handle_t knet_h, uint8_t thread_id, uint8_t status)
++{
++	if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock");
++		return -1;
++	}
++
++	knet_h->threads_flush_queue[thread_id] = status;
++
++	log_debug(knet_h, KNET_SUB_HANDLE, "Updated flush queue request for thread %s to %u",
++		  get_thread_name(thread_id), status);
++
++	pthread_mutex_unlock(&knet_h->threads_status_mutex);
++	return 0;
++}
++
++int wait_all_threads_flush_queue(knet_handle_t knet_h)
++{
++	uint8_t i = 0, found = 0;
++
++	while (!found) {
++		usleep(KNET_THREADS_TIMERES);
++
++		if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
++			continue;
++		}
++
++		found = 1;
++
++		for (i = 0; i < KNET_THREAD_MAX; i++) {
++			if (knet_h->threads_flush_queue[i] == KNET_THREAD_QUEUE_FLUSHED) {
++				continue;
++			}
++			log_debug(knet_h, KNET_SUB_HANDLE, "Checking thread: %s queue: %u",
++					get_thread_name(i),
++					knet_h->threads_flush_queue[i]);
++			if (knet_h->threads_flush_queue[i] != KNET_THREAD_QUEUE_FLUSHED) {
++				found = 0;
++			}
++		}
++
++		pthread_mutex_unlock(&knet_h->threads_status_mutex);
++	}
++
++	return 0;
++}
++
+ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status)
+ {
+ 	if (pthread_mutex_lock(&knet_h->threads_status_mutex) != 0) {
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 596de147..9d4daaa0 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -32,6 +32,9 @@
+ #endif
+ #define KNET_THREAD_MAX		32
+ 
++#define KNET_THREAD_QUEUE_FLUSHED 0
++#define KNET_THREAD_QUEUE_FLUSH   1
++
+ #define timespec_diff(start, end, diff) \
+ do { \
+ 	if (end.tv_sec > start.tv_sec) \
+@@ -43,6 +46,9 @@ do { \
+ 
+ int shutdown_in_progress(knet_handle_t knet_h);
+ int get_global_wrlock(knet_handle_t knet_h);
++int get_thread_flush_queue(knet_handle_t knet_h, uint8_t thread_id);
++int set_thread_flush_queue(knet_handle_t knet_h, uint8_t thread_id, uint8_t status);
++int wait_all_threads_flush_queue(knet_handle_t knet_h);
+ int set_thread_status(knet_handle_t knet_h, uint8_t thread_id, uint8_t status);
+ int wait_all_threads_status(knet_handle_t knet_h, uint8_t status);
+ void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu);
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index b2a5dad9..f4cc1642 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -861,6 +861,15 @@ void *_handle_recv_from_links_thread(void *data)
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		nev = epoll_wait(knet_h->recv_from_links_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
+ 
++		/*
++		 * the RX threads only need to notify that there has been at least
++		 * one successful run after queue flush has been requested.
++		 * See setfwd in handle.c
++		 */
++		if (get_thread_flush_queue(knet_h, KNET_THREAD_RX) == KNET_THREAD_QUEUE_FLUSH) {
++			set_thread_flush_queue(knet_h, KNET_THREAD_RX, KNET_THREAD_QUEUE_FLUSHED);
++		}
++
+ 		/*
+ 		 * we use timeout to detect if thread is shutting down
+ 		 */
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 32d65d54..3969b109 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -673,6 +673,7 @@ void *_handle_send_to_links_thread(void *data)
+ 	knet_handle_t knet_h = (knet_handle_t) data;
+ 	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
+ 	int i, nev, type;
++	int flush, flush_queue_limit;
+ 	int8_t channel;
+ 	struct iovec iov_in;
+ 	struct msghdr msg;
+@@ -700,16 +701,49 @@ void *_handle_send_to_links_thread(void *data)
+ 		knet_h->send_to_links_buf[i]->kh_node = htons(knet_h->host_id);
+ 	}
+ 
++	flush_queue_limit = 0;
++
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		nev = epoll_wait(knet_h->send_to_links_epollfd, events, KNET_EPOLL_MAX_EVENTS + 1, KNET_THREADS_TIMERES / 1000);
+ 
++		flush = get_thread_flush_queue(knet_h, KNET_THREAD_TX);
++
+ 		/*
+ 		 * we use timeout to detect if thread is shutting down
+ 		 */
+ 		if (nev == 0) {
++			/*
++			 * ideally we want to communicate that we are done flushing
++			 * the queue when we have an epoll timeout event
++			 */
++			if (flush == KNET_THREAD_QUEUE_FLUSH) {
++				set_thread_flush_queue(knet_h, KNET_THREAD_TX, KNET_THREAD_QUEUE_FLUSHED);
++				flush_queue_limit = 0;
++			}
+ 			continue;
+ 		}
+ 
++		/*
++		 * fall back in case the TX sockets will continue receive traffic
++		 * and we do not hit an epoll timeout.
++		 *
++		 * allow up to a 100 loops to flush queues, then we give up.
++		 * there might be more clean ways to do it by checking the buffer queue
++		 * on each socket, but we have tons of sockets and calculations can go wrong.
++		 * Also, why would you disable data forwarding and still send packets?
++		 */
++		if (flush == KNET_THREAD_QUEUE_FLUSH) {
++			if (flush_queue_limit >= 100) {
++				log_debug(knet_h, KNET_SUB_TX, "Timeout flushing the TX queue, expect packet loss");
++				set_thread_flush_queue(knet_h, KNET_THREAD_TX, KNET_THREAD_QUEUE_FLUSHED);
++				flush_queue_limit = 0;
++			} else {
++				flush_queue_limit++;
++			}
++		} else {
++			flush_queue_limit = 0;
++		}
++
+ 		if (pthread_rwlock_rdlock(&knet_h->global_rwlock) != 0) {
+ 			log_debug(knet_h, KNET_SUB_TX, "Unable to get read lock");
+ 			continue;
+@@ -739,6 +773,7 @@ void *_handle_send_to_links_thread(void *data)
+ 			_handle_send_to_links(knet_h, &msg, events[i].data.fd, channel, type);
+ 			pthread_mutex_unlock(&knet_h->tx_mutex);
+ 		}
++
+ 		pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0271-crypto-fix-log-information.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0271-crypto-fix-log-information.patch
new file mode 100644
index 000000000..3d503f355
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0271-crypto-fix-log-information.patch
@@ -0,0 +1,32 @@ 
+From 063988e418f1e29cd911aae68b19eeac1d6adbc2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Jul 2019 11:18:33 +0200
+Subject: [PATCH] [crypto] fix log information
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 9f05fbaf..9d6757b6 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -151,8 +151,6 @@ int crypto_init(
+ 		goto out;
+ 	}
+ 
+-	log_debug(knet_h, KNET_SUB_CRYPTO, "security network overhead: %zu", knet_h->sec_header_size);
+-
+ out:
+ 	if (!err) {
+ 		knet_h->crypto_instance = new;
+@@ -161,6 +159,8 @@ out:
+ 		knet_h->sec_hash_size = new->sec_hash_size;
+ 		knet_h->sec_salt_size = new->sec_salt_size;
+ 
++		log_debug(knet_h, KNET_SUB_CRYPTO, "security network overhead: %zu", knet_h->sec_header_size);
++
+ 		if (current) {
+ 			if (crypto_modules_cmds[current->model].ops->fini != NULL) {
+ 				crypto_modules_cmds[current->model].ops->fini(knet_h, current);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0272-udp-log-information-about-detected-kernel-MTU.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0272-udp-log-information-about-detected-kernel-MTU.patch
new file mode 100644
index 000000000..d629ebbc1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0272-udp-log-information-about-detected-kernel-MTU.patch
@@ -0,0 +1,22 @@ 
+From 39a79e74fcf19a5ddec3c5e3ebeeb823d63b5069 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 31 Jul 2019 14:15:07 +0200
+Subject: [PATCH] [udp] log information about detected kernel MTU
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_udp.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 53d2ba0b..be990bbf 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -337,6 +337,7 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 									break;
+ 								} else {
+ 									knet_h->kernel_mtu = sock_err->ee_info;
++									log_debug(knet_h, KNET_SUB_TRANSP_UDP, "detected kernel MTU: %u", knet_h->kernel_mtu);
+ 									pthread_mutex_unlock(&knet_h->kmtu_mutex);
+ 								}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0273-docs-add-knet-packet-layout.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0273-docs-add-knet-packet-layout.patch
new file mode 100644
index 000000000..060be08dd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0273-docs-add-knet-packet-layout.patch
@@ -0,0 +1,43 @@ 
+From 8d41316679e1153a9b378c57827c7908e107e355 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 2 Aug 2019 10:43:09 +0200
+Subject: [PATCH] [docs] add knet packet layout
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_pmtud.c | 22 ++++++++++++++++++++++
+ 1 file changed, 22 insertions(+)
+
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 603f5951..2cd48f92 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -91,6 +91,28 @@ restart:
+ 		failsafe++;
+ 	}
+ 
++	/*
++	 * unencrypted packet looks like:
++	 *
++	 * | ip | protocol | knet_header | unencrypted data                                  |
++	 * | onwire_len                                                                      |
++	 * | overhead_len  |
++	 *                 | data_len                                                        |
++	 *                               | app MTU                                           |
++	 *
++	 * encrypted packet looks like (not to scale):
++	 *
++	 * | ip | protocol | salt | crypto(knet_header | data)      | crypto_data_pad | hash |
++	 * | onwire_len                                                                      |
++	 * | overhead_len  |
++	 *                 | data_len                                                        |
++	 *                                             | app MTU    |
++	 *
++	 * knet_h->sec_block_size is >= 0 if encryption will pad the data
++	 * knet_h->sec_salt_size is >= 0 if encryption is enabled
++	 * knet_h->sec_hash_size is >= 0 if signing is enabled
++	 */
++
+ 	data_len = onwire_len - overhead_len;
+ 
+ 	if (knet_h->crypto_instance) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0274-PMTUd-fix-MTU-calculation-when-using-crypto-and-add-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0274-PMTUd-fix-MTU-calculation-when-using-crypto-and-add-.patch
new file mode 100644
index 000000000..b5f50ef8c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0274-PMTUd-fix-MTU-calculation-when-using-crypto-and-add-.patch
@@ -0,0 +1,100 @@ 
+From 1e04409ba9f4091ce2a9eef397159eca1963f870 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 2 Aug 2019 10:44:23 +0200
+Subject: [PATCH] [PMTUd] fix MTU calculation when using crypto and add docs
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_pmtud.c | 55 ++++++++++++++++++++++++++++++++++++-----
+ 1 file changed, 49 insertions(+), 6 deletions(-)
+
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 2cd48f92..1a198065 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -113,29 +113,68 @@ restart:
+ 	 * knet_h->sec_hash_size is >= 0 if signing is enabled
+ 	 */
+ 
++	/*
++	 * common to all packets
++	 */
+ 	data_len = onwire_len - overhead_len;
+ 
+ 	if (knet_h->crypto_instance) {
+ 
++realign:
+ 		if (knet_h->sec_block_size) {
++
++			/*
++			 * drop both salt and hash, that leaves only the crypto data and padding
++			 * we need to calculate the padding based on the real encrypted data.
++			 */
++			data_len = data_len - (knet_h->sec_salt_size + knet_h->sec_hash_size);
++
++			/*
++			 * if the crypto mechanism requires padding, calculate the padding
++			 * and add it back to data_len because that's what the crypto layer
++			 * would do.
++			 */
+ 			pad_len = knet_h->sec_block_size - (data_len % knet_h->sec_block_size);
++
++			/*
++			 * if are at the boundary, reset padding
++			 */
+ 			if (pad_len == knet_h->sec_block_size) {
+ 				pad_len = 0;
+ 			}
+ 			data_len = data_len + pad_len;
+-		}
+ 
+-		data_len = data_len + (knet_h->sec_hash_size + knet_h->sec_salt_size + knet_h->sec_block_size);
+-
+-		if (knet_h->sec_block_size) {
++			/*
++			 * if our current data_len is higher than max_mtu_len
++			 * then we need to reduce by padding size (that is our
++			 * increment / decrement value)
++			 *
++			 * this generally happens only on the first PMTUd run
++			 */
+ 			while (data_len + overhead_len >= max_mtu_len) {
+ 				data_len = data_len - knet_h->sec_block_size;
+ 			}
++
++			/*
++			 * add both hash and salt size back, similar to padding above,
++			 * the crypto layer will add them to the data_len
++			 */
++			data_len = data_len + (knet_h->sec_salt_size + knet_h->sec_hash_size);
+ 		}
+ 
+ 		if (dst_link->last_bad_mtu) {
+-			while (data_len + overhead_len >= dst_link->last_bad_mtu) {
+-				data_len = data_len - (knet_h->sec_hash_size + knet_h->sec_salt_size + knet_h->sec_block_size);
++			if (data_len + overhead_len >= dst_link->last_bad_mtu) {
++				/*
++				 * reduce data_len to something lower than last_bad_mtu, overhead_len
++				 * and sec_block_size (decrementing step) - 1 (granularity)
++				 */
++				data_len = dst_link->last_bad_mtu - overhead_len - knet_h->sec_block_size - 1;
++				if (knet_h->sec_block_size) {
++					/*
++					 * make sure that data_len is aligned to the sec_block_size boundary
++					 */
++					goto realign;
++				}
+ 			}
+ 		}
+ 
+@@ -144,6 +183,10 @@ restart:
+ 			return -1;
+ 		}
+ 
++		/*
++		 * recalculate onwire_len based on crypto information
++		 * and place it in the PMTUd packet info
++		 */
+ 		onwire_len = data_len + overhead_len;
+ 		knet_h->pmtudbuf->khp_pmtud_size = onwire_len;
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0275-PMTUd-rework-the-whole-math-to-calculate-MTU.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0275-PMTUd-rework-the-whole-math-to-calculate-MTU.patch
new file mode 100644
index 000000000..370c03022
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0275-PMTUd-rework-the-whole-math-to-calculate-MTU.patch
@@ -0,0 +1,1108 @@ 
+From a378e16cce598d2f906ff08f47dcd942ef3432a1 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 12 Aug 2019 16:52:59 +0200
+Subject: [PATCH] [PMTUd] rework the whole math to calculate MTU
+
+internal changes:
+- drop the concept of sec_header_size that was completely wrong
+  and unnecessary
+- bump crypto API to version 3 due to the above change
+- clarify the difference between link->proto_overhead and
+  link->status->proto_overhead. We cannot rename the status
+  one as it would also change ABI.
+- add onwire.c with documentation on the packet format
+  and what various len(s) mean in context.
+- add 3 new functions to calculate MTUs back and forth
+  and use them around, hopefully with enough clarification
+  on why things are done in a given way.
+- heavily change thread_pmtud.c to use those new facilities.
+- fix major calculation issues when using crypto (non-crypto
+  was not affected by the problem).
+- fix checks around to make sure they match the new math.
+- fix padding calculation.
+- add functional PMTUd crypto test
+  this test can take several hours (12+) and should be executed
+  on a controlled environment since it automatically changes
+  loopback MTU to run tests.
+- fix way the lowest MTU is calculated during a PMTUd run
+  to avoid spurious double notifications.
+- drop redundant checks.
+
+user visible changes:
+- Global MTU is now calculated properly when using crypto
+  and values will be in general bigger than before due
+  to incorrect padding calculation in the previous implementation.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am                  |   1 +
+ libknet/crypto.c                     |   7 +-
+ libknet/crypto_model.h               |   3 +-
+ libknet/crypto_nss.c                 |   5 -
+ libknet/crypto_openssl.c             |   5 -
+ libknet/internals.h                  |   5 +-
+ libknet/links.c                      |  27 ++-
+ libknet/onwire.c                     | 127 +++++++++++
+ libknet/onwire.h                     |   8 +-
+ libknet/tests/Makefile.am            |  15 +-
+ libknet/tests/api_knet_send_crypto.c |   2 +-
+ libknet/tests/fun_pmtud_crypto.c     | 326 +++++++++++++++++++++++++++
+ libknet/threads_common.c             |   2 +-
+ libknet/threads_pmtud.c              | 183 ++++-----------
+ 14 files changed, 557 insertions(+), 159 deletions(-)
+ create mode 100644 libknet/onwire.c
+ create mode 100644 libknet/tests/fun_pmtud_crypto.c
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index d0807327..2fa24164 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -36,6 +36,7 @@ sources			= \
+ 			  links_acl_loopback.c \
+ 			  logging.c \
+ 			  netutils.c \
++			  onwire.c \
+ 			  threads_common.c \
+ 			  threads_dsthandler.c \
+ 			  threads_heartbeat.c \
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 9d6757b6..afa4f88c 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -154,12 +154,14 @@ int crypto_init(
+ out:
+ 	if (!err) {
+ 		knet_h->crypto_instance = new;
+-		knet_h->sec_header_size = new->sec_header_size;
+ 		knet_h->sec_block_size = new->sec_block_size;
+ 		knet_h->sec_hash_size = new->sec_hash_size;
+ 		knet_h->sec_salt_size = new->sec_salt_size;
+ 
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "security network overhead: %zu", knet_h->sec_header_size);
++		log_debug(knet_h, KNET_SUB_CRYPTO, "Hash size: %zu salt size: %zu block size: %zu",
++			  knet_h->sec_hash_size,
++			  knet_h->sec_salt_size,
++			  knet_h->sec_block_size);
+ 
+ 		if (current) {
+ 			if (crypto_modules_cmds[current->model].ops->fini != NULL) {
+@@ -195,7 +197,6 @@ void crypto_fini(
+ 			crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini(knet_h, knet_h->crypto_instance);
+ 		}
+ 		free(knet_h->crypto_instance);
+-		knet_h->sec_header_size = 0;
+ 		knet_h->sec_block_size = 0;
+ 		knet_h->sec_hash_size = 0;
+ 		knet_h->sec_salt_size = 0;
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index 70f6238f..b05e49c8 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -14,13 +14,12 @@
+ struct crypto_instance {
+ 	int	model;
+ 	void	*model_instance;
+-	size_t	sec_header_size;
+ 	size_t	sec_block_size;
+ 	size_t	sec_hash_size;
+ 	size_t	sec_salt_size;
+ };
+ 
+-#define KNET_CRYPTO_MODEL_ABI 2
++#define KNET_CRYPTO_MODEL_ABI 3
+ 
+ /*
+  * see compress_model.h for explanation of the various lib related functions
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 330b40cc..c624a479 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -801,10 +801,7 @@ static int nsscrypto_init(
+ 		goto out_err;
+ 	}
+ 
+-	crypto_instance->sec_header_size = 0;
+-
+ 	if (nsscrypto_instance->crypto_hash_type > 0) {
+-		crypto_instance->sec_header_size += nsshash_len[nsscrypto_instance->crypto_hash_type];
+ 		crypto_instance->sec_hash_size = nsshash_len[nsscrypto_instance->crypto_hash_type];
+ 	}
+ 
+@@ -821,8 +818,6 @@ static int nsscrypto_init(
+ 			}
+ 		}
+ 
+-		crypto_instance->sec_header_size += (block_size * 2);
+-		crypto_instance->sec_header_size += SALT_SIZE;
+ 		crypto_instance->sec_salt_size = SALT_SIZE;
+ 		crypto_instance->sec_block_size = block_size;
+ 	}
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 0cbc6f57..65714984 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -566,11 +566,8 @@ static int opensslcrypto_init(
+ 	memmove(opensslcrypto_instance->private_key, knet_handle_crypto_cfg->private_key, knet_handle_crypto_cfg->private_key_len);
+ 	opensslcrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len;
+ 
+-	crypto_instance->sec_header_size = 0;
+-
+ 	if (opensslcrypto_instance->crypto_hash_type) {
+ 		crypto_instance->sec_hash_size = EVP_MD_size(opensslcrypto_instance->crypto_hash_type);
+-		crypto_instance->sec_header_size += crypto_instance->sec_hash_size;
+ 	}
+ 
+ 	if (opensslcrypto_instance->crypto_cipher_type) {
+@@ -578,8 +575,6 @@ static int opensslcrypto_init(
+ 
+ 		block_size = EVP_CIPHER_block_size(opensslcrypto_instance->crypto_cipher_type);
+ 
+-		crypto_instance->sec_header_size += (block_size * 2);
+-		crypto_instance->sec_header_size += SALT_SIZE;
+ 		crypto_instance->sec_salt_size = SALT_SIZE;
+ 		crypto_instance->sec_block_size = block_size;
+ 	}
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 47ef904f..c3f484fd 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -71,7 +71,9 @@ struct knet_link {
+ 	uint8_t received_pong;
+ 	struct timespec ping_last;
+ 	/* used by PMTUD thread as temp per-link variables and should always contain the onwire_len value! */
+-	uint32_t proto_overhead;
++	uint32_t proto_overhead;		/* IP + UDP/SCTP overhead. NOT to be confused
++						   with stats.proto_overhead that includes also knet headers
++						   and crypto headers */
+ 	struct timespec pmtud_last;
+ 	uint32_t last_ping_size;
+ 	uint32_t last_good_mtu;
+@@ -198,7 +200,6 @@ struct knet_handle {
+ 	int pmtud_forcerun;
+ 	int pmtud_abort;
+ 	struct crypto_instance *crypto_instance;
+-	size_t sec_header_size;
+ 	size_t sec_block_size;
+ 	size_t sec_hash_size;
+ 	size_t sec_salt_size;
+diff --git a/libknet/links.c b/libknet/links.c
+index 4ec308ce..9b75be27 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -265,7 +265,32 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		host->status.reachable = 1;
+ 		link->status.mtu = KNET_PMTUD_SIZE_V6;
+ 	} else {
+-		link->status.mtu =  KNET_PMTUD_MIN_MTU_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
++		/*
++		 * calculate the minimum MTU that is safe to use,
++		 * based on RFCs and that each network device should
++		 * be able to support without any troubles
++		 */
++		if (link->dynamic == KNET_LINK_STATIC) {
++			/*
++			 * with static link we can be more precise than using
++			 * the generic calc_min_mtu()
++			 */
++			switch (link->dst_addr.ss_family) {
++				case AF_INET6:
++					link->status.mtu =  calc_max_data_outlen(knet_h, KNET_PMTUD_MIN_MTU_V6 - (KNET_PMTUD_OVERHEAD_V6 + link->proto_overhead));
++					break;
++				case AF_INET:
++					link->status.mtu =  calc_max_data_outlen(knet_h, KNET_PMTUD_MIN_MTU_V4 - (KNET_PMTUD_OVERHEAD_V4 + link->proto_overhead));
++					break;
++			}
++		} else {
++			/*
++			 * for dynamic links we start with the minimum MTU
++			 * possible and PMTUd will kick in immediately
++			 * after connection status is 1
++			 */
++			link->status.mtu =  calc_min_mtu(knet_h);
++		}
+ 		link->has_valid_mtu = 1;
+ 	}
+ 
+diff --git a/libknet/onwire.c b/libknet/onwire.c
+new file mode 100644
+index 00000000..143ac4b7
+--- /dev/null
++++ b/libknet/onwire.c
+@@ -0,0 +1,127 @@
++/*
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <sys/errno.h>
++#include <stdlib.h>
++#include <string.h>
++
++#include "crypto.h"
++#include "internals.h"
++#include "logging.h"
++#include "common.h"
++#include "transport_udp.h"
++#include "transport_sctp.h"
++
++/*
++ * unencrypted packet looks like:
++ *
++ * | ip | protocol  | knet_header | unencrypted data                                  |
++ * | onwire_len                                                                       |
++ * | proto_overhead |
++ *                  | data_len                                                        |
++ *                                | app MTU                                           |
++ *
++ * encrypted packet looks like (not to scale):
++ *
++ * | ip | protocol  | salt | crypto(knet_header | data)      | crypto_data_pad | hash |
++ * | onwire_len                                                                       |
++ * | proto_overhead |
++ *                  | data_len                                                        |
++ *                                              | app MTU    |
++ *
++ * knet_h->sec_block_size is >= 0 if encryption will pad the data
++ * knet_h->sec_salt_size is >= 0 if encryption is enabled
++ * knet_h->sec_hash_size is >= 0 if signing is enabled
++ */
++
++/*
++ * this function takes in the data that we would like to send
++ * and tells us the outgoing onwire data size with crypto and
++ * all the headers adjustment.
++ * calling thread needs to account for protocol overhead.
++ */
++
++size_t calc_data_outlen(knet_handle_t knet_h, size_t inlen)
++{
++	size_t outlen = inlen, pad_len = 0;
++
++	if (knet_h->sec_block_size) {
++		/*
++		 * if the crypto mechanism requires padding, calculate the padding
++		 * and add it back to outlen because that's what the crypto layer
++		 * would do.
++		 */
++		pad_len = knet_h->sec_block_size - (outlen % knet_h->sec_block_size);
++
++		outlen = outlen + pad_len;
++	}
++
++	return outlen + knet_h->sec_salt_size + knet_h->sec_hash_size;
++}
++
++/*
++ * this function takes in the data that we would like to send
++ * and tells us what is the real maximum data we can send
++ * accounting for headers and crypto
++ * calling thread needs to account for protocol overhead.
++ */
++
++size_t calc_max_data_outlen(knet_handle_t knet_h, size_t inlen)
++{
++	size_t outlen = inlen, pad_len = 0;
++
++	if (knet_h->sec_block_size) {
++		/*
++		 * drop both salt and hash, that leaves only the crypto data and padding
++		 * we need to calculate the padding based on the real encrypted data
++		 * that includes the knet_header.
++		 */
++		outlen = outlen - (knet_h->sec_salt_size + knet_h->sec_hash_size);
++
++		/*
++		 * if the crypto mechanism requires padding, calculate the padding
++		 * and remove it, to align the data.
++		 * NOTE: we need to remove pad_len + 1 because, based on testing,
++		 * if we send data that are already aligned to block_size, the
++		 * crypto implementations will add another block_size!
++		 * so we want to make sure that our data won't add an unnecessary
++		 * block_size that we need to remove later.
++		 */
++		pad_len = outlen % knet_h->sec_block_size;
++
++		outlen = outlen - (pad_len + 1);
++
++		/*
++		 * add both hash and salt size back, similar to padding above,
++		 * the crypto layer will add them to the outlen
++		 */
++		outlen = outlen + (knet_h->sec_salt_size + knet_h->sec_hash_size);
++	}
++
++	/*
++	 * drop KNET_HEADER_ALL_SIZE to provide a clean application MTU
++	 * and various crypto headers
++	 */
++	outlen = outlen - (KNET_HEADER_ALL_SIZE + knet_h->sec_salt_size + knet_h->sec_hash_size);
++
++	return outlen;
++}
++
++/*
++ * set the lowest possible value as failsafe for all links.
++ * KNET_PMTUD_MIN_MTU_V4 < KNET_PMTUD_MIN_MTU_V6
++ * KNET_PMTUD_OVERHEAD_V6 > KNET_PMTUD_OVERHEAD_V4
++ * KNET_PMTUD_SCTP_OVERHEAD > KNET_PMTUD_UDP_OVERHEAD
++ */
++
++size_t calc_min_mtu(knet_handle_t knet_h)
++{
++	return calc_max_data_outlen(knet_h, KNET_PMTUD_MIN_MTU_V4 - (KNET_PMTUD_OVERHEAD_V6 + KNET_PMTUD_SCTP_OVERHEAD));
++}
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index 9815bc38..74d4d091 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -120,7 +120,9 @@ struct knet_header_payload_ping {
+ #define KNET_PMTUD_SIZE_V4 65535
+ #define KNET_PMTUD_SIZE_V6 KNET_PMTUD_SIZE_V4
+ 
+-/* These two get the protocol-specific overheads added to them */
++/*
++ * IPv4/IPv6 header size
++ */
+ #define KNET_PMTUD_OVERHEAD_V4 20
+ #define KNET_PMTUD_OVERHEAD_V6 40
+ 
+@@ -199,4 +201,8 @@ struct knet_header {
+ #define KNET_HEADER_PMTUD_SIZE (KNET_HEADER_SIZE + sizeof(struct knet_header_payload_pmtud))
+ #define KNET_HEADER_DATA_SIZE (KNET_HEADER_SIZE + sizeof(struct knet_header_payload_data))
+ 
++size_t calc_data_outlen(knet_handle_t knet_h, size_t inlen);
++size_t calc_max_data_outlen(knet_handle_t knet_h, size_t inlen);
++size_t calc_min_mtu(knet_handle_t knet_h);
++
+ #endif
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 33465962..91607809 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -38,6 +38,12 @@ int_checks		= \
+ 
+ fun_checks		=
+ 
++# checks below need to be executed manually
++# or with a specifi environment
++
++long_run_checks		= \
++			  fun_pmtud_crypto_test
++
+ benchmarks		= \
+ 			  knet_bench_test
+ 
+@@ -45,6 +51,7 @@ noinst_PROGRAMS		= \
+ 			  api_knet_handle_new_limit_test \
+ 			  pckt_test \
+ 			  $(benchmarks) \
++			  $(long_run_checks) \
+ 			  $(check_PROGRAMS)
+ 
+ noinst_SCRIPTS		= \
+@@ -71,6 +78,7 @@ int_links_acl_ip_test_SOURCES = int_links_acl_ip.c \
+ 				../logging.c \
+ 				../netutils.c \
+ 				../threads_common.c \
++				../onwire.c \
+ 				../transports.c \
+ 				../transport_common.c \
+ 				../transport_loopback.c \
+@@ -88,4 +96,9 @@ knet_bench_test_SOURCES	= knet_bench.c \
+ 			  ../logging.c \
+ 			  ../compat.c \
+ 			  ../transport_common.c \
+-			  ../threads_common.c
++			  ../threads_common.c \
++			  ../onwire.c
++
++fun_pmtud_crypto_test_SOURCES = fun_pmtud_crypto.c \
++				test-common.c \
++				../onwire.c
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index 3e53e039..8d740d29 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -67,7 +67,7 @@ static void test(const char *model)
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+-	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha256", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+ 	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+diff --git a/libknet/tests/fun_pmtud_crypto.c b/libknet/tests/fun_pmtud_crypto.c
+new file mode 100644
+index 00000000..91c062c4
+--- /dev/null
++++ b/libknet/tests/fun_pmtud_crypto.c
+@@ -0,0 +1,326 @@
++/*
++ * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++#include <sys/ioctl.h>
++#include <net/ethernet.h>
++#include <ifaddrs.h>
++#include <net/if.h>
++
++#include "libknet.h"
++
++#include "compress.h"
++#include "internals.h"
++#include "netutils.h"
++#include "onwire.h"
++#include "test-common.h"
++
++static int private_data;
++
++static void sock_notify(void *pvt_data,
++			int datafd,
++			int8_t channel,
++			uint8_t tx_rx,
++			int error,
++			int errorno)
++{
++	return;
++}
++
++static int iface_fd = 0;
++static int default_mtu = 0;
++
++#ifdef KNET_LINUX
++const char *loopback = "lo";
++#endif
++#ifdef KNET_BSD
++const char *loopback = "lo0";
++#endif
++
++static int fd_init(void)
++{
++#ifdef KNET_LINUX
++	return socket(AF_INET, SOCK_STREAM, 0);
++#endif
++#ifdef KNET_BSD
++	return socket(AF_LOCAL, SOCK_DGRAM, 0);
++#endif
++	return -1;
++}
++
++static int set_iface_mtu(uint32_t mtu)
++{
++	int err = 0;
++	struct ifreq ifr;
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifr.ifr_name, loopback, IFNAMSIZ - 1);
++	ifr.ifr_mtu = mtu;
++
++	err = ioctl(iface_fd, SIOCSIFMTU, &ifr);
++
++	return err;
++}
++
++static int get_iface_mtu(void)
++{
++	int err = 0, savederrno = 0;
++	struct ifreq ifr;
++
++	memset(&ifr, 0, sizeof(struct ifreq));
++	strncpy(ifr.ifr_name, loopback, IFNAMSIZ - 1);
++
++	err = ioctl(iface_fd, SIOCGIFMTU, &ifr);
++	if (err) {
++		savederrno = errno;
++		goto out_clean;
++	}
++
++	err = ifr.ifr_mtu;
++
++out_clean:
++	errno = savederrno;
++	return err;
++}
++
++static int exit_local(int code)
++{
++	set_iface_mtu(default_mtu);
++	close(iface_fd);
++	iface_fd = 0;
++	exit(code);
++}
++
++static void test_mtu(const char *model, const char *crypto, const char *hash)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	int datafd = 0;
++	int8_t channel = 0;
++	struct sockaddr_storage lo;
++	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
++	unsigned int data_mtu, expected_mtu;
++	size_t calculated_iface_mtu = 0, detected_iface_mtu = 0;
++
++	if (make_local_sockaddr(&lo, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit_local(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_send with %s and valid data\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, crypto, sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, hash, sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
++		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++        }
++
++	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
++		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++        }
++
++	datafd = 0;
++	channel = -1;
++
++	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
++		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	if (knet_host_add(knet_h, 1) < 0) {
++		printf("knet_host_add failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	if (knet_link_set_pong_count(knet_h, 1, 0, 1) < 0) {
++		printf("knet_link_set_pong_count failed: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
++		printf("knet_link_set_enable failed: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	if (wait_for_host(knet_h, 1, 4, logfds[0], stdout) < 0) {
++		printf("timeout waiting for host to be reachable");
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_handle_pmtud_get(knet_h, &data_mtu) < 0) {
++		printf("knet_handle_pmtud_get failed error: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	calculated_iface_mtu = calc_data_outlen(knet_h, data_mtu + KNET_HEADER_ALL_SIZE) + 28;
++	detected_iface_mtu = get_iface_mtu();
++	/*
++	 * 28 = 20 IP header + 8 UDP header
++	 */
++	expected_mtu = calc_max_data_outlen(knet_h, detected_iface_mtu - 28);
++
++	if (expected_mtu != data_mtu) {
++		printf("Wrong MTU detected! interface mtu: %zu knet mtu: %u expected mtu: %u\n", detected_iface_mtu, data_mtu, expected_mtu);
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	if ((detected_iface_mtu - calculated_iface_mtu) >= knet_h->sec_block_size) {
++		printf("Wrong MTU detected! real iface mtu: %zu calculated: %zu\n", detected_iface_mtu, calculated_iface_mtu);
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit_local(FAIL);
++	}
++
++	knet_link_set_enable(knet_h, 1, 0, 0);
++	knet_link_clear_config(knet_h, 1, 0);
++	knet_host_remove(knet_h, 1);
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++static void test(const char *model, const char *crypto, const char *hash)
++{
++	int i = 576;
++	int max = 65535;
++
++	while (i <= max) {
++		printf("Setting interface MTU to: %i\n", i);
++		set_iface_mtu(i);
++		test_mtu(model, crypto, hash);
++		if (i == max) {
++			break;
++		}
++		i = i + 15;
++		if (i > max) {
++			i = max;
++		}
++	}
++}
++
++int main(int argc, char *argv[])
++{
++	struct knet_crypto_info crypto_list[16];
++	size_t crypto_list_entries;
++
++#ifdef KNET_BSD
++	if (is_memcheck() || is_helgrind()) {
++		printf("valgrind-freebsd cannot run this test properly. Skipping\n");
++		return SKIP;
++	}
++#endif
++
++	if (geteuid() != 0) {
++		printf("This test requires root privileges\n");
++		return SKIP;
++	}
++
++	iface_fd = fd_init();
++	if (iface_fd < 0) {
++		printf("fd_init failed: %s\n", strerror(errno));
++		return FAIL;
++	}
++
++	default_mtu = get_iface_mtu();
++	if (default_mtu < 0) {
++		printf("get_iface_mtu failed: %s\n", strerror(errno));
++		return FAIL;
++	}
++
++	memset(crypto_list, 0, sizeof(crypto_list));
++
++	if (knet_get_crypto_list(crypto_list, &crypto_list_entries) < 0) {
++		printf("knet_get_crypto_list failed: %s\n", strerror(errno));
++		return FAIL;
++	}
++
++	if (crypto_list_entries == 0) {
++		printf("no crypto modules detected. Skipping\n");
++		return SKIP;
++	}
++
++	test(crypto_list[0].name, "aes128", "sha1");
++	test(crypto_list[0].name, "aes128", "sha256");
++	test(crypto_list[0].name, "aes256", "sha1");
++	test(crypto_list[0].name, "aes256", "sha256");
++
++	exit_local(PASS);
++}
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 0c914c15..479c9c56 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -223,7 +223,7 @@ void force_pmtud_run(knet_handle_t knet_h, uint8_t subsystem, uint8_t reset_mtu)
+ {
+ 	if (reset_mtu) {
+ 		log_debug(knet_h, subsystem, "PMTUd has been reset to default");
+-		knet_h->data_mtu = KNET_PMTUD_MIN_MTU_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
++		knet_h->data_mtu = calc_min_mtu(knet_h);
+ 		if (knet_h->pmtud_notify_fn) {
+ 			knet_h->pmtud_notify_fn(knet_h->pmtud_notify_fn_private_data,
+ 						knet_h->data_mtu);
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 1a198065..1dd17882 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -25,16 +25,16 @@
+ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_link *dst_link)
+ {
+ 	int err, ret, savederrno, mutex_retry_limit, failsafe, use_kernel_mtu, warn_once;
+-	uint32_t kernel_mtu; /* record kernel_mtu from EMSGSIZE */
+-	size_t onwire_len;   /* current packet onwire size */
+-	size_t overhead_len; /* onwire packet overhead (protocol based) */
+-	size_t max_mtu_len;  /* max mtu for protocol */
+-	size_t data_len;     /* how much data we can send in the packet
+-			      * generally would be onwire_len - overhead_len
+-			      * needs to be adjusted for crypto
+-			      */
+-	size_t pad_len;	     /* crypto packet pad size, needs to move into crypto.c callbacks */
+-	ssize_t len;	     /* len of what we were able to sendto onwire */
++	uint32_t kernel_mtu;		/* record kernel_mtu from EMSGSIZE */
++	size_t onwire_len;   		/* current packet onwire size */
++	size_t ipproto_overhead_len;	/* onwire packet overhead (protocol based) */
++	size_t max_mtu_len;		/* max mtu for protocol */
++	size_t data_len;		/* how much data we can send in the packet
++					 * generally would be onwire_len - ipproto_overhead_len
++					 * needs to be adjusted for crypto
++					 */
++	size_t app_mtu_len;		/* real data that we can send onwire */
++	ssize_t len;			/* len of what we were able to sendto onwire */
+ 
+ 	struct timespec ts;
+ 	unsigned long long pong_timeout_adj_tmp;
+@@ -45,20 +45,16 @@ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_
+ 	mutex_retry_limit = 0;
+ 	failsafe = 0;
+ 
+-	dst_link->last_bad_mtu = 0;
+-
+ 	knet_h->pmtudbuf->khp_pmtud_link = dst_link->link_id;
+ 
+ 	switch (dst_link->dst_addr.ss_family) {
+ 		case AF_INET6:
+ 			max_mtu_len = KNET_PMTUD_SIZE_V6;
+-			overhead_len = KNET_PMTUD_OVERHEAD_V6 + dst_link->proto_overhead;
+-			dst_link->last_good_mtu = dst_link->last_ping_size + overhead_len;
++			ipproto_overhead_len = KNET_PMTUD_OVERHEAD_V6 + dst_link->proto_overhead;
+ 			break;
+ 		case AF_INET:
+ 			max_mtu_len = KNET_PMTUD_SIZE_V4;
+-			overhead_len = KNET_PMTUD_OVERHEAD_V4 + dst_link->proto_overhead;
+-			dst_link->last_good_mtu = dst_link->last_ping_size + overhead_len;
++			ipproto_overhead_len = KNET_PMTUD_OVERHEAD_V4 + dst_link->proto_overhead;
+ 			break;
+ 		default:
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "PMTUD aborted, unknown protocol");
+@@ -66,6 +62,9 @@ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_
+ 			break;
+ 	}
+ 
++	dst_link->last_bad_mtu = 0;
++	dst_link->last_good_mtu = dst_link->last_ping_size + ipproto_overhead_len;
++
+ 	/*
+ 	 * discovery starts from the top because kernel will
+ 	 * refuse to send packets > current iface mtu.
+@@ -92,107 +91,39 @@ restart:
+ 	}
+ 
+ 	/*
+-	 * unencrypted packet looks like:
+-	 *
+-	 * | ip | protocol | knet_header | unencrypted data                                  |
+-	 * | onwire_len                                                                      |
+-	 * | overhead_len  |
+-	 *                 | data_len                                                        |
+-	 *                               | app MTU                                           |
+-	 *
+-	 * encrypted packet looks like (not to scale):
+-	 *
+-	 * | ip | protocol | salt | crypto(knet_header | data)      | crypto_data_pad | hash |
+-	 * | onwire_len                                                                      |
+-	 * | overhead_len  |
+-	 *                 | data_len                                                        |
+-	 *                                             | app MTU    |
+-	 *
+-	 * knet_h->sec_block_size is >= 0 if encryption will pad the data
+-	 * knet_h->sec_salt_size is >= 0 if encryption is enabled
+-	 * knet_h->sec_hash_size is >= 0 if signing is enabled
++	 * common to all packets
+ 	 */
+ 
+ 	/*
+-	 * common to all packets
++	 * calculate the application MTU based on current onwire_len minus ipproto_overhead_len
+ 	 */
+-	data_len = onwire_len - overhead_len;
+-
+-	if (knet_h->crypto_instance) {
+ 
+-realign:
+-		if (knet_h->sec_block_size) {
++	app_mtu_len = calc_max_data_outlen(knet_h, onwire_len - ipproto_overhead_len);
+ 
+-			/*
+-			 * drop both salt and hash, that leaves only the crypto data and padding
+-			 * we need to calculate the padding based on the real encrypted data.
+-			 */
+-			data_len = data_len - (knet_h->sec_salt_size + knet_h->sec_hash_size);
+-
+-			/*
+-			 * if the crypto mechanism requires padding, calculate the padding
+-			 * and add it back to data_len because that's what the crypto layer
+-			 * would do.
+-			 */
+-			pad_len = knet_h->sec_block_size - (data_len % knet_h->sec_block_size);
+-
+-			/*
+-			 * if are at the boundary, reset padding
+-			 */
+-			if (pad_len == knet_h->sec_block_size) {
+-				pad_len = 0;
+-			}
+-			data_len = data_len + pad_len;
+-
+-			/*
+-			 * if our current data_len is higher than max_mtu_len
+-			 * then we need to reduce by padding size (that is our
+-			 * increment / decrement value)
+-			 *
+-			 * this generally happens only on the first PMTUd run
+-			 */
+-			while (data_len + overhead_len >= max_mtu_len) {
+-				data_len = data_len - knet_h->sec_block_size;
+-			}
++	/*
++	 * recalculate onwire len back that might be different based
++	 * on data padding from crypto layer.
++	 */
+ 
+-			/*
+-			 * add both hash and salt size back, similar to padding above,
+-			 * the crypto layer will add them to the data_len
+-			 */
+-			data_len = data_len + (knet_h->sec_salt_size + knet_h->sec_hash_size);
+-		}
++	onwire_len = calc_data_outlen(knet_h, app_mtu_len + KNET_HEADER_ALL_SIZE) + ipproto_overhead_len;
+ 
+-		if (dst_link->last_bad_mtu) {
+-			if (data_len + overhead_len >= dst_link->last_bad_mtu) {
+-				/*
+-				 * reduce data_len to something lower than last_bad_mtu, overhead_len
+-				 * and sec_block_size (decrementing step) - 1 (granularity)
+-				 */
+-				data_len = dst_link->last_bad_mtu - overhead_len - knet_h->sec_block_size - 1;
+-				if (knet_h->sec_block_size) {
+-					/*
+-					 * make sure that data_len is aligned to the sec_block_size boundary
+-					 */
+-					goto realign;
+-				}
+-			}
+-		}
++	/*
++	 * calculate the size of what we need to send to sendto(2).
++	 * see also onwire.c for packet format explanation.
++	 */
++	data_len = app_mtu_len + knet_h->sec_hash_size + knet_h->sec_salt_size + KNET_HEADER_ALL_SIZE;
+ 
+-		if (data_len < (knet_h->sec_hash_size + knet_h->sec_salt_size + knet_h->sec_block_size) + 1) {
++	if (knet_h->crypto_instance) {
++		if (data_len < (knet_h->sec_hash_size + knet_h->sec_salt_size) + 1) {
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "Aborting PMTUD process: link mtu smaller than crypto header detected (link might have been disconnected)");
+ 			return -1;
+ 		}
+ 
+-		/*
+-		 * recalculate onwire_len based on crypto information
+-		 * and place it in the PMTUd packet info
+-		 */
+-		onwire_len = data_len + overhead_len;
+ 		knet_h->pmtudbuf->khp_pmtud_size = onwire_len;
+ 
+ 		if (crypto_encrypt_and_sign(knet_h,
+ 					    (const unsigned char *)knet_h->pmtudbuf,
+-					    data_len - (knet_h->sec_hash_size + knet_h->sec_salt_size + knet_h->sec_block_size),
++					    data_len - (knet_h->sec_hash_size + knet_h->sec_salt_size),
+ 					    knet_h->pmtudbuf_crypt,
+ 					    (ssize_t *)&data_len) < 0) {
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "Unable to crypto pmtud packet");
+@@ -201,11 +132,8 @@ realign:
+ 
+ 		outbuf = knet_h->pmtudbuf_crypt;
+ 		knet_h->stats_extra.tx_crypt_pmtu_packets++;
+-
+ 	} else {
+-
+ 		knet_h->pmtudbuf->khp_pmtud_size = onwire_len;
+-
+ 	}
+ 
+ 	/* link has gone down, aborting pmtud */
+@@ -417,7 +345,7 @@ retry:
+ 				/*
+ 				 * account for IP overhead, knet headers and crypto in PMTU calculation
+ 				 */
+-				dst_link->status.mtu = onwire_len - dst_link->status.proto_overhead;
++				dst_link->status.mtu = calc_max_data_outlen(knet_h, onwire_len - ipproto_overhead_len);
+ 				pthread_mutex_unlock(&knet_h->pmtud_mutex);
+ 				return 0;
+ 			}
+@@ -437,7 +365,7 @@ retry:
+ 	goto restart;
+ }
+ 
+-static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_link *dst_link, unsigned int *min_mtu, int force_run)
++static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_link *dst_link, int force_run)
+ {
+ 	uint8_t saved_valid_pmtud;
+ 	unsigned int saved_pmtud;
+@@ -455,17 +383,22 @@ static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		timespec_diff(dst_link->pmtud_last, clock_now, &diff_pmtud);
+ 
+ 		if (diff_pmtud < interval) {
+-			*min_mtu = dst_link->status.mtu;
+ 			return dst_link->has_valid_mtu;
+ 		}
+ 	}
+ 
++	/*
++	 * status.proto_overhead should include all IP/(UDP|SCTP)/knet headers
++	 *
++	 * please note that it is not the same as link->proto_overhead that
++	 * includes only either UDP or SCTP (at the moment) overhead.
++	 */
+ 	switch (dst_link->dst_addr.ss_family) {
+ 		case AF_INET6:
+-			dst_link->status.proto_overhead = KNET_PMTUD_OVERHEAD_V6 + dst_link->proto_overhead + KNET_HEADER_ALL_SIZE + knet_h->sec_header_size;
++			dst_link->status.proto_overhead = KNET_PMTUD_OVERHEAD_V6 + dst_link->proto_overhead + KNET_HEADER_ALL_SIZE + knet_h->sec_hash_size + knet_h->sec_salt_size;
+ 			break;
+ 		case AF_INET:
+-			dst_link->status.proto_overhead = KNET_PMTUD_OVERHEAD_V4 + dst_link->proto_overhead + KNET_HEADER_ALL_SIZE + knet_h->sec_header_size;
++			dst_link->status.proto_overhead = KNET_PMTUD_OVERHEAD_V4 + dst_link->proto_overhead + KNET_HEADER_ALL_SIZE + knet_h->sec_hash_size + knet_h->sec_salt_size;
+ 			break;
+ 	}
+ 
+@@ -486,26 +419,6 @@ static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		dst_link->has_valid_mtu = 0;
+ 	} else {
+ 		dst_link->has_valid_mtu = 1;
+-		switch (dst_link->dst_addr.ss_family) {
+-			case AF_INET6:
+-				if (((dst_link->status.mtu + dst_link->status.proto_overhead) < KNET_PMTUD_MIN_MTU_V6) ||
+-				    ((dst_link->status.mtu + dst_link->status.proto_overhead) > KNET_PMTUD_SIZE_V6)) {
+-					log_debug(knet_h, KNET_SUB_PMTUD,
+-						  "PMTUD detected an IPv6 MTU out of bound value (%u) for host: %u link: %u.",
+-						  dst_link->status.mtu + dst_link->status.proto_overhead, dst_host->host_id, dst_link->link_id);
+-					dst_link->has_valid_mtu = 0;
+-				}
+-				break;
+-			case AF_INET:
+-				if (((dst_link->status.mtu + dst_link->status.proto_overhead) < KNET_PMTUD_MIN_MTU_V4) ||
+-				    ((dst_link->status.mtu + dst_link->status.proto_overhead) > KNET_PMTUD_SIZE_V4)) {
+-					log_debug(knet_h, KNET_SUB_PMTUD,
+-						  "PMTUD detected an IPv4 MTU out of bound value (%u) for host: %u link: %u.",
+-						  dst_link->status.mtu + dst_link->status.proto_overhead, dst_host->host_id, dst_link->link_id);
+-					dst_link->has_valid_mtu = 0;
+-				}
+-				break;
+-		}
+ 		if (dst_link->has_valid_mtu) {
+ 			if ((saved_pmtud) && (saved_pmtud != dst_link->status.mtu)) {
+ 				log_info(knet_h, KNET_SUB_PMTUD, "PMTUD link change for host: %u link: %u from %u to %u",
+@@ -513,9 +426,6 @@ static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host,
+ 			}
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "PMTUD completed for host: %u link: %u current link mtu: %u",
+ 				  dst_host->host_id, dst_link->link_id, dst_link->status.mtu);
+-			if (dst_link->status.mtu < *min_mtu) {
+-				*min_mtu = dst_link->status.mtu;
+-			}
+ 
+ 			/*
+ 			 * set pmtud_last, if we can, after we are done with the PMTUd process
+@@ -541,14 +451,14 @@ void *_handle_pmtud_link_thread(void *data)
+ 	struct knet_host *dst_host;
+ 	struct knet_link *dst_link;
+ 	int link_idx;
+-	unsigned int min_mtu, have_mtu;
++	unsigned int have_mtu;
+ 	unsigned int lower_mtu;
+ 	int link_has_mtu;
+ 	int force_run = 0;
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_STARTED);
+ 
+-	knet_h->data_mtu = KNET_PMTUD_MIN_MTU_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
++	knet_h->data_mtu = calc_min_mtu(knet_h);
+ 
+ 	/* preparing pmtu buffer */
+ 	knet_h->pmtudbuf->kh_version = KNET_HEADER_VERSION;
+@@ -578,7 +488,6 @@ void *_handle_pmtud_link_thread(void *data)
+ 		}
+ 
+ 		lower_mtu = KNET_PMTUD_SIZE_V4;
+-		min_mtu = KNET_PMTUD_SIZE_V4 - KNET_HEADER_ALL_SIZE - knet_h->sec_header_size;
+ 		have_mtu = 0;
+ 
+ 		for (dst_host = knet_h->host_head; dst_host != NULL; dst_host = dst_host->next) {
+@@ -593,14 +502,14 @@ void *_handle_pmtud_link_thread(void *data)
+ 				     (dst_link->status.dynconnected != 1)))
+ 					continue;
+ 
+-				link_has_mtu = _handle_check_pmtud(knet_h, dst_host, dst_link, &min_mtu, force_run);
++				link_has_mtu = _handle_check_pmtud(knet_h, dst_host, dst_link, force_run);
+ 				if (errno == EDEADLK) {
+ 					goto out_unlock;
+ 				}
+ 				if (link_has_mtu) {
+ 					have_mtu = 1;
+-					if (min_mtu < lower_mtu) {
+-						lower_mtu = min_mtu;
++					if (dst_link->status.mtu < lower_mtu) {
++						lower_mtu = dst_link->status.mtu;
+ 					}
+ 				}
+ 			}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0276-PMTUd-add-dynamic-pong-timeout-when-using-crypto.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0276-PMTUd-add-dynamic-pong-timeout-when-using-crypto.patch
new file mode 100644
index 000000000..d1abde948
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0276-PMTUd-add-dynamic-pong-timeout-when-using-crypto.patch
@@ -0,0 +1,195 @@ 
+From e260ba9179e9c20a588be899d0f740f0daa13fa0 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 13 Aug 2019 06:41:32 +0200
+Subject: [PATCH] [PMTUd] add dynamic pong timeout when using crypto
+
+problem originally reported by proxmox community, users
+observed that under pressure the MTU would flap back and forth
+between 2 values due to other node response timeout.
+
+implement a dynamic timeout multiplier when using crypto that
+should solve the problem in a more flexible fashion.
+
+When a timeout hits, those new logs will show:
+
+[knet]: [info] host: host: 1 (passive) best link: 0 (pri: 0)
+[knet]: [debug] pmtud: Starting PMTUD for host: 1 link: 0
+[knet]: [debug] pmtud: Increasing PMTUd response timeout multiplier to (4) for host 1 link: 0
+[knet]: [info] pmtud: PMTUD link change for host: 1 link: 0 from 469 to 65429
+[knet]: [debug] pmtud: PMTUD completed for host: 1 link: 0 current link mtu: 65429
+[knet]: [info] pmtud: Global data MTU changed to: 65429
+[knet]: [debug] pmtud: Starting PMTUD for host: 1 link: 0
+[knet]: [debug] pmtud: Increasing PMTUd response timeout multiplier to (8) for host 1 link: 0
+[knet]: [debug] pmtud: Increasing PMTUd response timeout multiplier to (16) for host 1 link: 0
+[knet]: [debug] pmtud: Increasing PMTUd response timeout multiplier to (32) for host 1 link: 0
+[knet]: [debug] pmtud: Increasing PMTUd response timeout multiplier to (64) for host 1 link: 0
+[knet]: [debug] pmtud: PMTUD completed for host: 1 link: 0 current link mtu: 65429
+[knet]: [debug] pmtud: Starting PMTUD for host: 1 link: 0
+[knet]: [debug] pmtud: Increasing PMTUd response timeout multiplier to (128) for host 1 link: 0
+[knet]: [debug] pmtud: PMTUD completed for host: 1 link: 0 current link mtu: 65429
+
+and when the latency reduces and it is safe to be more responsive again:
+
+[knet]: [debug] pmtud: Starting PMTUD for host: 1 link: 0
+[knet]: [debug] pmtud: Decreasing PMTUd response timeout multiplier to (64) for host 1 link: 0
+[knet]: [debug] pmtud: PMTUD completed for host: 1 link: 0 current link mtu: 65429
+
+....
+
+testing this patch on normal hosts is a bit challenging tho.
+
+Patch was tested by hardcoding a super low timeout here:
+
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 4f0ba0f..5e2b89b 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -261,7 +271,8 @@ retry:
+                        /*
+                         * crypto, under pressure, is a royal PITA
+                         */
+-                       pong_timeout_adj_tmp = dst_link->pong_timeout_adj * 2;
++                       //pong_timeout_adj_tmp = dst_link->pong_timeout_adj * dst_link->pmtud_crypto_timeout_multiplier;
++                       pong_timeout_adj_tmp = 30 * dst_link->pmtud_crypto_timeout_multiplier;
+                } else {
+                        pong_timeout_adj_tmp = dst_link->pong_timeout_adj;
+                }
+
+and using a long running version of api_knet_send_crypto_test with a short PMTUd setfreq (10 sec).
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h     |  1 +
+ libknet/links.c         |  1 +
+ libknet/links.h         | 10 ++++++++++
+ libknet/threads_pmtud.c | 44 ++++++++++++++++++++++++++++++++++++++---
+ 4 files changed, 53 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index c3f484fd..5ddab9a8 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -80,6 +80,7 @@ struct knet_link {
+ 	uint32_t last_bad_mtu;
+ 	uint32_t last_sent_mtu;
+ 	uint32_t last_recv_mtu;
++	uint32_t pmtud_crypto_timeout_multiplier;/* used by PMTUd to adjust timeouts on high loads */
+ 	uint8_t has_valid_mtu;
+ };
+ 
+diff --git a/libknet/links.c b/libknet/links.c
+index 9b75be27..cd18d9cc 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -219,6 +219,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		}
+ 	}
+ 
++	link->pmtud_crypto_timeout_multiplier = KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MIN;
+ 	link->pong_count = KNET_LINK_DEFAULT_PONG_COUNT;
+ 	link->has_valid_mtu = 0;
+ 	link->ping_interval = KNET_LINK_DEFAULT_PING_INTERVAL * 1000; /* microseconds */
+diff --git a/libknet/links.h b/libknet/links.h
+index e14958de..c8ca6109 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -30,6 +30,16 @@
+  */
+ #define KNET_LINK_PONG_TIMEOUT_LAT_MUL	2
+ 
++/*
++ * under heavy load with crypto enabled, it takes much
++ * longer time to receive a response from the other node.
++ *
++ * 128 is somewhat arbitrary number but we want to set a limit
++ * and report failures after that.
++ */
++#define KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MIN	  2
++#define KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MAX	128
++
+ int _link_updown(knet_handle_t knet_h, knet_node_id_t node_id, uint8_t link_id,
+ 		 unsigned int enabled, unsigned int connected);
+ 
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 1dd17882..d342697e 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -36,8 +36,9 @@ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_
+ 	size_t app_mtu_len;		/* real data that we can send onwire */
+ 	ssize_t len;			/* len of what we were able to sendto onwire */
+ 
+-	struct timespec ts;
+-	unsigned long long pong_timeout_adj_tmp;
++	struct timespec ts, pmtud_crypto_start_ts, pmtud_crypto_stop_ts;
++	unsigned long long pong_timeout_adj_tmp, timediff;
++	int pmtud_crypto_reduce = 1;
+ 	unsigned char *outbuf = (unsigned char *)knet_h->pmtudbuf;
+ 
+ 	warn_once = 0;
+@@ -242,6 +243,15 @@ retry:
+ 			return -1;
+ 		}
+ 
++		/*
++		 * non fatal, we can wait the next round to reduce the
++		 * multiplier
++		 */
++		if (clock_gettime(CLOCK_MONOTONIC, &pmtud_crypto_start_ts) < 0) {
++			log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get current time: %s", strerror(errno));
++			pmtud_crypto_reduce = 0;
++		}
++
+ 		/*
+ 		 * set PMTUd reply timeout to match pong_timeout on a given link
+ 		 *
+@@ -261,7 +271,7 @@ retry:
+ 			/*
+ 			 * crypto, under pressure, is a royal PITA
+ 			 */
+-			pong_timeout_adj_tmp = dst_link->pong_timeout_adj * 2;
++			pong_timeout_adj_tmp = dst_link->pong_timeout_adj * dst_link->pmtud_crypto_timeout_multiplier;
+ 		} else {
+ 			pong_timeout_adj_tmp = dst_link->pong_timeout_adj;
+ 		}
+@@ -295,6 +305,17 @@ retry:
+ 
+ 		if (ret) {
+ 			if (ret == ETIMEDOUT) {
++				if ((knet_h->crypto_instance) && (dst_link->pmtud_crypto_timeout_multiplier < KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MAX)) {
++					dst_link->pmtud_crypto_timeout_multiplier = dst_link->pmtud_crypto_timeout_multiplier * 2;
++					pmtud_crypto_reduce = 0;
++					log_debug(knet_h, KNET_SUB_PMTUD,
++							"Increasing PMTUd response timeout multiplier to (%u) for host %u link: %u",
++							dst_link->pmtud_crypto_timeout_multiplier,
++							dst_host->host_id,
++							dst_link->link_id);
++					pthread_mutex_unlock(&knet_h->pmtud_mutex);
++					goto restart;
++				}
+ 				if (!warn_once) {
+ 					log_warn(knet_h, KNET_SUB_PMTUD,
+ 							"possible MTU misconfiguration detected. "
+@@ -323,6 +344,23 @@ retry:
+ 			}
+ 		}
+ 
++		if ((knet_h->crypto_instance) && (pmtud_crypto_reduce == 1) &&
++		    (dst_link->pmtud_crypto_timeout_multiplier > KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MIN)) {
++			if (!clock_gettime(CLOCK_MONOTONIC, &pmtud_crypto_stop_ts)) {
++				timespec_diff(pmtud_crypto_start_ts, pmtud_crypto_stop_ts, &timediff);
++				if (((pong_timeout_adj_tmp * 1000) / 2) > timediff) {
++					dst_link->pmtud_crypto_timeout_multiplier = dst_link->pmtud_crypto_timeout_multiplier / 2;
++					log_debug(knet_h, KNET_SUB_PMTUD,
++							"Decreasing PMTUd response timeout multiplier to (%u) for host %u link: %u",
++							dst_link->pmtud_crypto_timeout_multiplier,
++							dst_host->host_id,
++							dst_link->link_id);
++				}
++			} else {
++				log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get current time: %s", strerror(errno));
++			}
++		}
++
+ 		if ((dst_link->last_recv_mtu != onwire_len) || (ret)) {
+ 			dst_link->last_bad_mtu = onwire_len;
+ 		} else {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0277-PMTUd-add-ability-to-manually-override-MTU-and-disab.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0277-PMTUd-add-ability-to-manually-override-MTU-and-disab.patch
new file mode 100644
index 000000000..9dcfe09dd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0277-PMTUd-add-ability-to-manually-override-MTU-and-disab.patch
@@ -0,0 +1,445 @@ 
+From 3b27a35e6178e48b1688d679ee21f8e1a6af1d65 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 20 Aug 2019 06:57:45 +0200
+Subject: [PATCH] [PMTUd] add ability to manually override MTU and disable
+ PMTUd
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c                          |  35 ++++
+ libknet/internals.h                       |   1 +
+ libknet/libknet.h                         |  26 +++
+ libknet/tests/api-check.mk                |   4 +
+ libknet/tests/api_knet_handle_pmtud_set.c | 226 ++++++++++++++++++++++
+ libknet/threads_pmtud.c                   |  48 ++++-
+ man/Makefile.am                           |   1 +
+ 7 files changed, 333 insertions(+), 8 deletions(-)
+ create mode 100644 libknet/tests/api_knet_handle_pmtud_set.c
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 10382480..4221bee5 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1361,6 +1361,41 @@ int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
+ 	return 0;
+ }
+ 
++int knet_handle_pmtud_set(knet_handle_t knet_h,
++			  unsigned int iface_mtu)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (iface_mtu > KNET_PMTUD_SIZE_V4) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_PMTUD, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	log_info(knet_h, KNET_SUB_PMTUD, "MTU manually set to: %u", iface_mtu);
++
++	knet_h->manual_mtu = iface_mtu;
++
++	force_pmtud_run(knet_h, KNET_SUB_PMTUD, 0);
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
+ int knet_handle_pmtud_get(knet_handle_t knet_h,
+ 			  unsigned int *data_mtu)
+ {
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 5ddab9a8..e0be5770 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -164,6 +164,7 @@ struct knet_handle {
+ 	int dst_link_handler_epollfd;
+ 	uint8_t use_access_lists; /* set to 0 for disable, 1 for enable */
+ 	unsigned int pmtud_interval;
++	unsigned int manual_mtu;
+ 	unsigned int data_mtu;	/* contains the max data size that we can send onwire
+ 				 * without frags */
+ 	struct knet_host *host_head;
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index acd1c86b..11350dba 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -614,6 +614,32 @@ int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
+ 						void *private_data,
+ 						unsigned int data_mtu));
+ 
++/**
++ * knet_handle_pmtud_set
++ *
++ * @brief Set the current interface MTU
++ *
++ * knet_h    - pointer to knet_handle_t
++ *
++ * iface_mtu - current interface MTU, value 0 to 65535. 0 will
++ *             re-enable automatic MTU discovery.
++ *             In a setup with multiple interfaces, please specify
++ *             the lowest MTU between the selected intefaces.
++ *             knet will automatically adjust this value for
++ *             all headers overhead and set the correct data_mtu.
++ *             data_mtu can be retrivied with knet_handle_pmtud_get(3)
++ *             or applications will receive a pmtud_nofity event
++ *             if enabled via knet_handle_enable_pmtud_notify(3).
++ *
++ * @return
++ * knet_handle_pmtud_set returns
++ * 0 on success
++ * -1 on error and errno is set.
++ */
++
++int knet_handle_pmtud_set(knet_handle_t knet_h,
++			  unsigned int iface_mtu);
++
+ /**
+  * knet_handle_pmtud_get
+  *
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 102ec52a..2ae2b30b 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -38,6 +38,7 @@ api_checks		= \
+ 			  api_knet_handle_pmtud_getfreq_test \
+ 			  api_knet_handle_enable_pmtud_notify_test \
+ 			  api_knet_handle_pmtud_get_test \
++			  api_knet_handle_pmtud_set_test \
+ 			  api_knet_host_add_test \
+ 			  api_knet_host_remove_test \
+ 			  api_knet_host_set_name_test \
+@@ -170,6 +171,9 @@ api_knet_handle_enable_pmtud_notify_test_SOURCES = api_knet_handle_enable_pmtud_
+ api_knet_handle_pmtud_get_test_SOURCES = api_knet_handle_pmtud_get.c \
+ 					 test-common.c
+ 
++api_knet_handle_pmtud_set_test_SOURCES = api_knet_handle_pmtud_set.c \
++					 test-common.c
++
+ api_knet_host_add_test_SOURCES = api_knet_host_add.c \
+ 				 test-common.c
+ 
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+new file mode 100644
+index 00000000..7a7ffb34
+--- /dev/null
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -0,0 +1,226 @@
++/*
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "test-common.h"
++
++static int private_data;
++
++static void sock_notify(void *pvt_data,
++			int datafd,
++			int8_t channel,
++			uint8_t tx_rx,
++			int error,
++			int errorno)
++{
++	return;
++}
++
++static void test(void)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	unsigned int iface_mtu = 0, data_mtu;
++	int datafd = 0;
++	int8_t channel = 0;
++	struct sockaddr_storage lo;
++
++	if (make_local_sockaddr(&lo, 0) < 0) {
++		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	printf("Test knet_handle_pmtud_set incorrect knet_h\n");
++
++	if ((!knet_handle_pmtud_set(NULL, iface_mtu)) || (errno != EINVAL)) {
++		printf("knet_handle_pmtud_set accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	flush_logs(logfds[0], stdout);
++
++	iface_mtu = KNET_PMTUD_SIZE_V4 + 1;
++	printf("Test knet_handle_pmtud_set with wrong iface_mtu\n");
++	if ((!knet_handle_pmtud_set(knet_h, iface_mtu)) || (errno != EINVAL)) {
++		printf("knet_handle_pmtud_set accepted invalid data_mtu or returned incorrect error: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
++		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++        }
++
++	datafd = 0;
++	channel = -1;
++
++	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
++		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_host_add(knet_h, 1) < 0) {
++		printf("knet_host_add failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++		printf("Unable to configure link: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_set_pong_count(knet_h, 1, 0, 1) < 0) {
++		printf("knet_link_set_pong_count failed: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
++		printf("knet_link_set_enable failed: %s\n", strerror(errno));
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (wait_for_host(knet_h, 1, 4, logfds[0], stdout) < 0) {
++		printf("timeout waiting for host to be reachable");
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_handle_pmtud_get(knet_h, &data_mtu) < 0) {
++		printf("knet_handle_pmtud_get failed error: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	/*
++	 * 28 = IP (20) + UDP (8)
++	 */
++	iface_mtu = data_mtu + 28 + KNET_HEADER_ALL_SIZE - 64;
++	printf("Test knet_handle_pmtud_set with iface_mtu %u\n", iface_mtu);
++
++	if (knet_handle_pmtud_set(knet_h, iface_mtu) < 0) {
++		printf("knet_handle_pmtud_set failed error: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	/*
++	 * wait for PMTUd to pick up the change
++	 */
++	sleep(1);
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->data_mtu != data_mtu - 64) {
++		printf("knet_handle_pmtud_set failed to set the value\n");
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	printf("Test knet_handle_pmtud_set with iface_mtu 0\n");
++	if (knet_handle_pmtud_set(knet_h, 0) < 0) {
++		printf("knet_handle_pmtud_set failed error: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	/*
++	 * wait for PMTUd to pick up the change
++	 */
++	sleep(1);
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->data_mtu != data_mtu) {
++		printf("knet_handle_pmtud_set failed to redetect MTU\n");
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	knet_link_set_enable(knet_h, 1, 0, 0);
++	knet_link_clear_config(knet_h, 1, 0);
++	knet_host_remove(knet_h, 1);
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index d342697e..ebd5b4b0 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -22,6 +22,28 @@
+ #include "threads_common.h"
+ #include "threads_pmtud.h"
+ 
++static int _calculate_manual_mtu(knet_handle_t knet_h, struct knet_link *dst_link)
++{
++	size_t ipproto_overhead_len;	/* onwire packet overhead (protocol based) */
++
++	switch (dst_link->dst_addr.ss_family) {
++		case AF_INET6:
++			ipproto_overhead_len = KNET_PMTUD_OVERHEAD_V6 + dst_link->proto_overhead;
++			break;
++		case AF_INET:
++			ipproto_overhead_len = KNET_PMTUD_OVERHEAD_V4 + dst_link->proto_overhead;
++			break;
++		default:
++			log_debug(knet_h, KNET_SUB_PMTUD, "unknown protocol");
++			return 0;
++			break;
++	}
++
++	dst_link->status.mtu = calc_max_data_outlen(knet_h, knet_h->manual_mtu - ipproto_overhead_len);
++
++	return 1;
++}
++
+ static int _handle_check_link_pmtud(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_link *dst_link)
+ {
+ 	int err, ret, savederrno, mutex_retry_limit, failsafe, use_kernel_mtu, warn_once;
+@@ -540,14 +562,24 @@ void *_handle_pmtud_link_thread(void *data)
+ 				     (dst_link->status.dynconnected != 1)))
+ 					continue;
+ 
+-				link_has_mtu = _handle_check_pmtud(knet_h, dst_host, dst_link, force_run);
+-				if (errno == EDEADLK) {
+-					goto out_unlock;
+-				}
+-				if (link_has_mtu) {
+-					have_mtu = 1;
+-					if (dst_link->status.mtu < lower_mtu) {
+-						lower_mtu = dst_link->status.mtu;
++				if (!knet_h->manual_mtu) {
++					link_has_mtu = _handle_check_pmtud(knet_h, dst_host, dst_link, force_run);
++					if (errno == EDEADLK) {
++						goto out_unlock;
++					}
++					if (link_has_mtu) {
++						have_mtu = 1;
++						if (dst_link->status.mtu < lower_mtu) {
++							lower_mtu = dst_link->status.mtu;
++						}
++					}
++				} else {
++					link_has_mtu = _calculate_manual_mtu(knet_h, dst_link);
++					if (link_has_mtu) {
++						have_mtu = 1;
++						if (dst_link->status.mtu < lower_mtu) {
++							lower_mtu = dst_link->status.mtu;
++						}
+ 					}
+ 				}
+ 			}
+diff --git a/man/Makefile.am b/man/Makefile.am
+index a473e900..fda8b216 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -58,6 +58,7 @@ knet_man3_MANS = \
+ 		knet_handle_new.3 \
+ 		knet_handle_new_ex.3 \
+ 		knet_handle_pmtud_get.3 \
++		knet_handle_pmtud_set.3 \
+ 		knet_handle_pmtud_getfreq.3 \
+ 		knet_handle_pmtud_setfreq.3 \
+ 		knet_handle_remove_datafd.3 \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0278-build-bump-soname-to-indicate-new-API-call.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0278-build-bump-soname-to-indicate-new-API-call.patch
new file mode 100644
index 000000000..fdc523613
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0278-build-bump-soname-to-indicate-new-API-call.patch
@@ -0,0 +1,23 @@ 
+From 7e818a3d94a1198923227d24e367ec152c68c3ad Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 21 Aug 2019 06:26:41 +0200
+Subject: [PATCH] [build] bump soname to indicate new API call
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 2fa24164..4bc48754 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -18,7 +18,7 @@ EXTRA_DIST		= $(SYMFILE)
+ SUBDIRS			= . tests
+ 
+ # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+-libversion		= 3:0:2
++libversion		= 4:0:3
+ 
+ # override global LIBS that pulls in lots of craft we don't need here
+ LIBS			=
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0279-Default-compress-level-use.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0279-Default-compress-level-use.patch
new file mode 100644
index 000000000..ca4019efa
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0279-Default-compress-level-use.patch
@@ -0,0 +1,396 @@ 
+From 678a2b50ca2d845cf3612ba7953f5dfa0806a189 Mon Sep 17 00:00:00 2001
+From: yuan ren <yren@suse.com>
+Date: Mon, 17 Jun 2019 19:58:20 +0800
+Subject: [PATCH] Default compress level use
+
+Discuss with Fabio, invalid compression level not the knet
+responsible for, so error logged. But if compress success but
+dstLen larger than srcLen, defualt compression level will be
+used, because the request level is not effective.
+
+Signed-off-by: yuan ren <yren@suse.com>
+---
+ libknet/compress.c                       | 27 ++++++++++++++++++++++++
+ libknet/compress_bzip2.c                 | 14 +++++++++++-
+ libknet/compress_lz4.c                   | 15 ++++++++++++-
+ libknet/compress_lz4hc.c                 | 13 +++++++++++-
+ libknet/compress_lzma.c                  | 14 +++++++++++-
+ libknet/compress_lzo2.c                  | 15 ++++++++++++-
+ libknet/compress_model.h                 |  8 ++++++-
+ libknet/compress_zlib.c                  | 14 +++++++++++-
+ libknet/compress_zstd.c                  | 14 +++++++++++-
+ libknet/tests/api_knet_handle_compress.c | 16 ++++++++++++++
+ 10 files changed, 142 insertions(+), 8 deletions(-)
+
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 24755c77..e85448b5 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -195,6 +195,7 @@ static int compress_lib_test(knet_handle_t knet_h)
+ 	unsigned char dst[KNET_DATABUFSIZE_COMPRESS];
+ 	ssize_t dst_comp_len = KNET_DATABUFSIZE_COMPRESS, dst_decomp_len = KNET_DATABUFSIZE;
+ 	unsigned int i;
++	int request_level;
+ 
+ 	memset(src, 0, KNET_DATABUFSIZE);
+ 	memset(dst, 0, KNET_DATABUFSIZE_COMPRESS);
+@@ -209,6 +210,32 @@ static int compress_lib_test(knet_handle_t knet_h)
+ 		log_err(knet_h, KNET_SUB_COMPRESS, "Unable to compress test buffer. Please check your compression settings: %s", strerror(savederrno));
+ 		errno = savederrno;
+ 		return -1;
++	} else if ((long unsigned int)dst_comp_len >= KNET_DATABUFSIZE) {
++		/*
++		 * compress not effective, try again using default compression level when available
++		 */
++		request_level = knet_h->compress_level;
++		log_warn(knet_h, KNET_SUB_COMPRESS, "Requested compression level (%d) did not generate any compressed data (source: %zu destination: %zu)",
++				request_level, sizeof(src), dst_comp_len);
++
++		if ((!compress_modules_cmds[knet_h->compress_model].ops->get_default_level()) ||
++				((knet_h->compress_level = compress_modules_cmds[knet_h->compress_model].ops->get_default_level()) == KNET_COMPRESS_UNKNOWN_DEFAULT)) {
++                        log_err(knet_h, KNET_SUB_COMPRESS, "compression %s does not provide a default value",
++					compress_modules_cmds[knet_h->compress_model].model_name);
++			return -1;
++                } else {
++			memset(src, 0, KNET_DATABUFSIZE);
++			memset(dst, 0, KNET_DATABUFSIZE_COMPRESS);
++			dst_comp_len = KNET_DATABUFSIZE_COMPRESS;
++			if (compress_modules_cmds[knet_h->compress_model].ops->compress(knet_h, src, KNET_DATABUFSIZE, dst, &dst_comp_len) < 0) {
++                                savederrno = errno;
++                                log_err(knet_h, KNET_SUB_COMPRESS, "Unable to compress with default compression level: %s", strerror(savederrno));
++				errno = savederrno;
++				return -1;
++			}
++			log_warn(knet_h, KNET_SUB_COMPRESS, "Requested compression level (%d) did not work, switching to default (%d)",
++					request_level, knet_h->compress_level);
++		}
+ 	}
+ 
+ 	if (compress_modules_cmds[knet_h->compress_model].ops->decompress(knet_h, dst, dst_comp_len, src, &dst_decomp_len) < 0) {
+diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c
+index 5a972fff..68f5280c 100644
+--- a/libknet/compress_bzip2.c
++++ b/libknet/compress_bzip2.c
+@@ -15,6 +15,12 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef BZIP2_COMPRESS_LEVEL
++#define KNET_COMPRESS_DEFAULT BZIP2_COMPRESS_LEVEL
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
++
+ static int bzip2_compress(
+ 	knet_handle_t knet_h,
+ 	const unsigned char *buf_in,
+@@ -103,6 +109,11 @@ static int bzip2_decompress(
+ 	return err;
+ }
+ 
++static int bzip2_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	NULL,
+@@ -110,5 +121,6 @@ compress_ops_t compress_model = {
+ 	NULL,
+ 	NULL,
+ 	bzip2_compress,
+-	bzip2_decompress
++	bzip2_decompress,
++	bzip2_get_default_level
+ };
+diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c
+index 60aa1966..db0fa514 100644
+--- a/libknet/compress_lz4.c
++++ b/libknet/compress_lz4.c
+@@ -6,6 +6,7 @@
+  * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
++#define ACCELERATION_DEFAULT 1 /* lz4 default compression level from lz4.c */
+ 
+ #include "config.h"
+ 
+@@ -15,6 +16,12 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef LZ4_COMPRESS_DEFAULT
++#define KNET_COMPRESS_DEFAULT LZ4_COMPRESS_DEFAULT
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
++
+ static int lz4_compress(
+ 	knet_handle_t knet_h,
+ 	const unsigned char *buf_in,
+@@ -80,6 +87,11 @@ static int lz4_decompress(
+ 	return err;
+ }
+ 
++static int lz4_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	NULL,
+@@ -87,5 +99,6 @@ compress_ops_t compress_model = {
+ 	NULL,
+ 	NULL,
+ 	lz4_compress,
+-	lz4_decompress
++	lz4_decompress,
++	lz4_get_default_level
+ };
+diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c
+index 781bf12f..963ad66c 100644
+--- a/libknet/compress_lz4hc.c
++++ b/libknet/compress_lz4hc.c
+@@ -16,6 +16,11 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef LZ4HC_CLEVEL_DEFAULT
++#define KNET_COMPRESS_DEFAULT LZ4HC_CLEVEL_DEFAULT /* lz4hc default compression level from lz4hc.h */
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
+ #ifdef LZ4HC_CLEVEL_MAX
+ #define KNET_LZ4HC_MAX LZ4HC_CLEVEL_MAX
+ #endif
+@@ -91,6 +96,11 @@ static int lz4_decompress(
+ 	return err;
+ }
+ 
++static int lz4hc_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	NULL,
+@@ -98,5 +108,6 @@ compress_ops_t compress_model = {
+ 	NULL,
+ 	NULL,
+ 	lz4hc_compress,
+-	lz4_decompress
++	lz4_decompress,
++	lz4hc_get_default_level
+ };
+diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
+index 7fdd1782..b4fd05c3 100644
+--- a/libknet/compress_lzma.c
++++ b/libknet/compress_lzma.c
+@@ -15,6 +15,12 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef LZMA_PRESET_DEFAULT
++#define KNET_COMPRESS_DEFAULT LZMA_PRESET_DEFAULT /* lzma default compression level from lzma.h */
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
++
+ static int lzma_compress(
+ 	knet_handle_t knet_h,
+ 	const unsigned char *buf_in,
+@@ -114,6 +120,11 @@ static int lzma_decompress(
+ 	return err;
+ }
+ 
++static int lzma_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	NULL,
+@@ -121,5 +132,6 @@ compress_ops_t compress_model = {
+ 	NULL,
+ 	NULL,
+ 	lzma_compress,
+-	lzma_decompress
++	lzma_decompress,
++	lzma_get_default_level
+ };
+diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c
+index 12066ed9..72dac824 100644
+--- a/libknet/compress_lzo2.c
++++ b/libknet/compress_lzo2.c
+@@ -6,6 +6,7 @@
+  * This software licensed under LGPL-2.0+
+  */
+ #define KNET_MODULE
++#define LZO2_COMPRESS_DEFAULT 1
+ 
+ #include "config.h"
+ 
+@@ -17,6 +18,12 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef LZO2_COMPRESS_DEFAULT
++#define KNET_COMPRESS_DEFAULT LZO2_COMPRESS_DEFAULT
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
++
+ static int lzo2_is_init(
+ 	knet_handle_t knet_h,
+ 	int method_idx)
+@@ -154,6 +161,11 @@ static int lzo2_decompress(
+ 	return err;
+ }
+ 
++static int lzo2_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	lzo2_is_init,
+@@ -161,5 +173,6 @@ compress_ops_t compress_model = {
+ 	lzo2_fini,
+ 	lzo2_val_level,
+ 	lzo2_compress,
+-	lzo2_decompress
++	lzo2_decompress,
++	lzo2_get_default_level
+ };
+diff --git a/libknet/compress_model.h b/libknet/compress_model.h
+index e69e4915..57cf8115 100644
+--- a/libknet/compress_model.h
++++ b/libknet/compress_model.h
+@@ -11,7 +11,8 @@
+ 
+ #include "internals.h"
+ 
+-#define KNET_COMPRESS_MODEL_ABI 1
++#define KNET_COMPRESS_MODEL_ABI            2
++#define KNET_COMPRESS_UNKNOWN_DEFAULT    (-2)
+ 
+ typedef struct {
+ 	uint8_t abi_ver;
+@@ -70,6 +71,11 @@ typedef struct {
+ 			 const ssize_t buf_in_len,
+ 			 unsigned char *buf_out,
+ 			 ssize_t *buf_out_len);
++
++	/*
++	 * Get default compression level
++	 */
++	int (*get_default_level) (void);
+ } compress_ops_t;
+ 
+ typedef struct {
+diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c
+index 2fb12f51..fa6ae011 100644
+--- a/libknet/compress_zlib.c
++++ b/libknet/compress_zlib.c
+@@ -15,6 +15,12 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef Z_DEFAULT_COMPRESSION
++#define KNET_COMPRESS_DEFAULT Z_DEFAULT_COMPRESSION /* zlib default compression level from zlib.h */
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
++
+ static int zlib_compress(
+ 	knet_handle_t knet_h,
+ 	const unsigned char *buf_in,
+@@ -106,6 +112,11 @@ static int zlib_decompress(
+ 	return err;
+ }
+ 
++static int zlib_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	NULL,
+@@ -113,5 +124,6 @@ compress_ops_t compress_model = {
+ 	NULL,
+ 	NULL,
+ 	zlib_compress,
+-	zlib_decompress
++	zlib_decompress,
++	zlib_get_default_level
+ };
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index e234f8d6..8e679bb6 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -17,6 +17,12 @@
+ #include "logging.h"
+ #include "compress_model.h"
+ 
++#ifdef ZSTD_CLEVEL_DEFAULT
++#define KNET_COMPRESS_DEFAULT ZSTD_CLEVEL_DEFAULT /* zstd default compression level from zstd.h */
++#else
++#define KNET_COMPRESS_DEFAULT KNET_COMPRESS_UNKNOWN_DEFAULT
++#endif
++
+ struct zstd_ctx {
+ 	ZSTD_CCtx* cctx;
+ 	ZSTD_DCtx* dctx;
+@@ -149,6 +155,11 @@ static int zstd_decompress(
+ 	return 0;
+ }
+ 
++static int zstd_get_default_level()
++{
++	return KNET_COMPRESS_DEFAULT;
++}
++
+ compress_ops_t compress_model = {
+ 	KNET_COMPRESS_MODEL_ABI,
+ 	zstd_is_init,
+@@ -156,5 +167,6 @@ compress_ops_t compress_model = {
+ 	zstd_fini,
+ 	NULL,
+ 	zstd_compress,
+-	zstd_decompress
++	zstd_decompress,
++	zstd_get_default_level
+ };
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 40b6f397..3cb2ef41 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -81,6 +81,22 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_handle_compress with zlib compress and not effective compression level (0)\n");
++
++	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
++	strncpy(knet_handle_compress_cfg.compress_model, "zlib", sizeof(knet_handle_compress_cfg.compress_model) - 1);
++	knet_handle_compress_cfg.compress_level = 0;
++
++	if((knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno == EINVAL)) {
++		printf("knet_handle_compress failed to compress with default compression level\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
+ 	printf("Test knet_handle_compress with zlib compress and negative level (-2)\n");
+ 
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0280-compress-Default-compression-level-use.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0280-compress-Default-compression-level-use.patch
new file mode 100644
index 000000000..6e73f2766
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0280-compress-Default-compression-level-use.patch
@@ -0,0 +1,44 @@ 
+From ed7a24ae391848fd6f61ee50079f656fed085b61 Mon Sep 17 00:00:00 2001
+From: yuan ren <yren@suse.com>
+Date: Tue, 25 Jun 2019 21:55:26 +0800
+Subject: [PATCH] [compress]Default compression level use
+
+1. add test casees for a module without default.Using default
+compression level.
+2. Discuss with Fabio, invalid compression level not the knet
+responsible for, so error logged. But if compress success but
+dstLen larger than srcLen, defualt compression level will be
+used, because the request level is not effective.
+
+Signed-off-by: yuan ren <yren@suse.com>
+---
+ libknet/tests/api_knet_handle_compress.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 3cb2ef41..31392cfd 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -81,6 +81,22 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_handle_compress with bzip2 (no default) with negative level (-3)\n");
++#ifdef BZIP2_COMPRESS_LEVEL
++        memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
++        strncpy(knet_handle_compress_cfg.compress_model, "bzip2", sizeof(knet_handle_compress_cfg.compress_model) - 1);
++        knet_handle_compress_cfg.compress_level = -3;
++
++        if((!knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
++                printf("knet_handle_compress accepted invalid (-3) compress level and for bzip2, which is no default defined\n");
++                knet_handle_free(knet_h);
++                flush_logs(logfds[0], stdout);
++                close_logpipes(logfds);
++                exit(FAIL);
++        }
++#endif
++	flush_logs(logfds[0], stdout);
++
+ 	printf("Test knet_handle_compress with zlib compress and not effective compression level (0)\n");
+ 
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0281-compress-fix-a-few-minor-space-vs-tab-and-code-forma.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0281-compress-fix-a-few-minor-space-vs-tab-and-code-forma.patch
new file mode 100644
index 000000000..532dd84ce
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0281-compress-fix-a-few-minor-space-vs-tab-and-code-forma.patch
@@ -0,0 +1,50 @@ 
+From efd5276439623bf251e5b910a5e3f55c63d96c58 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 26 Jun 2019 05:31:06 +0200
+Subject: [PATCH] [compress] fix a few minor space vs tab and code formatting
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/compress.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/libknet/compress.c b/libknet/compress.c
+index e85448b5..1ed0dc5e 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -215,26 +215,28 @@ static int compress_lib_test(knet_handle_t knet_h)
+ 		 * compress not effective, try again using default compression level when available
+ 		 */
+ 		request_level = knet_h->compress_level;
+-		log_warn(knet_h, KNET_SUB_COMPRESS, "Requested compression level (%d) did not generate any compressed data (source: %zu destination: %zu)",
+-				request_level, sizeof(src), dst_comp_len);
++		log_warn(knet_h, KNET_SUB_COMPRESS,
++			 "Requested compression level (%d) did not generate any compressed data (source: %zu destination: %zu)",
++			 request_level, sizeof(src), dst_comp_len);
+ 
+ 		if ((!compress_modules_cmds[knet_h->compress_model].ops->get_default_level()) ||
+-				((knet_h->compress_level = compress_modules_cmds[knet_h->compress_model].ops->get_default_level()) == KNET_COMPRESS_UNKNOWN_DEFAULT)) {
++		    ((knet_h->compress_level = compress_modules_cmds[knet_h->compress_model].ops->get_default_level()) == KNET_COMPRESS_UNKNOWN_DEFAULT)) {
+                         log_err(knet_h, KNET_SUB_COMPRESS, "compression %s does not provide a default value",
+-					compress_modules_cmds[knet_h->compress_model].model_name);
++				compress_modules_cmds[knet_h->compress_model].model_name);
++			errno = EINVAL;
+ 			return -1;
+                 } else {
+ 			memset(src, 0, KNET_DATABUFSIZE);
+ 			memset(dst, 0, KNET_DATABUFSIZE_COMPRESS);
+ 			dst_comp_len = KNET_DATABUFSIZE_COMPRESS;
+ 			if (compress_modules_cmds[knet_h->compress_model].ops->compress(knet_h, src, KNET_DATABUFSIZE, dst, &dst_comp_len) < 0) {
+-                                savederrno = errno;
+-                                log_err(knet_h, KNET_SUB_COMPRESS, "Unable to compress with default compression level: %s", strerror(savederrno));
++				savederrno = errno;
++				log_err(knet_h, KNET_SUB_COMPRESS, "Unable to compress with default compression level: %s", strerror(savederrno));
+ 				errno = savederrno;
+ 				return -1;
+ 			}
+ 			log_warn(knet_h, KNET_SUB_COMPRESS, "Requested compression level (%d) did not work, switching to default (%d)",
+-					request_level, knet_h->compress_level);
++				 request_level, knet_h->compress_level);
+ 		}
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0282-compress-fix-if-def-around-BZIP2-testing.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0282-compress-fix-if-def-around-BZIP2-testing.patch
new file mode 100644
index 000000000..2048d9b47
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0282-compress-fix-if-def-around-BZIP2-testing.patch
@@ -0,0 +1,35 @@ 
+From 593ebacc8ec4d1de40e7048bbc86602d8c9731a4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 26 Jun 2019 05:31:23 +0200
+Subject: [PATCH] [compress] fix #if def around BZIP2 testing
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_handle_compress.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 31392cfd..509bdf6c 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -81,8 +81,8 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++#if WITH_COMPRESS_BZIP2 > 0
+ 	printf("Test knet_handle_compress with bzip2 (no default) with negative level (-3)\n");
+-#ifdef BZIP2_COMPRESS_LEVEL
+         memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+         strncpy(knet_handle_compress_cfg.compress_model, "bzip2", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+         knet_handle_compress_cfg.compress_level = -3;
+@@ -94,8 +94,9 @@ static void test(void)
+                 close_logpipes(logfds);
+                 exit(FAIL);
+         }
+-#endif
++
+ 	flush_logs(logfds[0], stdout);
++#endif
+ 
+ 	printf("Test knet_handle_compress with zlib compress and not effective compression level (0)\n");
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0283-coverity-add-.travis.yml-to-integrate-CI-with-coveri.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0283-coverity-add-.travis.yml-to-integrate-CI-with-coveri.patch
new file mode 100644
index 000000000..7c007ac8a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0283-coverity-add-.travis.yml-to-integrate-CI-with-coveri.patch
@@ -0,0 +1,79 @@ 
+From 8909fdb96a1baec9571ec4fc7e34c3b6b0b24ba6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 17 Jul 2019 09:41:20 +0200
+Subject: [PATCH] [coverity] add .travis.yml to integrate CI with coverity scan
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ .travis.yml | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 62 insertions(+)
+ create mode 100644 .travis.yml
+
+diff --git a/.travis.yml b/.travis.yml
+new file mode 100644
+index 00000000..ab7a66d9
+--- /dev/null
++++ b/.travis.yml
+@@ -0,0 +1,62 @@
++sudo: false
++
++language: c
++
++compiler:
++  - gcc
++
++env:
++  global:
++   # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
++   #   via the "travis encrypt" command using the project repo's public key
++   - secure: "UzfmWmjTx8Vq4DBlcbvXiEqWfDoPkoQ63dYgWrdlpvp+JTCb+XYMa/KAt0v8+U2IhixudI6Vuq5ztGFqFL8jnNFHOqfjIqTtdxi5Hen8vRymyqar963HOOhlXQ9+XN6+IztqmJx7jVI26O7m+Pt+CTzhaz8u2eh3yTYq6pIQ0Cs="
++
++git:
++  depth: false
++
++before_install:
++  - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
++  - ./autogen.sh
++
++script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./configure && make ; fi
++
++branches:
++  only:
++    - coverity_scan
++
++addons:
++  coverity_scan:
++    project:
++      name: "kronosnet/kronosnet"
++      description: "Kronosnet, often referred to as knet, is a network abstraction layer designed for High Availability use cases, where redundancy, security, fault tolerance and fast fail-over are the core requirements of your application."
++    notification_email: fdinitto@redhat.com
++    build_command_prepend: "./configure"
++    build_command: "make"
++    branch_pattern: coverity_scan
++  apt:
++    packages:
++      - build-essential
++      - libtool-bin
++      - make
++      - git
++      - gcc
++      - clang
++      - autoconf
++      - autotools-dev
++      - libtool
++      - libnss3-dev
++      - libnspr4-dev
++      - libssl-dev
++      - pkg-config
++      - zlib1g-dev
++      - liblz4-dev
++      - liblzo2-dev
++      - liblzma-dev
++      - libbz2-dev
++      - libsctp-dev
++      - libqb-dev
++      - libxml2-dev
++      - doxygen
++      - libzstd-dev
++      - libnl-3-dev
++      - libnl-route-3-dev
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0284-sctp-fix-deference-after-null-check.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0284-sctp-fix-deference-after-null-check.patch
new file mode 100644
index 000000000..60353c7cd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0284-sctp-fix-deference-after-null-check.patch
@@ -0,0 +1,23 @@ 
+From 2f7e14b1d61adbd8a07821ec0048ad0092032d65 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 15 Jul 2019 15:10:15 +0200
+Subject: [PATCH] [sctp] fix deference after null check
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index d97d6f98..94682f32 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1034,7 +1034,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 
+ exit_error:
+ 	if (err) {
+-		if (info->on_listener_epoll) {
++		if ((info) && (info->on_listener_epoll)) {
+ 			epoll_ctl(handle_info->listen_epollfd, EPOLL_CTL_DEL, listen_sock, &ev);
+ 		}
+ 		check_rmall(knet_h, listen_sock, KNET_TRANSPORT_SCTP);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0285-sctp-free-access-list-only-if-the-socket-is-valid.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0285-sctp-free-access-list-only-if-the-socket-is-valid.patch
new file mode 100644
index 000000000..252e2cd42
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0285-sctp-free-access-list-only-if-the-socket-is-valid.patch
@@ -0,0 +1,24 @@ 
+From 6f689d94abda747ac5158c6123551b0b2e48e3ff Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 07:03:11 +0200
+Subject: [PATCH] [sctp] free access list only if the socket is valid
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 94682f32..85e1008c 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1037,8 +1037,8 @@ exit_error:
+ 		if ((info) && (info->on_listener_epoll)) {
+ 			epoll_ctl(handle_info->listen_epollfd, EPOLL_CTL_DEL, listen_sock, &ev);
+ 		}
+-		check_rmall(knet_h, listen_sock, KNET_TRANSPORT_SCTP);
+ 		if (listen_sock >= 0) {
++			check_rmall(knet_h, listen_sock, KNET_TRANSPORT_SCTP);
+ 			close(listen_sock);
+ 		}
+ 		if (info) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0286-rx-align-data-types.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0286-rx-align-data-types.patch
new file mode 100644
index 000000000..8f3789e77
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0286-rx-align-data-types.patch
@@ -0,0 +1,25 @@ 
+From 9ade8bb55f1e5af5a6bcf73fbb05cedf8a979676 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 07:11:56 +0200
+Subject: [PATCH] [rx] align data types
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index e0be5770..4f9db0fe 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -93,8 +93,8 @@ struct knet_host_defrag_buf {
+ 	uint8_t frag_recv;		/* how many frags did we receive */
+ 	uint8_t frag_map[PCKT_FRAG_MAX];/* bitmap of what we received? */
+ 	uint8_t	last_first;		/* special case if we receive the last fragment first */
+-	uint16_t frag_size;		/* normal frag size (not the last one) */
+-	uint16_t last_frag_size;	/* the last fragment might not be aligned with MTU size */
++	ssize_t frag_size;		/* normal frag size (not the last one) */
++	ssize_t last_frag_size;		/* the last fragment might not be aligned with MTU size */
+ 	struct timespec last_update;	/* keep time of the last pckt */
+ };
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0287-handle-make-sure-that-the-pmtud-buf-contains-at-leas.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0287-handle-make-sure-that-the-pmtud-buf-contains-at-leas.patch
new file mode 100644
index 000000000..6c4ebcc0b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0287-handle-make-sure-that-the-pmtud-buf-contains-at-leas.patch
@@ -0,0 +1,32 @@ 
+From e006c9c0fcfdf222f7db58fc91d9a2efd1ffb34f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 07:50:37 +0200
+Subject: [PATCH] [handle] make sure that the pmtud buf contains at least knet
+ header size
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 4221bee5..3d62e8f3 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -234,14 +234,14 @@ static int _init_buffers(knet_handle_t knet_h)
+ 	}
+ 	memset(knet_h->pingbuf, 0, KNET_HEADER_PING_SIZE);
+ 
+-	knet_h->pmtudbuf = malloc(KNET_PMTUD_SIZE_V6);
++	knet_h->pmtudbuf = malloc(KNET_PMTUD_SIZE_V6 + KNET_HEADER_ALL_SIZE);
+ 	if (!knet_h->pmtudbuf) {
+ 		savederrno = errno;
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to allocate memory for pmtud buffer: %s",
+ 			strerror(savederrno));
+ 		goto exit_fail;
+ 	}
+-	memset(knet_h->pmtudbuf, 0, KNET_PMTUD_SIZE_V6);
++	memset(knet_h->pmtudbuf, 0, KNET_PMTUD_SIZE_V6 + KNET_HEADER_ALL_SIZE);
+ 
+ 	for (i = 0; i < PCKT_FRAG_MAX; i++) {
+ 		bufsize = ceil((float)KNET_MAX_PACKET_SIZE / (i + 1)) + KNET_HEADER_ALL_SIZE + KNET_DATABUFSIZE_CRYPT_PAD;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0288-sctp-revalidate-fd-to-make-coverity-scan-happy.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0288-sctp-revalidate-fd-to-make-coverity-scan-happy.patch
new file mode 100644
index 000000000..ddc93bbf3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0288-sctp-revalidate-fd-to-make-coverity-scan-happy.patch
@@ -0,0 +1,42 @@ 
+From 9c421300f8372f337db338bb49d1dd5da0c8b8b8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 07:59:01 +0200
+Subject: [PATCH] [sctp] revalidate fd to make coverity scan happy
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 85e1008c..d0d2c2ee 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -611,6 +611,13 @@ static void _handle_connected_sctp_errors(knet_handle_t knet_h)
+ 		return;
+ 	}
+ 
++	/*
++	 * revalidate sockfd
++	 */
++	if ((sockfd < 0) || (sockfd >= KNET_MAX_FDS)) {
++		return;
++	}
++
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Processing connected error on socket: %d", sockfd);
+ 
+ 	info = knet_h->knet_transport_fd_tracker[sockfd].data;
+@@ -839,6 +846,13 @@ static void _handle_listen_sctp_errors(knet_handle_t knet_h)
+ 		return;
+ 	}
+ 
++	/*
++	 * revalidate sockfd
++	 */
++	if ((sockfd < 0) || (sockfd >= KNET_MAX_FDS)) {
++		return;
++	}
++
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Processing listen error on socket: %d", sockfd);
+ 
+ 	accept_info = knet_h->knet_transport_fd_tracker[sockfd].data;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0289-tests-fix-knet_bench-coverity-errors.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0289-tests-fix-knet_bench-coverity-errors.patch
new file mode 100644
index 000000000..fd6757586
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0289-tests-fix-knet_bench-coverity-errors.patch
@@ -0,0 +1,166 @@ 
+From b534ef1de09a7eb11d3b5a71c552018e03c9c25d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 10:23:14 +0200
+Subject: [PATCH] [tests] fix knet_bench coverity errors
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/knet_bench.c | 99 ++++++++++++++++++++------------------
+ 1 file changed, 52 insertions(+), 47 deletions(-)
+
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index dfe5238e..dc04239c 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -277,22 +277,24 @@ static void setup_knet(int argc, char *argv[])
+ 					printf("Error: -p can only be specified once\n");
+ 					exit(FAIL);
+ 				}
+-				policystr = optarg;
+-				if (!strcmp(policystr, "active")) {
+-					policy = KNET_LINK_POLICY_ACTIVE;
+-					policyfound = 1;
+-				}
+-				/*
+-				 * we can't use rr because clangs can't compile
+-				 * an array of 3 strings, one of which is 2 bytes long
+-				 */
+-				if (!strcmp(policystr, "round-robin")) {
+-					policy = KNET_LINK_POLICY_RR;
+-					policyfound = 1;
+-				}
+-				if (!strcmp(policystr, "passive")) {
+-					policy = KNET_LINK_POLICY_PASSIVE;
+-					policyfound = 1;
++				if (optarg) {
++					policystr = optarg;
++					if (!strcmp(policystr, "active")) {
++						policy = KNET_LINK_POLICY_ACTIVE;
++						policyfound = 1;
++					}
++					/*
++					 * we can't use rr because clangs can't compile
++					 * an array of 3 strings, one of which is 2 bytes long
++					 */
++					if (!strcmp(policystr, "round-robin")) {
++						policy = KNET_LINK_POLICY_RR;
++						policyfound = 1;
++					}
++					if (!strcmp(policystr, "passive")) {
++						policy = KNET_LINK_POLICY_PASSIVE;
++						policyfound = 1;
++					}
+ 				}
+ 				if (!policyfound) {
+ 					printf("Error: invalid policy %s specified. -p accepts active|passive|rr\n", policystr);
+@@ -304,14 +306,16 @@ static void setup_knet(int argc, char *argv[])
+ 					printf("Error: -P can only be specified once\n");
+ 					exit(FAIL);
+ 				}
+-				protostr = optarg;
+-				if (!strcmp(protostr, "UDP")) {
+-					protocol = KNET_TRANSPORT_UDP;
+-					protofound = 1;
+-				}
+-				if (!strcmp(protostr, "SCTP")) {
+-					protocol = KNET_TRANSPORT_SCTP;
+-					protofound = 1;
++				if (optarg) {
++					protostr = optarg;
++					if (!strcmp(protostr, "UDP")) {
++						protocol = KNET_TRANSPORT_UDP;
++						protofound = 1;
++					}
++					if (!strcmp(protostr, "SCTP")) {
++						protocol = KNET_TRANSPORT_SCTP;
++						protofound = 1;
++					}
+ 				}
+ 				if (!protofound) {
+ 					printf("Error: invalid protocol %s specified. -P accepts udp|sctp\n", policystr);
+@@ -380,17 +384,22 @@ static void setup_knet(int argc, char *argv[])
+ 				}
+ 				break;
+ 			case 'T':
+-				if (!strcmp("ping", optarg)) {
+-					test_type = TEST_PING;
+-				}
+-				if (!strcmp("ping_data", optarg)) {
+-					test_type = TEST_PING_AND_DATA;
+-				}
+-				if (!strcmp("perf-by-size", optarg)) {
+-					test_type = TEST_PERF_BY_SIZE;
+-				}
+-				if (!strcmp("perf-by-time", optarg)) {
+-					test_type = TEST_PERF_BY_TIME;
++				if (optarg) {
++					if (!strcmp("ping", optarg)) {
++						test_type = TEST_PING;
++					}
++					if (!strcmp("ping_data", optarg)) {
++						test_type = TEST_PING_AND_DATA;
++					}
++					if (!strcmp("perf-by-size", optarg)) {
++						test_type = TEST_PERF_BY_SIZE;
++					}
++					if (!strcmp("perf-by-time", optarg)) {
++						test_type = TEST_PERF_BY_TIME;
++					}
++				} else {
++					printf("Error: -T requires an option\n");
++					exit(FAIL);
+ 				}
+ 				break;
+ 			case 'S':
+@@ -957,15 +966,14 @@ static void display_stats(int level)
+ 	struct knet_link_stats total_link_stats;
+ 	knet_node_id_t host_list[KNET_MAX_HOST];
+ 	uint8_t link_list[KNET_MAX_LINK];
+-	int res;
+ 	unsigned int i,j;
+ 	size_t num_hosts, num_links;
+ 
+-	res = knet_handle_get_stats(knet_h, &handle_stats, sizeof(handle_stats));
+-	if (res) {
++	if (knet_handle_get_stats(knet_h, &handle_stats, sizeof(handle_stats)) < 0) {
+ 		perror("[info]: failed to get knet handle stats");
+ 		return;
+ 	}
++
+ 	if (compresscfg || cryptocfg) {
+ 		printf("\n");
+ 		printf("[stat]: handle stats\n");
+@@ -1005,8 +1013,7 @@ static void display_stats(int level)
+ 
+ 	memset(&total_link_stats, 0, sizeof(struct knet_link_stats));
+ 
+-	res = knet_host_get_host_list(knet_h, host_list, &num_hosts);
+-	if (res) {
++	if (knet_host_get_host_list(knet_h, host_list, &num_hosts) < 0) {
+ 		perror("[info]: cannot get host list for stats");
+ 		return;
+ 	}
+@@ -1015,18 +1022,16 @@ static void display_stats(int level)
+ 	qsort(host_list, num_hosts, sizeof(uint16_t), node_compare);
+ 
+ 	for (j=0; j<num_hosts; j++) {
+-		res = knet_link_get_link_list(knet_h, host_list[j], link_list, &num_links);
+-		if (res) {
++		if (knet_link_get_link_list(knet_h, host_list[j], link_list, &num_links) < 0) {
+ 			perror("[info]: cannot get link list for stats");
+ 			return;
+ 		}
+ 
+ 		for (i=0; i < num_links; i++) {
+-			res = knet_link_get_status(knet_h,
+-						   host_list[j],
+-						   link_list[i],
+-						   &link_status,
+-						   sizeof(link_status));
++			if (knet_link_get_status(knet_h, host_list[j], link_list[i], &link_status, sizeof(link_status)) < 0) {
++				perror("[info]: cannot get link status");
++				return;
++			}
+ 
+ 			total_link_stats.tx_data_packets += link_status.stats.tx_data_packets;
+ 			total_link_stats.rx_data_packets += link_status.stats.rx_data_packets;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0290-common-fix-dlopen-error-handling.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0290-common-fix-dlopen-error-handling.patch
new file mode 100644
index 000000000..0d6f252d2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0290-common-fix-dlopen-error-handling.patch
@@ -0,0 +1,32 @@ 
+From f3c771f36549efcdbdd34d0934e694da08034e2a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 10:36:43 +0200
+Subject: [PATCH] [common] fix dlopen error handling
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/common.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/common.c b/libknet/common.c
+index 30e537e5..14715268 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -67,10 +67,13 @@ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags
+ 	dlerror();
+ 
+ 	ret = dlopen(libname, RTLD_NOW | RTLD_GLOBAL | extra_flags);
+-	error = dlerror();
+-	if (error != NULL) {
+-		log_err(knet_h, KNET_SUB_COMMON, "unable to dlopen %s: %s",
+-			libname, error);
++	if (!ret) {
++		error = dlerror();
++		if (error) {
++			log_err(knet_h, KNET_SUB_COMMON, "unable to dlopen %s: %s", libname, error);
++		} else {
++			log_err(knet_h, KNET_SUB_COMMON, "unable to dlopen %s: unknown error", libname);
++		}
+ 		errno = EAGAIN;
+ 		return NULL;
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0291-rx-better-error-report-if-we-can-t-resolve-hostname-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0291-rx-better-error-report-if-we-can-t-resolve-hostname-.patch
new file mode 100644
index 000000000..05943c9e4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0291-rx-better-error-report-if-we-can-t-resolve-hostname-.patch
@@ -0,0 +1,33 @@ 
+From 65534567372beba5cdecfb7c5f6bd6ffdc609813 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 10:43:58 +0200
+Subject: [PATCH] [rx] better error report if we can't resolve hostname / port
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index f4cc1642..4b0b7656 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -813,11 +813,14 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 
+ 						memset(src_ipaddr, 0, KNET_MAX_HOST_LEN);
+ 						memset(src_port, 0, KNET_MAX_PORT_LEN);
+-						knet_addrtostr(msg[i].msg_hdr.msg_name, sockaddr_len(msg[i].msg_hdr.msg_name),
+-							       src_ipaddr, KNET_MAX_HOST_LEN,
+-							       src_port, KNET_MAX_PORT_LEN);
++						if (knet_addrtostr(msg[i].msg_hdr.msg_name, sockaddr_len(msg[i].msg_hdr.msg_name),
++								   src_ipaddr, KNET_MAX_HOST_LEN,
++								   src_port, KNET_MAX_PORT_LEN) < 0) {
+ 
+-						log_debug(knet_h, KNET_SUB_RX, "Packet rejected from %s/%s", src_ipaddr, src_port);
++							log_debug(knet_h, KNET_SUB_RX, "Packet rejected: unable to resolve host/port");
++						} else {
++							log_debug(knet_h, KNET_SUB_RX, "Packet rejected from %s/%s", src_ipaddr, src_port);
++						}
+ 						/*
+ 						 * continue processing the other packets
+ 						 */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0292-acl-avoid-forward-null-deferencing.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0292-acl-avoid-forward-null-deferencing.patch
new file mode 100644
index 000000000..e0c6eea00
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0292-acl-avoid-forward-null-deferencing.patch
@@ -0,0 +1,31 @@ 
+From bcd31001d99bd43d1eb6243c75e3eaa7978370e2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 11:08:32 +0200
+Subject: [PATCH] [acl] avoid forward null deferencing
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl_ip.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index e479bbdb..4692afa5 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -279,10 +279,15 @@ int ipcheck_addip(void *fd_tracker_match_entry_head, int index,
+ 			/*
+ 			 * find the end of the list or stop at "index"
+ 			 */
+-			while ((match_entry->next) || (i < index)) {
++
++			while (match_entry->next) {
+ 				match_entry = match_entry->next;
++				if (i == index) {
++					break;
++				}
+ 				i++;
+ 			}
++
+ 			/*
+ 			 * insert if there are more entries in the list
+ 			 */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0293-sctp-cleanup-bugs-detected-in-error-paths-by-coverit.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0293-sctp-cleanup-bugs-detected-in-error-paths-by-coverit.patch
new file mode 100644
index 000000000..4356e3dbe
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0293-sctp-cleanup-bugs-detected-in-error-paths-by-coverit.patch
@@ -0,0 +1,40 @@ 
+From 4d99315ef5ba369555a7913d4e40feeaafba053f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 11:57:36 +0200
+Subject: [PATCH] [sctp] cleanup bugs detected in error paths by coverity scan
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 8 +++++---
+ 1 file changed, 5 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index d0d2c2ee..cde9851e 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -811,12 +811,14 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 
+ exit_error:
+ 	if (err) {
+-		if ((i >= 0) || (i < MAX_ACCEPTED_SOCKS)) {
++		if ((i >= 0) && (i < MAX_ACCEPTED_SOCKS)) {
+ 			info->accepted_socks[i] = -1;
+ 		}
+ 		_set_fd_tracker(knet_h, new_fd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL);
+ 		free(accept_info);
+-		close(new_fd);
++		if (new_fd >= 0) {
++			close(new_fd);
++		}
+ 	}
+ 	errno = savederrno;
+ 	return;
+@@ -1205,7 +1207,7 @@ int sctp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_li
+ exit_error:
+ 	if (err) {
+ 		if (info) {
+-			if (info->connect_sock) {
++			if (info->connect_sock >= 0) {
+ 				close(info->connect_sock);
+ 			}
+ 			if (info->listener) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0294-nozzle-fix-negative-return-detected-by-coverity-scan.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0294-nozzle-fix-negative-return-detected-by-coverity-scan.patch
new file mode 100644
index 000000000..bfa32a5f4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0294-nozzle-fix-negative-return-detected-by-coverity-scan.patch
@@ -0,0 +1,23 @@ 
+From b545e744d28de1dcbe254638e3118fab3253ac17 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 13:04:54 +0200
+Subject: [PATCH] [nozzle] fix negative return detected by coverity scan
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 15863ecf..c9fcd7ac 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -104,7 +104,7 @@ static void destroy_iface(nozzle_t nozzle)
+ 	if (!nozzle)
+ 		return;
+ 
+-	if (nozzle->fd)
++	if (nozzle->fd >= 0)
+ 		close(nozzle->fd);
+ 
+ #ifdef KNET_BSD
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0295-nozzle-don-t-leak-memory-on-error.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0295-nozzle-don-t-leak-memory-on-error.patch
new file mode 100644
index 000000000..85f2bc9e6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0295-nozzle-don-t-leak-memory-on-error.patch
@@ -0,0 +1,24 @@ 
+From 05cf6f3c336b6736096755f336926fdd1623894a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 13:09:05 +0200
+Subject: [PATCH] [nozzle] don't leak memory on error
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index c9fcd7ac..e63fce56 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -252,7 +252,8 @@ static int _set_ip(nozzle_t nozzle,
+ 	addr = rtnl_addr_alloc();
+ 	if (!addr) {
+ 		errno = ENOMEM;
+-		return -1;
++		err = -1;
++		goto out;
+ 	}
+ 
+ 	if (rtnl_link_alloc_cache(lib_cfg.nlsock, AF_UNSPEC, &cache) < 0) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0296-compress-don-t-leak-memory-in-case-of-errors-during-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0296-compress-don-t-leak-memory-in-case-of-errors-during-.patch
new file mode 100644
index 000000000..29c18cf36
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0296-compress-don-t-leak-memory-in-case-of-errors-during-.patch
@@ -0,0 +1,33 @@ 
+From 7c5649dc10823d7629d10033fc1051e78031497f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 13:12:36 +0200
+Subject: [PATCH] [compress] don't leak memory in case of errors during zstd
+ init
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/compress_zstd.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index 8e679bb6..e460d273 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -72,6 +72,8 @@ static int zstd_init(
+ 		}
+ 		memset(zstd_ctx, 0, sizeof(struct zstd_ctx));
+ 
++		knet_h->compress_int_data[method_idx] = zstd_ctx;
++
+ 		zstd_ctx->cctx = ZSTD_createCCtx();
+ 		if (!zstd_ctx->cctx) {
+ 			log_err(knet_h, KNET_SUB_ZSTDCOMP, "Unable to create compression context");
+@@ -85,8 +87,6 @@ static int zstd_init(
+ 			err = -1;
+ 			goto out_err;
+ 		}
+-
+-		knet_h->compress_int_data[method_idx] = zstd_ctx;
+ 	}
+ 
+ out_err:
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0297-logging-make-sure-not-to-overrun-buffers-by-pre-allo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0297-logging-make-sure-not-to-overrun-buffers-by-pre-allo.patch
new file mode 100644
index 000000000..5820d3edc
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0297-logging-make-sure-not-to-overrun-buffers-by-pre-allo.patch
@@ -0,0 +1,33 @@ 
+From 5520840d830b139ece764a85cd09a2387ed6a4ad Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 13:31:32 +0200
+Subject: [PATCH] [logging] make sure not to overrun buffers by pre-allocating
+ them
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/logging.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 2efee1b9..378eef59 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -20,7 +20,7 @@
+ #include "logging.h"
+ #include "threads_common.h"
+ 
+-static struct pretty_names subsystem_names[] =
++static struct pretty_names subsystem_names[KNET_MAX_SUBSYSTEMS] =
+ {
+ 	{ "common", KNET_SUB_COMMON },
+ 	{ "handle", KNET_SUB_HANDLE },
+@@ -99,7 +99,7 @@ static int is_valid_subsystem(uint8_t subsystem)
+ 	return -1;
+ }
+ 
+-static struct pretty_names loglevel_names[] =
++static struct pretty_names loglevel_names[KNET_LOG_DEBUG + 1] =
+ {
+ 	{ "ERROR", KNET_LOG_ERR },
+ 	{ "WARNING", KNET_LOG_WARN },
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0298-compress-do-not-overrun-allocated-array-for-compress.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0298-compress-do-not-overrun-allocated-array-for-compress.patch
new file mode 100644
index 000000000..5012f2b7c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0298-compress-do-not-overrun-allocated-array-for-compress.patch
@@ -0,0 +1,44 @@ 
+From 510030d4c14dfdc12031c9fdaef2f93f16a9a6be Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 18 Jul 2019 15:39:57 +0200
+Subject: [PATCH] [compress] do not overrun allocated array for compress
+ modules
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/compress.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 1ed0dc5e..20645a96 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -32,7 +32,7 @@
+  * Always add new items before the last NULL.
+  */
+ 
+-static compress_model_t compress_modules_cmds[] = {
++static compress_model_t compress_modules_cmds[KNET_MAX_COMPRESS_METHODS + 1] = {
+ 	{ "none" , 0, 0, 0, NULL },
+ 	{ "zlib" , 1, WITH_COMPRESS_ZLIB , 0, NULL },
+ 	{ "lz4"  , 2, WITH_COMPRESS_LZ4  , 0, NULL },
+@@ -41,7 +41,7 @@ static compress_model_t compress_modules_cmds[] = {
+ 	{ "lzma" , 5, WITH_COMPRESS_LZMA , 0, NULL },
+ 	{ "bzip2", 6, WITH_COMPRESS_BZIP2, 0, NULL },
+ 	{ "zstd" , 7, WITH_COMPRESS_ZSTD, 0, NULL },
+-	{ NULL, 255, 0, 0, NULL }
++	{ NULL, KNET_MAX_COMPRESS_METHODS, 0, 0, NULL }
+ };
+ 
+ static int max_model = 0;
+@@ -387,8 +387,8 @@ void compress_fini(
+ 		return;
+ 	}
+ 
+-	while (compress_modules_cmds[idx].model_name != NULL) {
+-		if ((idx < KNET_MAX_COMPRESS_METHODS) && /* check idx first so we don't read bad data */
++	while (idx < KNET_MAX_COMPRESS_METHODS) {
++		if ((compress_modules_cmds[idx].model_name != NULL) &&
+ 		    (compress_modules_cmds[idx].built_in == 1) &&
+ 		    (compress_modules_cmds[idx].loaded == 1) &&
+ 		    (compress_modules_cmds[idx].model_id > 0) &&
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0299-coverity-add-test-targets-to-run-coverity-automatica.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0299-coverity-add-test-targets-to-run-coverity-automatica.patch
new file mode 100644
index 000000000..b77ea046e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0299-coverity-add-test-targets-to-run-coverity-automatica.patch
@@ -0,0 +1,81 @@ 
+From 3c6ffa8332876d93a2882d14b7ac6f1ae52ce11e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 23 Jul 2019 09:15:15 +0200
+Subject: [PATCH] [coverity] add test targets to run coverity automatically
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ .gitignore         |  1 +
+ Makefile.am        |  2 +-
+ build-aux/check.mk | 18 ++++++++++++++++++
+ configure.ac       |  9 +++++++++
+ 4 files changed, 29 insertions(+), 1 deletion(-)
+
+diff --git a/.gitignore b/.gitignore
+index 4c954dfa..1bcf390e 100644
+--- a/.gitignore
++++ b/.gitignore
+@@ -57,3 +57,4 @@ doxyfile*.stamp
+ xml-*/
+ doxyxml
+ *.3
++cov*
+diff --git a/Makefile.am b/Makefile.am
+index dc5f8a5e..b7d0205a 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -47,7 +47,7 @@ dist_doc_DATA		= \
+ all-local: $(SPEC)
+ 
+ clean-local:
+-	rm -f $(SPEC)
++	rm -rf $(SPEC) cov*
+ 
+ distclean-local:
+ 	rm -f $(PACKAGE_NAME)-*.tar.* $(PACKAGE_NAME)-*.sha256* tag-*
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index f42e5528..f372968b 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -26,3 +26,21 @@ if HAS_VALGRIND
+ else
+ 	@echo valgrind not available on this platform
+ endif
++
++check-covscan:
++if HAS_COVBUILD
++	rm -rf $(abs_top_builddir)/cov*
++	$(MAKE) -C $(abs_top_builddir) clean
++	$(COVBUILD_EXEC) --dir=$(abs_top_builddir)/cov $(MAKE) -C $(abs_top_builddir)
++if HAS_COVANALYZE
++	$(COVANALYZE_EXEC) --dir=$(abs_top_builddir)/cov --wait-for-license $(covoptions)
++if HAS_COVFORMATERRORS
++	$(COVFORMATERRORS_EXEC) --dir=$(abs_top_builddir)/cov --emacs-style > $(abs_top_builddir)/cov.output.txt
++	$(COVFORMATERRORS_EXEC) --dir=$(abs_top_builddir)/cov --html-output $(abs_top_builddir)/cov.html
++endif
++else
++	@echo directory $(abs_top_builddir)/cov ready to be uploaded to https://scan.coverity.com
++endif
++else
++	@echo cov-build not available on this platform
++endif
+diff --git a/configure.ac b/configure.ac
+index e9625922..778b12a5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -85,6 +85,15 @@ PKG_PROG_PKG_CONFIG
+ AC_CHECK_PROGS([VALGRIND_EXEC], [valgrind])
+ AM_CONDITIONAL([HAS_VALGRIND], [test x$VALGRIND_EXEC != "x"])
+ 
++AC_CHECK_PROGS([COVBUILD_EXEC], [cov-build])
++AM_CONDITIONAL([HAS_COVBUILD], [test x$COVBUILD_EXEC != "x"])
++
++AC_CHECK_PROGS([COVANALYZE_EXEC], [cov-analyze])
++AM_CONDITIONAL([HAS_COVANALYZE], [test x$COVANALYZE_EXEC != "x"])
++
++AC_CHECK_PROGS([COVFORMATERRORS_EXEC], [cov-format-errors])
++AM_CONDITIONAL([HAS_COVFORMATERRORS], [test x$COVFORMATERRORS_EXEC != "x"])
++
+ # KNET_OPTION_DEFINES(stem,type,detection code)
+ # stem: enters name of option, Automake conditional and preprocessor define
+ # type: compress or crypto, determines where the default comes from
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0300-PMTUd-do-not-double-unlock-global-read-lock.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0300-PMTUd-do-not-double-unlock-global-read-lock.patch
new file mode 100644
index 000000000..43dbf188c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0300-PMTUd-do-not-double-unlock-global-read-lock.patch
@@ -0,0 +1,27 @@ 
+From 214ea3fb3a9c546c2f23adeece1a80c18f28c097 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 24 Jul 2019 08:38:56 +0200
+Subject: [PATCH] [PMTUd] do not double unlock global read lock
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_pmtud.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index ebd5b4b0..6f3af26a 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -319,7 +319,11 @@ retry:
+ 			return -1;
+ 		}
+ 
+-		if (shutdown_in_progress(knet_h)) {
++		/*
++		 * we cannot use shutdown_in_progress in here because
++		 * we already hold the read lock
++		 */
++		if (knet_h->fini_in_progress) {
+ 			pthread_mutex_unlock(&knet_h->pmtud_mutex);
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "PMTUD aborted. shutdown in progress");
+ 			return -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0301-nozzle-avoid-tons-of-possible-buffer-overruns.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0301-nozzle-avoid-tons-of-possible-buffer-overruns.patch
new file mode 100644
index 000000000..3e1c8af80
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0301-nozzle-avoid-tons-of-possible-buffer-overruns.patch
@@ -0,0 +1,46 @@ 
+From 2f84adf69d40ca0e0af2431885d0b5d735d23e9c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 24 Jul 2019 11:00:00 +0200
+Subject: [PATCH] [nozzle] avoid tons of possible buffer overruns
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h | 2 +-
+ libnozzle/libnozzle.c | 4 ++--
+ 2 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index c9192a81..ab870ef7 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -34,7 +34,7 @@ struct nozzle_lib_config {
+ #define UPDOWN_PATH_MAX    PATH_MAX - 11 - 1 - IFNAMSIZ
+ 
+ struct nozzle_iface {
+-	char name[IFNAMSIZ];		/* interface name */
++	char name[IFNAMSIZ - 1];	/* interface name */
+ 	int fd;				/* interface fd */
+ 	int up;				/* interface status 0 is down, 1 is up */
+ 	/*
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index e63fce56..91946c64 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -508,7 +508,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		goto out_error;
+ 	}
+ 	strncpy(devname, curnozzle, IFNAMSIZ);
+-	strncpy(nozzle->name, curnozzle, IFNAMSIZ);
++	memmove(nozzle->name, curnozzle, IFNAMSIZ - 1);
+ #endif
+ 
+ #ifdef KNET_LINUX
+@@ -532,7 +532,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	}
+ 
+ 	strncpy(devname, ifname, IFNAMSIZ);
+-	strncpy(nozzle->name, ifname, IFNAMSIZ);
++	memmove(nozzle->name, ifname, IFNAMSIZ - 1);
+ #endif
+ 
+ 	nozzle->default_mtu = get_iface_mtu(nozzle);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0302-test-simplify-flush-log.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0302-test-simplify-flush-log.patch
new file mode 100644
index 000000000..0e44567a5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0302-test-simplify-flush-log.patch
@@ -0,0 +1,53 @@ 
+From f40627df248f171ce3ff4c366944ee733d4a922a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 24 Jul 2019 13:46:51 +0200
+Subject: [PATCH] [test] simplify flush log
+
+allocate on stack only once and make sure strings are null terminated
+drop useless read loop since log msg are always smaller than PAGE_SIZE
+and read are atomic at that level
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index a7d6c5cc..4bf58c61 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -217,22 +217,21 @@ void close_logpipes(int *logfds)
+ 
+ void flush_logs(int logfd, FILE *std)
+ {
++	struct knet_log_msg msg;
++	int len;
++
+ 	while (1) {
+-		struct knet_log_msg msg;
+-
+-		for (size_t bytes_read = 0; bytes_read < sizeof(msg); ) {
+-			int len = read(logfd, &msg + bytes_read,
+-				       sizeof(msg) - bytes_read);
+-			if (len <= 0) {
+-				/*
+-				 * clear errno to avoid incorrect propagation
+-				 */
+-				errno = 0;
+-				return;
+-			}
+-			bytes_read += len;
++		len = read(logfd, &msg, sizeof(msg));
++		if (len != sizeof(msg)) {
++			/*
++			 * clear errno to avoid incorrect propagation
++			 */
++			errno = 0;
++			return;
+ 		}
+ 
++		msg.msg[sizeof(msg.msg) - 1] = 0;
++
+ 		fprintf(std, "[knet]: [%s] %s: %.*s\n",
+ 			knet_log_get_loglevel_name(msg.msglevel),
+ 			knet_log_get_subsystem_name(msg.subsystem),
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0303-common-make-sure-string-is-null-terminated.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0303-common-make-sure-string-is-null-terminated.patch
new file mode 100644
index 000000000..3d1176a67
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0303-common-make-sure-string-is-null-terminated.patch
@@ -0,0 +1,22 @@ 
+From 8579d655d758adff83b2b7ea0daf0cda9973a222 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 24 Jul 2019 13:59:47 +0200
+Subject: [PATCH] [common] make sure string is null terminated
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libknet/common.c b/libknet/common.c
+index 14715268..00907c91 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -108,6 +108,7 @@ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags
+ 				log_debug(knet_h, KNET_SUB_COMMON, "Unable to readlink %s: %s", path, strerror(errno));
+ 				goto out;
+ 			}
++			link[sizeof(link) - 1] = 0;
+ 			/*
+ 			 * symlink is relative to the directory
+ 			 */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0304-tx-drop-unnecessary-usleep-when-sending-to-localhost.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0304-tx-drop-unnecessary-usleep-when-sending-to-localhost.patch
new file mode 100644
index 000000000..3770b2883
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0304-tx-drop-unnecessary-usleep-when-sending-to-localhost.patch
@@ -0,0 +1,22 @@ 
+From 447c8992891de3909dbe4125246adbba973babc8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 25 Jul 2019 08:28:34 +0200
+Subject: [PATCH] [tx] drop unnecessary usleep when sending to localhost
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_tx.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 3969b109..3462cf70 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -235,7 +235,6 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 						local_link->status.stats.tx_data_retries++;
+ 						buf += err;
+ 						buflen -= err;
+-						usleep(KNET_THREADS_TIMERES / 16);
+ 						goto local_retry;
+ 					}
+ 					if (err == buflen) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0305-nozzle-fix-a-few-coverity-errors-in-the-test-suite.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0305-nozzle-fix-a-few-coverity-errors-in-the-test-suite.patch
new file mode 100644
index 000000000..3102db0bd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0305-nozzle-fix-a-few-coverity-errors-in-the-test-suite.patch
@@ -0,0 +1,76 @@ 
+From 40acb9863a3fb575679d2b5d6efd49b2f423e63d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 25 Jul 2019 09:24:26 +0200
+Subject: [PATCH] [nozzle] fix a few coverity errors in the test suite
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/api_nozzle_get_name_by_handle.c |  8 ++++++--
+ libnozzle/tests/api_nozzle_set_mac.c            | 14 +++++---------
+ 2 files changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index 0fe9eb4f..c05e4486 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -33,8 +33,12 @@ static int test(void)
+ 	}
+ 
+ 	device_name_tmp = nozzle_get_name_by_handle(nozzle);
+-	if ((!device_name_tmp) && (errno != ENOENT)) {
+-		printf("Unable to get name by handle\n");
++	if (!device_name_tmp) {
++		if (errno != ENOENT) {
++			printf("Unable to get name by handle\n");
++		} else {
++			printf("received incorrect errno!\n");
++		}
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index 244e866f..abb96364 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -34,7 +34,7 @@ static int test(void)
+ 	size_t size = IFNAMSIZ;
+ 	int err=0;
+ 	nozzle_t nozzle;
+-	char *original_mac = NULL, *current_mac = NULL, *temp_mac = NULL, *err_mac = NULL;
++	char *original_mac = NULL, *current_mac = NULL, *temp_mac = NULL;
+ 	struct ether_addr *orig_mac, *cur_mac, *tmp_mac;
+ 
+ 	printf("Testing set MAC\n");
+@@ -96,8 +96,10 @@ static int test(void)
+ 		goto out_clean;
+ 	}
+ 
+-	if (current_mac)
++	if (current_mac) {
+ 		free(current_mac);
++		current_mac = NULL;
++	}
+ 
+ 	if (nozzle_get_mac(nozzle, &current_mac) < 0) {
+ 		printf("Unable to get current MAC address.\n");
+@@ -124,19 +126,13 @@ static int test(void)
+ 
+ 	printf("Pass NULL to set_mac (pass2)\n");
+ 	errno = 0;
+-	if ((nozzle_set_mac(NULL, err_mac) >= 0) || (errno != EINVAL)) {
++	if ((nozzle_set_mac(NULL, current_mac) >= 0) || (errno != EINVAL)) {
+ 		printf("Something is wrong in nozzle_set_mac sanity checks\n");
+ 		err = -1;
+ 		goto out_clean;
+ 	}
+ 
+ out_clean:
+-	if (err_mac) {
+-		printf("Something managed to set err_mac!\n");
+-		err = -1;
+-		free(err_mac);
+-	}
+-
+ 	if (current_mac)
+ 		free(current_mac);
+ 	if (temp_mac)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0306-tx-clean-up-channel-management-code-for-internal-com.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0306-tx-clean-up-channel-management-code-for-internal-com.patch
new file mode 100644
index 000000000..f2bd2d467
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0306-tx-clean-up-channel-management-code-for-internal-com.patch
@@ -0,0 +1,85 @@ 
+From dd3664fb83e558a3b07312a088d3f8adfbb00c7c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 25 Jul 2019 11:18:19 +0200
+Subject: [PATCH] [tx] clean up channel management code for internal
+ communications
+
+the code is still not in use but it's more clear and doesn't trigger
+memory overrun
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h  |  6 ++++--
+ libknet/threads_tx.c | 22 ++++++++++++++--------
+ 2 files changed, 18 insertions(+), 10 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 4f9db0fe..ce1d0f28 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -33,7 +33,9 @@
+ #define PCKT_FRAG_MAX UINT8_MAX
+ #define PCKT_RX_BUFS  512
+ 
+-#define KNET_EPOLL_MAX_EVENTS KNET_DATAFD_MAX
++#define KNET_EPOLL_MAX_EVENTS KNET_DATAFD_MAX + 1
++
++#define KNET_INTERNAL_DATA_CHANNEL KNET_DATAFD_MAX
+ 
+ typedef void *knet_transport_link_t; /* per link transport handle */
+ typedef void *knet_transport_t;      /* per knet_h transport handle */
+@@ -154,7 +156,7 @@ struct knet_handle_stats_extra {
+ struct knet_handle {
+ 	knet_node_id_t host_id;
+ 	unsigned int enabled:1;
+-	struct knet_sock sockfd[KNET_DATAFD_MAX];
++	struct knet_sock sockfd[KNET_DATAFD_MAX + 1];
+ 	int logfd;
+ 	uint8_t log_levels[KNET_MAX_SUBSYSTEMS];
+ 	int hostsockfd[2];
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 3462cf70..1d954d6e 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -645,19 +645,25 @@ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int
+ 		docallback = 1;
+ 		memset(&ev, 0, sizeof(struct epoll_event));
+ 
+-		if (epoll_ctl(knet_h->send_to_links_epollfd,
+-			      EPOLL_CTL_DEL, knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], &ev)) {
+-			log_err(knet_h, KNET_SUB_TX, "Unable to del datafd %d from linkfd epoll pool: %s",
+-				knet_h->sockfd[channel].sockfd[0], strerror(savederrno));
+-		} else {
+-			knet_h->sockfd[channel].has_error = 1;
++		if (channel != KNET_INTERNAL_DATA_CHANNEL) {
++			if (epoll_ctl(knet_h->send_to_links_epollfd,
++				      EPOLL_CTL_DEL, knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], &ev)) {
++				log_err(knet_h, KNET_SUB_TX, "Unable to del datafd %d from linkfd epoll pool: %s",
++					knet_h->sockfd[channel].sockfd[0], strerror(savederrno));
++			} else {
++				knet_h->sockfd[channel].has_error = 1;
++			}
+ 		}
++		/*
++		 * TODO: add error handling for KNET_INTERNAL_DATA_CHANNEL
++		 *       once we add support for internal knet communication
++		 */
+ 	} else {
+ 		knet_h->recv_from_sock_buf->kh_type = type;
+ 		_parse_recv_from_sock(knet_h, inlen, channel, 0);
+ 	}
+ 
+-	if (docallback) {
++	if ((docallback) && (channel != KNET_INTERNAL_DATA_CHANNEL)) {
+ 		knet_h->sock_notify_fn(knet_h->sock_notify_fn_private_data,
+ 				       knet_h->sockfd[channel].sockfd[0],
+ 				       channel,
+@@ -751,7 +757,7 @@ void *_handle_send_to_links_thread(void *data)
+ 		for (i = 0; i < nev; i++) {
+ 			if (events[i].data.fd == knet_h->hostsockfd[0]) {
+ 				type = KNET_HEADER_TYPE_HOST_INFO;
+-				channel = -1;
++				channel = KNET_INTERNAL_DATA_CHANNEL;
+ 			} else {
+ 				type = KNET_HEADER_TYPE_DATA;
+ 				for (channel = 0; channel < KNET_DATAFD_MAX; channel++) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0307-sctp-retry-locking-in-case-of-failure.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0307-sctp-retry-locking-in-case-of-failure.patch
new file mode 100644
index 000000000..53b46c703
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0307-sctp-retry-locking-in-case-of-failure.patch
@@ -0,0 +1,79 @@ 
+From 97ab4d1d0d3c9896bde36458cb64664da2ad7955 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 21 Aug 2019 10:44:49 +0200
+Subject: [PATCH] [sctp] retry locking in case of failure
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 37 +++++++++++++++++++++++++++++--------
+ 1 file changed, 29 insertions(+), 8 deletions(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index cde9851e..505c1f29 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -15,6 +15,7 @@
+ #include <sys/types.h>
+ #include <sys/socket.h>
+ #include <stdlib.h>
++#include <assert.h>
+ 
+ #include "compat.h"
+ #include "host.h"
+@@ -274,6 +275,32 @@ exit_error:
+ 	return err;
+ }
+ 
++static void _lock_sleep_relock(knet_handle_t knet_h)
++{
++	int i = 0;
++
++	/* Don't hold onto the lock while sleeping */
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	while (i < 5) {
++		usleep(KNET_THREADS_TIMERES / 16);
++		if (!pthread_rwlock_rdlock(&knet_h->global_rwlock)) {
++			/*
++			 * lock acquired, we can go out
++			 */
++			return;
++		} else {
++			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to get read lock!");
++			i++;
++		}
++	}
++	/*
++	 * time to crash! if we cannot re-acquire the lock
++	 * there is no easy way out of this one
++	 */
++	assert(0);
++}
++
+ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno)
+ {
+ 	sctp_connect_link_info_t *connect_info = knet_h->knet_transport_fd_tracker[sockfd].data;
+@@ -300,10 +327,7 @@ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ #ifdef DEBUG
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Sock: %d is overloaded. Slowing TX down", sockfd);
+ #endif
+-			/* Don't hold onto the lock while sleeping */
+-			pthread_rwlock_unlock(&knet_h->global_rwlock);
+-			usleep(KNET_THREADS_TIMERES / 16);
+-			pthread_rwlock_rdlock(&knet_h->global_rwlock);
++			_lock_sleep_relock(knet_h);
+ 			return 1;
+ 		}
+ 		return -1;
+@@ -406,10 +430,7 @@ int sctp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 	 * Under RX pressure we need to give time to IPC to pick up the message
+ 	 */
+ 
+-	/* Don't hold onto the lock while sleeping */
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	usleep(KNET_THREADS_TIMERES / 2);
+-	pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	_lock_sleep_relock(knet_h);
+ 	return 0;
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0308-man-Fix-priority-description-of-POLICY_PASSIVE.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0308-man-Fix-priority-description-of-POLICY_PASSIVE.patch
new file mode 100644
index 000000000..03273b697
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0308-man-Fix-priority-description-of-POLICY_PASSIVE.patch
@@ -0,0 +1,25 @@ 
+From 6632994e56f5c64ed57a05cf4eb06b9312f9999f Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Mon, 26 Aug 2019 15:41:23 +0200
+Subject: [PATCH] [man] Fix priority description of POLICY_PASSIVE
+
+... to match source code.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ libknet/libknet.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 11350dba..6a94a78c 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1098,7 +1098,7 @@ int knet_host_get_host_list(knet_handle_t knet_h,
+  *
+  * policy   - there are currently 3 kind of simple switching policies
+  *            based on link configuration.
+- *            KNET_LINK_POLICY_PASSIVE - the active link with the lowest
++ *            KNET_LINK_POLICY_PASSIVE - the active link with the highest
+  *                                       priority will be used.
+  *                                       if one or more active links share
+  *                                       the same priority, the one with
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0309-common-Include-correct-errno.h.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0309-common-Include-correct-errno.h.patch
new file mode 100644
index 000000000..0a6c667ae
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0309-common-Include-correct-errno.h.patch
@@ -0,0 +1,53 @@ 
+From 3b097aa906f4f88dab9154f943f791b0f2403d82 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Mon, 2 Sep 2019 10:05:18 +0200
+Subject: [PATCH] [common] Include correct errno.h
+
+sys/errno.h is system-specific path and errno.h should be used instead.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ libknet/compat.c | 2 +-
+ libknet/crypto.c | 2 +-
+ libknet/onwire.c | 2 +-
+ 3 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/compat.c b/libknet/compat.c
+index e808f332..2e73c9fc 100644
+--- a/libknet/compat.c
++++ b/libknet/compat.c
+@@ -22,7 +22,7 @@
+ #include <sys/types.h>
+ #include <sys/event.h>
+ #include <sys/time.h>
+-#include <sys/errno.h>
++#include <errno.h>
+ 
+ static int32_t
+ _poll_to_filter_(int32_t event)
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index afa4f88c..2c4d5f5c 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -8,7 +8,7 @@
+ 
+ #include "config.h"
+ 
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+ #include <pthread.h>
+diff --git a/libknet/onwire.c b/libknet/onwire.c
+index 143ac4b7..e3fd293b 100644
+--- a/libknet/onwire.c
++++ b/libknet/onwire.c
+@@ -8,7 +8,7 @@
+ 
+ #include "config.h"
+ 
+-#include <sys/errno.h>
++#include <errno.h>
+ #include <stdlib.h>
+ #include <string.h>
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0310-common-Conditionalize-RTLD_DI_ORIGIN.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0310-common-Conditionalize-RTLD_DI_ORIGIN.patch
new file mode 100644
index 000000000..fcf5f7eea
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0310-common-Conditionalize-RTLD_DI_ORIGIN.patch
@@ -0,0 +1,83 @@ 
+From 70be33a5f079445d75b552b1653517d484e77a19 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Mon, 2 Sep 2019 11:11:27 +0200
+Subject: [PATCH] [common] Conditionalize RTLD_DI_ORIGIN
+
+RTLD_DI_ORIGIN is used to get absolute path of plugin. It is used only
+for logging useful info and not strictly needed, so use it only when it
+is defined (only musl is known to author of the patch)
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ configure.ac     |  4 ++++
+ libknet/common.c | 28 +++++++++++++++++++++++++++-
+ 2 files changed, 31 insertions(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 778b12a5..e430aeb8 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -205,6 +205,10 @@ AC_SEARCH_LIBS([dlopen], [dl dld], , [AC_MSG_ERROR([dlopen not found])])
+ AC_SUBST([dl_LIBS], [$LIBS])
+ LIBS="$saved_LIBS"
+ 
++# Check RTLD_DI_ORIGIN (not decalred by musl. glibc has it as an enum so cannot use ifdef)
++AC_CHECK_DECL([RTLD_DI_ORIGIN], [AC_DEFINE([HAVE_RTLD_DI_ORIGIN], 1,
++    [define when RTLD_DI_ORIGIN is declared])], ,[[#include <dlfcn.h>]])
++
+ # OS detection
+ 
+ AC_MSG_CHECKING([for os in ${host_os}])
+diff --git a/libknet/common.c b/libknet/common.c
+index 00907c91..ed8ac899 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -12,6 +12,8 @@
+ #include <fcntl.h>
+ #include <dlfcn.h>
+ #include <errno.h>
++#include <libgen.h>
++#include <link.h>
+ #include <string.h>
+ #include <sys/param.h>
+ #include <sys/types.h>
+@@ -54,6 +56,30 @@ int _fdset_nonblock(int fd)
+ 	return 0;
+ }
+ 
++static int get_lib_dir(void *lib_handle, char dir[MAXPATHLEN])
++{
++	int res;
++#ifndef HAVE_RTLD_DI_ORIGIN
++	struct link_map *lm;
++	char l_name[MAXPATHLEN];
++#endif
++
++#ifdef HAVE_RTLD_DI_ORIGIN
++	res = dlinfo(lib_handle, RTLD_DI_ORIGIN, dir);
++#else
++	/*
++	 * musl libc doesn't support RTLD_DI_ORIGIN
++	 */
++	res = dlinfo(lib_handle, RTLD_DI_LINKMAP, &lm);
++	if (res == 0) {
++		snprintf(l_name, sizeof(l_name), "%s", lm->l_name);
++		snprintf(dir, MAXPATHLEN, "%s", dirname(l_name));
++	}
++#endif
++
++	return res;
++}
++
+ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags)
+ {
+ 	void *ret = NULL;
+@@ -81,7 +107,7 @@ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags
+ 	memset(dir, 0, sizeof(dir));
+ 	memset(link, 0, sizeof(link));
+ 	memset(path, 0, sizeof(path));
+-	if (dlinfo(ret, RTLD_DI_ORIGIN, &dir) < 0) {
++	if (get_lib_dir(ret, dir) < 0) {
+ 		/*
+ 		 * should we dlclose and return error?
+ 		 */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0311-handle-Set-thread-stack-size-on-create.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0311-handle-Set-thread-stack-size-on-create.patch
new file mode 100644
index 000000000..4f7efd701
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0311-handle-Set-thread-stack-size-on-create.patch
@@ -0,0 +1,116 @@ 
+From e98f322891c9b39997d315cd23172563112072e7 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Mon, 2 Sep 2019 13:56:34 +0200
+Subject: [PATCH] [handle] Set thread stack size on create
+
+Musl libc has small stack size for threads. Knet needs ~300KiB (tested
+at the time when this patch was created). Glibc seems to use ~8MiB. As a
+compromise, 1MiB is used.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ libknet/handle.c    | 34 +++++++++++++++++++++++++++++-----
+ libknet/internals.h |  8 ++++++++
+ 2 files changed, 37 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 3d62e8f3..2b11e0f3 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -456,9 +456,24 @@ static void _close_epolls(knet_handle_t knet_h)
+ static int _start_threads(knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
++	pthread_attr_t attr;
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_PMTUD, KNET_THREAD_REGISTERED);
+-	savederrno = pthread_create(&knet_h->pmtud_link_handler_thread, 0,
++
++	savederrno = pthread_attr_init(&attr);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to init pthread attributes: %s",
++			strerror(savederrno));
++		goto exit_fail;
++	}
++	savederrno = pthread_attr_setstacksize(&attr, KNET_THREAD_STACK_SIZE);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to set stack size attribute: %s",
++			strerror(savederrno));
++		goto exit_fail;
++	}
++
++	savederrno = pthread_create(&knet_h->pmtud_link_handler_thread, &attr,
+ 				    _handle_pmtud_link_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to start pmtud link thread: %s",
+@@ -467,7 +482,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 	}
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_DST_LINK, KNET_THREAD_REGISTERED);
+-	savederrno = pthread_create(&knet_h->dst_link_handler_thread, 0,
++	savederrno = pthread_create(&knet_h->dst_link_handler_thread, &attr,
+ 				    _handle_dst_link_handler_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to start dst cache thread: %s",
+@@ -476,7 +491,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 	}
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_REGISTERED);
+-	savederrno = pthread_create(&knet_h->send_to_links_thread, 0,
++	savederrno = pthread_create(&knet_h->send_to_links_thread, &attr,
+ 				    _handle_send_to_links_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to start datafd to link thread: %s",
+@@ -485,7 +500,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 	}
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_REGISTERED);
+-	savederrno = pthread_create(&knet_h->recv_from_links_thread, 0,
++	savederrno = pthread_create(&knet_h->recv_from_links_thread, &attr,
+ 				    _handle_recv_from_links_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to start link to datafd thread: %s",
+@@ -494,7 +509,7 @@ static int _start_threads(knet_handle_t knet_h)
+ 	}
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_HB, KNET_THREAD_REGISTERED);
+-	savederrno = pthread_create(&knet_h->heartbt_thread, 0,
++	savederrno = pthread_create(&knet_h->heartbt_thread, &attr,
+ 				    _handle_heartbt_thread, (void *) knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to start heartbeat thread: %s",
+@@ -502,6 +517,15 @@ static int _start_threads(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	savederrno = pthread_attr_destroy(&attr);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to destroy pthread attributes: %s",
++			strerror(savederrno));
++		/*
++		 * Do not return error code. Error is not critical.
++		 */
++	}
++
+ 	return 0;
+ 
+ exit_fail:
+diff --git a/libknet/internals.h b/libknet/internals.h
+index ce1d0f28..4fa12543 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -37,6 +37,14 @@
+ 
+ #define KNET_INTERNAL_DATA_CHANNEL KNET_DATAFD_MAX
+ 
++/*
++ * Size of threads stack. Value is choosen by experimenting, how much is needed
++ * to sucesfully finish test suite, and at the time of writing patch it was
++ * ~300KiB. To have some room for future enhancement it is increased
++ * by factor of 3 and rounded.
++ */
++#define KNET_THREAD_STACK_SIZE (1024 * 1024)
++
+ typedef void *knet_transport_link_t; /* per link transport handle */
+ typedef void *knet_transport_t;      /* per knet_h transport handle */
+ struct  knet_transport_ops;          /* Forward because of circular dependancy */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0312-links-stabilize-latency-calculation-when-nodes-are-n.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0312-links-stabilize-latency-calculation-when-nodes-are-n.patch
new file mode 100644
index 000000000..5eb2fe85a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0312-links-stabilize-latency-calculation-when-nodes-are-n.patch
@@ -0,0 +1,133 @@ 
+From 38dc5e6c2db7b32188017e131ef3ece44448f54d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 6 Sep 2019 07:05:19 +0200
+Subject: [PATCH] [links] stabilize latency calculation when nodes are not
+ responsive
+
+The following scenario is more of a corner case than normal, but
+this change allows to better deal with this situation:
+
+1) 2 nodes cluster (corosync) (node A and node B)
+2) kill -stop $(pidof corosync) on node A
+3) node B will continue to send ping packets to node A
+4) node A is accumulating those ping packets in the kernel network socket
+5) wait some seconds and unpause node A
+6) node A will start processing the ping packets in the queue
+   and send pong replies to node B
+7) node B will see an extreme increase of latency due
+   those "obsoleted" ping/pong packets
+8) node B, as latency increases, will take longer and longer
+   to notice that node A is down due to the pong_timeout adjustment
+   for latency (required for initial cluster spike).
+
+the solution:
+
+1) Use average latency to calculate pong_timeout_adj vs latency_max.
+   Averate latency will go down again in time, while latency_max is never
+   reset.
+
+2) RX thread will filter out all pong packets that have higher latency
+   than currently configure pong_timeout. This barrier should have
+   been in place even before.
+
+this solution reduces the latency spike on node B to a perfectly
+reasonable level and it will all eventually stabilize over time
+as latency samples increase and latency will reduce.
+
+Please be aware that using a pong_timeout smaller than latency will
+simply mark the link down now.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_heartbeat.c |  2 +-
+ libknet/threads_rx.c        | 61 ++++++++++++++++++++-----------------
+ 2 files changed, 34 insertions(+), 29 deletions(-)
+
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 8f8a7ecb..fa1f30c4 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -177,7 +177,7 @@ static void _adjust_pong_timeouts(knet_handle_t knet_h)
+ 				dst_link->pong_timeout_backoff--;
+ 			}
+ 
+-			dst_link->pong_timeout_adj = (dst_link->pong_timeout * dst_link->pong_timeout_backoff) + (dst_link->status.stats.latency_max * KNET_LINK_PONG_TIMEOUT_LAT_MUL);
++			dst_link->pong_timeout_adj = (dst_link->pong_timeout * dst_link->pong_timeout_backoff) + (dst_link->status.latency * KNET_LINK_PONG_TIMEOUT_LAT_MUL);
+ 		}
+ 	}
+ 
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 4b0b7656..e8fe264a 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -615,37 +615,42 @@ retry_pong:
+ 		timespec_diff(recvtime,
+ 				src_link->status.pong_last, &latency_last);
+ 
+-		src_link->status.latency =
+-			((src_link->status.latency * src_link->latency_exp) +
+-			((latency_last / 1000llu) *
+-				(src_link->latency_fix - src_link->latency_exp))) /
+-					src_link->latency_fix;
+-
+-		if (src_link->status.latency < src_link->pong_timeout_adj) {
+-			if (!src_link->status.connected) {
+-				if (src_link->received_pong >= src_link->pong_count) {
+-					log_info(knet_h, KNET_SUB_RX, "host: %u link: %u is up",
+-						 src_host->host_id, src_link->link_id);
+-					_link_updown(knet_h, src_host->host_id, src_link->link_id, src_link->status.enabled, 1);
+-				} else {
+-					src_link->received_pong++;
+-					log_debug(knet_h, KNET_SUB_RX, "host: %u link: %u received pong: %u",
+-						  src_host->host_id, src_link->link_id, src_link->received_pong);
++		if ((latency_last / 1000llu) > src_link->pong_timeout) {
++			log_debug(knet_h, KNET_SUB_RX,
++				  "Incoming pong packet from host: %u link: %u has higher latency than pong_timeout. Discarding",
++				  src_host->host_id, src_link->link_id);
++		} else {
++			src_link->status.latency =
++				((src_link->status.latency * src_link->latency_exp) +
++				((latency_last / 1000llu) *
++					(src_link->latency_fix - src_link->latency_exp))) /
++						src_link->latency_fix;
++
++			if (src_link->status.latency < src_link->pong_timeout_adj) {
++				if (!src_link->status.connected) {
++					if (src_link->received_pong >= src_link->pong_count) {
++						log_info(knet_h, KNET_SUB_RX, "host: %u link: %u is up",
++							 src_host->host_id, src_link->link_id);
++						_link_updown(knet_h, src_host->host_id, src_link->link_id, src_link->status.enabled, 1);
++					} else {
++						src_link->received_pong++;
++						log_debug(knet_h, KNET_SUB_RX, "host: %u link: %u received pong: %u",
++							  src_host->host_id, src_link->link_id, src_link->received_pong);
++					}
+ 				}
+ 			}
++			/* Calculate latency stats */
++			if (src_link->status.latency > src_link->status.stats.latency_max) {
++				src_link->status.stats.latency_max = src_link->status.latency;
++			}
++			if (src_link->status.latency < src_link->status.stats.latency_min) {
++				src_link->status.stats.latency_min = src_link->status.latency;
++			}
++			src_link->status.stats.latency_ave =
++				(src_link->status.stats.latency_ave * src_link->status.stats.latency_samples +
++				 src_link->status.latency) / (src_link->status.stats.latency_samples+1);
++			src_link->status.stats.latency_samples++;
+ 		}
+-		/* Calculate latency stats */
+-		if (src_link->status.latency > src_link->status.stats.latency_max) {
+-			src_link->status.stats.latency_max = src_link->status.latency;
+-		}
+-		if (src_link->status.latency < src_link->status.stats.latency_min) {
+-			src_link->status.stats.latency_min = src_link->status.latency;
+-		}
+-		src_link->status.stats.latency_ave =
+-			(src_link->status.stats.latency_ave * src_link->status.stats.latency_samples +
+-			 src_link->status.latency) / (src_link->status.stats.latency_samples+1);
+-		src_link->status.stats.latency_samples++;
+-
+ 		break;
+ 	case KNET_HEADER_TYPE_PMTUD:
+ 		src_link->status.stats.rx_pmtu_packets++;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0313-pmtud-switch-to-use-async-version-of-dstcache-update.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0313-pmtud-switch-to-use-async-version-of-dstcache-update.patch
new file mode 100644
index 000000000..37126167b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0313-pmtud-switch-to-use-async-version-of-dstcache-update.patch
@@ -0,0 +1,24 @@ 
+From 0ff209f729054ebfe154f5e9104ad52f0df56269 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 9 Sep 2019 15:11:25 +0200
+Subject: [PATCH] [pmtud] switch to use async version of dstcache update due to
+ locking context (read vs write)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_pmtud.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 6f3af26a..75d51962 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -503,7 +503,7 @@ static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host,
+ 	}
+ 
+ 	if (saved_valid_pmtud != dst_link->has_valid_mtu) {
+-		_host_dstcache_update_sync(knet_h, dst_host);
++		_host_dstcache_update_async(knet_h, dst_host);
+ 	}
+ 
+ 	return dst_link->has_valid_mtu;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0314-nozzle-fix-tapX-range-on-newer-FreeBSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0314-nozzle-fix-tapX-range-on-newer-FreeBSD.patch
new file mode 100644
index 000000000..f231a8bcd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0314-nozzle-fix-tapX-range-on-newer-FreeBSD.patch
@@ -0,0 +1,38 @@ 
+From dcd52dac9cf53c4e12b1e2975ae5ab0379b61fef Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 12 Sep 2019 06:01:38 +0200
+Subject: [PATCH] [nozzle] fix tapX range on newer FreeBSD
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/libnozzle.c | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 91946c64..3a1f827c 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -488,7 +488,23 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 
+ #ifdef KNET_BSD
+ 	if (!strlen(devname)) {
++		/*
++		 * FreeBSD 13 kernel has changed how the tap module
++		 * works and tap0 cannot be removed from the system.
++		 * This means that tap0 settings are never reset to default
++		 * and nozzle cannot control the default state of the device
++		 * when taking over.
++		 * nozzle expects some parameters to be default when opening
++		 * a tap device (such as random mac address, default MTU, no
++		 * other attributes, etc.)
++		 *
++		 * For 13 and higher, simply skip tap0 as usable device.
++		 */
++#if __FreeBSD__ >= 13
++		for (i = 1; i < 256; i++) {
++#else
+ 		for (i = 0; i < 256; i++) {
++#endif
+ 			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
+ 			nozzle->fd = open(curnozzle, O_RDWR);
+ 			savederrno = errno;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0315-tests-fix-ip-generation-boundaries.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0315-tests-fix-ip-generation-boundaries.patch
new file mode 100644
index 000000000..d4029f6ce
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0315-tests-fix-ip-generation-boundaries.patch
@@ -0,0 +1,27 @@ 
+From 7b6a85fed331a8a62bf3ae31eacfa3e4d3a15327 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 13 Sep 2019 07:28:55 +0200
+Subject: [PATCH] [tests] fix ip generation boundaries
+
+https://ci.kronosnet.org/job/knet-build-all-voting/1450/knet-build-all-voting=rhel80z-s390x/console
+
+and similar, when pid = 255, the secondary IP would hit 256 that is of course invalid.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/test-common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index b36be79c..3afd2ec8 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -124,7 +124,7 @@ void make_local_ips(char *testipv4_1, char *testipv4_2, char *testipv6_1, char *
+ 	pid = (uint8_t *)&mypid;
+ 
+ 	for (i = 0; i < sizeof(pid_t); i++) {
+-		if (pid[i] == 0) {
++		if ((pid[i] == 0) || (pid[i] == 255)) {
+ 			pid[i] = 128;
+ 		}
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0316-tests-give-PMTUd-more-time-to-redetect-MTU.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0316-tests-give-PMTUd-more-time-to-redetect-MTU.patch
new file mode 100644
index 000000000..94ce931ba
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0316-tests-give-PMTUd-more-time-to-redetect-MTU.patch
@@ -0,0 +1,26 @@ 
+From 7a3189deb63438ecc9e575f8b5747d33ab525313 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 13 Sep 2019 07:30:06 +0200
+Subject: [PATCH] [tests] give PMTUd more time to redetect MTU
+
+Ideal fix would be to use PMTUd callback, but that requires a lot of
+extra test infrastructure. For now just workaround the problem.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_handle_pmtud_set.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+index 7a7ffb34..44043688 100644
+--- a/libknet/tests/api_knet_handle_pmtud_set.c
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -196,7 +196,7 @@ static void test(void)
+ 	/*
+ 	 * wait for PMTUd to pick up the change
+ 	 */
+-	sleep(1);
++	sleep(2);
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	if (knet_h->data_mtu != data_mtu) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0317-links-fix-memory-corryption-of-link-structure.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0317-links-fix-memory-corryption-of-link-structure.patch
new file mode 100644
index 000000000..a502018b3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0317-links-fix-memory-corryption-of-link-structure.patch
@@ -0,0 +1,39 @@ 
+From 9aadcd44d278b6536da0c3728d5bdc25cbb95b41 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 19 Sep 2019 09:02:44 +0200
+Subject: [PATCH] [links] fix memory corryption of link structure
+
+the index would overflow the buffer and overwrite data in the link
+structure. Depending on what was written the cluster could fall
+apart in many ways, from crashing, to hung.
+
+Fixes: https://github.com/kronosnet/kronosnet/issues/255
+
+thanks to the proxmox developers and community for reporting the issue
+and for all the help reproducing / debugging the problem.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index cd18d9cc..f7eccc3f 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -43,13 +43,13 @@ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 	if (connected) {
+ 		time(&link->status.stats.last_up_times[link->status.stats.last_up_time_index]);
+ 		link->status.stats.up_count++;
+-		if (++link->status.stats.last_up_time_index > MAX_LINK_EVENTS) {
++		if (++link->status.stats.last_up_time_index >= MAX_LINK_EVENTS) {
+ 			link->status.stats.last_up_time_index = 0;
+ 		}
+ 	} else {
+ 		time(&link->status.stats.last_down_times[link->status.stats.last_down_time_index]);
+ 		link->status.stats.down_count++;
+-		if (++link->status.stats.last_down_time_index > MAX_LINK_EVENTS) {
++		if (++link->status.stats.last_down_time_index >= MAX_LINK_EVENTS) {
+ 			link->status.stats.last_down_time_index = 0;
+ 		}
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0318-tests-skip-the-SCTP-test-if-SCTP-is-not-supported-by.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0318-tests-skip-the-SCTP-test-if-SCTP-is-not-supported-by.patch
new file mode 100644
index 000000000..643ec42ff
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0318-tests-skip-the-SCTP-test-if-SCTP-is-not-supported-by.patch
@@ -0,0 +1,36 @@ 
+From 6a6cbc4e85bb31b1b1453bd03801496103a7309f Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Wed, 3 Apr 2019 10:26:11 +0200
+Subject: [PATCH] tests: skip the SCTP test if SCTP is not supported by the
+ kernel
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+For example, module loading is disabled on Debian build daemons.
+(In the vein of c5aa1c3343703455b480cef5c173f471e1bb020f.)
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/tests/api_knet_send.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 50469ee3..c2166efe 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -181,12 +181,13 @@ static void test(uint8_t transport)
+ 	}
+ 
+ 	if (knet_link_set_config(knet_h, 1, 0, transport, &lo, &lo, 0) < 0) {
++		int exit_status = transport == KNET_TRANSPORT_SCTP && errno == EPROTONOSUPPORT ? SKIP : FAIL;
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+ 		close_logpipes(logfds);
+-		exit(FAIL);
++		exit(exit_status);
+ 	}
+ 
+ 	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0319-Fix-typo-trasport-transport.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0319-Fix-typo-trasport-transport.patch
new file mode 100644
index 000000000..baff75617
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0319-Fix-typo-trasport-transport.patch
@@ -0,0 +1,26 @@ 
+From cbb29b17570a6e1d259a98a8c8264a92e6bcfc44 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Wed, 29 May 2019 11:42:08 +0200
+Subject: [PATCH] Fix typo: trasport -> transport
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Ferenc Wágner <wferi@debian.org>
+---
+ libknet/transport_sctp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 505c1f29..a5b9ccfe 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1266,7 +1266,7 @@ int sctp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_
+ 	if ((sctp_link_listener_stop(knet_h, kn_link) <0) && (errno != EBUSY)) {
+ 		savederrno = errno;
+ 		err = -1;
+-		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove listener trasport: %s",
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove listener transport: %s",
+ 			strerror(savederrno));
+ 		goto exit_error;
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0320-tests-add-common-function-to-sleep-based-on-how-the-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0320-tests-add-common-function-to-sleep-based-on-how-the-.patch
new file mode 100644
index 000000000..548e932ad
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0320-tests-add-common-function-to-sleep-based-on-how-the-.patch
@@ -0,0 +1,96 @@ 
+From 3b8442d3a41316dcb7e3b767a447cd2a6073fe1f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 26 Sep 2019 07:18:46 +0200
+Subject: [PATCH] [tests] add common function to sleep based on how the test
+ suite is running
+
+Address issue while waiting for host to be up and PMTUd first run.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_handle_pmtud_set.c |  6 +++---
+ libknet/tests/api_knet_link_set_enable.c  |  2 +-
+ libknet/tests/test-common.c               | 11 +++++++++++
+ libknet/tests/test-common.h               |  1 +
+ 4 files changed, 16 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+index 44043688..15b1ddde 100644
+--- a/libknet/tests/api_knet_handle_pmtud_set.c
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -167,7 +167,7 @@ static void test(void)
+ 	/*
+ 	 * wait for PMTUd to pick up the change
+ 	 */
+-	sleep(1);
++	test_sleep(knet_h, 1);
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	if (knet_h->data_mtu != data_mtu - 64) {
+@@ -196,11 +196,11 @@ static void test(void)
+ 	/*
+ 	 * wait for PMTUd to pick up the change
+ 	 */
+-	sleep(2);
++	test_sleep(knet_h, 1);
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	if (knet_h->data_mtu != data_mtu) {
+-		printf("knet_handle_pmtud_set failed to redetect MTU\n");
++		printf("knet_handle_pmtud_set failed to redetect MTU: detected mtu: %u data_mtu: %u \n", knet_h->data_mtu, data_mtu);
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_link_set_enable.c b/libknet/tests/api_knet_link_set_enable.c
+index 17e6e031..fc233ea3 100644
+--- a/libknet/tests/api_knet_link_set_enable.c
++++ b/libknet/tests/api_knet_link_set_enable.c
+@@ -293,7 +293,7 @@ static void test_sctp(void)
+ 	}
+ 
+ 	printf("Wait 2 seconds for sockets to connect\n");
+-	sleep(2);
++	test_sleep(knet_h, 2);
+ 
+ 	printf("Test knet_link_set_enable with correct values (0)\n");
+ 
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 4bf58c61..617addca 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -468,6 +468,15 @@ int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset)
+ 	return _make_local_sockaddr(lo, offset, AF_INET6);
+ }
+ 
++void test_sleep(knet_handle_t knet_h, int seconds)
++{
++	if (is_memcheck() || is_helgrind()) {
++		printf("Test suite is running under valgrind, adjusting sleep timers\n");
++		seconds = seconds * 16;
++	}
++	sleep(seconds);
++}
++
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std)
+ {
+ 	int i = 0;
+@@ -480,6 +489,8 @@ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd
+ 	while (i < seconds) {
+ 		flush_logs(logfd, std);
+ 		if (knet_h->host_index[host_id]->status.reachable == 1) {
++			printf("Waiting for host to settle\n");
++			test_sleep(knet_h, 1);
+ 			return 0;
+ 		}
+ 		printf("waiting host %u to be reachable for %d more seconds\n", host_id, seconds - i);
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index f1375ab8..963c4382 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -71,5 +71,6 @@ int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset);
+ int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset);
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std);
+ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd, int logfd, FILE *std);
++void test_sleep(knet_handle_t knet_h, int seconds);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0321-host-rename-variables-to-make-it-easier-to-read-the-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0321-host-rename-variables-to-make-it-easier-to-read-the-.patch
new file mode 100644
index 000000000..6276b1835
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0321-host-rename-variables-to-make-it-easier-to-read-the-.patch
@@ -0,0 +1,65 @@ 
+From 9f8f99761266205ac996bec24eb7d4822d59ef59 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 15 Oct 2019 06:46:36 +0200
+Subject: [PATCH] [host] rename variables to make it easier to read the code
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c | 24 ++++++++++++------------
+ 1 file changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index abb1f894..ac26b89d 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -569,7 +569,7 @@ static void _clear_cbuffers(struct knet_host *host, seq_num_t rx_seq_num)
+ 
+ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, int clear_buf)
+ {
+-	size_t i, j; /* circular buffer indexes */
++	size_t head, tail; /* circular buffer indexes */
+ 	seq_num_t seq_dist;
+ 	char *dst_cbuf = host->circular_buffer;
+ 	char *dst_cbuf_defrag = host->circular_buffer_defrag;
+@@ -585,13 +585,13 @@ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, i
+ 		seq_dist = *dst_seq_num - seq_num;
+ 	}
+ 
+-	j = seq_num % KNET_CBUFFER_SIZE;
++	head = seq_num % KNET_CBUFFER_SIZE;
+ 
+ 	if (seq_dist < KNET_CBUFFER_SIZE) { /* seq num is in ring buffer */
+ 		if (!defrag_buf) {
+-			return (dst_cbuf[j] == 0) ? 1 : 0;
++			return (dst_cbuf[head] == 0) ? 1 : 0;
+ 		} else {
+-			return (dst_cbuf_defrag[j] == 0) ? 1 : 0;
++			return (dst_cbuf_defrag[head] == 0) ? 1 : 0;
+ 		}
+ 	} else if (seq_dist <= SEQ_MAX - KNET_CBUFFER_SIZE) {
+ 		memset(dst_cbuf, 0, KNET_CBUFFER_SIZE);
+@@ -600,16 +600,16 @@ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, i
+ 	}
+ 
+ 	/* cleaning up circular buffer */
+-	i = (*dst_seq_num + 1) % KNET_CBUFFER_SIZE;
++	tail = (*dst_seq_num + 1) % KNET_CBUFFER_SIZE;
+ 
+-	if (i > j) {
+-		memset(dst_cbuf + i, 0, KNET_CBUFFER_SIZE - i);
+-		memset(dst_cbuf, 0, j + 1);
+-		memset(dst_cbuf_defrag + i, 0, KNET_CBUFFER_SIZE - i);
+-		memset(dst_cbuf_defrag, 0, j + 1);
++	if (tail > head) {
++		memset(dst_cbuf + tail, 0, KNET_CBUFFER_SIZE - tail);
++		memset(dst_cbuf, 0, head + 1);
++		memset(dst_cbuf_defrag + tail, 0, KNET_CBUFFER_SIZE - tail);
++		memset(dst_cbuf_defrag, 0, head + 1);
+ 	} else {
+-		memset(dst_cbuf + i, 0, j - i + 1);
+-		memset(dst_cbuf_defrag + i, 0, j - i + 1);
++		memset(dst_cbuf + tail, 0, head - tail + 1);
++		memset(dst_cbuf_defrag + tail, 0, head - tail + 1);
+ 	}
+ 
+ 	*dst_seq_num = seq_num;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0322-host-fix-defrag-buffers-reclaim-logic.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0322-host-fix-defrag-buffers-reclaim-logic.patch
new file mode 100644
index 000000000..60b2d9b99
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0322-host-fix-defrag-buffers-reclaim-logic.patch
@@ -0,0 +1,94 @@ 
+From 45456b119a12123933529b6922873ab8113d70bf Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 15 Oct 2019 06:53:24 +0200
+Subject: [PATCH] [host] fix defrag buffers reclaim logic
+
+The problem:
+
+- let's assume a 2 nodes (A and B) cluster setup
+- node A sends fragmented packets to node B and there is
+  packet loss on the network.
+- node B receives all those fragments and attempts to
+  reassemble them.
+- node A sends packet seq_num X in Y fragments.
+- node B receives only part of the fragments and stores
+  them in a defrag buf.
+- packet loss stops.
+- node A continues to send packets and a seq_num
+  roll-over takes place.
+- node A sends a new packet seq_num X in Y fragments.
+- node B gets confused here because the parts of the old
+  packet seq_num X are still stored and the buffer
+  has not been reclaimed.
+- node B continues to rebuild packet seq_num X with
+  old stale data and new data from after the roll-over.
+- node B completes reassembling the packet and delivers
+  junk to the application.
+
+The solution:
+
+Add a much stronger buffer reclaim logic that will apply
+on each received packet and not only when defrag buffers
+are needed, as there might be a mix of fragmented and not
+fragmented packets in-flight.
+
+The new logic creates a window of N packets that can be
+handled at the same time (based on the number of buffers)
+and clear everything else.
+
+Fixes https://github.com/kronosnet/kronosnet/issues/261
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c | 31 +++++++++++++++++++++++++++++++
+ 1 file changed, 31 insertions(+)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index ac26b89d..85d4626b 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -562,6 +562,35 @@ static void _clear_cbuffers(struct knet_host *host, seq_num_t rx_seq_num)
+ 	}
+ }
+ 
++static void _reclaim_old_defrag_bufs(struct knet_host *host, seq_num_t seq_num)
++{
++	seq_num_t head, tail; /* seq_num boundaries */
++	int i;
++
++	head = seq_num + 1;
++	tail = seq_num - (KNET_MAX_LINK + 1);
++
++	/*
++	 * expire old defrag buffers
++	 */
++	for (i = 0; i < KNET_MAX_LINK; i++) {
++		if (host->defrag_buf[i].in_use) {
++			/*
++			 * head has done a rollover to 0+
++			 */
++			if (tail > head) {
++				if ((host->defrag_buf[i].pckt_seq >= head) && (host->defrag_buf[i].pckt_seq <= tail)) {
++					host->defrag_buf[i].in_use = 0;
++				}
++			} else {
++				if ((host->defrag_buf[i].pckt_seq >= head) || (host->defrag_buf[i].pckt_seq <= tail)){
++					host->defrag_buf[i].in_use = 0;
++				}
++			}
++		}
++	}
++}
++
+ /*
+  * check if a given packet seq num is in the circular buffers
+  * defrag_buf = 0 -> use normal cbuf 1 -> use the defrag buffer lookup
+@@ -579,6 +608,8 @@ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, i
+ 		_clear_cbuffers(host, seq_num);
+ 	}
+ 
++	_reclaim_old_defrag_bufs(host, seq_num);
++
+ 	if (seq_num < *dst_seq_num) {
+ 		seq_dist =  (SEQ_MAX - seq_num) + *dst_seq_num;
+ 	} else {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0323-rx-copy-data-into-the-defrag-buffer-only-if-we-know-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0323-rx-copy-data-into-the-defrag-buffer-only-if-we-know-.patch
new file mode 100644
index 000000000..0e06a76ff
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0323-rx-copy-data-into-the-defrag-buffer-only-if-we-know-.patch
@@ -0,0 +1,28 @@ 
+From 21fbea95c9ad5da1cb91fa2d5a742dca65f7ecc7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 15 Oct 2019 07:02:05 +0200
+Subject: [PATCH] [rx] copy data into the defrag buffer only if we know the
+ size of the frame
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index e8fe264a..ef0c2cc2 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -186,8 +186,10 @@ static int pckt_defrag(knet_handle_t knet_h, struct knet_header *inbuf, ssize_t
+ 		defrag_buf->frag_size = *len;
+ 	}
+ 
+-	memmove(defrag_buf->buf + ((inbuf->khp_data_frag_seq - 1) * defrag_buf->frag_size),
+-	       inbuf->khp_data_userdata, *len);
++	if (defrag_buf->frag_size) {
++		memmove(defrag_buf->buf + ((inbuf->khp_data_frag_seq - 1) * defrag_buf->frag_size),
++		       inbuf->khp_data_userdata, *len);
++	}
+ 
+ 	defrag_buf->frag_recv++;
+ 	defrag_buf->frag_map[inbuf->khp_data_frag_seq] = 1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0324-test-add-ability-to-knet_bench-to-specify-a-fixed-pa.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0324-test-add-ability-to-knet_bench-to-specify-a-fixed-pa.patch
new file mode 100644
index 000000000..9ffbaaac8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0324-test-add-ability-to-knet_bench-to-specify-a-fixed-pa.patch
@@ -0,0 +1,102 @@ 
+From 8cbc9b523120f31d0246b7e7c4a9bccefa1b8782 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 15 Oct 2019 07:16:22 +0200
+Subject: [PATCH] [test] add ability to knet_bench to specify a fixed packet
+ size for perf test
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/knet_bench.c | 24 ++++++++++++++++++++----
+ 1 file changed, 20 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index dc04239c..54b53031 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -67,6 +67,8 @@ static int test_type = TEST_PING;
+ static uint64_t perf_by_size_size = 1 * ONE_GIGABYTE;
+ static uint64_t perf_by_time_secs = 10;
+ 
++static uint32_t force_packet_size = 0;
++
+ struct node {
+ 	int nodeid;
+ 	int links;
+@@ -109,6 +111,7 @@ static void print_help(void)
+ 	printf(" -s                                        nodeid that will generate traffic for benchmarks\n");
+ 	printf(" -S [size|seconds]                         when used in combination with -T perf-by-size it indicates how many GB of traffic to generate for the test. (default: 1GB)\n");
+ 	printf("                                           when used in combination with -T perf-by-time it indicates how many Seconds of traffic to generate for the test. (default: 10 seconds)\n");
++	printf(" -x                                        force packet size for perf-by-time or perf-by-size\n");
+ 	printf(" -C                                        repeat the test continously (default: off)\n");
+ 	printf(" -X[XX]                                    show stats at the end of the run (default: 1)\n");
+ 	printf("                                           1: show handle stats, 2: show summary link stats\n");
+@@ -250,7 +253,7 @@ static void setup_knet(int argc, char *argv[])
+ 
+ 	memset(nodes, 0, sizeof(nodes));
+ 
+-	while ((rv = getopt(argc, argv, "aCT:S:s:ldfom:wb:t:n:c:p:X::P:z:h")) != EOF) {
++	while ((rv = getopt(argc, argv, "aCT:S:s:ldfom:wb:t:n:c:p:x:X::P:z:h")) != EOF) {
+ 		switch(rv) {
+ 			case 'h':
+ 				print_help();
+@@ -406,6 +409,13 @@ static void setup_knet(int argc, char *argv[])
+ 				perf_by_size_size = (uint64_t)atoi(optarg) * ONE_GIGABYTE;
+ 				perf_by_time_secs = (uint64_t)atoi(optarg);
+ 				break;
++			case 'x':
++				force_packet_size = (uint32_t)atoi(optarg);
++				if ((force_packet_size < 1) || (force_packet_size > 65536)) {
++					printf("Unsupported packet size %u (accepted 1 - 65536)\n", force_packet_size);
++					exit(FAIL);
++				}
++				break;
+ 			case 'C':
+ 				continous = 1;
+ 				break;
+@@ -874,7 +884,7 @@ static int setup_send_buffers_common(struct knet_mmsghdr *msg, struct iovec *iov
+ 			printf("TXT: Unable to malloc!\n");
+ 			return -1;
+ 		}
+-		memset(tx_buf[i], 0, KNET_MAX_PACKET_SIZE);
++		memset(tx_buf[i], i, KNET_MAX_PACKET_SIZE);
+ 		iov_out[i].iov_base = (void *)tx_buf[i];
+ 		memset(&msg[i].msg_hdr, 0, sizeof(struct msghdr));
+ 		msg[i].msg_hdr.msg_iov = &iov_out[i];
+@@ -898,6 +908,9 @@ static void send_perf_data_by_size(void)
+ 	setup_send_buffers_common(msg, iov_out, tx_buf);
+ 
+ 	while (packetsize <= KNET_MAX_PACKET_SIZE) {
++		if (force_packet_size) {
++			packetsize = force_packet_size;
++		}
+ 		for (i = 0; i < PCKT_FRAG_MAX; i++) {
+ 			iov_out[i].iov_len = packetsize;
+ 		}
+@@ -926,7 +939,7 @@ static void send_perf_data_by_size(void)
+ 
+ 		knet_send(knet_h, ctrl_message, TEST_STOP, channel);
+ 
+-		if (packetsize == KNET_MAX_PACKET_SIZE) {
++		if ((packetsize == KNET_MAX_PACKET_SIZE) || (force_packet_size)) {
+ 			break;
+ 		}
+ 
+@@ -1175,6 +1188,9 @@ static void send_perf_data_by_time(void)
+ 	memset(&clock_end, 0, sizeof(clock_start));
+ 
+ 	while (packetsize <= KNET_MAX_PACKET_SIZE) {
++		if (force_packet_size) {
++			packetsize = force_packet_size;
++		}
+ 		for (i = 0; i < PCKT_FRAG_MAX; i++) {
+ 			iov_out[i].iov_len = packetsize;
+ 		}
+@@ -1205,7 +1221,7 @@ static void send_perf_data_by_time(void)
+ 
+ 		knet_send(knet_h, ctrl_message, TEST_STOP, channel);
+ 
+-		if (packetsize == KNET_MAX_PACKET_SIZE) {
++		if ((packetsize == KNET_MAX_PACKET_SIZE) || (force_packet_size)) {
+ 			break;
+ 		}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0325-PMTUd-invalidate-MTU-for-a-link-if-the-value-is-lowe.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0325-PMTUd-invalidate-MTU-for-a-link-if-the-value-is-lowe.patch
new file mode 100644
index 000000000..ac6d432fa
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0325-PMTUd-invalidate-MTU-for-a-link-if-the-value-is-lowe.patch
@@ -0,0 +1,36 @@ 
+From 521080221f04d1a7856d6fdb1a5a94bfe486926d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 15 Oct 2019 11:53:56 +0200
+Subject: [PATCH] [PMTUd] invalidate MTU for a link if the value is lower than
+ minimum
+
+Under heavy network load and packet loss, calculated MTU can be
+too small. In that case we need to invalidate the link mtu,
+that would remove the link from the rotation (and traffic) and
+would give PMTUd time to get the right MTU in the next round.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_pmtud.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 75d51962..f4d15ae1 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -482,7 +482,14 @@ static int _handle_check_pmtud(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		}
+ 		dst_link->has_valid_mtu = 0;
+ 	} else {
+-		dst_link->has_valid_mtu = 1;
++		if (dst_link->status.mtu < calc_min_mtu(knet_h)) {
++			log_info(knet_h, KNET_SUB_PMTUD,
++				 "Invalid MTU detected for host: %u link: %u mtu: %u",
++				 dst_host->host_id, dst_link->link_id, dst_link->status.mtu);
++			dst_link->has_valid_mtu = 0;
++		} else {
++			dst_link->has_valid_mtu = 1;
++		}
+ 		if (dst_link->has_valid_mtu) {
+ 			if ((saved_pmtud) && (saved_pmtud != dst_link->status.mtu)) {
+ 				log_info(knet_h, KNET_SUB_PMTUD, "PMTUD link change for host: %u link: %u from %u to %u",
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0326-test-add-packet-verification-option-to-knet_bench.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0326-test-add-packet-verification-option-to-knet_bench.patch
new file mode 100644
index 000000000..0ef148805
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0326-test-add-packet-verification-option-to-knet_bench.patch
@@ -0,0 +1,138 @@ 
+From 914d45080b6ea466461dea0aa9e145098dc27f70 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 16 Oct 2019 08:10:23 +0200
+Subject: [PATCH] [test] add packet verification option to knet_bench
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/knet_bench.c | 58 ++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 55 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index 54b53031..c9e1c062 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -47,6 +47,7 @@ static char *compresscfg = NULL;
+ static char *cryptocfg = NULL;
+ static int machine_output = 0;
+ static int use_access_lists = 0;
++static int use_pckt_verification = 0;
+ 
+ static int bench_shutdown_in_progress = 0;
+ static pthread_mutex_t shutdown_mutex = PTHREAD_MUTEX_INITIALIZER;
+@@ -76,6 +77,11 @@ struct node {
+ 	struct sockaddr_storage address[KNET_MAX_LINK];
+ };
+ 
++struct pckt_ver {
++	uint32_t len;
++	uint32_t chksum;
++};
++
+ static void print_help(void)
+ {
+ 	printf("knet_bench usage:\n");
+@@ -117,6 +123,7 @@ static void print_help(void)
+ 	printf("                                           1: show handle stats, 2: show summary link stats\n");
+ 	printf("                                           3: show detailed link stats\n");
+ 	printf(" -a                                        enable machine parsable output (default: off).\n");
++	printf(" -v                                        enable packet verification for performance tests (default: off).\n");
+ }
+ 
+ static void parse_nodes(char *nodesinfo[MAX_NODES], int onidx, int port, struct node nodes[MAX_NODES], int *thisidx)
+@@ -253,7 +260,7 @@ static void setup_knet(int argc, char *argv[])
+ 
+ 	memset(nodes, 0, sizeof(nodes));
+ 
+-	while ((rv = getopt(argc, argv, "aCT:S:s:ldfom:wb:t:n:c:p:x:X::P:z:h")) != EOF) {
++	while ((rv = getopt(argc, argv, "aCT:S:s:lvdfom:wb:t:n:c:p:x:X::P:z:h")) != EOF) {
+ 		switch(rv) {
+ 			case 'h':
+ 				print_help();
+@@ -411,11 +418,14 @@ static void setup_knet(int argc, char *argv[])
+ 				break;
+ 			case 'x':
+ 				force_packet_size = (uint32_t)atoi(optarg);
+-				if ((force_packet_size < 1) || (force_packet_size > 65536)) {
+-					printf("Unsupported packet size %u (accepted 1 - 65536)\n", force_packet_size);
++				if ((force_packet_size < 64) || (force_packet_size > 65536)) {
++					printf("Unsupported packet size %u (accepted 64 - 65536)\n", force_packet_size);
+ 					exit(FAIL);
+ 				}
+ 				break;
++			case 'v':
++				use_pckt_verification = 1;
++				break;
+ 			case 'C':
+ 				continous = 1;
+ 				break;
+@@ -654,6 +664,24 @@ static void setup_knet(int argc, char *argv[])
+ 	}
+ }
+ 
++/*
++ * calculate weak chksum (stole from corosync for debugging purposes)
++ */
++static uint32_t compute_chsum(const unsigned char *data, uint32_t data_len)
++{
++	unsigned int i;
++	unsigned int checksum = 0;
++
++	for (i = 0; i < data_len; i++) {
++		if (checksum & 1) {
++			checksum |= 0x10000;
++		}
++
++		checksum = ((checksum >> 1) + (unsigned char)data[i]) & 0xffff;
++	}
++	return (checksum);
++}
++
+ static void *_rx_thread(void *args)
+ {
+ 	int rx_epoll;
+@@ -766,6 +794,20 @@ static void *_rx_thread(void *args)
+ 							}
+ 							continue;
+ 						}
++						if (use_pckt_verification) {
++							struct pckt_ver *recv_pckt = (struct pckt_ver *)msg[i].msg_hdr.msg_iov->iov_base;
++							uint32_t chksum;
++
++							if (msg[i].msg_len != recv_pckt->len) {
++								printf("Wrong packet len received: %u expected: %u!\n", msg[i].msg_len, recv_pckt->len);
++								exit(FAIL);
++							}
++							chksum = compute_chsum((const unsigned char *)msg[i].msg_hdr.msg_iov->iov_base + sizeof(struct pckt_ver), msg[i].msg_len - sizeof(struct pckt_ver));
++							if (recv_pckt->chksum != chksum){
++								printf("Wrong packet checksum received: %u expected: %u!\n", recv_pckt->chksum, chksum);
++								exit(FAIL);
++							}
++						}
+ 						rx_pkts++;
+ 						rx_bytes = rx_bytes + msg[i].msg_len;
+ 						current_pckt_size = msg[i].msg_len;
+@@ -913,6 +955,11 @@ static void send_perf_data_by_size(void)
+ 		}
+ 		for (i = 0; i < PCKT_FRAG_MAX; i++) {
+ 			iov_out[i].iov_len = packetsize;
++			if (use_pckt_verification) {
++				struct pckt_ver *tx_pckt = (struct pckt_ver *)&iov_out[i].iov_base;
++				tx_pckt->len = iov_out[i].iov_len;
++				tx_pckt->chksum = compute_chsum((const unsigned char *)iov_out[i].iov_base + sizeof(struct pckt_ver), iov_out[i].iov_len - sizeof(struct pckt_ver));
++			}
+ 		}
+ 
+ 		total_pkts_to_tx = perf_by_size_size / packetsize;
+@@ -1193,6 +1240,11 @@ static void send_perf_data_by_time(void)
+ 		}
+ 		for (i = 0; i < PCKT_FRAG_MAX; i++) {
+ 			iov_out[i].iov_len = packetsize;
++			if (use_pckt_verification) {
++				struct pckt_ver *tx_pckt = (struct pckt_ver *)iov_out[i].iov_base;
++				tx_pckt->len = iov_out[i].iov_len;
++				tx_pckt->chksum = compute_chsum((const unsigned char *)iov_out[i].iov_base + sizeof(struct pckt_ver), iov_out[i].iov_len - sizeof(struct pckt_ver));
++			}
+ 		}
+ 		printf("[info]: testing with %u bytes packet size for %" PRIu64 " seconds.\n", packetsize, perf_by_time_secs);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0327-test-append-newline-to-knet_send-timeout-message.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0327-test-append-newline-to-knet_send-timeout-message.patch
new file mode 100644
index 000000000..dd7105e9a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0327-test-append-newline-to-knet_send-timeout-message.patch
@@ -0,0 +1,22 @@ 
+From e11b078d5bc2ab1386005f5ab9c69d373af24fd8 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Fri, 18 Oct 2019 08:38:04 +0200
+Subject: [PATCH] [test] append newline to knet_send timeout message
+
+---
+ libknet/tests/api_knet_send.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index c2166efe..1445e315 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -212,7 +212,7 @@ static void test(uint8_t transport)
+ 	}
+ 
+ 	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
++		printf("timeout waiting for host to be reachable\n");
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0328-build-fix-openssl-version-detection-when-not-using-p.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0328-build-fix-openssl-version-detection-when-not-using-p.patch
new file mode 100644
index 000000000..9193ed9c0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0328-build-fix-openssl-version-detection-when-not-using-p.patch
@@ -0,0 +1,98 @@ 
+From 02e2861674ae7cde289b6b09aca63eefa4569ab5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 27 Oct 2019 06:42:54 +0100
+Subject: [PATCH] [build] fix openssl version detection when not using
+ pkg-config
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac             |  8 +-------
+ libknet/crypto_openssl.c | 15 ++++++---------
+ 2 files changed, 7 insertions(+), 16 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index e430aeb8..74d75e08 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -122,19 +122,13 @@ AC_ARG_ENABLE([crypto-all],
+ 	[ enable_crypto_all="yes" ])
+ 
+ KNET_OPTION_DEFINES([nss],[crypto],[PKG_CHECK_MODULES([nss], [nss])])
+-KNET_OPTION_DEFINES([openssl],[crypto],[
+-	PKG_CHECK_MODULES([openssl],[libcrypto < 1.1],
+-			  [AC_DEFINE_UNQUOTED([BUILDCRYPTOOPENSSL10], [1], [openssl 1.0 crypto])],
+-			  [PKG_CHECK_MODULES([openssl],[libcrypto >= 1.1],
+-					     [AC_DEFINE_UNQUOTED([BUILDCRYPTOOPENSSL11], [1], [openssl 1.1 crypto])])])
+-])
++KNET_OPTION_DEFINES([openssl],[crypto],[PKG_CHECK_MODULES([openssl],[libcrypto])])
+ 
+ AC_ARG_ENABLE([compress-all],
+ 	[AS_HELP_STRING([--disable-compress-all],[disable libknet all compress modules support])],,
+ 	[ enable_compress_all="yes" ])
+ 
+ KNET_OPTION_DEFINES([zstd],[compress],[PKG_CHECK_MODULES([libzstd], [libzstd])])
+-
+ KNET_OPTION_DEFINES([zlib],[compress],[PKG_CHECK_MODULES([zlib], [zlib])])
+ KNET_OPTION_DEFINES([lz4],[compress],[PKG_CHECK_MODULES([liblz4], [liblz4])])
+ KNET_OPTION_DEFINES([lzo2],[compress],[
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 65714984..6df4a331 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -50,7 +50,7 @@ static int openssl_is_init = 0;
+  * crypt/decrypt functions openssl1.0
+  */
+ 
+-#ifdef BUILDCRYPTOOPENSSL10
++#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ static int encrypt_openssl(
+ 	knet_handle_t knet_h,
+ 	const struct iovec *iov,
+@@ -150,9 +150,7 @@ out:
+ 	EVP_CIPHER_CTX_cleanup(&ctx);
+ 	return err;
+ }
+-#endif
+-
+-#ifdef BUILDCRYPTOOPENSSL11
++#else /* (OPENSSL_VERSION_NUMBER < 0x10100000L) */
+ static int encrypt_openssl(
+ 	knet_handle_t knet_h,
+ 	const struct iovec *iov,
+@@ -386,7 +384,7 @@ static int opensslcrypto_authenticate_and_decrypt (
+ 	return 0;
+ }
+ 
+-#ifdef BUILDCRYPTOOPENSSL10
++#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ static pthread_mutex_t *openssl_internal_lock;
+ 
+ static void openssl_internal_locking_callback(int mode, int type, char *file, int line)
+@@ -476,7 +474,7 @@ static void opensslcrypto_fini(
+ 		crypto_instance->model_instance = NULL;
+ 	}
+ 
+-#ifdef BUILDCRYPTOOPENSSL10
++#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ 	ERR_free_strings();
+ #endif
+ 
+@@ -497,7 +495,7 @@ static int opensslcrypto_init(
+ 		  knet_handle_crypto_cfg->crypto_hash_type);
+ 
+ 	if (!openssl_is_init) {
+-#ifdef BUILDCRYPTOOPENSSL10
++#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ 		ERR_load_crypto_strings();
+ 		OPENSSL_add_all_algorithms_noconf();
+ 		if (openssl_internal_lock_setup() < 0) {
+@@ -505,8 +503,7 @@ static int opensslcrypto_init(
+ 			errno = EAGAIN;
+ 			return -1;
+ 		}
+-#endif
+-#ifdef BUILDCRYPTOOPENSSL11
++#else
+ 		if (!OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
+ 					 | OPENSSL_INIT_ADD_ALL_DIGESTS, NULL)) {
+ 			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to init openssl");
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0329-RX-Discard-incoming-packets-if-knet-cannot-reply-bac.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0329-RX-Discard-incoming-packets-if-knet-cannot-reply-bac.patch
new file mode 100644
index 000000000..080901602
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0329-RX-Discard-incoming-packets-if-knet-cannot-reply-bac.patch
@@ -0,0 +1,31 @@ 
+From 791de3eacc8a39d47f3d430faaa67a1197eca0a3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 18 Oct 2019 10:41:49 +0200
+Subject: [PATCH] [RX] Discard incoming packets if knet cannot reply back.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 9 ++-------
+ 1 file changed, 2 insertions(+), 7 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index ef0c2cc2..9457c12b 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -339,14 +339,9 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	switch (inbuf->kh_type) {
+ 	case KNET_HEADER_TYPE_HOST_INFO:
+ 	case KNET_HEADER_TYPE_DATA:
+-		/*
+-		 * TODO: should we accept data even if we can't reply to the other node?
+-		 *       how would that work with SCTP and guaranteed delivery?
+-		 */
+-
+ 		if (!src_host->status.reachable) {
+-			log_debug(knet_h, KNET_SUB_RX, "Source host %u not reachable yet", src_host->host_id);
+-			//return;
++			log_debug(knet_h, KNET_SUB_RX, "Source host %u not reachable yet. Discarding packet.", src_host->host_id);
++			return;
+ 		}
+ 		inbuf->khp_data_seq_num = ntohs(inbuf->khp_data_seq_num);
+ 		channel = inbuf->khp_data_channel;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0330-RX-handle-short-write-to-the-application-properly.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0330-RX-handle-short-write-to-the-application-properly.patch
new file mode 100644
index 000000000..5dcb9242d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0330-RX-handle-short-write-to-the-application-properly.patch
@@ -0,0 +1,51 @@ 
+From 8f772089871bf7b10077d7e5745cb02f358c0ac4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 19 Oct 2019 08:47:27 +0200
+Subject: [PATCH] [RX] handle short write to the application properly
+
+this change affects only applications that are not using knet
+generated socketpairs to deliver/receive data to/from knet.
+
+If an application uses a fd that is not SOCK_SEQPACKET (basically
+streaming), we have to handle short writes accordingly, and knet
+will continue delivering as long as there is progress.
+
+The application is responsible to verify that the data packet
+is complete as the delivery is not guaranteed to be complete.
+The application can either embed the size of the packet in their
+data structure or use the socket error notification callback
+that will be invoked in case of errors or 0 data delivery.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 14 ++++++++++++--
+ 1 file changed, 12 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 9457c12b..efa7ed55 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -476,11 +476,21 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 				return;
+ 			}
+ 
++			outlen = 0;
+ 			memset(iov_out, 0, sizeof(iov_out));
+-			iov_out[0].iov_base = (void *) inbuf->khp_data_userdata;
+-			iov_out[0].iov_len = len - KNET_HEADER_DATA_SIZE;
++
++retry:
++			iov_out[0].iov_base = (void *) inbuf->khp_data_userdata + outlen;
++			iov_out[0].iov_len = len - (outlen + KNET_HEADER_DATA_SIZE);
+ 
+ 			outlen = writev(knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], iov_out, 1);
++			if ((outlen > 0) && (outlen < (ssize_t)iov_out[0].iov_len)) {
++				log_debug(knet_h, KNET_SUB_RX,
++					  "Unable to send all data to the application in one go. Expected: %zu Sent: %zd\n",
++					  iov_out[0].iov_len, outlen);
++				goto retry;
++			}
++
+ 			if (outlen <= 0) {
+ 				knet_h->sock_notify_fn(knet_h->sock_notify_fn_private_data,
+ 						       knet_h->sockfd[channel].sockfd[0],
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0331-TX-discard-too-big-packets-when-reading-from-socketp.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0331-TX-discard-too-big-packets-when-reading-from-socketp.patch
new file mode 100644
index 000000000..6002f1f40
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0331-TX-discard-too-big-packets-when-reading-from-socketp.patch
@@ -0,0 +1,82 @@ 
+From 0dd85a54c04d33d93cabb4a2dcb23a1e836b944f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 18 Oct 2019 11:17:57 +0200
+Subject: [PATCH] [TX] discard too big packets when reading from socketpairs
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_send.c | 31 +++++++++++++++++++++++++++++--
+ libknet/threads_tx.c          |  4 ++++
+ 2 files changed, 33 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 1445e315..4b01e6f1 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -40,7 +40,7 @@ static void test(uint8_t transport)
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+ 	struct knet_link_status link_status;
+-	char send_buff[KNET_MAX_PACKET_SIZE];
++	char send_buff[KNET_MAX_PACKET_SIZE + 1];
+ 	char recv_buff[KNET_MAX_PACKET_SIZE];
+ 	ssize_t send_len = 0;
+ 	int recv_len = 0;
+@@ -234,7 +234,7 @@ static void test(uint8_t transport)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (send_len != sizeof(send_buff)) {
++	if (send_len != sizeof(send_buff) - 1) {
+ 		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+ 		knet_link_set_enable(knet_h, 1, 0, 0);
+ 		knet_link_clear_config(knet_h, 1, 0);
+@@ -324,6 +324,33 @@ static void test(uint8_t transport)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	if (knet_handle_setfwd(knet_h, 1) < 0) {
++		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	printf("try to send big packet to local datafd (bypass knet_send)\n");
++	if (write(datafd, &send_buff, sizeof(send_buff)) != KNET_MAX_PACKET_SIZE + 1) {
++		printf("Error writing to datafd: %s\n", strerror(errno));
++	}
++
++	if (!wait_for_packet(knet_h, 2, datafd, logfds[0], stdout)) {
++		printf("Received unexpected packet!\n");
++		knet_link_set_enable(knet_h, 1, 0, 0);
++		knet_link_clear_config(knet_h, 1, 0);
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	knet_link_set_enable(knet_h, 1, 0, 0);
+ 	knet_link_clear_config(knet_h, 1, 0);
+ 	knet_host_remove(knet_h, 1);
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 1d954d6e..6f06e5d9 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -633,6 +633,10 @@ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int
+ 		inlen = readv(sockfd, msg->msg_iov, 1);
+ 	} else {
+ 		inlen = recvmsg(sockfd, msg, MSG_DONTWAIT | MSG_NOSIGNAL);
++		if (msg->msg_flags & MSG_TRUNC) {
++			log_warn(knet_h, KNET_SUB_TX, "Received truncated message from sock %d. Discarding", sockfd);
++			return;
++		}
+ 	}
+ 
+ 	if (inlen == 0) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0332-RX-silence-defrag-buffer-expiration-debug-error.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0332-RX-silence-defrag-buffer-expiration-debug-error.patch
new file mode 100644
index 000000000..1322ae8f9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0332-RX-silence-defrag-buffer-expiration-debug-error.patch
@@ -0,0 +1,27 @@ 
+From 566fea2dec3fe3ed389eec6255e12f9a31de65b6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 19 Oct 2019 09:05:16 +0200
+Subject: [PATCH] [RX] silence defrag buffer expiration debug error
+
+when using active-active links, it is simply too noisy and
+doesn't provide very useful information.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 3 ---
+ 1 file changed, 3 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index efa7ed55..1d136aea 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -128,9 +128,6 @@ static int pckt_defrag(knet_handle_t knet_h, struct knet_header *inbuf, ssize_t
+ 
+ 	defrag_buf_idx = find_pckt_defrag_buf(knet_h, inbuf);
+ 	if (defrag_buf_idx < 0) {
+-		if (errno == ETIME) {
+-			log_debug(knet_h, KNET_SUB_RX, "Defrag buffer expired");
+-		}
+ 		return 1;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0333-handle-make-sure-to-unlock-config-handle-on-failure.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0333-handle-make-sure-to-unlock-config-handle-on-failure.patch
new file mode 100644
index 000000000..9ded6aa5d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0333-handle-make-sure-to-unlock-config-handle-on-failure.patch
@@ -0,0 +1,22 @@ 
+From 7f6fcca6decdeb312a209a46b268fc9d13d1d098 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 29 Oct 2019 13:20:55 +0100
+Subject: [PATCH] [handle] make sure to unlock config handle on failure
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 2b11e0f3..91c3f870 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -665,6 +665,7 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to init handles traceker: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
++		pthread_mutex_unlock(&handle_config_mutex);
+ 		goto exit_fail;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0334-handle-fix-typo-in-error-log-message.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0334-handle-fix-typo-in-error-log-message.patch
new file mode 100644
index 000000000..acac8928a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0334-handle-fix-typo-in-error-log-message.patch
@@ -0,0 +1,22 @@ 
+From 834756973d3801f8556c3bdba361929eb29901ca Mon Sep 17 00:00:00 2001
+From: wferi <wferi@debian.org>
+Date: Sun, 3 Nov 2019 09:22:38 +0100
+Subject: [PATCH] [handle] fix typo in error log message
+
+---
+ libknet/handle.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 91c3f870..2c7d312f 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -662,7 +662,7 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 
+ 	if (_init_shlib_tracker(knet_h) < 0) {
+ 		savederrno = errno;
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to init handles traceker: %s",
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to init handle tracker: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
+ 		pthread_mutex_unlock(&handle_config_mutex);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0335-tests-mark-array-as-static.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0335-tests-mark-array-as-static.patch
new file mode 100644
index 000000000..8e4c08990
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0335-tests-mark-array-as-static.patch
@@ -0,0 +1,43 @@ 
+From bfec85e5369c7d910cbb46e299868241d09da6f9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 20 Nov 2019 09:47:39 +0100
+Subject: [PATCH] [tests] mark array as static
+
+fixes an odd segfault when running the test on ppc when built with clang
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/int_links_acl_ip.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+index 41e7d592..829a2351 100644
+--- a/libknet/tests/int_links_acl_ip.c
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -76,7 +76,7 @@ static int read_2ip(const char *buf, const char *delim, struct sockaddr_storage
+  * ipcheck_validate calls
+  */
+ 
+-const char *rules[100] = {
++static const char *rules[100] = {
+ 	/*
+ 	 * ipv4
+ 	 */
+@@ -188,7 +188,7 @@ static int default_rules(int load)
+ 	return 0;
+ }
+ 
+-const char *tests[100] = {
++static const char *tests[100] = {
+ 	/*
+ 	 * ipv4
+ 	 */
+@@ -209,7 +209,7 @@ const char *tests[100] = {
+ 	"A3ffe:1::1:1"
+ };
+ 
+-const char *after_insert_tests[100] = {
++static const char *after_insert_tests[100] = {
+ 	/*
+ 	 * ipv4
+ 	 */
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0336-host-use-KNET_MAX_HOST_LEN-consistently.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0336-host-use-KNET_MAX_HOST_LEN-consistently.patch
new file mode 100644
index 000000000..50481e52e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0336-host-use-KNET_MAX_HOST_LEN-consistently.patch
@@ -0,0 +1,43 @@ 
+From 6db356d6212bf972ce33a9c6e502cbd708d1a05c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 22 Jan 2020 05:17:39 +0100
+Subject: [PATCH] [host] use KNET_MAX_HOST_LEN consistently
+
+detected by gcc10
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index 85d4626b..d919dff4 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -77,7 +77,7 @@ int knet_host_add(knet_handle_t knet_h, knet_node_id_t host_id)
+ 	/*
+ 	 * set default host->name to host_id for logging
+ 	 */
+-	snprintf(host->name, KNET_MAX_HOST_LEN - 1, "%u", host_id);
++	snprintf(host->name, KNET_MAX_HOST_LEN, "%u", host_id);
+ 
+ 	/*
+ 	 * initialize links internal data
+@@ -226,7 +226,7 @@ int knet_host_set_name(knet_handle_t knet_h, knet_node_id_t host_id, const char
+ 	}
+ 
+ 	for (host = knet_h->host_head; host != NULL; host = host->next) {
+-		if (!strncmp(host->name, name, KNET_MAX_HOST_LEN - 1)) {
++		if (!strncmp(host->name, name, KNET_MAX_HOST_LEN)) {
+ 			err = -1;
+ 			savederrno = EEXIST;
+ 			log_err(knet_h, KNET_SUB_HOST, "Duplicated name found on host_id %u",
+@@ -235,7 +235,7 @@ int knet_host_set_name(knet_handle_t knet_h, knet_node_id_t host_id, const char
+ 		}
+ 	}
+ 
+-	snprintf(knet_h->host_index[host_id]->name, KNET_MAX_HOST_LEN - 1, "%s", name);
++	snprintf(knet_h->host_index[host_id]->name, KNET_MAX_HOST_LEN, "%s", name);
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0337-nozzle-use-interface-name-size-consistently-and-drop.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0337-nozzle-use-interface-name-size-consistently-and-drop.patch
new file mode 100644
index 000000000..a15bbdd43
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0337-nozzle-use-interface-name-size-consistently-and-drop.patch
@@ -0,0 +1,114 @@ 
+From b54a868571a3889cfa8670e82fef43c67a0280a7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 22 Jan 2020 05:39:17 +0100
+Subject: [PATCH] [nozzle] use interface name size consistently and drop
+ strncpy in favour of memmove
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/internals.h |  2 +-
+ libnozzle/libnozzle.c | 22 +++++++++++-----------
+ 2 files changed, 12 insertions(+), 12 deletions(-)
+
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index ab870ef7..c9192a81 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -34,7 +34,7 @@ struct nozzle_lib_config {
+ #define UPDOWN_PATH_MAX    PATH_MAX - 11 - 1 - IFNAMSIZ
+ 
+ struct nozzle_iface {
+-	char name[IFNAMSIZ - 1];	/* interface name */
++	char name[IFNAMSIZ];		/* interface name */
+ 	int fd;				/* interface fd */
+ 	int up;				/* interface status 0 is down, 1 is up */
+ 	/*
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 3a1f827c..61096096 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -109,7 +109,7 @@ static void destroy_iface(nozzle_t nozzle)
+ 
+ #ifdef KNET_BSD
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ 
+ 	ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
+ #endif
+@@ -127,7 +127,7 @@ static int get_iface_mtu(const nozzle_t nozzle)
+ 	struct ifreq ifr;
+ 
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ 
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCGIFMTU, &ifr);
+ 	if (err) {
+@@ -155,7 +155,7 @@ static int get_iface_mac(const nozzle_t nozzle, char **ether_addr)
+ 
+ 	memset(&mac, 0, MACADDR_CHAR_MAX);
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ 
+ #ifdef KNET_LINUX
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+@@ -523,8 +523,8 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		savederrno = EBUSY;
+ 		goto out_error;
+ 	}
+-	strncpy(devname, curnozzle, IFNAMSIZ);
+-	memmove(nozzle->name, curnozzle, IFNAMSIZ - 1);
++	memmove(devname, curnozzle, IFNAMSIZ);
++	memmove(nozzle->name, curnozzle, IFNAMSIZ);
+ #endif
+ 
+ #ifdef KNET_LINUX
+@@ -547,8 +547,8 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 		goto out_error;
+ 	}
+ 
+-	strncpy(devname, ifname, IFNAMSIZ);
+-	memmove(nozzle->name, ifname, IFNAMSIZ - 1);
++	memmove(devname, ifname, IFNAMSIZ);
++	memmove(nozzle->name, ifname, IFNAMSIZ);
+ #endif
+ 
+ 	nozzle->default_mtu = get_iface_mtu(nozzle);
+@@ -732,7 +732,7 @@ int nozzle_set_up(nozzle_t nozzle)
+ 	}
+ 
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ 
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+ 	if (err) {
+@@ -777,7 +777,7 @@ int nozzle_set_down(nozzle_t nozzle)
+ 	}
+ 
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ 
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCGIFFLAGS, &ifr);
+ 	if (err) {
+@@ -878,7 +878,7 @@ int nozzle_set_mac(nozzle_t nozzle, const char *ether_addr)
+ 	}
+ 
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ #ifdef KNET_LINUX
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCGIFHWADDR, &ifr);
+ 	if (err) {
+@@ -1025,7 +1025,7 @@ int nozzle_set_mtu(nozzle_t nozzle, const int mtu)
+ 	}
+ 
+ 	memset(&ifr, 0, sizeof(struct ifreq));
+-	strncpy(ifname, nozzle->name, IFNAMSIZ);
++	memmove(ifname, nozzle->name, IFNAMSIZ);
+ 	ifr.ifr_mtu = mtu;
+ 
+ 	err = ioctl(lib_cfg.ioctlfd, SIOCSIFMTU, &ifr);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0338-udp-don-t-make-socket-spin-if-a-network-I-F-is-down.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0338-udp-don-t-make-socket-spin-if-a-network-I-F-is-down.patch
new file mode 100644
index 000000000..7cfd40923
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0338-udp-don-t-make-socket-spin-if-a-network-I-F-is-down.patch
@@ -0,0 +1,37 @@ 
+From ee2c5c6f601655ad6eb711f5950f4ab04826a0d4 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 24 Jan 2020 09:33:50 +0000
+Subject: [PATCH] [udp] don't make socket spin if a network I/F is down
+
+UDP treats ENETUNREACH as a temporary error and just retries,
+but this causes the TX thread to spin just doing sendto() therefore
+blocking all other traffic.
+
+(To reproduce this try starting corosync with 2 links configured in
+corosync.conf but only one of them configured to the 'right' address
+- it will spin in a tight loop and need to be killed with -9)
+
+SCTP does not seem to suffer from this.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_udp.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index be990bbf..dac6fbef 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -401,6 +401,12 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 		if ((recv_errno == ENOBUFS) || (recv_errno == EAGAIN)) {
+ #ifdef DEBUG
+ 			log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is overloaded. Slowing TX down", sockfd);
++#endif
++			usleep(KNET_THREADS_TIMERES / 16);
++		}
++		if (recv_errno == ENETUNREACH) {
++#ifdef DEBUG
++			log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is unreachable", sockfd);
+ #endif
+ 			usleep(KNET_THREADS_TIMERES / 16);
+ 		} else {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0339-udp-simplify-code-same-logic.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0339-udp-simplify-code-same-logic.patch
new file mode 100644
index 000000000..dc7c4c8da
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0339-udp-simplify-code-same-logic.patch
@@ -0,0 +1,36 @@ 
+From 5e274a692769bea3c720254c1315a9a254e96fe6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sat, 25 Jan 2020 06:26:28 +0100
+Subject: [PATCH] [udp] simplify code (same logic)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_udp.c | 14 ++++++--------
+ 1 file changed, 6 insertions(+), 8 deletions(-)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index dac6fbef..b5120970 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -398,15 +398,13 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 		if (recv_errno == EINVAL || recv_errno == EPERM) {
+ 			return -1;
+ 		}
+-		if ((recv_errno == ENOBUFS) || (recv_errno == EAGAIN)) {
++		if ((recv_errno == ENOBUFS) || (recv_errno == EAGAIN) || (recv_errno == ENETUNREACH)) {
+ #ifdef DEBUG
+-			log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is overloaded. Slowing TX down", sockfd);
+-#endif
+-			usleep(KNET_THREADS_TIMERES / 16);
+-		}
+-		if (recv_errno == ENETUNREACH) {
+-#ifdef DEBUG
+-			log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is unreachable", sockfd);
++			if (recv_errno == ENETUNREACH) {
++				log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is unreachable", sockfd);
++			} else {
++				log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is overloaded. Slowing TX down", sockfd);
++			}
+ #endif
+ 			usleep(KNET_THREADS_TIMERES / 16);
+ 		} else {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0340-udp-Better-fix-for-ENETUNREACH.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0340-udp-Better-fix-for-ENETUNREACH.patch
new file mode 100644
index 000000000..e249fc1a4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0340-udp-Better-fix-for-ENETUNREACH.patch
@@ -0,0 +1,43 @@ 
+From 308e676e57b5a684730d6350e217cc1d1cf6634a Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Wed, 29 Jan 2020 15:52:26 +0000
+Subject: [PATCH] [udp] Better fix for -ENETUNREACH
+
+This fix for the ENETUNREACH problem works better than the last one
+in that it also works with Linux kernels > 5.0.0 (which return
+-ENETUNREACH) if an interfaces is brought down, and also on FreeBSD
+which returns ENETDOWN.
+---
+ libknet/transport_udp.c | 16 +++++++++-------
+ 1 file changed, 9 insertions(+), 7 deletions(-)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index b5120970..3f7ca047 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -395,16 +395,18 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 			read_errs_from_sock(knet_h, sockfd);
+ 			return 0;
+ 		}
+-		if (recv_errno == EINVAL || recv_errno == EPERM) {
++		if ((recv_errno == EINVAL) || (recv_errno == EPERM) ||
++		    (recv_errno == ENETUNREACH) || (recv_errno == ENETDOWN)) {
++#ifdef DEBUG
++			if ((recv_errno == ENETUNREACH) || (recv_errno == ENETDOWN)) {
++				log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is unreachable.", sockfd);
++			}
++#endif
+ 			return -1;
+ 		}
+-		if ((recv_errno == ENOBUFS) || (recv_errno == EAGAIN) || (recv_errno == ENETUNREACH)) {
++		if ((recv_errno == ENOBUFS) || (recv_errno == EAGAIN)) {
+ #ifdef DEBUG
+-			if (recv_errno == ENETUNREACH) {
+-				log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is unreachable", sockfd);
+-			} else {
+-				log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is overloaded. Slowing TX down", sockfd);
+-			}
++			log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is overloaded. Slowing TX down", sockfd);
+ #endif
+ 			usleep(KNET_THREADS_TIMERES / 16);
+ 		} else {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0341-latency-fix-incorrect-math-that-could-lead-to-bad-la.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0341-latency-fix-incorrect-math-that-could-lead-to-bad-la.patch
new file mode 100644
index 000000000..e1ac781f2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0341-latency-fix-incorrect-math-that-could-lead-to-bad-la.patch
@@ -0,0 +1,117 @@ 
+From 97c0bedcc8714380fb6499faee2d553b086c43fd Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 29 Jan 2020 16:02:46 +0100
+Subject: [PATCH] [latency] fix incorrect math that could lead to bad latency
+ calculation
+
+Also, document a bit better how latency is calculated
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h                           |  4 ++--
+ libknet/links.c                               | 11 ++++-------
+ libknet/tests/api_knet_link_set_ping_timers.c |  2 +-
+ libknet/threads_rx.c                          | 18 ++++++++++++++----
+ 4 files changed, 21 insertions(+), 14 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 4fa12543..00216241 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -65,7 +65,8 @@ struct knet_link {
+ 	unsigned long long pong_timeout;	/* timeout */
+ 	unsigned long long pong_timeout_adj;	/* timeout adjusted for latency */
+ 	uint8_t pong_timeout_backoff;		/* see link.h for definition */
+-	unsigned int latency_fix;		/* precision */
++	unsigned int latency_max_samples;	/* precision */
++	unsigned int latency_cur_samples;
+ 	uint8_t pong_count;			/* how many ping/pong to send/receive before link is up */
+ 	uint64_t flags;
+ 	/* status */
+@@ -77,7 +78,6 @@ struct knet_link {
+ 	int outsock;
+ 	unsigned int configured:1;		/* set to 1 if src/dst have been configured transport initialized on this link*/
+ 	unsigned int transport_connected:1;	/* set to 1 if lower level transport is connected */
+-	unsigned int latency_exp;
+ 	uint8_t received_pong;
+ 	struct timespec ping_last;
+ 	/* used by PMTUD thread as temp per-link variables and should always contain the onwire_len value! */
+diff --git a/libknet/links.c b/libknet/links.c
+index f7eccc3f..2b5dca3f 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -226,9 +226,8 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	link->pong_timeout = KNET_LINK_DEFAULT_PING_TIMEOUT * 1000; /* microseconds */
+ 	link->pong_timeout_backoff = KNET_LINK_PONG_TIMEOUT_BACKOFF;
+ 	link->pong_timeout_adj = link->pong_timeout * link->pong_timeout_backoff; /* microseconds */
+-	link->latency_fix = KNET_LINK_DEFAULT_PING_PRECISION;
+-	link->latency_exp = KNET_LINK_DEFAULT_PING_PRECISION - \
+-			    ((link->ping_interval * KNET_LINK_DEFAULT_PING_PRECISION) / 8000000);
++	link->latency_max_samples = KNET_LINK_DEFAULT_PING_PRECISION;
++	link->latency_cur_samples = 0;
+ 	link->flags = flags;
+ 
+ 	if (transport_link_set_config(knet_h, link, transport) < 0) {
+@@ -813,9 +812,7 @@ int knet_link_set_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
+ 
+ 	link->ping_interval = interval * 1000; /* microseconds */
+ 	link->pong_timeout = timeout * 1000; /* microseconds */
+-	link->latency_fix = precision;
+-	link->latency_exp = precision - \
+-			    ((link->ping_interval * precision) / 8000000);
++	link->latency_max_samples = precision;
+ 
+ 	log_debug(knet_h, KNET_SUB_LINK,
+ 		  "host: %u link: %u timeout update - interval: %llu timeout: %llu precision: %u",
+@@ -888,7 +885,7 @@ int knet_link_get_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
+ 
+ 	*interval = link->ping_interval / 1000; /* microseconds */
+ 	*timeout = link->pong_timeout / 1000;
+-	*precision = link->latency_fix;
++	*precision = link->latency_max_samples;
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+diff --git a/libknet/tests/api_knet_link_set_ping_timers.c b/libknet/tests/api_knet_link_set_ping_timers.c
+index 46170f6e..bc4d142e 100644
+--- a/libknet/tests/api_knet_link_set_ping_timers.c
++++ b/libknet/tests/api_knet_link_set_ping_timers.c
+@@ -156,7 +156,7 @@ static void test(void)
+ 
+ 	if ((knet_h->host_index[1]->link[0].ping_interval != 1000000) ||
+ 	    (knet_h->host_index[1]->link[0].pong_timeout != 2000000) ||
+-	    (knet_h->host_index[1]->link[0].latency_fix != 2048)) {
++	    (knet_h->host_index[1]->link[0].latency_max_samples != 2048)) {
+ 		printf("knet_link_set_ping_timers failed to set values\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 1d136aea..f42cacb9 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -624,11 +624,21 @@ retry_pong:
+ 				  "Incoming pong packet from host: %u link: %u has higher latency than pong_timeout. Discarding",
+ 				  src_host->host_id, src_link->link_id);
+ 		} else {
++
++			/*
++			 * in words : ('previous mean' * '(count -1)') + 'new value') / 'count'
++			 */
++
++			src_link->latency_cur_samples++;
++
++			/*
++			 * limit to max_samples (precision)
++			 */
++			if (src_link->latency_cur_samples >= src_link->latency_max_samples) {
++				src_link->latency_cur_samples = src_link->latency_max_samples;
++			}
+ 			src_link->status.latency =
+-				((src_link->status.latency * src_link->latency_exp) +
+-				((latency_last / 1000llu) *
+-					(src_link->latency_fix - src_link->latency_exp))) /
+-						src_link->latency_fix;
++				(((src_link->status.latency * (src_link->latency_cur_samples - 1)) + (latency_last / 1000llu)) / src_link->latency_cur_samples);
+ 
+ 			if (src_link->status.latency < src_link->pong_timeout_adj) {
+ 				if (!src_link->status.connected) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0342-rx-unify-latency-values-to-a-capped-value-to-link-pr.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0342-rx-unify-latency-values-to-a-capped-value-to-link-pr.patch
new file mode 100644
index 000000000..124847073
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0342-rx-unify-latency-values-to-a-capped-value-to-link-pr.patch
@@ -0,0 +1,36 @@ 
+From d85e69fccc1e05e4ef79370640cce029bd158325 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 30 Jan 2020 15:23:39 +0100
+Subject: [PATCH] [rx] unify latency values to a capped value to link precision
+
+keep the patch simple to avoid API/ABI breakage for now for easy backporting
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index f42cacb9..fe73aff6 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -660,10 +660,15 @@ retry_pong:
+ 			if (src_link->status.latency < src_link->status.stats.latency_min) {
+ 				src_link->status.stats.latency_min = src_link->status.latency;
+ 			}
+-			src_link->status.stats.latency_ave =
+-				(src_link->status.stats.latency_ave * src_link->status.stats.latency_samples +
+-				 src_link->status.latency) / (src_link->status.stats.latency_samples+1);
+-			src_link->status.stats.latency_samples++;
++
++			/*
++			 * those 2 lines below make all latency average calculations consistent and capped to
++			 * link precision. In future we will kill the one above to keep only this one in
++			 * the stats structure, but for now we leave it around to avoid API/ABI
++			 * breakage as we backport the fixes to stable
++			 */
++			src_link->status.stats.latency_ave = src_link->status.latency;
++			src_link->status.stats.latency_samples = src_link->latency_cur_samples;
+ 		}
+ 		break;
+ 	case KNET_HEADER_TYPE_PMTUD:
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0343-rx-send-reply-packets-only-when-transport-is-connect.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0343-rx-send-reply-packets-only-when-transport-is-connect.patch
new file mode 100644
index 000000000..d9dcc0719
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0343-rx-send-reply-packets-only-when-transport-is-connect.patch
@@ -0,0 +1,138 @@ 
+From ff3b8e7decef502f3e2e531e2f8b5d6b9233bcce Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 31 Jan 2020 06:28:56 +0100
+Subject: [PATCH] [rx] send reply packets only when transport is connected
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 108 ++++++++++++++++++++++---------------------
+ 1 file changed, 56 insertions(+), 52 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index fe73aff6..b3ca357e 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -581,34 +581,36 @@ retry:
+ 		}
+ 
+ retry_pong:
+-		if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+-			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+-				     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
+-		} else {
+-			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+-		}
+-		savederrno = errno;
+-		if (len != outlen) {
+-			err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
+-			switch(err) {
+-				case -1: /* unrecoverable error */
+-					log_debug(knet_h, KNET_SUB_RX,
+-						  "Unable to send pong reply (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
+-						  src_link->outsock, errno, strerror(errno),
+-						  src_link->status.src_ipaddr, src_link->status.src_port,
+-						  src_link->status.dst_ipaddr, src_link->status.dst_port);
+-					src_link->status.stats.tx_pong_errors++;
+-					break;
+-				case 0: /* ignore error and continue */
+-					break;
+-				case 1: /* retry to send those same data */
+-					src_link->status.stats.tx_pong_retries++;
+-					goto retry_pong;
+-					break;
++		if (src_link->transport_connected) {
++			if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
++					     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
++			} else {
++				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++			}
++			savederrno = errno;
++			if (len != outlen) {
++				err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
++				switch(err) {
++					case -1: /* unrecoverable error */
++						log_debug(knet_h, KNET_SUB_RX,
++							  "Unable to send pong reply (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
++							  src_link->outsock, errno, strerror(errno),
++							  src_link->status.src_ipaddr, src_link->status.src_port,
++							  src_link->status.dst_ipaddr, src_link->status.dst_port);
++						src_link->status.stats.tx_pong_errors++;
++						break;
++					case 0: /* ignore error and continue */
++						break;
++					case 1: /* retry to send those same data */
++						src_link->status.stats.tx_pong_retries++;
++						goto retry_pong;
++						break;
++				}
+ 			}
++			src_link->status.stats.tx_pong_packets++;
++			src_link->status.stats.tx_pong_bytes += outlen;
+ 		}
+-		src_link->status.stats.tx_pong_packets++;
+-		src_link->status.stats.tx_pong_bytes += outlen;
+ 		break;
+ 	case KNET_HEADER_TYPE_PONG:
+ 		src_link->status.stats.rx_pong_packets++;
+@@ -697,32 +699,34 @@ retry_pong:
+ 			goto out_pmtud;
+ 		}
+ retry_pmtud:
+-		if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+-			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+-				     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
+-		} else {
+-			len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+-		}
+-		savederrno = errno;
+-		if (len != outlen) {
+-			err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
+-			switch(err) {
+-				case -1: /* unrecoverable error */
+-					log_debug(knet_h, KNET_SUB_RX,
+-						  "Unable to send PMTUd reply (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
+-						  src_link->outsock, errno, strerror(errno),
+-						  src_link->status.src_ipaddr, src_link->status.src_port,
+-						  src_link->status.dst_ipaddr, src_link->status.dst_port);
+-
+-					src_link->status.stats.tx_pmtu_errors++;
+-					break;
+-				case 0: /* ignore error and continue */
+-					src_link->status.stats.tx_pmtu_errors++;
+-					break;
+-				case 1: /* retry to send those same data */
+-					src_link->status.stats.tx_pmtu_retries++;
+-					goto retry_pmtud;
+-					break;
++		if (src_link->transport_connected) {
++			if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
++					     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
++			} else {
++				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++			}
++			savederrno = errno;
++			if (len != outlen) {
++				err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
++				switch(err) {
++					case -1: /* unrecoverable error */
++						log_debug(knet_h, KNET_SUB_RX,
++							  "Unable to send PMTUd reply (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
++							  src_link->outsock, errno, strerror(errno),
++							  src_link->status.src_ipaddr, src_link->status.src_port,
++							  src_link->status.dst_ipaddr, src_link->status.dst_port);
++
++						src_link->status.stats.tx_pmtu_errors++;
++						break;
++					case 0: /* ignore error and continue */
++						src_link->status.stats.tx_pmtu_errors++;
++						break;
++					case 1: /* retry to send those same data */
++						src_link->status.stats.tx_pmtu_retries++;
++						goto retry_pmtud;
++						break;
++				}
+ 			}
+ 		}
+ 		pthread_mutex_unlock(&knet_h->tx_mutex);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0344-rx-Don-t-return-512-EOF-messages-from-_recvmmsg.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0344-rx-Don-t-return-512-EOF-messages-from-_recvmmsg.patch
new file mode 100644
index 000000000..bb111ceb0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0344-rx-Don-t-return-512-EOF-messages-from-_recvmmsg.patch
@@ -0,0 +1,62 @@ 
+From cee181d0834c1cd3e88e9f1442327d5c6fe0c758 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 16 Jan 2020 09:18:19 +0000
+Subject: [PATCH] [rx] Don't return 512 EOF messages from _recvmmsg
+
+If recvmsg() returns 0 for EOF then it's going to do so
+until the error is rectified or read with getsockopt(). But
+the _recvmmsg() wrapper keeps reading until the vector is full
+thus returning a block of 512 EOF messages all of which the caller
+has to plough through.
+
+This patch causes _recvmmsg() to return as soon as it has got
+the first EOF so the the caller can deal with it in good time
+and not spin looking at the same thing over and over again.
+
+I've also fixed a couple of typos in related comments
+---
+ libknet/transport_common.c | 6 ++++++
+ libknet/transport_sctp.c   | 6 +++---
+ 2 files changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 72866438..edd66497 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -41,6 +41,12 @@ int _recvmmsg(int sockfd, struct knet_mmsghdr *msgvec, unsigned int vlen, unsign
+ 		savederrno = errno;
+ 		if (err >= 0) {
+ 			msgvec[i].msg_len = err;
++			if (err == 0) {
++				/* No point in reading anything more until we know this has been dealt with
++				   or we'll just get a vector full of them. Several in fact */
++				i++;
++				break;
++			}
+ 		} else {
+ 			if ((i > 0) &&
+ 			    ((errno == EAGAIN) || (errno == EWOULDBLOCK))) {
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index a5b9ccfe..c5732ddc 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -345,16 +345,16 @@ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+  *       because scheduling can make it so that this thread will overload
+  *       and the threads supposed to take care of the error will never
+  *       be able to take action.
+- *       we CANNOT handle FDs here diretly (close/reconnect/etc) due
++ *       we CANNOT handle FDs here directly (close/reconnect/etc) due
+  *       to locking context. We need to delegate that to their respective
+- *       management threads within global write lock.
++ *       management threads within the global write lock.
+  *
+  * this function is called from:
+  * - RX thread with recv_err <= 0 directly on recvmmsg error
+  * - transport_rx_is_data when msg_len == 0 (recv_err = 1)
+  * - transport_rx_is_data on notification (recv_err = 2)
+  *
+- * basically this small abouse of recv_err is to detect notifications
++ * basically this small abuse of recv_err is to detect notifications
+  * generated by sockets created by listen().
+  */
+ int sctp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0345-tx-Don-t-Clear-out-msghdr-for-all-transports.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0345-tx-Don-t-Clear-out-msghdr-for-all-transports.patch
new file mode 100644
index 000000000..ec1996139
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0345-tx-Don-t-Clear-out-msghdr-for-all-transports.patch
@@ -0,0 +1,42 @@ 
+From c047f89ec326c5a35a11e96742fe47e495563c40 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Wed, 22 Jan 2020 15:15:49 +0000
+Subject: [PATCH] [tx] Don't Clear out msghdr for all transports.
+
+When sending a message to multiple links, if one of those links
+is not connection-oriented then msg_name & msg_namelen would be cleared,
+thus breaking the send to any subsequent non-connection-oriented links.
+
+So now, if we need to clear out msg_name & msg_namelen, we take a copy of the
+msghdr and edit that instead,
+---
+ libknet/transport_common.c | 12 +++++++++---
+ 1 file changed, 9 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index edd66497..1e4b0958 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -64,13 +64,19 @@ int _sendmmsg(int sockfd, int connection_oriented, struct knet_mmsghdr *msgvec,
+ {
+ 	int savederrno = 0, err = 0;
+ 	unsigned int i;
++	struct msghdr temp_msg;
++	struct msghdr *use_msghdr;
+ 
+ 	for (i = 0; i < vlen; i++) {
+ 		if (connection_oriented == TRANSPORT_PROTO_IS_CONNECTION_ORIENTED) {
+-			msgvec[i].msg_hdr.msg_name = NULL;
+-			msgvec[i].msg_hdr.msg_namelen = 0;
++			memcpy(&temp_msg, &msgvec[i].msg_hdr, sizeof(struct msghdr));
++			temp_msg.msg_name = NULL;
++			temp_msg.msg_namelen = 0;
++			use_msghdr = &temp_msg;
++		} else {
++			use_msghdr = &msgvec[i].msg_hdr;
+ 		}
+-		err = sendmsg(sockfd, &msgvec[i].msg_hdr, flags);
++		err = sendmsg(sockfd, use_msghdr, flags);
+ 		savederrno = errno;
+ 		if (err < 0) {
+ 			break;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0346-rx-use-defines-to-determine-RX-data-types-vs-random-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0346-rx-use-defines-to-determine-RX-data-types-vs-random-.patch
new file mode 100644
index 000000000..02e9d23cd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0346-rx-use-defines-to-determine-RX-data-types-vs-random-.patch
@@ -0,0 +1,97 @@ 
+From 4d6ce3f80ca18d2f2ecc1b5a9e83062fcdeb68d9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 24 Jan 2020 05:08:26 +0100
+Subject: [PATCH] [rx] use defines to determine RX data types vs random numbers
+
+also extend a bit to make ready for SCTP extra return codes
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c    | 15 +++++++++++----
+ libknet/transport_udp.c |  5 +++--
+ libknet/transports.h    |  7 +++++++
+ 3 files changed, 21 insertions(+), 6 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index b3ca357e..009be3b9 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -818,18 +818,18 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 		 */
+ 
+ 		switch(err) {
+-			case -1: /* on error */
++			case KNET_TRANSPORT_RX_ERROR: /* on error */
+ 				log_debug(knet_h, KNET_SUB_RX, "Transport reported error parsing packet");
+ 				goto exit_unlock;
+ 				break;
+-			case 0: /* packet is not data and we should continue the packet process loop */
++			case KNET_TRANSPORT_RX_NOT_DATA_CONTINUE: /* packet is not data and we should continue the packet process loop */
+ 				log_debug(knet_h, KNET_SUB_RX, "Transport reported no data, continue");
+ 				break;
+-			case 1: /* packet is not data and we should STOP the packet process loop */
++			case KNET_TRANSPORT_RX_NOT_DATA_STOP: /* packet is not data and we should STOP the packet process loop */
+ 				log_debug(knet_h, KNET_SUB_RX, "Transport reported no data, stop");
+ 				goto exit_unlock;
+ 				break;
+-			case 2: /* packet is data and should be parsed as such */
++			case KNET_TRANSPORT_RX_IS_DATA: /* packet is data and should be parsed as such */
+ 				/*
+ 				 * processing incoming packets vs access lists
+ 				 */
+@@ -857,6 +857,13 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 				}
+ 				_parse_recv_from_links(knet_h, sockfd, &msg[i]);
+ 				break;
++			case KNET_TRANSPORT_RX_OOB_DATA_CONTINUE:
++				log_debug(knet_h, KNET_SUB_RX, "Transport is processing sock OOB data, continue");
++				break;
++			case KNET_TRANSPORT_RX_OOB_DATA_STOP:
++				log_debug(knet_h, KNET_SUB_RX, "Transport has completed processing sock OOB data, stop");
++				goto exit_unlock;
++				break;
+ 		}
+ 	}
+ 
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 3f7ca047..cdb2b654 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -29,6 +29,7 @@
+ #include "common.h"
+ #include "transport_common.h"
+ #include "transport_udp.h"
++#include "transports.h"
+ #include "threads_common.h"
+ 
+ typedef struct udp_handle_info {
+@@ -421,9 +422,9 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int udp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg)
+ {
+ 	if (msg->msg_len == 0)
+-		return 0;
++		return KNET_TRANSPORT_RX_NOT_DATA_CONTINUE;
+ 
+-	return 2;
++	return KNET_TRANSPORT_RX_IS_DATA;
+ }
+ 
+ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link)
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 3a29ce61..90ac9cd4 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -9,6 +9,13 @@
+ #ifndef __KNET_TRANSPORTS_H__
+ #define __KNET_TRANSPORTS_H__
+ 
++#define KNET_TRANSPORT_RX_ERROR -1
++#define KNET_TRANSPORT_RX_NOT_DATA_CONTINUE 0
++#define KNET_TRANSPORT_RX_NOT_DATA_STOP 1
++#define KNET_TRANSPORT_RX_IS_DATA 2
++#define KNET_TRANSPORT_RX_OOB_DATA_CONTINUE 3
++#define KNET_TRANSPORT_RX_OOB_DATA_STOP 4
++
+ int start_all_transports(knet_handle_t knet_h);
+ void stop_all_transports(knet_handle_t knet_h);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0347-sctp-major-surgery-to-use-only-SCTP-events-to-determ.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0347-sctp-major-surgery-to-use-only-SCTP-events-to-determ.patch
new file mode 100644
index 000000000..c66adb9fb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0347-sctp-major-surgery-to-use-only-SCTP-events-to-determ.patch
@@ -0,0 +1,547 @@ 
+From cac4f6cf5649e3fe7851d44498d9dd49f2bdadb3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 30 Jan 2020 12:36:18 +0100
+Subject: [PATCH] [sctp] major surgery to use only SCTP events to determine
+ socket status
+
+- drop concept of on_connected_epoll to determine if socket is ready or not
+- provide much better debugging output at all levels
+- incorporate fix from Xin Long <lxin@redhat.com> to gather socket status
+  at the right time
+- deal with a recent kernel change on SCTP socket that broke knet (from rhel7):
+  [net] sctp: allow delivering notifications after receiving SHUTDOWN
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ README                   |   4 +
+ libknet/transport_sctp.c | 279 +++++++++++++++++----------------------
+ 2 files changed, 128 insertions(+), 155 deletions(-)
+
+diff --git a/README b/README
+index f8f3ea6f..d83125a2 100644
+--- a/README
++++ b/README
+@@ -33,4 +33,8 @@ knet requires big socket buffers and you need to set:
+ kern.ipc.maxsockbuf=18388608
+ in /etc/sysctl.conf or knet will fail to run.
+ 
++currently, knet requires also:
++net.inet.sctp.blackhole=1
++in /etc/sysctl.conf or knet will fail to work with SCTP.
++
+ libnozzle requires if_tap.ko loaded in the kernel.
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index c5732ddc..a34d524a 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -25,6 +25,7 @@
+ #include "logging.h"
+ #include "common.h"
+ #include "transport_common.h"
++#include "transports.h"
+ #include "threads_common.h"
+ 
+ #ifdef HAVE_NETINET_SCTP_H
+@@ -64,6 +65,7 @@ typedef struct sctp_listen_link_info {
+ 	struct sockaddr_storage src_address;
+ 	int on_listener_epoll;
+ 	int on_rx_epoll;
++	int sock_shutdown;
+ } sctp_listen_link_info_t;
+ 
+ typedef struct sctp_accepted_link_info {
+@@ -78,9 +80,9 @@ typedef struct sctp_connect_link_info {
+ 	struct knet_link *link;
+ 	struct sockaddr_storage dst_address;
+ 	int connect_sock;
+-	int on_connected_epoll;
+ 	int on_rx_epoll;
+ 	int close_sock;
++	int sock_shutdown;
+ } sctp_connect_link_info_t;
+ 
+ /*
+@@ -97,37 +99,36 @@ typedef struct sctp_connect_link_info {
+ static int _close_connect_socket(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+ 	int err = 0, savederrno = 0;
+-	sctp_connect_link_info_t *info = kn_link->transport_link;
+-	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	struct epoll_event ev;
++	sctp_connect_link_info_t *info = kn_link->transport_link;
+ 
+-	if (info->on_connected_epoll) {
+-		memset(&ev, 0, sizeof(struct epoll_event));
+-		ev.events = EPOLLOUT;
+-		ev.data.fd = info->connect_sock;
+-		if (epoll_ctl(handle_info->connect_epollfd, EPOLL_CTL_DEL, info->connect_sock, &ev)) {
+-			savederrno = errno;
+-			err = -1;
+-			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove connected socket from the epoll pool: %s",
+-				strerror(errno));
+-			goto exit_error;
++	if (info->connect_sock != -1) {
++		if (info->on_rx_epoll) {
++			memset(&ev, 0, sizeof(struct epoll_event));
++			ev.events = EPOLLIN;
++			ev.data.fd = info->connect_sock;
++			if (epoll_ctl(knet_h->recv_from_links_epollfd, EPOLL_CTL_DEL, info->connect_sock, &ev)) {
++				savederrno = errno;
++				err = -1;
++				log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove connected socket from epoll pool: %s",
++				strerror(savederrno));
++				goto exit_error;
++			}
++			info->on_rx_epoll = 0;
+ 		}
+-		info->on_connected_epoll = 0;
+-	}
+ 
+-exit_error:
+-	if (info->connect_sock != -1) {
+ 		if (_set_fd_tracker(knet_h, info->connect_sock, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0) {
+ 			savederrno = errno;
+ 			err = -1;
+ 			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+ 				strerror(savederrno));
+-			goto exit_error;
++		} else {
++			close(info->connect_sock);
++			info->connect_sock = -1;
+ 		}
+-		close(info->connect_sock);
+-		info->connect_sock = -1;
+ 	}
+ 
++exit_error:
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -191,34 +192,17 @@ static int _reconnect_socket(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+ 	int err = 0, savederrno = 0;
+ 	sctp_connect_link_info_t *info = kn_link->transport_link;
+-	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+-	struct epoll_event ev;
+ 
+ 	if (connect(info->connect_sock, (struct sockaddr *)&kn_link->dst_addr, sockaddr_len(&kn_link->dst_addr)) < 0) {
+-		if ((errno != EALREADY) && (errno != EINPROGRESS) && (errno != EISCONN)) {
+-			savederrno = errno;
++		savederrno = errno;
++		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP socket %d received error: %s", info->connect_sock, strerror(savederrno));
++		if ((savederrno != EALREADY) && (savederrno != EINPROGRESS) && (savederrno != EISCONN)) {
+ 			err = -1;
+ 			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to connect SCTP socket %d: %s",
+ 				info->connect_sock, strerror(savederrno));
+-			goto exit_error;
+ 		}
+ 	}
+ 
+-	if (!info->on_connected_epoll) {
+-		memset(&ev, 0, sizeof(struct epoll_event));
+-		ev.events = EPOLLOUT;
+-		ev.data.fd = info->connect_sock;
+-		if (epoll_ctl(handle_info->connect_epollfd, EPOLL_CTL_ADD, info->connect_sock, &ev)) {
+-			savederrno = errno;
+-			err = -1;
+-			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to add send/recv to epoll pool: %s",
+-				strerror(savederrno));
+-			goto exit_error;
+-		}
+-		info->on_connected_epoll = 1;
+-	}
+-
+-exit_error:
+ 	errno = savederrno;
+ 	return err;
+ }
+@@ -226,9 +210,8 @@ exit_error:
+ static int _create_connect_socket(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+ 	int err = 0, savederrno = 0;
+-	sctp_connect_link_info_t *info = kn_link->transport_link;
+-	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	struct epoll_event ev;
++	sctp_connect_link_info_t *info = kn_link->transport_link;
+ 	int connect_sock;
+ 
+ 	connect_sock = socket(kn_link->dst_addr.ss_family, SOCK_STREAM, IPPROTO_SCTP);
+@@ -254,8 +237,19 @@ static int _create_connect_socket(knet_handle_t knet_h, struct knet_link *kn_lin
+ 		goto exit_error;
+ 	}
+ 
++	memset(&ev, 0, sizeof(struct epoll_event));
++	ev.events = EPOLLIN;
++	ev.data.fd = connect_sock;
++	if (epoll_ctl(knet_h->recv_from_links_epollfd, EPOLL_CTL_ADD, connect_sock, &ev)) {
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to add connected socket to epoll pool: %s",
++			strerror(errno));
++	}
++	info->on_rx_epoll = 1;
++
+ 	info->connect_sock = connect_sock;
+ 	info->close_sock = 0;
++	kn_link->outsock = info->connect_sock;
++
+ 	if (_reconnect_socket(knet_h, kn_link) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+@@ -264,9 +258,6 @@ static int _create_connect_socket(knet_handle_t knet_h, struct knet_link *kn_lin
+ 
+ exit_error:
+ 	if (err) {
+-		if (info->on_connected_epoll) {
+-			epoll_ctl(handle_info->connect_epollfd, EPOLL_CTL_DEL, connect_sock, &ev);
+-		}
+ 		if (connect_sock >= 0) {
+ 			close(connect_sock);
+ 		}
+@@ -360,7 +351,6 @@ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int sctp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno)
+ {
+ 	struct epoll_event ev;
+-	sctp_connect_link_info_t *connect_info = knet_h->knet_transport_fd_tracker[sockfd].data;
+ 	sctp_accepted_link_info_t *accepted_info = knet_h->knet_transport_fd_tracker[sockfd].data;
+ 	sctp_listen_link_info_t *listen_info;
+ 	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+@@ -376,18 +366,6 @@ int sctp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 			 * they follow a notification (double notification)
+ 			 */
+ 			if (recv_err != 1) {
+-				connect_info->link->transport_connected = 0;
+-				if (connect_info->on_rx_epoll) {
+-					memset(&ev, 0, sizeof(struct epoll_event));
+-					ev.events = EPOLLIN;
+-					ev.data.fd = sockfd;
+-					if (epoll_ctl(knet_h->recv_from_links_epollfd, EPOLL_CTL_DEL, sockfd, &ev)) {
+-						log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove EOFed socket from epoll pool: %s",
+-						strerror(errno));
+-						return -1;
+-					}
+-					connect_info->on_rx_epoll = 0;
+-				}
+ 				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Notifying connect thread that sockfd %d received an error", sockfd);
+ 				if (sendto(handle_info->connectsockfd[1], &sockfd, sizeof(int), MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0) != sizeof(int)) {
+ 					log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to notify connect thread: %s", strerror(errno));
+@@ -446,24 +424,34 @@ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsg
+ 	size_t iovlen = msg->msg_hdr.msg_iovlen;
+ 	struct sctp_assoc_change *sac;
+ 	union sctp_notification  *snp;
+-	sctp_accepted_link_info_t *info = knet_h->knet_transport_fd_tracker[sockfd].data;
++	sctp_accepted_link_info_t *listen_info = knet_h->knet_transport_fd_tracker[sockfd].data;
++	sctp_connect_link_info_t *connect_info = knet_h->knet_transport_fd_tracker[sockfd].data;
+ 
+ 	if (!(msg->msg_hdr.msg_flags & MSG_NOTIFICATION)) {
+ 		if (msg->msg_len == 0) {
+-			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "received 0 bytes len packet: %d", sockfd);
+ 			/*
+ 			 * NOTE: with event notification enabled, we receive error twice:
+ 			 *       1) from the event notification
+ 			 *       2) followed by a 0 byte msg_len
+ 			 *
+-			 * This is generally not a problem if not for causing extra
+-			 * handling for the same issue. Should we drop notifications
+-			 * and keep the code generic (handle all errors via msg_len = 0)
+-			 * or keep the duplication as safety measure, or drop msg_len = 0
+-			 * handling (what about sockets without events enabled?)
++			 * the event handler should take care to avoid #2 by stopping
++			 * the rx thread from processing more packets than necessary.
+ 			 */
+-			sctp_transport_rx_sock_error(knet_h, sockfd, 1, 0);
+-			return 1;
++			if (knet_h->knet_transport_fd_tracker[sockfd].data_type == SCTP_CONNECT_LINK_INFO) {
++				if (connect_info->sock_shutdown) {
++					return KNET_TRANSPORT_RX_OOB_DATA_CONTINUE;
++				}
++			} else {
++				if (listen_info->link_info->sock_shutdown) {
++					return KNET_TRANSPORT_RX_OOB_DATA_CONTINUE;
++				}
++			}
++			/*
++			 * this is pretty much dead code and we should never hit it.
++			 * keep it for safety and avoid the rx thread to process
++			 * bad info / data.
++			 */
++			return KNET_TRANSPORT_RX_NOT_DATA_STOP;
+ 		}
+ 		/*
+ 		 * missing MSG_EOR has to be treated as a short read
+@@ -475,9 +463,9 @@ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsg
+ 			 * copy the incoming data into mread_buf + mread_len (incremental)
+ 			 * and increase mread_len
+ 			 */
+-			memmove(info->mread_buf + info->mread_len, iov->iov_base, msg->msg_len);
+-			info->mread_len = info->mread_len + msg->msg_len;
+-			return 0;
++			memmove(listen_info->mread_buf + listen_info->mread_len, iov->iov_base, msg->msg_len);
++			listen_info->mread_len = listen_info->mread_len + msg->msg_len;
++			return KNET_TRANSPORT_RX_NOT_DATA_CONTINUE;
+ 		}
+ 		/*
+ 		 * got EOR.
+@@ -485,57 +473,88 @@ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsg
+ 		 * complete reassembling the packet in mread_buf, copy it back in the iov
+ 		 * and set the iov/msg len numbers (size) correctly
+ 		 */
+-		if (info->mread_len) {
++		if (listen_info->mread_len) {
+ 			/*
+ 			 * add last fragment to mread_buf
+ 			 */
+-			memmove(info->mread_buf + info->mread_len, iov->iov_base, msg->msg_len);
+-			info->mread_len = info->mread_len + msg->msg_len;
++			memmove(listen_info->mread_buf + listen_info->mread_len, iov->iov_base, msg->msg_len);
++			listen_info->mread_len = listen_info->mread_len + msg->msg_len;
+ 			/*
+ 			 * move all back into the iovec
+ 			 */
+-			memmove(iov->iov_base, info->mread_buf, info->mread_len);
+-			msg->msg_len = info->mread_len;
+-			info->mread_len = 0;
++			memmove(iov->iov_base, listen_info->mread_buf, listen_info->mread_len);
++			msg->msg_len = listen_info->mread_len;
++			listen_info->mread_len = 0;
+ 		}
+-		return 2;
++		return KNET_TRANSPORT_RX_IS_DATA;
+ 	}
+ 
+ 	if (!(msg->msg_hdr.msg_flags & MSG_EOR)) {
+-		return 1;
++		return KNET_TRANSPORT_RX_NOT_DATA_STOP;
+ 	}
+ 
+-	for (i=0; i< iovlen; i++) {
++	for (i = 0; i < iovlen; i++) {
+ 		snp = iov[i].iov_base;
+ 
+ 		switch (snp->sn_header.sn_type) {
+ 			case SCTP_ASSOC_CHANGE:
+-				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change");
+ 				sac = &snp->sn_assoc_change;
+-				if (sac->sac_state == SCTP_COMM_LOST) {
+-					log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change: comm_lost");
+-					sctp_transport_rx_sock_error(knet_h, sockfd, 2, 0);
++				switch (sac->sac_state) {
++					case SCTP_COMM_LOST:
++						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: comm_lost", sockfd);
++						sctp_transport_rx_sock_error(knet_h, sockfd, 2, 0);
++						return KNET_TRANSPORT_RX_OOB_DATA_STOP;
++						break;
++					case SCTP_COMM_UP:
++						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: comm_up", sockfd);
++						if (knet_h->knet_transport_fd_tracker[sockfd].data_type == SCTP_CONNECT_LINK_INFO) {
++							connect_info->link->transport_connected = 1;
++						}
++						break;
++					case SCTP_RESTART:
++						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: restart", sockfd);
++						break;
++					case SCTP_SHUTDOWN_COMP:
++						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: shutdown comp", sockfd);
++						if (knet_h->knet_transport_fd_tracker[sockfd].data_type == SCTP_CONNECT_LINK_INFO) {
++							connect_info->close_sock = 1;
++						}
++						sctp_transport_rx_sock_error(knet_h, sockfd, 2, 0);
++						return KNET_TRANSPORT_RX_OOB_DATA_STOP;
++						break;
++					case SCTP_CANT_STR_ASSOC:
++						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: cant str assoc", sockfd);
++						sctp_transport_rx_sock_error(knet_h, sockfd, 2, 0);
++						break;
++					default:
++						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: unknown %d", sockfd, sac->sac_state);
++						break;
+ 				}
+ 				break;
+ 			case SCTP_SHUTDOWN_EVENT:
+-				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp shutdown event");
+-				sctp_transport_rx_sock_error(knet_h, sockfd, 2, 0);
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp shutdown event socket %d", sockfd);
++				if (knet_h->knet_transport_fd_tracker[sockfd].data_type == SCTP_CONNECT_LINK_INFO) {
++					connect_info->link->transport_connected = 0;
++					connect_info->sock_shutdown = 1;
++				} else {
++					listen_info->link_info->sock_shutdown = 1;
++				}
+ 				break;
+ 			case SCTP_SEND_FAILED:
+-				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp send failed");
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp send failed socket: %d", sockfd);
+ 				break;
+ 			case SCTP_PEER_ADDR_CHANGE:
+-				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp peer addr change");
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp peer addr change socket %d", sockfd);
+ 				break;
+ 			case SCTP_REMOTE_ERROR:
+-				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp remote error");
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp remote error socket %d", sockfd);
+ 				break;
+ 			default:
+-				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] unknown sctp event type: %hu\n", snp->sn_header.sn_type);
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] unknown sctp event socket: %d type: %hu", sockfd, snp->sn_header.sn_type);
+ 				break;
+ 		}
+ 	}
+-	return 0;
++	return KNET_TRANSPORT_RX_OOB_DATA_CONTINUE;
+ }
+ 
+ /*
+@@ -546,25 +565,16 @@ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsg
+  * _handle_connected_sctp* are called with a global write lock
+  * from the connect_thread
+  */
+-static void _handle_connected_sctp(knet_handle_t knet_h, int connect_sock)
++static void _handle_connected_sctp_socket(knet_handle_t knet_h, int connect_sock)
+ {
+ 	int err;
+-	struct epoll_event ev;
+ 	unsigned int status, len = sizeof(status);
+-	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+ 	sctp_connect_link_info_t *info = knet_h->knet_transport_fd_tracker[connect_sock].data;
+ 	struct knet_link *kn_link = info->link;
+ 
+-	err = getsockopt(connect_sock, SOL_SOCKET, SO_ERROR, &status, &len);
+-	if (err) {
+-		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP getsockopt() on connecting socket %d failed: %s",
+-			connect_sock, strerror(errno));
+-		return;
+-	}
+-
+ 	if (info->close_sock) {
+ 		if (_close_connect_socket(knet_h, kn_link) < 0) {
+-			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to close sock %d from _handle_connected_sctp: %s", connect_sock, strerror(errno));
++			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to close sock %d from _handle_connected_sctp_socket: %s", connect_sock, strerror(errno));
+ 			return;
+ 		}
+ 		info->close_sock = 0;
+@@ -574,6 +584,15 @@ static void _handle_connected_sctp(knet_handle_t knet_h, int connect_sock)
+ 		}
+ 	}
+ 
++	_reconnect_socket(knet_h, info->link);
++
++	err = getsockopt(connect_sock, SOL_SOCKET, SO_ERROR, &status, &len);
++	if (err) {
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP getsockopt() on connecting socket %d failed: %s",
++			connect_sock, strerror(errno));
++		return;
++	}
++
+ 	if (status) {
+ 		log_info(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP connect on %d to %s port %s failed: %s",
+ 			 connect_sock, kn_link->status.dst_ipaddr, kn_link->status.dst_port,
+@@ -583,44 +602,18 @@ static void _handle_connected_sctp(knet_handle_t knet_h, int connect_sock)
+ 		 * No need to create a new socket if connect failed,
+ 		 * just retry connect
+ 		 */
+-		_reconnect_socket(knet_h, info->link);
+ 		return;
+ 	}
+ 
+-	/*
+-	 * Connected - Remove us from the connect epoll
+-	 */
+-	memset(&ev, 0, sizeof(struct epoll_event));
+-	ev.events = EPOLLOUT;
+-	ev.data.fd = connect_sock;
+-	if (epoll_ctl(handle_info->connect_epollfd, EPOLL_CTL_DEL, connect_sock, &ev)) {
+-		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove connected socket %d from epoll pool: %s",
+-			connect_sock, strerror(errno));
+-	}
+-	info->on_connected_epoll = 0;
+-
+-	kn_link->transport_connected = 1;
+-	kn_link->outsock = info->connect_sock;
+-
+-	memset(&ev, 0, sizeof(struct epoll_event));
+-	ev.events = EPOLLIN;
+-	ev.data.fd = connect_sock;
+-	if (epoll_ctl(knet_h->recv_from_links_epollfd, EPOLL_CTL_ADD, connect_sock, &ev)) {
+-		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to add connected socket to epoll pool: %s",
+-			strerror(errno));
+-	}
+-	info->on_rx_epoll = 1;
+-
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "SCTP handler fd %d now connected to %s port %s",
+ 		  connect_sock,
+ 		  kn_link->status.dst_ipaddr, kn_link->status.dst_port);
+ }
+ 
+-static void _handle_connected_sctp_errors(knet_handle_t knet_h)
++static void _handle_connected_sctp_notifications(knet_handle_t knet_h)
+ {
+ 	int sockfd = -1;
+ 	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
+-	sctp_connect_link_info_t *info;
+ 
+ 	if (recv(handle_info->connectsockfd[0], &sockfd, sizeof(int), MSG_DONTWAIT | MSG_NOSIGNAL) != sizeof(int)) {
+ 		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Short read on connectsockfd");
+@@ -641,11 +634,7 @@ static void _handle_connected_sctp_errors(knet_handle_t knet_h)
+ 
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Processing connected error on socket: %d", sockfd);
+ 
+-	info = knet_h->knet_transport_fd_tracker[sockfd].data;
+-
+-	info->close_sock = 1;
+-	info->link->transport_connected = 0;
+-	_reconnect_socket(knet_h, info->link);
++	_handle_connected_sctp_socket(knet_h, sockfd);
+ }
+ 
+ static void *_sctp_connect_thread(void *data)
+@@ -695,13 +684,9 @@ static void *_sctp_connect_thread(void *data)
+ 		for (i = 0; i < nev; i++) {
+ 			if (events[i].data.fd == handle_info->connectsockfd[0]) {
+ 				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Received notification from rx_error for connected socket");
+-				_handle_connected_sctp_errors(knet_h);
++				_handle_connected_sctp_notifications(knet_h);
+ 			} else {
+-				if (_is_valid_fd(knet_h, events[i].data.fd) == 1) {
+-					_handle_connected_sctp(knet_h, events[i].data.fd);
+-				} else {
+-					log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Received stray notification for dead fd %d\n", events[i].data.fd);
+-				}
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Received stray notification on connected sockfd %d\n", events[i].data.fd);
+ 			}
+ 		}
+ 		pthread_rwlock_unlock(&knet_h->global_rwlock);
+@@ -1204,7 +1189,6 @@ int sctp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_li
+ 	info->link = kn_link;
+ 
+ 	memmove(&info->dst_address, &kn_link->dst_addr, sizeof(struct sockaddr_storage));
+-	info->on_connected_epoll = 0;
+ 	info->connect_sock = -1;
+ 
+ 	info->listener = sctp_link_listener_start(knet_h, kn_link);
+@@ -1249,7 +1233,6 @@ int sctp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_
+ {
+ 	int err = 0, savederrno = 0;
+ 	sctp_connect_link_info_t *info;
+-	struct epoll_event ev;
+ 
+ 	if (!kn_link) {
+ 		errno = EINVAL;
+@@ -1271,20 +1254,6 @@ int sctp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_
+ 		goto exit_error;
+ 	}
+ 
+-	if (info->on_rx_epoll) {
+-		memset(&ev, 0, sizeof(struct epoll_event));
+-		ev.events = EPOLLIN;
+-		ev.data.fd = info->connect_sock;
+-		if (epoll_ctl(knet_h->recv_from_links_epollfd, EPOLL_CTL_DEL, info->connect_sock, &ev)) {
+-			savederrno = errno;
+-			err = -1;
+-			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove connected socket from epoll pool: %s",
+-			strerror(savederrno));
+-			goto exit_error;
+-		}
+-		info->on_rx_epoll = 0;
+-	}
+-
+ 	if (_close_connect_socket(knet_h, kn_link) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0348-global-Update-copyright-across-the-board.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0348-global-Update-copyright-across-the-board.patch
new file mode 100644
index 000000000..edb61d5e6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0348-global-Update-copyright-across-the-board.patch
@@ -0,0 +1,2587 @@ 
+From ac01e270bbf813255d7112c20d0169b1473bfc5d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 31 Jan 2020 09:55:02 +0100
+Subject: [PATCH] [global] Update copyright across the board
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ COPYRIGHT                                                     | 2 +-
+ Makefile.am                                                   | 2 +-
+ README                                                        | 2 +-
+ autogen.sh                                                    | 2 +-
+ build-aux/check.mk                                            | 2 +-
+ build-aux/git-version-gen                                     | 2 +-
+ build-aux/release.mk                                          | 2 +-
+ configure.ac                                                  | 2 +-
+ init/Makefile.am                                              | 2 +-
+ init/kronosnetd.default                                       | 2 +-
+ init/kronosnetd.in                                            | 2 +-
+ init/kronosnetd.service.in                                    | 2 +-
+ kronosnet.spec.in                                             | 2 +-
+ kronosnetd/Makefile.am                                        | 2 +-
+ kronosnetd/cfg.c                                              | 2 +-
+ kronosnetd/cfg.h                                              | 2 +-
+ kronosnetd/etherfilter.c                                      | 2 +-
+ kronosnetd/etherfilter.h                                      | 2 +-
+ kronosnetd/keygen.c                                           | 2 +-
+ kronosnetd/kronosnetd.logrotate.in                            | 2 +-
+ kronosnetd/logging.c                                          | 2 +-
+ kronosnetd/logging.h                                          | 2 +-
+ kronosnetd/main.c                                             | 2 +-
+ kronosnetd/vty.c                                              | 2 +-
+ kronosnetd/vty.h                                              | 2 +-
+ kronosnetd/vty_auth.c                                         | 2 +-
+ kronosnetd/vty_auth.h                                         | 2 +-
+ kronosnetd/vty_cli.c                                          | 2 +-
+ kronosnetd/vty_cli.h                                          | 2 +-
+ kronosnetd/vty_cli_cmds.c                                     | 2 +-
+ kronosnetd/vty_cli_cmds.h                                     | 2 +-
+ kronosnetd/vty_utils.c                                        | 2 +-
+ kronosnetd/vty_utils.h                                        | 2 +-
+ libknet/Makefile.am                                           | 2 +-
+ libknet/common.c                                              | 2 +-
+ libknet/common.h                                              | 2 +-
+ libknet/compat.c                                              | 2 +-
+ libknet/compat.h                                              | 2 +-
+ libknet/compress.c                                            | 2 +-
+ libknet/compress.h                                            | 2 +-
+ libknet/compress_bzip2.c                                      | 2 +-
+ libknet/compress_lz4.c                                        | 2 +-
+ libknet/compress_lz4hc.c                                      | 2 +-
+ libknet/compress_lzma.c                                       | 2 +-
+ libknet/compress_lzo2.c                                       | 2 +-
+ libknet/compress_model.h                                      | 2 +-
+ libknet/compress_zlib.c                                       | 2 +-
+ libknet/compress_zstd.c                                       | 2 +-
+ libknet/crypto.c                                              | 2 +-
+ libknet/crypto.h                                              | 2 +-
+ libknet/crypto_model.h                                        | 2 +-
+ libknet/crypto_nss.c                                          | 2 +-
+ libknet/crypto_openssl.c                                      | 2 +-
+ libknet/handle.c                                              | 2 +-
+ libknet/host.c                                                | 2 +-
+ libknet/host.h                                                | 2 +-
+ libknet/internals.h                                           | 2 +-
+ libknet/libknet.h                                             | 4 ++--
+ libknet/libknet.pc.in                                         | 2 +-
+ libknet/libknet_exported_syms                                 | 2 +-
+ libknet/links.c                                               | 2 +-
+ libknet/links.h                                               | 2 +-
+ libknet/links_acl.c                                           | 2 +-
+ libknet/links_acl.h                                           | 2 +-
+ libknet/links_acl_ip.c                                        | 2 +-
+ libknet/links_acl_ip.h                                        | 2 +-
+ libknet/links_acl_loopback.c                                  | 2 +-
+ libknet/links_acl_loopback.h                                  | 2 +-
+ libknet/logging.c                                             | 2 +-
+ libknet/logging.h                                             | 2 +-
+ libknet/netutils.c                                            | 2 +-
+ libknet/netutils.h                                            | 2 +-
+ libknet/onwire.c                                              | 2 +-
+ libknet/onwire.h                                              | 2 +-
+ libknet/tests/Makefile.am                                     | 2 +-
+ libknet/tests/api-check.mk                                    | 2 +-
+ libknet/tests/api-test-coverage                               | 2 +-
+ libknet/tests/api_knet_addrtostr.c                            | 2 +-
+ libknet/tests/api_knet_get_compress_list.c                    | 2 +-
+ libknet/tests/api_knet_get_crypto_list.c                      | 2 +-
+ libknet/tests/api_knet_get_transport_id_by_name.c             | 2 +-
+ libknet/tests/api_knet_get_transport_list.c                   | 2 +-
+ libknet/tests/api_knet_get_transport_name_by_id.c             | 2 +-
+ libknet/tests/api_knet_handle_add_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_clear_stats.c                   | 2 +-
+ libknet/tests/api_knet_handle_compress.c                      | 2 +-
+ libknet/tests/api_knet_handle_crypto.c                        | 2 +-
+ libknet/tests/api_knet_handle_enable_access_lists.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_filter.c                 | 2 +-
+ libknet/tests/api_knet_handle_enable_pmtud_notify.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_sock_notify.c            | 2 +-
+ libknet/tests/api_knet_handle_free.c                          | 2 +-
+ libknet/tests/api_knet_handle_get_channel.c                   | 2 +-
+ libknet/tests/api_knet_handle_get_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_get_stats.c                     | 2 +-
+ .../tests/api_knet_handle_get_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_new.c                           | 2 +-
+ libknet/tests/api_knet_handle_new_limit.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_get.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_getfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_pmtud_set.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_setfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_remove_datafd.c                 | 2 +-
+ .../tests/api_knet_handle_set_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_setfwd.c                        | 2 +-
+ libknet/tests/api_knet_host_add.c                             | 2 +-
+ libknet/tests/api_knet_host_enable_status_change_notify.c     | 2 +-
+ libknet/tests/api_knet_host_get_host_list.c                   | 2 +-
+ libknet/tests/api_knet_host_get_id_by_host_name.c             | 2 +-
+ libknet/tests/api_knet_host_get_name_by_host_id.c             | 2 +-
+ libknet/tests/api_knet_host_get_policy.c                      | 2 +-
+ libknet/tests/api_knet_host_get_status.c                      | 2 +-
+ libknet/tests/api_knet_host_remove.c                          | 2 +-
+ libknet/tests/api_knet_host_set_name.c                        | 2 +-
+ libknet/tests/api_knet_host_set_policy.c                      | 2 +-
+ libknet/tests/api_knet_link_add_acl.c                         | 2 +-
+ libknet/tests/api_knet_link_clear_acl.c                       | 2 +-
+ libknet/tests/api_knet_link_clear_config.c                    | 2 +-
+ libknet/tests/api_knet_link_get_config.c                      | 2 +-
+ libknet/tests/api_knet_link_get_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_get_link_list.c                   | 2 +-
+ libknet/tests/api_knet_link_get_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_get_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_get_priority.c                    | 2 +-
+ libknet/tests/api_knet_link_get_status.c                      | 2 +-
+ libknet/tests/api_knet_link_insert_acl.c                      | 2 +-
+ libknet/tests/api_knet_link_rm_acl.c                          | 2 +-
+ libknet/tests/api_knet_link_set_config.c                      | 2 +-
+ libknet/tests/api_knet_link_set_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_set_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_set_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_set_priority.c                    | 2 +-
+ libknet/tests/api_knet_log_get_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_id.c                  | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_name.c                | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_id.c                 | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_name.c               | 2 +-
+ libknet/tests/api_knet_log_set_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_recv.c                                 | 2 +-
+ libknet/tests/api_knet_send.c                                 | 2 +-
+ libknet/tests/api_knet_send_compress.c                        | 2 +-
+ libknet/tests/api_knet_send_crypto.c                          | 2 +-
+ libknet/tests/api_knet_send_loopback.c                        | 2 +-
+ libknet/tests/api_knet_send_sync.c                            | 2 +-
+ libknet/tests/api_knet_strtoaddr.c                            | 2 +-
+ libknet/tests/fun_pmtud_crypto.c                              | 2 +-
+ libknet/tests/int_links_acl_ip.c                              | 2 +-
+ libknet/tests/int_timediff.c                                  | 2 +-
+ libknet/tests/knet_bench.c                                    | 2 +-
+ libknet/tests/pckt_test.c                                     | 2 +-
+ libknet/tests/test-common.c                                   | 2 +-
+ libknet/tests/test-common.h                                   | 2 +-
+ libknet/threads_common.c                                      | 2 +-
+ libknet/threads_common.h                                      | 2 +-
+ libknet/threads_dsthandler.c                                  | 2 +-
+ libknet/threads_dsthandler.h                                  | 2 +-
+ libknet/threads_heartbeat.c                                   | 2 +-
+ libknet/threads_heartbeat.h                                   | 2 +-
+ libknet/threads_pmtud.c                                       | 2 +-
+ libknet/threads_pmtud.h                                       | 2 +-
+ libknet/threads_rx.c                                          | 2 +-
+ libknet/threads_rx.h                                          | 2 +-
+ libknet/threads_tx.c                                          | 2 +-
+ libknet/threads_tx.h                                          | 2 +-
+ libknet/transport_common.c                                    | 2 +-
+ libknet/transport_common.h                                    | 2 +-
+ libknet/transport_loopback.c                                  | 2 +-
+ libknet/transport_loopback.h                                  | 2 +-
+ libknet/transport_sctp.c                                      | 2 +-
+ libknet/transport_sctp.h                                      | 2 +-
+ libknet/transport_udp.c                                       | 2 +-
+ libknet/transport_udp.h                                       | 2 +-
+ libknet/transports.c                                          | 2 +-
+ libknet/transports.h                                          | 2 +-
+ libnozzle/Makefile.am                                         | 2 +-
+ libnozzle/internals.c                                         | 2 +-
+ libnozzle/internals.h                                         | 2 +-
+ libnozzle/libnozzle.c                                         | 2 +-
+ libnozzle/libnozzle.h                                         | 4 ++--
+ libnozzle/libnozzle.pc.in                                     | 2 +-
+ libnozzle/libnozzle_exported_syms                             | 2 +-
+ libnozzle/tests/Makefile.am                                   | 2 +-
+ libnozzle/tests/api-test-coverage                             | 2 +-
+ libnozzle/tests/api_nozzle_add_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_close.c                            | 2 +-
+ libnozzle/tests/api_nozzle_del_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_fd.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_handle_by_name.c               | 2 +-
+ libnozzle/tests/api_nozzle_get_ips.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_name_by_handle.c               | 2 +-
+ libnozzle/tests/api_nozzle_open.c                             | 2 +-
+ libnozzle/tests/api_nozzle_run_updown.c                       | 2 +-
+ libnozzle/tests/api_nozzle_set_down.c                         | 2 +-
+ libnozzle/tests/api_nozzle_set_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_up.c                           | 2 +-
+ libnozzle/tests/int_execute_bin_sh_command.c                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_false                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_true                   | 2 +-
+ libnozzle/tests/test-common.c                                 | 2 +-
+ libnozzle/tests/test-common.h                                 | 2 +-
+ man/Doxyfile-knet.in                                          | 2 +-
+ man/Doxyfile-nozzle.in                                        | 2 +-
+ man/Makefile.am                                               | 2 +-
+ man/api-to-man-page-coverage                                  | 2 +-
+ man/knet-keygen.8                                             | 2 +-
+ man/kronosnetd.8                                              | 2 +-
+ poc-code/Makefile.am                                          | 2 +-
+ poc-code/iov-hash/Makefile.am                                 | 2 +-
+ poc-code/iov-hash/main.c                                      | 2 +-
+ 212 files changed, 214 insertions(+), 214 deletions(-)
+
+diff --git a/COPYRIGHT b/COPYRIGHT
+index da386c75..a6834ee2 100644
+--- a/COPYRIGHT
++++ b/COPYRIGHT
+@@ -1,4 +1,4 @@
+-Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ 
+ Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+          Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/Makefile.am b/Makefile.am
+index b7d0205a..23f76a6c 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/README b/README
+index d83125a2..edbbbbcc 100644
+--- a/README
++++ b/README
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/autogen.sh b/autogen.sh
+index 92e9483b..073beddc 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index f372968b..890bf903 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index cb0b2894..e1a07790 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -2,7 +2,7 @@
+ # Print a version string.
+ scriptversion=2018-08-31.20; # UTC
+ 
+-# Copyright (C) 2012-2019 Red Hat, Inc.
++# Copyright (C) 2012-2020 Red Hat, Inc.
+ # Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ #
+ # This program is free software: you can redistribute it and/or modify
+diff --git a/build-aux/release.mk b/build-aux/release.mk
+index 003125d2..52db79e0 100644
+--- a/build-aux/release.mk
++++ b/build-aux/release.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/configure.ac b/configure.ac
+index 74d75e08..3534c0f1 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/init/Makefile.am b/init/Makefile.am
+index fe0d9b0b..4581ee14 100644
+--- a/init/Makefile.am
++++ b/init/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/init/kronosnetd.default b/init/kronosnetd.default
+index 9f6755c4..a29b829f 100644
+--- a/init/kronosnetd.default
++++ b/init/kronosnetd.default
+@@ -1,6 +1,6 @@
+ # kronosnetd startup options (see man kronosnetd.8)
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/init/kronosnetd.in b/init/kronosnetd.in
+index 1da32733..d1a58909 100644
+--- a/init/kronosnetd.in
++++ b/init/kronosnetd.in
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/init/kronosnetd.service.in b/init/kronosnetd.service.in
+index cfc80f79..04507c51 100644
+--- a/init/kronosnetd.service.in
++++ b/init/kronosnetd.service.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 094090b0..28b0ea20 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -1,7 +1,7 @@
+ ###############################################################################
+ ###############################################################################
+ ##
+-##  Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++##  Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ ##
+ ##  This copyrighted material is made available to anyone wishing to use,
+ ##  modify, copy, or redistribute it subject to the terms and conditions
+diff --git a/kronosnetd/Makefile.am b/kronosnetd/Makefile.am
+index 5ce8fa5e..041d1f8c 100644
+--- a/kronosnetd/Makefile.am
++++ b/kronosnetd/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/kronosnetd/cfg.c b/kronosnetd/cfg.c
+index 406532a8..19ffce50 100644
+--- a/kronosnetd/cfg.c
++++ b/kronosnetd/cfg.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/cfg.h b/kronosnetd/cfg.h
+index 56fa4d50..e3a2acdb 100644
+--- a/kronosnetd/cfg.h
++++ b/kronosnetd/cfg.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/etherfilter.c b/kronosnetd/etherfilter.c
+index 5f0d9fb4..dbea73cc 100644
+--- a/kronosnetd/etherfilter.c
++++ b/kronosnetd/etherfilter.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/etherfilter.h b/kronosnetd/etherfilter.h
+index 63e18b6c..9c733dd4 100644
+--- a/kronosnetd/etherfilter.h
++++ b/kronosnetd/etherfilter.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/keygen.c b/kronosnetd/keygen.c
+index 42706ad5..41251cff 100644
+--- a/kronosnetd/keygen.c
++++ b/kronosnetd/keygen.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/kronosnetd.logrotate.in b/kronosnetd/kronosnetd.logrotate.in
+index a8a6969b..e78034cc 100644
+--- a/kronosnetd/kronosnetd.logrotate.in
++++ b/kronosnetd/kronosnetd.logrotate.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/kronosnetd/logging.c b/kronosnetd/logging.c
+index 9c141cd8..ee30dd17 100644
+--- a/kronosnetd/logging.c
++++ b/kronosnetd/logging.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/logging.h b/kronosnetd/logging.h
+index 1bc12b93..a32d7277 100644
+--- a/kronosnetd/logging.h
++++ b/kronosnetd/logging.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/main.c b/kronosnetd/main.c
+index ec43871b..86a530ff 100644
+--- a/kronosnetd/main.c
++++ b/kronosnetd/main.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty.c b/kronosnetd/vty.c
+index 2c5d4d30..4e54a1fa 100644
+--- a/kronosnetd/vty.c
++++ b/kronosnetd/vty.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty.h b/kronosnetd/vty.h
+index 3c3e6e04..79d33cfa 100644
+--- a/kronosnetd/vty.h
++++ b/kronosnetd/vty.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty_auth.c b/kronosnetd/vty_auth.c
+index 30e0929d..d599c377 100644
+--- a/kronosnetd/vty_auth.c
++++ b/kronosnetd/vty_auth.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_auth.h b/kronosnetd/vty_auth.h
+index 58d75cbf..c03c5a60 100644
+--- a/kronosnetd/vty_auth.h
++++ b/kronosnetd/vty_auth.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_cli.c b/kronosnetd/vty_cli.c
+index 95e4c8f4..bc971f63 100644
+--- a/kronosnetd/vty_cli.c
++++ b/kronosnetd/vty_cli.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty_cli.h b/kronosnetd/vty_cli.h
+index 0d7e515f..fb0adecb 100644
+--- a/kronosnetd/vty_cli.h
++++ b/kronosnetd/vty_cli.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_cli_cmds.c b/kronosnetd/vty_cli_cmds.c
+index e5ad4965..de68e99d 100644
+--- a/kronosnetd/vty_cli_cmds.c
++++ b/kronosnetd/vty_cli_cmds.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnetd/vty_cli_cmds.h b/kronosnetd/vty_cli_cmds.h
+index ba40ddf0..89ab0ede 100644
+--- a/kronosnetd/vty_cli_cmds.h
++++ b/kronosnetd/vty_cli_cmds.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_utils.c b/kronosnetd/vty_utils.c
+index 2cf51176..33b30e4a 100644
+--- a/kronosnetd/vty_utils.c
++++ b/kronosnetd/vty_utils.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/kronosnetd/vty_utils.h b/kronosnetd/vty_utils.h
+index 7ac318a2..14e7370a 100644
+--- a/kronosnetd/vty_utils.h
++++ b/kronosnetd/vty_utils.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 4bc48754..f9ba25db 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/common.c b/libknet/common.c
+index ed8ac899..3cfd5042 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/common.h b/libknet/common.h
+index 6128b160..129be4c1 100644
+--- a/libknet/common.h
++++ b/libknet/common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/compat.c b/libknet/compat.c
+index 2e73c9fc..c31e85d7 100644
+--- a/libknet/compat.c
++++ b/libknet/compat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compat.h b/libknet/compat.h
+index 903fdfb3..c2e0453d 100644
+--- a/libknet/compat.h
++++ b/libknet/compat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 20645a96..f62861d6 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress.h b/libknet/compress.h
+index d43a9d5f..95464e82 100644
+--- a/libknet/compress.h
++++ b/libknet/compress.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c
+index 68f5280c..70362157 100644
+--- a/libknet/compress_bzip2.c
++++ b/libknet/compress_bzip2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c
+index db0fa514..2a3a07d6 100644
+--- a/libknet/compress_lz4.c
++++ b/libknet/compress_lz4.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c
+index 963ad66c..607ec47e 100644
+--- a/libknet/compress_lz4hc.c
++++ b/libknet/compress_lz4hc.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
+index b4fd05c3..ab9aa206 100644
+--- a/libknet/compress_lzma.c
++++ b/libknet/compress_lzma.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c
+index 72dac824..bb109517 100644
+--- a/libknet/compress_lzo2.c
++++ b/libknet/compress_lzo2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_model.h b/libknet/compress_model.h
+index 57cf8115..6a4ee6f9 100644
+--- a/libknet/compress_model.h
++++ b/libknet/compress_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c
+index fa6ae011..5bb6003f 100644
+--- a/libknet/compress_zlib.c
++++ b/libknet/compress_zlib.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index e460d273..e64ff042 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 2c4d5f5c..8f0aa8f3 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index f80cb43e..cc476d14 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index b05e49c8..06e10a0d 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index c624a479..bf4cdc1a 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 6df4a331..fe3684a4 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 2c7d312f..e86f0ab5 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.c b/libknet/host.c
+index d919dff4..cf351798 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.h b/libknet/host.h
+index 307b6e77..bd2e8a70 100644
+--- a/libknet/host.h
++++ b/libknet/host.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 00216241..63926204 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 6a94a78c..d2e00a28 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+@@ -19,7 +19,7 @@
+ /**
+  * @file libknet.h
+  * @brief kronosnet API include file
+- * @copyright Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Kronosnet is an advanced VPN system for High Availability applications.
+  */
+diff --git a/libknet/libknet.pc.in b/libknet/libknet.pc.in
+index 021b2c44..e9960560 100644
+--- a/libknet/libknet.pc.in
++++ b/libknet/libknet.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Federico Simoncelli <fsimon@kronosnet.org>
+ #
+diff --git a/libknet/libknet_exported_syms b/libknet/libknet_exported_syms
+index 1d8bddbb..f2254b05 100644
+--- a/libknet/libknet_exported_syms
++++ b/libknet/libknet_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libknet.so
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/links.c b/libknet/links.c
+index 2b5dca3f..2a0597d4 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links.h b/libknet/links.h
+index c8ca6109..66890a84 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index eb77e7be..a24ea978 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 4617c9b2..6f4f0263 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 4692afa5..b77eaf43 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index f566c1e9..6d22daaa 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index 0a0adec7..10092489 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index d10764cf..78cc6bf8 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 378eef59..c01886dc 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/logging.h b/libknet/logging.h
+index 01dcaf14..2ee0da46 100644
+--- a/libknet/logging.h
++++ b/libknet/logging.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index e37f4fe8..754e1984 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index b293115e..e668ada6 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/onwire.c b/libknet/onwire.c
+index e3fd293b..146baa19 100644
+--- a/libknet/onwire.c
++++ b/libknet/onwire.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index 74d4d091..e00ad915 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 91607809..37f5935f 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 2ae2b30b..75a51507 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-test-coverage b/libknet/tests/api-test-coverage
+index e988ab17..2fa0edbd 100755
+--- a/libknet/tests/api-test-coverage
++++ b/libknet/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index 9cdf5021..f7031082 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/api_knet_get_compress_list.c b/libknet/tests/api_knet_get_compress_list.c
+index 53e4192d..3db7ad9f 100644
+--- a/libknet/tests/api_knet_get_compress_list.c
++++ b/libknet/tests/api_knet_get_compress_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_crypto_list.c b/libknet/tests/api_knet_get_crypto_list.c
+index 760adab5..600fee69 100644
+--- a/libknet/tests/api_knet_get_crypto_list.c
++++ b/libknet/tests/api_knet_get_crypto_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_id_by_name.c b/libknet/tests/api_knet_get_transport_id_by_name.c
+index 9bcd673e..e30f7f8e 100644
+--- a/libknet/tests/api_knet_get_transport_id_by_name.c
++++ b/libknet/tests/api_knet_get_transport_id_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_list.c b/libknet/tests/api_knet_get_transport_list.c
+index 9ab5c103..bdb57bc2 100644
+--- a/libknet/tests/api_knet_get_transport_list.c
++++ b/libknet/tests/api_knet_get_transport_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_name_by_id.c b/libknet/tests/api_knet_get_transport_name_by_id.c
+index 3233a1d8..ff6e325c 100644
+--- a/libknet/tests/api_knet_get_transport_name_by_id.c
++++ b/libknet/tests/api_knet_get_transport_name_by_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_add_datafd.c b/libknet/tests/api_knet_handle_add_datafd.c
+index 30887976..bf8d0d50 100644
+--- a/libknet/tests/api_knet_handle_add_datafd.c
++++ b/libknet/tests/api_knet_handle_add_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index 0867b13c..346f72e0 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 509bdf6c..3dbd1dd8 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index 1eed96e7..1fa962df 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_access_lists.c b/libknet/tests/api_knet_handle_enable_access_lists.c
+index be54bc44..d80a2e25 100644
+--- a/libknet/tests/api_knet_handle_enable_access_lists.c
++++ b/libknet/tests/api_knet_handle_enable_access_lists.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_filter.c b/libknet/tests/api_knet_handle_enable_filter.c
+index e518b426..bc0a479a 100644
+--- a/libknet/tests/api_knet_handle_enable_filter.c
++++ b/libknet/tests/api_knet_handle_enable_filter.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_pmtud_notify.c b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+index f11abc38..828df6fa 100644
+--- a/libknet/tests/api_knet_handle_enable_pmtud_notify.c
++++ b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_sock_notify.c b/libknet/tests/api_knet_handle_enable_sock_notify.c
+index adefb5a2..eb71b018 100644
+--- a/libknet/tests/api_knet_handle_enable_sock_notify.c
++++ b/libknet/tests/api_knet_handle_enable_sock_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_free.c b/libknet/tests/api_knet_handle_free.c
+index 53b6dc62..7344ea29 100644
+--- a/libknet/tests/api_knet_handle_free.c
++++ b/libknet/tests/api_knet_handle_free.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_channel.c b/libknet/tests/api_knet_handle_get_channel.c
+index 0196136f..3cab4a84 100644
+--- a/libknet/tests/api_knet_handle_get_channel.c
++++ b/libknet/tests/api_knet_handle_get_channel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_datafd.c b/libknet/tests/api_knet_handle_get_datafd.c
+index 57aedf59..a2fd6954 100644
+--- a/libknet/tests/api_knet_handle_get_datafd.c
++++ b/libknet/tests/api_knet_handle_get_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_stats.c b/libknet/tests/api_knet_handle_get_stats.c
+index 38a0c971..38d3f081 100644
+--- a/libknet/tests/api_knet_handle_get_stats.c
++++ b/libknet/tests/api_knet_handle_get_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+index f013a5bf..7bd773c0 100644
+--- a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_new.c b/libknet/tests/api_knet_handle_new.c
+index 9559d4a3..eac7b6f3 100644
+--- a/libknet/tests/api_knet_handle_new.c
++++ b/libknet/tests/api_knet_handle_new.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_new_limit.c b/libknet/tests/api_knet_handle_new_limit.c
+index fc3bdcda..840a6a6f 100644
+--- a/libknet/tests/api_knet_handle_new_limit.c
++++ b/libknet/tests/api_knet_handle_new_limit.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_get.c b/libknet/tests/api_knet_handle_pmtud_get.c
+index 803a2888..0e54f12b 100644
+--- a/libknet/tests/api_knet_handle_pmtud_get.c
++++ b/libknet/tests/api_knet_handle_pmtud_get.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_getfreq.c b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+index 23e32393..64ea6e1a 100644
+--- a/libknet/tests/api_knet_handle_pmtud_getfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+index 15b1ddde..2631e44c 100644
+--- a/libknet/tests/api_knet_handle_pmtud_set.c
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_setfreq.c b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+index 2a720c30..7023215a 100644
+--- a/libknet/tests/api_knet_handle_pmtud_setfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_remove_datafd.c b/libknet/tests/api_knet_handle_remove_datafd.c
+index ace5df7f..a7b81376 100644
+--- a/libknet/tests/api_knet_handle_remove_datafd.c
++++ b/libknet/tests/api_knet_handle_remove_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+index c5615598..3b929bb2 100644
+--- a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_setfwd.c b/libknet/tests/api_knet_handle_setfwd.c
+index 21a5c9fd..2408b97b 100644
+--- a/libknet/tests/api_knet_handle_setfwd.c
++++ b/libknet/tests/api_knet_handle_setfwd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_add.c b/libknet/tests/api_knet_host_add.c
+index 65104f59..e6d66603 100644
+--- a/libknet/tests/api_knet_host_add.c
++++ b/libknet/tests/api_knet_host_add.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_enable_status_change_notify.c b/libknet/tests/api_knet_host_enable_status_change_notify.c
+index b0467a5b..6a81bb9e 100644
+--- a/libknet/tests/api_knet_host_enable_status_change_notify.c
++++ b/libknet/tests/api_knet_host_enable_status_change_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_host_list.c b/libknet/tests/api_knet_host_get_host_list.c
+index fc573bbe..3a5988e4 100644
+--- a/libknet/tests/api_knet_host_get_host_list.c
++++ b/libknet/tests/api_knet_host_get_host_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_id_by_host_name.c b/libknet/tests/api_knet_host_get_id_by_host_name.c
+index 745dbfa7..c3920510 100644
+--- a/libknet/tests/api_knet_host_get_id_by_host_name.c
++++ b/libknet/tests/api_knet_host_get_id_by_host_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_name_by_host_id.c b/libknet/tests/api_knet_host_get_name_by_host_id.c
+index 46045251..81d39836 100644
+--- a/libknet/tests/api_knet_host_get_name_by_host_id.c
++++ b/libknet/tests/api_knet_host_get_name_by_host_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_policy.c b/libknet/tests/api_knet_host_get_policy.c
+index 8511815e..1fc025d4 100644
+--- a/libknet/tests/api_knet_host_get_policy.c
++++ b/libknet/tests/api_knet_host_get_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_status.c b/libknet/tests/api_knet_host_get_status.c
+index 3b46f0c6..65dca278 100644
+--- a/libknet/tests/api_knet_host_get_status.c
++++ b/libknet/tests/api_knet_host_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_remove.c b/libknet/tests/api_knet_host_remove.c
+index 36dd47c8..8fe989a2 100644
+--- a/libknet/tests/api_knet_host_remove.c
++++ b/libknet/tests/api_knet_host_remove.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_set_name.c b/libknet/tests/api_knet_host_set_name.c
+index c899d339..c9261465 100644
+--- a/libknet/tests/api_knet_host_set_name.c
++++ b/libknet/tests/api_knet_host_set_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_set_policy.c b/libknet/tests/api_knet_host_set_policy.c
+index 25831149..17780001 100644
+--- a/libknet/tests/api_knet_host_set_policy.c
++++ b/libknet/tests/api_knet_host_set_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index 52d6022c..87ff624f 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index 3516b4d2..64dfd7b8 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_clear_config.c b/libknet/tests/api_knet_link_clear_config.c
+index ff9c4739..4523f1f7 100644
+--- a/libknet/tests/api_knet_link_clear_config.c
++++ b/libknet/tests/api_knet_link_clear_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_config.c b/libknet/tests/api_knet_link_get_config.c
+index 60a56fd6..2b1ad5ea 100644
+--- a/libknet/tests/api_knet_link_get_config.c
++++ b/libknet/tests/api_knet_link_get_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_enable.c b/libknet/tests/api_knet_link_get_enable.c
+index b0e13489..b437cf8c 100644
+--- a/libknet/tests/api_knet_link_get_enable.c
++++ b/libknet/tests/api_knet_link_get_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_link_list.c b/libknet/tests/api_knet_link_get_link_list.c
+index 6114f839..386ae525 100644
+--- a/libknet/tests/api_knet_link_get_link_list.c
++++ b/libknet/tests/api_knet_link_get_link_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_ping_timers.c b/libknet/tests/api_knet_link_get_ping_timers.c
+index 414619f0..e684b2e2 100644
+--- a/libknet/tests/api_knet_link_get_ping_timers.c
++++ b/libknet/tests/api_knet_link_get_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_pong_count.c b/libknet/tests/api_knet_link_get_pong_count.c
+index e032b963..77e587b6 100644
+--- a/libknet/tests/api_knet_link_get_pong_count.c
++++ b/libknet/tests/api_knet_link_get_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_priority.c b/libknet/tests/api_knet_link_get_priority.c
+index 80538fea..1ecb04c2 100644
+--- a/libknet/tests/api_knet_link_get_priority.c
++++ b/libknet/tests/api_knet_link_get_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_status.c b/libknet/tests/api_knet_link_get_status.c
+index 5139692c..1362efeb 100644
+--- a/libknet/tests/api_knet_link_get_status.c
++++ b/libknet/tests/api_knet_link_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index 2f55c16f..08d507ef 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index 7217a4f5..75af8283 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index c43a4de7..c3085403 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_enable.c b/libknet/tests/api_knet_link_set_enable.c
+index fc233ea3..b62acb35 100644
+--- a/libknet/tests/api_knet_link_set_enable.c
++++ b/libknet/tests/api_knet_link_set_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_ping_timers.c b/libknet/tests/api_knet_link_set_ping_timers.c
+index bc4d142e..ea5879e1 100644
+--- a/libknet/tests/api_knet_link_set_ping_timers.c
++++ b/libknet/tests/api_knet_link_set_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_pong_count.c b/libknet/tests/api_knet_link_set_pong_count.c
+index b8974e3a..151b6df4 100644
+--- a/libknet/tests/api_knet_link_set_pong_count.c
++++ b/libknet/tests/api_knet_link_set_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_priority.c b/libknet/tests/api_knet_link_set_priority.c
+index aac0ea20..003a900e 100644
+--- a/libknet/tests/api_knet_link_set_priority.c
++++ b/libknet/tests/api_knet_link_set_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel.c b/libknet/tests/api_knet_log_get_loglevel.c
+index 4d4a52cb..09db26ab 100644
+--- a/libknet/tests/api_knet_log_get_loglevel.c
++++ b/libknet/tests/api_knet_log_get_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_id.c b/libknet/tests/api_knet_log_get_loglevel_id.c
+index 379ba717..31d82f24 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_id.c
++++ b/libknet/tests/api_knet_log_get_loglevel_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_name.c b/libknet/tests/api_knet_log_get_loglevel_name.c
+index ef19af28..3375f214 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_name.c
++++ b/libknet/tests/api_knet_log_get_loglevel_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_id.c b/libknet/tests/api_knet_log_get_subsystem_id.c
+index cff9e8aa..d631300c 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_id.c
++++ b/libknet/tests/api_knet_log_get_subsystem_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_name.c b/libknet/tests/api_knet_log_get_subsystem_name.c
+index 03847305..08165c71 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_name.c
++++ b/libknet/tests/api_knet_log_get_subsystem_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_set_loglevel.c b/libknet/tests/api_knet_log_set_loglevel.c
+index 7a9232a4..f2501c5a 100644
+--- a/libknet/tests/api_knet_log_set_loglevel.c
++++ b/libknet/tests/api_knet_log_set_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_recv.c b/libknet/tests/api_knet_recv.c
+index 99bd7bc0..10419c8f 100644
+--- a/libknet/tests/api_knet_recv.c
++++ b/libknet/tests/api_knet_recv.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 4b01e6f1..8805bc59 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index bbb357a4..d302a4b0 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index 8d740d29..a894e9fa 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 6c0054c2..825d672d 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 007e4f59..240bdf4a 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index a0be1da9..bcdf1cf3 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/fun_pmtud_crypto.c b/libknet/tests/fun_pmtud_crypto.c
+index 91c062c4..9e552fc2 100644
+--- a/libknet/tests/fun_pmtud_crypto.c
++++ b/libknet/tests/fun_pmtud_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+index 829a2351..945b349f 100644
+--- a/libknet/tests/int_links_acl_ip.c
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/tests/int_timediff.c b/libknet/tests/int_timediff.c
+index a878a319..5ec0ac20 100644
+--- a/libknet/tests/int_timediff.c
++++ b/libknet/tests/int_timediff.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index c9e1c062..de68cc8a 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/pckt_test.c b/libknet/tests/pckt_test.c
+index f3e21007..9522c187 100644
+--- a/libknet/tests/pckt_test.c
++++ b/libknet/tests/pckt_test.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 617addca..3461fb7d 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 963c4382..96672e8e 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 479c9c56..029b2c6f 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 9d4daaa0..56a9d759 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 07761079..6e9b2492 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.h b/libknet/threads_dsthandler.h
+index db9117c9..5f43db07 100644
+--- a/libknet/threads_dsthandler.h
++++ b/libknet/threads_dsthandler.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index fa1f30c4..1ed6207c 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.h b/libknet/threads_heartbeat.h
+index b2580d10..11280555 100644
+--- a/libknet/threads_heartbeat.h
++++ b/libknet/threads_heartbeat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index f4d15ae1..dee87bb9 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.h b/libknet/threads_pmtud.h
+index 5ed31555..c2c2c7b7 100644
+--- a/libknet/threads_pmtud.h
++++ b/libknet/threads_pmtud.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 009be3b9..4199b79f 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.h b/libknet/threads_rx.h
+index b88c0982..95113c69 100644
+--- a/libknet/threads_rx.h
++++ b/libknet/threads_rx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 6f06e5d9..f1b74a30 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.h b/libknet/threads_tx.h
+index 28c49585..5f3513f0 100644
+--- a/libknet/threads_tx.h
++++ b/libknet/threads_tx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 1e4b0958..32192430 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 0ca21d05..8360ed9f 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index 17253f54..b36fed20 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index a848ff81..0cb7bb37 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index a34d524a..41a2caa8 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index 0b8f320c..bbf7a789 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index cdb2b654..2b3e4327 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index 1dec8635..8e3ea5f6 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 93119c58..e6457238 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 90ac9cd4..763fce37 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 8ac438ad..63757635 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 53c0cdbd..be943e44 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index c9192a81..6f7ab3af 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 61096096..5e9d6e44 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index ad7c4749..64bf8094 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -16,7 +16,7 @@
+  *
+  * @file libnozzle.h
+  * @brief tap interfaces management API include file
+- * @copyright Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+diff --git a/libnozzle/libnozzle.pc.in b/libnozzle/libnozzle.pc.in
+index 9df09187..910a36a4 100644
+--- a/libnozzle/libnozzle.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/libnozzle_exported_syms b/libnozzle/libnozzle_exported_syms
+index f6f62d21..bb7b36d2 100644
+--- a/libnozzle/libnozzle_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libnozzle.so
+ #
+-# Copyright (C) 2011-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2011-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index cdc42a3b..8da00dd5 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index 4049ad94..eaea7090 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+index a9d76c65..af588c49 100644
+--- a/libnozzle/tests/api_nozzle_add_ip.c
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index 7ba17c44..e7b456b4 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+index 625484f9..85bc3c0e 100644
+--- a/libnozzle/tests/api_nozzle_del_ip.c
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index 5dc5b4c1..b84013ba 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+index 1fa5a0a1..8984ce86 100644
+--- a/libnozzle/tests/api_nozzle_get_handle_by_name.c
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index 446a79ad..f306ccc8 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index f4c72cc9..c835ab65 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 1b1f85ef..1790172f 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index c05e4486..896266ef 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index 413f2c24..be26df46 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index 1536b5b2..d470515f 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index 9466bdb9..2ee9bdcb 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index abb96364..65a89219 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index ce4ccbbe..3e295297 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index d258b6a6..b2f891a3 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index 97422a2d..91a2e01f 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_false b/libnozzle/tests/nozzle_run_updown_exit_false
+index 795456a7..2ef4ee90 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_false
++++ b/libnozzle/tests/nozzle_run_updown_exit_false
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_true b/libnozzle/tests/nozzle_run_updown_exit_true
+index 7b6e3552..8eda37d8 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_true
++++ b/libnozzle/tests/nozzle_run_updown_exit_true
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2010-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index 3afd2ec8..2a9a8a29 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index fcfafefa..dc2ea89f 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/man/Doxyfile-knet.in b/man/Doxyfile-knet.in
+index 4750c9a5..e703d757 100644
+--- a/man/Doxyfile-knet.in
++++ b/man/Doxyfile-knet.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Doxyfile-nozzle.in b/man/Doxyfile-nozzle.in
+index 793d49d4..bcc4f9f7 100644
+--- a/man/Doxyfile-nozzle.in
++++ b/man/Doxyfile-nozzle.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Makefile.am b/man/Makefile.am
+index fda8b216..b4454af5 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+index a1f54a39..76729367 100755
+--- a/man/api-to-man-page-coverage
++++ b/man/api-to-man-page-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/man/knet-keygen.8 b/man/knet-keygen.8
+index 96109c6e..4dca73ad 100644
+--- a/man/knet-keygen.8
++++ b/man/knet-keygen.8
+@@ -1,5 +1,5 @@
+ .\"/*
+-.\" * Copyright (C) 2012-2019 Red Hat, Inc.
++.\" * Copyright (C) 2012-2020 Red Hat, Inc.
+ .\" *
+ .\" * All rights reserved.
+ .\" *
+diff --git a/man/kronosnetd.8 b/man/kronosnetd.8
+index f4480be0..58959904 100644
+--- a/man/kronosnetd.8
++++ b/man/kronosnetd.8
+@@ -1,5 +1,5 @@
+ .\"/*
+-.\" * Copyright (C) 2012-2019 Red Hat, Inc.
++.\" * Copyright (C) 2012-2020 Red Hat, Inc.
+ .\" *
+ .\" * All rights reserved.
+ .\" *
+diff --git a/poc-code/Makefile.am b/poc-code/Makefile.am
+index ddbea085..6c03b49a 100644
+--- a/poc-code/Makefile.am
++++ b/poc-code/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/poc-code/iov-hash/Makefile.am b/poc-code/iov-hash/Makefile.am
+index acd6b51f..ed76e412 100644
+--- a/poc-code/iov-hash/Makefile.am
++++ b/poc-code/iov-hash/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/poc-code/iov-hash/main.c b/poc-code/iov-hash/main.c
+index fa407a26..b3efae34 100644
+--- a/poc-code/iov-hash/main.c
++++ b/poc-code/iov-hash/main.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0349-man-Fix-covscan-reports-in-doxyxml.c.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0349-man-Fix-covscan-reports-in-doxyxml.c.patch
new file mode 100644
index 000000000..2c1882339
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0349-man-Fix-covscan-reports-in-doxyxml.c.patch
@@ -0,0 +1,133 @@ 
+From aff3835ca91f7982529856135e46633a0a74604d Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 5 Aug 2019 12:41:06 +0100
+Subject: [PATCH] man: Fix covscan reports in doxyxml.c
+
+This fixes most of the remaining covscan errors in doxyxml.c.
+The ones that remain are caused by malloced structures being
+stored in qb_hashtable_maps.
+
+These still cause unfreed memory, because the contents of the maps
+are never explictly freed, but as they are used until the very end of
+the program (when the OS will free everything) I'm dubious as to
+whether it's worth doing it in the code - or whether covscan will
+work out what's going on anyway.
+---
+ man/doxyxml.c | 27 +++++++++++++++++----------
+ 1 file changed, 17 insertions(+), 10 deletions(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 2f289767..ae860325 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -175,7 +175,7 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
+ 			if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameternamelist") == 0) {
+ 				paramname = (char*)sub_tag->children->next->children->content;
+ 			}
+-			if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameterdescription") == 0) {
++			if (paramname && sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameterdescription") == 0) {
+ 				paramdesc = (char*)sub_tag->children->next->children->content;
+ 
+ 				/* Add text to the param_map */
+@@ -239,6 +239,7 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 			if (returntext && strcmp(kind, "return") == 0) {
+ 				*returntext = tmp;
+ 			}
++			free(kind);
+ 		}
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "parameterlist") == 0) {
+@@ -249,6 +250,7 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 			if (strcmp(kind, "retval") == 0) {
+ 				get_param_info(this_tag, &retval_list);
+ 			}
++			free(kind);
+ 		}
+ 	}
+ 	return strdup(buffer);
+@@ -421,10 +423,10 @@ char *get_texttree(int *type, xmlNode *cur_node, char **returntext)
+ 	}
+ 
+ 	if (buffer[0]) {
+-		tmp = strdup(buffer);
++		return strdup(buffer);
++	} else {
++		return NULL;
+ 	}
+-
+-	return tmp;
+ }
+ 
+ /* The text output is VERY basic and just a check that it's working really */
+@@ -670,6 +672,7 @@ static void collect_functions(xmlNode *cur_node, void *arg)
+ 				num_functions++;
+ 			}
+ 		}
++		free(kind);
+ 	}
+ }
+ 
+@@ -692,6 +695,7 @@ static void collect_enums(xmlNode *cur_node, void *arg)
+ 			for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 				if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0) {
+ 					name = strdup((char *)this_tag->children->content);
++					break;
+ 				}
+ 			}
+ 
+@@ -704,8 +708,10 @@ static void collect_enums(xmlNode *cur_node, void *arg)
+ 					traverse_node(cur_node, "enumvalue", read_struct, si);
+ 					qb_map_put(structures_map, refid, si);
+ 				}
++				free(name);
+ 			}
+ 		}
++		free(kind);
+ 	}
+ }
+ 
+@@ -732,14 +738,14 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 			if (!this_tag->children || !this_tag->children->content)
+ 				continue;
+ 
+-			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "definition") == 0)
++			if (!def && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "definition") == 0)
+ 				def = strdup((char *)this_tag->children->content);
+-			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "argsstring") == 0)
++			if (!args && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "argsstring") == 0)
+ 				args = strdup((char *)this_tag->children->content);
+-			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0)
++			if (!name && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0)
+ 				name = strdup((char *)this_tag->children->content);
+ 
+-			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "briefdescription") == 0) {
++			if (!brief && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "briefdescription") == 0) {
+ 				brief = get_texttree(&type, this_tag, &returntext);
+ 				if (brief) {
+ 					/*
+@@ -749,7 +755,7 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 					brief[strlen(brief) - 3] = '\0';
+ 				}
+ 			}
+-			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "detaileddescription") == 0) {
++			if (!detailed && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "detaileddescription") == 0) {
+ 				detailed = get_texttree(&type, this_tag, &returntext);
+ 			}
+ 			/* Get all the params */
+@@ -767,7 +773,6 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		}
+ 
+ 		if (kind && strcmp(kind, "function") == 0) {
+-
+ 			/* Make sure function has a doxygen description */
+ 			if (!detailed) {
+ 				fprintf(stderr, "No doxygen description for function '%s' - please fix this\n", name);
+@@ -786,6 +791,8 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		free(kind);
+ 		free(def);
+ 		free(args);
++		free(detailed);
++		free(brief);
+ 		free(name);
+ 	}
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0350-man-Change-strcat-to-strncat.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0350-man-Change-strcat-to-strncat.patch
new file mode 100644
index 000000000..d61e91d67
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0350-man-Change-strcat-to-strncat.patch
@@ -0,0 +1,73 @@ 
+From 3969c46d307089e0b57496d34c0fc0a79fa1f787 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 8 Aug 2019 13:26:54 +0100
+Subject: [PATCH] man: Change strcat to strncat
+
+Oddly, covscan doesn't compain about the use of strcat, but
+I'm going to pre-empt it, just in case it decides to.
+---
+ man/doxyxml.c | 22 +++++++++++-----------
+ 1 file changed, 11 insertions(+), 11 deletions(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index ae860325..343449c4 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -115,12 +115,12 @@ static char *get_child(xmlNode *node, const char *tag)
+ 			refid = NULL;
+ 			for (child = this_node->children; child; child = child->next) {
+ 				if (child->content) {
+-					strcat(buffer, (char *)child->content);
++					strncat(buffer, (char *)child->content, sizeof(buffer)-1);
+ 				}
+ 
+ 				if ((strcmp( (char*)child->name, "ref") == 0)) {
+ 					if (child->children->content) {
+-						strcat(buffer,(char *)child->children->content);
++						strncat(buffer, (char *)child->children->content, sizeof(buffer)-1);
+ 					}
+ 					refid = get_attr(child, "refid");
+ 				}
+@@ -207,24 +207,24 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 		if (this_tag->type == XML_TEXT_NODE && strcmp((char *)this_tag->name, "text") == 0) {
+ 			if (not_all_whitespace((char*)this_tag->content)) {
+-				strcat(buffer, (char*)this_tag->content);
+-				strcat(buffer, "\n");
++				strncat(buffer, (char*)this_tag->content, sizeof(buffer)-1);
++				strncat(buffer, "\n", sizeof(buffer)-1);
+ 			}
+ 		}
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "emphasis") == 0) {
+ 			if (print_man) {
+-				strcat(buffer, "\\fB");
++				strncat(buffer, "\\fB", sizeof(buffer)-1);
+ 			}
+-			strcat(buffer, (char*)this_tag->children->content);
++			strncat(buffer, (char*)this_tag->children->content, sizeof(buffer)-1);
+ 			if (print_man) {
+-				strcat(buffer, "\\fR");
++				strncat(buffer, "\\fR", sizeof(buffer)-1);
+ 			}
+ 		}
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "itemizedlist") == 0) {
+ 			for (sub_tag = this_tag->children; sub_tag; sub_tag = sub_tag->next) {
+ 				if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "listitem") == 0) {
+-					strcat(buffer, (char*)sub_tag->children->children->content);
+-					strcat(buffer, "\n");
++					strncat(buffer, (char*)sub_tag->children->children->content, sizeof(buffer)-1);
++					strncat(buffer, "\n", sizeof(buffer)-1);
+ 				}
+ 			}
+ 		}
+@@ -416,8 +416,8 @@ char *get_texttree(int *type, xmlNode *cur_node, char **returntext)
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "para") == 0) {
+ 			tmp = get_text(this_tag, returntext);
+-			strcat(buffer, tmp);
+-			strcat(buffer, "\n");
++			strncat(buffer, tmp, sizeof(buffer)-1);
++			strncat(buffer, "\n", sizeof(buffer)-1);
+ 			free(tmp);
+ 		}
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0351-man-Enhance-prio-description-of-POLICY_PASSIVE.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0351-man-Enhance-prio-description-of-POLICY_PASSIVE.patch
new file mode 100644
index 000000000..2ef2dd13f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0351-man-Enhance-prio-description-of-POLICY_PASSIVE.patch
@@ -0,0 +1,27 @@ 
+From ab744adafc2a0ec071baff8253bbf8bbfa1fc1a0 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Tue, 25 Feb 2020 15:09:19 +0100
+Subject: [PATCH] [man] Enhance prio description of POLICY_PASSIVE
+
+Some users found description of POLICY_PASSIVE priority confusing
+(probably because "priority" word is too overloaded) so add
+some redundancy to make description unambiguous.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ libknet/libknet.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index d2e00a28..52cc321c 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1099,7 +1099,7 @@ int knet_host_get_host_list(knet_handle_t knet_h,
+  * policy   - there are currently 3 kind of simple switching policies
+  *            based on link configuration.
+  *            KNET_LINK_POLICY_PASSIVE - the active link with the highest
+- *                                       priority will be used.
++ *                                       priority (highest number) will be used.
+  *                                       if one or more active links share
+  *                                       the same priority, the one with
+  *                                       lowest link_id will be used.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0352-transports-use-SO_REUSEADDR-only-for-sctp.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0352-transports-use-SO_REUSEADDR-only-for-sctp.patch
new file mode 100644
index 000000000..596ebc358
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0352-transports-use-SO_REUSEADDR-only-for-sctp.patch
@@ -0,0 +1,51 @@ 
+From 14899106201bcdf61978bb7b4def751e283af122 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 25 Feb 2020 08:18:53 +0100
+Subject: [PATCH] [transports] use SO_REUSEADDR only for sctp
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_common.c | 9 ---------
+ libknet/transport_sctp.c   | 9 +++++++++
+ 2 files changed, 9 insertions(+), 9 deletions(-)
+
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 32192430..00036974 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -349,15 +349,6 @@ int _configure_transport_socket(knet_handle_t knet_h, int sock, struct sockaddr_
+ #endif
+ 	}
+ 
+-	value = 1;
+-	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) < 0) {
+-		savederrno = errno;
+-		err = -1;
+-		log_err(knet_h, KNET_SUB_TRANSPORT, "Unable to set %s reuseaddr: %s",
+-			type, strerror(savederrno));
+-		goto exit_error;
+-	}
+-
+ exit_error:
+ 	errno = savederrno;
+ 	return err;
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 41a2caa8..667d80cf 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -169,6 +169,15 @@ static int _configure_sctp_socket(knet_handle_t knet_h, int sock, struct sockadd
+ 		goto exit_error;
+ 	}
+ 
++	value = 1;
++	if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &value, sizeof(value)) < 0) {
++		savederrno = errno;
++		err = -1;
++		log_err(knet_h, KNET_SUB_TRANSPORT, "Unable to set reuseaddr on socket %d: %s",
++			sock, strerror(savederrno));
++		goto exit_error;
++	}
++
+ 	value = 1;
+ 	if (setsockopt(sock, level, SCTP_NODELAY, &value, sizeof(value)) < 0) {
+ 		savederrno = errno;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0353-tests-rework-test-suite-link-port-allocation.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0353-tests-rework-test-suite-link-port-allocation.patch
new file mode 100644
index 000000000..396ffbd89
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0353-tests-rework-test-suite-link-port-allocation.patch
@@ -0,0 +1,1017 @@ 
+From c294b39539d1e9c7eb0f78e8df7bee530ab3f3c2 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 27 Feb 2020 15:12:30 +0100
+Subject: [PATCH] [tests] rework test suite link port allocation
+
+Logic is to try to configure a link with port X and if it fails, try the next
+port. This avoids port collisions between services and knet test suite.
+
+Please note that the implementation in test-common.c is NOT super clean.
+There is still some redundant code in there that is left on purpose.
+
+There is another branch, not yet merged, that implements functional testing
+framework that does heavy use of those functions.
+
+We will clean test-common.c as we port the functional testing branch and make
+it ready for merging.
+
+For now, this is good enough to have a more stable test suite.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_handle_clear_stats.c   |  7 +-
+ libknet/tests/api_knet_handle_pmtud_set.c     |  7 +-
+ libknet/tests/api_knet_host_remove.c          | 13 +---
+ libknet/tests/api_knet_link_add_acl.c         |  6 +-
+ libknet/tests/api_knet_link_clear_acl.c       |  9 +--
+ libknet/tests/api_knet_link_clear_config.c    | 14 +---
+ libknet/tests/api_knet_link_get_config.c      | 24 ++-----
+ libknet/tests/api_knet_link_get_enable.c      | 14 +---
+ libknet/tests/api_knet_link_get_link_list.c   | 14 +---
+ libknet/tests/api_knet_link_get_ping_timers.c | 14 +---
+ libknet/tests/api_knet_link_get_pong_count.c  | 14 +---
+ libknet/tests/api_knet_link_get_priority.c    | 14 +---
+ libknet/tests/api_knet_link_get_status.c      | 14 +---
+ libknet/tests/api_knet_link_insert_acl.c      |  4 +-
+ libknet/tests/api_knet_link_rm_acl.c          |  4 +-
+ libknet/tests/api_knet_link_set_config.c      | 51 +++++---------
+ libknet/tests/api_knet_send.c                 |  7 +-
+ libknet/tests/api_knet_send_compress.c        |  7 +-
+ libknet/tests/api_knet_send_crypto.c          |  7 +-
+ libknet/tests/api_knet_send_loopback.c        | 16 ++---
+ libknet/tests/api_knet_send_sync.c            |  7 +-
+ libknet/tests/fun_pmtud_crypto.c              |  7 +-
+ libknet/tests/test-common.c                   | 70 ++++++++++++++++---
+ libknet/tests/test-common.h                   | 12 +++-
+ 24 files changed, 133 insertions(+), 223 deletions(-)
+
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index 346f72e0..e87b3c39 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -47,11 +47,6 @@ static void test(void)
+ 	int savederrno;
+ 	struct sockaddr_storage lo;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	printf("Test knet_handle_clear_stats incorrect knet_h\n");
+@@ -94,7 +89,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+index 2631e44c..c0db7af2 100644
+--- a/libknet/tests/api_knet_handle_pmtud_set.c
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -40,11 +40,6 @@ static void test(void)
+ 	int8_t channel = 0;
+ 	struct sockaddr_storage lo;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	printf("Test knet_handle_pmtud_set incorrect knet_h\n");
+ 
+ 	if ((!knet_handle_pmtud_set(NULL, iface_mtu)) || (errno != EINVAL)) {
+@@ -95,7 +90,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_host_remove.c b/libknet/tests/api_knet_host_remove.c
+index 8fe989a2..13be5661 100644
+--- a/libknet/tests/api_knet_host_remove.c
++++ b/libknet/tests/api_knet_host_remove.c
+@@ -25,7 +25,7 @@ static void test(void)
+ 	int logfds[2];
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	size_t host_ids_entries;
+-	struct sockaddr_storage ss;
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_host_add incorrect knet_h\n");
+ 
+@@ -64,16 +64,7 @@ static void test(void)
+ 
+ 	printf("Test knet_host_remove with configured host_id and links\n");
+ 
+-	if (make_local_sockaddr(&ss, 0) < 0) {
+-		printf("Unable to convert str to sockaddr: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &ss, NULL, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index 87ff624f..54b8208b 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -163,7 +163,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_add_acl with point to point link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -173,7 +173,7 @@ static void test(void)
+ 	}
+ 
+ 	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
++		printf("knet_link_add_acl accepted point to point link or returned incorrect error: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -188,7 +188,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_add_acl with dynamic link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index 64dfd7b8..ce11071c 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -29,11 +29,6 @@ static void test(void)
+ 	struct knet_link *link;
+ 	struct sockaddr_storage lo;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	printf("Test knet_link_clear_acl incorrect knet_h\n");
+ 
+ 	if ((!knet_link_clear_acl(NULL, 1, 0)) || (errno != EINVAL)) {
+@@ -93,7 +88,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_clear_acl with point to point link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -118,7 +113,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_clear_acl with dynamic link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_clear_config.c b/libknet/tests/api_knet_link_clear_config.c
+index 4523f1f7..0e98f2af 100644
+--- a/libknet/tests/api_knet_link_clear_config.c
++++ b/libknet/tests/api_knet_link_clear_config.c
+@@ -25,17 +25,7 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_clear_config incorrect knet_h\n");
+ 
+@@ -96,7 +86,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_clear_config with enabled linkid\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_get_config.c b/libknet/tests/api_knet_link_get_config.c
+index 2b1ad5ea..6dc91244 100644
+--- a/libknet/tests/api_knet_link_get_config.c
++++ b/libknet/tests/api_knet_link_get_config.c
+@@ -25,20 +25,10 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst, get_src, get_dst;
++	struct sockaddr_storage lo, get_src, get_dst;
+ 	uint8_t dynamic = 0, transport = 0;
+ 	uint64_t flags;
+ 
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	printf("Test knet_link_get_config incorrect knet_h\n");
+ 
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+@@ -142,7 +132,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_config with incorrect dst_addr\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -202,8 +192,8 @@ static void test(void)
+ 	}
+ 
+ 	if ((dynamic) ||
+-	    (memcmp(&src, &get_src, sizeof(struct sockaddr_storage))) ||
+-	    (memcmp(&dst, &get_dst, sizeof(struct sockaddr_storage)))) {
++	    (memcmp(&lo, &get_src, sizeof(struct sockaddr_storage))) ||
++	    (memcmp(&lo, &get_dst, sizeof(struct sockaddr_storage)))) {
+ 		printf("knet_link_get_config returned invalid data\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -226,7 +216,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, NULL, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -250,7 +240,7 @@ static void test(void)
+ 	}
+ 
+ 	if ((!dynamic) ||
+-	    (memcmp(&src, &get_src, sizeof(struct sockaddr_storage)))) {
++	    (memcmp(&lo, &get_src, sizeof(struct sockaddr_storage)))) {
+ 		printf("knet_link_get_config returned invalid data\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -278,7 +268,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, NULL, KNET_LINK_FLAG_TRAFFICHIPRIO) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, KNET_LINK_FLAG_TRAFFICHIPRIO, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_link_get_enable.c b/libknet/tests/api_knet_link_get_enable.c
+index b437cf8c..2098c9d0 100644
+--- a/libknet/tests/api_knet_link_get_enable.c
++++ b/libknet/tests/api_knet_link_get_enable.c
+@@ -25,18 +25,8 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+ 	unsigned int enabled;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_get_enable incorrect knet_h\n");
+ 
+@@ -110,7 +100,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_enable with disabled link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_get_link_list.c b/libknet/tests/api_knet_link_get_link_list.c
+index 386ae525..d59f4f7a 100644
+--- a/libknet/tests/api_knet_link_get_link_list.c
++++ b/libknet/tests/api_knet_link_get_link_list.c
+@@ -25,19 +25,9 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+ 	uint8_t link_ids[KNET_MAX_LINK];
+ 	size_t link_ids_entries = 0;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	memset(&link_ids, 1, sizeof(link_ids));
+ 
+@@ -123,7 +113,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_link_list with 1 link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_get_ping_timers.c b/libknet/tests/api_knet_link_get_ping_timers.c
+index e684b2e2..889b4536 100644
+--- a/libknet/tests/api_knet_link_get_ping_timers.c
++++ b/libknet/tests/api_knet_link_get_ping_timers.c
+@@ -25,19 +25,9 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+ 	time_t interval = 0, timeout = 0;
+ 	unsigned int precision = 0;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_get_ping_timers incorrect knet_h\n");
+ 
+@@ -137,7 +127,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_ping_timers with correct values\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_get_pong_count.c b/libknet/tests/api_knet_link_get_pong_count.c
+index 77e587b6..2fa41572 100644
+--- a/libknet/tests/api_knet_link_get_pong_count.c
++++ b/libknet/tests/api_knet_link_get_pong_count.c
+@@ -25,18 +25,8 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+ 	uint8_t pong_count = 0;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_get_pong_count incorrect knet_h\n");
+ 
+@@ -110,7 +100,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_pong_count with correct values\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_get_priority.c b/libknet/tests/api_knet_link_get_priority.c
+index 1ecb04c2..16272964 100644
+--- a/libknet/tests/api_knet_link_get_priority.c
++++ b/libknet/tests/api_knet_link_get_priority.c
+@@ -25,18 +25,8 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+ 	uint8_t priority = 0;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_get_priority incorrect knet_h\n");
+ 
+@@ -110,7 +100,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_priority with correct values\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_get_status.c b/libknet/tests/api_knet_link_get_status.c
+index 1362efeb..5a590383 100644
+--- a/libknet/tests/api_knet_link_get_status.c
++++ b/libknet/tests/api_knet_link_get_status.c
+@@ -25,18 +25,8 @@ static void test(void)
+ {
+ 	knet_handle_t knet_h;
+ 	int logfds[2];
+-	struct sockaddr_storage src, dst;
+ 	struct knet_link_status status;
+-
+-	if (make_local_sockaddr(&src, 0) < 0) {
+-		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_get_status incorrect knet_h\n");
+ 
+@@ -112,7 +102,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_get_status with correct values\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index 08d507ef..8b53019c 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -163,7 +163,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_insert_acl with point to point link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -188,7 +188,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_insert_acl with dynamic link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index 75af8283..180eaa4a 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -163,7 +163,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_rm_acl with point to point link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -188,7 +188,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_rm_acl with dynamic link\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index c3085403..fd0ecd93 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -27,28 +27,20 @@ static void test(void)
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 	int logfds[2];
+-	char src_portstr[32];
+-	char dst_portstr[32];
+-	struct sockaddr_storage src, dst;
+-	struct sockaddr_in *src_in = (struct sockaddr_in *)&src;
+-	struct sockaddr_in *dst_in = (struct sockaddr_in *)&dst;
++	char lo_portstr[32];
++	struct sockaddr_storage lo, lo6;
++	struct sockaddr_in *lo_in = (struct sockaddr_in *)&lo;
+ 	struct knet_link_status link_status;
+ 
+-	if (make_local_sockaddr(&src, 0) < 0) {
++	if (make_local_sockaddr(&lo, -1) < 0) {
+ 		printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+-	sprintf(src_portstr, "%d", ntohs(src_in->sin_port));
+-
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-	sprintf(dst_portstr, "%d", ntohs(dst_in->sin_port));
++	sprintf(lo_portstr, "%d", ntohs(lo_in->sin_port));
+ 
+ 	printf("Test knet_link_set_config incorrect knet_h\n");
+ 
+-	if ((!knet_link_set_config(NULL, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0)) || (errno != EINVAL)) {
++	if ((!knet_link_set_config(NULL, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0)) || (errno != EINVAL)) {
+ 		printf("knet_link_set_config accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+@@ -59,7 +51,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with unconfigured host_id\n");
+ 
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0)) || (errno != EINVAL)) {
++	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0)) || (errno != EINVAL)) {
+ 		printf("knet_link_set_config accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+@@ -69,7 +61,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with bad transport type\n");
+ 
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_MAX_TRANSPORTS, &src, &dst, 0)) || (errno != EINVAL)) {
++	if ((!knet_link_set_config(knet_h, 1, 0, KNET_MAX_TRANSPORTS, &lo, &lo, 0)) || (errno != EINVAL)) {
+ 		printf("knet_link_set_config accepted invalid transport or returned incorrect error: %s\n", strerror(errno));
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+@@ -89,7 +81,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if ((!knet_link_set_config(knet_h, 1, KNET_MAX_LINK, KNET_TRANSPORT_UDP, &src, &dst, 0)) || (errno != EINVAL)) {
++	if ((!knet_link_set_config(knet_h, 1, KNET_MAX_LINK, KNET_TRANSPORT_UDP, &lo, &lo, 0)) || (errno != EINVAL)) {
+ 		printf("knet_link_set_config accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -102,7 +94,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with incorrect src_addr\n");
+ 
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, NULL, &dst, 0)) || (errno != EINVAL)) {
++	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, NULL, &lo, 0)) || (errno != EINVAL)) {
+ 		printf("knet_link_set_config accepted invalid src_addr or returned incorrect error: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -115,12 +107,12 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with conflicting address families\n");
+ 
+-	if (make_local_sockaddr6(&dst, 1) < 0) {
++	if (make_local_sockaddr6(&lo6, -1) < 0) {
+ 		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) == 0) {
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo6, 0) == 0) {
+ 		printf("knet_link_set_config accepted invalid address families: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -133,7 +125,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with dynamic dst_addr\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, NULL, 0) < 0) {
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -167,7 +159,7 @@ static void test(void)
+ 
+ 	if ((link_status.enabled != 0) ||
+ 	    (strcmp(link_status.src_ipaddr, "127.0.0.1")) ||
+-	    (strcmp(link_status.src_port, src_portstr)) ||
++	    (strcmp(link_status.src_port, lo_portstr)) ||
+ 	    (knet_h->host_index[1]->link[0].dynamic != KNET_LINK_DYNIP)) {
+ 		printf("knet_link_set_config failed to set configuration. enabled: %d src_addr %s src_port %s dynamic %u\n",
+ 		       link_status.enabled, link_status.src_ipaddr, link_status.src_port, knet_h->host_index[1]->link[0].dynamic);
+@@ -182,7 +174,7 @@ static void test(void)
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_link_set_config with already configured link\n");
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, NULL, 0) || (errno != EBUSY))) {
++	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) || (errno != EBUSY))) {
+ 		printf("knet_link_set_config accepted request while link configured or returned incorrect error: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -214,7 +206,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, NULL, 0)) || (errno != EBUSY)) {
++	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0)) || (errno != EBUSY)) {
+ 		printf("knet_link_set_config accepted request while link enabled or returned incorrect error: %s\n", strerror(errno));
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -245,12 +237,7 @@ static void test(void)
+ 
+ 	printf("Test knet_link_set_config with static dst_addr\n");
+ 
+-	if (make_local_sockaddr(&dst, 1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
++	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -284,9 +271,9 @@ static void test(void)
+ 
+ 	if ((link_status.enabled != 0) ||
+ 	    (strcmp(link_status.src_ipaddr, "127.0.0.1")) ||
+-	    (strcmp(link_status.src_port, src_portstr)) ||
++	    (strcmp(link_status.src_port, lo_portstr)) ||
+ 	    (strcmp(link_status.dst_ipaddr, "127.0.0.1")) ||
+-	    (strcmp(link_status.dst_port, dst_portstr)) || 
++	    (strcmp(link_status.dst_port, lo_portstr)) ||
+ 	    (knet_h->host_index[1]->link[0].dynamic != KNET_LINK_STATIC)) {
+ 		printf("knet_link_set_config failed to set configuration. enabled: %d src_addr %s src_port %s dst_addr %s dst_port %s dynamic %u\n",
+ 		       link_status.enabled, link_status.src_ipaddr, link_status.src_port, link_status.dst_ipaddr, link_status.dst_port, knet_h->host_index[1]->link[0].dynamic);
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index 8805bc59..e999d617 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -47,11 +47,6 @@ static void test(uint8_t transport)
+ 	int savederrno;
+ 	struct sockaddr_storage lo;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	printf("Test knet_send incorrect knet_h\n");
+@@ -180,7 +175,7 @@ static void test(uint8_t transport)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, transport, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, transport, 0, AF_INET, 0, &lo) < 0 ) {
+ 		int exit_status = transport == KNET_TRANSPORT_SCTP && errno == EPROTONOSUPPORT ? SKIP : FAIL;
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index d302a4b0..64d174d8 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -49,11 +49,6 @@ static void test(const char *model)
+ 	struct sockaddr_storage lo;
+ 	struct knet_handle_compress_cfg knet_handle_compress_cfg;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	setup_logpipes(logfds);
+@@ -104,7 +99,7 @@ static void test(const char *model)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index a894e9fa..4b2982c9 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -49,11 +49,6 @@ static void test(const char *model)
+ 	struct sockaddr_storage lo;
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	setup_logpipes(logfds);
+@@ -105,7 +100,7 @@ static void test(const char *model)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 825d672d..18aae92a 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -64,10 +64,6 @@ static void test(void)
+ 	int savederrno;
+ 	struct sockaddr_storage lo;
+ 
+-	if (make_local_sockaddr(&lo, 1) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	setup_logpipes(logfds);
+@@ -105,7 +101,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -114,7 +110,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) == 0) {
++	if (_knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) == 0) {
+ 		printf("Managed to configure two LOOPBACK links - this is wrong\n");
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -126,7 +122,7 @@ static void test(void)
+ 	flush_logs(logfds[0], stdout);
+ 	printf("Test configuring UDP link after loopback\n");
+ 
+-	if (knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_UDP, &lo, &lo, 0) == 0) {
++	if (_knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) == 0) {
+ 		printf("Managed to configure UDP and LOOPBACK links together: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -147,7 +143,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Failed to configure UDP link for testing: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -156,7 +152,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) == 0) {
++	if (_knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) == 0) {
+ 		printf("Managed to configure LOOPBACK link after UDP: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+@@ -185,7 +181,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Failed configure LOOPBACK link for sending: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 240bdf4a..2b5359a4 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -101,11 +101,6 @@ static void test(void)
+ 	char send_buff[KNET_MAX_PACKET_SIZE];
+ 	struct sockaddr_storage lo;
+ 
+-	if (make_local_sockaddr(&lo, 1) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	printf("Test knet_send_sync incorrect knet_h\n");
+@@ -296,7 +291,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/fun_pmtud_crypto.c b/libknet/tests/fun_pmtud_crypto.c
+index 9e552fc2..bbd31451 100644
+--- a/libknet/tests/fun_pmtud_crypto.c
++++ b/libknet/tests/fun_pmtud_crypto.c
+@@ -114,11 +114,6 @@ static void test_mtu(const char *model, const char *crypto, const char *hash)
+ 	unsigned int data_mtu, expected_mtu;
+ 	size_t calculated_iface_mtu = 0, detected_iface_mtu = 0;
+ 
+-	if (make_local_sockaddr(&lo, 0) < 0) {
+-		printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
+-		exit_local(FAIL);
+-	}
+-
+ 	setup_logpipes(logfds);
+ 
+ 	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+@@ -168,7 +163,7 @@ static void test_mtu(const char *model, const char *crypto, const char *hash)
+ 		exit_local(FAIL);
+ 	}
+ 
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
++	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+ 		knet_host_remove(knet_h, 1);
+ 		knet_handle_free(knet_h);
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 3461fb7d..481d7fe0 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -435,18 +435,21 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 	return 0;
+ }
+ 
+-static int _make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset, int family)
++static int _make_local_sockaddr(struct sockaddr_storage *lo, int offset, int family)
+ {
+-	uint32_t port;
++	in_port_t port;
+ 	char portstr[32];
+ 
+-	/* Use the pid if we can. but makes sure its in a sensible range */
+-	port = (uint32_t)getpid() + offset;
+-	if (port < 1024) {
+-		port += 1024;
+-	}
+-	if (port > 65536) {
+-		port = port & 0xFFFF;
++	if (offset < 0) {
++		/*
++		 * api_knet_link_set_config needs to access the API directly, but
++		 * it does not send any traffic, so it´s safe to ask the kernel
++		 * for a random port.
++		 */
++		port = 0;
++	} else {
++		/* Use the pid if we can. but makes sure its in a sensible range */
++		port = (getpid() + offset) % (65536-1024) + 1024;
+ 	}
+ 	sprintf(portstr, "%u", port);
+ 	memset(lo, 0, sizeof(struct sockaddr_storage));
+@@ -458,16 +461,61 @@ static int _make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset, in
+ 	return knet_strtoaddr("127.0.0.1", portstr, lo, sizeof(struct sockaddr_storage));
+ }
+ 
+-int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset)
++int make_local_sockaddr(struct sockaddr_storage *lo, int offset)
+ {
+ 	return _make_local_sockaddr(lo, offset, AF_INET);
+ }
+ 
+-int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset)
++int make_local_sockaddr6(struct sockaddr_storage *lo, int offset)
+ {
+ 	return _make_local_sockaddr(lo, offset, AF_INET6);
+ }
+ 
++int _knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++			  uint8_t transport, uint64_t flags, int family, int dynamic,
++			  struct sockaddr_storage *lo)
++{
++	int err = 0, savederrno = 0;
++	uint32_t port;
++	char portstr[32];
++
++	for (port = 1025; port < 65536; port++) {
++		sprintf(portstr, "%u", port);
++		memset(lo, 0, sizeof(struct sockaddr_storage));
++		if (family == AF_INET6) {
++			err = knet_strtoaddr("::1", portstr, lo, sizeof(struct sockaddr_storage));
++		} else {
++			err = knet_strtoaddr("127.0.0.1", portstr, lo, sizeof(struct sockaddr_storage));
++		}
++		if (err < 0) {
++			printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++			goto out;
++		}
++		errno = 0;
++		if (dynamic) {
++			err = knet_link_set_config(knet_h, host_id, link_id, transport, lo, NULL, flags);
++		} else {
++			err = knet_link_set_config(knet_h, host_id, link_id, transport, lo, lo, flags);
++		}
++		savederrno = errno;
++		if ((err < 0)  && (savederrno != EADDRINUSE)) {
++			printf("Unable to configure link: %s\n", strerror(savederrno));
++			goto out;
++		}
++		if (!err) {
++			printf("Using port %u\n", port);
++			goto out;
++		}
++	}
++
++	if (err) {
++		printf("No more ports available\n");
++	}
++out:
++	errno = savederrno;
++	return err;
++}
++
+ void test_sleep(knet_handle_t knet_h, int seconds)
+ {
+ 	if (is_memcheck() || is_helgrind()) {
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 96672e8e..0c40400f 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -46,6 +46,14 @@ knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level);
+  */
+ int knet_handle_stop(knet_handle_t knet_h);
+ 
++/*
++ * knet_link_set_config wrapper required to find a free port
++ */
++
++int _knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++			  uint8_t transport, uint64_t flags, int family, int dynamic,
++			  struct sockaddr_storage *lo);
++
+ /*
+  * high level logging function.
+  * automatically setup logpipes and start/stop logging thread.
+@@ -67,8 +75,8 @@ void close_logpipes(int *logfds);
+ void flush_logs(int logfd, FILE *std);
+ int start_logthread(int logfd, FILE *std);
+ int stop_logthread(void);
+-int make_local_sockaddr(struct sockaddr_storage *lo, uint16_t offset);
+-int make_local_sockaddr6(struct sockaddr_storage *lo, uint16_t offset);
++int make_local_sockaddr(struct sockaddr_storage *lo, int offset);
++int make_local_sockaddr6(struct sockaddr_storage *lo, int offset);
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std);
+ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd, int logfd, FILE *std);
+ void test_sleep(knet_handle_t knet_h, int seconds);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0354-rx-kill-unused-variable.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0354-rx-kill-unused-variable.patch
new file mode 100644
index 000000000..161854412
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0354-rx-kill-unused-variable.patch
@@ -0,0 +1,30 @@ 
+From df1c3e5664e6ce7b8edf3011452cf4f1e92b82d7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Feb 2020 10:26:49 +0100
+Subject: [PATCH] [rx] kill unused variable
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 2 --
+ 1 file changed, 2 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 4199b79f..28df49cc 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -236,7 +236,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	knet_node_id_t dst_host_ids[KNET_MAX_HOST];
+ 	size_t dst_host_ids_entries = 0;
+ 	int bcast = 1;
+-	int was_decrypted = 0;
+ 	uint64_t crypt_time = 0;
+ 	struct timespec recvtime;
+ 	struct knet_header *inbuf = msg->msg_hdr.msg_iov->iov_base;
+@@ -275,7 +274,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 
+ 		len = outlen;
+ 		inbuf = (struct knet_header *)knet_h->recv_from_links_buf_decrypt;
+-		was_decrypted++;
+ 	}
+ 
+ 	if (len < (ssize_t)(KNET_HEADER_SIZE + 1)) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0355-stats-allow-knet_handle_get_stats-to-operate-in-a-re.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0355-stats-allow-knet_handle_get_stats-to-operate-in-a-re.patch
new file mode 100644
index 000000000..a65fcbfea
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0355-stats-allow-knet_handle_get_stats-to-operate-in-a-re.patch
@@ -0,0 +1,382 @@ 
+From 54d48d89979ded6932588d0a9079b9d489609df9 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 Feb 2020 11:04:38 +0100
+Subject: [PATCH] [stats] allow knet_handle_get_stats to operate in a readlock
+ context
+
+- add global stat mutex lock to protect stats updates
+- use global stat mutex lock across all the threads
+- fix up some minor bugs:
+  - update RX crypto stats only when crypto is enabled
+  - update compress and crypto stats in a consistent fashion
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c            | 26 +++++++++++---
+ libknet/internals.h         |  1 +
+ libknet/threads_heartbeat.c |  5 +++
+ libknet/threads_pmtud.c     |  5 +++
+ libknet/threads_rx.c        | 68 ++++++++++++++++++++++++++-----------
+ libknet/threads_tx.c        | 63 +++++++++++++++++++++++++---------
+ 6 files changed, 128 insertions(+), 40 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index e86f0ab5..aae5bb8a 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -80,6 +80,13 @@ static int _init_locks(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
++	savederrno = pthread_mutex_init(&knet_h->handle_stats_mutex, NULL);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize handle stats mutex: %s",
++			strerror(savederrno));
++		goto exit_fail;
++	}
++
+ 	savederrno = pthread_mutex_init(&knet_h->threads_status_mutex, NULL);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize threads status mutex: %s",
+@@ -154,6 +161,7 @@ static void _destroy_locks(knet_handle_t knet_h)
+ 	pthread_mutex_destroy(&knet_h->backoff_mutex);
+ 	pthread_mutex_destroy(&knet_h->tx_seq_num_mutex);
+ 	pthread_mutex_destroy(&knet_h->threads_status_mutex);
++	pthread_mutex_destroy(&knet_h->handle_stats_mutex);
+ }
+ 
+ static int _init_socks(knet_handle_t knet_h)
+@@ -1677,7 +1685,7 @@ out_unlock:
+ 
+ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats, size_t struct_size)
+ {
+-	int savederrno = 0;
++	int err = 0, savederrno = 0;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -1689,14 +1697,22 @@ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats,
+ 		return -1;
+ 	}
+ 
+-	savederrno = get_global_wrlock(knet_h);
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+ 	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+ 			strerror(savederrno));
+ 		errno = savederrno;
+ 		return -1;
+ 	}
+ 
++	savederrno = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock: %s",
++			strerror(savederrno));
++		err = -1;
++		goto out_unlock;
++	}
++
+ 	if (struct_size > sizeof(struct knet_handle_stats)) {
+ 		struct_size = sizeof(struct knet_handle_stats);
+ 	}
+@@ -1716,8 +1732,10 @@ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats,
+ 	/* Tell the caller our full size in case they have an old version */
+ 	stats->size = sizeof(struct knet_handle_stats);
+ 
++out_unlock:
++	pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	return 0;
++	return err;
+ }
+ 
+ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 63926204..9ea064e7 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -183,6 +183,7 @@ struct knet_handle {
+ 	struct knet_fd_trackers knet_transport_fd_tracker[KNET_MAX_FDS]; /* track status for each fd handled by transports */
+ 	struct knet_handle_stats stats;
+ 	struct knet_handle_stats_extra stats_extra;
++	pthread_mutex_t handle_stats_mutex;	/* used to protect handle stats */
+ 	uint32_t reconnect_int;
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	size_t host_ids_entries;
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 1ed6207c..0f0c6633 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -81,7 +81,12 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 			}
+ 
+ 			outbuf = knet_h->pingbuf_crypt;
++			if (pthread_mutex_lock(&knet_h->handle_stats_mutex) < 0) {
++				log_err(knet_h, KNET_SUB_HEARTBEAT, "Unable to get mutex lock");
++				return;
++			}
+ 			knet_h->stats_extra.tx_crypt_ping_packets++;
++			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
+ retry:
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index dee87bb9..67a8e7a5 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -154,7 +154,12 @@ restart:
+ 		}
+ 
+ 		outbuf = knet_h->pmtudbuf_crypt;
++		if (pthread_mutex_lock(&knet_h->handle_stats_mutex) < 0) {
++			log_err(knet_h, KNET_SUB_PMTUD, "Unable to get mutex lock");
++			return -1;
++		}
+ 		knet_h->stats_extra.tx_crypt_pmtu_packets++;
++		pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 	} else {
+ 		knet_h->pmtudbuf->khp_pmtud_size = onwire_len;
+ 	}
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 28df49cc..4b41c5c3 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -228,7 +228,7 @@ static int pckt_defrag(knet_handle_t knet_h, struct knet_header *inbuf, ssize_t
+ 
+ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struct knet_mmsghdr *msg)
+ {
+-	int err = 0, savederrno = 0;
++	int err = 0, savederrno = 0, stats_err = 0;
+ 	ssize_t outlen;
+ 	struct knet_host *src_host;
+ 	struct knet_link *src_link;
+@@ -236,7 +236,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	knet_node_id_t dst_host_ids[KNET_MAX_HOST];
+ 	size_t dst_host_ids_entries = 0;
+ 	int bcast = 1;
+-	uint64_t crypt_time = 0;
++	uint64_t decrypt_time = 0;
+ 	struct timespec recvtime;
+ 	struct knet_header *inbuf = msg->msg_hdr.msg_iov->iov_base;
+ 	unsigned char *outbuf = (unsigned char *)msg->msg_hdr.msg_iov->iov_base;
+@@ -263,14 +263,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 			return;
+ 		}
+ 		clock_gettime(CLOCK_MONOTONIC, &end_time);
+-		timespec_diff(start_time, end_time, &crypt_time);
+-
+-		if (crypt_time < knet_h->stats.rx_crypt_time_min) {
+-			knet_h->stats.rx_crypt_time_min = crypt_time;
+-		}
+-		if (crypt_time > knet_h->stats.rx_crypt_time_max) {
+-			knet_h->stats.rx_crypt_time_max = crypt_time;
+-		}
++		timespec_diff(start_time, end_time, &decrypt_time);
+ 
+ 		len = outlen;
+ 		inbuf = (struct knet_header *)knet_h->recv_from_links_buf_decrypt;
+@@ -380,11 +373,18 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 					 len - KNET_HEADER_DATA_SIZE,
+ 					 knet_h->recv_from_links_buf_decompress,
+ 					 &decmp_outlen);
++
++			stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++			if (stats_err < 0) {
++				log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
++				return;
++			}
++
++			clock_gettime(CLOCK_MONOTONIC, &end_time);
++			timespec_diff(start_time, end_time, &compress_time);
++
+ 			if (!err) {
+ 				/* Collect stats */
+-				clock_gettime(CLOCK_MONOTONIC, &end_time);
+-				timespec_diff(start_time, end_time, &compress_time);
+-
+ 				if (compress_time < knet_h->stats.rx_compress_time_min) {
+ 					knet_h->stats.rx_compress_time_min = compress_time;
+ 				}
+@@ -402,23 +402,39 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 				memmove(inbuf->khp_data_userdata, knet_h->recv_from_links_buf_decompress, decmp_outlen);
+ 				len = decmp_outlen + KNET_HEADER_DATA_SIZE;
+ 			} else {
++				pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 				log_warn(knet_h, KNET_SUB_COMPRESS, "Unable to decompress packet (%d): %s",
+ 					 err, strerror(errno));
+ 				return;
+ 			}
++			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
+ 		if (inbuf->kh_type == KNET_HEADER_TYPE_DATA) {
++			if (knet_h->crypto_instance) {
++				stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++				if (stats_err < 0) {
++					log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
++					return;
++				}
++				/* Only update the crypto overhead for data packets. Mainly to be
++				   consistent with TX */
++				if (decrypt_time < knet_h->stats.rx_crypt_time_min) {
++					knet_h->stats.rx_crypt_time_min = decrypt_time;
++				}
++				if (decrypt_time > knet_h->stats.rx_crypt_time_max) {
++					knet_h->stats.rx_crypt_time_max = decrypt_time;
++				}
++				knet_h->stats.rx_crypt_time_ave =
++					(knet_h->stats.rx_crypt_time_ave * knet_h->stats.rx_crypt_packets +
++					 decrypt_time) / (knet_h->stats.rx_crypt_packets+1);
++				knet_h->stats.rx_crypt_packets++;
++				pthread_mutex_unlock(&knet_h->handle_stats_mutex);
++			}
++
+ 			if (knet_h->enabled != 1) /* data forward is disabled */
+ 				break;
+ 
+-			/* Only update the crypto overhead for data packets. Mainly to be
+-			   consistent with TX */
+-			knet_h->stats.rx_crypt_time_ave =
+-				(knet_h->stats.rx_crypt_time_ave * knet_h->stats.rx_crypt_packets +
+-				 crypt_time) / (knet_h->stats.rx_crypt_packets+1);
+-			knet_h->stats.rx_crypt_packets++;
+-
+ 			if (knet_h->dst_host_filter_fn) {
+ 				size_t host_idx;
+ 				int found = 0;
+@@ -575,7 +591,13 @@ retry:
+ 				break;
+ 			}
+ 			outbuf = knet_h->recv_from_links_buf_crypt;
++			stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++			if (stats_err < 0) {
++				log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
++				break;
++			}
+ 			knet_h->stats_extra.tx_crypt_pong_packets++;
++			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
+ retry_pong:
+@@ -688,7 +710,13 @@ retry_pong:
+ 				break;
+ 			}
+ 			outbuf = knet_h->recv_from_links_buf_crypt;
++			stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++			if (stats_err < 0) {
++				log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
++				break;
++			}
+ 			knet_h->stats_extra.tx_crypt_pmtu_reply_packets++;
++			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
+ 		savederrno = pthread_mutex_lock(&knet_h->tx_mutex);
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index f1b74a30..be54952f 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -154,6 +154,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 	int send_local = 0;
+ 	int data_compressed = 0;
+ 	size_t uncrypted_frag_size;
++	int stats_locked = 0, stats_err = 0;
+ 
+ 	inbuf = knet_h->recv_from_sock_buf;
+ 
+@@ -346,23 +347,33 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 		err = compress(knet_h,
+ 			       (const unsigned char *)inbuf->khp_data_userdata, inlen,
+ 			       knet_h->send_to_links_buf_compress, (ssize_t *)&cmp_outlen);
+-		if (err < 0) {
+-			log_warn(knet_h, KNET_SUB_COMPRESS, "Compression failed (%d): %s", err, strerror(errno));
+-		} else {
+-			/* Collect stats */
+-			clock_gettime(CLOCK_MONOTONIC, &end_time);
+-			timespec_diff(start_time, end_time, &compress_time);
+ 
+-	                if (compress_time < knet_h->stats.tx_compress_time_min) {
+-				knet_h->stats.tx_compress_time_min = compress_time;
+-			}
+-			if (compress_time > knet_h->stats.tx_compress_time_max) {
+-				knet_h->stats.tx_compress_time_max = compress_time;
+-			}
+-			knet_h->stats.tx_compress_time_ave =
+-				(unsigned long long)(knet_h->stats.tx_compress_time_ave * knet_h->stats.tx_compressed_packets +
+-				 compress_time) / (knet_h->stats.tx_compressed_packets+1);
++		savederrno = errno;
+ 
++		stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++		if (stats_err < 0) {
++			log_err(knet_h, KNET_SUB_TX, "Unable to get mutex lock: %s", strerror(stats_err));
++			err = -1;
++			savederrno = stats_err;
++			goto out_unlock;
++		}
++		stats_locked = 1;
++		/* Collect stats */
++		clock_gettime(CLOCK_MONOTONIC, &end_time);
++		timespec_diff(start_time, end_time, &compress_time);
++
++		if (compress_time < knet_h->stats.tx_compress_time_min) {
++			knet_h->stats.tx_compress_time_min = compress_time;
++		}
++		if (compress_time > knet_h->stats.tx_compress_time_max) {
++			knet_h->stats.tx_compress_time_max = compress_time;
++		}
++		knet_h->stats.tx_compress_time_ave =
++			(unsigned long long)(knet_h->stats.tx_compress_time_ave * knet_h->stats.tx_compressed_packets +
++			 compress_time) / (knet_h->stats.tx_compressed_packets+1);
++		if (err < 0) {
++			log_warn(knet_h, KNET_SUB_COMPRESS, "Compression failed (%d): %s", err, strerror(savederrno));
++		} else {
+ 			knet_h->stats.tx_compressed_packets++;
+ 			knet_h->stats.tx_compressed_original_bytes += inlen;
+ 			knet_h->stats.tx_compressed_size_bytes += cmp_outlen;
+@@ -374,9 +385,20 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 			}
+ 		}
+ 	}
++	if (!stats_locked) {
++		stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++		if (stats_err < 0) {
++			log_err(knet_h, KNET_SUB_TX, "Unable to get mutex lock: %s", strerror(stats_err));
++			err = -1;
++			savederrno = stats_err;
++			goto out_unlock;
++		}
++	}
+ 	if (knet_h->compress_model > 0 && !data_compressed) {
+ 		knet_h->stats.tx_uncompressed_packets++;
+ 	}
++	pthread_mutex_unlock(&knet_h->handle_stats_mutex);
++	stats_locked = 0;
+ 
+ 	/*
+ 	 * prepare the outgoing buffers
+@@ -488,7 +510,15 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 			clock_gettime(CLOCK_MONOTONIC, &end_time);
+ 			timespec_diff(start_time, end_time, &crypt_time);
+ 
+-	                if (crypt_time < knet_h->stats.tx_crypt_time_min) {
++			stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++			if (stats_err < 0) {
++				log_err(knet_h, KNET_SUB_TX, "Unable to get mutex lock: %s", strerror(stats_err));
++				err = -1;
++				savederrno = stats_err;
++				goto out_unlock;
++			}
++
++			if (crypt_time < knet_h->stats.tx_crypt_time_min) {
+ 				knet_h->stats.tx_crypt_time_min = crypt_time;
+ 			}
+ 			if (crypt_time > knet_h->stats.tx_crypt_time_max) {
+@@ -504,6 +534,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 			}
+ 			knet_h->stats.tx_crypt_byte_overhead += (outlen - uncrypted_frag_size);
+ 			knet_h->stats.tx_crypt_packets++;
++			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 
+ 			iov_out[frag_idx][0].iov_base = knet_h->send_to_links_buf_crypt[frag_idx];
+ 			iov_out[frag_idx][0].iov_len = outlen;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0356-stats-allow-knet_link_get_status-to-operate-in-readl.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0356-stats-allow-knet_link_get_status-to-operate-in-readl.patch
new file mode 100644
index 000000000..51b18ff96
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0356-stats-allow-knet_link_get_status-to-operate-in-readl.patch
@@ -0,0 +1,501 @@ 
+From 1fd226bdef91daf4670f11af8dd3f111376f4b9f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 20 Feb 2020 09:04:59 +0100
+Subject: [PATCH] [stats] allow knet_link_get_status to operate in readlock
+ context
+
+- add per link stats mutex
+- use per link stats mutex across the board
+
+note: some threads need to lock for a slightly longer period of time than
+strictly necessary to avoid reverse-order locking with other mutexes.
+
+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h         |  1 +
+ libknet/links.c             | 43 ++++++++++++++++++++++++++++---
+ libknet/links.h             |  2 +-
+ libknet/threads_heartbeat.c | 12 +++++++--
+ libknet/threads_pmtud.c     | 14 +++++++++++
+ libknet/threads_rx.c        | 50 ++++++++++++++++++++++++++++++-------
+ libknet/threads_tx.c        | 16 +++++++++++-
+ 7 files changed, 121 insertions(+), 17 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 9ea064e7..94e208b6 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -72,6 +72,7 @@ struct knet_link {
+ 	/* status */
+ 	struct knet_link_status status;
+ 	/* internals */
++	pthread_mutex_t link_stats_mutex;	/* used to update link stats */
+ 	uint8_t link_id;
+ 	uint8_t transport;                      /* #defined constant from API */
+ 	knet_transport_link_t transport_link;   /* link_info_t from transport */
+diff --git a/libknet/links.c b/libknet/links.c
+index 2a0597d4..d08065bd 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -23,9 +23,11 @@
+ #include "links_acl.h"
+ 
+ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+-		 unsigned int enabled, unsigned int connected)
++		 unsigned int enabled, unsigned int connected, unsigned int lock_stats)
+ {
+-	struct knet_link *link = &knet_h->host_index[host_id]->link[link_id];
++	struct knet_host *host = knet_h->host_index[host_id];
++	struct knet_link *link = &host->link[link_id];
++	int savederrno = 0;
+ 
+ 	if ((link->status.enabled == enabled) &&
+ 	    (link->status.connected == connected))
+@@ -40,6 +42,16 @@ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 	    (!link->status.connected))
+ 		link->status.dynconnected = 0;
+ 
++	if (lock_stats) {
++		savederrno = pthread_mutex_lock(&link->link_stats_mutex);
++		if (savederrno) {
++			log_err(knet_h, KNET_SUB_LINK, "Unable to get stats mutex lock for host %u link %u: %s",
++				host_id, link_id, strerror(savederrno));
++			errno = savederrno;
++			return -1;
++		}
++	}
++
+ 	if (connected) {
+ 		time(&link->status.stats.last_up_times[link->status.stats.last_up_time_index]);
+ 		link->status.stats.up_count++;
+@@ -53,6 +65,10 @@ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 			link->status.stats.last_down_time_index = 0;
+ 		}
+ 	}
++
++	if (lock_stats) {
++		pthread_mutex_unlock(&link->link_stats_mutex);
++	}
+ 	return 0;
+ }
+ 
+@@ -230,6 +246,13 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	link->latency_cur_samples = 0;
+ 	link->flags = flags;
+ 
++	savederrno = pthread_mutex_init(&link->link_stats_mutex, NULL);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_LINK, "Unable to initialize link stats mutex: %s", strerror(savederrno));
++		err = -1;
++		goto exit_unlock;
++	}
++
+ 	if (transport_link_set_config(knet_h, link, transport) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+@@ -487,6 +510,8 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 		check_rmall(knet_h, sock, transport);
+ 	}
+ 
++	pthread_mutex_destroy(&link->link_stats_mutex);
++
+ 	memset(link, 0, sizeof(struct knet_link));
+ 	link->link_id = link_id;
+ 
+@@ -560,7 +585,7 @@ int knet_link_set_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		goto exit_unlock;
+ 	}
+ 
+-	err = _link_updown(knet_h, host_id, link_id, enabled, link->status.connected);
++	err = _link_updown(knet_h, host_id, link_id, enabled, link->status.connected, 0);
+ 	savederrno = errno;
+ 
+ 	if (enabled) {
+@@ -1102,7 +1127,7 @@ int knet_link_get_status(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		return -1;
+ 	}
+ 
+-	savederrno = get_global_wrlock(knet_h);
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_LINK, "Unable to get read lock: %s",
+ 			strerror(savederrno));
+@@ -1129,8 +1154,18 @@ int knet_link_get_status(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		goto exit_unlock;
+ 	}
+ 
++	savederrno = pthread_mutex_lock(&link->link_stats_mutex);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_LINK, "Unable to get stats mutex lock for host %u link %u: %s",
++			host_id, link_id, strerror(savederrno));
++		err = -1;
++		goto exit_unlock;
++	}
++
+ 	memmove(status, &link->status, struct_size);
+ 
++	pthread_mutex_unlock(&link->link_stats_mutex);
++
+ 	/* Calculate totals - no point in doing this on-the-fly */
+ 	status->stats.rx_total_packets =
+ 		status->stats.rx_data_packets +
+diff --git a/libknet/links.h b/libknet/links.h
+index 66890a84..1ba2b70a 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -41,7 +41,7 @@
+ #define KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MAX	128
+ 
+ int _link_updown(knet_handle_t knet_h, knet_node_id_t node_id, uint8_t link_id,
+-		 unsigned int enabled, unsigned int connected);
++		 unsigned int enabled, unsigned int connected, unsigned int lock_stats);
+ 
+ void _link_clear_stats(knet_handle_t knet_h);
+ 
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 0f0c6633..3b6ca161 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -31,13 +31,13 @@ static void _link_down(knet_handle_t knet_h, struct knet_host *dst_host, struct
+ 	if (dst_link->status.connected == 1) {
+ 		log_info(knet_h, KNET_SUB_LINK, "host: %u link: %u is down",
+ 			 dst_host->host_id, dst_link->link_id);
+-		_link_updown(knet_h, dst_host->host_id, dst_link->link_id, dst_link->status.enabled, 0);
++		_link_updown(knet_h, dst_host->host_id, dst_link->link_id, dst_link->status.enabled, 0, 1);
+ 	}
+ }
+ 
+ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_link *dst_link, int timed)
+ {
+-	int err = 0, savederrno = 0;
++	int err = 0, savederrno = 0, stats_err = 0;
+ 	int len;
+ 	ssize_t outlen = KNET_HEADER_PING_SIZE;
+ 	struct timespec clock_now, pong_last;
+@@ -89,6 +89,13 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
++		stats_err = pthread_mutex_lock(&dst_link->link_stats_mutex);
++		if (stats_err) {
++			log_err(knet_h, KNET_SUB_HEARTBEAT, "Unable to get stats mutex lock for host %u link %u: %s",
++				dst_host->host_id, dst_link->link_id, strerror(stats_err));
++			return;
++		}
++
+ retry:
+ 		if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
+@@ -123,6 +130,7 @@ retry:
+ 		} else {
+ 			dst_link->last_ping_size = outlen;
+ 		}
++		pthread_mutex_unlock(&dst_link->link_stats_mutex);
+ 	}
+ 
+ 	timespec_diff(pong_last, clock_now, &diff_ping);
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 67a8e7a5..2c4a2630 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -188,9 +188,20 @@ restart:
+ 
+ 	savederrno = pthread_mutex_lock(&knet_h->tx_mutex);
+ 	if (savederrno) {
++		pthread_mutex_unlock(&knet_h->pmtud_mutex);
+ 		log_err(knet_h, KNET_SUB_PMTUD, "Unable to get TX mutex lock: %s", strerror(savederrno));
+ 		return -1;
+ 	}
++
++	savederrno = pthread_mutex_lock(&dst_link->link_stats_mutex);
++	if (savederrno) {
++		pthread_mutex_unlock(&knet_h->pmtud_mutex);
++		pthread_mutex_unlock(&knet_h->tx_mutex);
++		log_err(knet_h, KNET_SUB_PMTUD, "Unable to get stats mutex lock for host %u link %u: %s",
++			dst_host->host_id, dst_link->link_id, strerror(savederrno));
++		return -1;
++	}
++
+ retry:
+ 	if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 		len = sendto(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL,
+@@ -223,6 +234,7 @@ retry:
+ 			pthread_mutex_unlock(&knet_h->tx_mutex);
+ 			pthread_mutex_unlock(&knet_h->pmtud_mutex);
+ 			dst_link->status.stats.tx_pmtu_errors++;
++			pthread_mutex_unlock(&dst_link->link_stats_mutex);
+ 			return -1;
+ 		case 0: /* ignore error and continue */
+ 			break;
+@@ -235,6 +247,7 @@ retry:
+ 	pthread_mutex_unlock(&knet_h->tx_mutex);
+ 
+ 	if (len != (ssize_t )data_len) {
++		pthread_mutex_unlock(&dst_link->link_stats_mutex);
+ 		if (savederrno == EMSGSIZE) {
+ 			/*
+ 			 * we cannot hold a lock on kmtu_mutex between resetting
+@@ -263,6 +276,7 @@ retry:
+ 		dst_link->last_recv_mtu = 0;
+ 		dst_link->status.stats.tx_pmtu_packets++;
+ 		dst_link->status.stats.tx_pmtu_bytes += data_len;
++		pthread_mutex_unlock(&dst_link->link_stats_mutex);
+ 
+ 		if (clock_gettime(CLOCK_REALTIME, &ts) < 0) {
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "Unable to get current time: %s", strerror(errno));
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 4b41c5c3..880174c1 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -286,8 +286,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		return;
+ 	}
+ 
+-	src_link = NULL;
+-
+ 	src_link = src_host->link +
+ 		(inbuf->khp_ping_link % KNET_MAX_LINK);
+ 	if ((inbuf->kh_type & KNET_HEADER_TYPE_PMSK) != 0) {
+@@ -324,10 +322,18 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		}
+ 	}
+ 
++	stats_err = pthread_mutex_lock(&src_link->link_stats_mutex);
++	if (stats_err) {
++		log_err(knet_h, KNET_SUB_RX, "Unable to get stats mutex lock for host %u link %u: %s",
++			src_host->host_id, src_link->link_id, strerror(savederrno));
++		return;
++	}
++
+ 	switch (inbuf->kh_type) {
+ 	case KNET_HEADER_TYPE_HOST_INFO:
+ 	case KNET_HEADER_TYPE_DATA:
+ 		if (!src_host->status.reachable) {
++			pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 			log_debug(knet_h, KNET_SUB_RX, "Source host %u not reachable yet. Discarding packet.", src_host->host_id);
+ 			return;
+ 		}
+@@ -335,12 +341,11 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		channel = inbuf->khp_data_channel;
+ 		src_host->got_data = 1;
+ 
+-		if (src_link) {
+-			src_link->status.stats.rx_data_packets++;
+-			src_link->status.stats.rx_data_bytes += len;
+-		}
++		src_link->status.stats.rx_data_packets++;
++		src_link->status.stats.rx_data_bytes += len;
+ 
+ 		if (!_seq_num_lookup(src_host, inbuf->khp_data_seq_num, 0, 0)) {
++			pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 			if (src_host->link_handler_policy != KNET_LINK_POLICY_ACTIVE) {
+ 				log_debug(knet_h, KNET_SUB_RX, "Packet has already been delivered");
+ 			}
+@@ -356,6 +361,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 			 */
+ 			len = len - KNET_HEADER_DATA_SIZE;
+ 			if (pckt_defrag(knet_h, inbuf, &len)) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 				return;
+ 			}
+ 			len = len + KNET_HEADER_DATA_SIZE;
+@@ -376,6 +382,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 
+ 			stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
+ 			if (stats_err < 0) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 				log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
+ 				return;
+ 			}
+@@ -403,6 +410,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 				len = decmp_outlen + KNET_HEADER_DATA_SIZE;
+ 			} else {
+ 				pthread_mutex_unlock(&knet_h->handle_stats_mutex);
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 				log_warn(knet_h, KNET_SUB_COMPRESS, "Unable to decompress packet (%d): %s",
+ 					 err, strerror(errno));
+ 				return;
+@@ -414,6 +422,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 			if (knet_h->crypto_instance) {
+ 				stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
+ 				if (stats_err < 0) {
++					pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 					log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
+ 					return;
+ 				}
+@@ -450,11 +459,13 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 						dst_host_ids,
+ 						&dst_host_ids_entries);
+ 				if (bcast < 0) {
++					pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 					log_debug(knet_h, KNET_SUB_RX, "Error from dst_host_filter_fn: %d", bcast);
+ 					return;
+ 				}
+ 
+ 				if ((!bcast) && (!dst_host_ids_entries)) {
++					pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 					log_debug(knet_h, KNET_SUB_RX, "Message is unicast but no dst_host_ids_entries");
+ 					return;
+ 				}
+@@ -462,6 +473,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 				/* check if we are dst for this packet */
+ 				if (!bcast) {
+ 					if (dst_host_ids_entries > KNET_MAX_HOST) {
++						pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 						log_debug(knet_h, KNET_SUB_RX, "dst_host_filter_fn returned too many destinations");
+ 						return;
+ 					}
+@@ -472,6 +484,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 						}
+ 					}
+ 					if (!found) {
++						pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 						log_debug(knet_h, KNET_SUB_RX, "Packet is not for us");
+ 						return;
+ 					}
+@@ -481,6 +494,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 
+ 		if (inbuf->kh_type == KNET_HEADER_TYPE_DATA) {
+ 			if (!knet_h->sockfd[channel].in_use) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 				log_debug(knet_h, KNET_SUB_RX,
+ 					  "received packet for channel %d but there is no local sock connected",
+ 					  channel);
+@@ -509,6 +523,7 @@ retry:
+ 						       KNET_NOTIFY_RX,
+ 						       outlen,
+ 						       errno);
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 				return;
+ 			}
+ 			if ((size_t)outlen == iov_out[0].iov_len) {
+@@ -520,6 +535,7 @@ retry:
+ 				knet_hostinfo->khi_dst_node_id = ntohs(knet_hostinfo->khi_dst_node_id);
+ 			}
+ 			if (!_seq_num_lookup(src_host, inbuf->khp_data_seq_num, 0, 0)) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 				return;
+ 			}
+ 			_seq_num_set(src_host, inbuf->khp_data_seq_num, 0);
+@@ -667,7 +683,7 @@ retry_pong:
+ 					if (src_link->received_pong >= src_link->pong_count) {
+ 						log_info(knet_h, KNET_SUB_RX, "host: %u link: %u is up",
+ 							 src_host->host_id, src_link->link_id);
+-						_link_updown(knet_h, src_host->host_id, src_link->link_id, src_link->status.enabled, 1);
++						_link_updown(knet_h, src_host->host_id, src_link->link_id, src_link->status.enabled, 1, 0);
+ 					} else {
+ 						src_link->received_pong++;
+ 						log_debug(knet_h, KNET_SUB_RX, "host: %u link: %u received pong: %u",
+@@ -719,6 +735,9 @@ retry_pong:
+ 			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
++		/* Unlock so we don't deadlock with tx_mutex */
++		pthread_mutex_unlock(&src_link->link_stats_mutex);
++
+ 		savederrno = pthread_mutex_lock(&knet_h->tx_mutex);
+ 		if (savederrno) {
+ 			log_err(knet_h, KNET_SUB_RX, "Unable to get TX mutex lock: %s", strerror(savederrno));
+@@ -735,6 +754,11 @@ retry_pmtud:
+ 			savederrno = errno;
+ 			if (len != outlen) {
+ 				err = transport_tx_sock_error(knet_h, src_link->transport, src_link->outsock, len, savederrno);
++				stats_err = pthread_mutex_lock(&src_link->link_stats_mutex);
++				if (stats_err < 0) {
++					log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
++					break;
++				}
+ 				switch(err) {
+ 					case -1: /* unrecoverable error */
+ 						log_debug(knet_h, KNET_SUB_RX,
+@@ -750,17 +774,23 @@ retry_pmtud:
+ 						break;
+ 					case 1: /* retry to send those same data */
+ 						src_link->status.stats.tx_pmtu_retries++;
++						pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 						goto retry_pmtud;
+ 						break;
+ 				}
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 			}
+ 		}
+ 		pthread_mutex_unlock(&knet_h->tx_mutex);
+ out_pmtud:
+-		break;
++		return; /* Don't need to unlock link_stats_mutex */
+ 	case KNET_HEADER_TYPE_PMTUD_REPLY:
+ 		src_link->status.stats.rx_pmtu_packets++;
+ 		src_link->status.stats.rx_pmtu_bytes += len;
++
++		/* pmtud_mutex can't be acquired while we hold a link_stats_mutex (ordering) */
++		pthread_mutex_unlock(&src_link->link_stats_mutex);
++
+ 		if (pthread_mutex_lock(&knet_h->pmtud_mutex) != 0) {
+ 			log_debug(knet_h, KNET_SUB_RX, "Unable to get mutex lock");
+ 			break;
+@@ -768,10 +798,12 @@ out_pmtud:
+ 		src_link->last_recv_mtu = inbuf->khp_pmtud_size;
+ 		pthread_cond_signal(&knet_h->pmtud_cond);
+ 		pthread_mutex_unlock(&knet_h->pmtud_mutex);
+-		break;
++		return;
+ 	default:
++		pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 		return;
+ 	}
++	pthread_mutex_unlock(&src_link->link_stats_mutex);
+ }
+ 
+ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg)
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index be54952f..d5539a1e 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -36,7 +36,7 @@
+ static int _dispatch_to_links(knet_handle_t knet_h, struct knet_host *dst_host, struct knet_mmsghdr *msg, int msgs_to_send)
+ {
+ 	int link_idx, msg_idx, sent_msgs, prev_sent, progress;
+-	int err = 0, savederrno = 0;
++	int err = 0, savederrno = 0, locked = 0;
+ 	unsigned int i;
+ 	struct knet_mmsghdr *cur;
+ 	struct knet_link *cur_link;
+@@ -44,6 +44,7 @@ static int _dispatch_to_links(knet_handle_t knet_h, struct knet_host *dst_host,
+ 	for (link_idx = 0; link_idx < dst_host->active_link_entries; link_idx++) {
+ 		prev_sent = 0;
+ 		progress = 1;
++		locked = 0;
+ 
+ 		cur_link = &dst_host->link[dst_host->active_links[link_idx]];
+ 
+@@ -51,6 +52,14 @@ static int _dispatch_to_links(knet_handle_t knet_h, struct knet_host *dst_host,
+ 			continue;
+ 		}
+ 
++		savederrno = pthread_mutex_lock(&cur_link->link_stats_mutex);
++		if (savederrno) {
++			log_err(knet_h, KNET_SUB_TX, "Unable to get stats mutex lock for host %u link %u: %s",
++				dst_host->host_id, cur_link->link_id, strerror(savederrno));
++			continue;
++		}
++		locked = 1;
++
+ 		msg_idx = 0;
+ 		while (msg_idx < msgs_to_send) {
+ 			msg[msg_idx].msg_hdr.msg_name = &cur_link->dst_addr;
+@@ -120,9 +129,14 @@ retry:
+ 
+ 			break;
+ 		}
++		pthread_mutex_unlock(&cur_link->link_stats_mutex);
++		locked = 0;
+ 	}
+ 
+ out_unlock:
++	if (locked) {
++		pthread_mutex_unlock(&cur_link->link_stats_mutex);
++	}
+ 	errno = savederrno;
+ 	return err;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0357-tests-fix-return-code-from-wait_for_packet.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0357-tests-fix-return-code-from-wait_for_packet.patch
new file mode 100644
index 000000000..97ec1b6b1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0357-tests-fix-return-code-from-wait_for_packet.patch
@@ -0,0 +1,21 @@ 
+From 917290816b7628bb7f676046bd1a266a50f3158d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 9 Mar 2020 09:37:41 +0100
+Subject: [PATCH] [tests] fix return code from wait_for_packet
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 481d7fe0..b3cf9638 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -581,5 +581,6 @@ try_again:
+ 		return 0;
+ 	}
+ 
++	errno = ETIMEDOUT;
+ 	return -1;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0358-lists-fix-build-with-recent-gcc-changes.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0358-lists-fix-build-with-recent-gcc-changes.patch
new file mode 100644
index 000000000..ea4c62068
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0358-lists-fix-build-with-recent-gcc-changes.patch
@@ -0,0 +1,33 @@ 
+From 7b4ab132075c9e6c48d117c4370d4eb8f88c079c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 16 Mar 2020 10:02:04 +0100
+Subject: [PATCH] [lists] fix build with recent gcc changes
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 94e208b6..e2f882b1 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -15,6 +15,7 @@
+  */
+ 
+ #include <pthread.h>
++#include <stddef.h>
+ #include "libknet.h"
+ #include "onwire.h"
+ #include "compat.h"
+@@ -527,8 +528,8 @@ static inline int32_t knet_list_empty(const struct knet_list_head *head)
+  * @param type:	the type of the struct this is embedded in.
+  * @param member:	the name of the list_struct within the struct.
+  */
+-#define knet_list_entry(ptr,type,member)\
+-	((type *)((char *)(ptr)-(char*)(&((type *)0)->member)))
++#define knet_list_entry(ptr,type,member) ({		\
++	((type *)((char*)ptr - offsetof(type, member))); })
+ 
+ /**
+  * Get the first element from a list
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0359-lists-drop-internal-implementation-and-use-libqb-one.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0359-lists-drop-internal-implementation-and-use-libqb-one.patch
new file mode 100644
index 000000000..59c0b11f5
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0359-lists-drop-internal-implementation-and-use-libqb-one.patch
@@ -0,0 +1,418 @@ 
+From 4adc424f0ea3f71c511c285b8f5ee6666dbea5d6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 16 Mar 2020 15:50:29 +0100
+Subject: [PATCH] [lists] drop internal implementation and use libqb one
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac             |   4 +-
+ kronosnet.spec.in        |   4 +-
+ libknet/Makefile.am      |   2 +-
+ libknet/internals.h      | 170 +--------------------------------------
+ libknet/transport_sctp.c |  26 +++---
+ libknet/transport_udp.c  |  14 ++--
+ 6 files changed, 26 insertions(+), 194 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 3534c0f1..0a8477fa 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -272,6 +272,8 @@ if test "x$enable_man" = "xyes"; then
+ 	ac_cv_path_PKG_CONFIG="$saved_ac_cv_path_PKG_CONFIG"
+ fi
+ 
++PKG_CHECK_MODULES([libqb], [libqb])
++
+ # checks for libnozzle
+ if test "x$enable_libnozzle" = xyes; then
+ 	if `echo $host_os | grep -q linux`; then
+@@ -294,8 +296,6 @@ if test "x$enable_kronosnetd" = xyes; then
+ 				       [AC_SUBST([pam_misc_LIBS], [-lpam_misc])],
+ 				       [AC_MSG_ERROR([Unable to find LinuxPAM MISC devel files])])])
+ 
+-	PKG_CHECK_MODULES([libqb], [libqb])
+-
+ 	AC_CHECK_LIB([qb], [qb_log_thread_priority_set],
+ 		     [have_qb_log_thread_priority_set="yes"],
+ 		     [have_qb_log_thread_priority_set="no"])
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 28b0ea20..6c0b6c5d 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -49,10 +49,10 @@ URL: https://kronosnet.org
+ Source0: https://kronosnet.org/releases/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz
+ 
+ # Build dependencies
+-BuildRequires: gcc
++BuildRequires: gcc libqb-devel
+ # required to build man pages
+ %if %{with buildman}
+-BuildRequires: libqb-devel libxml2-devel doxygen
++BuildRequires: libxml2-devel doxygen
+ %endif
+ %if %{with sctp}
+ BuildRequires: lksctp-tools-devel
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index f9ba25db..1be2bee8 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -87,7 +87,7 @@ lib_LTLIBRARIES		= libknet.la
+ 
+ libknet_la_SOURCES	= $(sources)
+ 
+-libknet_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS)
++libknet_la_CFLAGS	= $(AM_CFLAGS) $(libqb_CFLAGS) $(PTHREAD_CFLAGS)
+ 
+ EXTRA_libknet_la_DEPENDENCIES	= $(SYMFILE)
+ 
+diff --git a/libknet/internals.h b/libknet/internals.h
+index e2f882b1..af0d50c3 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -16,6 +16,7 @@
+ 
+ #include <pthread.h>
+ #include <stddef.h>
++#include <qb/qblist.h>
+ #include "libknet.h"
+ #include "onwire.h"
+ #include "compat.h"
+@@ -409,173 +410,4 @@ struct pretty_names {
+ 	uint8_t val;
+ };
+ 
+-/**
+- * This is a kernel style list implementation.
+- *
+- * @author Steven Dake <sdake@redhat.com>
+- */
+-
+-struct knet_list_head {
+-	struct knet_list_head *next;
+-	struct knet_list_head *prev;
+-};
+-
+-/**
+- * @def KNET_LIST_DECLARE()
+- * Declare and initialize a list head.
+- */
+-#define KNET_LIST_DECLARE(name) \
+-    struct knet_list_head name = { &(name), &(name) }
+-
+-#define KNET_INIT_LIST_HEAD(ptr) do { \
+-	(ptr)->next = (ptr); (ptr)->prev = (ptr); \
+-} while (0)
+-
+-/**
+- * Initialize the list entry.
+- *
+- * Points next and prev pointers to head.
+- * @param head pointer to the list head
+- */
+-static inline void knet_list_init(struct knet_list_head *head)
+-{
+-	head->next = head;
+-	head->prev = head;
+-}
+-
+-/**
+- * Add this element to the list.
+- *
+- * @param element the new element to insert.
+- * @param head pointer to the list head
+- */
+-static inline void knet_list_add(struct knet_list_head *element,
+-			       struct knet_list_head *head)
+-{
+-	head->next->prev = element;
+-	element->next = head->next;
+-	element->prev = head;
+-	head->next = element;
+-}
+-
+-/**
+- * Add to the list (but at the end of the list).
+- *
+- * @param element pointer to the element to add
+- * @param head pointer to the list head
+- * @see knet_list_add()
+- */
+-static inline void knet_list_add_tail(struct knet_list_head *element,
+-				    struct knet_list_head *head)
+-{
+-	head->prev->next = element;
+-	element->next = head;
+-	element->prev = head->prev;
+-	head->prev = element;
+-}
+-
+-/**
+- * Delete an entry from the list.
+- *
+- * @param _remove the list item to remove
+- */
+-static inline void knet_list_del(struct knet_list_head *_remove)
+-{
+-	_remove->next->prev = _remove->prev;
+-	_remove->prev->next = _remove->next;
+-}
+-
+-/**
+- * Replace old entry by new one
+- * @param old: the element to be replaced
+- * @param new: the new element to insert
+- */
+-static inline void knet_list_replace(struct knet_list_head *old,
+-		struct knet_list_head *new)
+-{
+-	new->next = old->next;
+-	new->next->prev = new;
+-	new->prev = old->prev;
+-	new->prev->next = new;
+-}
+-
+-/**
+- * Tests whether list is the last entry in list head
+- * @param list: the entry to test
+- * @param head: the head of the list
+- * @return boolean true/false
+- */
+-static inline int knet_list_is_last(const struct knet_list_head *list,
+-		const struct knet_list_head *head)
+-{
+-	return list->next == head;
+-}
+-
+-/**
+- * A quick test to see if the list is empty (pointing to it's self).
+- * @param head pointer to the list head
+- * @return boolean true/false
+- */
+-static inline int32_t knet_list_empty(const struct knet_list_head *head)
+-{
+-	return head->next == head;
+-}
+-
+-
+-/**
+- * Get the struct for this entry
+- * @param ptr:	the &struct list_head pointer.
+- * @param type:	the type of the struct this is embedded in.
+- * @param member:	the name of the list_struct within the struct.
+- */
+-#define knet_list_entry(ptr,type,member) ({		\
+-	((type *)((char*)ptr - offsetof(type, member))); })
+-
+-/**
+- * Get the first element from a list
+- * @param ptr:	the &struct list_head pointer.
+- * @param type:	the type of the struct this is embedded in.
+- * @param member:	the name of the list_struct within the struct.
+- */
+-#define knet_list_first_entry(ptr, type, member) \
+-	knet_list_entry((ptr)->next, type, member)
+-
+-/**
+- * Iterate over a list
+- * @param pos:	the &struct list_head to use as a loop counter.
+- * @param head:	the head for your list.
+- */
+-#define knet_list_for_each(pos, head) \
+-	for (pos = (head)->next; pos != (head); pos = pos->next)
+-
+-/**
+- * Iterate over a list backwards
+- * @param pos:	the &struct list_head to use as a loop counter.
+- * @param head:	the head for your list.
+- */
+-#define knet_list_for_each_reverse(pos, head) \
+-	for (pos = (head)->prev; pos != (head); pos = pos->prev)
+-
+-/**
+- * Iterate over a list safe against removal of list entry
+- * @param pos:	the &struct list_head to use as a loop counter.
+- * @param n:		another &struct list_head to use as temporary storage
+- * @param head:	the head for your list.
+- */
+-#define knet_list_for_each_safe(pos, n, head) \
+-	for (pos = (head)->next, n = pos->next; pos != (head); \
+-		pos = n, n = pos->next)
+-
+-/**
+- * Iterate over list of given type
+- * @param pos:	the type * to use as a loop counter.
+- * @param head:	the head for your list.
+- * @param member:	the name of the list_struct within the struct.
+- */
+-#define knet_list_for_each_entry(pos, head, member)			\
+-	for (pos = knet_list_entry((head)->next, typeof(*pos), member);	\
+-	     &pos->member != (head);					\
+-	     pos = knet_list_entry(pos->member.next, typeof(*pos), member))
+-
+-
+ #endif
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 667d80cf..dc208ba2 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -33,8 +33,8 @@
+ #include "transport_sctp.h"
+ 
+ typedef struct sctp_handle_info {
+-	struct knet_list_head listen_links_list;
+-	struct knet_list_head connect_links_list;
++	struct qb_list_head listen_links_list;
++	struct qb_list_head connect_links_list;
+ 	int connect_epollfd;
+ 	int connectsockfd[2];
+ 	int listen_epollfd;
+@@ -59,7 +59,7 @@ typedef struct sctp_handle_info {
+ #define MAX_ACCEPTED_SOCKS 256
+ 
+ typedef struct sctp_listen_link_info {
+-	struct knet_list_head list;
++	struct qb_list_head list;
+ 	int listen_sock;
+ 	int accepted_socks[MAX_ACCEPTED_SOCKS];
+ 	struct sockaddr_storage src_address;
+@@ -75,7 +75,7 @@ typedef struct sctp_accepted_link_info {
+ } sctp_accepted_link_info_t ;
+ 
+ typedef struct sctp_connect_link_info {
+-	struct knet_list_head list;
++	struct qb_list_head list;
+ 	sctp_listen_link_info_t *listener;
+ 	struct knet_link *link;
+ 	struct sockaddr_storage dst_address;
+@@ -977,7 +977,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	/*
+ 	 * Only allocate a new listener if src address is different
+ 	 */
+-	knet_list_for_each_entry(info, &handle_info->listen_links_list, list) {
++	qb_list_for_each_entry(info, &handle_info->listen_links_list, list) {
+ 		if (memcmp(&info->src_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
+ 			if ((check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP, -1,
+ 				       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+@@ -1059,7 +1059,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	info->on_listener_epoll = 1;
+ 
+ 	info->listen_sock = listen_sock;
+-	knet_list_add(&info->list, &handle_info->listen_links_list);
++	qb_list_add(&info->list, &handle_info->listen_links_list);
+ 
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Listening on fd %d for %s:%s", listen_sock, kn_link->status.src_ipaddr, kn_link->status.src_port);
+ 
+@@ -1169,7 +1169,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		}
+ 	}
+ 
+-	knet_list_del(&info->list);
++	qb_list_del(&info->list);
+ 	free(info);
+ 	this_link_info->listener = NULL;
+ 
+@@ -1216,7 +1216,7 @@ int sctp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_li
+ 		kn_link->outsock = info->connect_sock;
+ 	}
+ 
+-	knet_list_add(&info->list, &handle_info->connect_links_list);
++	qb_list_add(&info->list, &handle_info->connect_links_list);
+ 
+ exit_error:
+ 	if (err) {
+@@ -1271,7 +1271,7 @@ int sctp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_
+ 		goto exit_error;
+ 	}
+ 
+-	knet_list_del(&info->list);
++	qb_list_del(&info->list);
+ 
+ 	free(info);
+ 	kn_link->transport_link = NULL;
+@@ -1305,10 +1305,10 @@ int sctp_transport_free(knet_handle_t knet_h)
+ 	/*
+ 	 * keep it here while we debug list usage and such
+ 	 */
+-	if (!knet_list_empty(&handle_info->listen_links_list)) {
++	if (!qb_list_empty(&handle_info->listen_links_list)) {
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Internal error. listen links list is not empty");
+ 	}
+-	if (!knet_list_empty(&handle_info->connect_links_list)) {
++	if (!qb_list_empty(&handle_info->connect_links_list)) {
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Internal error. connect links list is not empty");
+ 	}
+ 
+@@ -1441,8 +1441,8 @@ int sctp_transport_init(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
+-	knet_list_init(&handle_info->listen_links_list);
+-	knet_list_init(&handle_info->connect_links_list);
++	qb_list_init(&handle_info->listen_links_list);
++	qb_list_init(&handle_info->connect_links_list);
+ 
+ 	handle_info->listen_epollfd = epoll_create(KNET_EPOLL_MAX_EVENTS + 1);
+ 	if (handle_info->listen_epollfd < 0) {
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 2b3e4327..17f53986 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -33,11 +33,11 @@
+ #include "threads_common.h"
+ 
+ typedef struct udp_handle_info {
+-	struct knet_list_head links_list;
++	struct qb_list_head links_list;
+ } udp_handle_info_t;
+ 
+ typedef struct udp_link_info {
+-	struct knet_list_head list;
++	struct qb_list_head list;
+ 	struct sockaddr_storage local_address;
+ 	int socket_fd;
+ 	int on_epoll;
+@@ -57,7 +57,7 @@ int udp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_lin
+ 	/*
+ 	 * Only allocate a new link if the local address is different
+ 	 */
+-	knet_list_for_each_entry(info, &handle_info->links_list, list) {
++	qb_list_for_each_entry(info, &handle_info->links_list, list) {
+ 		if (memcmp(&info->local_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
+ 			log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Re-using existing UDP socket for new link");
+ 			kn_link->outsock = info->socket_fd;
+@@ -152,7 +152,7 @@ int udp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_lin
+ 
+ 	memmove(&info->local_address, &kn_link->src_addr, sizeof(struct sockaddr_storage));
+ 	info->socket_fd = sock;
+-	knet_list_add(&info->list, &handle_info->links_list);
++	qb_list_add(&info->list, &handle_info->links_list);
+ 
+ 	kn_link->outsock = sock;
+ 	kn_link->transport_link = info;
+@@ -226,7 +226,7 @@ int udp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_l
+ 	}
+ 
+ 	close(info->socket_fd);
+-	knet_list_del(&info->list);
++	qb_list_del(&info->list);
+ 	free(kn_link->transport_link);
+ 
+ exit_error:
+@@ -248,7 +248,7 @@ int udp_transport_free(knet_handle_t knet_h)
+ 	/*
+ 	 * keep it here while we debug list usage and such
+ 	 */
+-	if (!knet_list_empty(&handle_info->links_list)) {
++	if (!qb_list_empty(&handle_info->links_list)) {
+ 		log_err(knet_h, KNET_SUB_TRANSP_UDP, "Internal error. handle list is not empty");
+ 		return -1;
+ 	}
+@@ -278,7 +278,7 @@ int udp_transport_init(knet_handle_t knet_h)
+ 
+ 	knet_h->transports[KNET_TRANSPORT_UDP] = handle_info;
+ 
+-	knet_list_init(&handle_info->links_list);
++	qb_list_init(&handle_info->links_list);
+ 
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0360-lists-add-missing-build-CFLAGS-for-test-suite.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0360-lists-add-missing-build-CFLAGS-for-test-suite.patch
new file mode 100644
index 000000000..093b832ef
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0360-lists-add-missing-build-CFLAGS-for-test-suite.patch
@@ -0,0 +1,23 @@ 
+From 2f7770266a25412e1f115255e989b6b6d12b59cd Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 17 Mar 2020 05:37:02 +0100
+Subject: [PATCH] [lists] add missing build CFLAGS for test suite
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 37f5935f..86312072 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -16,7 +16,7 @@ EXTRA_DIST		= \
+ 			  api-check.mk
+ 
+ AM_CPPFLAGS		= -I$(top_srcdir)/libknet
+-AM_CFLAGS		+= $(PTHREAD_CFLAGS)
++AM_CFLAGS		+= $(PTHREAD_CFLAGS) $(libqb_CFLAGS)
+ LIBS			= $(top_builddir)/libknet/libknet.la \
+ 			  $(PTHREAD_LIBS) $(dl_LIBS)
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0361-build-make-sure-to-use-correct-libqb-include-files-a.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0361-build-make-sure-to-use-correct-libqb-include-files-a.patch
new file mode 100644
index 000000000..6112d1613
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0361-build-make-sure-to-use-correct-libqb-include-files-a.patch
@@ -0,0 +1,25 @@ 
+From af6c7cfd3791d1a64c451faf5a3b88ecc93a2ccd Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 18 Mar 2020 06:52:40 +0100
+Subject: [PATCH] [build] make sure to use correct libqb include files across
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 1be2bee8..3550a86a 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -87,7 +87,9 @@ lib_LTLIBRARIES		= libknet.la
+ 
+ libknet_la_SOURCES	= $(sources)
+ 
+-libknet_la_CFLAGS	= $(AM_CFLAGS) $(libqb_CFLAGS) $(PTHREAD_CFLAGS)
++AM_CFLAGS		+= $(libqb_CFLAGS)
++
++libknet_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS)
+ 
+ EXTRA_libknet_la_DEPENDENCIES	= $(SYMFILE)
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0362-man-use-libqb-version-of-doxygen2man-when-available.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0362-man-use-libqb-version-of-doxygen2man-when-available.patch
new file mode 100644
index 000000000..13352a9db
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0362-man-use-libqb-version-of-doxygen2man-when-available.patch
@@ -0,0 +1,140 @@ 
+From e9c9907bf9b6f7a383149aab58225fb94e221906 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 24 Mar 2020 06:28:32 +0100
+Subject: [PATCH] [man] use libqb version of doxygen2man when available
+
+and add pkg_check_var compat macro
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac        | 46 ++++++++++++++++++++++++++++++---------------
+ m4/pkg_check_var.m4 | 14 ++++++++++++++
+ man/Makefile.am     |  8 +++++---
+ 3 files changed, 50 insertions(+), 18 deletions(-)
+ create mode 100644 m4/pkg_check_var.m4
+
+diff --git a/configure.ac b/configure.ac
+index 0a8477fa..56124540 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -251,28 +251,44 @@ AC_TYPE_INT16_T
+ AC_TYPE_INT32_T
+ AC_TYPE_INT64_T
+ 
++PKG_CHECK_MODULES([libqb], [libqb])
++
+ if test "x$enable_man" = "xyes"; then
+ 	AC_ARG_VAR([DOXYGEN], [override doxygen executable])
+ 	AC_CHECK_PROGS([DOXYGEN], [doxygen], [no])
+ 	if test "x$DOXYGEN" = xno; then
+ 		AC_MSG_ERROR(["Doxygen command not found"])
+ 	fi
+-	# required by doxyxml to build man pages dynamically
+-	# Don't let AC_PROC_CC (invoked by AX_PROG_CC_FOR_BUILD) replace
+-	# undefined CFLAGS_FOR_BUILD with -g -O2, overriding our special OPT_CFLAGS.
+-	: ${CFLAGS_FOR_BUILD=""}
+-	AX_PROG_CC_FOR_BUILD
+-	saved_PKG_CONFIG="$PKG_CONFIG"
+-	saved_ac_cv_path_PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
+-	unset PKG_CONFIG ac_cv_path_PKG_CONFIG
+-	AC_PATH_PROG([PKG_CONFIG], [pkg-config])
+-	PKG_CHECK_MODULES([libqb_BUILD], [libqb])
+-	PKG_CHECK_MODULES([libxml_BUILD], [libxml-2.0])
+-	PKG_CONFIG="$saved_PKG_CONFIG"
+-	ac_cv_path_PKG_CONFIG="$saved_ac_cv_path_PKG_CONFIG"
+-fi
+ 
+-PKG_CHECK_MODULES([libqb], [libqb])
++	AC_ARG_VAR([DOXYGEN2MAN], [override doxygen2man executable])
++	if test "x$cross_compiling" = "xno"; then
++		PKG_CHECK_VAR([libqb_PREFIX], [libqb], [prefix])
++		AC_PATH_PROG([DOXYGEN2MAN], [doxygen2man], [no], [$libqb_PREFIX/bin$PATH_SEPARATOR$PATH])
++	fi
++	if test "x$DOXYGEN2MAN" = "xno"; then
++		# required by doxyxml to build man pages dynamically
++		# Don't let AC_PROC_CC (invoked by AX_PROG_CC_FOR_BUILD) replace
++		# undefined CFLAGS_FOR_BUILD with -g -O2, overriding our special OPT_CFLAGS.
++		: ${CFLAGS_FOR_BUILD=""}
++		AX_PROG_CC_FOR_BUILD
++		saved_PKG_CONFIG="$PKG_CONFIG"
++		saved_ac_cv_path_PKG_CONFIG="$ac_cv_path_PKG_CONFIG"
++		unset PKG_CONFIG ac_cv_path_PKG_CONFIG
++		AC_PATH_PROG([PKG_CONFIG], [pkg-config])
++		PKG_CHECK_MODULES([libqb_BUILD], [libqb])
++		PKG_CHECK_VAR([libqb_BUILD_PREFIX], [libqb], [prefix])
++		AC_PATH_PROG([DOXYGEN2MAN], [doxygen2man], [no], [$libqb_BUILD_PREFIX/bin$PATH_SEPARATOR$PATH])
++		if test "x$DOXYGEN2MAN" = "xno"; then
++			PKG_CHECK_MODULES([libxml_BUILD], [libxml-2.0])
++			DOXYGEN2MAN="\${abs_top_builddir}/man/doxyxml"
++			build_doxy=yes
++		fi
++		PKG_CONFIG="$saved_PKG_CONFIG"
++		ac_cv_path_PKG_CONFIG="$saved_ac_cv_path_PKG_CONFIG"
++	fi
++	AC_SUBST([DOXYGEN2MAN])
++	AM_CONDITIONAL([BUILD_DOXYXML], [test "x$build_doxy" = "xyes"])
++fi
+ 
+ # checks for libnozzle
+ if test "x$enable_libnozzle" = xyes; then
+diff --git a/m4/pkg_check_var.m4 b/m4/pkg_check_var.m4
+new file mode 100644
+index 00000000..ae1bf222
+--- /dev/null
++++ b/m4/pkg_check_var.m4
+@@ -0,0 +1,14 @@
++# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
++# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
++# -------------------------------------------
++# Retrieves the value of the pkg-config variable for the given module.
++
++m4_ifndef([PKG_CHECK_VAR],
++	  [AC_DEFUN([PKG_CHECK_VAR],
++		    [AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
++		     AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
++		     _PKG_CONFIG([$1], [variable="][$3]["], [$2])
++		     AS_VAR_COPY([$1], [pkg_cv_][$1])
++		     AS_VAR_IF([$1], [""], [$5], [$4])dnl
++		    ])# PKG_CHECK_VAR
++])
+diff --git a/man/Makefile.am b/man/Makefile.am
+index b4454af5..f813b97d 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -30,11 +30,13 @@ if BUILD_KRONOSNETD
+ man8_MANS	= kronosnetd.8 knet-keygen.8
+ endif
+ 
++if BUILD_DOXYXML
+ noinst_PROGRAMS	= doxyxml
+ 
+ doxyxml_SOURCES = doxyxml.c
+ doxyxml_CFLAGS = $(AM_CFLAGS) $(libqb_BUILD_CFLAGS) $(libxml_BUILD_CFLAGS)
+ doxyxml_LDADD = $(libqb_BUILD_LIBS) $(libxml_BUILD_LIBS)
++endif
+ 
+ knet_man3_MANS = \
+ 		knet_addrtostr.3 \
+@@ -130,14 +132,14 @@ $(MANS): doxyfile-knet.stamp doxyfile-nozzle.stamp
+ 
+ doxyfile-knet.stamp: $(noinst_PROGRAMS) Doxyfile-knet $(top_srcdir)/libknet/libknet.h
+ 	$(DOXYGEN) Doxyfile-knet
+-	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
++	$(DOXYGEN2MAN) -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
+ 	touch doxyfile-knet.stamp
+ 
+ doxyfile-nozzle.stamp: $(noinst_PROGRAMS) Doxyfile-nozzle $(top_srcdir)/libnozzle/libnozzle.h
+ if BUILD_LIBNOZZLE
+ 	$(DOXYGEN) Doxyfile-nozzle
+-	$(builddir)/doxyxml -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
++	$(DOXYGEN2MAN) -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
+ endif
+ 	touch doxyfile-nozzle.stamp
+@@ -157,4 +159,4 @@ check-api-to-man-page-coverage-libknet:
+ endif
+ 
+ clean-local:
+-	rm -rf doxyfile*.stamp xml* *.3
++	rm -rf doxyxml doxyfile*.stamp xml* *.3
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0363-sctp-make-sure-outgoing-connections-are-bound-to-a-s.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0363-sctp-make-sure-outgoing-connections-are-bound-to-a-s.patch
new file mode 100644
index 000000000..099ed8400
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0363-sctp-make-sure-outgoing-connections-are-bound-to-a-s.patch
@@ -0,0 +1,54 @@ 
+From 50e5702d9d52d569158cc641d3895787c31f03fe Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Apr 2020 06:57:29 +0200
+Subject: [PATCH] [sctp] make sure outgoing connections are bound to a specific
+ IP address
+
+https://github.com/kronosnet/kronosnet/issues/300
+
+if 2 or more nodes in a knet network have a duplicate IP address,
+for example a virtbr interface with default config, sctp
+will fail to build the associations and abort all connections.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index dc208ba2..528cf563 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -222,6 +222,7 @@ static int _create_connect_socket(knet_handle_t knet_h, struct knet_link *kn_lin
+ 	struct epoll_event ev;
+ 	sctp_connect_link_info_t *info = kn_link->transport_link;
+ 	int connect_sock;
++	struct sockaddr_storage connect_addr;
+ 
+ 	connect_sock = socket(kn_link->dst_addr.ss_family, SOCK_STREAM, IPPROTO_SCTP);
+ 	if (connect_sock < 0) {
+@@ -238,6 +239,24 @@ static int _create_connect_socket(knet_handle_t knet_h, struct knet_link *kn_lin
+ 		goto exit_error;
+ 	}
+ 
++	memset(&connect_addr, 0, sizeof(struct sockaddr_storage));
++	if (knet_strtoaddr(kn_link->status.src_ipaddr, "0", &connect_addr, sockaddr_len(&connect_addr)) < 0) {
++		savederrno = errno;
++		err = -1;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to resolve connecting socket: %s",
++			strerror(savederrno));
++		goto exit_error;
++
++	}
++
++	if (bind(connect_sock, (struct sockaddr *)&connect_addr, sockaddr_len(&connect_addr)) < 0) {
++		savederrno = errno;
++		err = -1;
++		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to bind connecting socket: %s",
++			strerror(savederrno));
++		goto exit_error;
++	}
++
+ 	if (_set_fd_tracker(knet_h, connect_sock, KNET_TRANSPORT_SCTP, SCTP_CONNECT_LINK_INFO, info) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0364-links-fix-spacing.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0364-links-fix-spacing.patch
new file mode 100644
index 000000000..5474e8c1a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0364-links-fix-spacing.patch
@@ -0,0 +1,23 @@ 
+From 9951d57ba2355d2fb4714f7878f72941633f5aa3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 19 Apr 2020 07:07:05 +0200
+Subject: [PATCH] [links] fix spacing
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl_ip.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index b77eaf43..0f269ef1 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -148,7 +148,7 @@ int ipcheck_validate(void *fd_tracker_match_entry_head, struct sockaddr_storage
+ 	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 	int (*match_fn)(struct sockaddr_storage *checkip, struct ip_acl_match_entry *match_entry);
+ 
+-	if (checkip->ss_family == AF_INET){
++	if (checkip->ss_family == AF_INET) {
+ 		match_fn = ip_matches_v4;
+ 	} else {
+ 		match_fn = ip_matches_v6;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0365-netutils-move-sockaddr_len-definition-where-it-belon.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0365-netutils-move-sockaddr_len-definition-where-it-belon.patch
new file mode 100644
index 000000000..0cff7782a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0365-netutils-move-sockaddr_len-definition-where-it-belon.patch
@@ -0,0 +1,61 @@ 
+From d6cd5bf77ca33f31cb7f8e8fc08111e1307b9b30 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 19 Apr 2020 07:08:19 +0200
+Subject: [PATCH] [netutils] move sockaddr_len definition where it belongs
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h      | 2 --
+ libknet/netutils.h       | 2 +-
+ libknet/transport_sctp.c | 1 +
+ libknet/transport_udp.c  | 1 +
+ 4 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index af0d50c3..c48f13d8 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -403,8 +403,6 @@ typedef struct knet_transport_ops {
+ 	int (*transport_rx_is_data)(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ } knet_transport_ops_t;
+ 
+-socklen_t sockaddr_len(const struct sockaddr_storage *ss);
+-
+ struct pretty_names {
+ 	const char *name;
+ 	uint8_t val;
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index e668ada6..ee10b2b1 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -15,5 +15,5 @@
+ int cmpaddr(const struct sockaddr_storage *ss1, socklen_t sslen1, const struct sockaddr_storage *ss2, socklen_t sslen2);
+ int cpyaddrport(struct sockaddr_storage *dst, const struct sockaddr_storage *src);
+ 
+-socklen_t knet_sockaddr_len(const struct sockaddr_storage *ss);
++socklen_t sockaddr_len(const struct sockaddr_storage *ss);
+ #endif
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 528cf563..7e95cf1b 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -23,6 +23,7 @@
+ #include "links_acl.h"
+ #include "links_acl_ip.h"
+ #include "logging.h"
++#include "netutils.h"
+ #include "common.h"
+ #include "transport_common.h"
+ #include "transports.h"
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 17f53986..fbbb04c0 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -27,6 +27,7 @@
+ #include "link.h"
+ #include "logging.h"
+ #include "common.h"
++#include "netutils.h"
+ #include "transport_common.h"
+ #include "transport_udp.h"
+ #include "transports.h"
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0366-sctp-fix-ifup-ifdown-handling-for-connected-sockets.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0366-sctp-fix-ifup-ifdown-handling-for-connected-sockets.patch
new file mode 100644
index 000000000..85ab26c8c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0366-sctp-fix-ifup-ifdown-handling-for-connected-sockets.patch
@@ -0,0 +1,25 @@ 
+From ee26a326d13065a912c8cc1f6cd7ea9f8310a415 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 20 Apr 2020 10:11:02 +0200
+Subject: [PATCH] [sctp] fix ifup/ifdown handling for connected sockets
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 7e95cf1b..49c5dcaa 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -531,6 +531,10 @@ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsg
+ 				switch (sac->sac_state) {
+ 					case SCTP_COMM_LOST:
+ 						log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "[event] sctp assoc change socket %d: comm_lost", sockfd);
++						if (knet_h->knet_transport_fd_tracker[sockfd].data_type == SCTP_CONNECT_LINK_INFO) {
++							connect_info->close_sock = 1;
++							connect_info->link->transport_connected = 0;
++						}
+ 						sctp_transport_rx_sock_error(knet_h, sockfd, 2, 0);
+ 						return KNET_TRANSPORT_RX_OOB_DATA_STOP;
+ 						break;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0367-transport-notify-transports-that-a-link-is-down.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0367-transport-notify-transports-that-a-link-is-down.patch
new file mode 100644
index 000000000..4a9c18823
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0367-transport-notify-transports-that-a-link-is-down.patch
@@ -0,0 +1,189 @@ 
+From e75e00de82e46db97a994fd9abff4fede72e43be Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 22 Apr 2020 12:15:02 +0200
+Subject: [PATCH] [transport] notify transports that a link is down
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h          |  7 +++++++
+ libknet/links.c              |  7 ++++++-
+ libknet/transport_loopback.c |  5 +++++
+ libknet/transport_loopback.h |  1 +
+ libknet/transport_sctp.c     | 16 ++++++++++++++++
+ libknet/transport_sctp.h     |  1 +
+ libknet/transport_udp.c      |  5 +++++
+ libknet/transport_udp.h      |  1 +
+ libknet/transports.c         | 13 +++++++++----
+ libknet/transports.h         |  1 +
+ 10 files changed, 52 insertions(+), 5 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index c48f13d8..b763d4a9 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -401,6 +401,13 @@ typedef struct knet_transport_ops {
+  * and fd_tracker read lock (from RX thread)
+  */
+ 	int (*transport_rx_is_data)(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
++
++/*
++ * this function is called by links.c when a link down event is recorded
++ * to notify the transport that packets are not going through, and give
++ * transport the opportunity to take actions.
++ */
++	int (*transport_link_is_down)(knet_handle_t knet_h, struct knet_link *link);
+ } knet_transport_ops_t;
+ 
+ struct pretty_names {
+diff --git a/libknet/links.c b/libknet/links.c
+index d08065bd..a127144a 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -39,8 +39,13 @@ int _link_updown(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 	_host_dstcache_update_async(knet_h, knet_h->host_index[host_id]);
+ 
+ 	if ((link->status.dynconnected) &&
+-	    (!link->status.connected))
++	    (!link->status.connected)) {
+ 		link->status.dynconnected = 0;
++	}
++
++	if (!connected) {
++		transport_link_is_down(knet_h, link);
++	}
+ 
+ 	if (lock_stats) {
+ 		savederrno = pthread_mutex_lock(&link->link_stats_mutex);
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index b36fed20..dfd6384d 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -78,3 +78,8 @@ int loopback_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *k
+ {
+ 	return 0;
+ }
++
++int loopback_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	return 0;
++}
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index 0cb7bb37..636034bb 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -24,5 +24,6 @@ int loopback_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_
+ int loopback_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int loopback_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+ int loopback_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
++int loopback_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 49c5dcaa..17e2f542 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -590,6 +590,22 @@ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsg
+ 	return KNET_TRANSPORT_RX_OOB_DATA_CONTINUE;
+ }
+ 
++int sctp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	sctp_handle_info_t *handle_info = knet_h->transports[KNET_TRANSPORT_SCTP];
++	sctp_connect_link_info_t *info = kn_link->transport_link;
++
++	kn_link->transport_connected = 0;
++	info->close_sock = 1;
++
++	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Notifying connect thread that sockfd %d received a link down event", info->connect_sock);
++	if (sendto(handle_info->connectsockfd[1], &info->connect_sock, sizeof(int), MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0) != sizeof(int)) {
++		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to notify connect thread: %s", strerror(errno));
++	}
++
++	return 0;
++}
++
+ /*
+  * connect / outgoing socket management thread
+  */
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index bbf7a789..3cd9740d 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -32,6 +32,7 @@ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int sctp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+ int sctp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
++int sctp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+ 
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index fbbb04c0..fe6c0968 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -438,3 +438,8 @@ int udp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_lin
+ {
+ 	return kn_link->outsock;
+ }
++
++int udp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	return 0;
++}
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index 8e3ea5f6..e2aa2dcd 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -24,5 +24,6 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int udp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+ int udp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
++int udp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transports.c b/libknet/transports.c
+index e6457238..1ec0aafc 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -27,14 +27,14 @@
+ #include "transport_sctp.h"
+ #include "threads_common.h"
+ 
+-#define empty_module 0, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
++#define empty_module 0, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+-	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data },
++	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data, loopback_transport_link_is_down },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data, udp_transport_link_is_down },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+-				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data },
++				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data, sctp_transport_link_is_down },
+ #else
+ empty_module
+ #endif
+@@ -138,6 +138,11 @@ int transport_get_connection_oriented(knet_handle_t knet_h, uint8_t transport)
+ 	return transport_modules_cmd[transport].transport_is_connection_oriented;
+ }
+ 
++int transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
++{
++	return transport_modules_cmd[kn_link->transport].transport_link_is_down(knet_h, kn_link);
++}
++
+ /*
+  * public api
+  */
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 763fce37..51063864 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -29,5 +29,6 @@ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, st
+ int transport_get_proto(knet_handle_t knet_h, uint8_t transport);
+ int transport_get_acl_type(knet_handle_t knet_h, uint8_t transport);
+ int transport_get_connection_oriented(knet_handle_t knet_h, uint8_t transport);
++int transport_link_is_down(knet_handle_t knet_h, struct knet_link *link);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0368-Always-define-the-Automake-conditional.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0368-Always-define-the-Automake-conditional.patch
new file mode 100644
index 000000000..4c6ea6dfe
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0368-Always-define-the-Automake-conditional.patch
@@ -0,0 +1,27 @@ 
+From 4465818ecd079f32d9a3e6968489edb372936788 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Tue, 28 Apr 2020 22:08:20 +0200
+Subject: [PATCH] Always define the Automake conditional
+
+Otherwise ./configure --disable-man fails with
+
+configure: error: conditional "BUILD_DOXYXML" was never defined.
+Usually this means the macro was only invoked conditionally.
+---
+ configure.ac | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/configure.ac b/configure.ac
+index 56124540..88695c77 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -287,8 +287,8 @@ if test "x$enable_man" = "xyes"; then
+ 		ac_cv_path_PKG_CONFIG="$saved_ac_cv_path_PKG_CONFIG"
+ 	fi
+ 	AC_SUBST([DOXYGEN2MAN])
+-	AM_CONDITIONAL([BUILD_DOXYXML], [test "x$build_doxy" = "xyes"])
+ fi
++AM_CONDITIONAL([BUILD_DOXYXML], [test "x$build_doxy" = "xyes"])
+ 
+ # checks for libnozzle
+ if test "x$enable_libnozzle" = xyes; then
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0369-tests-strip-extra-symbol-information-generated-by-ne.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0369-tests-strip-extra-symbol-information-generated-by-ne.patch
new file mode 100644
index 000000000..dde236c88
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0369-tests-strip-extra-symbol-information-generated-by-ne.patch
@@ -0,0 +1,39 @@ 
+From 213b5019aa060c56b9cba9d423b56985b4bacf6f Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 13 May 2020 14:59:16 +0200
+Subject: [PATCH] [tests] strip extra symbol information generated by new nm
+
+spotted on debian experimental
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api-test-coverage   | 2 +-
+ libnozzle/tests/api-test-coverage | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/tests/api-test-coverage b/libknet/tests/api-test-coverage
+index 2fa0edbd..4b6e223a 100755
+--- a/libknet/tests/api-test-coverage
++++ b/libknet/tests/api-test-coverage
+@@ -15,7 +15,7 @@ headerapicalls="$(grep knet_ "$srcdir"/../libknet.h | grep -v "^ \*" | grep -v ^
+ # The PowerPC64 ELFv1 ABI defines the address of a function as that of a
+ # function descriptor defined in .opd, a data (D) section.  Other ABIs
+ # use the entry address of the function itself in the text (T) section.
+-exportedapicalls="$(nm -B -D "$builddir"/../.libs/libknet.so | grep ' [DT] ' | awk '{print $3}')"
++exportedapicalls="$(nm -B -D "$builddir"/../.libs/libknet.so | grep ' [DT] ' | awk '{print $3}' | sed -e 's#@@LIBKNET##g')"
+ 
+ echo "Checking for exported symbols NOT available in header file"
+ 
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index eaea7090..e6d762d7 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -15,7 +15,7 @@ headerapicalls="$(grep nozzle_ "$srcdir"/../libnozzle.h | grep -v "^ \*" | grep
+ # The PowerPC64 ELFv1 ABI defines the address of a function as that of a
+ # function descriptor defined in .opd, a data (D) section.  Other ABIs
+ # use the entry address of the function itself in the text (T) section.
+-exportedapicalls="$(nm -B -D "$builddir"/../.libs/libnozzle.so | grep ' [DT] ' | awk '{print $3}')"
++exportedapicalls="$(nm -B -D "$builddir"/../.libs/libnozzle.so | grep ' [DT] ' | awk '{print $3}' | sed -e 's#@@LIBNOZZLE##g')"
+ 
+ echo "Checking for exported symbols NOT available in header file"
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0370-openssl-allow-use-of-deprecated-HMAC-interface-with-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0370-openssl-allow-use-of-deprecated-HMAC-interface-with-.patch
new file mode 100644
index 000000000..6844da667
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0370-openssl-allow-use-of-deprecated-HMAC-interface-with-.patch
@@ -0,0 +1,36 @@ 
+From 71a4a6be8928e50d2eba7398b7279c757d8a28df Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 10 Jun 2020 07:30:36 +0200
+Subject: [PATCH] [openssl] allow use of deprecated HMAC interface with openssl
+ 3.0
+
+Port will be done after rekey feature is complete (too much code conflict atm)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index fe3684a4..6332287d 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -9,6 +9,18 @@
+ 
+ #include "config.h"
+ 
++/*
++ * allow to build with openssl 3.0 that has deprecated
++ * use of direct access to HMAC API.
++ *
++ * knet will require some heavy rewrite to port to 3.0,
++ * but it clashes with the re-key feature branch.
++ *
++ * use path of less resistance for now, then we will
++ * port at a later stage.
++ */
++#define OPENSSL_API_COMPAT 0x1010000L
++
+ #include <string.h>
+ #include <errno.h>
+ #include <dlfcn.h>
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0371-man-sync-doxygen2man-from-libqb-master.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0371-man-sync-doxygen2man-from-libqb-master.patch
new file mode 100644
index 000000000..02c6edce7
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0371-man-sync-doxygen2man-from-libqb-master.patch
@@ -0,0 +1,925 @@ 
+From 9592a747fdea3264b968a0492968e5f74e378def Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 3 Jul 2020 10:12:47 +0200
+Subject: [PATCH] [man] sync doxygen2man from libqb master
+
+this change is not required in master branch
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/doxyxml.c | 468 ++++++++++++++++++++++++++++++++++++--------------
+ 1 file changed, 343 insertions(+), 125 deletions(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 343449c4..278c1883 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+@@ -12,7 +12,7 @@
+  * XML out from doxygen and is probably very fragile to changes in that XML
+  * schema. It probably leaks memory all over the place too.
+  *
+- * In its favour, it *does* generate man pages and should only be run very ocasionally
++ * In its favour, it *does* generate nice man pages and should only be run very ocasionally
+  */
+ 
+ #define _DEFAULT_SOURCE
+@@ -21,23 +21,22 @@
+ #define _XOPEN_SOURCE_EXTENDED
+ #include <stdlib.h>
+ #include <sys/time.h>
++#include <sys/stat.h>
+ #include <time.h>
+ #include <stdio.h>
+ #include <limits.h>
+ #include <string.h>
+ #include <getopt.h>
+ #include <errno.h>
++#include <ctype.h>
+ #include <libxml/tree.h>
+ #include <qb/qblist.h>
+ #include <qb/qbmap.h>
+ 
+-#define XML_DIR "../man/xml-knet"
+-#define XML_FILE "libknet_8h.xml"
+-
+ /*
+  * This isn't a maximum size, it just defines how long a parameter
+- * type can get before we decide it's not worth lining everything up to.
+- * it's mainly to stop function pointer types (which can get VERY long because
++ * type can get before we decide it's not worth lining everything up.
++ * It's mainly to stop function pointer types (which can get VERY long because
+  * of all *their* parameters) making everything else 'line-up' over separate lines
+  */
+ #define LINE_LENGTH 80
+@@ -45,15 +44,21 @@
+ static int print_ascii = 1;
+ static int print_man = 0;
+ static int print_params = 0;
++static int print_general = 0;
+ static int num_functions = 0;
++static int quiet=0;
+ static const char *man_section="3";
+-static const char *package_name="Kronosnet";
+-static const char *header="Kronosnet Programmer's Manual";
++static const char *package_name="Package";
++static const char *header="Programmer's Manual";
++static const char *company="Red Hat";
+ static const char *output_dir="./";
+-static const char *xml_dir = XML_DIR;
+-static const char *xml_file = XML_FILE;
++static const char *xml_dir = "./xml/";
++static const char *xml_file;
+ static const char *manpage_date = NULL;
++static const char *headerfile = NULL;
++static const char *header_prefix = "";
+ static long manpage_year = LONG_MIN;
++static long start_year = 2010;
+ static struct qb_list_head params_list;
+ static struct qb_list_head retval_list;
+ static qb_map_t *function_map;
+@@ -71,11 +76,13 @@ struct param_info {
+ struct struct_info {
+ 	enum {STRUCTINFO_STRUCT, STRUCTINFO_ENUM} kind;
+ 	char *structname;
++	char *description;
++	char *brief_description;
+ 	struct qb_list_head params_list; /* our params */
+ 	struct qb_list_head list;
+ };
+ 
+-static char *get_texttree(int *type, xmlNode *cur_node, char **returntext);
++static char *get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext);
+ static void traverse_node(xmlNode *parentnode, const char *leafname, void (do_members(xmlNode*, void*)), void *arg);
+ 
+ static void free_paraminfo(struct param_info *pi)
+@@ -120,7 +127,7 @@ static char *get_child(xmlNode *node, const char *tag)
+ 
+ 				if ((strcmp( (char*)child->name, "ref") == 0)) {
+ 					if (child->children->content) {
+-						strncat(buffer, (char *)child->children->content, sizeof(buffer)-1);
++						strncat(buffer,(char *)child->children->content, sizeof(buffer)-1);
+ 					}
+ 					refid = get_attr(child, "refid");
+ 				}
+@@ -172,10 +179,12 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
+ 	/* This is not robust, and very inflexible */
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 		for (sub_tag = this_tag->children; sub_tag; sub_tag = sub_tag->next) {
+-			if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameternamelist") == 0) {
++			if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameternamelist") == 0 &&
++				sub_tag->children->next->children) {
+ 				paramname = (char*)sub_tag->children->next->children->content;
+ 			}
+-			if (paramname && sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameterdescription") == 0) {
++			if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameterdescription") == 0 &&
++			    paramname && sub_tag->children->next->children) {
+ 				paramdesc = (char*)sub_tag->children->next->children->content;
+ 
+ 				/* Add text to the param_map */
+@@ -197,7 +206,7 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
+ 	}
+ }
+ 
+-static char *get_text(xmlNode *cur_node, char **returntext)
++static char *get_text(xmlNode *cur_node, char **returntext, char **notetext)
+ {
+ 	xmlNode *this_tag;
+ 	xmlNode *sub_tag;
+@@ -208,7 +217,6 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 		if (this_tag->type == XML_TEXT_NODE && strcmp((char *)this_tag->name, "text") == 0) {
+ 			if (not_all_whitespace((char*)this_tag->content)) {
+ 				strncat(buffer, (char*)this_tag->content, sizeof(buffer)-1);
+-				strncat(buffer, "\n", sizeof(buffer)-1);
+ 			}
+ 		}
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "emphasis") == 0) {
+@@ -220,6 +228,17 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 				strncat(buffer, "\\fR", sizeof(buffer)-1);
+ 			}
+ 		}
++
++		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "ref") == 0) {
++			if (print_man) {
++				strncat(buffer, "\\fI", sizeof(buffer)-1);
++			}
++			strncat(buffer, (char*)this_tag->children->content, sizeof(buffer)-1);
++			if (print_man) {
++				strncat(buffer, "\\fR", sizeof(buffer)-1);
++			}
++		}
++
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "itemizedlist") == 0) {
+ 			for (sub_tag = this_tag->children; sub_tag; sub_tag = sub_tag->next) {
+ 				if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "listitem") == 0) {
+@@ -234,12 +253,14 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 			char *tmp;
+ 
+ 			kind = get_attr(this_tag, "kind");
+-			tmp = get_text(this_tag->children, NULL);
++			tmp = get_text(this_tag->children, NULL, NULL);
+ 
+ 			if (returntext && strcmp(kind, "return") == 0) {
+ 				*returntext = tmp;
+ 			}
+-			free(kind);
++			if (notetext && strcmp(kind, "note") == 0) {
++				*notetext = tmp;
++			}
+ 		}
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "parameterlist") == 0) {
+@@ -250,7 +271,6 @@ static char *get_text(xmlNode *cur_node, char **returntext)
+ 			if (strcmp(kind, "retval") == 0) {
+ 				get_param_info(this_tag, &retval_list);
+ 			}
+-			free(kind);
+ 		}
+ 	}
+ 	return strdup(buffer);
+@@ -268,6 +288,41 @@ static void read_structname(xmlNode *cur_node, void *arg)
+ 	}
+ }
+ 
++static void read_structdesc(xmlNode *cur_node, void *arg)
++{
++	struct struct_info *si=arg;
++	xmlNode *this_tag;
++
++	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
++		if (strcmp((char*)this_tag->name, "detaileddescription") == 0) {
++			char *desc = get_texttree(NULL, this_tag, NULL, NULL);
++			if (desc) {
++				si->description = strdup((char*)desc);
++			}
++		}
++		if (strcmp((char*)this_tag->name, "briefdescription") == 0) {
++			char *brief = get_texttree(NULL, this_tag, NULL, NULL);
++			if (brief) {
++				si->brief_description = brief;
++			}
++		}
++	}
++}
++
++
++static void read_headername(xmlNode *cur_node, void *arg)
++{
++	char **h_file = arg;
++	xmlNode *this_tag;
++
++	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
++		if (strcmp((char*)this_tag->name, "compoundname") == 0) {
++			*h_file = strdup((char*)this_tag->children->content);
++		}
++	}
++}
++
++
+ /* Called from traverse_node() */
+ static void read_struct(xmlNode *cur_node, void *arg)
+ {
+@@ -281,10 +336,14 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ 
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 		if (strcmp((char*)this_tag->name, "type") == 0) {
+-			type = (char*)this_tag->children->content ;
++			type = (char*)this_tag->children->content;
++			/* If type is NULL then look for a ref - it's probably an external struct or typedef */
++			if (type == NULL) {
++				type = get_child(this_tag, "ref");
++			}
+ 		}
+ 		if (strcmp((char*)this_tag->name, "name") == 0) {
+-			name = (char*)this_tag->children->content ;
++			name = (char*)this_tag->children->content;
+ 		}
+ 		if (this_tag->children && strcmp((char*)this_tag->name, "argsstring") == 0) {
+ 			args = (char*)this_tag->children->content;
+@@ -303,16 +362,22 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ 	}
+ }
+ 
+-static int read_structure_from_xml(char *refid, char *name)
++static int read_structure_from_xml(const char *refid, const char *name)
+ {
+ 	char fname[PATH_MAX];
+ 	xmlNode *rootdoc;
+ 	xmlDocPtr doc;
+ 	struct struct_info *si;
++	struct stat st;
+ 	int ret = -1;
+ 
+ 	snprintf(fname, sizeof(fname),  "%s/%s.xml", xml_dir, refid);
+ 
++	/* Don't call into libxml if the file does not exist - saves unwanted error messages */
++	if (stat(fname, &st) == -1) {
++		return -1;
++	}
++
+ 	doc = xmlParseFile(fname);
+ 	if (doc == NULL) {
+ 		fprintf(stderr, "Error: unable to open xml file for %s\n", refid);
+@@ -327,9 +392,11 @@ static int read_structure_from_xml(char *refid, char *name)
+ 
+ 	si = malloc(sizeof(struct struct_info));
+ 	if (si) {
++		memset(si, 0, sizeof(*si));
+ 		si->kind = STRUCTINFO_STRUCT;
+ 		qb_list_init(&si->params_list);
+ 		traverse_node(rootdoc, "memberdef", read_struct, si);
++		traverse_node(rootdoc, "compounddef", read_structdesc, si);
+ 		traverse_node(rootdoc, "compounddef", read_structname, si);
+ 		ret = 0;
+ 		qb_map_put(structures_map, refid, si);
+@@ -339,22 +406,40 @@ static int read_structure_from_xml(char *refid, char *name)
+ 	return ret;
+ }
+ 
++static char *allcaps(const char *name)
++{
++	static char buffer[1024] = {'\0'};
++	int i;
++
++	for (i=0; i< strlen(name); i++) {
++		buffer[i] = toupper(name[i]);
++	}
++	buffer[strlen(name)] = '\0';
++	return buffer;
++}
+ 
+ static void print_param(FILE *manfile, struct param_info *pi, int field_width, int bold, const char *delimiter)
+ {
+-	char *asterisks = "  ";
++	const char *asterisks = "  ";
+ 	char *type = pi->paramtype;
++	int typelength = strlen(type);
+ 
+ 	/* Reformat pointer params so they look nicer */
+-	if (pi->paramtype[strlen(pi->paramtype)-1] == '*') {
++	if (typelength > 0 && pi->paramtype[typelength-1] == '*') {
+ 		asterisks=" *";
+ 		type = strdup(pi->paramtype);
+-		type[strlen(type)-1] = '\0';
++		type[typelength-1] = '\0';
+ 
+ 		/* Cope with double pointers */
+-		if (pi->paramtype[strlen(type)-1] == '*') {
++		if (typelength > 1 && pi->paramtype[typelength-2] == '*') {
+ 			asterisks="**";
+-			type[strlen(type)-1] = '\0';
++			type[typelength-2] = '\0';
++		}
++
++		/* Tidy function pointers */
++		if (typelength > 1 && pi->paramtype[typelength-2] == '(') {
++			asterisks="(*";
++			type[typelength-2] = '\0';
+ 		}
+ 	}
+ 
+@@ -367,46 +452,48 @@ static void print_param(FILE *manfile, struct param_info *pi, int field_width, i
+ 	}
+ }
+ 
+-static void print_structure(FILE *manfile, char *refid, char *name)
++static void print_structure(FILE *manfile, struct struct_info *si)
+ {
+-	struct struct_info *si;
+ 	struct param_info *pi;
+ 	struct qb_list_head *iter;
+ 	unsigned int max_param_length=0;
+ 
+-	/* If it's not been read in - go and look for it */
+-	si = qb_map_get(structures_map, refid);
+-	if (!si) {
+-		if (!read_structure_from_xml(refid, name)) {
+-			si = qb_map_get(structures_map, refid);
+-		}
++	fprintf(manfile, ".nf\n");
++	fprintf(manfile, "\\fB\n");
++
++	if (si->brief_description) {
++		fprintf(manfile, "%s\n", si->brief_description);
++	}
++	if (si->description) {
++		fprintf(manfile, "%s\n", si->description);
+ 	}
+ 
+-	if (si) {
+-		qb_list_for_each(iter, &si->params_list) {
+-			pi = qb_list_entry(iter, struct param_info, list);
+-			if (strlen(pi->paramtype) > max_param_length) {
+-				max_param_length = strlen(pi->paramtype);
+-			}
++	qb_list_for_each(iter, &si->params_list) {
++		pi = qb_list_entry(iter, struct param_info, list);
++		if (strlen(pi->paramtype) > max_param_length) {
++			max_param_length = strlen(pi->paramtype);
+ 		}
++	}
+ 
+-		if (si->kind == STRUCTINFO_STRUCT) {
+-			fprintf(manfile, "struct %s {\n", si->structname);
+-		} else if (si->kind == STRUCTINFO_ENUM) {
+-			fprintf(manfile, "enum %s {\n", si->structname);
+-		} else {
+-			fprintf(manfile, "%s {\n", si->structname);
+-		}
++	if (si->kind == STRUCTINFO_STRUCT) {
++		fprintf(manfile, "struct %s {\n", si->structname);
++	} else if (si->kind == STRUCTINFO_ENUM) {
++		fprintf(manfile, "enum %s {\n", si->structname);
++	} else {
++		fprintf(manfile, "%s {\n", si->structname);
++	}
+ 
+-		qb_list_for_each(iter, &si->params_list) {
+-			pi = qb_list_entry(iter, struct param_info, list);
+-			print_param(manfile, pi, max_param_length, 0,";");
+-		}
+-		fprintf(manfile, "};\n");
++	qb_list_for_each(iter, &si->params_list) {
++		pi = qb_list_entry(iter, struct param_info, list);
++		print_param(manfile, pi, max_param_length, 0,";");
+ 	}
++	fprintf(manfile, "};\n");
++
++	fprintf(manfile, "\\fP\n");
++	fprintf(manfile, ".fi\n");
+ }
+ 
+-char *get_texttree(int *type, xmlNode *cur_node, char **returntext)
++char *get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext)
+ {
+ 	xmlNode *this_tag;
+ 	char *tmp = NULL;
+@@ -415,7 +502,7 @@ char *get_texttree(int *type, xmlNode *cur_node, char **returntext)
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "para") == 0) {
+-			tmp = get_text(this_tag, returntext);
++			tmp = get_text(this_tag, returntext, notetext);
+ 			strncat(buffer, tmp, sizeof(buffer)-1);
+ 			strncat(buffer, "\n", sizeof(buffer)-1);
+ 			free(tmp);
+@@ -431,22 +518,35 @@ char *get_texttree(int *type, xmlNode *cur_node, char **returntext)
+ 
+ /* The text output is VERY basic and just a check that it's working really */
+ static void print_text(char *name, char *def, char *brief, char *args, char *detailed,
+-		       struct qb_list_head *param_list, char *returntext)
++		       struct qb_list_head *param_list, char *returntext, char *notetext)
+ {
+ 	printf(" ------------------ %s --------------------\n", name);
+ 	printf("NAME\n");
+-	printf("        %s - %s\n", name, brief);
++	if (brief) {
++		printf("        %s - %s\n", name, brief);
++	} else {
++		printf("        %s\n", name);
++	}
+ 
+ 	printf("SYNOPSIS\n");
+-	printf("        %s %s\n\n", name, args);
++	printf("        #include <%s%s>\n", header_prefix, headerfile);
++	if (args) {
++		printf("        %s %s\n\n", name, args);
++	}
+ 
+-	printf("DESCRIPTION\n");
+-	printf("        %s\n", detailed);
++	if (detailed) {
++		printf("DESCRIPTION\n");
++		printf("        %s\n", detailed);
++	}
+ 
+ 	if (returntext) {
+ 		printf("RETURN VALUE\n");
+ 		printf("        %s\n", returntext);
+ 	}
++	if (notetext) {
++		printf("NOTE\n");
++		printf("        %s\n", notetext);
++	}
+ }
+ 
+ /* Print a long string with para marks in it. */
+@@ -466,10 +566,15 @@ static void man_print_long_string(FILE *manfile, char *text)
+ 		current = next_nl+1;
+ 		next_nl = strchr(current, '\n');
+ 	}
++
++	/* The bit at the end */
++	if (strlen(current)) {
++		fprintf(manfile, ".PP\n%s\n", current);
++	}
+ }
+ 
+ static void print_manpage(char *name, char *def, char *brief, char *args, char *detailed,
+-			  struct qb_list_head *param_map, char *returntext)
++			  struct qb_list_head *param_map, char *returntext, char *notetext)
+ {
+ 	char manfilename[PATH_MAX];
+ 	char gendate[64];
+@@ -520,6 +625,12 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	qb_list_for_each(iter, &params_list) {
+ 		pi = qb_list_entry(iter, struct param_info, list);
+ 
++		/* It's mainly macros that break this,
++		 * macros need more work
++		 */
++		if (!pi->paramtype) {
++			pi->paramtype = strdup("");
++		}
+ 		if ((strlen(pi->paramtype) < LINE_LENGTH) &&
+ 		    (strlen(pi->paramtype) > max_param_type_len)) {
+ 			max_param_type_len = strlen(pi->paramtype);
+@@ -536,27 +647,32 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	/* Off we go */
+ 
+ 	fprintf(manfile, ".\\\"  Automatically generated man page, do not edit\n");
+-	fprintf(manfile, ".TH %s %s %s \"%s\" \"%s\"\n", name, man_section, dateptr, package_name, header);
++	fprintf(manfile, ".TH %s %s %s \"%s\" \"%s\"\n", allcaps(name), man_section, dateptr, package_name, header);
+ 
+ 	fprintf(manfile, ".SH NAME\n");
+-	fprintf(manfile, "%s \\- %s\n", name, brief);
++	if (brief) {
++		fprintf(manfile, "%s \\- %s\n", name, brief);
++	} else {
++		fprintf(manfile, "%s\n", name);
++	}
+ 
+ 	fprintf(manfile, ".SH SYNOPSIS\n");
+ 	fprintf(manfile, ".nf\n");
+-	fprintf(manfile, ".B #include <libknet.h>\n");
+-	fprintf(manfile, ".sp\n");
+-	fprintf(manfile, "\\fB%s\\fP(\n", def);
++	fprintf(manfile, ".B #include <%s%s>\n", header_prefix, headerfile);
++	if (def) {
++		fprintf(manfile, ".sp\n");
++		fprintf(manfile, "\\fB%s\\fP(\n", def);
+ 
++		qb_list_for_each(iter, &params_list) {
++			pi = qb_list_entry(iter, struct param_info, list);
+ 
+-	qb_list_for_each(iter, &params_list) {
+-		pi = qb_list_entry(iter, struct param_info, list);
++			print_param(manfile, pi, max_param_type_len, 1, ++param_num < param_count?",":"");
++		}
+ 
+-		print_param(manfile, pi, max_param_type_len, 1, ++param_num < param_count?",":"");
++		fprintf(manfile, ");\n");
++		fprintf(manfile, ".fi\n");
+ 	}
+ 
+-	fprintf(manfile, ");\n");
+-	fprintf(manfile, ".fi\n");
+-
+ 	if (print_params && num_param_descs) {
+ 		fprintf(manfile, ".SH PARAMS\n");
+ 
+@@ -568,21 +684,37 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 		}
+ 	}
+ 
+-	fprintf(manfile, ".SH DESCRIPTION\n");
+-	man_print_long_string(manfile, detailed);
++	if (detailed) {
++		fprintf(manfile, ".SH DESCRIPTION\n");
++		man_print_long_string(manfile, detailed);
++	}
+ 
+ 	if (qb_map_count_get(used_structures_map)) {
+-		fprintf(manfile, ".SH STRUCTURES\n");
++		int first_struct = 1;
+ 
+ 		map_iter = qb_map_iter_create(used_structures_map);
+ 		for (p = qb_map_iter_next(map_iter, &data); p; p = qb_map_iter_next(map_iter, &data)) {
+-			fprintf(manfile, ".nf\n");
+-			fprintf(manfile, "\\fB\n");
++			struct struct_info *si;
++			const char *refid = p;
++			char *refname = data;
+ 
+-			print_structure(manfile, (char*)p, (char *)data);
++			/* If it's not been read in - go and look for it */
++			si = qb_map_get(structures_map, refid);
++			if (!si) {
++				if (!read_structure_from_xml(refid, refname)) {
++					si = qb_map_get(structures_map, refid);
++				}
++			}
+ 
+-			fprintf(manfile, "\\fP\n");
+-			fprintf(manfile, ".fi\n");
++			/* Only print header if the struct files exist - sometimes they don't */
++			if (si && first_struct) {
++				fprintf(manfile, ".SH STRUCTURES\n");
++				first_struct = 0;
++			}
++			if (si) {
++				print_structure(manfile, si);
++				fprintf(manfile, ".PP\n");
++			}
+ 		}
+ 		qb_map_iter_free(map_iter);
+ 
+@@ -592,16 +724,22 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	if (returntext) {
+ 		fprintf(manfile, ".SH RETURN VALUE\n");
+ 		man_print_long_string(manfile, returntext);
++		fprintf(manfile, ".PP\n");
+ 	}
+ 
+ 	qb_list_for_each(iter, &retval_list) {
+ 		pi = qb_list_entry(iter, struct param_info, list);
+ 
+-		fprintf(manfile, "\\fB%-*s \\fP\\fI%s\\fP\n", 10, pi->paramname,
++		fprintf(manfile, "\\fB%-*s \\fP%s\n", 10, pi->paramname,
+ 			pi->paramdesc);
+ 		fprintf(manfile, ".PP\n");
+ 	}
+ 
++	if (notetext) {
++		fprintf(manfile, ".SH NOTE\n");
++		man_print_long_string(manfile, notetext);
++	}
++
+ 	fprintf(manfile, ".SH SEE ALSO\n");
+ 	fprintf(manfile, ".PP\n");
+ 	fprintf(manfile, ".nh\n");
+@@ -613,7 +751,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 
+ 		/* Exclude us! */
+ 		if (strcmp(data, name)) {
+-			fprintf(manfile, "\\fI%s(%s)%s", (char *)data, man_section,
++			fprintf(manfile, "\\fI%s\\fR(%s)%s", (char *)data, man_section,
+ 				param_num < (num_functions - 1)?", ":"");
+ 		}
+ 		param_num++;
+@@ -625,7 +763,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	fprintf(manfile, ".hy\n");
+ 	fprintf(manfile, ".SH \"COPYRIGHT\"\n");
+ 	fprintf(manfile, ".PP\n");
+-	fprintf(manfile, "Copyright (C) 2010-%4ld Red Hat, Inc. All rights reserved.\n", manpage_year);
++	fprintf(manfile, "Copyright (C) %4ld-%4ld %s, Inc. All rights reserved.\n", start_year, manpage_year, company);
+ 	fclose(manfile);
+ 
+ 	/* Free the params & retval info */
+@@ -672,7 +810,6 @@ static void collect_functions(xmlNode *cur_node, void *arg)
+ 				num_functions++;
+ 			}
+ 		}
+-		free(kind);
+ 	}
+ }
+ 
+@@ -695,23 +832,21 @@ static void collect_enums(xmlNode *cur_node, void *arg)
+ 			for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 				if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0) {
+ 					name = strdup((char *)this_tag->children->content);
+-					break;
+ 				}
+ 			}
+ 
+ 			if (name) {
+ 				si = malloc(sizeof(struct struct_info));
+ 				if (si) {
++					memset(si, 0, sizeof(*si));
+ 					si->kind = STRUCTINFO_ENUM;
+ 					qb_list_init(&si->params_list);
+ 					si->structname = strdup(name);
+ 					traverse_node(cur_node, "enumvalue", read_struct, si);
+ 					qb_map_put(structures_map, refid, si);
+ 				}
+-				free(name);
+ 			}
+ 		}
+-		free(kind);
+ 	}
+ }
+ 
+@@ -719,7 +854,9 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ {
+ 	xmlNode *this_tag;
+ 
+-	if (cur_node->name && strcmp((char *)cur_node->name, "memberdef") == 0) {
++	/* if arg == NULL then we're generating a page for the whole header file */
++	if ((cur_node->name && (strcmp((char *)cur_node->name, "memberdef") == 0)) ||
++	    ((arg == NULL) && cur_node->name && strcmp((char *)cur_node->name, "compounddef")) == 0) {
+ 		char *kind = NULL;
+ 		char *def = NULL;
+ 		char *args = NULL;
+@@ -727,6 +864,7 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		char *brief = NULL;
+ 		char *detailed = NULL;
+ 		char *returntext = NULL;
++		char *notetext = NULL;
+ 		int type;
+ 
+ 		kind=def=args=name=NULL;
+@@ -738,25 +876,25 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 			if (!this_tag->children || !this_tag->children->content)
+ 				continue;
+ 
+-			if (!def && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "definition") == 0)
++			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "definition") == 0)
+ 				def = strdup((char *)this_tag->children->content);
+-			if (!args && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "argsstring") == 0)
++			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "argsstring") == 0)
+ 				args = strdup((char *)this_tag->children->content);
+-			if (!name && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0)
++			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "name") == 0)
+ 				name = strdup((char *)this_tag->children->content);
+ 
+-			if (!brief && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "briefdescription") == 0) {
+-				brief = get_texttree(&type, this_tag, &returntext);
++			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "briefdescription") == 0) {
++				brief = get_texttree(&type, this_tag, &returntext, &notetext);
+ 				if (brief) {
+ 					/*
+-					 * apparently brief text contains extra trailing space and 2 \n.
++					 * apparently brief text contains extra trailing space and a \n.
+ 					 * remove them.
+ 					 */
+-					brief[strlen(brief) - 3] = '\0';
++					brief[strlen(brief) - 2] = '\0';
+ 				}
+ 			}
+-			if (!detailed && this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "detaileddescription") == 0) {
+-				detailed = get_texttree(&type, this_tag, &returntext);
++			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "detaileddescription") == 0) {
++				detailed = get_texttree(&type, this_tag, &returntext, &notetext);
+ 			}
+ 			/* Get all the params */
+ 			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "param") == 0) {
+@@ -772,18 +910,39 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 			}
+ 		}
+ 
++		if (arg == headerfile) {
++			/* Print header page */
++			name = (char*)headerfile;
++			if (print_man) {
++				if (!quiet) {
++					printf("Printing header manpage for %s\n", name);
++				}
++				print_manpage(name, def, brief, args, detailed, &params_list, returntext, notetext);
++			}
++			else {
++				print_text(name, def, brief, args, detailed, &params_list, returntext, notetext);
++			}
++		}
++
+ 		if (kind && strcmp(kind, "function") == 0) {
++
+ 			/* Make sure function has a doxygen description */
+ 			if (!detailed) {
+-				fprintf(stderr, "No doxygen description for function '%s' - please fix this\n", name);
+-				exit(1);
++				fprintf(stderr, "No detailed description for function '%s' - please fix this\n", name);
+ 			}
+ 
+-			if (print_man) {
+-				print_manpage(name, def, brief, args, detailed, &params_list, returntext);
+-			}
+-			else {
+-				print_text(name, def, brief, args, detailed, &params_list, returntext);
++			if (!name) {
++				fprintf(stderr, "Internal error - no name found for function\n");
++			} else {
++				if (print_man) {
++					if (!quiet) {
++						printf("Printing manpage for %s\n", name);
++					}
++					print_manpage(name, def, brief, args, detailed, &params_list, returntext, notetext);
++				}
++				else {
++					print_text(name, def, brief, args, detailed, &params_list, returntext, notetext);
++				}
+ 			}
+ 
+ 		}
+@@ -791,8 +950,6 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		free(kind);
+ 		free(def);
+ 		free(args);
+-		free(detailed);
+-		free(brief);
+ 		free(name);
+ 	}
+ }
+@@ -803,7 +960,6 @@ static void traverse_node(xmlNode *parentnode, const char *leafname, void (do_me
+ 	xmlNode *cur_node;
+ 
+ 	for (cur_node = parentnode->children; cur_node; cur_node = cur_node->next) {
+-
+ 		if (cur_node->type == XML_ELEMENT_NODE && cur_node->name
+ 		    && strcmp((char*)cur_node->name, leafname)==0) {
+ 			do_members(cur_node, arg);
+@@ -819,32 +975,61 @@ static void traverse_node(xmlNode *parentnode, const char *leafname, void (do_me
+ static void usage(char *name)
+ {
+ 	printf("Usage:\n");
+-	printf("      %s [OPTIONS] [<XML file>]\n", name);
++	printf("      %s [OPTIONS] <XML file>\n", name);
++	printf("\n");
++	printf(" This is a tool to generate API manpages from a doxygen-annotated header file.\n");
++	printf(" First run doxygen on the file and then run this program against the main XML file\n");
++	printf(" it created and the directory containing the ancilliary files. It will then\n");
++	printf(" output a lot of *.3 man page files which you can then ship with your library.\n");
+ 	printf("\n");
+-	printf("      <XML file> defaults to %s\n", XML_FILE);
++	printf(" You will need to invoke this program once for each .h file in your library,\n");
++	printf(" using the name of the generated .xml file. This file will usually be called\n");
++	printf(" something like <include-file>_8h.xml, eg qbipcs_8h.xml\n");
++	printf("\n");
++	printf(" If you want HTML output then simpy use nroff on the generated files as you\n");
++	printf(" would do with any other man page.\n");
+ 	printf("\n");
+ 	printf("       -a            Print ASCII dump of man pages to stdout\n");
+ 	printf("       -m            Write man page files to <output dir>\n");
+ 	printf("       -P            Print PARAMS section\n");
++	printf("       -g            Print general man page for the whole header file\n");
+ 	printf("       -s <s>        Write man pages into section <s> <default 3)\n");
+-	printf("       -p <package>  Use <package> name. default <Kronosnet>\n");
+-	printf("       -H <header>   Set header (default \"Kronosnet Programmer's Manual\"\n");
++	printf("       -p <package>  Use <package> name. default <Package>\n");
++	printf("       -H <header>   Set header (default \"Programmer's Manual\"\n");
++	printf("       -I <include>  Set include filename (default taken from xml)\n");
++	printf("       -i <prefix>   Prefix for include files. eg qb/ (default \"\")\n");
++	printf("       -C <company>  Company name in copyright (defaults to Red Hat)\n");
+ 	printf("       -D <date>     Date to print at top of man pages (format not checked, default: today)\n");
++	printf("       -S <year>     Start year to print at end of copyright line (default: 2010)\n");
+ 	printf("       -Y <year>     Year to print at end of copyright line (default: today's year)\n");
+ 	printf("       -o <dir>      Write all man pages to <dir> (default .)\n");
+-	printf("       -d <dir>      Directory for XML files (default %s)\n", XML_DIR);
++	printf("       -d <dir>      Directory for XML files (./xml/)\n");
+ 	printf("       -h            Print this usage text\n");
+ }
+ 
++static long get_year(char *optionarg, char optionchar)
++{
++	long year = strtol(optionarg, NULL, 10);
++	/*
++	 * Don't make too many assumptions about the year. I was on call at the
++	 * 2000 rollover. #experience
++	 */
++	if (year == LONG_MIN || year == LONG_MAX ||
++	    year < 1900) {
++		fprintf(stderr, "Value passed to -%c is not a valid year number\n", optionchar);
++		return 0;
++	}
++	return year;
++}
++
+ int main(int argc, char *argv[])
+ {
+ 	xmlNode *rootdoc;
+ 	xmlDocPtr doc;
+-	int quiet=0;
+ 	int opt;
+ 	char xml_filename[PATH_MAX];
+ 
+-	while ( (opt = getopt_long(argc, argv, "H:amPD:Y:s:d:o:p:f:h?", NULL, NULL)) != EOF)
++	while ( (opt = getopt_long(argc, argv, "H:amqgPD:Y:s:S:d:o:p:f:I:i:C:h?", NULL, NULL)) != EOF)
+ 	{
+ 		switch(opt)
+ 		{
+@@ -859,9 +1044,30 @@ int main(int argc, char *argv[])
+ 			case 'P':
+ 				print_params = 1;
+ 				break;
++			case 'g':
++				print_general = 1;
++				break;
++			case 'q':
++				quiet = 1;
++				break;
++			case 'I':
++				headerfile = optarg;
++				break;
++			case 'i':
++				header_prefix = optarg;
++				break;
++			case 'C':
++				company = optarg;
++				break;
+ 			case 's':
+ 				man_section = optarg;
+ 				break;
++			case 'S':
++				start_year = get_year(optarg, 'S');
++				if (start_year == 0) {
++					return 1;
++				}
++				break;
+ 			case 'd':
+ 				xml_dir = optarg;
+ 				break;
+@@ -869,14 +1075,8 @@ int main(int argc, char *argv[])
+ 				manpage_date = optarg;
+ 				break;
+ 			case 'Y':
+-				manpage_year = strtol(optarg, NULL, 10);
+-				/*
+-				 * Don't make too many assumptions about the year. I was on call at the
+-				 * 2000 rollover. #experience
+-				 */
+-				if (manpage_year == LONG_MIN || manpage_year == LONG_MAX ||
+-				    manpage_year < 1900) {
+-					fprintf(stderr, "Value passed to -Y is not a valid year number\n");
++				manpage_year = get_year(optarg, 'Y');
++				if (manpage_year == 0) {
+ 					return 1;
+ 				}
+ 				break;
+@@ -899,8 +1099,13 @@ int main(int argc, char *argv[])
+ 	if (argv[optind]) {
+ 		xml_file = argv[optind];
+ 	}
++	if (!xml_file) {
++		usage(argv[0]);
++		exit(1);
++	}
++
+ 	if (!quiet) {
+-		fprintf(stderr, "reading xml ... ");
++		printf("reading %s ... ", xml_file);
+ 	}
+ 
+ 	snprintf(xml_filename, sizeof(xml_filename), "%s/%s", xml_dir, xml_file);
+@@ -916,7 +1121,16 @@ int main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 	if (!quiet)
+-		fprintf(stderr, "done.\n");
++		printf("done.\n");
++
++	/* Get our header file name */
++	if (!headerfile) {
++		traverse_node(rootdoc, "compounddef", read_headername, &headerfile);
++	}
++	/* Default to *something* if it all goes wrong */
++	if (!headerfile) {
++		headerfile = "unknown.h";
++	}
+ 
+ 	qb_list_init(&params_list);
+ 	qb_list_init(&retval_list);
+@@ -933,5 +1147,9 @@ int main(int argc, char *argv[])
+ 	/* print pages */
+ 	traverse_node(rootdoc, "memberdef", traverse_members, NULL);
+ 
++	if (print_general) {
++		/* Generate and print a page for the headerfile itself */
++		traverse_node(rootdoc, "compounddef", traverse_members, (char *)headerfile);
++	}
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0372-build-Fix-fallback-handling-in-git-version-gen.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0372-build-Fix-fallback-handling-in-git-version-gen.patch
new file mode 100644
index 000000000..e73f1e768
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0372-build-Fix-fallback-handling-in-git-version-gen.patch
@@ -0,0 +1,29 @@ 
+From 64ba119ddb6e898382bdb008b0d7268b5cd30f11 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Tue, 7 Jul 2020 14:29:05 +0200
+Subject: [PATCH] [build] Fix fallback handling in git-version-gen
+
+When fallback is defined and gitarchive file doesn't exists, use fallback
+rather than UNKNOWN.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ build-aux/git-version-gen | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index e1a07790..ff0c5347 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -216,8 +216,10 @@ elif test "x$fallback" = x || git --version >/dev/null 2>&1; then
+         test -z "$v" \
+             && echo "$0: WARNING: $gitarchive_version_file doesn't contain valid version tag" 1>&2 \
+             && v=UNKNOWN
+-    else
++    elif test "x$fallback" = x; then
+         v=UNKNOWN
++    else
++        v=$fallback
+     fi
+ else
+     v=$fallback
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0373-build-Use-git-version-gen-during-specfile-build.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0373-build-Use-git-version-gen-during-specfile-build.patch
new file mode 100644
index 000000000..234ebbe56
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0373-build-Use-git-version-gen-during-specfile-build.patch
@@ -0,0 +1,63 @@ 
+From 854f7c50434b292f0ef82663cd32405fac113c80 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Tue, 7 Jul 2020 14:47:34 +0200
+Subject: [PATCH] [build] Use git-version-gen during specfile build
+
+Instead of copying parts of git-version-gen for spec target use
+git-version-gen directly and parse final version into components
+(rpmver, alphatag, numcomm) and use them.
+
+Main reason is to simplify code a bit (sed scripts are a bit repetitive
+tho), reuse the code and also allow building of RPM from dist tarball
+generated from non-tagged commit or dirty git (not very useful).
+
+The code relies on fact, that hyphen is never used in tagged release
+name.
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ Makefile.am | 26 ++++++++++----------------
+ 1 file changed, 10 insertions(+), 16 deletions(-)
+
+diff --git a/Makefile.am b/Makefile.am
+index 23f76a6c..cf1366e1 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -57,27 +57,21 @@ distclean-local:
+ $(SPEC): $(SPEC).in .version config.status
+ 	rm -f $@-t $@
+ 	date="`LC_ALL=C $(UTC_DATE_AT)$(SOURCE_EPOCH) "+%a %b %d %Y"`" && \
+-	if [ -f $(abs_srcdir)/.tarball-version ]; then \
+-		gitver="`cat $(abs_srcdir)/.tarball-version`" && \
+-		rpmver=$$gitver && \
++	gvgver="`cd $(abs_srcdir); build-aux/git-version-gen --fallback $(VERSION) .tarball-version .gitarchivever`" && \
++	if [ "$$gvgver" = "`echo $$gvgver | sed 's/-/./'`" ];then \
++		rpmver="$$gvgver" && \
+ 		alphatag="" && \
+ 		dirty="" && \
+ 		numcomm="0"; \
+-	elif [ "`git log -1 --pretty=format:x . 2>&1`" = "x" ]; then \
+-		gitver="`GIT_DIR=$(abs_srcdir)/.git git describe --abbrev=4 --match='v*' HEAD 2>/dev/null`" && \
+-		rpmver=`echo $$gitver | sed -e "s/^v//" -e "s/-.*//g"` && \
+-		alphatag=`echo $$gitver | sed -e "s/.*-//" -e "s/^g//"` && \
+-		vtag=`echo $$gitver | sed -e "s/-.*//g"` && \
+-		numcomm=`GIT_DIR=$(abs_srcdir)/.git git rev-list $$vtag..HEAD | wc -l` && \
+-		cd $(abs_srcdir) && \
+-		git update-index --refresh > /dev/null 2>&1 || true && \
+-		dirty=`git diff-index --name-only HEAD 2>/dev/null` && cd - 2>/dev/null; \
+ 	else \
+-		gitver="`cd $(abs_srcdir); build-aux/git-version-gen .tarball-version .gitarchivever`" && \
+-		rpmver=$$gitver && \
+-		alphatag="" && \
++		gitver="`echo $$gvgver | sed 's/\(.*\)\./\1-/'`" && \
++		rpmver=`echo $$gitver | sed 's/-.*//g'` && \
++		alphatag=`echo $$gvgver | sed 's/[^-]*-\([^-]*\).*/\1/'` && \
++		numcomm=`echo $$gitver | sed 's/[^-]*-\([^-]*\).*/\1/'` && \
+ 		dirty="" && \
+-		numcomm="0"; \
++		if [ "`echo $$gitver | sed 's/^.*-dirty$$//g'`" = "" ];then \
++			dirty="dirty"; \
++		fi \
+ 	fi && \
+ 	if [ -n "$$dirty" ]; then dirty="dirty"; else dirty=""; fi && \
+ 	if [ "$$numcomm" = "0" ]; then \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0374-tests-remove-unnecessary-shutdown-locking.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0374-tests-remove-unnecessary-shutdown-locking.patch
new file mode 100644
index 000000000..fdf5bf58d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0374-tests-remove-unnecessary-shutdown-locking.patch
@@ -0,0 +1,55 @@ 
+From 679d06eab81d01f429f102676a74fb8822e8add7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 25 Mar 2019 06:48:09 +0100
+Subject: [PATCH] [tests] remove unnecessary shutdown locking
+
+the test should be in charge not to shutdown too much at once
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 19 -------------------
+ 1 file changed, 19 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index b3cf9638..439a89a9 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -33,8 +33,6 @@ struct log_thread_data {
+ 	FILE *std;
+ };
+ static struct log_thread_data data;
+-static pthread_mutex_t shutdown_mutex = PTHREAD_MUTEX_INITIALIZER;
+-static int stop_in_progress = 0;
+ 
+ static int _read_pipe(int fd, char **file, size_t *length)
+ {
+@@ -366,29 +364,12 @@ knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level)
+ 
+ int knet_handle_stop(knet_handle_t knet_h)
+ {
+-	int savederrno;
+ 	size_t i, j;
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	uint8_t link_ids[KNET_MAX_LINK];
+ 	size_t host_ids_entries = 0, link_ids_entries = 0;
+ 	struct knet_link_status status;
+ 
+-	savederrno = pthread_mutex_lock(&shutdown_mutex);
+-	if (savederrno) {
+-		printf("Unable to get shutdown mutex lock\n");
+-		return -1;
+-	}
+-
+-	if (stop_in_progress) {
+-		pthread_mutex_unlock(&shutdown_mutex);
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	stop_in_progress = 1;
+-
+-	pthread_mutex_unlock(&shutdown_mutex);
+-
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+ 		return -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0375-tests-use-link_get_enable-instead-of-get_status.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0375-tests-use-link_get_enable-instead-of-get_status.patch
new file mode 100644
index 000000000..617e7dc28
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0375-tests-use-link_get_enable-instead-of-get_status.patch
@@ -0,0 +1,52 @@ 
+From ed4f5ce026c42815052360401d01fff289643bc3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 25 Mar 2019 06:56:08 +0100
+Subject: [PATCH] [tests] use link_get_enable instead of get_status
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 439a89a9..1586b54f 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -368,7 +368,7 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	uint8_t link_ids[KNET_MAX_LINK];
+ 	size_t host_ids_entries = 0, link_ids_entries = 0;
+-	struct knet_link_status status;
++	unsigned int enabled;
+ 
+ 	if (!knet_h) {
+ 		errno = EINVAL;
+@@ -391,16 +391,17 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 			return -1;
+ 		}
+ 		for (j = 0; j < link_ids_entries; j++) {
+-			if (knet_link_get_status(knet_h, host_ids[i], link_ids[j], &status, sizeof(struct knet_link_status))) {
+-				printf("knet_link_get_status failed: %s\n", strerror(errno));
++			if (knet_link_get_enable(knet_h, host_ids[i], link_ids[j], &enabled)) {
++				printf("knet_link_get_enable failed: %s\n", strerror(errno));
+ 				return -1;
+ 			}
+-			if (status.enabled) {
++			if (enabled) {
+ 				if (knet_link_set_enable(knet_h, host_ids[i], j, 0)) {
+ 					printf("knet_link_set_enable failed: %s\n", strerror(errno));
+ 					return -1;
+ 				}
+ 			}
++			printf("clearing config for: %p host: %u link: %lu\n", knet_h, host_ids[i], j);
+ 			knet_link_clear_config(knet_h, host_ids[i], j);
+ 		}
+ 		if (knet_host_remove(knet_h, host_ids[i]) < 0) {
+@@ -413,6 +414,7 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 		printf("knet_handle_free failed: %s\n", strerror(errno));
+ 		return -1;
+ 	}
++
+ 	return 0;
+ }
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0376-tests-add-basic-framework-to-create-join-and-stop-ma.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0376-tests-add-basic-framework-to-create-join-and-stop-ma.patch
new file mode 100644
index 000000000..b2b2c47b4
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0376-tests-add-basic-framework-to-create-join-and-stop-ma.patch
@@ -0,0 +1,174 @@ 
+From 832d3ccc60c87de308e9fd3dc638ec0b94f5ed67 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 25 Mar 2019 07:27:39 +0100
+Subject: [PATCH] [tests] add basic framework to create, join and stop many
+ nodes
+
+all nodes will be using loopback interface (lo) at different
+port offset.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/test-common.c | 126 +++++++++++++++++++++++++++++++++++-
+ libknet/tests/test-common.h |   7 ++
+ 2 files changed, 132 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 1586b54f..0906bac5 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -401,7 +401,7 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 					return -1;
+ 				}
+ 			}
+-			printf("clearing config for: %p host: %u link: %lu\n", knet_h, host_ids[i], j);
++			printf("clearing config for: %p host: %u link: %zu\n", knet_h, host_ids[i], j);
+ 			knet_link_clear_config(knet_h, host_ids[i], j);
+ 		}
+ 		if (knet_host_remove(knet_h, host_ids[i]) < 0) {
+@@ -567,3 +567,127 @@ try_again:
+ 	errno = ETIMEDOUT;
+ 	return -1;
+ }
++
++/*
++ * functional tests helpers
++ */
++
++void knet_handle_start_nodes(knet_handle_t knet_h[], uint8_t numnodes, int logfds[2], uint8_t log_level)
++{
++	uint8_t i;
++
++	for (i = 1; i <= numnodes; i++) {
++		knet_h[i] = knet_handle_new_ex(i, logfds[1], log_level, 0);
++		if (!knet_h[i]) {
++			printf("failed to create handle: %s\n", strerror(errno));
++			break;
++		} else {
++			printf("knet_h[%u] at %p\n", i, knet_h[i]);
++		}
++	}
++
++	if (i < numnodes) {
++		knet_handle_stop_nodes(knet_h, i);
++		exit(FAIL);
++	}
++
++	return;
++}
++
++void knet_handle_stop_nodes(knet_handle_t knet_h[], uint8_t numnodes)
++{
++	uint8_t i;
++
++	for (i = 1; i <= numnodes; i++) {
++		printf("stopping handle %u at %p\n", i, knet_h[i]);
++		knet_handle_stop(knet_h[i]);
++	}
++
++	return;
++}
++
++void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t numlinks, int family, uint8_t transport)
++{
++	uint8_t i, x, j;
++	struct sockaddr_storage src, dst;
++
++	for (i = 1; i <= numnodes; i++) {
++		for (j = 1; j <= numnodes; j++) {
++			/*
++			 * don´t connect to itself
++			 */
++			if (j == i) {
++				continue;
++			}
++
++			printf("host %u adding host: %u\n", i, j);
++
++			if (knet_host_add(knet_h[i], j) < 0) {
++				printf("Unable to add host: %s\n", strerror(errno));
++				knet_handle_stop_nodes(knet_h, numnodes);
++				exit(FAIL);
++			}
++
++			for (x = 0; x < numlinks; x++) {
++				if (family == AF_INET6) {
++					if (make_local_sockaddr6(&src, i + x) < 0) {
++						printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
++						knet_handle_stop_nodes(knet_h, numnodes);
++						exit(FAIL);
++					}
++
++					if (make_local_sockaddr6(&dst, j + x) < 0) {
++						printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
++						knet_handle_stop_nodes(knet_h, numnodes);
++						exit(FAIL);
++					}
++				} else {
++					if (make_local_sockaddr(&src, i + x) < 0) {
++						printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
++						knet_handle_stop_nodes(knet_h, numnodes);
++						exit(FAIL);
++					}
++
++					if (make_local_sockaddr(&dst, j + x) < 0) {
++						printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
++						knet_handle_stop_nodes(knet_h, numnodes);
++						exit(FAIL);
++					}
++				}
++
++				printf("joining node %u with node %u via link %u src offset: %u dst offset: %u\n", i, j, x, i+x, j+x);
++
++				if (knet_link_set_config(knet_h[i], j, x, transport, &src, &dst, 0) < 0) {
++					printf("unable to configure link: %s\n", strerror(errno));
++					knet_handle_stop_nodes(knet_h, numnodes);
++					exit(FAIL);
++				}
++
++				if (knet_link_set_enable(knet_h[i], j, x, 1) < 0) {
++					printf("unable to enable link: %s\n", strerror(errno));
++					knet_handle_stop_nodes(knet_h, numnodes);
++					exit(FAIL);
++				}
++			}
++		}
++	}
++
++	for (i = 1; i <= numnodes; i++) {
++		for (j = 1; j <= numnodes; j++) {
++			/*
++			 * don´t wait for self
++			 */
++			if (j == i) {
++				continue;
++			}
++
++			if (wait_for_host(knet_h[i], j, (10 * numnodes) , knet_h[i]->logfd, stdout) < 0) {
++					printf("Cannot connect node %u to node %u: %s\n", i, j, strerror(errno));
++					knet_handle_stop_nodes(knet_h, numnodes);
++					exit(FAIL);
++			}
++		}
++	}
++
++	return;
++}
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 0c40400f..cc31e62c 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -54,6 +54,13 @@ int _knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 			  uint8_t transport, uint64_t flags, int family, int dynamic,
+ 			  struct sockaddr_storage *lo);
+ 
++/*
++ * functional test helpers
++ */
++void knet_handle_start_nodes(knet_handle_t knet_h[], uint8_t numnodes, int logfds[2], uint8_t log_level);
++void knet_handle_stop_nodes(knet_handle_t knet_h[], uint8_t numnodes);
++void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t numlinks, int family, uint8_t transport);
++
+ /*
+  * high level logging function.
+  * automatically setup logpipes and start/stop logging thread.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0377-tests-sets-defaults-for-coverity-scan-check-to-match.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0377-tests-sets-defaults-for-coverity-scan-check-to-match.patch
new file mode 100644
index 000000000..2fc3ea183
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0377-tests-sets-defaults-for-coverity-scan-check-to-match.patch
@@ -0,0 +1,28 @@ 
+From e9d6503049f7419dee86d037ce764a3096383489 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 3 Jul 2020 09:51:37 +0200
+Subject: [PATCH] [tests] sets defaults for coverity scan check to match CI
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/check.mk | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index 890bf903..7b8911f5 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -33,7 +33,12 @@ if HAS_COVBUILD
+ 	$(MAKE) -C $(abs_top_builddir) clean
+ 	$(COVBUILD_EXEC) --dir=$(abs_top_builddir)/cov $(MAKE) -C $(abs_top_builddir)
+ if HAS_COVANALYZE
+-	$(COVANALYZE_EXEC) --dir=$(abs_top_builddir)/cov --wait-for-license $(covoptions)
++	if [ -z "$(covoptions)" ]; then \
++		COVOPTS="--all --disable STACK_USE --disable-parse-warnings";\
++	else \
++		COVOPTS="$(covoptions)";\
++	fi; \
++	$(COVANALYZE_EXEC) --dir=$(abs_top_builddir)/cov --wait-for-license $$COVOPTS
+ if HAS_COVFORMATERRORS
+ 	$(COVFORMATERRORS_EXEC) --dir=$(abs_top_builddir)/cov --emacs-style > $(abs_top_builddir)/cov.output.txt
+ 	$(COVFORMATERRORS_EXEC) --dir=$(abs_top_builddir)/cov --html-output $(abs_top_builddir)/cov.html
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0378-build-update-valgrind-memcheck-exception-file.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0378-build-update-valgrind-memcheck-exception-file.patch
new file mode 100644
index 000000000..7abf71902
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0378-build-update-valgrind-memcheck-exception-file.patch
@@ -0,0 +1,1101 @@ 
+From 16fd562eec609e0805a021eb2e234bfc7a4562a3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 3 Jul 2020 09:54:03 +0200
+Subject: [PATCH] [build] update valgrind memcheck exception file
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 1078 ++++++-------------------
+ 1 file changed, 256 insertions(+), 822 deletions(-)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index b877a59f..9956ca8a 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -1,592 +1,260 @@
+ {
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_stream_header_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_crc32
+-   fun:lzma_stream_header_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_crc32
+-   fun:lzma_stream_header_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_block_header_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:is_overlap
+-   fun:memcpy@@GLIBC_2.14
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:memcpy@@GLIBC_2.14
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:memcpy@@GLIBC_2.14
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_vli_encode
+-   fun:lzma_filter_flags_encode
+-   fun:lzma_block_header_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_filter_flags_encode
+-   fun:lzma_block_header_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:memset
+-   fun:lzma_block_header_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:memset
+-   fun:lzma_block_header_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_block_unpadded_size
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_index_append
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_vli_size
+-   fun:lzma_index_append
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_vli_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_vli_encode
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_crc32
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_crc32
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_index_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_stream_footer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Value8
+-   fun:lzma_crc32
+-   fun:lzma_stream_footer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   fun:lzma_crc32
+-   fun:lzma_stream_footer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   lzma internal stuff
+-   Memcheck:Cond
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   obj:/usr/lib64/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-}
+-{
+-   lzma internal stuff (Debian Unstable)
+-   Memcheck:Cond
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-}
+-{
+-   lzma internal stuff (Debian Experimental)
+-   Memcheck:Cond
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   obj:*/libknet/.libs/compress_lzma.so
+-   obj:*
+-}
+-{
+-   lzma internal stuff (Debian / Ubuntu)
+-   Memcheck:Cond
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
+-   fun:lzma_block_buffer_encode
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:compress_lib_test
+-   fun:compress_cfg
+-   fun:knet_handle_compress
+-   fun:test
+-}
+-{
+-   lzma internal stuff (Ubuntu 17.10 i386)
+-   Memcheck:Cond
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-}
+-{
+-   lzma internal stuff (Ubuntu 17.10 i386)
+-   Memcheck:Cond
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:compress
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-}
+-{
+-   lzma internal stuff (Ubuntu 17.10 i386)
+-   Memcheck:Cond
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
+-   fun:lzma_stream_buffer_encode
+-   fun:lzma_easy_buffer_encode
+-   fun:lzma_compress
+-   fun:compress_lib_test
+-   fun:compress_cfg
+-   fun:knet_handle_compress
+-}
+-{
+-   nss internal leak (3.38+) non recurring
+-   Memcheck:Leak
+-   match-leak-kinds: definite
+-   fun:malloc
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   fun:init_nss
+-   fun:nsscrypto_init
+-   fun:crypto_init
+-   fun:knet_handle_crypto
+-   fun:test
+-   fun:main
+-}
+-{
+-   nss internal leak (3.38+) non recurring
+-   Memcheck:Leak
+-   match-leak-kinds: definite
+-   fun:calloc
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   fun:init_nss
+-   fun:nsscrypto_init
+-   fun:crypto_init
+-   fun:knet_handle_crypto
+-   fun:test
+-   fun:main
+-}
+-{
+-   nss internal leak (3.38+) non recurring
+-   Memcheck:Addr8
+-   obj:/usr/lib64/libp11-kit.so.0.3.0
+-   obj:/usr/lib64/libp11-kit.so.0.3.0
+-   fun:_dl_close_worker
+-   fun:_dl_close
+-   fun:_dl_catch_exception
+-   fun:_dl_catch_error
+-   fun:_dlerror_run
+-   fun:dlclose
+-   fun:PR_UnloadLibrary
+-   obj:/usr/lib64/libnss3.so
+-   obj:/usr/lib64/libnss3.so
+-   obj:/usr/lib64/libnss3.so
++  lzma internals (spotted on Debian 9 and Ubuntu 18.04 LTS x86-64)
++  Memcheck:Cond
++  obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/x86_64-linux-gnu/liblzma.so.5.2.2
++  fun:lzma_block_buffer_encode
++  fun:lzma_stream_buffer_encode
++  fun:lzma_easy_buffer_encode
++  fun:lzma_compress
++  fun:compress_lib_test
++  fun:compress_cfg
++  fun:knet_handle_compress
++  fun:test
++}
++{
++  lzma internals (spotted on Ubuntu 18.04 LTS i386)
++  Memcheck:Cond
++  obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
++  obj:/lib/i386-linux-gnu/liblzma.so.5.2.2
++  fun:lzma_stream_buffer_encode
++  fun:lzma_easy_buffer_encode
++  fun:lzma_compress
++  fun:compress_lib_test
++  fun:compress_cfg
++  fun:knet_handle_compress
++}
++{
++  openssl internals (spotted on OpenSUSE 15)
++  Memcheck:Cond
++  fun:__memcmp_sse4_1
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:FIPS_selftest
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:FIPS_mode_set
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:call_init.part.0
++  fun:_dl_init
++  fun:dl_open_worker
++  fun:_dl_catch_error
++  fun:_dl_open
++  fun:dlopen_doit
++}
++{
++  openssl internals (spotted on OpenSUSE Tumbleweed)
++  Memcheck:Cond
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++}
++{
++  openssl internals (spotted on OpenSUSE Tumbleweed)
++  Memcheck:Cond
++  obj:/usr/lib64/libcrypto.so.1.1
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++}
++{
++  openssl internals (spotted on OpenSUSE Tumbleweed)
++  Memcheck:Cond
++  obj:/usr/lib64/libcrypto.so.1.1
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl internals (spotted on OpenSUSE Tumbleweed)
++  Memcheck:Cond
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl internals (spotted on OpenSUSE 15)
++  Memcheck:Cond
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:FIPS_mode_set
++  obj:/usr/lib64/libcrypto.so.1.1
++  fun:call_init.part.0
++  fun:_dl_init
++  fun:dl_open_worker
++  fun:_dl_catch_error
++  fun:_dl_open
++  fun:dlopen_doit
++  fun:_dl_catch_error
++  fun:_dlerror_run
++  fun:dlopen@@GLIBC_2.2.5
++}
++{
++  openssl uninitialised byte(s) (spotted on OpenSUSE Tumbleweed and Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Param
++  socketcall.sendto(msg)
++  fun:sendto
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl uninitialised byte(s) (spotted on OpenSUSE Tumbleweed and Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Param
++  socketcall.sendto(msg)
++  fun:sendto
++  fun:_parse_recv_from_links
++  fun:_handle_recv_from_links
++  fun:_handle_recv_from_links_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl uninitialised byte(s) (spotted on OpenSUSE Tumbleweed and Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Param
++  socketcall.sendto(msg)
++  fun:sendto
++  fun:_handle_check_link_pmtud
++  fun:_handle_check_pmtud
++  fun:_handle_pmtud_link_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl uninitialised byte(s) (spotted on OpenSUSE Tumbleweed)
++  Memcheck:Param
++  sendmsg(msg.msg_iov[0])
++  fun:sendmsg
++  fun:_sendmmsg
++  fun:_dispatch_to_links
++  fun:_parse_recv_from_sock
++  fun:_handle_send_to_links
++  fun:_handle_send_to_links_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2019-10-30)
++  Memcheck:Param
++  sendmsg(msg.msg_iov[0])
++  fun:__libc_sendmsg
++  fun:sendmsg
++  fun:_sendmmsg
++  fun:_dispatch_to_links
++  fun:_parse_recv_from_sock
++  fun:_handle_send_to_links
++  fun:_handle_send_to_links_thread
++  fun:start_thread
++  fun:clone
+ }
+ {
+    nss internal leak (3.41) non recurring (spotted on f29)
+@@ -605,237 +273,3 @@
+    obj:*
+    obj:/usr/lib64/libnss3.so
+ }
+-{
+-   arm internal memory leak
+-   Memcheck:Leak
+-   match-leak-kinds: definite
+-   fun:malloc
+-   fun:dl_open_worker
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Cond
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_instantiate
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_get0_public
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Cond
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_instantiate
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_get0_public
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Cond
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   fun:RAND_DRBG_bytes
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Cond
+-   obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   fun:RAND_DRBG_bytes
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Param
+-   socketcall.sendto(msg)
+-   fun:sendto
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Param
+-   socketcall.sendto(msg)
+-   fun:sendto
+-   fun:_parse_recv_from_links
+-   fun:_handle_recv_from_links
+-   fun:_handle_recv_from_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Param
+-   socketcall.sendto(msg)
+-   fun:sendto
+-   fun:_handle_check_link_pmtud
+-   fun:_handle_check_pmtud
+-   fun:_handle_pmtud_link_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   openssl 1.1.1c missing fix from master
+-   Memcheck:Param
+-   sendmsg(msg.msg_iov[0])
+-   fun:__libc_sendmsg
+-   fun:sendmsg
+-   fun:_sendmmsg
+-   fun:_dispatch_to_links
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   Opensuse 15 libnss
+-   Memcheck:Cond
+-   fun:__memcmp_sse4_1
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:FIPS_selftest
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:FIPS_mode_set
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:call_init.part.0
+-   fun:_dl_init
+-   fun:dl_open_worker
+-   fun:_dl_catch_error
+-   fun:_dl_open
+-   fun:dlopen_doit
+-}
+-{
+-   Opensuse 15 libnss
+-   Memcheck:Cond
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:FIPS_mode_set
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:call_init.part.0
+-   fun:_dl_init
+-   fun:dl_open_worker
+-   fun:_dl_catch_error
+-   fun:_dl_open
+-   fun:dlopen_doit
+-   fun:_dl_catch_error
+-   fun:_dlerror_run
+-   fun:dlopen@@GLIBC_2.2.5
+-}
+-{
+-   Opensuse tumbleweed libnss
+-   Memcheck:Cond
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_instantiate
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_get0_public
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-}
+-{
+-   Opensuse tumbleweed libnss
+-   Memcheck:Cond
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_instantiate
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_get0_public
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-}
+-{
+-   Opensuse tumbleweed libnss
+-   Memcheck:Cond
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   fun:RAND_DRBG_bytes
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   Opensuse tumbleweed libnss
+-   Memcheck:Cond
+-   obj:/usr/lib64/libcrypto.so.1.1
+-   fun:RAND_DRBG_generate
+-   fun:RAND_DRBG_bytes
+-   fun:encrypt_openssl
+-   fun:opensslcrypto_encrypt_and_signv
+-   fun:opensslcrypto_encrypt_and_sign
+-   fun:_handle_check_each
+-   fun:_send_pings
+-   fun:_handle_heartbt_thread
+-   fun:start_thread
+-   fun:clone
+-}
+-{
+-   Opensuse tumbleweed libnss
+-   Memcheck:Param
+-   sendmsg(msg.msg_iov[0])
+-   fun:sendmsg
+-   fun:_sendmmsg
+-   fun:_dispatch_to_links
+-   fun:_parse_recv_from_sock
+-   fun:_handle_send_to_links
+-   fun:_handle_send_to_links_thread
+-   fun:start_thread
+-   fun:clone
+-}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0379-crypto-add-support-for-live-reconfiguration.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0379-crypto-add-support-for-live-reconfiguration.patch
new file mode 100644
index 000000000..329fcbc70
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0379-crypto-add-support-for-live-reconfiguration.patch
@@ -0,0 +1,2504 @@ 
+From 2fe44c88a982abcc30ddfa1a21dbc040772c4cf3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 8 Jul 2020 13:29:31 +0200
+Subject: [PATCH] [crypto] add support for live reconfiguration
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto.c                              | 132 +++++-
+ libknet/crypto.h                              |  10 +-
+ libknet/crypto_model.h                        |   8 +-
+ libknet/crypto_nss.c                          |  83 +++-
+ libknet/crypto_openssl.c                      |  92 ++--
+ libknet/handle.c                              | 175 ++++++-
+ libknet/internals.h                           |   6 +-
+ libknet/libknet.h                             | 108 ++++-
+ libknet/tests/Makefile.am                     |   6 +-
+ libknet/tests/api-check.mk                    |  14 +-
+ libknet/tests/api_knet_handle_crypto.c        |  12 +-
+ .../api_knet_handle_crypto_rx_clear_traffic.c | 103 +++++
+ .../tests/api_knet_handle_crypto_set_config.c | 432 ++++++++++++++++++
+ .../tests/api_knet_handle_crypto_use_config.c | 248 ++++++++++
+ libknet/tests/fun_config_crypto.c             | 281 ++++++++++++
+ libknet/threads_heartbeat.c                   |   2 +-
+ libknet/threads_pmtud.c                       |   8 +-
+ libknet/threads_rx.c                          |  39 +-
+ libknet/threads_tx.c                          |   2 +-
+ man/Makefile.am                               |   5 +-
+ 20 files changed, 1640 insertions(+), 126 deletions(-)
+ create mode 100644 libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+ create mode 100644 libknet/tests/api_knet_handle_crypto_set_config.c
+ create mode 100644 libknet/tests/api_knet_handle_crypto_use_config.c
+ create mode 100644 libknet/tests/fun_config_crypto.c
+
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 8f0aa8f3..0c475d0f 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -53,7 +53,7 @@ int crypto_encrypt_and_sign (
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	return crypto_modules_cmds[knet_h->crypto_instance->model].ops->crypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
++	return crypto_modules_cmds[knet_h->crypto_instance[knet_h->crypto_in_use_config]->model].ops->crypt(knet_h, knet_h->crypto_instance[knet_h->crypto_in_use_config], buf_in, buf_in_len, buf_out, buf_out_len);
+ }
+ 
+ int crypto_encrypt_and_signv (
+@@ -63,7 +63,7 @@ int crypto_encrypt_and_signv (
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	return crypto_modules_cmds[knet_h->crypto_instance->model].ops->cryptv(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len);
++	return crypto_modules_cmds[knet_h->crypto_instance[knet_h->crypto_in_use_config]->model].ops->cryptv(knet_h, knet_h->crypto_instance[knet_h->crypto_in_use_config], iov_in, iovcnt_in, buf_out, buf_out_len);
+ }
+ 
+ int crypto_authenticate_and_decrypt (
+@@ -73,18 +73,92 @@ int crypto_authenticate_and_decrypt (
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	return crypto_modules_cmds[knet_h->crypto_instance->model].ops->decrypt(knet_h, buf_in, buf_in_len, buf_out, buf_out_len);
++	int i, err = 0;
++	int multiple_configs = 0;
++	uint8_t log_level = KNET_LOG_ERR;
++
++	for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
++		if (knet_h->crypto_instance[i]) {
++			multiple_configs++;
++		}
++	}
++
++	/*
++	 * attempt to decrypt first with the in-use config
++	 * to avoid excessive performance hit.
++	 */
++
++	if (multiple_configs > 1) {
++		log_level = KNET_LOG_DEBUG;
++	}
++
++	if (knet_h->crypto_in_use_config) {
++		err = crypto_modules_cmds[knet_h->crypto_instance[knet_h->crypto_in_use_config]->model].ops->decrypt(knet_h, knet_h->crypto_instance[knet_h->crypto_in_use_config], buf_in, buf_in_len, buf_out, buf_out_len, log_level);
++	} else {
++		err = -1;
++	}
++
++	/*
++	 * if we fail, try to use the other configurations
++	 */
++	if (err) {
++		for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
++			/*
++			 * in-use config was already attempted
++			 */
++			if (i == knet_h->crypto_in_use_config) {
++				continue;
++			}
++			if (knet_h->crypto_instance[i]) {
++				log_debug(knet_h, KNET_SUB_CRYPTO, "Alternative crypto configuration found, attempting to decrypt with config %u", i);
++				err = crypto_modules_cmds[knet_h->crypto_instance[i]->model].ops->decrypt(knet_h, knet_h->crypto_instance[i], buf_in, buf_in_len, buf_out, buf_out_len, KNET_LOG_ERR);
++				if (!err) {
++					errno = 0; /* clear errno from previous failures */
++					return err;
++				}
++				log_debug(knet_h, KNET_SUB_CRYPTO, "Packet failed to decrypt with crypto config %u", i);
++			}
++		}
++	}
++	return err;
++}
++
++int crypto_use_config(
++	knet_handle_t knet_h,
++	uint8_t config_num)
++{
++	if ((config_num) && (!knet_h->crypto_instance[config_num])) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	knet_h->crypto_in_use_config = config_num;
++
++	if (config_num) {
++		knet_h->sec_block_size = knet_h->crypto_instance[config_num]->sec_block_size;
++		knet_h->sec_hash_size = knet_h->crypto_instance[config_num]->sec_hash_size;
++		knet_h->sec_salt_size = knet_h->crypto_instance[config_num]->sec_salt_size;
++	} else {
++		knet_h->sec_block_size = 0;
++		knet_h->sec_hash_size = 0;
++		knet_h->sec_salt_size = 0;
++	}
++
++	force_pmtud_run(knet_h, KNET_SUB_CRYPTO, 1);
++
++	return 0;
+ }
+ 
+ int crypto_init(
+ 	knet_handle_t knet_h,
+-	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
++	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++	uint8_t config_num)
+ {
+ 	int err = 0, savederrno = 0;
+ 	int model = 0;
+ 	struct crypto_instance *current = NULL, *new = NULL;
+ 
+-	current = knet_h->crypto_instance;
++	current = knet_h->crypto_instance[config_num];
+ 
+ 	model = crypto_get_model(knet_handle_crypto_cfg->crypto_model);
+ 	if (model < 0) {
+@@ -153,17 +227,16 @@ int crypto_init(
+ 
+ out:
+ 	if (!err) {
+-		knet_h->crypto_instance = new;
+-		knet_h->sec_block_size = new->sec_block_size;
+-		knet_h->sec_hash_size = new->sec_hash_size;
+-		knet_h->sec_salt_size = new->sec_salt_size;
+-
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "Hash size: %zu salt size: %zu block size: %zu",
+-			  knet_h->sec_hash_size,
+-			  knet_h->sec_salt_size,
+-			  knet_h->sec_block_size);
++		knet_h->crypto_instance[config_num] = new;
+ 
+ 		if (current) {
++			/*
++			 * if we are replacing the current config, we need to enable it right away
++			 */
++			if (knet_h->crypto_in_use_config == config_num) {
++				crypto_use_config(knet_h, config_num);
++			}
++
+ 			if (crypto_modules_cmds[current->model].ops->fini != NULL) {
+ 				crypto_modules_cmds[current->model].ops->fini(knet_h, current);
+ 			}
+@@ -180,10 +253,24 @@ out:
+ 	return err;
+ }
+ 
++static void crypto_fini_config(
++	knet_handle_t knet_h,
++	uint8_t config_num)
++{
++	if (knet_h->crypto_instance[config_num]) {
++		if (crypto_modules_cmds[knet_h->crypto_instance[config_num]->model].ops->fini != NULL) {
++			crypto_modules_cmds[knet_h->crypto_instance[config_num]->model].ops->fini(knet_h, knet_h->crypto_instance[config_num]);
++		}
++		free(knet_h->crypto_instance[config_num]);
++		knet_h->crypto_instance[config_num] = NULL;
++	}
++}
++
+ void crypto_fini(
+-	knet_handle_t knet_h)
++	knet_handle_t knet_h,
++	uint8_t config_num)
+ {
+-	int savederrno = 0;
++	int savederrno = 0, i;
+ 
+ 	savederrno = pthread_rwlock_wrlock(&shlib_rwlock);
+ 	if (savederrno) {
+@@ -192,15 +279,12 @@ void crypto_fini(
+ 		return;
+ 	}
+ 
+-	if (knet_h->crypto_instance) {
+-		if (crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini != NULL) {
+-			crypto_modules_cmds[knet_h->crypto_instance->model].ops->fini(knet_h, knet_h->crypto_instance);
++	if (config_num > KNET_MAX_CRYPTO_INSTANCES) {
++		for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
++			crypto_fini_config(knet_h, i);
+ 		}
+-		free(knet_h->crypto_instance);
+-		knet_h->sec_block_size = 0;
+-		knet_h->sec_hash_size = 0;
+-		knet_h->sec_salt_size = 0;
+-		knet_h->crypto_instance = NULL;
++	} else {
++		crypto_fini_config(knet_h, config_num);
+ 	}
+ 
+ 	pthread_rwlock_unlock(&shlib_rwlock);
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index cc476d14..d04bc484 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -32,11 +32,17 @@ int crypto_encrypt_and_signv (
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len);
+ 
++int crypto_use_config (
++	knet_handle_t knet_h,
++	uint8_t config_num);
++
+ int crypto_init(
+ 	knet_handle_t knet_h,
+-	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg);
++	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++	uint8_t config_num);
+ 
+ void crypto_fini(
+-	knet_handle_t knet_h);
++	knet_handle_t knet_h,
++	uint8_t config_num);
+ 
+ #endif
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index 06e10a0d..0e6ccb4e 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -19,7 +19,7 @@ struct crypto_instance {
+ 	size_t	sec_salt_size;
+ };
+ 
+-#define KNET_CRYPTO_MODEL_ABI 3
++#define KNET_CRYPTO_MODEL_ABI 4
+ 
+ /*
+  * see compress_model.h for explanation of the various lib related functions
+@@ -32,20 +32,24 @@ typedef struct {
+ 	void (*fini)	(knet_handle_t knet_h,
+ 			 struct crypto_instance *crypto_instance);
+ 	int (*crypt)	(knet_handle_t knet_h,
++			 struct crypto_instance *crypto_instance,
+ 			 const unsigned char *buf_in,
+ 			 const ssize_t buf_in_len,
+ 			 unsigned char *buf_out,
+ 			 ssize_t *buf_out_len);
+ 	int (*cryptv)	(knet_handle_t knet_h,
++			 struct crypto_instance *crypto_instance,
+ 			 const struct iovec *iov_in,
+ 			 int iovcnt_in,
+ 			 unsigned char *buf_out,
+ 			 ssize_t *buf_out_len);
+ 	int (*decrypt)	(knet_handle_t knet_h,
++			 struct crypto_instance *crypto_instance,
+ 			 const unsigned char *buf_in,
+ 			 const ssize_t buf_in_len,
+ 			 unsigned char *buf_out,
+-			 ssize_t *buf_out_len);
++			 ssize_t *buf_out_len,
++			 uint8_t log_level);
+ } crypto_ops_t;
+ 
+ typedef struct {
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index bf4cdc1a..d0b5e4f2 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -344,12 +344,13 @@ static int init_nss_crypto(knet_handle_t knet_h, struct crypto_instance *crypto_
+ 
+ static int encrypt_nss(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const struct iovec *iov,
+ 	int iovcnt,
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 	PK11Context*	crypt_context = NULL;
+ 	SECItem		crypt_param;
+ 	SECItem		*nss_sec_param = NULL;
+@@ -431,12 +432,14 @@ out:
+ 
+ static int decrypt_nss (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+-	ssize_t *buf_out_len)
++	ssize_t *buf_out_len,
++	uint8_t log_level)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 	PK11Context*	decrypt_context = NULL;
+ 	SECItem		decrypt_param;
+ 	int		tmp1_outlen = 0;
+@@ -467,15 +470,25 @@ static int decrypt_nss (
+ 
+ 	if (PK11_CipherOp(decrypt_context, buf_out, &tmp1_outlen,
+ 			  KNET_DATABUFSIZE_CRYPT, data, datalen) != SECSuccess) {
+-		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp (decrypt) failed (err %d): %s",
+-			PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp (decrypt) failed (err %d): %s",
++				  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		} else {
++			log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp (decrypt) failed (err %d): %s",
++				PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		}
+ 		goto out;
+ 	}
+ 
+ 	if (PK11_DigestFinal(decrypt_context, buf_out + tmp1_outlen, &tmp2_outlen,
+ 			     KNET_DATABUFSIZE_CRYPT - tmp1_outlen) != SECSuccess) {
+-		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinal (decrypt) failed (err %d): %s",
+-			PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinal (decrypt) failed (err %d): %s",
++				  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		} else {
++			log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinal (decrypt) failed (err %d): %s",
++				PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		}
+ 		goto out;
+ 	}
+ 
+@@ -533,11 +546,13 @@ static int init_nss_hash(knet_handle_t knet_h, struct crypto_instance *crypto_in
+ 
+ static int calculate_nss_hash(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf,
+ 	const size_t buf_len,
+-	unsigned char *hash)
++	unsigned char *hash,
++	uint8_t log_level)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 	PK11Context*	hash_context = NULL;
+ 	SECItem		hash_param;
+ 	unsigned int	hash_tmp_outlen = 0;
+@@ -568,17 +583,29 @@ static int calculate_nss_hash(
+ 	}
+ 
+ 	if (PK11_DigestOp(hash_context, buf, buf_len) != SECSuccess) {
+-		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestOp failed (hash) hash_type=%d (err %d): %s",
+-			(int)hash_to_nss[instance->crypto_hash_type],
+-			PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestOp failed (hash) hash_type=%d (err %d): %s",
++				  (int)hash_to_nss[instance->crypto_hash_type],
++				  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		} else {
++			log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestOp failed (hash) hash_type=%d (err %d): %s",
++				(int)hash_to_nss[instance->crypto_hash_type],
++				PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		}
+ 		goto out;
+ 	}
+ 
+ 	if (PK11_DigestFinal(hash_context, hash,
+ 			     &hash_tmp_outlen, nsshash_len[instance->crypto_hash_type]) != SECSuccess) {
+-		log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinale failed (hash) hash_type=%d (err %d): %s",
+-			(int)hash_to_nss[instance->crypto_hash_type],
+-			PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinale failed (hash) hash_type=%d (err %d): %s",
++				  (int)hash_to_nss[instance->crypto_hash_type],
++				  PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		} else {
++			log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_DigestFinale failed (hash) hash_type=%d (err %d): %s",
++				(int)hash_to_nss[instance->crypto_hash_type],
++				PR_GetError(), PR_ErrorToString(PR_GetError(), PR_LANGUAGE_I_DEFAULT));
++		}
+ 		goto out;
+ 	}
+ 
+@@ -636,16 +663,17 @@ static int init_nss(knet_handle_t knet_h, struct crypto_instance *crypto_instanc
+ 
+ static int nsscrypto_encrypt_and_signv (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const struct iovec *iov_in,
+ 	int iovcnt_in,
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 	int i;
+ 
+ 	if (cipher_to_nss[instance->crypto_cipher_type]) {
+-		if (encrypt_nss(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) {
++		if (encrypt_nss(knet_h, crypto_instance, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) {
+ 			return -1;
+ 		}
+ 	} else {
+@@ -657,7 +685,7 @@ static int nsscrypto_encrypt_and_signv (
+ 	}
+ 
+ 	if (hash_to_nss[instance->crypto_hash_type]) {
+-		if (calculate_nss_hash(knet_h, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
++		if (calculate_nss_hash(knet_h, crypto_instance, buf_out, *buf_out_len, buf_out + *buf_out_len, KNET_LOG_ERR) < 0) {
+ 			return -1;
+ 		}
+ 		*buf_out_len = *buf_out_len + nsshash_len[instance->crypto_hash_type];
+@@ -668,6 +696,7 @@ static int nsscrypto_encrypt_and_signv (
+ 
+ static int nsscrypto_encrypt_and_sign (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+@@ -679,17 +708,19 @@ static int nsscrypto_encrypt_and_sign (
+ 	iov_in.iov_base = (unsigned char *)buf_in;
+ 	iov_in.iov_len = buf_in_len;
+ 
+-	return nsscrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len);
++	return nsscrypto_encrypt_and_signv(knet_h, crypto_instance, &iov_in, 1, buf_out, buf_out_len);
+ }
+ 
+ static int nsscrypto_authenticate_and_decrypt (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+-	ssize_t *buf_out_len)
++	ssize_t *buf_out_len,
++	uint8_t log_level)
+ {
+-	struct nsscrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct nsscrypto_instance *instance = crypto_instance->model_instance;
+ 	ssize_t temp_len = buf_in_len;
+ 
+ 	if (hash_to_nss[instance->crypto_hash_type]) {
+@@ -701,12 +732,16 @@ static int nsscrypto_authenticate_and_decrypt (
+ 			return -1;
+ 		}
+ 
+-		if (calculate_nss_hash(knet_h, buf_in, temp_buf_len, tmp_hash) < 0) {
++		if (calculate_nss_hash(knet_h, crypto_instance, buf_in, temp_buf_len, tmp_hash, log_level) < 0) {
+ 			return -1;
+ 		}
+ 
+ 		if (memcmp(tmp_hash, buf_in + temp_buf_len, nsshash_len[instance->crypto_hash_type]) != 0) {
+-			log_err(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match");
++			if (log_level == KNET_LOG_DEBUG) {
++				log_debug(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match");
++			} else {
++				log_err(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match");
++			}
+ 			return -1;
+ 		}
+ 
+@@ -715,7 +750,7 @@ static int nsscrypto_authenticate_and_decrypt (
+ 	}
+ 
+ 	if (cipher_to_nss[instance->crypto_cipher_type]) {
+-		if (decrypt_nss(knet_h, buf_in, temp_len, buf_out, buf_out_len) < 0) {
++		if (decrypt_nss(knet_h, crypto_instance, buf_in, temp_len, buf_out, buf_out_len, log_level) < 0) {
+ 			return -1;
+ 		}
+ 	} else {
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 6332287d..5ae663cf 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -65,12 +65,13 @@ static int openssl_is_init = 0;
+ #if (OPENSSL_VERSION_NUMBER < 0x10100000L)
+ static int encrypt_openssl(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const struct iovec *iov,
+ 	int iovcnt,
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	EVP_CIPHER_CTX	ctx;
+ 	int		tmplen = 0, offset = 0;
+ 	unsigned char	*salt = buf_out;
+@@ -121,12 +122,14 @@ out:
+ 
+ static int decrypt_openssl (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+-	ssize_t *buf_out_len)
++	ssize_t *buf_out_len,
++	uint8_t log_level)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	EVP_CIPHER_CTX	ctx;
+ 	int		tmplen1 = 0, tmplen2 = 0;
+ 	unsigned char	*salt = (unsigned char *)buf_in;
+@@ -144,14 +147,22 @@ static int decrypt_openssl (
+ 
+ 	if (!EVP_DecryptUpdate(&ctx, buf_out, &tmplen1, data, datalen)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr);
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr);
++		} else {
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr);
++		}
+ 		err = -1;
+ 		goto out;
+ 	}
+ 
+ 	if (!EVP_DecryptFinal_ex(&ctx, buf_out + tmplen1, &tmplen2)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr);
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr);
++		} else {
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr);
++		}
+ 		err = -1;
+ 		goto out;
+ 	}
+@@ -165,12 +176,13 @@ out:
+ #else /* (OPENSSL_VERSION_NUMBER < 0x10100000L) */
+ static int encrypt_openssl(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const struct iovec *iov,
+ 	int iovcnt,
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	EVP_CIPHER_CTX	*ctx;
+ 	int		tmplen = 0, offset = 0;
+ 	unsigned char	*salt = buf_out;
+@@ -221,12 +233,14 @@ out:
+ 
+ static int decrypt_openssl (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+-	ssize_t *buf_out_len)
++	ssize_t *buf_out_len,
++	uint8_t log_level)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	EVP_CIPHER_CTX	*ctx = NULL;
+ 	int		tmplen1 = 0, tmplen2 = 0;
+ 	unsigned char	*salt = (unsigned char *)buf_in;
+@@ -250,14 +264,22 @@ static int decrypt_openssl (
+ 
+ 	if (!EVP_DecryptUpdate(ctx, buf_out, &tmplen1, data, datalen)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr);
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr);
++		} else {
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to decrypt: %s", sslerr);
++		}
+ 		err = -1;
+ 		goto out;
+ 	}
+ 
+ 	if (!EVP_DecryptFinal_ex(ctx, buf_out + tmplen1, &tmplen2)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr);
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr);
++		} else {
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize decrypt: %s", sslerr);
++		}
+ 		err = -1;
+ 		goto out;
+ 	}
+@@ -278,11 +300,13 @@ out:
+ 
+ static int calculate_openssl_hash(
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf,
+ 	const size_t buf_len,
+-	unsigned char *hash)
++	unsigned char *hash,
++	uint8_t log_level)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	unsigned int hash_len = 0;
+ 	unsigned char *hash_out = NULL;
+ 	char sslerr[SSLERR_BUF_SIZE];
+@@ -292,9 +316,13 @@ static int calculate_openssl_hash(
+ 			buf, buf_len,
+ 			hash, &hash_len);
+ 
+-	if ((!hash_out) || (hash_len != knet_h->sec_hash_size)) {
++	if ((!hash_out) || (hash_len != crypto_instance->sec_hash_size)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to calculate hash: %s", sslerr);
++		if (log_level == KNET_LOG_DEBUG) {
++			log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to calculate hash: %s", sslerr);
++		} else {
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to calculate hash: %s", sslerr);
++		}
+ 		return -1;
+ 	}
+ 
+@@ -307,16 +335,17 @@ static int calculate_openssl_hash(
+ 
+ static int opensslcrypto_encrypt_and_signv (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const struct iovec *iov_in,
+ 	int iovcnt_in,
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	int i;
+ 
+ 	if (instance->crypto_cipher_type) {
+-		if (encrypt_openssl(knet_h, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) {
++		if (encrypt_openssl(knet_h, crypto_instance, iov_in, iovcnt_in, buf_out, buf_out_len) < 0) {
+ 			return -1;
+ 		}
+ 	} else {
+@@ -328,10 +357,10 @@ static int opensslcrypto_encrypt_and_signv (
+ 	}
+ 
+ 	if (instance->crypto_hash_type) {
+-		if (calculate_openssl_hash(knet_h, buf_out, *buf_out_len, buf_out + *buf_out_len) < 0) {
++		if (calculate_openssl_hash(knet_h, crypto_instance, buf_out, *buf_out_len, buf_out + *buf_out_len, KNET_LOG_ERR) < 0) {
+ 			return -1;
+ 		}
+-		*buf_out_len = *buf_out_len + knet_h->sec_hash_size;
++		*buf_out_len = *buf_out_len + crypto_instance->sec_hash_size;
+ 	}
+ 
+ 	return 0;
+@@ -339,6 +368,7 @@ static int opensslcrypto_encrypt_and_signv (
+ 
+ static int opensslcrypto_encrypt_and_sign (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+@@ -350,42 +380,48 @@ static int opensslcrypto_encrypt_and_sign (
+ 	iov_in.iov_base = (unsigned char *)buf_in;
+ 	iov_in.iov_len = buf_in_len;
+ 
+-	return opensslcrypto_encrypt_and_signv(knet_h, &iov_in, 1, buf_out, buf_out_len);
++	return opensslcrypto_encrypt_and_signv(knet_h, crypto_instance, &iov_in, 1, buf_out, buf_out_len);
+ }
+ 
+ static int opensslcrypto_authenticate_and_decrypt (
+ 	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
+ 	const unsigned char *buf_in,
+ 	const ssize_t buf_in_len,
+ 	unsigned char *buf_out,
+-	ssize_t *buf_out_len)
++	ssize_t *buf_out_len,
++	uint8_t log_level)
+ {
+-	struct opensslcrypto_instance *instance = knet_h->crypto_instance->model_instance;
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
+ 	ssize_t temp_len = buf_in_len;
+ 
+ 	if (instance->crypto_hash_type) {
+-		unsigned char tmp_hash[knet_h->sec_hash_size];
+-		ssize_t temp_buf_len = buf_in_len - knet_h->sec_hash_size;
++		unsigned char tmp_hash[crypto_instance->sec_hash_size];
++		ssize_t temp_buf_len = buf_in_len - crypto_instance->sec_hash_size;
+ 
+ 		if ((temp_buf_len <= 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
+ 			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Incorrect packet size.");
+ 			return -1;
+ 		}
+ 
+-		if (calculate_openssl_hash(knet_h, buf_in, temp_buf_len, tmp_hash) < 0) {
++		if (calculate_openssl_hash(knet_h, crypto_instance, buf_in, temp_buf_len, tmp_hash, log_level) < 0) {
+ 			return -1;
+ 		}
+ 
+-		if (memcmp(tmp_hash, buf_in + temp_buf_len, knet_h->sec_hash_size) != 0) {
+-			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match");
++		if (memcmp(tmp_hash, buf_in + temp_buf_len, crypto_instance->sec_hash_size) != 0) {
++			if (log_level == KNET_LOG_DEBUG) {
++				log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match");
++			} else {
++				log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match");
++			}
+ 			return -1;
+ 		}
+ 
+-		temp_len = temp_len - knet_h->sec_hash_size;
++		temp_len = temp_len - crypto_instance->sec_hash_size;
+ 		*buf_out_len = temp_len;
+ 	}
+ 	if (instance->crypto_cipher_type) {
+-		if (decrypt_openssl(knet_h, buf_in, temp_len, buf_out, buf_out_len) < 0) {
++		if (decrypt_openssl(knet_h, crypto_instance, buf_in, temp_len, buf_out, buf_out_len, log_level) < 0) {
+ 			return -1;
+ 		}
+ 	} else {
+diff --git a/libknet/handle.c b/libknet/handle.c
+index aae5bb8a..71658926 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -792,7 +792,7 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	_close_epolls(knet_h);
+ 	_destroy_buffers(knet_h);
+ 	_close_socks(knet_h);
+-	crypto_fini(knet_h);
++	crypto_fini(knet_h, KNET_MAX_CRYPTO_INSTANCES + 1); /* values above MAX_CRYPTO will release all crypto resources */
+ 	compress_fini(knet_h, 1);
+ 	_destroy_locks(knet_h);
+ 
+@@ -1460,7 +1460,10 @@ int knet_handle_pmtud_get(knet_handle_t knet_h,
+ 	return 0;
+ }
+ 
+-int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
++static int _knet_handle_crypto_set_config(knet_handle_t knet_h,
++					  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++					  uint8_t config_num,
++					  uint8_t force)
+ {
+ 	int savederrno = 0;
+ 	int err = 0;
+@@ -1475,6 +1478,11 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 		return -1;
+ 	}
+ 
++	if ((config_num < 1) || (config_num > KNET_MAX_CRYPTO_INSTANCES)) {
++		errno = EINVAL;
++		return -1;
++	}
++
+ 	savederrno = get_global_wrlock(knet_h);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+@@ -1483,32 +1491,38 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 		return -1;
+ 	}
+ 
+-	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) || 
++	if ((knet_h->crypto_in_use_config == config_num) && (!force)) {
++		savederrno = EBUSY;
++		err = -1;
++		goto exit_unlock;
++	}
++
++	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) ||
+ 	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
+ 	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
+-		crypto_fini(knet_h);
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "crypto is not enabled");
++		crypto_fini(knet_h, config_num);
++		log_debug(knet_h, KNET_SUB_CRYPTO, "crypto config %u is not enabled", config_num);
+ 		err = 0;
+ 		goto exit_unlock;
+ 	}
+ 
+ 	if (knet_handle_crypto_cfg->private_key_len < KNET_MIN_KEY_LEN) {
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too short (min %d): %u",
+-			  KNET_MIN_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
++		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too short for config %u (min %d): %u",
++			  config_num, KNET_MIN_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
+ 		savederrno = EINVAL;
+ 		err = -1;
+ 		goto exit_unlock;
+ 	}
+ 
+ 	if (knet_handle_crypto_cfg->private_key_len > KNET_MAX_KEY_LEN) {
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too long (max %d): %u",
+-			  KNET_MAX_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
++		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too long for config %u (max %d): %u",
++			  config_num, KNET_MAX_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
+ 		savederrno = EINVAL;
+ 		err = -1;
+ 		goto exit_unlock;
+ 	}
+ 
+-	err = crypto_init(knet_h, knet_handle_crypto_cfg);
++	err = crypto_init(knet_h, knet_handle_crypto_cfg, config_num);
+ 
+ 	if (err) {
+ 		err = -2;
+@@ -1516,14 +1530,151 @@ int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet
+ 	}
+ 
+ exit_unlock:
+-	if (!err) {
+-		force_pmtud_run(knet_h, KNET_SUB_CRYPTO, 1);
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++int knet_handle_crypto_set_config(knet_handle_t knet_h,
++				  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++				  uint8_t config_num)
++{
++	return _knet_handle_crypto_set_config(knet_h, knet_handle_crypto_cfg, config_num, 0);
++}
++
++int knet_handle_crypto_rx_clear_traffic(knet_handle_t knet_h,
++					uint8_t value)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (value > KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->crypto_only = value;
++	if (knet_h->crypto_only) {
++		log_debug(knet_h, KNET_SUB_CRYPTO, "Only crypto traffic allowed for RX");
++	} else {
++		log_debug(knet_h, KNET_SUB_CRYPTO, "Both crypto and clear traffic allowed for RX");
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	return 0;
++}
++
++int knet_handle_crypto_use_config(knet_handle_t knet_h,
++				  uint8_t config_num)
++{
++	int savederrno = 0;
++	int err = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
+ 	}
++
++	if (config_num > KNET_MAX_CRYPTO_INSTANCES) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	err = crypto_use_config(knet_h, config_num);
++	savederrno = errno;
++
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	errno = err ? savederrno : 0;
+ 	return err;
+ }
+ 
++/*
++ * compatibility wrapper for 1.x releases
++ */
++int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
++{
++	int err = 0;
++	uint8_t value;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	value = knet_h->crypto_only;
++	/*
++	 * configure crypto in slot 1
++	 */
++	err = _knet_handle_crypto_set_config(knet_h, knet_handle_crypto_cfg, 1, 1);
++	if (err < 0) {
++		return err;
++	}
++
++	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) ||
++	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
++	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
++		err = knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC);
++		if (err < 0) {
++			return err;
++		}
++
++		/*
++		 * start using clear traffic
++		 */
++		err = knet_handle_crypto_use_config(knet_h, 0);
++		if (err < 0) {
++			err = knet_handle_crypto_rx_clear_traffic(knet_h, value);
++			if (err < 0) {
++				/*
++				 * force attempt or things will go bad
++				 */
++				knet_h->crypto_only = value;
++			}
++		}
++		return err;
++	} else {
++		err = knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC);
++		if (err < 0) {
++			return err;
++		}
++
++		/*
++		 * start using crypto traffic
++		 */
++		err = knet_handle_crypto_use_config(knet_h, 1);
++		if (err < 0) {
++			err = knet_handle_crypto_rx_clear_traffic(knet_h, value);
++			if (err < 0) {
++				/*
++				 * force attempt or things will go bad
++				 */
++				knet_h->crypto_only = value;
++			}
++		}
++		return err;
++	}
++}
++
+ int knet_handle_compress(knet_handle_t knet_h, struct knet_handle_compress_cfg *knet_handle_compress_cfg)
+ {
+ 	int savederrno = 0;
+diff --git a/libknet/internals.h b/libknet/internals.h
+index b763d4a9..cda58a6d 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -157,6 +157,8 @@ struct knet_fd_trackers {
+ 
+ #define KNET_MAX_COMPRESS_METHODS UINT8_MAX
+ 
++#define KNET_MAX_CRYPTO_INSTANCES 2
++
+ struct knet_handle_stats_extra {
+ 	uint64_t tx_crypt_pmtu_packets;
+ 	uint64_t tx_crypt_pmtu_reply_packets;
+@@ -215,7 +217,9 @@ struct knet_handle {
+ 	int pmtud_running;
+ 	int pmtud_forcerun;
+ 	int pmtud_abort;
+-	struct crypto_instance *crypto_instance;
++	struct crypto_instance *crypto_instance[KNET_MAX_CRYPTO_INSTANCES + 1]; /* store an extra pointer to allow 0|1|2 values without too much magic in the code */
++	uint8_t crypto_in_use_config;		/* crypto config to use for TX */
++	uint8_t crypto_only;			/* allow only crypto (1) or also clear (0) traffic */
+ 	size_t sec_block_size;
+ 	size_t sec_hash_size;
+ 	size_t sec_salt_size;
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 52cc321c..636e442c 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -671,7 +671,7 @@ struct knet_handle_crypto_cfg {
+ };
+ 
+ /**
+- * knet_handle_crypto
++ * knet_handle_crypto_set_config
+  *
+  * @brief set up packet cryptographic signing & encryption
+  *
+@@ -710,23 +710,117 @@ struct knet_handle_crypto_cfg {
+  *            private_key_len
+  *                         length of the provided private_key.
+  *
++ * config_num - knet supports 2 concurrent sets of crypto configurations,
++ *              to allow runtime change of crypto config and keys.
++ *              On RX both configurations will be used sequentially
++ *              in an attempt to decrypt/validate a packet (when 2 are available).
++ *              Note that this might slow down performance during a reconfiguration.
++ *              See also knet_handle_crypto_rx_clear_traffic(3) to enable / disable
++ *              processing of clear (unencrypted) traffic.
++ *              For TX, the user needs to specify which configuration to use via
++ *              knet_handle_crypto_use_config(3).
++ *              config_num accepts 0, 1 or 2 as the value. 0 should be used when
++ *              all crypto is being disabled.
++ *              Calling knet_handle_crypto_set_config(3) twice with
++ *              the same config_num will REPLACE the configuration and
++ *              NOT activate the second key. If the configuration is currently in use
++ *              EBUSY will be returned. See also knet_handle_crypto_use_config(3).
++ *              The correct sequence to perform a runtime rekey / reconfiguration
++ *              is:
++ *              - knet_handle_crypto_set_config(..., 1). -> first time config, will use config1
++ *              - knet_handle_crypto_use_config(..., 1). -> switch TX to config 1
++ *              - knet_handle_crypto_set_config(..., 2). -> install config2 and use it only for RX
++ *              - knet_handle_crypto_use_config(..., 2). -> switch TX to config 2
++ *              - knet_handle_crypto_set_config(..., 1). -> with a "none"/"none"/"none" configuration to
++ *                                                          release the resources previously allocated
++ *              The application is responsible for synchronizing calls on the nodes
++ *              to make sure the new config is in place before switching the TX configuration.
++ *              Failure to do so will result in knet being unable to talk to some of the nodes.
++ *
+  * Implementation notes/current limitations:
+  * - enabling crypto, will increase latency as packets have
+  *   to processed.
+  * - enabling crypto might reduce the overall throughtput
+  *   due to crypto data overhead.
+- * - re-keying is not implemented yet.
+  * - private/public key encryption/hashing is not currently
+  *   planned.
+  * - crypto key must be the same for all hosts in the same
+- *   knet instance.
+- * - it is safe to call knet_handle_crypto multiple times at runtime.
++ *   knet instance / configX.
++ * - it is safe to call knet_handle_crypto_set_config multiple times at runtime.
+  *   The last config will be used.
+- *   IMPORTANT: a call to knet_handle_crypto can fail due to:
++ *   IMPORTANT: a call to knet_handle_crypto_set_config can fail due to:
+  *              1) failure to obtain locking
+  *              2) errors to initializing the crypto level.
+- *   This can happen even in subsequent calls to knet_handle_crypto.
+- *   A failure in crypto init will restore the previous crypto configuration.
++ *   This can happen even in subsequent calls to knet_handle_crypto_set_config(3).
++ *   A failure in crypto init will restore the previous crypto configuration if any.
++ *
++ * @return
++ * knet_handle_crypto_set_config returns:
++ * @retval 0 on success
++ * @retval -1 on error and errno is set.
++ * @retval -2 on crypto subsystem initialization error. No errno is provided at the moment (yet).
++ */
++
++int knet_handle_crypto_set_config(knet_handle_t knet_h,
++				  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++				  uint8_t config_num);
++
++
++
++#define KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC 0
++#define KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC 1
++
++/**
++ * knet_handle_crypto_rx_clear_traffic
++ *
++ * @brief enable or disable RX processing of clear (unencrypted) traffic
++ *
++ * knet_h   - pointer to knet_handle_t
++ *
++ * value    - KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC or KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC
++ *
++ * @return
++ * knet_handle_crypto_use_config returns:
++ * @retval 0 on success
++ * @retval -1 on error and errno is set.
++ */
++
++int knet_handle_crypto_rx_clear_traffic(knet_handle_t knet_h, uint8_t value);
++
++/**
++ * knet_handle_crypto_use_config
++ *
++ * @brief specify crypto configuration to use for TX
++ *
++ * knet_h   - pointer to knet_handle_t
++ *
++ * config_num - 1|2 use configuration 1 or 2, 0 for clear (unencrypted) traffic.
++ *
++ * @return
++ * knet_handle_crypto_use_config returns:
++ * @retval 0 on success
++ * @retval -1 on error and errno is set.
++ */
++
++int knet_handle_crypto_use_config(knet_handle_t knet_h,
++				  uint8_t config_num);
++
++/**
++ * knet_handle_crypto
++ *
++ * @brief set up packet cryptographic signing & encryption
++ *
++ * knet_h   - pointer to knet_handle_t
++ *
++ * knet_handle_crypto_cfg -
++ *            pointer to a knet_handle_crypto_cfg structure
++ *            see knet_handle_crypto_set_config(3) for details.
++ *
++ *
++ * Implementation notes:
++ *
++ * knet_handle_crypto(3) is now a wrapper for knet_handle_crypto_set_config(3)
++ * and knet_handle_crypto_use_config(3) with config_num set to 1.
+  *
+  * @return
+  * knet_handle_crypto returns:
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 86312072..aa948218 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -36,7 +36,8 @@ int_checks		= \
+ 			  int_links_acl_ip_test \
+ 			  int_timediff_test
+ 
+-fun_checks		=
++fun_checks		= \
++			  fun_config_crypto_test
+ 
+ # checks below need to be executed manually
+ # or with a specifi environment
+@@ -102,3 +103,6 @@ knet_bench_test_SOURCES	= knet_bench.c \
+ fun_pmtud_crypto_test_SOURCES = fun_pmtud_crypto.c \
+ 				test-common.c \
+ 				../onwire.c
++
++fun_config_crypto_test_SOURCES = fun_config_crypto.c \
++				 test-common.c
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 75a51507..97afcfbe 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -73,7 +73,10 @@ api_checks		= \
+ 			  api_knet_link_add_acl_test \
+ 			  api_knet_link_insert_acl_test \
+ 			  api_knet_link_rm_acl_test \
+-			  api_knet_link_clear_acl_test
++			  api_knet_link_clear_acl_test \
++			  api_knet_handle_crypto_set_config_test \
++			  api_knet_handle_crypto_use_config_test \
++			  api_knet_handle_crypto_rx_clear_traffic_test
+ 
+ api_knet_handle_new_test_SOURCES = api_knet_handle_new.c \
+ 				   test-common.c
+@@ -276,3 +279,12 @@ api_knet_link_rm_acl_test_SOURCES = api_knet_link_rm_acl.c \
+ 
+ api_knet_link_clear_acl_test_SOURCES = api_knet_link_clear_acl.c \
+ 				       test-common.c
++
++api_knet_handle_crypto_set_config_test_SOURCES = api_knet_handle_crypto_set_config.c \
++						 test-common.c
++
++api_knet_handle_crypto_use_config_test_SOURCES = api_knet_handle_crypto_use_config.c \
++						 test-common.c
++
++api_knet_handle_crypto_rx_clear_traffic_test_SOURCES = api_knet_handle_crypto_rx_clear_traffic.c \
++						       test-common.c
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index 1fa962df..e02e9041 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -156,7 +156,7 @@ static void test(const char *model, const char *model2)
+ 
+ 	printf("Test knet_handle_crypto reconfig with %s/aes128/sha1 and normal key\n", model2);
+ 
+-	current = knet_h->crypto_instance;
++	current = knet_h->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -174,7 +174,7 @@ static void test(const char *model, const char *model2)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (current == knet_h->crypto_instance) {
++	if (current == knet_h->crypto_instance[1]) {
+ 		printf("knet_handle_crypto failed to install new correct config: %s\n", strerror(errno));
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+@@ -186,7 +186,7 @@ static void test(const char *model, const char *model2)
+ 
+ 	printf("Test knet_handle_crypto reconfig with %s/aes128/sha1 and normal key\n", model);
+ 
+-	current = knet_h->crypto_instance;
++	current = knet_h->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -204,7 +204,7 @@ static void test(const char *model, const char *model2)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (current == knet_h->crypto_instance) {
++	if (current == knet_h->crypto_instance[1]) {
+ 		printf("knet_handle_crypto failed to install new correct config: %s\n", strerror(errno));
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+@@ -216,7 +216,7 @@ static void test(const char *model, const char *model2)
+ 
+ 	printf("Test knet_handle_crypto reconfig with %s/aes129/sha1 and normal key\n", model);
+ 
+-	current = knet_h->crypto_instance;
++	current = knet_h->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -234,7 +234,7 @@ static void test(const char *model, const char *model2)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (current != knet_h->crypto_instance) {
++	if (current != knet_h->crypto_instance[1]) {
+ 		printf("knet_handle_crypto failed to restore correct config: %s\n", strerror(errno));
+ 		knet_handle_free(knet_h);
+ 		flush_logs(logfds[0], stdout);
+diff --git a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+new file mode 100644
+index 00000000..d62bd776
+--- /dev/null
++++ b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+@@ -0,0 +1,103 @@
++/*
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "crypto_model.h"
++#include "test-common.h"
++
++static void test()
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++
++	printf("Test knet_handle_crypto_rx_clear_traffic incorrect knet_h\n");
++
++	if ((!knet_handle_crypto_rx_clear_traffic(NULL, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_rx_clear_traffic accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_rx_clear_traffic with invalid value\n");
++
++	if ((!knet_handle_crypto_rx_clear_traffic(knet_h, 2)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_rx_clear_traffic accepted invalid value (%u) or returned incorrect error: %s\n", 2, strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_rx_clear_traffic with valid value KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC\n");
++
++	if ((knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC)) < 0) {
++		printf("knet_handle_crypto_rx_clear_traffic did not accept valid value\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->crypto_only != KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC) {
++		printf("knet_handle_crypto_rx_clear_traffic failed to set correct value\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_rx_clear_traffic with valid value KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC\n");
++
++	if ((knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC)) < 0) {
++		printf("knet_handle_crypto_rx_clear_traffic did not accept valid value\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->crypto_only != KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
++		printf("knet_handle_crypto_rx_clear_traffic failed to set correct value\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	test();
++
++	return PASS;
++}
+diff --git a/libknet/tests/api_knet_handle_crypto_set_config.c b/libknet/tests/api_knet_handle_crypto_set_config.c
+new file mode 100644
+index 00000000..520249f4
+--- /dev/null
++++ b/libknet/tests/api_knet_handle_crypto_set_config.c
+@@ -0,0 +1,432 @@
++/*
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "crypto_model.h"
++#include "test-common.h"
++
++static void test(const char *model, const char *model2)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
++	struct crypto_instance *current = NULL;
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++
++	printf("Test knet_handle_crypto_set_config incorrect knet_h\n");
++
++	if ((!knet_handle_crypto_set_config(NULL, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_set_config accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with invalid cfg\n");
++
++	if ((!knet_handle_crypto_set_config(knet_h, NULL, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_set_config accepted invalid cfg or returned incorrect error: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with invalid config num\n");
++
++	if ((!knet_handle_crypto_set_config(knet_h, NULL, KNET_MAX_CRYPTO_INSTANCES + 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_set_config accepted invalid config num (%u) or returned incorrect error: %s\n", KNET_MAX_CRYPTO_INSTANCES + 1, strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with un-initialized cfg\n");
++
++	if ((!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_set_config accepted invalid un-initialized cfg\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with none crypto model (disable crypto)\n");
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, "none", sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) != 0) {
++		printf("knet_handle_crypto_set_config did not accept none crypto mode cfg\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with none crypto cipher and hash (disable crypto)\n");
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) != 0) {
++		printf("knet_handle_crypto_set_config did not accept none crypto cipher and hash cfg\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and too short key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 10;
++
++	if ((!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_set_config accepted too short private key\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and too long key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 10000;
++
++	if ((!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_set_config accepted too long private key\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and normal key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
++		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config reconfig with %s/aes128/sha1 and normal key\n", model2);
++
++	current = knet_h->crypto_instance[1];
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
++		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (current == knet_h->crypto_instance[1]) {
++		printf("knet_handle_crypto_set_config failed to install new correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config reconfig with %s/aes128/sha1 and normal key\n", model);
++
++	current = knet_h->crypto_instance[1];
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
++		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (current == knet_h->crypto_instance[1]) {
++		printf("knet_handle_crypto_set_config failed to install new correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config reconfig with %s/aes129/sha1 and normal key\n", model);
++
++	current = knet_h->crypto_instance[1];
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes129", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
++		printf("knet_handle_crypto_set_config failed to detect incorrect config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (current != knet_h->crypto_instance[1]) {
++		printf("knet_handle_crypto_set_config failed to restore correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with %s/aes128/none and normal key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
++		printf("knet_handle_crypto_set_config accepted crypto without hashing\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and key where (key_len %% wrap_key_block_size != 0)\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	/*
++	 * Prime number so chance that (private_key_len % wrap_key_block_size == 0) is minimalized
++	 */
++	knet_handle_crypto_cfg.private_key_len = 2003;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) < 0) {
++		printf("knet_handle_crypto_set_config doesn't accept private_ley with len 2003: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config second with %s/aes128/sha1 and normal key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) < 0) {
++		printf("knet_handle_crypto_set_config failed to install second config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (!knet_h->crypto_instance[2]) {
++		printf("knet_handle_crypto_set_config failed to install second config but reported success\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_h->crypto_instance[1] == knet_h->crypto_instance[2]) {
++		printf("knet_handle_crypto_set_config failed to install second config and assigned to first\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	printf("Test knet_handle_crypto_set_config second config BUSY test\n");
++
++	if (knet_handle_crypto_use_config(knet_h, 2) < 0) {
++		printf("knet_handle_crypto_use_config failed to enable second config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) && (errno != EBUSY)) {
++		printf("knet_handle_crypto_set_config failed to detect second config in use: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_handle_crypto_use_config(knet_h, 0) < 0) {
++		printf("knet_handle_crypto_use_config failed to enable second config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Shutdown crypto\n");
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, "none", sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) < 0) {
++		printf("Unable to shutdown crypto: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->crypto_instance[1]) {
++		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) < 0) {
++		printf("Unable to shutdown crypto: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->crypto_instance[2]) {
++		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	struct knet_crypto_info crypto_list[16];
++	size_t crypto_list_entries;
++	size_t i;
++
++	memset(crypto_list, 0, sizeof(crypto_list));
++
++	if (knet_get_crypto_list(crypto_list, &crypto_list_entries) < 0) {
++		printf("knet_get_crypto_list failed: %s\n", strerror(errno));
++		return FAIL;
++	}
++
++	if (crypto_list_entries == 0) {
++		printf("no crypto modules detected. Skipping\n");
++		return SKIP;
++	}
++
++	for (i=0; i < crypto_list_entries; i++) {
++		test(crypto_list[i].name, crypto_list[0].name);
++	}
++
++	return PASS;
++}
+diff --git a/libknet/tests/api_knet_handle_crypto_use_config.c b/libknet/tests/api_knet_handle_crypto_use_config.c
+new file mode 100644
+index 00000000..2f1974dc
+--- /dev/null
++++ b/libknet/tests/api_knet_handle_crypto_use_config.c
+@@ -0,0 +1,248 @@
++/*
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "crypto_model.h"
++#include "test-common.h"
++
++static void test(const char *model, const char *model2)
++{
++	knet_handle_t knet_h;
++	int logfds[2];
++	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++
++	printf("Test knet_handle_crypto_use_config incorrect knet_h\n");
++
++	if ((!knet_handle_crypto_use_config(NULL, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_use_config accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
++		exit(FAIL);
++	}
++
++	setup_logpipes(logfds);
++
++	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_use_config with invalid config num\n");
++
++	if ((!knet_handle_crypto_use_config(knet_h, KNET_MAX_CRYPTO_INSTANCES + 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_use_config accepted invalid config num (%u) or returned incorrect error: %s\n", KNET_MAX_CRYPTO_INSTANCES + 1, strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_use_config with un-initialized cfg\n");
++
++	if ((!knet_handle_crypto_use_config(knet_h, 1)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_use_config accepted invalid un-initialized cfg (1): %d\n", errno);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if ((!knet_handle_crypto_use_config(knet_h, 2)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_use_config accepted invalid un-initialized cfg (2)\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and normal key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
++		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_use_config with un-initialized cfg (part 2)\n");
++
++	if ((!knet_handle_crypto_use_config(knet_h, 2)) || (errno != EINVAL)) {
++		printf("knet_handle_crypto_use_config accepted invalid un-initialized cfg (2)\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if ((knet_handle_crypto_use_config(knet_h, 1)) < 0) {
++		printf("knet_handle_crypto_use_config did not accept valid config (1)\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_set_config for second config with %s/aes128/sha1 and normal key\n", model);
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2)) {
++		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Test knet_handle_crypto_use_config with valid data\n");
++
++	if ((knet_handle_crypto_use_config(knet_h, 2)) < 0) {
++		printf("knet_handle_crypto_use_config did not accept valid config (1)\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->crypto_in_use_config != 2) {
++		printf("knet_handle_crypto_set_config failed to set crypto in-use config to 2\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	printf("Shutdown crypto\n");
++
++	printf("Test knet_handle_crypto_use_config with valid data\n");
++
++	if ((knet_handle_crypto_use_config(knet_h, 0)) < 0) {
++		printf("knet_handle_crypto_use_config did not accept valid config (1)\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->crypto_in_use_config != 0) {
++		printf("knet_handle_crypto_set_config failed to set crypto in-use config to 2\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, "none", sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) < 0) {
++		printf("Unable to shutdown crypto: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->crypto_instance[1]) {
++		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) < 0) {
++		printf("Unable to shutdown crypto: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	if (knet_h->crypto_instance[2]) {
++		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	knet_handle_free(knet_h);
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++}
++
++int main(int argc, char *argv[])
++{
++	struct knet_crypto_info crypto_list[16];
++	size_t crypto_list_entries;
++	size_t i;
++
++	memset(crypto_list, 0, sizeof(crypto_list));
++
++	if (knet_get_crypto_list(crypto_list, &crypto_list_entries) < 0) {
++		printf("knet_get_crypto_list failed: %s\n", strerror(errno));
++		return FAIL;
++	}
++
++	if (crypto_list_entries == 0) {
++		printf("no crypto modules detected. Skipping\n");
++		return SKIP;
++	}
++
++	for (i=0; i < crypto_list_entries; i++) {
++		test(crypto_list[i].name, crypto_list[0].name);
++	}
++
++	return PASS;
++}
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+new file mode 100644
+index 00000000..6adb51da
+--- /dev/null
++++ b/libknet/tests/fun_config_crypto.c
+@@ -0,0 +1,281 @@
++/*
++ * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++
++#include "libknet.h"
++
++#include "compress.h"
++#include "internals.h"
++#include "netutils.h"
++#include "test-common.h"
++
++#define TESTNODES 2
++
++static void test(const char *model)
++{
++	knet_handle_t knet_h[TESTNODES + 1];
++	int logfds[2];
++	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
++	int i,x,j;
++	int seconds = 10;
++
++	if (is_memcheck() || is_helgrind()) {
++		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
++		seconds = seconds * 16;
++	}
++
++	setup_logpipes(logfds);
++
++	knet_handle_start_nodes(knet_h, TESTNODES, logfds, KNET_LOG_DEBUG);
++
++	flush_logs(logfds[0], stdout);
++
++	/*
++	 * config1: aes128/sha256 key1 is all 0s (2000 bytes)
++	 */
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha256", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	memset(knet_handle_crypto_cfg.private_key, 0, KNET_MAX_KEY_LEN);
++	knet_handle_crypto_cfg.private_key_len = 2000;
++
++	for (i = 1; i <= TESTNODES; i++) {
++		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 1) < 0) {
++			printf("knet_handle_crypto_set_config (1) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++		if (knet_handle_crypto_use_config(knet_h[i], 1) < 0) {
++			printf("knet_handle_crypto_use_config (1) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++		if (knet_handle_crypto_rx_clear_traffic(knet_h[i], KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC)) {
++			printf("knet_handle_crypto_rx_clear_traffic failed: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	knet_handle_join_nodes(knet_h, TESTNODES, 1, AF_INET, KNET_TRANSPORT_UDP);
++
++	flush_logs(logfds[0], stdout);
++
++	/*
++	 * config2: aes256/sha512 key1 is all 1s (KNET_MAX_KEY_LEN bytes)
++	 */
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes256", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha512", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	memset(knet_handle_crypto_cfg.private_key, 1, KNET_MAX_KEY_LEN);
++	knet_handle_crypto_cfg.private_key_len = KNET_MAX_KEY_LEN;
++
++	for (i = 1; i <= TESTNODES; i++) {
++		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 2) < 0) {
++			printf("knet_handle_crypto_set_config (2) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Testing crypto config switch from 1 to 2\n");
++
++	for (i = 1; i <= TESTNODES; i++) {
++		if (knet_handle_crypto_use_config(knet_h[i], 2) < 0) {
++			printf("knet_handle_crypto_use_config (2) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++		for (x = 0; x < seconds; x++){
++			flush_logs(logfds[0], stdout);
++			sleep(1);
++			x++;
++		}
++		for (x = 1; x <= TESTNODES; x++) {
++			for (j = 1; j <= TESTNODES; j++) {
++				if (j == x) {
++					continue;
++				}
++				if (knet_h[x]->host_index[j]->status.reachable != 1) {
++					printf("knet failed to switch config for host %d\n", x);
++					knet_handle_stop_nodes(knet_h, TESTNODES);
++					flush_logs(logfds[0], stdout);
++					close_logpipes(logfds);
++					exit(FAIL);
++				}
++			}
++		}
++	}
++
++	flush_logs(logfds[0], stdout);
++
++	printf("Testing crypto config switch from 2 to 1\n");
++
++	for (i = 1; i <= TESTNODES; i++) {
++		if (knet_handle_crypto_use_config(knet_h[i], 1) < 0) {
++			printf("knet_handle_crypto_use_config (1) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++		for (x = 0; x < seconds; x++){
++			flush_logs(logfds[0], stdout);
++			sleep(1);
++			x++;
++		}
++		for (x = 1; x <= TESTNODES; x++) {
++			for (j = 1; j <= TESTNODES; j++) {
++				if (j == x) {
++					continue;
++				}
++				if (knet_h[x]->host_index[j]->status.reachable != 1) {
++					printf("knet failed to switch config for host %d\n", x);
++					knet_handle_stop_nodes(knet_h, TESTNODES);
++					flush_logs(logfds[0], stdout);
++					close_logpipes(logfds);
++					exit(FAIL);
++				}
++			}
++		}
++	}
++
++	printf("Testing disable crypto config and allow clear traffic\n");
++
++	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	strncpy(knet_handle_crypto_cfg.crypto_model, "none", sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
++	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
++	memset(knet_handle_crypto_cfg.private_key, 0, KNET_MAX_KEY_LEN);
++	knet_handle_crypto_cfg.private_key_len = KNET_MAX_KEY_LEN;
++
++	for (i = 1; i <= TESTNODES; i++) {
++		/*
++		 * config2 is no longer in use
++		 */
++		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 2) < 0) {
++			printf("knet_handle_crypto_set_config (2) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++		/*
++		 * allow clear traffic on RX on all nodes, before we change config to clear traffic
++		 */
++		if (knet_handle_crypto_rx_clear_traffic(knet_h[i], KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC)) {
++			printf("knet_handle_crypto_rx_clear_traffic failed: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++	}
++
++	for (i = 1; i <= TESTNODES; i++) {
++		/*
++		 * switch to clear traffic on RX on all nodes
++		 */
++		if (knet_handle_crypto_use_config(knet_h[i], 0) < 0) {
++			printf("knet_handle_crypto_use_config (0) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++	}
++
++
++	for (i = 1; i <= TESTNODES; i++) {
++		/*
++		 * config1 is no longer in use
++		 */
++		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 1) < 0) {
++			printf("knet_handle_crypto_set_config (2) failed with correct config: %s\n", strerror(errno));
++			knet_handle_stop_nodes(knet_h, TESTNODES);
++			flush_logs(logfds[0], stdout);
++			close_logpipes(logfds);
++			exit(FAIL);
++		}
++	}
++
++	for (i = 1; i <= TESTNODES; i++) {
++		for (x = 0; x < seconds; x++){
++			flush_logs(logfds[0], stdout);
++			sleep(1);
++			x++;
++		}
++		for (x = 1; x <= TESTNODES; x++) {
++			for (j = 1; j <= TESTNODES; j++) {
++				if (j == x) {
++					continue;
++				}
++				if (knet_h[x]->host_index[j]->status.reachable != 1) {
++					printf("knet failed to switch config for host %d\n", x);
++					knet_handle_stop_nodes(knet_h, TESTNODES);
++					flush_logs(logfds[0], stdout);
++					close_logpipes(logfds);
++					exit(FAIL);
++				}
++			}
++		}
++	}
++
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++	knet_handle_stop_nodes(knet_h, TESTNODES);
++}
++
++int main(int argc, char *argv[])
++{
++	struct knet_crypto_info crypto_list[16];
++	size_t crypto_list_entries;
++	size_t i;
++
++	memset(crypto_list, 0, sizeof(crypto_list));
++
++	if (knet_get_crypto_list(crypto_list, &crypto_list_entries) < 0) {
++		printf("knet_get_crypto_list failed: %s\n", strerror(errno));
++		return FAIL;
++	}
++
++	if (crypto_list_entries == 0) {
++		printf("no crypto modules detected. Skipping\n");
++		return SKIP;
++	}
++
++	for (i=0; i < crypto_list_entries; i++) {
++		test(crypto_list[i].name);
++	}
++
++	return PASS;
++}
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 3b6ca161..df3d5d17 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -70,7 +70,7 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		pthread_mutex_unlock(&knet_h->tx_seq_num_mutex);
+ 		knet_h->pingbuf->khp_ping_timed = timed;
+ 
+-		if (knet_h->crypto_instance) {
++		if (knet_h->crypto_in_use_config) {
+ 			if (crypto_encrypt_and_sign(knet_h,
+ 						    (const unsigned char *)knet_h->pingbuf,
+ 						    outlen,
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 2c4a2630..b4432898 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -136,7 +136,7 @@ restart:
+ 	 */
+ 	data_len = app_mtu_len + knet_h->sec_hash_size + knet_h->sec_salt_size + KNET_HEADER_ALL_SIZE;
+ 
+-	if (knet_h->crypto_instance) {
++	if (knet_h->crypto_in_use_config) {
+ 		if (data_len < (knet_h->sec_hash_size + knet_h->sec_salt_size) + 1) {
+ 			log_debug(knet_h, KNET_SUB_PMTUD, "Aborting PMTUD process: link mtu smaller than crypto header detected (link might have been disconnected)");
+ 			return -1;
+@@ -308,7 +308,7 @@ retry:
+ 			return -1;
+ 		}
+ 
+-		if (knet_h->crypto_instance) {
++		if (knet_h->crypto_in_use_config) {
+ 			/*
+ 			 * crypto, under pressure, is a royal PITA
+ 			 */
+@@ -350,7 +350,7 @@ retry:
+ 
+ 		if (ret) {
+ 			if (ret == ETIMEDOUT) {
+-				if ((knet_h->crypto_instance) && (dst_link->pmtud_crypto_timeout_multiplier < KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MAX)) {
++				if ((knet_h->crypto_in_use_config) && (dst_link->pmtud_crypto_timeout_multiplier < KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MAX)) {
+ 					dst_link->pmtud_crypto_timeout_multiplier = dst_link->pmtud_crypto_timeout_multiplier * 2;
+ 					pmtud_crypto_reduce = 0;
+ 					log_debug(knet_h, KNET_SUB_PMTUD,
+@@ -389,7 +389,7 @@ retry:
+ 			}
+ 		}
+ 
+-		if ((knet_h->crypto_instance) && (pmtud_crypto_reduce == 1) &&
++		if ((knet_h->crypto_in_use_config) && (pmtud_crypto_reduce == 1) &&
+ 		    (dst_link->pmtud_crypto_timeout_multiplier > KNET_LINK_PMTUD_CRYPTO_TIMEOUT_MULTIPLIER_MIN)) {
+ 			if (!clock_gettime(CLOCK_MONOTONIC, &pmtud_crypto_stop_ts)) {
+ 				timespec_diff(pmtud_crypto_start_ts, pmtud_crypto_stop_ts, &timediff);
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 880174c1..bff7dbad 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -247,12 +247,24 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	struct sockaddr_storage pckt_src;
+ 	seq_num_t recv_seq_num;
+ 	int wipe_bufs = 0;
++	int try_decrypt = 0, decrypted = 0, i;
+ 
+-	if (knet_h->crypto_instance) {
++	for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
++		if (knet_h->crypto_instance[i]) {
++			try_decrypt = 1;
++			break;
++		}
++	}
++
++	if ((!try_decrypt) && (knet_h->crypto_only == KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC)) {
++		log_debug(knet_h, KNET_SUB_RX, "RX thread configured to accept only crypto packets, but no crypto configs are configured!");
++		return;
++	}
++
++	if (try_decrypt) {
+ 		struct timespec start_time;
+ 		struct timespec end_time;
+ 
+-
+ 		clock_gettime(CLOCK_MONOTONIC, &start_time);
+ 		if (crypto_authenticate_and_decrypt(knet_h,
+ 						    (unsigned char *)inbuf,
+@@ -260,13 +272,18 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 						    knet_h->recv_from_links_buf_decrypt,
+ 						    &outlen) < 0) {
+ 			log_debug(knet_h, KNET_SUB_RX, "Unable to decrypt/auth packet");
+-			return;
+-		}
+-		clock_gettime(CLOCK_MONOTONIC, &end_time);
+-		timespec_diff(start_time, end_time, &decrypt_time);
++			if (knet_h->crypto_only == KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
++				return;
++			}
++			log_debug(knet_h, KNET_SUB_RX, "Attempting to process packet as clear data");
++		} else {
++			clock_gettime(CLOCK_MONOTONIC, &end_time);
++			timespec_diff(start_time, end_time, &decrypt_time);
+ 
+-		len = outlen;
+-		inbuf = (struct knet_header *)knet_h->recv_from_links_buf_decrypt;
++			len = outlen;
++			inbuf = (struct knet_header *)knet_h->recv_from_links_buf_decrypt;
++			decrypted = 1;
++		}
+ 	}
+ 
+ 	if (len < (ssize_t)(KNET_HEADER_SIZE + 1)) {
+@@ -419,7 +436,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		}
+ 
+ 		if (inbuf->kh_type == KNET_HEADER_TYPE_DATA) {
+-			if (knet_h->crypto_instance) {
++			if (decrypted) {
+ 				stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
+ 				if (stats_err < 0) {
+ 					pthread_mutex_unlock(&src_link->link_stats_mutex);
+@@ -597,7 +614,7 @@ retry:
+ 			}
+ 		}
+ 
+-		if (knet_h->crypto_instance) {
++		if (knet_h->crypto_in_use_config) {
+ 			if (crypto_encrypt_and_sign(knet_h,
+ 						    (const unsigned char *)inbuf,
+ 						    outlen,
+@@ -716,7 +733,7 @@ retry_pong:
+ 		inbuf->kh_type = KNET_HEADER_TYPE_PMTUD_REPLY;
+ 		inbuf->kh_node = htons(knet_h->host_id);
+ 
+-		if (knet_h->crypto_instance) {
++		if (knet_h->crypto_in_use_config) {
+ 			if (crypto_encrypt_and_sign(knet_h,
+ 						    (const unsigned char *)inbuf,
+ 						    outlen,
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index d5539a1e..be5fb6b2 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -503,7 +503,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 		iovcnt_out = 1;
+ 	}
+ 
+-	if (knet_h->crypto_instance) {
++	if (knet_h->crypto_in_use_config) {
+ 		struct timespec start_time;
+ 		struct timespec end_time;
+ 		uint64_t crypt_time;
+diff --git a/man/Makefile.am b/man/Makefile.am
+index f813b97d..5223f595 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -103,7 +103,10 @@ knet_man3_MANS = \
+ 		knet_link_add_acl.3 \
+ 		knet_link_insert_acl.3 \
+ 		knet_link_rm_acl.3 \
+-		knet_link_clear_acl.3
++		knet_link_clear_acl.3 \
++		knet_handle_crypto_set_config.3 \
++		knet_handle_crypto_use_config.3 \
++		knet_handle_crypto_rx_clear_traffic.3
+ 
+ if BUILD_LIBNOZZLE
+ nozzle_man3_MANS = \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0380-Update-copyright.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0380-Update-copyright.patch
new file mode 100644
index 000000000..230d5eedc
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0380-Update-copyright.patch
@@ -0,0 +1,57 @@ 
+From ef64a781c0529b874868345b0b054fbaed1e45ae Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 9 Jul 2020 15:08:58 +0200
+Subject: [PATCH] Update copyright
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c | 2 +-
+ libknet/tests/api_knet_handle_crypto_set_config.c       | 2 +-
+ libknet/tests/api_knet_handle_crypto_use_config.c       | 2 +-
+ libknet/tests/fun_config_crypto.c                       | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+index d62bd776..cbd87e22 100644
+--- a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
++++ b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto_set_config.c b/libknet/tests/api_knet_handle_crypto_set_config.c
+index 520249f4..b4e398ba 100644
+--- a/libknet/tests/api_knet_handle_crypto_set_config.c
++++ b/libknet/tests/api_knet_handle_crypto_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto_use_config.c b/libknet/tests/api_knet_handle_crypto_use_config.c
+index 2f1974dc..d9dd0040 100644
+--- a/libknet/tests/api_knet_handle_crypto_use_config.c
++++ b/libknet/tests/api_knet_handle_crypto_use_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+index 6adb51da..02c5e286 100644
+--- a/libknet/tests/fun_config_crypto.c
++++ b/libknet/tests/fun_config_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2019 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0381-tests-fix-variable-increment-logic-detected-by-clang.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0381-tests-fix-variable-increment-logic-detected-by-clang.patch
new file mode 100644
index 000000000..edfdb5694
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0381-tests-fix-variable-increment-logic-detected-by-clang.patch
@@ -0,0 +1,47 @@ 
+From 53b0f39a0056b461fbe0a310322e0e40e8773ecb Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 10 Jul 2020 05:00:49 +0200
+Subject: [PATCH] [tests] fix variable increment logic (detected by clang)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/tests/fun_config_crypto.c | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+index 02c5e286..2a4b5df1 100644
+--- a/libknet/tests/fun_config_crypto.c
++++ b/libknet/tests/fun_config_crypto.c
+@@ -30,7 +30,7 @@ static void test(const char *model)
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 	int i,x,j;
+-	int seconds = 10;
++	int seconds = 5;
+ 
+ 	if (is_memcheck() || is_helgrind()) {
+ 		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
+@@ -118,7 +118,6 @@ static void test(const char *model)
+ 		for (x = 0; x < seconds; x++){
+ 			flush_logs(logfds[0], stdout);
+ 			sleep(1);
+-			x++;
+ 		}
+ 		for (x = 1; x <= TESTNODES; x++) {
+ 			for (j = 1; j <= TESTNODES; j++) {
+@@ -151,7 +150,6 @@ static void test(const char *model)
+ 		for (x = 0; x < seconds; x++){
+ 			flush_logs(logfds[0], stdout);
+ 			sleep(1);
+-			x++;
+ 		}
+ 		for (x = 1; x <= TESTNODES; x++) {
+ 			for (j = 1; j <= TESTNODES; j++) {
+@@ -232,7 +230,6 @@ static void test(const char *model)
+ 		for (x = 0; x < seconds; x++){
+ 			flush_logs(logfds[0], stdout);
+ 			sleep(1);
+-			x++;
+ 		}
+ 		for (x = 1; x <= TESTNODES; x++) {
+ 			for (j = 1; j <= TESTNODES; j++) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0382-tests-ignore-openssl-errors-triggered-when-building-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0382-tests-ignore-openssl-errors-triggered-when-building-.patch
new file mode 100644
index 000000000..d6c515ebb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0382-tests-ignore-openssl-errors-triggered-when-building-.patch
@@ -0,0 +1,133 @@ 
+From 664c9a8badbdf3e97896e3571795a87cd43d3aa5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 10 Jul 2020 17:51:53 +0200
+Subject: [PATCH] [tests] ignore openssl errors triggered when building with
+ clang
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 113 ++++++++++++++++++++++----
+ 1 file changed, 98 insertions(+), 15 deletions(-)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 9956ca8a..89bb3fd1 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -257,19 +257,102 @@
+   fun:clone
+ }
+ {
+-   nss internal leak (3.41) non recurring (spotted on f29)
+-   Memcheck:Leak
+-   match-leak-kinds: definite
+-   fun:malloc
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:*
+-   obj:/usr/lib64/libnss3.so
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2020-07-10)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2020-07-10)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2020-07-10)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++}
++{
++  openssl internals (spotted on Ubuntu Devel x86-64 - 2020-07-10)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:_handle_check_each
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  nss internal leak (3.41) non recurring (spotted on f29)
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:/usr/lib64/libnss3.so
++}
++{
++  nss internal leak (3.41) non recurring
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:calloc
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  fun:init_nss
++  fun:nsscrypto_init
++  fun:crypto_init
++  fun:knet_handle_crypto_set_config
++  fun:test
++  fun:main
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0383-tests-more-ignore-list-of-nss-internal-stuff.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0383-tests-more-ignore-list-of-nss-internal-stuff.patch
new file mode 100644
index 000000000..85806352e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0383-tests-more-ignore-list-of-nss-internal-stuff.patch
@@ -0,0 +1,35 @@ 
+From 445d1851d2f33dec73caebe2d7f9d18463bbdd0e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 13 Jul 2020 11:47:47 +0200
+Subject: [PATCH] [tests] more ignore list of nss internal stuff
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 17 +++++++++++++++++
+ 1 file changed, 17 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 89bb3fd1..06a3ec00 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -356,3 +356,20 @@
+   fun:test
+   fun:main
+ }
++{
++  nss internal leak (3.41) non recurring
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  fun:init_nss
++  fun:nsscrypto_init
++  fun:crypto_init
++  fun:knet_handle_crypto_set_config
++  fun:test
++  fun:main
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0384-man-fix-type-comparison.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0384-man-fix-type-comparison.patch
new file mode 100644
index 000000000..6801a4f6b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0384-man-fix-type-comparison.patch
@@ -0,0 +1,23 @@ 
+From e0eecbe044286fb1b98d29c428f18386f7b73b59 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 14 Jul 2020 16:27:48 +0200
+Subject: [PATCH] [man] fix type comparison
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/doxyxml.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 278c1883..880734a1 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -409,7 +409,7 @@ static int read_structure_from_xml(const char *refid, const char *name)
+ static char *allcaps(const char *name)
+ {
+ 	static char buffer[1024] = {'\0'};
+-	int i;
++	size_t i;
+ 
+ 	for (i=0; i< strlen(name); i++) {
+ 		buffer[i] = toupper(name[i]);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0385-f6b11c05112c520ccda3b28e7676acbc6b8a7938.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0385-f6b11c05112c520ccda3b28e7676acbc6b8a7938.patch
new file mode 100644
index 000000000..9a996f00f
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0385-f6b11c05112c520ccda3b28e7676acbc6b8a7938.patch
@@ -0,0 +1,23 @@ 
+From 0ee62c2cfea6e3937f0d68380f7e30c2961b0690 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 14 Jul 2020 16:31:12 +0200
+Subject: [PATCH] f6b11c05112c520ccda3b28e7676acbc6b8a7938
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 3550a86a..3127642a 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -18,7 +18,7 @@ EXTRA_DIST		= $(SYMFILE)
+ SUBDIRS			= . tests
+ 
+ # https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
+-libversion		= 4:0:3
++libversion		= 5:0:4
+ 
+ # override global LIBS that pulls in lots of craft we don't need here
+ LIBS			=
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0386-crypto-add-support-for-openssl-3.0.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0386-crypto-add-support-for-openssl-3.0.patch
new file mode 100644
index 000000000..8bcb58e5a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0386-crypto-add-support-for-openssl-3.0.patch
@@ -0,0 +1,228 @@ 
+From 5d2cdac08bd876719015439a958342683b3195e4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 15 Jul 2020 10:02:15 +0200
+Subject: [PATCH] [crypto] add support for openssl 3.0
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 137 +++++++++++++++++++++++++++++++++------
+ 1 file changed, 116 insertions(+), 21 deletions(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 5ae663cf..e3618e90 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -9,25 +9,17 @@
+ 
+ #include "config.h"
+ 
+-/*
+- * allow to build with openssl 3.0 that has deprecated
+- * use of direct access to HMAC API.
+- *
+- * knet will require some heavy rewrite to port to 3.0,
+- * but it clashes with the re-key feature branch.
+- *
+- * use path of less resistance for now, then we will
+- * port at a later stage.
+- */
+-#define OPENSSL_API_COMPAT 0x1010000L
+-
+ #include <string.h>
+ #include <errno.h>
+ #include <dlfcn.h>
+ #include <stdlib.h>
+ #include <openssl/conf.h>
+ #include <openssl/evp.h>
++#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
+ #include <openssl/hmac.h>
++#else
++#include <openssl/mac.h>
++#endif
+ #include <openssl/rand.h>
+ #include <openssl/err.h>
+ 
+@@ -46,6 +38,15 @@
+ 
+ #define SALT_SIZE 16
+ 
++/*
++ * required by OSSL_PARAM_construct_*
++ * making them global and cost, saves 2 strncpy and some memory on each config
++ */
++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
++static const char *hash = "digest";
++static const char *key = "key";
++#endif
++
+ struct opensslcrypto_instance {
+ 	void *private_key;
+ 
+@@ -54,6 +55,11 @@ struct opensslcrypto_instance {
+ 	const EVP_CIPHER *crypto_cipher_type;
+ 
+ 	const EVP_MD *crypto_hash_type;
++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
++	EVP_MAC *crypto_hash_mac;
++	OSSL_PARAM params[3];
++	char hash_type[16]; /* Need to store a copy from knet_handle_crypto_cfg for OSSL_PARAM_construct_* */
++#endif
+ };
+ 
+ static int openssl_is_init = 0;
+@@ -298,6 +304,7 @@ out:
+  * hash/hmac/digest functions
+  */
+ 
++#if (OPENSSL_VERSION_NUMBER < 0x30000000L)
+ static int calculate_openssl_hash(
+ 	knet_handle_t knet_h,
+ 	struct crypto_instance *crypto_instance,
+@@ -328,6 +335,66 @@ static int calculate_openssl_hash(
+ 
+ 	return 0;
+ }
++#else
++static int calculate_openssl_hash(
++	knet_handle_t knet_h,
++	struct crypto_instance *crypto_instance,
++	const unsigned char *buf,
++	const size_t buf_len,
++	unsigned char *hash,
++	uint8_t log_level)
++{
++	struct opensslcrypto_instance *instance = crypto_instance->model_instance;
++	EVP_MAC_CTX *ctx = NULL;
++	char sslerr[SSLERR_BUF_SIZE];
++	int err = 0;
++	size_t outlen = 0;
++
++	ctx = EVP_MAC_new_ctx(instance->crypto_hash_mac);
++	if (!ctx) {
++		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate openssl context: %s", sslerr);
++		err = -1;
++		goto out_err;
++	}
++
++	if (EVP_MAC_set_ctx_params(ctx, instance->params) < 0) {
++		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to set openssl context parameters: %s", sslerr);
++		err = -1;
++		goto out_err;
++	}
++
++	if (!EVP_MAC_init(ctx)) {
++		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to set openssl context parameters: %s", sslerr);
++		err = -1;
++		goto out_err;
++	}
++
++	if (!EVP_MAC_update(ctx, buf, buf_len)) {
++		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to update hash: %s", sslerr);
++		err = -1;
++		goto out_err;
++	}
++
++	if (!EVP_MAC_final(ctx, hash, &outlen, crypto_instance->sec_hash_size)) {
++		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to finalize hash: %s", sslerr);
++		err = -1;
++		goto out_err;
++	}
++
++out_err:
++	if (ctx) {
++		EVP_MAC_free_ctx(ctx);
++	}
++
++	return err;
++
++}
++#endif
+ 
+ /*
+  * exported API
+@@ -518,6 +585,11 @@ static void opensslcrypto_fini(
+ 			free(opensslcrypto_instance->private_key);
+ 			opensslcrypto_instance->private_key = NULL;
+ 		}
++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
++		if (opensslcrypto_instance->crypto_hash_mac) {
++			EVP_MAC_free(opensslcrypto_instance->crypto_hash_mac);
++		}
++#endif
+ 		free(opensslcrypto_instance);
+ 		crypto_instance->model_instance = NULL;
+ 	}
+@@ -536,6 +608,10 @@ static int opensslcrypto_init(
+ {
+ 	struct opensslcrypto_instance *opensslcrypto_instance = NULL;
+ 	int savederrno;
++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
++	char sslerr[SSLERR_BUF_SIZE];
++	size_t params_n = 0;
++#endif
+ 
+ 	log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO,
+ 		  "Initizializing openssl crypto module [%s/%s]",
+@@ -573,6 +649,15 @@ static int opensslcrypto_init(
+ 
+ 	memset(opensslcrypto_instance, 0, sizeof(struct opensslcrypto_instance));
+ 
++	opensslcrypto_instance->private_key = malloc(knet_handle_crypto_cfg->private_key_len);
++	if (!opensslcrypto_instance->private_key) {
++		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate memory for openssl private key");
++		savederrno = ENOMEM;
++		goto out_err;
++	}
++	memmove(opensslcrypto_instance->private_key, knet_handle_crypto_cfg->private_key, knet_handle_crypto_cfg->private_key_len);
++	opensslcrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len;
++
+ 	if (strcmp(knet_handle_crypto_cfg->crypto_cipher_type, "none") == 0) {
+ 		opensslcrypto_instance->crypto_cipher_type = NULL;
+ 	} else {
+@@ -593,6 +678,25 @@ static int opensslcrypto_init(
+ 			savederrno = ENXIO;
+ 			goto out_err;
+ 		}
++
++#if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
++		opensslcrypto_instance->crypto_hash_mac = EVP_MAC_fetch(NULL, "HMAC", NULL);
++		if (!opensslcrypto_instance->crypto_hash_mac) {
++			ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
++			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "unable to fetch HMAC: %s", sslerr);
++			savederrno = ENXIO;
++			goto out_err;
++		}
++
++		/*
++		 * OSSL_PARAM_construct_* store pointers to the data, it´s important that the referenced data are per-instance
++		 */
++		memmove(opensslcrypto_instance->hash_type, knet_handle_crypto_cfg->crypto_hash_type, sizeof(opensslcrypto_instance->hash_type));
++
++		opensslcrypto_instance->params[params_n++] = OSSL_PARAM_construct_utf8_string(hash, opensslcrypto_instance->hash_type, 0);
++		opensslcrypto_instance->params[params_n++] = OSSL_PARAM_construct_octet_string(key, opensslcrypto_instance->private_key, opensslcrypto_instance->private_key_len);
++		opensslcrypto_instance->params[params_n] = OSSL_PARAM_construct_end();
++#endif
+ 	}
+ 
+ 	if ((opensslcrypto_instance->crypto_cipher_type) &&
+@@ -602,15 +706,6 @@ static int opensslcrypto_init(
+ 		goto out_err;
+ 	}
+ 
+-	opensslcrypto_instance->private_key = malloc(knet_handle_crypto_cfg->private_key_len);
+-	if (!opensslcrypto_instance->private_key) {
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate memory for openssl private key");
+-		savederrno = ENOMEM;
+-		goto out_err;
+-	}
+-	memmove(opensslcrypto_instance->private_key, knet_handle_crypto_cfg->private_key, knet_handle_crypto_cfg->private_key_len);
+-	opensslcrypto_instance->private_key_len = knet_handle_crypto_cfg->private_key_len;
+-
+ 	if (opensslcrypto_instance->crypto_hash_type) {
+ 		crypto_instance->sec_hash_size = EVP_MD_size(opensslcrypto_instance->crypto_hash_type);
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0387-cleanup-Move-public-APIs-calls-to-more-suitable-loca.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0387-cleanup-Move-public-APIs-calls-to-more-suitable-loca.patch
new file mode 100644
index 000000000..081aba708
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0387-cleanup-Move-public-APIs-calls-to-more-suitable-loca.patch
@@ -0,0 +1,2565 @@ 
+From 816d2cc5f869f7e000b1aa70f12eeded234ded32 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 15 Jul 2020 15:15:22 +0200
+Subject: [PATCH] [cleanup] Move public APIs calls to more suitable location
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am     |    1 +
+ libknet/compress.c      |   34 +-
+ libknet/compress.h      |    4 -
+ libknet/crypto.c        |  219 +++++++-
+ libknet/crypto.h        |    9 -
+ libknet/handle.c        | 1115 ---------------------------------------
+ libknet/handle_api.c    |  602 +++++++++++++++++++++
+ libknet/threads_pmtud.c |  162 ++++++
+ libknet/threads_rx.c    |   63 +++
+ libknet/threads_tx.c    |  204 ++++---
+ 10 files changed, 1212 insertions(+), 1201 deletions(-)
+ create mode 100644 libknet/handle_api.c
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 3127642a..dd16fd40 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -29,6 +29,7 @@ sources			= \
+ 			  compress.c \
+ 			  crypto.c \
+ 			  handle.c \
++			  handle_api.c \
+ 			  host.c \
+ 			  links.c \
+ 			  links_acl.c \
+diff --git a/libknet/compress.c b/libknet/compress.c
+index f62861d6..ec6f16d8 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -273,7 +273,7 @@ int compress_init(
+ 	return 0;
+ }
+ 
+-int compress_cfg(
++static int compress_cfg(
+ 	knet_handle_t knet_h,
+ 	struct knet_handle_compress_cfg *knet_handle_compress_cfg)
+ {
+@@ -485,6 +485,38 @@ out_unlock:
+ 	return err;
+ }
+ 
++int knet_handle_compress(knet_handle_t knet_h, struct knet_handle_compress_cfg *knet_handle_compress_cfg)
++{
++	int savederrno = 0;
++	int err = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!knet_handle_compress_cfg) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	compress_fini(knet_h, 0);
++	err = compress_cfg(knet_h, knet_handle_compress_cfg);
++	savederrno = errno;
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
+ int knet_get_compress_list(struct knet_compress_info *compress_list, size_t *compress_list_entries)
+ {
+ 	int err = 0;
+diff --git a/libknet/compress.h b/libknet/compress.h
+index 95464e82..c0f28f19 100644
+--- a/libknet/compress.h
++++ b/libknet/compress.h
+@@ -11,10 +11,6 @@
+ 
+ #include "internals.h"
+ 
+-int compress_cfg(
+-	knet_handle_t knet_h,
+-	struct knet_handle_compress_cfg *knet_handle_compress_cfg);
+-
+ int compress_init(
+ 	knet_handle_t knet_h);
+ 
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 0c475d0f..28d29ef3 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -123,7 +123,7 @@ int crypto_authenticate_and_decrypt (
+ 	return err;
+ }
+ 
+-int crypto_use_config(
++static int crypto_use_config(
+ 	knet_handle_t knet_h,
+ 	uint8_t config_num)
+ {
+@@ -149,7 +149,7 @@ int crypto_use_config(
+ 	return 0;
+ }
+ 
+-int crypto_init(
++static int crypto_init(
+ 	knet_handle_t knet_h,
+ 	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
+ 	uint8_t config_num)
+@@ -291,6 +291,154 @@ void crypto_fini(
+ 	return;
+ }
+ 
++static int _knet_handle_crypto_set_config(knet_handle_t knet_h,
++				  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++				  uint8_t config_num,
++				  uint8_t force)
++{
++	int savederrno = 0;
++	int err = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!knet_handle_crypto_cfg) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((config_num < 1) || (config_num > KNET_MAX_CRYPTO_INSTANCES)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if ((knet_h->crypto_in_use_config == config_num) && (!force)) {
++		savederrno = EBUSY;
++		err = -1;
++		goto exit_unlock;
++	}
++
++	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) ||
++	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
++	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
++		crypto_fini(knet_h, config_num);
++		log_debug(knet_h, KNET_SUB_CRYPTO, "crypto config %u is not enabled", config_num);
++		err = 0;
++		goto exit_unlock;
++	}
++
++	if (knet_handle_crypto_cfg->private_key_len < KNET_MIN_KEY_LEN) {
++		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too short for config %u (min %d): %u",
++			  config_num, KNET_MIN_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
++		savederrno = EINVAL;
++		err = -1;
++		goto exit_unlock;
++	}
++
++	if (knet_handle_crypto_cfg->private_key_len > KNET_MAX_KEY_LEN) {
++		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too long for config %u (max %d): %u",
++			  config_num, KNET_MAX_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
++		savederrno = EINVAL;
++		err = -1;
++		goto exit_unlock;
++	}
++
++	err = crypto_init(knet_h, knet_handle_crypto_cfg, config_num);
++
++	if (err) {
++		err = -2;
++		savederrno = errno;
++	}
++
++exit_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++int knet_handle_crypto_set_config(knet_handle_t knet_h,
++				  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
++				  uint8_t config_num)
++{
++	return _knet_handle_crypto_set_config(knet_h, knet_handle_crypto_cfg, config_num, 0);
++}
++
++int knet_handle_crypto_rx_clear_traffic(knet_handle_t knet_h,
++					uint8_t value)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (value > KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->crypto_only = value;
++	if (knet_h->crypto_only) {
++		log_debug(knet_h, KNET_SUB_CRYPTO, "Only crypto traffic allowed for RX");
++	} else {
++		log_debug(knet_h, KNET_SUB_CRYPTO, "Both crypto and clear traffic allowed for RX");
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	return 0;
++}
++
++int knet_handle_crypto_use_config(knet_handle_t knet_h,
++				  uint8_t config_num)
++{
++	int savederrno = 0;
++	int err = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (config_num > KNET_MAX_CRYPTO_INSTANCES) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	err = crypto_use_config(knet_h, config_num);
++	savederrno = errno;
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
+ int knet_get_crypto_list(struct knet_crypto_info *crypto_list, size_t *crypto_list_entries)
+ {
+ 	int err = 0;
+@@ -317,3 +465,70 @@ int knet_get_crypto_list(struct knet_crypto_info *crypto_list, size_t *crypto_li
+ 		errno = 0;
+ 	return err;
+ }
++
++/*
++ * compatibility wrapper for 1.x releases
++ */
++int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
++{
++	int err = 0;
++	uint8_t value;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	value = knet_h->crypto_only;
++	/*
++	 * configure crypto in slot 1
++	 */
++	err = _knet_handle_crypto_set_config(knet_h, knet_handle_crypto_cfg, 1, 1);
++	if (err < 0) {
++		return err;
++	}
++
++	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) ||
++	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
++	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
++		err = knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC);
++		if (err < 0) {
++			return err;
++		}
++
++		/*
++		 * start using clear traffic
++		 */
++		err = knet_handle_crypto_use_config(knet_h, 0);
++		if (err < 0) {
++			err = knet_handle_crypto_rx_clear_traffic(knet_h, value);
++			if (err < 0) {
++				/*
++				 * force attempt or things will go bad
++				 */
++				knet_h->crypto_only = value;
++			}
++		}
++		return err;
++	} else {
++		err = knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC);
++		if (err < 0) {
++			return err;
++		}
++
++		/*
++		 * start using crypto traffic
++		 */
++		err = knet_handle_crypto_use_config(knet_h, 1);
++		if (err < 0) {
++			err = knet_handle_crypto_rx_clear_traffic(knet_h, value);
++			if (err < 0) {
++				/*
++				 * force attempt or things will go bad
++				 */
++				knet_h->crypto_only = value;
++			}
++		}
++		return err;
++	}
++}
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index d04bc484..864ceba3 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -32,15 +32,6 @@ int crypto_encrypt_and_signv (
+ 	unsigned char *buf_out,
+ 	ssize_t *buf_out_len);
+ 
+-int crypto_use_config (
+-	knet_handle_t knet_h,
+-	uint8_t config_num);
+-
+-int crypto_init(
+-	knet_handle_t knet_h,
+-	struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
+-	uint8_t config_num);
+-
+ void crypto_fini(
+ 	knet_handle_t knet_h,
+ 	uint8_t config_num);
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 71658926..68641d6e 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -14,7 +14,6 @@
+ #include <unistd.h>
+ #include <errno.h>
+ #include <pthread.h>
+-#include <sys/uio.h>
+ #include <math.h>
+ #include <sys/time.h>
+ #include <sys/resource.h>
+@@ -807,1117 +806,3 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	errno = 0;
+ 	return 0;
+ }
+-
+-int knet_handle_enable_sock_notify(knet_handle_t knet_h,
+-				   void *sock_notify_fn_private_data,
+-				   void (*sock_notify_fn) (
+-						void *private_data,
+-						int datafd,
+-						int8_t channel,
+-						uint8_t tx_rx,
+-						int error,
+-						int errorno))
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!sock_notify_fn) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	knet_h->sock_notify_fn_private_data = sock_notify_fn_private_data;
+-	knet_h->sock_notify_fn = sock_notify_fn;
+-	log_debug(knet_h, KNET_SUB_HANDLE, "sock_notify_fn enabled");
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	return 0;
+-}
+-
+-int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel)
+-{
+-	int err = 0, savederrno = 0;
+-	int i;
+-	struct epoll_event ev;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (datafd == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (*channel >= KNET_DATAFD_MAX) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!knet_h->sock_notify_fn) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Adding datafd requires sock notify callback enabled!");
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-	if (*datafd > 0) {
+-		for (i = 0; i < KNET_DATAFD_MAX; i++) {
+-			if  ((knet_h->sockfd[i].in_use) && (knet_h->sockfd[i].sockfd[0] == *datafd)) {
+-				log_err(knet_h, KNET_SUB_HANDLE, "requested datafd: %d already exist in index: %d", *datafd, i);
+-				savederrno = EEXIST;
+-				err = -1;
+-				goto out_unlock;
+-			}
+-		}
+-	}
+-
+-	/*
+-	 * auto allocate a channel
+-	 */
+-	if (*channel < 0) {
+-		for (i = 0; i < KNET_DATAFD_MAX; i++) {
+-			if (!knet_h->sockfd[i].in_use) {
+-				*channel = i;
+-				break;
+-			}
+-		}
+-		if (*channel < 0) {
+-			savederrno = EBUSY;
+-			err = -1;
+-			goto out_unlock;
+-		}
+-	} else {
+-		if (knet_h->sockfd[*channel].in_use) {
+-			savederrno = EBUSY;
+-			err = -1;
+-			goto out_unlock;
+-		}
+-	}
+-
+-	knet_h->sockfd[*channel].is_created = 0;
+-	knet_h->sockfd[*channel].is_socket = 0;
+-	knet_h->sockfd[*channel].has_error = 0;
+-
+-	if (*datafd > 0) {
+-		int sockopt;
+-		socklen_t sockoptlen = sizeof(sockopt);
+-
+-		if (_fdset_cloexec(*datafd)) {
+-			savederrno = errno;
+-			err = -1;
+-			log_err(knet_h, KNET_SUB_HANDLE, "Unable to set CLOEXEC on datafd: %s",
+-				strerror(savederrno));
+-			goto out_unlock;
+-		}
+-
+-		if (_fdset_nonblock(*datafd)) {
+-			savederrno = errno;
+-			err = -1;
+-			log_err(knet_h, KNET_SUB_HANDLE, "Unable to set NONBLOCK on datafd: %s",
+-				strerror(savederrno));
+-			goto out_unlock;
+-		}
+-
+-		knet_h->sockfd[*channel].sockfd[0] = *datafd;
+-		knet_h->sockfd[*channel].sockfd[1] = 0;
+-
+-		if (!getsockopt(knet_h->sockfd[*channel].sockfd[0], SOL_SOCKET, SO_TYPE, &sockopt, &sockoptlen)) {
+-			knet_h->sockfd[*channel].is_socket = 1;
+-		}
+-	} else {
+-		if (_init_socketpair(knet_h, knet_h->sockfd[*channel].sockfd)) {
+-			savederrno = errno;
+-			err = -1;
+-			goto out_unlock;
+-		}
+-
+-		knet_h->sockfd[*channel].is_created = 1;
+-		knet_h->sockfd[*channel].is_socket = 1;
+-		*datafd = knet_h->sockfd[*channel].sockfd[0];
+-	}
+-
+-	memset(&ev, 0, sizeof(struct epoll_event));
+-	ev.events = EPOLLIN;
+-	ev.data.fd = knet_h->sockfd[*channel].sockfd[knet_h->sockfd[*channel].is_created];
+-
+-	if (epoll_ctl(knet_h->send_to_links_epollfd,
+-		      EPOLL_CTL_ADD, knet_h->sockfd[*channel].sockfd[knet_h->sockfd[*channel].is_created], &ev)) {
+-		savederrno = errno;
+-		err = -1;
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to add datafd %d to linkfd epoll pool: %s",
+-			knet_h->sockfd[*channel].sockfd[knet_h->sockfd[*channel].is_created], strerror(savederrno));
+-		if (knet_h->sockfd[*channel].is_created) {
+-			_close_socketpair(knet_h, knet_h->sockfd[*channel].sockfd);
+-		}
+-		goto out_unlock;
+-	}
+-
+-	knet_h->sockfd[*channel].in_use = 1;
+-
+-out_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-int knet_handle_remove_datafd(knet_handle_t knet_h, int datafd)
+-{
+-	int err = 0, savederrno = 0;
+-	int8_t channel = -1;
+-	int i;
+-	struct epoll_event ev;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (datafd <= 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	for (i = 0; i < KNET_DATAFD_MAX; i++) {
+-		if  ((knet_h->sockfd[i].in_use) &&
+-		     (knet_h->sockfd[i].sockfd[0] == datafd)) {
+-			channel = i;
+-			break;
+-		}
+-	}
+-
+-	if (channel < 0) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-	if (!knet_h->sockfd[channel].has_error) {
+-		memset(&ev, 0, sizeof(struct epoll_event));
+-
+-		if (epoll_ctl(knet_h->send_to_links_epollfd,
+-			      EPOLL_CTL_DEL, knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], &ev)) {
+-			savederrno = errno;
+-			err = -1;
+-			log_err(knet_h, KNET_SUB_HANDLE, "Unable to del datafd %d from linkfd epoll pool: %s",
+-				knet_h->sockfd[channel].sockfd[0], strerror(savederrno));
+-			goto out_unlock;
+-		}
+-	}
+-
+-	if (knet_h->sockfd[channel].is_created) {
+-		_close_socketpair(knet_h, knet_h->sockfd[channel].sockfd);
+-	}
+-
+-	memset(&knet_h->sockfd[channel], 0, sizeof(struct knet_sock));
+-
+-out_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-int knet_handle_get_datafd(knet_handle_t knet_h, const int8_t channel, int *datafd)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((channel < 0) || (channel >= KNET_DATAFD_MAX)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (datafd == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!knet_h->sockfd[channel].in_use) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-	*datafd = knet_h->sockfd[channel].sockfd[0];
+-
+-out_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-int knet_handle_get_channel(knet_handle_t knet_h, const int datafd, int8_t *channel)
+-{
+-	int err = 0, savederrno = 0;
+-	int i;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (datafd <= 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	*channel = -1;
+-
+-	for (i = 0; i < KNET_DATAFD_MAX; i++) {
+-		if  ((knet_h->sockfd[i].in_use) &&
+-		     (knet_h->sockfd[i].sockfd[0] == datafd)) {
+-			*channel = i;
+-			break;
+-		}
+-	}
+-
+-	if (*channel < 0) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-out_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-int knet_handle_enable_filter(knet_handle_t knet_h,
+-			      void *dst_host_filter_fn_private_data,
+-			      int (*dst_host_filter_fn) (
+-					void *private_data,
+-					const unsigned char *outdata,
+-					ssize_t outdata_len,
+-					uint8_t tx_rx,
+-					knet_node_id_t this_host_id,
+-					knet_node_id_t src_node_id,
+-					int8_t *channel,
+-					knet_node_id_t *dst_host_ids,
+-					size_t *dst_host_ids_entries))
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	knet_h->dst_host_filter_fn_private_data = dst_host_filter_fn_private_data;
+-	knet_h->dst_host_filter_fn = dst_host_filter_fn;
+-	if (knet_h->dst_host_filter_fn) {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "dst_host_filter_fn enabled");
+-	} else {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "dst_host_filter_fn disabled");
+-	}
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (enabled > 1) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (enabled) {
+-		knet_h->enabled = enabled;
+-		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is enabled");
+-	} else {
+-		/*
+-		 * notify TX and RX threads to flush the queues
+-		 */
+-		if (set_thread_flush_queue(knet_h, KNET_THREAD_TX, KNET_THREAD_QUEUE_FLUSH) < 0) {
+-			log_debug(knet_h, KNET_SUB_HANDLE, "Unable to request queue flushing for TX thread");
+-		}
+-		if (set_thread_flush_queue(knet_h, KNET_THREAD_RX, KNET_THREAD_QUEUE_FLUSH) < 0) {
+-			log_debug(knet_h, KNET_SUB_HANDLE, "Unable to request queue flushing for RX thread");
+-		}
+-	}
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	/*
+-	 * when disabling data forward, we need to give time to TX and RX
+-	 * to flush the queues.
+-	 *
+-	 * the TX thread is the main leader here. When there is no more
+-	 * data in the TX queue, we will also close traffic for RX.
+-	 */
+-	if (!enabled) {
+-		/*
+-		 * this usleep might be unnecessary, but wait_all_threads_flush_queue
+-		 * adds extra locking delay.
+-		 *
+-		 * allow all threads to run free without extra locking interference
+-		 * and then we switch to a more active wait in case the scheduler
+-		 * has decided to delay one thread or another
+-		 */
+-		usleep(KNET_THREADS_TIMERES * 2);
+-		wait_all_threads_flush_queue(knet_h);
+-
+-		/*
+-		 * all threads have done flushing the queue, we can stop data forwarding
+-		 */
+-		savederrno = get_global_wrlock(knet_h);
+-		if (savederrno) {
+-			log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-				strerror(savederrno));
+-			errno = savederrno;
+-			return -1;
+-		}
+-		knet_h->enabled = enabled;
+-		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is disabled");
+-		pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	}
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_enable_access_lists(knet_handle_t knet_h, unsigned int enabled)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (enabled > 1) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	knet_h->use_access_lists = enabled;
+-
+-	if (enabled) {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "Links access lists are enabled");
+-	} else {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "Links access lists are disabled");
+-	}
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_pmtud_getfreq(knet_handle_t knet_h, unsigned int *interval)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!interval) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	*interval = knet_h->pmtud_interval;
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_pmtud_setfreq(knet_handle_t knet_h, unsigned int interval)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((!interval) || (interval > 86400)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	knet_h->pmtud_interval = interval;
+-	log_debug(knet_h, KNET_SUB_HANDLE, "PMTUd interval set to: %u seconds", interval);
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
+-				    void *pmtud_notify_fn_private_data,
+-				    void (*pmtud_notify_fn) (
+-						void *private_data,
+-						unsigned int data_mtu))
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	knet_h->pmtud_notify_fn_private_data = pmtud_notify_fn_private_data;
+-	knet_h->pmtud_notify_fn = pmtud_notify_fn;
+-	if (knet_h->pmtud_notify_fn) {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "pmtud_notify_fn enabled");
+-	} else {
+-		log_debug(knet_h, KNET_SUB_HANDLE, "pmtud_notify_fn disabled");
+-	}
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_pmtud_set(knet_handle_t knet_h,
+-			  unsigned int iface_mtu)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (iface_mtu > KNET_PMTUD_SIZE_V4) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_PMTUD, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	log_info(knet_h, KNET_SUB_PMTUD, "MTU manually set to: %u", iface_mtu);
+-
+-	knet_h->manual_mtu = iface_mtu;
+-
+-	force_pmtud_run(knet_h, KNET_SUB_PMTUD, 0);
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-int knet_handle_pmtud_get(knet_handle_t knet_h,
+-			  unsigned int *data_mtu)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!data_mtu) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	*data_mtu = knet_h->data_mtu;
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = 0;
+-	return 0;
+-}
+-
+-static int _knet_handle_crypto_set_config(knet_handle_t knet_h,
+-					  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
+-					  uint8_t config_num,
+-					  uint8_t force)
+-{
+-	int savederrno = 0;
+-	int err = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!knet_handle_crypto_cfg) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((config_num < 1) || (config_num > KNET_MAX_CRYPTO_INSTANCES)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if ((knet_h->crypto_in_use_config == config_num) && (!force)) {
+-		savederrno = EBUSY;
+-		err = -1;
+-		goto exit_unlock;
+-	}
+-
+-	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) ||
+-	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
+-	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
+-		crypto_fini(knet_h, config_num);
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "crypto config %u is not enabled", config_num);
+-		err = 0;
+-		goto exit_unlock;
+-	}
+-
+-	if (knet_handle_crypto_cfg->private_key_len < KNET_MIN_KEY_LEN) {
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too short for config %u (min %d): %u",
+-			  config_num, KNET_MIN_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto exit_unlock;
+-	}
+-
+-	if (knet_handle_crypto_cfg->private_key_len > KNET_MAX_KEY_LEN) {
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "private key len too long for config %u (max %d): %u",
+-			  config_num, KNET_MAX_KEY_LEN, knet_handle_crypto_cfg->private_key_len);
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto exit_unlock;
+-	}
+-
+-	err = crypto_init(knet_h, knet_handle_crypto_cfg, config_num);
+-
+-	if (err) {
+-		err = -2;
+-		savederrno = errno;
+-	}
+-
+-exit_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-int knet_handle_crypto_set_config(knet_handle_t knet_h,
+-				  struct knet_handle_crypto_cfg *knet_handle_crypto_cfg,
+-				  uint8_t config_num)
+-{
+-	return _knet_handle_crypto_set_config(knet_h, knet_handle_crypto_cfg, config_num, 0);
+-}
+-
+-int knet_handle_crypto_rx_clear_traffic(knet_handle_t knet_h,
+-					uint8_t value)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (value > KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	knet_h->crypto_only = value;
+-	if (knet_h->crypto_only) {
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "Only crypto traffic allowed for RX");
+-	} else {
+-		log_debug(knet_h, KNET_SUB_CRYPTO, "Both crypto and clear traffic allowed for RX");
+-	}
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	return 0;
+-}
+-
+-int knet_handle_crypto_use_config(knet_handle_t knet_h,
+-				  uint8_t config_num)
+-{
+-	int savederrno = 0;
+-	int err = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (config_num > KNET_MAX_CRYPTO_INSTANCES) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	err = crypto_use_config(knet_h, config_num);
+-	savederrno = errno;
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-/*
+- * compatibility wrapper for 1.x releases
+- */
+-int knet_handle_crypto(knet_handle_t knet_h, struct knet_handle_crypto_cfg *knet_handle_crypto_cfg)
+-{
+-	int err = 0;
+-	uint8_t value;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	value = knet_h->crypto_only;
+-	/*
+-	 * configure crypto in slot 1
+-	 */
+-	err = _knet_handle_crypto_set_config(knet_h, knet_handle_crypto_cfg, 1, 1);
+-	if (err < 0) {
+-		return err;
+-	}
+-
+-	if ((!strncmp("none", knet_handle_crypto_cfg->crypto_model, 4)) ||
+-	    ((!strncmp("none", knet_handle_crypto_cfg->crypto_cipher_type, 4)) &&
+-	     (!strncmp("none", knet_handle_crypto_cfg->crypto_hash_type, 4)))) {
+-		err = knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC);
+-		if (err < 0) {
+-			return err;
+-		}
+-
+-		/*
+-		 * start using clear traffic
+-		 */
+-		err = knet_handle_crypto_use_config(knet_h, 0);
+-		if (err < 0) {
+-			err = knet_handle_crypto_rx_clear_traffic(knet_h, value);
+-			if (err < 0) {
+-				/*
+-				 * force attempt or things will go bad
+-				 */
+-				knet_h->crypto_only = value;
+-			}
+-		}
+-		return err;
+-	} else {
+-		err = knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC);
+-		if (err < 0) {
+-			return err;
+-		}
+-
+-		/*
+-		 * start using crypto traffic
+-		 */
+-		err = knet_handle_crypto_use_config(knet_h, 1);
+-		if (err < 0) {
+-			err = knet_handle_crypto_rx_clear_traffic(knet_h, value);
+-			if (err < 0) {
+-				/*
+-				 * force attempt or things will go bad
+-				 */
+-				knet_h->crypto_only = value;
+-			}
+-		}
+-		return err;
+-	}
+-}
+-
+-int knet_handle_compress(knet_handle_t knet_h, struct knet_handle_compress_cfg *knet_handle_compress_cfg)
+-{
+-	int savederrno = 0;
+-	int err = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!knet_handle_compress_cfg) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	compress_fini(knet_h, 0);
+-	err = compress_cfg(knet_h, knet_handle_compress_cfg);
+-	savederrno = errno;
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-ssize_t knet_recv(knet_handle_t knet_h, char *buff, const size_t buff_len, const int8_t channel)
+-{
+-	int savederrno = 0;
+-	ssize_t err = 0;
+-	struct iovec iov_in;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff_len <= 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff_len > KNET_MAX_PACKET_SIZE) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel < 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel >= KNET_DATAFD_MAX) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!knet_h->sockfd[channel].in_use) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-	memset(&iov_in, 0, sizeof(iov_in));
+-	iov_in.iov_base = (void *)buff;
+-	iov_in.iov_len = buff_len;
+-
+-	err = readv(knet_h->sockfd[channel].sockfd[0], &iov_in, 1);
+-	savederrno = errno;
+-
+-out_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-ssize_t knet_send(knet_handle_t knet_h, const char *buff, const size_t buff_len, const int8_t channel)
+-{
+-	int savederrno = 0;
+-	ssize_t err = 0;
+-	struct iovec iov_out[1];
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff_len <= 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff_len > KNET_MAX_PACKET_SIZE) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel < 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel >= KNET_DATAFD_MAX) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!knet_h->sockfd[channel].in_use) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-	memset(iov_out, 0, sizeof(iov_out));
+-
+-	iov_out[0].iov_base = (void *)buff;
+-	iov_out[0].iov_len = buff_len;
+-
+-	err = writev(knet_h->sockfd[channel].sockfd[0], iov_out, 1);
+-	savederrno = errno;
+-
+-out_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+-int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats, size_t struct_size)
+-{
+-	int err = 0, savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (!stats) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&knet_h->handle_stats_mutex);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock: %s",
+-			strerror(savederrno));
+-		err = -1;
+-		goto out_unlock;
+-	}
+-
+-	if (struct_size > sizeof(struct knet_handle_stats)) {
+-		struct_size = sizeof(struct knet_handle_stats);
+-	}
+-
+-	memmove(stats, &knet_h->stats, struct_size);
+-
+-	/*
+-	 * TX crypt stats only count the data packets sent, so add in the ping/pong/pmtud figures
+-	 * RX is OK as it counts them before they are sorted.
+-	 */
+-
+-	stats->tx_crypt_packets += knet_h->stats_extra.tx_crypt_ping_packets +
+-		knet_h->stats_extra.tx_crypt_pong_packets +
+-		knet_h->stats_extra.tx_crypt_pmtu_packets +
+-		knet_h->stats_extra.tx_crypt_pmtu_reply_packets;
+-
+-	/* Tell the caller our full size in case they have an old version */
+-	stats->size = sizeof(struct knet_handle_stats);
+-
+-out_unlock:
+-	pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	return err;
+-}
+-
+-int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+-{
+-	int savederrno = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (clear_option != KNET_CLEARSTATS_HANDLE_ONLY &&
+-	    clear_option != KNET_CLEARSTATS_HANDLE_AND_LINK) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	memset(&knet_h->stats, 0, sizeof(struct knet_handle_stats));
+-	memset(&knet_h->stats_extra, 0, sizeof(struct knet_handle_stats_extra));
+-	if (clear_option == KNET_CLEARSTATS_HANDLE_AND_LINK) {
+-		_link_clear_stats(knet_h);
+-	}
+-
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-	return 0;
+-}
+diff --git a/libknet/handle_api.c b/libknet/handle_api.c
+new file mode 100644
+index 00000000..bf4324f5
+--- /dev/null
++++ b/libknet/handle_api.c
+@@ -0,0 +1,602 @@
++/*
++ * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *          Federico Simoncelli <fsimon@kronosnet.org>
++ *
++ * This software licensed under LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <errno.h>
++#include <pthread.h>
++#include <sys/uio.h>
++
++#include "internals.h"
++#include "crypto.h"
++#include "links.h"
++#include "common.h"
++#include "transport_common.h"
++#include "logging.h"
++
++int knet_handle_enable_sock_notify(knet_handle_t knet_h,
++				   void *sock_notify_fn_private_data,
++				   void (*sock_notify_fn) (
++						void *private_data,
++						int datafd,
++						int8_t channel,
++						uint8_t tx_rx,
++						int error,
++						int errorno))
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!sock_notify_fn) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->sock_notify_fn_private_data = sock_notify_fn_private_data;
++	knet_h->sock_notify_fn = sock_notify_fn;
++	log_debug(knet_h, KNET_SUB_HANDLE, "sock_notify_fn enabled");
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	return 0;
++}
++
++int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel)
++{
++	int err = 0, savederrno = 0;
++	int i;
++	struct epoll_event ev;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (datafd == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (*channel >= KNET_DATAFD_MAX) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!knet_h->sock_notify_fn) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Adding datafd requires sock notify callback enabled!");
++		savederrno = EINVAL;
++		err = -1;
++		goto out_unlock;
++	}
++
++	if (*datafd > 0) {
++		for (i = 0; i < KNET_DATAFD_MAX; i++) {
++			if  ((knet_h->sockfd[i].in_use) && (knet_h->sockfd[i].sockfd[0] == *datafd)) {
++				log_err(knet_h, KNET_SUB_HANDLE, "requested datafd: %d already exist in index: %d", *datafd, i);
++				savederrno = EEXIST;
++				err = -1;
++				goto out_unlock;
++			}
++		}
++	}
++
++	/*
++	 * auto allocate a channel
++	 */
++	if (*channel < 0) {
++		for (i = 0; i < KNET_DATAFD_MAX; i++) {
++			if (!knet_h->sockfd[i].in_use) {
++				*channel = i;
++				break;
++			}
++		}
++		if (*channel < 0) {
++			savederrno = EBUSY;
++			err = -1;
++			goto out_unlock;
++		}
++	} else {
++		if (knet_h->sockfd[*channel].in_use) {
++			savederrno = EBUSY;
++			err = -1;
++			goto out_unlock;
++		}
++	}
++
++	knet_h->sockfd[*channel].is_created = 0;
++	knet_h->sockfd[*channel].is_socket = 0;
++	knet_h->sockfd[*channel].has_error = 0;
++
++	if (*datafd > 0) {
++		int sockopt;
++		socklen_t sockoptlen = sizeof(sockopt);
++
++		if (_fdset_cloexec(*datafd)) {
++			savederrno = errno;
++			err = -1;
++			log_err(knet_h, KNET_SUB_HANDLE, "Unable to set CLOEXEC on datafd: %s",
++				strerror(savederrno));
++			goto out_unlock;
++		}
++
++		if (_fdset_nonblock(*datafd)) {
++			savederrno = errno;
++			err = -1;
++			log_err(knet_h, KNET_SUB_HANDLE, "Unable to set NONBLOCK on datafd: %s",
++				strerror(savederrno));
++			goto out_unlock;
++		}
++
++		knet_h->sockfd[*channel].sockfd[0] = *datafd;
++		knet_h->sockfd[*channel].sockfd[1] = 0;
++
++		if (!getsockopt(knet_h->sockfd[*channel].sockfd[0], SOL_SOCKET, SO_TYPE, &sockopt, &sockoptlen)) {
++			knet_h->sockfd[*channel].is_socket = 1;
++		}
++	} else {
++		if (_init_socketpair(knet_h, knet_h->sockfd[*channel].sockfd)) {
++			savederrno = errno;
++			err = -1;
++			goto out_unlock;
++		}
++
++		knet_h->sockfd[*channel].is_created = 1;
++		knet_h->sockfd[*channel].is_socket = 1;
++		*datafd = knet_h->sockfd[*channel].sockfd[0];
++	}
++
++	memset(&ev, 0, sizeof(struct epoll_event));
++	ev.events = EPOLLIN;
++	ev.data.fd = knet_h->sockfd[*channel].sockfd[knet_h->sockfd[*channel].is_created];
++
++	if (epoll_ctl(knet_h->send_to_links_epollfd,
++		      EPOLL_CTL_ADD, knet_h->sockfd[*channel].sockfd[knet_h->sockfd[*channel].is_created], &ev)) {
++		savederrno = errno;
++		err = -1;
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to add datafd %d to linkfd epoll pool: %s",
++			knet_h->sockfd[*channel].sockfd[knet_h->sockfd[*channel].is_created], strerror(savederrno));
++		if (knet_h->sockfd[*channel].is_created) {
++			_close_socketpair(knet_h, knet_h->sockfd[*channel].sockfd);
++		}
++		goto out_unlock;
++	}
++
++	knet_h->sockfd[*channel].in_use = 1;
++
++out_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++int knet_handle_remove_datafd(knet_handle_t knet_h, int datafd)
++{
++	int err = 0, savederrno = 0;
++	int8_t channel = -1;
++	int i;
++	struct epoll_event ev;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (datafd <= 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	for (i = 0; i < KNET_DATAFD_MAX; i++) {
++		if  ((knet_h->sockfd[i].in_use) &&
++		     (knet_h->sockfd[i].sockfd[0] == datafd)) {
++			channel = i;
++			break;
++		}
++	}
++
++	if (channel < 0) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_unlock;
++	}
++
++	if (!knet_h->sockfd[channel].has_error) {
++		memset(&ev, 0, sizeof(struct epoll_event));
++
++		if (epoll_ctl(knet_h->send_to_links_epollfd,
++			      EPOLL_CTL_DEL, knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], &ev)) {
++			savederrno = errno;
++			err = -1;
++			log_err(knet_h, KNET_SUB_HANDLE, "Unable to del datafd %d from linkfd epoll pool: %s",
++				knet_h->sockfd[channel].sockfd[0], strerror(savederrno));
++			goto out_unlock;
++		}
++	}
++
++	if (knet_h->sockfd[channel].is_created) {
++		_close_socketpair(knet_h, knet_h->sockfd[channel].sockfd);
++	}
++
++	memset(&knet_h->sockfd[channel], 0, sizeof(struct knet_sock));
++
++out_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++int knet_handle_get_datafd(knet_handle_t knet_h, const int8_t channel, int *datafd)
++{
++	int err = 0, savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((channel < 0) || (channel >= KNET_DATAFD_MAX)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (datafd == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!knet_h->sockfd[channel].in_use) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_unlock;
++	}
++
++	*datafd = knet_h->sockfd[channel].sockfd[0];
++
++out_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++int knet_handle_get_channel(knet_handle_t knet_h, const int datafd, int8_t *channel)
++{
++	int err = 0, savederrno = 0;
++	int i;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (datafd <= 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	*channel = -1;
++
++	for (i = 0; i < KNET_DATAFD_MAX; i++) {
++		if  ((knet_h->sockfd[i].in_use) &&
++		     (knet_h->sockfd[i].sockfd[0] == datafd)) {
++			*channel = i;
++			break;
++		}
++	}
++
++	if (*channel < 0) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_unlock;
++	}
++
++out_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++int knet_handle_enable_filter(knet_handle_t knet_h,
++			      void *dst_host_filter_fn_private_data,
++			      int (*dst_host_filter_fn) (
++					void *private_data,
++					const unsigned char *outdata,
++					ssize_t outdata_len,
++					uint8_t tx_rx,
++					knet_node_id_t this_host_id,
++					knet_node_id_t src_node_id,
++					int8_t *channel,
++					knet_node_id_t *dst_host_ids,
++					size_t *dst_host_ids_entries))
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->dst_host_filter_fn_private_data = dst_host_filter_fn_private_data;
++	knet_h->dst_host_filter_fn = dst_host_filter_fn;
++	if (knet_h->dst_host_filter_fn) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "dst_host_filter_fn enabled");
++	} else {
++		log_debug(knet_h, KNET_SUB_HANDLE, "dst_host_filter_fn disabled");
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
++int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (enabled > 1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if (enabled) {
++		knet_h->enabled = enabled;
++		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is enabled");
++	} else {
++		/*
++		 * notify TX and RX threads to flush the queues
++		 */
++		if (set_thread_flush_queue(knet_h, KNET_THREAD_TX, KNET_THREAD_QUEUE_FLUSH) < 0) {
++			log_debug(knet_h, KNET_SUB_HANDLE, "Unable to request queue flushing for TX thread");
++		}
++		if (set_thread_flush_queue(knet_h, KNET_THREAD_RX, KNET_THREAD_QUEUE_FLUSH) < 0) {
++			log_debug(knet_h, KNET_SUB_HANDLE, "Unable to request queue flushing for RX thread");
++		}
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	/*
++	 * when disabling data forward, we need to give time to TX and RX
++	 * to flush the queues.
++	 *
++	 * the TX thread is the main leader here. When there is no more
++	 * data in the TX queue, we will also close traffic for RX.
++	 */
++	if (!enabled) {
++		/*
++		 * this usleep might be unnecessary, but wait_all_threads_flush_queue
++		 * adds extra locking delay.
++		 *
++		 * allow all threads to run free without extra locking interference
++		 * and then we switch to a more active wait in case the scheduler
++		 * has decided to delay one thread or another
++		 */
++		usleep(KNET_THREADS_TIMERES * 2);
++		wait_all_threads_flush_queue(knet_h);
++
++		/*
++		 * all threads have done flushing the queue, we can stop data forwarding
++		 */
++		savederrno = get_global_wrlock(knet_h);
++		if (savederrno) {
++			log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++				strerror(savederrno));
++			errno = savederrno;
++			return -1;
++		}
++		knet_h->enabled = enabled;
++		log_debug(knet_h, KNET_SUB_HANDLE, "Data forwarding is disabled");
++		pthread_rwlock_unlock(&knet_h->global_rwlock);
++	}
++
++	errno = 0;
++	return 0;
++}
++
++int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats, size_t struct_size)
++{
++	int err = 0, savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!stats) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	savederrno = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get mutex lock: %s",
++			strerror(savederrno));
++		err = -1;
++		goto out_unlock;
++	}
++
++	if (struct_size > sizeof(struct knet_handle_stats)) {
++		struct_size = sizeof(struct knet_handle_stats);
++	}
++
++	memmove(stats, &knet_h->stats, struct_size);
++
++	/*
++	 * TX crypt stats only count the data packets sent, so add in the ping/pong/pmtud figures
++	 * RX is OK as it counts them before they are sorted.
++	 */
++
++	stats->tx_crypt_packets += knet_h->stats_extra.tx_crypt_ping_packets +
++		knet_h->stats_extra.tx_crypt_pong_packets +
++		knet_h->stats_extra.tx_crypt_pmtu_packets +
++		knet_h->stats_extra.tx_crypt_pmtu_reply_packets;
++
++	/* Tell the caller our full size in case they have an old version */
++	stats->size = sizeof(struct knet_handle_stats);
++
++out_unlock:
++	pthread_mutex_unlock(&knet_h->handle_stats_mutex);
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	return err;
++}
++
++int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (clear_option != KNET_CLEARSTATS_HANDLE_ONLY &&
++	    clear_option != KNET_CLEARSTATS_HANDLE_AND_LINK) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	memset(&knet_h->stats, 0, sizeof(struct knet_handle_stats));
++	memset(&knet_h->stats_extra, 0, sizeof(struct knet_handle_stats_extra));
++	if (clear_option == KNET_CLEARSTATS_HANDLE_AND_LINK) {
++		_link_clear_stats(knet_h);
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	return 0;
++}
++
++int knet_handle_enable_access_lists(knet_handle_t knet_h, unsigned int enabled)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (enabled > 1) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->use_access_lists = enabled;
++
++	if (enabled) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Links access lists are enabled");
++	} else {
++		log_debug(knet_h, KNET_SUB_HANDLE, "Links access lists are disabled");
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index b4432898..d49827aa 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -640,3 +640,165 @@ out_unlock:
+ 
+ 	return NULL;
+ }
++
++int knet_handle_pmtud_getfreq(knet_handle_t knet_h, unsigned int *interval)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!interval) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	*interval = knet_h->pmtud_interval;
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
++int knet_handle_pmtud_setfreq(knet_handle_t knet_h, unsigned int interval)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if ((!interval) || (interval > 86400)) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->pmtud_interval = interval;
++	log_debug(knet_h, KNET_SUB_HANDLE, "PMTUd interval set to: %u seconds", interval);
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
++int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
++				    void *pmtud_notify_fn_private_data,
++				    void (*pmtud_notify_fn) (
++						void *private_data,
++						unsigned int data_mtu))
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = get_global_wrlock(knet_h);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get write lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	knet_h->pmtud_notify_fn_private_data = pmtud_notify_fn_private_data;
++	knet_h->pmtud_notify_fn = pmtud_notify_fn;
++	if (knet_h->pmtud_notify_fn) {
++		log_debug(knet_h, KNET_SUB_HANDLE, "pmtud_notify_fn enabled");
++	} else {
++		log_debug(knet_h, KNET_SUB_HANDLE, "pmtud_notify_fn disabled");
++	}
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
++int knet_handle_pmtud_set(knet_handle_t knet_h,
++			  unsigned int iface_mtu)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (iface_mtu > KNET_PMTUD_SIZE_V4) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_PMTUD, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	log_info(knet_h, KNET_SUB_PMTUD, "MTU manually set to: %u", iface_mtu);
++
++	knet_h->manual_mtu = iface_mtu;
++
++	force_pmtud_run(knet_h, KNET_SUB_PMTUD, 0);
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
++
++int knet_handle_pmtud_get(knet_handle_t knet_h,
++			  unsigned int *data_mtu)
++{
++	int savederrno = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (!data_mtu) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	*data_mtu = knet_h->data_mtu;
++
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = 0;
++	return 0;
++}
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index bff7dbad..61e2862d 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -999,3 +999,66 @@ void *_handle_recv_from_links_thread(void *data)
+ 
+ 	return NULL;
+ }
++
++ssize_t knet_recv(knet_handle_t knet_h, char *buff, const size_t buff_len, const int8_t channel)
++{
++	int savederrno = 0;
++	ssize_t err = 0;
++	struct iovec iov_in;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff_len <= 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff_len > KNET_MAX_PACKET_SIZE) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel < 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel >= KNET_DATAFD_MAX) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!knet_h->sockfd[channel].in_use) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_unlock;
++	}
++
++	memset(&iov_in, 0, sizeof(iov_in));
++	iov_in.iov_base = (void *)buff;
++	iov_in.iov_len = buff_len;
++
++	err = readv(knet_h->sockfd[channel].sockfd[0], &iov_in, 1);
++	savederrno = errno;
++
++out_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index be5fb6b2..852064c2 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -597,76 +597,6 @@ out_unlock:
+ 	return err;
+ }
+ 
+-int knet_send_sync(knet_handle_t knet_h, const char *buff, const size_t buff_len, const int8_t channel)
+-{
+-	int savederrno = 0, err = 0;
+-
+-	if (!knet_h) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff == NULL) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff_len <= 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (buff_len > KNET_MAX_PACKET_SIZE) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel < 0) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if (channel >= KNET_DATAFD_MAX) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_TX, "Unable to get read lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	if (!knet_h->sockfd[channel].in_use) {
+-		savederrno = EINVAL;
+-		err = -1;
+-		goto out;
+-	}
+-
+-	savederrno = pthread_mutex_lock(&knet_h->tx_mutex);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_TX, "Unable to get TX mutex lock: %s",
+-			strerror(savederrno));
+-		err = -1;
+-		goto out;
+-	}
+-
+-	knet_h->recv_from_sock_buf->kh_type = KNET_HEADER_TYPE_DATA;
+-	memmove(knet_h->recv_from_sock_buf->khp_data_userdata, buff, buff_len);
+-	err = _parse_recv_from_sock(knet_h, buff_len, channel, 1);
+-	savederrno = errno;
+-
+-	pthread_mutex_unlock(&knet_h->tx_mutex);
+-
+-out:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = err ? savederrno : 0;
+-	return err;
+-}
+-
+ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int sockfd, int8_t channel, int type)
+ {
+ 	ssize_t inlen = 0;
+@@ -835,3 +765,137 @@ void *_handle_send_to_links_thread(void *data)
+ 
+ 	return NULL;
+ }
++
++int knet_send_sync(knet_handle_t knet_h, const char *buff, const size_t buff_len, const int8_t channel)
++{
++	int savederrno = 0, err = 0;
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff_len <= 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff_len > KNET_MAX_PACKET_SIZE) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel < 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel >= KNET_DATAFD_MAX) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_TX, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!knet_h->sockfd[channel].in_use) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out;
++	}
++
++	savederrno = pthread_mutex_lock(&knet_h->tx_mutex);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_TX, "Unable to get TX mutex lock: %s",
++			strerror(savederrno));
++		err = -1;
++		goto out;
++	}
++
++	knet_h->recv_from_sock_buf->kh_type = KNET_HEADER_TYPE_DATA;
++	memmove(knet_h->recv_from_sock_buf->khp_data_userdata, buff, buff_len);
++	err = _parse_recv_from_sock(knet_h, buff_len, channel, 1);
++	savederrno = errno;
++
++	pthread_mutex_unlock(&knet_h->tx_mutex);
++
++out:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++
++	errno = err ? savederrno : 0;
++	return err;
++}
++
++ssize_t knet_send(knet_handle_t knet_h, const char *buff, const size_t buff_len, const int8_t channel)
++{
++	int savederrno = 0;
++	ssize_t err = 0;
++	struct iovec iov_out[1];
++
++	if (!knet_h) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff == NULL) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff_len <= 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (buff_len > KNET_MAX_PACKET_SIZE) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel < 0) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	if (channel >= KNET_DATAFD_MAX) {
++		errno = EINVAL;
++		return -1;
++	}
++
++	savederrno = pthread_rwlock_rdlock(&knet_h->global_rwlock);
++	if (savederrno) {
++		log_err(knet_h, KNET_SUB_HANDLE, "Unable to get read lock: %s",
++			strerror(savederrno));
++		errno = savederrno;
++		return -1;
++	}
++
++	if (!knet_h->sockfd[channel].in_use) {
++		savederrno = EINVAL;
++		err = -1;
++		goto out_unlock;
++	}
++
++	memset(iov_out, 0, sizeof(iov_out));
++
++	iov_out[0].iov_base = (void *)buff;
++	iov_out[0].iov_len = buff_len;
++
++	err = writev(knet_h->sockfd[channel].sockfd[0], iov_out, 1);
++	savederrno = errno;
++
++out_unlock:
++	pthread_rwlock_unlock(&knet_h->global_rwlock);
++	errno = err ? savederrno : 0;
++	return err;
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0388-cleanup-kill-all-unsupported-kronosnetd-code.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0388-cleanup-kill-all-unsupported-kronosnetd-code.patch
new file mode 100644
index 000000000..8db216780
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0388-cleanup-kill-all-unsupported-kronosnetd-code.patch
@@ -0,0 +1,5820 @@ 
+From 8eee8b6b72ee67e23d6aa9a36e8270d859d7eb76 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 13 Aug 2020 09:24:21 +0200
+Subject: [PATCH] [cleanup] kill all unsupported kronosnetd code
+
+corosync can provide similar capabilities right now
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ Makefile.am                        |    7 +-
+ NOTES_TO_PACKAGE_MAINTAINERS       |    9 +-
+ configure.ac                       |  116 +-
+ init/Makefile.am                   |   47 -
+ init/kronosnetd.default            |   11 -
+ init/kronosnetd.in                 |  152 --
+ init/kronosnetd.service.in         |   20 -
+ kronosnet.spec.in                  |   51 -
+ kronosnetd/Makefile.am             |   89 --
+ kronosnetd/cfg.c                   |   88 --
+ kronosnetd/cfg.h                   |   55 -
+ kronosnetd/etherfilter.c           |   64 -
+ kronosnetd/etherfilter.h           |   25 -
+ kronosnetd/keygen.c                |  180 ---
+ kronosnetd/kronosnetd.logrotate.in |   17 -
+ kronosnetd/logging.c               |   55 -
+ kronosnetd/logging.h               |   29 -
+ kronosnetd/main.c                  |  347 -----
+ kronosnetd/vty.c                   |  504 -------
+ kronosnetd/vty.h                   |   74 -
+ kronosnetd/vty_auth.c              |  305 ----
+ kronosnetd/vty_auth.h              |   18 -
+ kronosnetd/vty_cli.c               |  531 -------
+ kronosnetd/vty_cli.h               |   20 -
+ kronosnetd/vty_cli_cmds.c          | 2188 ----------------------------
+ kronosnetd/vty_cli_cmds.h          |   50 -
+ kronosnetd/vty_utils.c             |  269 ----
+ kronosnetd/vty_utils.h             |   35 -
+ libknet/libknet.h                  |    2 -
+ man/Makefile.am                    |    5 -
+ man/knet-keygen.8                  |   28 -
+ man/kronosnetd.8                   |   51 -
+ 32 files changed, 4 insertions(+), 5438 deletions(-)
+ delete mode 100644 init/Makefile.am
+ delete mode 100644 init/kronosnetd.default
+ delete mode 100644 init/kronosnetd.in
+ delete mode 100644 init/kronosnetd.service.in
+ delete mode 100644 kronosnetd/Makefile.am
+ delete mode 100644 kronosnetd/cfg.c
+ delete mode 100644 kronosnetd/cfg.h
+ delete mode 100644 kronosnetd/etherfilter.c
+ delete mode 100644 kronosnetd/etherfilter.h
+ delete mode 100644 kronosnetd/keygen.c
+ delete mode 100644 kronosnetd/kronosnetd.logrotate.in
+ delete mode 100644 kronosnetd/logging.c
+ delete mode 100644 kronosnetd/logging.h
+ delete mode 100644 kronosnetd/main.c
+ delete mode 100644 kronosnetd/vty.c
+ delete mode 100644 kronosnetd/vty.h
+ delete mode 100644 kronosnetd/vty_auth.c
+ delete mode 100644 kronosnetd/vty_auth.h
+ delete mode 100644 kronosnetd/vty_cli.c
+ delete mode 100644 kronosnetd/vty_cli.h
+ delete mode 100644 kronosnetd/vty_cli_cmds.c
+ delete mode 100644 kronosnetd/vty_cli_cmds.h
+ delete mode 100644 kronosnetd/vty_utils.c
+ delete mode 100644 kronosnetd/vty_utils.h
+ delete mode 100644 man/knet-keygen.8
+ delete mode 100644 man/kronosnetd.8
+
+diff --git a/Makefile.am b/Makefile.am
+index cf1366e1..ff85e55b 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -27,7 +27,7 @@ EXTRA_DIST		= autogen.sh .version \
+ 			  NOTES_TO_PACKAGE_MAINTAINERS \
+ 			  $(SPEC).in build-aux
+ 
+-SUBDIRS			= init libnozzle libknet kronosnetd
++SUBDIRS			= libnozzle libknet
+ 
+ if BUILD_MAN
+ SUBDIRS			+= man
+@@ -137,11 +137,6 @@ if BUILD_COMPRESS_ZSTD
+ else
+ 	sed -i -e "s#@zstd@#bcond_with#g" $@-t
+ endif
+-if BUILD_KRONOSNETD
+-	sed -i -e "s#@kronosnetd@#bcond_without#g" $@-t
+-else
+-	sed -i -e "s#@kronosnetd@#bcond_with#g" $@-t
+-endif
+ if BUILD_LIBNOZZLE
+ 	sed -i -e "s#@libnozzle@#bcond_without#g" $@-t
+ else
+diff --git a/NOTES_TO_PACKAGE_MAINTAINERS b/NOTES_TO_PACKAGE_MAINTAINERS
+index 5acff702..fd931f4b 100644
+--- a/NOTES_TO_PACKAGE_MAINTAINERS
++++ b/NOTES_TO_PACKAGE_MAINTAINERS
+@@ -4,13 +4,8 @@ Those are a few things about this project that you should know.
+ 
+ I surely welcome patches to support both in a better way.
+ 
+-DO NOT ship kronosnetd. It's an experimental piece of super
+-crappy code. IF you decide to ship it anyway, you get to
+-be also the upstream maintainer :-) you have been warned.
+-
+-libnozzle is a simple commodity library used only by kronosnetd
+-and a future release of corosync. This is the first GA release
+-for libnozzle, please allow space for minor screw ups.
++libnozzle is a simple commodity library currently used by
++corosync, to manage tun/tap devices.
+ 
+ libknet is the core of this project. It is considered stable
+ and supported in the stable* branches and still under
+diff --git a/configure.ac b/configure.ac
+index 88695c77..d3ff26dd 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -39,26 +39,18 @@ LT_INIT
+ LDFLAGS="$saved_LDFLAGS"
+ 
+ AC_CONFIG_MACRO_DIR([m4])
+-AC_CONFIG_SRCDIR([kronosnetd/main.c])
++AC_CONFIG_SRCDIR([libknet/handle.c])
+ AC_CONFIG_HEADERS([config.h])
+ 
+ AC_CANONICAL_HOST
+ 
+ AC_LANG([C])
+ 
+-systemddir=${prefix}/lib/systemd/system
+-
+ if test "$prefix" = "NONE"; then
+ 	prefix="/usr"
+ 	if test "$localstatedir" = "\${prefix}/var"; then
+ 		localstatedir="/var"
+ 	fi
+-	if test "$sysconfdir" = "\${prefix}/etc"; then
+-		sysconfdir="/etc"
+-	fi
+-	if test "$systemddir" = "NONE/lib/systemd/system"; then
+-		systemddir=/lib/systemd/system
+-	fi
+ 	if test "$libdir" = "\${exec_prefix}/lib"; then
+ 		if test -e /usr/lib64; then
+ 			libdir="/usr/lib64"
+@@ -159,11 +151,6 @@ AC_ARG_ENABLE([poc],
+ 	[ enable_poc="no" ])
+ AM_CONDITIONAL([BUILD_POC], [test x$enable_poc = xyes])
+ 
+-AC_ARG_ENABLE([kronosnetd],
+-	[AS_HELP_STRING([--enable-kronosnetd],[Kronosnetd support])],,
+-	[ enable_kronosnetd="no" ])
+-AM_CONDITIONAL([BUILD_KRONOSNETD], [test x$enable_kronosnetd = xyes])
+-
+ AC_ARG_ENABLE([runautogen],
+ 	[AS_HELP_STRING([--enable-runautogen],[run autogen.sh])],,
+ 	[ enable_runautogen="no" ])
+@@ -180,9 +167,6 @@ AC_ARG_ENABLE([libnozzle],
+ 	[AS_HELP_STRING([--enable-libnozzle],[libnozzle support])],,
+ 	[ enable_libnozzle="yes" ])
+ 
+-if test "x$enable_kronosnetd" = xyes; then
+-	enable_libnozzle=yes
+-fi
+ AM_CONDITIONAL([BUILD_LIBNOZZLE], [test x$enable_libnozzle = xyes])
+ 
+ # Checks for libraries.
+@@ -300,26 +284,6 @@ if test "x$enable_libnozzle" = xyes; then
+ 	fi
+ fi
+ 
+-# checks for kronosnetd
+-if test "x$enable_kronosnetd" = xyes; then
+-	AC_CHECK_HEADERS([security/pam_appl.h],
+-			 [AC_CHECK_LIB([pam], [pam_start],
+-				       [AC_SUBST([pam_LIBS], [-lpam])],
+-				       [AC_MSG_ERROR([Unable to find LinuxPAM devel files])])])
+-
+-	AC_CHECK_HEADERS([security/pam_misc.h],
+-			 [AC_CHECK_LIB([pam_misc], [misc_conv],
+-				       [AC_SUBST([pam_misc_LIBS], [-lpam_misc])],
+-				       [AC_MSG_ERROR([Unable to find LinuxPAM MISC devel files])])])
+-
+-	AC_CHECK_LIB([qb], [qb_log_thread_priority_set],
+-		     [have_qb_log_thread_priority_set="yes"],
+-		     [have_qb_log_thread_priority_set="no"])
+-	if test "x${have_qb_log_thread_priority_set}" = xyes; then
+-		AC_DEFINE_UNQUOTED([HAVE_QB_LOG_THREAD_PRIORITY_SET], [1], [have qb_log_thread_priority_set])
+-	fi
+-fi
+-
+ # local options
+ AC_ARG_ENABLE([debug],
+ 	[AS_HELP_STRING([--enable-debug],[enable debug build])])
+@@ -329,84 +293,9 @@ AC_ARG_WITH([testdir],
+ 	[ TESTDIR="$withval" ],
+ 	[ TESTDIR="$libdir/kronosnet/tests" ])
+ 
+-AC_ARG_WITH([initdefaultdir],
+-	[AS_HELP_STRING([--with-initdefaultdir=DIR],[path to /etc/sysconfig or /etc/default dir])],
+-	[ INITDEFAULTDIR="$withval" ],
+-	[ INITDEFAULTDIR="$sysconfdir/default" ])
+-
+-AC_ARG_WITH([initddir],
+-	[AS_HELP_STRING([--with-initddir=DIR],[path to init script directory])],
+-	[ INITDDIR="$withval" ],
+-	[ INITDDIR="$sysconfdir/init.d" ])
+-
+-AC_ARG_WITH([systemddir],
+-	[AS_HELP_STRING([--with-systemddir=DIR],[path to systemd unit files directory])],
+-	[ SYSTEMDDIR="$withval" ],
+-	[ SYSTEMDDIR="$systemddir" ])
+-
+-AC_ARG_WITH([syslogfacility],
+-	[AS_HELP_STRING([--with-syslogfacility=FACILITY],[default syslog facility])],
+-	[ SYSLOGFACILITY="$withval" ],
+-	[ SYSLOGFACILITY="LOG_DAEMON" ])
+-
+-AC_ARG_WITH([sysloglevel],
+-	[AS_HELP_STRING([--with-sysloglevel=LEVEL],[default syslog level])],
+-	[ SYSLOGLEVEL="$withval" ],
+-	[ SYSLOGLEVEL="LOG_INFO" ])
+-
+-AC_ARG_WITH([defaultadmgroup],
+-	[AS_HELP_STRING([--with-defaultadmgroup=GROUP],
+-		[define PAM group. Users part of this group will be allowed to configure
+-		 kronosnet. Others will only receive read-only rights.])],
+-	[ DEFAULTADMGROUP="$withval" ],
+-	[ DEFAULTADMGROUP="kronosnetadm" ])
+-
+-## random vars
+-LOGDIR=${localstatedir}/log/
+-RUNDIR=${localstatedir}/run/
+-DEFAULT_CONFIG_DIR=${sysconfdir}/kronosnet
+-
+ ## do subst
+ 
+ AC_SUBST([TESTDIR])
+-AC_SUBST([DEFAULT_CONFIG_DIR])
+-AC_SUBST([INITDEFAULTDIR])
+-AC_SUBST([INITDDIR])
+-AC_SUBST([SYSTEMDDIR])
+-AC_SUBST([LOGDIR])
+-AC_SUBST([DEFAULTADMGROUP])
+-
+-AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_DIR],
+-		   ["$(eval echo ${DEFAULT_CONFIG_DIR})"],
+-		   [Default config directory])
+-
+-AC_DEFINE_UNQUOTED([DEFAULT_CONFIG_FILE],
+-		   ["$(eval echo ${DEFAULT_CONFIG_DIR}/kronosnetd.conf)"],
+-		   [Default config file])
+-
+-AC_DEFINE_UNQUOTED([LOGDIR],
+-		   ["$(eval echo ${LOGDIR})"],
+-		   [Default logging directory])
+-
+-AC_DEFINE_UNQUOTED([DEFAULT_LOG_FILE],
+-		   ["$(eval echo ${LOGDIR}/kronosnetd.log)"],
+-		   [Default log file])
+-
+-AC_DEFINE_UNQUOTED([RUNDIR],
+-		   ["$(eval echo ${RUNDIR})"],
+-		   [Default run directory])
+-
+-AC_DEFINE_UNQUOTED([SYSLOGFACILITY],
+-		   [$(eval echo ${SYSLOGFACILITY})],
+-		   [Default syslog facility])
+-
+-AC_DEFINE_UNQUOTED([SYSLOGLEVEL],
+-		   [$(eval echo ${SYSLOGLEVEL})],
+-		   [Default syslog level])
+-
+-AC_DEFINE_UNQUOTED([DEFAULTADMGROUP],
+-		   ["$(eval echo ${DEFAULTADMGROUP})"],
+-		   [Default admin group])
+ 
+ # debug build stuff
+ if test "x${enable_debug}" = xyes; then
+@@ -474,12 +363,9 @@ AC_MSG_NOTICE([using source epoch $($UTC_DATE_AT$SOURCE_EPOCH +'%F %T %Z')])
+ 
+ AC_CONFIG_FILES([
+ 		Makefile
+-		init/Makefile
+ 		libnozzle/Makefile
+ 		libnozzle/libnozzle.pc
+ 		libnozzle/tests/Makefile
+-		kronosnetd/Makefile
+-		kronosnetd/kronosnetd.logrotate
+ 		libknet/Makefile
+ 		libknet/libknet.pc
+ 		libknet/tests/Makefile
+diff --git a/init/Makefile.am b/init/Makefile.am
+deleted file mode 100644
+index 4581ee14..00000000
+--- a/init/Makefile.am
++++ /dev/null
+@@ -1,47 +0,0 @@
+-#
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-MAINTAINERCLEANFILES	= Makefile.in
+-
+-include $(top_srcdir)/build-aux/check.mk
+-
+-EXTRA_DIST		= kronosnetd.in kronosnetd.service.in \
+-			  kronosnetd.default
+-
+-if BUILD_KRONOSNETD
+-
+-systemdconfdir		= $(SYSTEMDDIR)
+-systemdconf_DATA	= kronosnetd.service
+-
+-initscriptdir		= $(INITDDIR)
+-initscript_SCRIPTS	= kronosnetd
+-
+-%: %.in Makefile
+-	rm -f $@-t $@
+-	cat $< | sed \
+-		-e 's#@''SBINDIR@#$(sbindir)#g' \
+-		-e 's#@''SYSCONFDIR@#$(sysconfdir)#g' \
+-		-e 's#@''INITDDIR@#$(INITDDIR)#g' \
+-		-e 's#@''LOCALSTATEDIR@#$(localstatedir)#g' \
+-	    > $@-t
+-	mv $@-t $@
+-
+-install-exec-local:
+-	$(INSTALL) -d $(DESTDIR)/$(INITDEFAULTDIR)
+-	$(INSTALL) -m 644 $(srcdir)/kronosnetd.default $(DESTDIR)/$(INITDEFAULTDIR)/kronosnetd
+-
+-uninstall-local:
+-	rm -f $(DESTDIR)/$(INITDEFAULTDIR)/kronosnetd
+-	rmdir $(DESTDIR)/$(INITDEFAULTDIR) || :;
+-
+-all-local: $(initscript_SCRIPTS) $(systemdconf_DATA)
+-
+-clean-local:
+-	rm -rf $(initscript_SCRIPTS) $(systemdconf_DATA)
+-
+-endif
+diff --git a/init/kronosnetd.default b/init/kronosnetd.default
+deleted file mode 100644
+index a29b829f..00000000
+--- a/init/kronosnetd.default
++++ /dev/null
+@@ -1,11 +0,0 @@
+-# kronosnetd startup options (see man kronosnetd.8)
+-#
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-
+-KNETD_OPTS=""
+diff --git a/init/kronosnetd.in b/init/kronosnetd.in
+deleted file mode 100644
+index d1a58909..00000000
+--- a/init/kronosnetd.in
++++ /dev/null
+@@ -1,152 +0,0 @@
+-#!/bin/bash
+-
+-#
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-# chkconfig: - 20 80
+-# description: kronosnetd vpn daemon
+-# processname: kronosnetd
+-#
+-### BEGIN INIT INFO
+-# Provides:		kronosnetd
+-# Required-Start:	$network $remote_fs $syslog
+-# Required-Stop:	$network $remote_fs $syslog
+-# Default-Start:	2 3 4 5
+-# Default-Stop:
+-# Short-Description:	Starts and stops kronosnetd vpn daemon.
+-# Description:		Starts and stops kronosnetd vpn daemon.
+-### END INIT INFO
+-
+-desc="kronosnetd"
+-prog="kronosnetd"
+-
+-# set secure PATH
+-PATH="/sbin:/bin:/usr/sbin:/usr/bin:@SBINDIR@"
+-
+-success()
+-{
+-	echo -ne "[  OK  ]\r"
+-}
+-
+-failure()
+-{
+-	echo -ne "[FAILED]\r"
+-}
+-
+-status()
+-{
+-	pid=$(pidof $1 2>/dev/null)
+-	rtrn=$?
+-	if [ $rtrn -ne 0 ]; then
+-		echo "$1 is stopped"
+-	else
+-		echo "$1 (pid $pid) is running..."
+-	fi
+-	return $rtrn
+-}
+-
+-# rpm based distros
+-if [ -d @SYSCONFDIR@/sysconfig ]; then
+-	[ -f @INITDDIR@/functions ] && . @INITDDIR@/functions
+-	[ -f @SYSCONFDIR@/sysconfig/$prog ] && . @SYSCONFDIR@/sysconfig/$prog
+-	[ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/subsys/$prog"
+-fi
+-
+-# deb based distros
+-if [ -d @SYSCONFDIR@/default ]; then
+-	[ -f @SYSCONFDIR@/default/$prog ] && . @SYSCONFDIR@/default/$prog
+-	[ -z "$LOCK_FILE" ] && LOCK_FILE="@LOCALSTATEDIR@/lock/$prog"
+-fi
+-
+-# The version of __pids_pidof in /etc/init.d/functions calls pidof with -x
+-# This means it matches scripts, including this one.
+-# Redefine it here so that status (from the same file) works.
+-# Otherwise simultaneous calls to stop() will loop forever
+-__pids_pidof() {
+-        pidof -c -o $$ -o $PPID -o %PPID "$1" || \
+-                pidof -c -o $$ -o $PPID -o %PPID "${1##*/}"
+-}
+-
+-start()
+-{
+-	echo -n "Starting $desc ($prog): "
+-
+-	# most recent distributions use tmpfs for @LOCALSTATEDIR@/run
+-	# to avoid to clean it up on every boot.
+-	# they also assume that init scripts will create
+-	# required subdirectories for proper operations
+-	mkdir -p @LOCALSTATEDIR@/run
+-
+-	if status $prog > /dev/null 2>&1; then
+-		success
+-	else
+-		$prog $KNETD_OPTS > /dev/null 2>&1
+-		touch $LOCK_FILE
+-		success
+-	fi
+-	echo
+-}
+-
+-stop()
+-{
+-	! status $prog > /dev/null 2>&1 && return
+-
+-	echo -n "Signaling $desc ($prog) to terminate: "
+-	kill -TERM $(pidof $prog) > /dev/null 2>&1
+-	success
+-	echo
+-
+-	echo -n "Waiting for $prog to unload:"
+-	while status $prog > /dev/null 2>&1; do
+-		sleep 1
+-		echo -n "."
+-	done
+-
+-	rm -f $LOCK_FILE
+-	success
+-	echo
+-}
+-
+-restart()
+-{
+-	stop
+-	start
+-}
+-
+-rtrn=0
+-
+-case "$1" in
+-start)
+-	start
+-	rtrn=$?
+-;;
+-restart|reload|force-reload)
+-	restart
+-	rtrn=$?
+-;;
+-condrestart|try-restart)
+-	if status $prog > /dev/null 2>&1; then
+-		restart
+-		rtrn=$?
+-	fi
+-;;
+-status)
+-	status $prog
+-	rtrn=$?
+-;;
+-stop)
+-	stop
+-	rtrn=$?
+-;;
+-*)
+-	echo "usage: $0 {start|stop|restart|reload|force-reload|condrestart|try-restart|status}"
+-	rtrn=2
+-;;
+-esac
+-
+-exit $rtrn
+diff --git a/init/kronosnetd.service.in b/init/kronosnetd.service.in
+deleted file mode 100644
+index 04507c51..00000000
+--- a/init/kronosnetd.service.in
++++ /dev/null
+@@ -1,20 +0,0 @@
+-#
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-[Unit]
+-Description=kronosnetd
+-Requires=network.target
+-After=network.target syslog.target
+-
+-[Service]
+-Type=forking
+-EnvironmentFile=/etc/sysconfig/kronosnetd
+-ExecStart=@SBINDIR@/kronosnetd $KNETD_OPTS
+-
+-[Install]
+-WantedBy=multi-user.target
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 6c0b6c5d..12ea00a5 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -25,7 +25,6 @@
+ %@lzma@ lzma
+ %@bzip2@ bzip2
+ %@zstd@ zstd
+-%@kronosnetd@ kronosnetd
+ %@libnozzle@ libnozzle
+ %@runautogen@ runautogen
+ %@rpmdebuginfo@ rpmdebuginfo
+@@ -97,9 +96,6 @@ BuildRequires: bzip2-devel
+ %if %{with zstd}
+ BuildRequires: libzstd-devel
+ %endif
+-%if %{with kronosnetd}
+-BuildRequires: pam-devel
+-%endif
+ %if %{with libnozzle}
+ BuildRequires: libnl3-devel
+ %endif
+@@ -171,11 +167,6 @@ BuildRequires: autoconf automake libtool
+ %else
+ 	--disable-compress-zstd \
+ %endif
+-%if %{with kronosnetd}
+-	--enable-kronosnetd \
+-%else
+-	--disable-kronosnetd \
+-%endif
+ %if %{with libnozzle}
+ 	--enable-libnozzle \
+ %else
+@@ -206,48 +197,6 @@ rm -rf %{buildroot}/usr/share/doc/kronosnet
+ %description
+  The kronosnet source
+ 
+-%if %{with kronosnetd}
+-## Runtime and subpackages section
+-%package -n kronosnetd
+-Summary: Multipoint-to-Multipoint VPN daemon
+-License: GPLv2+
+-Requires(post):   systemd-sysv
+-Requires(post):   systemd-units
+-Requires(preun):  systemd-units
+-Requires(postun): systemd-units
+-Requires(post):   shadow-utils
+-Requires(preun):  shadow-utils
+-Requires: pam, /etc/pam.d/passwd
+-
+-%description -n kronosnetd
+- The kronosnet daemon is a bridge between kronosnet switching engine
+- and kernel network tap devices, to create and administer a
+- distributed LAN over multipoint-to-multipoint VPNs.
+- The daemon does a poor attempt to provide a configure UI similar
+- to other known network devices/tools (Cisco, quagga).
+- Beside looking horrific, it allows runtime changes and
+- reconfiguration of the kronosnet(s) without daemon reload
+- or service disruption.
+-
+-%post -n kronosnetd
+-%systemd_post kronosnetd.service
+-getent group @defaultadmgroup@ >/dev/null || groupadd --force --system @defaultadmgroup@
+-
+-%preun -n kronosnetd
+-%systemd_preun kronosnetd.service
+-
+-%files -n kronosnetd
+-%license COPYING.* COPYRIGHT
+-%dir %{_sysconfdir}/kronosnet
+-%dir %{_sysconfdir}/kronosnet/*
+-%config(noreplace) %{_sysconfdir}/sysconfig/kronosnetd
+-%config(noreplace) %{_sysconfdir}/pam.d/kronosnetd
+-%config(noreplace) %{_sysconfdir}/logrotate.d/kronosnetd
+-%{_unitdir}/kronosnetd.service
+-%{_sbindir}/*
+-%{_mandir}/man8/*
+-%endif
+-
+ %if %{with libnozzle}
+ %package -n libnozzle1
+ Summary: Simple userland wrapper around kernel tap devices
+diff --git a/kronosnetd/Makefile.am b/kronosnetd/Makefile.am
+deleted file mode 100644
+index 041d1f8c..00000000
+--- a/kronosnetd/Makefile.am
++++ /dev/null
+@@ -1,89 +0,0 @@
+-#
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-MAINTAINERCLEANFILES	= Makefile.in kronostnetd.logrotate
+-
+-include $(top_srcdir)/build-aux/check.mk
+-
+-EXTRA_DIST		= kronosnetd.logrotate.in
+-
+-noinst_HEADERS		= \
+-			  cfg.h \
+-			  etherfilter.h \
+-			  logging.h \
+-			  vty.h \
+-			  vty_auth.h \
+-			  vty_cli.h \
+-			  vty_cli_cmds.h \
+-			  vty_utils.h 
+-
+-kronosnetd_SOURCES	= \
+-			  cfg.c \
+-			  etherfilter.c \
+-			  main.c \
+-			  logging.c \
+-			  vty.c \
+-			  vty_auth.c \
+-			  vty_cli.c \
+-			  vty_cli_cmds.c \
+-			  vty_utils.c
+-
+-kronosnetd_CPPFLAGS	= \
+-			  -I$(top_srcdir)/libnozzle \
+-			  -I$(top_srcdir)/libknet
+-
+-kronosnetd_CFLAGS	= $(AM_CFLAGS) $(libqb_CFLAGS)
+-
+-kronosnetd_LDADD	= \
+-			  $(top_builddir)/libknet/libknet.la \
+-			  $(top_builddir)/libnozzle/libnozzle.la \
+-			  $(libqb_LIBS) \
+-			  $(pam_misc_LIBS) $(pam_LIBS)
+-
+-knet_keygen_SOURCES	= keygen.c
+-
+-knet_keygen_CPPFLAGS	= -I$(top_srcdir)/libknet
+-
+-if BUILD_KRONOSNETD
+-
+-sbin_PROGRAMS		= kronosnetd \
+-			  knet-keygen
+-
+-install-exec-local:
+-	$(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)
+-	$(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/down.d
+-	$(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/post-down.d
+-	$(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/pre-up.d
+-	$(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/up.d
+-	$(INSTALL) -d $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/cryptokeys.d
+-	$(INSTALL) -d -m 0755 $(DESTDIR)/$(sysconfdir)/logrotate.d
+-	$(INSTALL) -m 644 kronosnetd.logrotate $(DESTDIR)/$(sysconfdir)/logrotate.d/kronosnetd
+-	$(INSTALL) -d -m 0755 $(DESTDIR)/$(sysconfdir)/pam.d
+-	if [ -a $(sysconfdir)/pam.d/password-auth ]; then \
+-		cd $(DESTDIR)/$(sysconfdir)/pam.d && \
+-			rm -f kronosnetd && \
+-			$(LN_S) password-auth kronosnetd; \
+-	else \
+-		cd $(DESTDIR)/$(sysconfdir)/pam.d && \
+-			rm -f kronosnetd && \
+-			$(LN_S) passwd kronosnetd; \
+-	fi
+-
+-uninstall-local:
+-	rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/cryptokeys.d || :;
+-	rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/down.d || :;
+-	rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/post-down.d || :;
+-	rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/pre-up.d || :;
+-	rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR)/up.d || :;
+-	rmdir $(DESTDIR)/$(DEFAULT_CONFIG_DIR) || :;
+-	rm -f $(DESTDIR)/$(sysconfdir)/logrotate.d/kronosnetd
+-	rmdir $(DESTDIR)/$(sysconfdir)/logrotate.d || :;
+-	rm -f $(DESTDIR)/$(sysconfdir)/pam.d/kronosnetd || :;
+-	rmdir $(DESTDIR)/$(sysconfdir)/pam.d || :;
+-
+-endif
+diff --git a/kronosnetd/cfg.c b/kronosnetd/cfg.c
+deleted file mode 100644
+index 19ffce50..00000000
+--- a/kronosnetd/cfg.c
++++ /dev/null
+@@ -1,88 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <pthread.h>
+-#include <unistd.h>
+-#include <stdlib.h>
+-#include <string.h>
+-
+-#include "cfg.h"
+-#include "libnozzle.h"
+-
+-struct knet_cfg *knet_get_iface(const char *name, int create)
+-{
+-	struct knet_cfg *knet_iface = knet_cfg_head.knet_cfg;
+-	int found = 0;
+-
+-	while (knet_iface != NULL) {
+-		if (!strcmp(tap_get_name(knet_iface->cfg_eth.tap), name)) {
+-			found = 1;
+-			break;
+-		}
+-		knet_iface = knet_iface->next;
+-	}
+-
+-	if ((!found) && (create)) {
+-		knet_iface = malloc(sizeof(struct knet_cfg));
+-		if (!knet_iface)
+-			goto out_clean;
+-
+-		memset(knet_iface, 0, sizeof(struct knet_cfg));
+-
+-		knet_iface->cfg_ring.base_port = KNET_RING_DEFPORT;
+-
+-		strncpy(knet_iface->knet_handle_crypto_cfg.crypto_model,
+-			"none",
+-			sizeof(knet_iface->knet_handle_crypto_cfg.crypto_model) - 1);
+-
+-		strncpy(knet_iface->knet_handle_crypto_cfg.crypto_cipher_type,
+-			"none",
+-			sizeof(knet_iface->knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+-
+-		strncpy(knet_iface->knet_handle_crypto_cfg.crypto_hash_type,
+-			"none",
+-			sizeof(knet_iface->knet_handle_crypto_cfg.crypto_hash_type) - 1);
+-
+-		if (knet_cfg_head.knet_cfg) {
+-			struct knet_cfg *knet_iface_last = knet_cfg_head.knet_cfg;
+-
+-			while (knet_iface_last->next != NULL) {
+-				knet_iface_last = knet_iface_last->next;
+-			}
+-			knet_iface_last->next = knet_iface;
+-		} else {
+-			knet_cfg_head.knet_cfg = knet_iface;
+-		}
+-	}
+-
+-out_clean:
+-
+-	return knet_iface;
+-}
+-
+-void knet_destroy_iface(struct knet_cfg *knet_iface)
+-{
+-	struct knet_cfg *knet_iface_tmp = knet_cfg_head.knet_cfg;
+-	struct knet_cfg *knet_iface_prev = knet_cfg_head.knet_cfg;
+-
+-	while (knet_iface_tmp != knet_iface) {
+-		knet_iface_prev = knet_iface_tmp;
+-		knet_iface_tmp = knet_iface_tmp->next;
+-	}
+-
+-	if (knet_iface_tmp == knet_iface) {
+-		if (knet_iface_tmp == knet_iface_prev) {
+-			knet_cfg_head.knet_cfg = knet_iface_tmp->next;
+-		} else {
+-			knet_iface_prev->next = knet_iface_tmp->next;
+-		}
+-		free(knet_iface);
+-	}
+-}
+diff --git a/kronosnetd/cfg.h b/kronosnetd/cfg.h
+deleted file mode 100644
+index e3a2acdb..00000000
+--- a/kronosnetd/cfg.h
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_CFG_H__
+-#define __KNETD_CFG_H__
+-
+-#include <stdint.h>
+-#include <net/if.h>
+-
+-#include "libnozzle.h"
+-#include "libknet.h"
+-
+-#define KNET_RING_DEFPORT 50000
+-
+-struct knet_cfg_eth {
+-	tap_t tap;
+-	int auto_mtu;
+-	knet_node_id_t node_id;
+-};
+-
+-struct knet_cfg_ring {
+-	knet_handle_t knet_h;
+-	int data_mtu;
+-	int base_port;
+-};
+-
+-struct knet_cfg {
+-	struct knet_cfg_eth cfg_eth;
+-	struct knet_cfg_ring cfg_ring;
+-	int active;
+-	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+-	struct knet_cfg *next;
+-};
+-
+-struct knet_cfg_top {
+-	char *conffile;
+-	char *logfile;
+-	char *vty_ipv4;
+-	char *vty_ipv6;
+-	char *vty_port;
+-	struct knet_cfg *knet_cfg;
+-};
+-
+-struct knet_cfg *knet_get_iface(const char *name, const int create);
+-void knet_destroy_iface(struct knet_cfg *knet_iface);
+-
+-extern struct knet_cfg_top knet_cfg_head;
+-
+-#endif
+diff --git a/kronosnetd/etherfilter.c b/kronosnetd/etherfilter.c
+deleted file mode 100644
+index dbea73cc..00000000
+--- a/kronosnetd/etherfilter.c
++++ /dev/null
+@@ -1,64 +0,0 @@
+-/*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <arpa/inet.h>
+-#include <netinet/ether.h>
+-#include <string.h>
+-
+-#include "etherfilter.h"
+-
+-/*
+- * stole from linux kernel/include/linux/etherdevice.h
+- */
+-
+-static inline int is_zero_ether_addr(const uint8_t *addr)
+-{
+-	return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
+-}
+-
+-static inline int is_multicast_ether_addr(const uint8_t *addr)
+-{
+-	return 0x01 & addr[0];
+-}
+-
+-static inline int is_broadcast_ether_addr(const uint8_t *addr)
+-{
+-	return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) == 0xff;
+-}
+-
+-int ether_host_filter_fn (void *private_data,
+-			  const unsigned char *outdata,
+-			  ssize_t outdata_len,
+-			  uint8_t tx_rx,
+-			  knet_node_id_t this_host_id,
+-			  knet_node_id_t src_host_id,
+-			  int8_t *channel,
+-			  knet_node_id_t *dst_host_ids,
+-			  size_t *dst_host_ids_entries)
+-{
+-	struct ether_header *eth_h = (struct ether_header *)outdata;
+-	uint8_t *dst_mac = (uint8_t *)eth_h->ether_dhost;
+-	uint16_t dst_host_id;
+-
+-	if (is_zero_ether_addr(dst_mac))
+-		return -1;
+-
+-	if (is_multicast_ether_addr(dst_mac) ||
+-	    is_broadcast_ether_addr(dst_mac)) {
+-		return 1;
+-	}
+-
+-	memmove(&dst_host_id, &dst_mac[4], 2);
+-
+-	dst_host_ids[0] = ntohs(dst_host_id);
+-	*dst_host_ids_entries = 1;
+-
+-	return 0;
+-}
+diff --git a/kronosnetd/etherfilter.h b/kronosnetd/etherfilter.h
+deleted file mode 100644
+index 9c733dd4..00000000
+--- a/kronosnetd/etherfilter.h
++++ /dev/null
+@@ -1,25 +0,0 @@
+-/*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_ETHERFILTER_H__
+-#define __KNETD_ETHERFILTER_H__
+-
+-#include <stdint.h>
+-#include "libknet.h"
+-
+-int ether_host_filter_fn (void *private_data,
+-			  const unsigned char *outdata,
+-			  ssize_t outdata_len,
+-			  uint8_t tx_rx,
+-			  knet_node_id_t this_host_id,
+-			  knet_node_id_t src_host_id,
+-			  int8_t *channel,
+-			  knet_node_id_t *dst_host_ids,
+-			  size_t *dst_host_ids_entries);
+-
+-#endif
+diff --git a/kronosnetd/keygen.c b/kronosnetd/keygen.c
+deleted file mode 100644
+index 41251cff..00000000
+--- a/kronosnetd/keygen.c
++++ /dev/null
+@@ -1,180 +0,0 @@
+-/*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <stdio.h>
+-#include <string.h>
+-#include <limits.h>
+-#include <unistd.h>
+-#include <stdlib.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-
+-#include <libknet.h>
+-
+-static char *output_file = NULL;
+-static ssize_t keylen = KNET_MAX_KEY_LEN;
+-
+-static void print_usage(void)
+-{
+-	printf("\nUsage:\n\n");
+-	printf("knet-keygen -o <output_file> [-s <size>]\n\n");
+-};
+-
+-#define OPTION_STRING "ho:s:"
+-
+-static int read_arguments(int argc, char **argv)
+-{
+-	int cont = 1;
+-	int optchar;
+-
+-	while (cont) {
+-		optchar = getopt(argc, argv, OPTION_STRING);
+-
+-		switch (optchar) {
+-
+-		case 'o':
+-			output_file = strdup(optarg);
+-			if (!output_file) {
+-				fprintf(stderr, "Error: Unable to allocate memory\n");
+-				return -1;
+-			}
+-			if (strlen(output_file) > PATH_MAX) {
+-				fprintf(stderr, "Seriously? WTF\n");
+-				return -1;
+-			}
+-			break;
+-
+-		case 's':
+-			keylen = atoi(optarg);
+-			if ((keylen < KNET_MIN_KEY_LEN) || (keylen > KNET_MAX_KEY_LEN)) {
+-				fprintf(stderr, "Error: Key size should be a value between %d and %d (default) included\n",
+-					KNET_MIN_KEY_LEN, KNET_MAX_KEY_LEN);
+-				return -1;
+-			}
+-			break;
+-
+-		case 'h':
+-			print_usage();
+-			exit(EXIT_SUCCESS);
+-			break;
+-
+-		case EOF:
+-			cont = 0;
+-			break;
+-
+-		default:
+-			fprintf(stderr, "Error: unknown option: %c\n", optchar);
+-			print_usage();
+-			return -1;
+-			break;
+-
+-		}
+-	}
+-	if (!output_file) {
+-		fprintf(stderr, "Error: no output file specified\n");
+-		print_usage();
+-		return -1;
+-	}
+-	return 0;
+-}
+-
+-int main (int argc, char *argv[])
+-{
+-	int ret = 0;
+-	int fd = -1;
+-	ssize_t res;
+-	ssize_t bytes_read = 0;
+-	char *keybuf = NULL;
+-
+-	printf (PACKAGE " key generator.\n");
+-
+-	if (read_arguments(argc, argv) < 0) {
+-		goto exit_error;
+-	}
+-
+-	if (geteuid() != 0) {
+-		fprintf(stderr, "Error: Authorization key must be generated as root user.\n");
+-		goto exit_error;
+-	}
+-
+-	fd = open ("/dev/random", O_RDONLY);
+-	if (fd < 0) {
+-		fprintf(stderr, "Error: Unable to open /dev/random\n");
+-		goto exit_error;
+-	}
+-
+-	keybuf = malloc(keylen);
+-	if (!keybuf) {
+-		fprintf(stderr, "Error: Unable to allocate memory for key\n");
+-		goto exit_error;
+-	}
+-
+-	printf("Gathering %zd bytes for key from /dev/random.\n", keylen);
+-	printf("This process might take a long time due the amount on entropy required\n");
+-	printf("Press keys on your keyboard, perform any kind of disk I/O and/or network to generate entropy faster.\n");
+-
+-keep_reading:
+-	res = read(fd, &keybuf[bytes_read], keylen - bytes_read);
+-	if (res == -1) {
+-		fprintf(stderr, "Error: Unable to read from /dev/random.\n");
+-		goto exit_error;
+-	}
+-	bytes_read += res;
+-	if (bytes_read != keylen) {
+-		printf("bytes read = %zd, missing = %zd.\n", bytes_read, keylen - bytes_read);
+-		goto keep_reading;
+-	}
+-	close (fd);
+-	fd = -1;
+-
+-	fd = open (output_file, O_CREAT|O_WRONLY, 600);
+-	if (fd == -1) {
+-		fprintf(stderr, "Error: Could not create %s\n", output_file);
+-		goto exit_error;
+-	}
+-
+-	/*
+-	 * Make sure file is owned by root and mode 0400
+-	 */
+-	if (fchown(fd, 0, 0)) {
+-		fprintf(stderr, "Error: Could not set uid 0 (root) and gid 0 (root) on keyfile %s\n", output_file);
+-		goto exit_error;
+-	}
+-	if (fchmod(fd, 0400)) {
+-		fprintf(stderr, "Error: Could not set read-only permissions on keyfile %s\n", output_file);
+-		goto exit_error;
+-	}
+-
+-	printf("Writing private key to %s\n", output_file);
+-
+-	if (write(fd, keybuf, keylen) != keylen) {
+-		fprintf(stderr, "Error: Could not write key to file %s\n", output_file);
+-		goto exit_error;
+-	}
+-
+-	printf("Done.\n");
+-	printf("Please copy this file in " DEFAULT_CONFIG_DIR "/cryptokeys.d/<knet_interface_name>\n");
+-	printf("on all nodes participating in the same kronosnet instance\n");
+-
+-exit_clean:
+-	if (output_file)
+-		free(output_file);
+-	if (keybuf)
+-		free(keybuf);
+-	if (fd > -1)
+-		close(fd);
+-
+-	return ret;
+-
+-exit_error:
+-	ret = -1;
+-	goto exit_clean;
+-}
+diff --git a/kronosnetd/kronosnetd.logrotate.in b/kronosnetd/kronosnetd.logrotate.in
+deleted file mode 100644
+index e78034cc..00000000
+--- a/kronosnetd/kronosnetd.logrotate.in
++++ /dev/null
+@@ -1,17 +0,0 @@
+-#
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-@LOGDIR@kronosnetd.log {
+-	missingok
+-	compress
+-	copytruncate
+-	daily
+-	rotate 31
+-	minsize 2048
+-	notifempty
+-}
+diff --git a/kronosnetd/logging.c b/kronosnetd/logging.c
+deleted file mode 100644
+index ee30dd17..00000000
+--- a/kronosnetd/logging.c
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include "logging.h"
+-
+-void logging_init_defaults(int debug, int daemonize, const char *logfile)
+-{
+-	int level = SYSLOGLEVEL;
+-	int32_t filetarget;
+-
+-	if (debug) {
+-		level = LOG_DEBUG;
+-	}
+-
+-	qb_log_init(PACKAGE "d", SYSLOGFACILITY, level);
+-
+-	qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_ENABLED, QB_TRUE);
+-	if (debug) {
+-		qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_PRIORITY_BUMP,
+-			   LOG_INFO - LOG_DEBUG);
+-	}
+-
+-	/*
+-	 * initialize stderr output only if we are not forking in background
+-	 */
+-	if (!daemonize) {
+-		qb_log_format_set(QB_LOG_STDERR, "%t %N [%p]: %b");
+-		qb_log_ctl(QB_LOG_STDERR, QB_LOG_CONF_ENABLED, QB_TRUE);
+-		qb_log_filter_ctl(QB_LOG_STDERR, QB_LOG_FILTER_ADD,
+-				  QB_LOG_FILTER_FUNCTION, "*", level);
+-	}
+-
+-	filetarget = qb_log_file_open(logfile);
+-	qb_log_ctl(filetarget, QB_LOG_CONF_ENABLED, QB_TRUE);
+-	qb_log_format_set(filetarget, "%t %N [%p]: %b");
+-	qb_log_filter_ctl(filetarget, QB_LOG_FILTER_ADD,
+-			  QB_LOG_FILTER_FUNCTION, "*", level);
+-
+-	qb_log_thread_start();
+-	qb_log_ctl(QB_LOG_SYSLOG, QB_LOG_CONF_THREADED, QB_TRUE);
+-	qb_log_ctl(filetarget, QB_LOG_CONF_THREADED, QB_TRUE);
+-}
+-
+-void logging_fini(void)
+-{
+-	qb_log_fini();
+-}
+diff --git a/kronosnetd/logging.h b/kronosnetd/logging.h
+deleted file mode 100644
+index a32d7277..00000000
+--- a/kronosnetd/logging.h
++++ /dev/null
+@@ -1,29 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_LOGGING_H__
+-#define __KNETD_LOGGING_H__
+-
+-#include <qb/qblog.h>
+-
+-#define log_debug(fmt, args...) qb_log(LOG_DEBUG, "(%s:%i|%s): " fmt, __FILE__, __LINE__, __FUNCTION__, ##args);
+-
+-#define log_kdebug(fmt, args...) qb_log(LOG_DEBUG, fmt, ##args);
+-
+-#define log_info(fmt, args...) qb_log(LOG_INFO, fmt, ##args);
+-
+-#define log_warn(fmt, args...) qb_log(LOG_WARNING, fmt, ##args);
+-
+-#define log_error(fmt, args...) qb_log(LOG_ERR, fmt, ##args);
+-
+-void logging_init_defaults(int debug, int daemonize, const char *logfile);
+-
+-void logging_fini(void);
+-
+-#endif
+diff --git a/kronosnetd/main.c b/kronosnetd/main.c
+deleted file mode 100644
+index 86a530ff..00000000
+--- a/kronosnetd/main.c
++++ /dev/null
+@@ -1,347 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <stdio.h>
+-#include <unistd.h>
+-#include <stdlib.h>
+-#include <sched.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#include <errno.h>
+-#include <string.h>
+-
+-#include "cfg.h"
+-#include "vty.h"
+-#include "logging.h"
+-
+-#define LOCKFILE_NAME RUNDIR PACKAGE "d.pid"
+-
+-#define OPTION_STRING "hdfVc:l:a:b:p:"
+-
+-static int debug = 0;
+-static int daemonize = 1;
+-
+-struct knet_cfg_top knet_cfg_head;
+-
+-static void print_usage(void)
+-{
+-	printf("Usage:\n\n");
+-	printf(PACKAGE "d [options]\n\n");
+-	printf("Options:\n\n");
+-	printf("  -a <ipv6_addr> Bind management VTY to ipv6_addr (default: localhost)\n");
+-	printf("  -b <ipv4_addr> Bind management VTY to ipv4_addr (default: localhost)\n");
+-	printf("  -p <port>      Bind management VTY to port (default %d)\n",
+-		KNET_VTY_DEFAULT_PORT);
+-	printf("  -c <file>      Use config file (default "DEFAULT_CONFIG_FILE")\n");
+-	printf("  -l <file>      Use log file (default "DEFAULT_LOG_FILE")\n");
+-	printf("  -f             Do not fork in background\n");
+-	printf("  -d             Enable debugging output\n");
+-	printf("  -h             This help\n");
+-	printf("  -V             Print program version information\n");
+-	return;
+-}
+-
+-static int read_arguments(int argc, char **argv)
+-{
+-	int cont = 1;
+-	int optchar;
+-	int int_port;
+-
+-	while (cont) {
+-		optchar = getopt(argc, argv, OPTION_STRING);
+-
+-		switch (optchar) {
+-
+-		case 'a':
+-			knet_cfg_head.vty_ipv6 = strdup(optarg);
+-			if (!knet_cfg_head.vty_ipv6)
+-				return -1;
+-			break;
+-
+-		case 'b':
+-			knet_cfg_head.vty_ipv4 = strdup(optarg);
+-			if (!knet_cfg_head.vty_ipv4)
+-				return -1;
+-			break;
+-
+-		case 'p':
+-			int_port = atoi(optarg);
+-			if ((int_port < 0) || (int_port > 65535)) {
+-				errno = EINVAL;
+-				return -1;
+-			}
+-			knet_cfg_head.vty_port = strdup(optarg);
+-			if (!knet_cfg_head.vty_port)
+-				return -1;
+-			break;
+-
+-		case 'c':
+-			knet_cfg_head.conffile = strdup(optarg);
+-			if (!knet_cfg_head.conffile)
+-				return -1;
+-			break;
+-
+-		case 'l':
+-			knet_cfg_head.logfile = strdup(optarg);
+-			if (!knet_cfg_head.logfile)
+-				return -1;
+-			break;
+-
+-		case 'd':
+-			debug = 1;
+-			break;
+-
+-		case 'f':
+-			daemonize = 0;
+-			break;
+-
+-		case 'h':
+-			print_usage();
+-			exit(EXIT_SUCCESS);
+-			break;
+-
+-		case 'V':
+-			printf(PACKAGE "d " PACKAGE_VERSION " (built " __DATE__
+-			       " " __TIME__ ")\n");
+-			exit(EXIT_SUCCESS);
+-			break;
+-
+-		case EOF:
+-			cont = 0;
+-			break;
+-
+-		default:
+-			fprintf(stderr, "unknown option: %c\n", optchar);
+-			print_usage();
+-			exit(EXIT_FAILURE);
+-			break;
+-
+-		}
+-	}
+-	return 0;
+-}
+-
+-static int set_scheduler(void)
+-{
+-	struct sched_param sched_param;
+-	int err;
+-
+-	err = sched_get_priority_max(SCHED_RR);
+-	if (err < 0) {
+-		log_warn("Could not get maximum scheduler priority");
+-		return err;
+-	}
+-
+-	sched_param.sched_priority = err;
+-	err = sched_setscheduler(0, SCHED_RR, &sched_param);
+-	if (err < 0)
+-		log_warn("could not set SCHED_RR priority %d",
+-			   sched_param.sched_priority);
+-
+-	return err;
+-}
+-
+-static void remove_lockfile(void)
+-{
+-	unlink(LOCKFILE_NAME);
+-}
+-
+-static int create_lockfile(const char *lockfile)
+-{
+-	int fd, value;
+-	size_t bufferlen;
+-	ssize_t write_out;
+-	struct flock lock;
+-	char buffer[50];
+-
+-	if ((fd = open(lockfile, O_CREAT | O_WRONLY,
+-		       (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
+-		fprintf(stderr, "Cannot open lockfile [%s], error was [%s]\n",
+-			lockfile, strerror(errno));
+-		return -1;
+-	}
+-
+-	lock.l_type = F_WRLCK;
+-	lock.l_start = 0;
+-	lock.l_whence = SEEK_SET;
+-	lock.l_len = 0;
+-
+-retry_fcntl:
+-
+-	if (fcntl(fd, F_SETLK, &lock) < 0) {
+-		switch (errno) {
+-		case EINTR:
+-			goto retry_fcntl;
+-			break;
+-		case EACCES:
+-		case EAGAIN:
+-			fprintf(stderr, "Cannot lock lockfile [%s], error was [%s]\n",
+-				lockfile, strerror(errno));
+-			break;
+-		default:
+-			fprintf(stderr, "process is already running\n");
+-		}
+-
+-		goto fail_close;
+-	}
+-
+-	if (ftruncate(fd, 0) < 0) {
+-		fprintf(stderr, "Cannot truncate pidfile [%s], error was [%s]\n",
+-			lockfile, strerror(errno));
+-
+-		goto fail_close_unlink;
+-	}
+-
+-	memset(buffer, 0, sizeof(buffer));
+-	snprintf(buffer, sizeof(buffer)-1, "%d\n", getpid());
+-
+-	bufferlen = strlen(buffer);
+-	write_out = write(fd, buffer, bufferlen);
+-
+-	if ((write_out < 0) || (write_out == 0 && errno)) {
+-		fprintf(stderr, "Cannot write pid to pidfile [%s], error was [%s]\n",
+-			lockfile, strerror(errno));
+-
+-		goto fail_close_unlink;
+-	}
+-
+-	if ((write_out == 0) || ((size_t)write_out < bufferlen)) {
+-		fprintf(stderr, "Cannot write pid to pidfile [%s], shortwrite of"
+-				"[%zd] bytes, expected [%zu]\n",
+-				lockfile, write_out, bufferlen);
+-
+-		goto fail_close_unlink;
+-	}
+-
+-	if ((value = fcntl(fd, F_GETFD, 0)) < 0) {
+-		fprintf(stderr, "Cannot get close-on-exec flag from pidfile [%s], "
+-				"error was [%s]\n", lockfile, strerror(errno));
+-
+-		goto fail_close_unlink;
+-	}
+-	value |= FD_CLOEXEC;
+-	if (fcntl(fd, F_SETFD, value) < 0) {
+-		fprintf(stderr, "Cannot set close-on-exec flag from pidfile [%s], "
+-				"error was [%s]\n", lockfile, strerror(errno));
+-
+-		goto fail_close_unlink;
+-	}
+-
+-	atexit(remove_lockfile);
+-
+-	return 0;
+-
+-fail_close_unlink:
+-	if (unlink(lockfile))
+-		fprintf(stderr, "Unable to unlink %s\n", lockfile);
+-
+-fail_close:
+-	if (close(fd))
+-		fprintf(stderr, "Unable to close %s file descriptor\n", lockfile);
+-	return -1;
+-}
+-
+-static void set_cfg_defaults(void)
+-{
+-	if (!knet_cfg_head.conffile)
+-		knet_cfg_head.conffile = strdup(DEFAULT_CONFIG_FILE);
+-	if (!knet_cfg_head.conffile) {
+-		fprintf(stderr, "Unable to allocate memory for config file\n");
+-		exit(EXIT_FAILURE);
+-	}
+-
+-	if (!knet_cfg_head.logfile)
+-		knet_cfg_head.logfile = strdup(DEFAULT_LOG_FILE);
+-	if (!knet_cfg_head.conffile) {
+-		fprintf(stderr, "Unable to allocate memory for log file\n");
+-		exit(EXIT_FAILURE);
+-	}
+-
+-	if (!knet_cfg_head.vty_ipv6)
+-		knet_cfg_head.vty_ipv6 = strdup("::1");
+-	if (!knet_cfg_head.vty_ipv6) {
+-		fprintf(stderr, "Unable to allocate memory for default ip address\n");
+-		exit(EXIT_FAILURE);
+-	}
+-
+-	if (!knet_cfg_head.vty_ipv4)
+-		knet_cfg_head.vty_ipv4 = strdup("127.0.0.1");
+-	if (!knet_cfg_head.vty_ipv4) {
+-		fprintf(stderr, "Unable to allocate memory for default ip address\n");
+-		exit(EXIT_FAILURE);
+-	}
+-
+-	if (!knet_cfg_head.vty_port) {
+-		char portbuf[8];
+-		memset(&portbuf, 0, sizeof(portbuf));
+-		snprintf(portbuf, sizeof(portbuf), "%d", KNET_VTY_DEFAULT_PORT);
+-		knet_cfg_head.vty_port = strdup(portbuf);
+-	}
+-	if (!knet_cfg_head.vty_port) {
+-		fprintf(stderr, "Unable to allocate memory for default port address\n");
+-		exit(EXIT_FAILURE);
+-	}
+-}
+-
+-int main(int argc, char **argv)
+-{
+-	int err;
+-
+-	memset(&knet_cfg_head, 0, sizeof(struct knet_cfg_top));
+-
+-	if (read_arguments(argc, argv) < 0) {
+-		fprintf(stderr, "Unable to parse options\n");
+-		exit(EXIT_FAILURE);
+-	}
+-
+-	set_cfg_defaults();
+-
+-	if (create_lockfile(LOCKFILE_NAME) < 0) {
+-		fprintf(stderr, "Unable to create lockfile\n");
+-		exit(EXIT_FAILURE);
+-	}
+-
+-	if (daemonize) {
+-		if (daemon(0, 0) < 0) {
+-			perror("Unable to daemonize");
+-			exit(EXIT_FAILURE);
+-		}
+-	}
+-
+-	logging_init_defaults(debug, daemonize, knet_cfg_head.logfile);
+-	log_info(PACKAGE "d version " VERSION);
+-
+-	/*
+-	 * don't fail if scheduler is not RR because systemd is
+-	 * an utter piece of shit that refuses us to set RR via init script
+-	 */
+-	set_scheduler();
+-
+-	err = knet_vty_main_loop(debug);
+-	if (err < 0)
+-		log_error("Detected fatal error in main loop");
+-
+-	if (knet_cfg_head.logfile)
+-		free(knet_cfg_head.logfile);
+-	if (knet_cfg_head.conffile)
+-		free(knet_cfg_head.conffile);
+-	if (knet_cfg_head.vty_ipv6)
+-		free(knet_cfg_head.vty_ipv6);
+-	if (knet_cfg_head.vty_ipv4)
+-		free(knet_cfg_head.vty_ipv4);
+-	if (knet_cfg_head.vty_port)
+-		free(knet_cfg_head.vty_port);
+-
+-	logging_fini();
+-
+-	return err;
+-}
+diff --git a/kronosnetd/vty.c b/kronosnetd/vty.c
+deleted file mode 100644
+index 4e54a1fa..00000000
+--- a/kronosnetd/vty.c
++++ /dev/null
+@@ -1,504 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include <unistd.h>
+-#include <fcntl.h>
+-#include <arpa/inet.h>
+-#include <string.h>
+-#include <errno.h>
+-#include <pthread.h>
+-#include <signal.h>
+-#include <stdlib.h>
+-
+-#include "cfg.h"
+-#include "logging.h"
+-#include "netutils.h"
+-#include "vty.h"
+-#include "vty_auth.h"
+-#include "vty_cli.h"
+-#include "vty_cli_cmds.h"
+-#include "vty_utils.h"
+-
+-static int vty_max_connections = KNET_VTY_DEFAULT_MAX_CONN;
+-static int vty_current_connections = 0;
+-static int daemon_quit = 0;
+-
+-pthread_mutex_t knet_vty_mutex = PTHREAD_MUTEX_INITIALIZER;
+-int knet_vty_config = -1;
+-struct knet_vty knet_vtys[KNET_VTY_TOTAL_MAX_CONN];
+-struct knet_vty_global_conf vty_global_conf;
+-pthread_t logging_thread;
+-
+-static int _fdset_cloexec(int fd)
+-{
+-	int fdflags;
+-
+-	fdflags = fcntl(fd, F_GETFD, 0);
+-	if (fdflags < 0)
+-		return -1;
+-
+-	fdflags |= FD_CLOEXEC;
+-
+-	if (fcntl(fd, F_SETFD, fdflags) < 0)
+-		return -1;
+-
+-	return 0;
+-}
+-
+-static int _fdset_nonblock(int fd)
+-{
+-	int fdflags;
+-
+-	fdflags = fcntl(fd, F_GETFL, 0);
+-	if (fdflags < 0)
+-		return -1;
+-
+-	fdflags |= O_NONBLOCK;
+-
+-	if (fcntl(fd, F_SETFL, fdflags) < 0)
+-		return -1;
+-
+-	return 0;
+-}
+-
+-static void *_handle_logging_thread(void *data)
+-{
+-	int logfd;
+-	int se_result = 0;
+-	fd_set rfds;
+-	struct timeval tv;
+-
+-	memmove(&logfd, data, sizeof(int));
+-
+-	while (se_result >= 0 && !daemon_quit){
+-		FD_ZERO (&rfds);
+-		FD_SET (logfd, &rfds);
+-
+-		tv.tv_sec = 1;
+-		tv.tv_usec = 0;
+-
+-		se_result = select(FD_SETSIZE, &rfds, 0, 0, &tv);
+-
+-		if (se_result == -1)
+-			goto out;
+-
+-		if (se_result == 0)
+-			continue;
+-
+-		if (FD_ISSET(logfd, &rfds))  {
+-			struct knet_log_msg msg;
+-			size_t bytes_read = 0;
+-			size_t len;
+-
+-			while (bytes_read < sizeof(struct knet_log_msg)) {
+-				len = read(logfd, &msg + bytes_read,
+-					   sizeof(struct knet_log_msg) - bytes_read);
+-				if (len <= 0) {
+-					break;
+-				}
+-				bytes_read += len;
+-			}
+-
+-			if (bytes_read != sizeof(struct knet_log_msg))
+-				continue;
+-
+-			switch(msg.msglevel) {
+-				case KNET_LOG_WARN:
+-					log_warn("(%s) %s", knet_log_get_subsystem_name(msg.subsystem), msg.msg);
+-					break;
+-				case KNET_LOG_INFO:
+-					log_info("(%s) %s", knet_log_get_subsystem_name(msg.subsystem), msg.msg);
+-					break;
+-				case KNET_LOG_DEBUG:
+-					log_kdebug("(%s) %s", knet_log_get_subsystem_name(msg.subsystem), msg.msg);
+-					break;
+-				case KNET_LOG_ERR:
+-				default:
+-					log_error("(%s) %s", knet_log_get_subsystem_name(msg.subsystem), msg.msg);
+-			}
+-		}
+-	}
+-
+-out:
+-	return NULL;
+-}
+-
+-static int knet_vty_init_listener(const char *ip_addr, const char *port)
+-{
+-	int sockfd = -1, sockopt = 1;
+-	int socktype = SOCK_STREAM;
+-	int err = 0;
+-	struct sockaddr_storage ss;
+-
+-	memset(&ss, 0, sizeof(struct sockaddr_storage));
+-
+-	if (knet_strtoaddr(ip_addr, port, &ss, sizeof(struct sockaddr_storage)) != 0)
+-		return -1;
+-
+-	pthread_mutex_lock(&knet_vty_mutex);
+-
+-	/* handle sigpipe if we decide to use KEEPALIVE */
+-
+-	sockfd = socket(ss.ss_family, socktype, 0);
+-	if (sockfd < 0) {
+-		err = sockfd;
+-		goto out_clean;
+-	}
+-
+-	if (ss.ss_family == AF_INET6) {
+-		err = setsockopt(sockfd, IPPROTO_IPV6, IPV6_V6ONLY,
+-				 (void *)&sockopt, sizeof(sockopt));
+-		if (err)
+-			goto out_clean;
+-	}
+-
+-	err = setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR,
+-			 (void *)&sockopt, sizeof(sockopt));
+-	if (err)
+-		goto out_clean;
+-
+-	if (_fdset_cloexec(sockfd)) {
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	err = bind(sockfd, (struct sockaddr *)&ss, sizeof(struct sockaddr_storage));
+-	if (err)
+-		goto out_clean;
+-
+-	err = listen(sockfd, 0);
+-	if (err)
+-		goto out_clean;
+-
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-
+-	return sockfd;
+-
+-out_clean:
+-	if (sockfd >= 0)
+-		close(sockfd);
+-
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-
+-	return err;
+-}
+-
+-static void knet_vty_close_listener(int listener_fd)
+-{
+-	pthread_mutex_lock(&knet_vty_mutex);
+-
+-	if (listener_fd <= 0)
+-		goto out_clean;
+-
+-	close(listener_fd);
+-	listener_fd = 0;
+-
+-out_clean:
+-
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-
+-	return;
+-}
+-
+-static void sigterm_handler(int sig)
+-{
+-	daemon_quit = 1;
+-}
+-
+-static void sigpipe_handler(int sig)
+-{
+-	return;
+-}
+-
+-static void knet_vty_close(struct knet_vty *vty)
+-{
+-	if (knet_vty_config == vty->conn_num)
+-		knet_vty_config = -1;
+-
+-	knet_vty_free_history(vty);
+-	vty->active = 0;
+-	close(vty->vty_sock);
+-	vty_current_connections--;
+-}
+-
+-static void *vty_accept_thread(void *arg)
+-{
+-	struct knet_vty *vty = (struct knet_vty *)&knet_vtys[*(int *)arg];
+-	char addr_str[KNET_MAX_HOST_LEN];
+-	char port_str[KNET_MAX_PORT_LEN];
+-	int err;
+-
+-	knet_vty_print_banner(vty);
+-	if (vty->got_epipe)
+-		goto out_clean;
+-
+-	err = knet_addrtostr(&vty->src_sa, vty->src_sa_len,
+-			     addr_str, KNET_MAX_HOST_LEN,
+-			     port_str, KNET_MAX_PORT_LEN);
+-
+-	if (!err) {
+-		strncpy(vty->ip, addr_str, sizeof(vty->ip));
+-	} else {
+-		strcpy(vty->ip, "unknown");
+-	}
+-
+-	if ((knet_vty_auth_user(vty, NULL) < 0) && (!vty->got_epipe)) {
+-		log_info("User failed to authenticate (ip: %s)", vty->ip);
+-		goto out_clean;
+-	}
+-	if (vty->got_epipe)
+-		goto out_clean;
+-
+-	log_info("User %s connected from %s", vty->username, vty->ip);
+-	knet_vty_write(vty, "Welcome %s (%s) on vty(%d)\n\n", vty->username, vty->ip, vty->conn_num);
+-	if (vty->got_epipe)
+-		goto out_clean;
+-
+-	if (knet_vty_set_iacs(vty) < 0) {
+-		knet_vty_write(vty, "Unable to set telnet session preferences");
+-		goto out_clean;
+-	}
+-	if (vty->got_epipe)
+-		goto out_clean;
+-
+-	knet_vty_cli_bind(vty);
+-
+-out_clean:
+-	pthread_mutex_lock(&knet_vty_mutex);
+-	knet_vty_close(vty);
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-
+-	return NULL;
+-}
+-
+-/*
+- * mainloop is not thread safe as there should only be one
+- */
+-int knet_vty_main_loop(int debug)
+-{
+-	int logfd[2];
+-	int vty_listener6_fd;
+-	int vty_listener4_fd;
+-	int vty_listener_fd;
+-	int vty_accept_fd;
+-	struct sockaddr_storage incoming_sa;
+-	socklen_t salen;
+-	fd_set rfds;
+-	int se_result = 0;
+-	struct timeval tv;
+-	int err = 0;
+-	int conn_index, found;
+-
+-	signal(SIGTERM, sigterm_handler);
+-	signal(SIGINT, sigterm_handler);
+-	signal(SIGPIPE, sigpipe_handler);
+-
+-	if (pipe(logfd)) {
+-		log_error("Unable to create logging pipe");
+-		return -1;
+-	}
+-
+-	if ((_fdset_cloexec(logfd[0])) ||
+-	    (_fdset_nonblock(logfd[0])) ||
+-	    (_fdset_cloexec(logfd[1])) ||
+-	    (_fdset_nonblock(logfd[1]))) {
+-		log_error("Unable to set FD_CLOEXEX / O_NONBLOCK on logfd pipe");
+-		return -1;
+-	}
+-
+-	err = pthread_create(&logging_thread,
+-			     NULL, _handle_logging_thread,
+-			     (void *)&logfd[0]);
+-	if (err) {
+-		log_error("Unable to create logging thread");
+-		return -1;
+-	}
+-
+-	memset(&knet_vtys, 0, sizeof(knet_vtys));
+-	memset(&vty_global_conf, 0, sizeof(struct knet_vty_global_conf));
+-	vty_global_conf.idle_timeout = KNET_VTY_CLI_TIMEOUT;
+-
+-	for(conn_index = 0; conn_index < KNET_VTY_TOTAL_MAX_CONN; conn_index++) {
+-		knet_vtys[conn_index].logfd = logfd[1];
+-		knet_vtys[conn_index].vty_global_conf = &vty_global_conf;
+-		if (debug) {
+-			knet_vtys[conn_index].loglevel = KNET_LOG_DEBUG;
+-		} else {
+-			knet_vtys[conn_index].loglevel = KNET_LOG_INFO;
+-		}
+-	}
+-
+-	if (knet_read_conf() < 0) {
+-		log_error("Unable to read config file %s", knet_cfg_head.conffile);
+-		return -1;
+-	}
+-
+-	vty_listener6_fd = knet_vty_init_listener(knet_cfg_head.vty_ipv6,
+-						  knet_cfg_head.vty_port);
+-	if (vty_listener6_fd < 0) {
+-		log_error("Unable to setup vty listener for ipv6");
+-		return -1;
+-	}
+-
+-	vty_listener4_fd = knet_vty_init_listener(knet_cfg_head.vty_ipv4,
+-						  knet_cfg_head.vty_port);
+-
+-	if (vty_listener4_fd < 0) {
+-		log_error("Unable to setup vty listener for ipv4");
+-		goto out;
+-	}
+-
+-	while (se_result >= 0 && !daemon_quit) {
+-		FD_ZERO (&rfds);
+-		FD_SET (vty_listener6_fd, &rfds);
+-		FD_SET (vty_listener4_fd, &rfds);
+-
+-		tv.tv_sec = 1;
+-		tv.tv_usec = 0;
+-
+-		se_result = select(FD_SETSIZE, &rfds, 0, 0, &tv);
+-
+-		if ((se_result == -1) && (daemon_quit)) {
+-			log_info("Got a SIGTERM, requesting CLI threads to exit");	
+-			for(conn_index = 0; conn_index < KNET_VTY_TOTAL_MAX_CONN; conn_index++) {
+-				if (knet_vtys[conn_index].active) {
+-					knet_vty_write(&knet_vtys[conn_index], "%s%sServer is going down..%s%s",
+-						telnet_newline, telnet_newline, telnet_newline, telnet_newline);
+-					knet_vty_close(&knet_vtys[conn_index]);
+-					knet_vtys[conn_index].got_epipe = 1;
+-				}
+-			}
+-			sleep(2); /* give time to all vty to exit */
+-			knet_close_down();
+-			log_info("Have a nice day! Goodbye");
+-			goto out;
+-		}
+-
+-		if (se_result == -1) {
+-			err = se_result;
+-			log_error("Unable to select on vty listener socket!");
+-			goto out;
+-		}
+-
+-		if (se_result == 0) {
+-			pthread_mutex_lock(&knet_vty_mutex);
+-			for(conn_index = 0; conn_index < KNET_VTY_TOTAL_MAX_CONN; conn_index++) {
+-				if ((knet_vtys[conn_index].active) &&
+-				    (knet_vtys[conn_index].idle_timeout)) {
+-					knet_vtys[conn_index].idle++;
+-					if (knet_vtys[conn_index].idle > knet_vtys[conn_index].idle_timeout) {
+-						knet_vty_close(&knet_vtys[conn_index]);
+-						knet_vtys[conn_index].got_epipe = 1;
+-					}
+-				}
+-			}
+-			pthread_mutex_unlock(&knet_vty_mutex);
+-			continue;
+-		}
+-
+-		if (FD_ISSET(vty_listener6_fd, &rfds)) {
+-			vty_listener_fd = vty_listener6_fd;
+-		} else if (FD_ISSET(vty_listener4_fd, &rfds)) {
+-			vty_listener_fd = vty_listener4_fd;
+-		} else {
+-			continue;
+-		}
+-
+-		memset(&incoming_sa, 0, sizeof(struct sockaddr_storage));
+-		salen = sizeof(struct sockaddr_storage);
+-
+-		vty_accept_fd = accept(vty_listener_fd, (struct sockaddr *)&incoming_sa, &salen);
+-		if (vty_accept_fd < 0) {
+-			log_error("Unable to accept connection to vty");
+-			continue;
+-		}
+-
+-		// check for ip address access list here against incoming_sa
+-
+-		pthread_mutex_lock(&knet_vty_mutex);
+-
+-		found = 0;
+-		for(conn_index = 0; conn_index <= vty_max_connections; conn_index++) {
+-			if (knet_vtys[conn_index].active == 0) {
+-				found = 1;
+-				break;
+-			}
+-		}
+-
+-		if ((vty_current_connections == vty_max_connections) || (!found)) {
+-			errno = ECONNREFUSED;
+-			log_error("Too many connections to VTY or no available slots");
+-			close(vty_accept_fd);
+-			pthread_mutex_unlock(&knet_vty_mutex);
+-			continue;
+-		}
+-
+-		vty_current_connections++;
+-
+-		memset(&knet_vtys[conn_index], 0,
+-		       sizeof(struct knet_vty));
+-
+-		knet_vtys[conn_index].vty_sock = vty_accept_fd;
+-		knet_vtys[conn_index].conn_num = conn_index;
+-		memmove(&knet_vtys[conn_index].src_sa, &incoming_sa, salen);
+-		knet_vtys[conn_index].src_sa_len = salen;
+-		knet_vtys[conn_index].active = 1;
+-		knet_vtys[conn_index].logfd = logfd[1];
+-		knet_vtys[conn_index].vty_global_conf = &vty_global_conf;
+-		knet_vtys[conn_index].idle_timeout = vty_global_conf.idle_timeout;
+-		if (debug) {
+-			knet_vtys[conn_index].loglevel = KNET_LOG_DEBUG;
+-		} else {
+-			knet_vtys[conn_index].loglevel = KNET_LOG_INFO;
+-		}
+-
+-		err = pthread_create(&knet_vtys[conn_index].vty_thread,
+-				     NULL, vty_accept_thread,
+-				     (void *)&conn_index);
+-		if (err < 0) {
+-			log_error("Unable to spawn vty thread");
+-			memset(&knet_vtys[conn_index], 0,
+-			       sizeof(struct knet_vty));
+-			vty_current_connections--;
+-		}
+-
+-		pthread_mutex_unlock(&knet_vty_mutex);
+-	}
+-
+-out:
+-	pthread_cancel(logging_thread);
+-	knet_vty_close_listener(vty_listener6_fd);
+-	knet_vty_close_listener(vty_listener4_fd);
+-	close(logfd[0]);
+-	close(logfd[1]);
+-
+-	return err;
+-}
+-
+-/*
+-int knet_vty_set_max_connections(const int max_connections)
+-{
+-	int err = 0;
+-
+-	pthread_mutex_lock(&knet_vty_mutex);
+-	if ((max_connections > KNET_VTY_TOTAL_MAX_CONN) ||
+-	    (max_connections < 1)) {
+-		errno = EINVAL;
+-		err = -1;
+-	} else {
+-		vty_max_connections = max_connections;
+-	}
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-	return err;
+-}
+-*/
+diff --git a/kronosnetd/vty.h b/kronosnetd/vty.h
+deleted file mode 100644
+index 79d33cfa..00000000
+--- a/kronosnetd/vty.h
++++ /dev/null
+@@ -1,74 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_VTY_H__
+-#define __KNETD_VTY_H__
+-
+-#include <pthread.h>
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-#include "libknet.h"
+-
+-#define KNET_VTY_DEFAULT_PORT		50000
+-
+-#define KNET_VTY_DEFAULT_MAX_CONN	4
+-#define KNET_VTY_TOTAL_MAX_CONN		16
+-#define KNET_VTY_CLI_TIMEOUT		300
+-
+-#define KNET_VTY_MAX_LINE		512
+-
+-#define KNET_VTY_MAX_HIST		50
+-
+-struct knet_vty_global_conf {
+-	int	idle_timeout;
+-};
+-
+-struct knet_vty {
+-	pthread_t		vty_thread;	/* thread struct for this vty */
+-	struct sockaddr_storage	src_sa;		/* source IP */
+-	socklen_t		src_sa_len;	/* sa len */
+-	char			ip[128];	/* ip addr of source */
+-	char			username[64];	/* username */
+-	char			line[KNET_VTY_MAX_LINE]; /* input line */
+-	char			*history[KNET_VTY_MAX_HIST]; /* history */
+-	int			history_idx;	/* index to history */
+-	int			history_pos;	/* position in the history */
+-	int			insert_mode;	/* add or insert */
+-	int			line_idx;	/* index on the input line */
+-	int			cursor_pos;	/* position of the cursor in the line */
+-	int			escape;		/* escape status */
+-	int			escape_code;	/* escape code buffer */
+-	int			user_can_enable;/* user is in group kronosnetadm */
+-	int			vty_sock;	/* tcp socket for this vty */
+-	int			conn_num;	/* vty number */
+-	int			active;		/* vty is active */
+-	int			got_epipe;	/* vty_sock has been closed */
+-	int			idle;		/* idle time */
+-	int			idle_timeout;	/* in seconds or 0 to disable automatic logout */
+-	int			node;		/* node number of the menus */
+-	int			prevnode;	/* node number of the menus (used by VTY node) */
+-	void			*param;		/* pointer to cmd param */
+-	int			paramoffset;	/* required if param is set */
+-	int			logfd;		/* fd to pass to iface create */
+-	int			loglevel;	/* loglevel (debug, etc) */
+-	void			*iface;		/* pointer to iface we are working on */
+-	knet_node_id_t		host_id;	/* peer/host we are working on */
+-	uint8_t			link_id;	/* link id we are working on */
+-	int			filemode;	/* tell print_conf to add or not carriage return */
+-	struct knet_vty_global_conf *vty_global_conf; /* pointer to vty global config */
+-};
+-
+-extern pthread_mutex_t knet_vty_mutex;
+-extern int knet_vty_config;
+-
+-extern struct knet_vty knet_vtys[KNET_VTY_TOTAL_MAX_CONN];
+-
+-int knet_vty_main_loop(int debug);
+-
+-#endif
+diff --git a/kronosnetd/vty_auth.c b/kronosnetd/vty_auth.c
+deleted file mode 100644
+index d599c377..00000000
+--- a/kronosnetd/vty_auth.c
++++ /dev/null
+@@ -1,305 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <stdio.h>
+-#include <stdarg.h>
+-#include <stdlib.h>
+-#include <unistd.h>
+-#include <string.h>
+-#include <sys/types.h>
+-#include <grp.h>
+-
+-#include <security/pam_appl.h>
+-#include <security/pam_misc.h>
+-
+-#include "logging.h"
+-#include "vty_auth.h"
+-#include "vty_utils.h"
+-
+-static int knet_pam_misc_conv(int num_msg, const struct pam_message **msgm,
+-			      struct pam_response **response, void *appdata_ptr)
+-{
+-	int count = 0;
+-	struct pam_response *reply;
+-	struct knet_vty *vty = (struct knet_vty *)appdata_ptr;
+-
+-	if (num_msg <= 0)
+-		return PAM_CONV_ERR;
+-
+-	reply = (struct pam_response *) calloc(num_msg, sizeof(struct pam_response));
+-
+-	if (reply == NULL)
+-		return PAM_CONV_ERR;
+-
+-	for (count=0; count < num_msg; ++count) {
+-		unsigned char readbuf[VTY_MAX_BUFFER_SIZE];
+-		char *string=NULL;
+-		int nc;
+-
+-		memset(readbuf, 0, sizeof(readbuf));
+-
+-		switch (msgm[count]->msg_style) {
+-		case PAM_PROMPT_ECHO_OFF:
+-			if (knet_vty_set_echo(vty, 0) < 0) {
+-				knet_vty_write(vty, "Unable to turn off terminal/telnet echo");
+-				goto failed_conversation;
+-			}
+-			knet_vty_write(vty, "%s", msgm[count]->msg);
+-			nc = knet_vty_read(vty, readbuf, sizeof(readbuf));
+-			if (nc < 0)
+-				goto failed_conversation;
+-			if (knet_vty_set_echo(vty, 1) < 0) {
+-				/* doesn't really make a lot of sense tho.... */
+-				knet_vty_write(vty, "Unable to turn on terminal/telnet echo");
+-				goto failed_conversation;
+-			}
+-			knet_vty_write(vty, "\n");
+-			readbuf[nc-2] = 0;
+-			string = strdup((const char*)readbuf);
+-			if (!string)
+-				goto failed_conversation;
+-			break;
+-		case PAM_PROMPT_ECHO_ON:
+-			knet_vty_write(vty, "\n%s", msgm[count]->msg);
+-			nc = knet_vty_read(vty, readbuf, sizeof(readbuf));
+-			if (nc < 0)
+-				goto failed_conversation;
+-			readbuf[nc-2] = 0;
+-			string = strdup((const char*)readbuf);
+-			if (!string)
+-				goto failed_conversation;
+-			break;
+-		case PAM_ERROR_MSG:
+-			log_error("Received PAM error message %s", msgm[count]->msg);
+-			knet_vty_write(vty, "%s", msgm[count]->msg);
+-			break;
+-		case PAM_TEXT_INFO:
+-			log_error("Received PAM text info: %s", msgm[count]->msg);
+-			knet_vty_write(vty, "%s", msgm[count]->msg);
+-			break;
+-		default:
+-			if (!vty->got_epipe) {
+-				log_error("Unknown PAM conversation message");
+-				knet_vty_write(vty, "Unknown PAM conversation message");
+-			}
+-			goto failed_conversation;
+-		}
+-
+-		if (string) {
+-			reply[count].resp_retcode = 0;
+-			reply[count].resp = string;
+-			string = NULL;
+-		}
+-	}
+-
+-	*response = reply;
+-	reply = NULL;
+-
+-	return PAM_SUCCESS;
+-
+-failed_conversation:
+-	if (!vty->got_epipe) {
+-		log_error("PAM conversation error");
+-		knet_vty_write(vty, "PAM conversation error");
+-	}
+-	if (reply) {
+-		for (count=0; count < num_msg; ++count) {
+-			if (reply[count].resp == NULL)
+-				continue;
+-			switch (msgm[count]->msg_style) {
+-			case PAM_PROMPT_ECHO_ON:
+-			case PAM_PROMPT_ECHO_OFF:
+-				_pam_overwrite(reply[count].resp);
+-				free(reply[count].resp);
+-				break;
+-			case PAM_BINARY_PROMPT:
+-				{
+-					void *bt_ptr = reply[count].resp;
+-					pam_binary_handler_free(appdata_ptr, bt_ptr);
+-					break;
+-				}
+-			case PAM_ERROR_MSG:
+-			case PAM_TEXT_INFO:
+-				free(reply[count].resp);
+-			}
+-		}
+-		free(reply);
+-		reply = NULL;
+-	}
+-
+-	return PAM_CONV_ERR;
+-}
+-
+-static int knet_vty_get_pam_user(struct knet_vty *vty, pam_handle_t *pamh)
+-{
+-	const void *value;
+-	int err;
+-
+-	memset(vty->username, 0, sizeof(vty->username));
+-
+-	err = pam_get_item(pamh, PAM_USER, &value);
+-
+-	if (err != PAM_SUCCESS)
+-		return err;
+-
+-	strncpy(vty->username, (const char*)value, 32);
+-
+-	return 0;
+-}
+-
+-static int knet_vty_pam_auth_user(struct knet_vty *vty, const char *user)
+-{
+-	pam_handle_t *pamh=NULL;
+-	struct pam_conv conv;
+-	int err;
+-	int retry = 1;
+-
+-	conv.conv = knet_pam_misc_conv;
+-	conv.appdata_ptr = (void *)vty;
+-
+-retry_auth:
+-	err = pam_start("kronosnetd", user, &conv, &pamh);
+-	if (err != PAM_SUCCESS) {
+-		errno = EINVAL;
+-		log_error("PAM fatal error: %s", pam_strerror(pamh, err));
+-		knet_vty_write(vty, "PAM fatal error: %s",
+-				pam_strerror(pamh, err));
+-		goto out_fatal;
+-	}
+-
+-	if (pam_set_item(pamh, PAM_USER_PROMPT, (const void *)"login: ") != PAM_SUCCESS) {
+-		log_error("PAM fatal error: %s", pam_strerror(pamh, err));
+-		knet_vty_write(vty, "PAM fatal error: %s",
+-				pam_strerror(pamh, err));
+-		goto out_fatal;
+-	}
+-
+-	err = pam_authenticate(pamh, 0);
+-	if (err != PAM_SUCCESS) {
+-		if (vty->got_epipe) {
+-			errno = EPIPE;
+-			goto out_fatal;
+-		} else {
+-			errno = EINVAL;
+-			goto out_clean;
+-		}
+-	}
+-
+-	if (knet_vty_get_pam_user(vty, pamh) != PAM_SUCCESS) {
+-		log_error("PAM: unable to get PAM_USER: %s",
+-			  pam_strerror(pamh, err));
+-		knet_vty_write(vty, "PAM: unable to get PAM_USER: %s",
+-				pam_strerror(pamh, err));
+-		goto out_clean;
+-	}
+-
+-	err = pam_acct_mgmt(pamh, 0);
+-	if (err != PAM_SUCCESS) {
+-		log_info("User: %s failed to authenticate on vty(%d) attempt %d",
+-			 vty->username, vty->conn_num, retry);
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	if (pamh) {
+-		pam_end(pamh, err);
+-		pamh = NULL;
+-	}
+-
+-	if ((err != PAM_SUCCESS) && (retry < AUTH_MAX_RETRY)) {
+-		retry++;
+-		goto retry_auth;
+-	}
+-
+-out_fatal:
+-	if (pamh) {
+-		pam_end(pamh, err);
+-		pamh = NULL;
+-	}
+-
+-	knet_vty_write(vty, "\n");
+-
+-	return err;
+-}
+-
+-static int knet_vty_group_check(struct knet_vty *vty)
+-{
+-	struct group grp;
+-	char *buf;
+-	size_t buflen;
+-	long int initlen;
+-	struct group *result;
+-	char *gr_mem;
+-	int err, i;
+-
+-	errno = 0;
+-	initlen = sysconf(_SC_GETGR_R_SIZE_MAX);
+-	if ((initlen < 0) && (errno == EINVAL))
+-		return -1;
+-
+-	if (initlen < 0)
+-		initlen = 1024;
+-
+-	buflen = (size_t) initlen;
+-
+-	buf = malloc(buflen);
+-	if (!buf)
+-		return -1;
+-
+-	while ((err = getgrnam_r(DEFAULTADMGROUP, &grp, buf, buflen, &result)) == ERANGE) {
+-		size_t newlen = 2 * buflen;
+-		char *newbuf;
+-
+-		newbuf = realloc(buf, newlen);
+-		if (!newbuf) {
+-			err = -1;
+-			goto out_clean;
+-		}
+-		buf = newbuf;
+-	}
+-	if (err)
+-		goto out_clean;
+-
+-	if (result == NULL) {
+-		errno = EACCES;
+-		log_error("No " DEFAULTADMGROUP " group found on the system");
+-		knet_vty_write(vty, "No " DEFAULTADMGROUP " group found on the system\n");
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	gr_mem = *grp.gr_mem;
+-
+-	i = 0;
+-	while(gr_mem != NULL) {
+-		if (!strcmp(vty->username, gr_mem)) {
+-			vty->user_can_enable = 1;
+-			break;
+-		}
+-		gr_mem = *(grp.gr_mem + i);
+-		i++;
+-	}
+-
+-out_clean:
+-	free(buf);
+-
+-	return err;
+-}
+-
+-int knet_vty_auth_user(struct knet_vty *vty, const char *user)
+-{
+-	int err;
+-
+-	err = knet_vty_pam_auth_user(vty, user);
+-	if (err != PAM_SUCCESS)
+-		return -1;
+-
+-	return knet_vty_group_check(vty);
+-}
+diff --git a/kronosnetd/vty_auth.h b/kronosnetd/vty_auth.h
+deleted file mode 100644
+index c03c5a60..00000000
+--- a/kronosnetd/vty_auth.h
++++ /dev/null
+@@ -1,18 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_VTY_AUTH_H__
+-#define __KNETD_VTY_AUTH_H__
+-
+-#include "vty.h"
+-
+-#define AUTH_MAX_RETRY 3
+-
+-int knet_vty_auth_user(struct knet_vty *vty, const char *user);
+-
+-#endif
+diff --git a/kronosnetd/vty_cli.c b/kronosnetd/vty_cli.c
+deleted file mode 100644
+index bc971f63..00000000
+--- a/kronosnetd/vty_cli.c
++++ /dev/null
+@@ -1,531 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <errno.h>
+-#include <sys/select.h>
+-#include <unistd.h>
+-#include <stdlib.h>
+-
+-#include "logging.h"
+-#include "vty.h"
+-#include "vty_cli.h"
+-#include "vty_cli_cmds.h"
+-#include "vty_utils.h"
+-
+-/* if this code looks like quagga lib/vty.c it is because we stole it in good part */
+-
+-#define CONTROL(X)	((X) - '@')
+-#define VTY_NORMAL	0
+-#define VTY_PRE_ESCAPE	1
+-#define VTY_ESCAPE	2
+-#define VTY_EXT_ESCAPE	3
+-
+-static void knet_vty_reset_buf(struct knet_vty *vty)
+-{
+-	memset(vty->line, 0, sizeof(vty->line));
+-	vty->line_idx = 0;
+-	vty->cursor_pos = 0;
+-	vty->history_pos = vty->history_idx;
+-}
+-
+-static void knet_vty_add_to_buf(struct knet_vty *vty, unsigned char *buf, int pos)
+-{
+-	char outbuf[2];
+-	int i;
+-
+-	if (vty->cursor_pos == vty->line_idx) {
+-		vty->line[vty->line_idx] = buf[pos];
+-		vty->line_idx++;
+-		vty->cursor_pos++;
+-	} else {
+-		if (!vty->insert_mode) {
+-			memmove(&vty->line[vty->cursor_pos+1], &vty->line[vty->cursor_pos],
+-				vty->line_idx - vty->cursor_pos);
+-			vty->line_idx++;
+-		}
+-		vty->line[vty->cursor_pos] = buf[pos];
+-		vty->cursor_pos++;
+-	}
+-
+-	outbuf[0] = buf[pos];
+-	outbuf[1] = 0;
+-	knet_vty_write(vty, "%s%s", outbuf, &vty->line[vty->cursor_pos]);
+-	for (i = 0; i < (vty->line_idx - vty->cursor_pos); i++)
+-		knet_vty_write(vty, "%s", telnet_backward_char);
+-}
+-
+-static void knet_vty_forward_char(struct knet_vty *vty)
+-{
+-	char buf[2];
+-
+-	if (vty->cursor_pos < vty->line_idx) {
+-		buf[0] = vty->line[vty->cursor_pos];
+-		buf[1] = 0;
+-		knet_vty_write(vty, "%s", buf);
+-		vty->cursor_pos++;
+-	}
+-}
+-
+-static void knet_vty_backward_char(struct knet_vty *vty)
+-{
+-	if (vty->cursor_pos > 0) {
+-		knet_vty_write(vty, "%s", telnet_backward_char);
+-		vty->cursor_pos--;
+-	}
+-}
+-
+-static void knet_vty_kill_line(struct knet_vty *vty)
+-{
+-	int size, i;
+-
+-	size = vty->line_idx - vty->cursor_pos;
+-
+-	if (size == 0)
+-		return;
+-
+-	for (i = 0; i < size; i++)
+-		knet_vty_write(vty, " ");
+-
+-	for (i = 0; i < size; i++)
+-		knet_vty_write(vty, "%s", telnet_backward_char);
+-
+-	memset(&vty->line[vty->cursor_pos], 0, size);
+-	vty->line_idx = vty->cursor_pos;
+-}
+-
+-static void knet_vty_newline(struct knet_vty *vty)
+-{
+-	knet_vty_write(vty, "%s", telnet_newline);
+-	knet_vty_reset_buf(vty);
+-	knet_vty_prompt(vty);
+-}
+-
+-static void knet_vty_delete_char(struct knet_vty *vty)
+-{
+-	int size, i;
+-
+-	if (vty->line_idx == 0) {
+-		knet_vty_exit_node(vty);
+-		if (!vty->got_epipe) {
+-			knet_vty_newline(vty);
+-		}
+-		return;
+-	}
+-
+-	if (vty->line_idx == vty->cursor_pos)
+-		return;
+-
+-	size = vty->line_idx - vty->cursor_pos;
+-
+-	vty->line_idx--;
+-	memmove(&vty->line[vty->cursor_pos], &vty->line[vty->cursor_pos+1],
+-		size - 1);
+-	vty->line[vty->line_idx] = '\0';
+-
+-	knet_vty_write(vty, "%s ", &vty->line[vty->cursor_pos]);
+-	for (i = 0; i < size; i++)
+-		knet_vty_write(vty, "%s", telnet_backward_char);
+-}
+-
+-static void knet_vty_delete_backward_char(struct knet_vty *vty)
+-{
+-	if (vty->cursor_pos == 0)
+-		return;
+-
+-	knet_vty_backward_char(vty);
+-	knet_vty_delete_char(vty);
+-}
+-
+-static void knet_vty_beginning_of_line(struct knet_vty *vty)
+-{
+-	while (vty->cursor_pos != 0)
+-		knet_vty_backward_char(vty);
+-}
+-
+-static void knet_vty_end_of_line(struct knet_vty *vty)
+-{
+-	while (vty->cursor_pos != vty->line_idx)
+-		knet_vty_forward_char(vty);
+-}
+-
+-static void knet_vty_kill_line_from_beginning(struct knet_vty *vty)
+-{
+-	knet_vty_beginning_of_line(vty);
+-	knet_vty_kill_line(vty);
+-}
+-
+-static void knet_vty_backward_word(struct knet_vty *vty)
+-{
+-	while(vty->cursor_pos > 0 && vty->line[vty->cursor_pos - 1] == ' ')
+-		knet_vty_backward_char(vty);
+-
+-	while(vty->cursor_pos > 0 && vty->line[vty->cursor_pos - 1] != ' ')
+-		knet_vty_backward_char(vty);
+-}
+-
+-static void knet_vty_forward_word(struct knet_vty *vty)
+-{
+-	while(vty->cursor_pos != vty->line_idx && vty->line[vty->cursor_pos] == ' ')
+-		knet_vty_forward_char(vty);
+-
+-	while(vty->cursor_pos != vty->line_idx && vty->line[vty->cursor_pos] != ' ')
+-		knet_vty_forward_char(vty);
+-}
+-
+-static void knet_vty_backward_kill_word(struct knet_vty *vty)
+-{
+-	while(vty->cursor_pos > 0 && vty->line[vty->cursor_pos - 1] == ' ')
+-		knet_vty_delete_backward_char(vty);
+-
+-	while(vty->cursor_pos > 0 && vty->line[vty->cursor_pos - 1] != ' ')
+-		knet_vty_delete_backward_char(vty);
+-}
+-
+-static void knet_vty_forward_kill_word(struct knet_vty *vty)
+-{
+-	while(vty->cursor_pos != vty->line_idx && vty->line[vty->cursor_pos] == ' ')
+-		knet_vty_delete_char(vty);
+-
+-	while(vty->cursor_pos != vty->line_idx && vty->line[vty->cursor_pos] != ' ')
+-		knet_vty_delete_backward_char(vty);
+-}
+-
+-static void knet_vty_transpose_chars(struct knet_vty *vty)
+-{
+-	unsigned char swap[2];
+-
+-	if (vty->line_idx < 2 || vty->cursor_pos < 2)
+-		return;
+-
+-	swap[0] = vty->line[vty->cursor_pos - 1];
+-	swap[1] = vty->line[vty->cursor_pos - 2];
+-	knet_vty_delete_backward_char(vty);
+-	knet_vty_delete_backward_char(vty);
+-	knet_vty_add_to_buf(vty, swap, 0);
+-	knet_vty_add_to_buf(vty, swap, 1);
+-}
+-
+-static void knet_vty_history_add(struct knet_vty *vty)
+-{
+-	int idx;
+-
+-	if (knet_vty_is_line_empty(vty))
+-		return;
+-
+-	idx = vty->history_idx % KNET_VTY_MAX_HIST;
+-
+-	if (vty->history[idx]) {
+-		free(vty->history[idx]);
+-		vty->history[idx] = NULL;
+-	}
+-
+-	vty->history[idx] = strdup(vty->line);
+-	if (vty->history[idx] == NULL) {
+-		log_error("Not enough memory to add history lines!");
+-		knet_vty_write(vty, "Not enough memory to add history lines!");
+-	}
+-
+-	vty->history_idx++;
+-
+-	if (vty->history_idx == KNET_VTY_MAX_HIST)
+-		vty->history_idx = 0;
+-
+-	vty->history_pos = vty->history_idx;
+-}
+-
+-static void knet_vty_history_print(struct knet_vty *vty)
+-{
+-	int len;
+-
+-	knet_vty_kill_line_from_beginning(vty);
+-
+-	len = strlen(vty->history[vty->history_pos]);
+-	memmove(vty->line, vty->history[vty->history_pos], len);
+-	vty->cursor_pos = vty->line_idx = len;
+-
+-	knet_vty_write(vty, "%s", vty->line);
+-}
+-
+-static void knet_vty_history_prev(struct knet_vty *vty)
+-{
+-	int idx;
+-
+-	idx = vty->history_pos;
+-
+-	if (idx == 0) {
+-		idx = KNET_VTY_MAX_HIST - 1;
+-	} else {
+-		idx--;
+-	}
+-
+-	if (vty->history[idx] == NULL)
+-		return;
+-
+-	vty->history_pos = idx;
+-
+-	knet_vty_history_print(vty);
+-}
+-
+-static void knet_vty_history_next(struct knet_vty *vty)
+-{
+-	int idx;
+-
+-	if (vty->history_pos == vty->history_idx)
+-		return;
+-
+-	idx = vty->history_pos;
+-
+-	if (idx == (KNET_VTY_MAX_HIST - 1)) {
+-		idx = 0;
+-	} else {
+-		idx++;
+-	}
+-
+-	if (vty->history[idx] == NULL) {
+-		knet_vty_kill_line_from_beginning(vty);
+-		vty->history_pos = vty->history_idx;
+-		return;
+-	}
+-
+-	vty->history_pos = idx;
+-
+-	knet_vty_history_print(vty);
+-}
+-
+-static int knet_vty_process_buf(struct knet_vty *vty, unsigned char *buf, int buflen)
+-{
+-	int i;
+-
+-	if (vty->line_idx >= KNET_VTY_MAX_LINE)
+-		return -1;
+-
+-	for (i = 0; i < buflen; i++) {
+-		if (vty->escape == VTY_EXT_ESCAPE)  {
+-			if (buf[i] != '~')
+-				goto vty_ext_escape_out;
+-
+-			switch (vty->escape_code) {
+-				case ('1'):
+-					knet_vty_beginning_of_line(vty);
+-					break;
+-				case ('2'):
+-					if (!vty->insert_mode) {
+-						vty->insert_mode = 1;
+-					} else {
+-						vty->insert_mode = 0;
+-					}
+-					break;
+-				case ('3'):
+-					knet_vty_delete_char(vty);
+-					break;
+-				case ('4'):
+-					knet_vty_end_of_line(vty);
+-					break;
+-				case ('5'):
+-					knet_vty_history_prev(vty);
+-					break;
+-				case ('6'):
+-					knet_vty_history_next(vty);
+-					break;
+-			}
+-
+-vty_ext_escape_out:
+-			vty->escape = VTY_NORMAL;
+-			continue;
+-		}
+-
+-		if (vty->escape == VTY_ESCAPE) {
+-			switch (buf[i]) {
+-				case ('A'):
+-					knet_vty_history_prev(vty);
+-					break;
+-				case ('B'):
+-					knet_vty_history_next(vty);
+-					break;
+-				case ('C'):
+-					knet_vty_forward_char(vty);
+-					break;
+-				case ('D'):
+-					knet_vty_backward_char(vty);
+-					break;
+-				case ('H'):
+-					knet_vty_beginning_of_line(vty);
+-					break;
+-				case ('F'):
+-					knet_vty_end_of_line(vty);
+-					break;
+-				case ('1'):
+-				case ('2'):
+-				case ('3'):
+-				case ('4'):
+-				case ('5'):
+-				case ('6'):
+-					vty->escape = VTY_EXT_ESCAPE;
+-					vty->escape_code = buf[i];
+-					break;
+-				default:
+-					break;
+-			}
+-
+-			if (vty->escape == VTY_ESCAPE)
+-				vty->escape = VTY_NORMAL;
+-
+-			continue;
+-		}
+-
+-		if (vty->escape == VTY_PRE_ESCAPE) {
+-			switch (buf[i]) {
+-				case 'O':
+-				case '[':
+-					vty->escape = VTY_ESCAPE;
+-					break;
+-				case 'b':
+-					vty->escape = VTY_NORMAL;
+-					knet_vty_backward_word(vty);
+-					break;
+-				case 'f':
+-					vty->escape = VTY_NORMAL;
+-					knet_vty_forward_word(vty);
+-					break;
+-				case 'd':
+-					vty->escape = VTY_NORMAL;
+-					knet_vty_forward_kill_word(vty);
+-					break;
+-				case CONTROL('H'):
+-				case 0x7f:
+-					vty->escape = VTY_NORMAL;
+-					knet_vty_backward_kill_word(vty);
+-					break;
+-				default:
+-					break;
+-			}
+-			continue;
+-		}
+-
+-		switch (buf[i]) {
+-			case CONTROL('A'):
+-				knet_vty_beginning_of_line(vty);
+-				break;
+-			case CONTROL('B'):
+-				knet_vty_backward_char(vty);
+-				break;
+-			case CONTROL('C'):
+-				knet_vty_newline(vty);
+-				break;
+-			case CONTROL('D'):
+-				knet_vty_delete_char(vty);
+-				break;
+-			case CONTROL('E'):
+-				knet_vty_end_of_line(vty);
+-				break;
+-			case CONTROL('F'):
+-				knet_vty_forward_char(vty);
+-				break;
+-			case CONTROL('H'):
+-			case 0x7f:
+-				knet_vty_delete_backward_char(vty);
+-				break;
+-			case CONTROL('K'):
+-				knet_vty_kill_line(vty);
+-				break;
+-			case CONTROL('N'):
+-				knet_vty_history_next(vty);
+-				break;
+-			case CONTROL('P'):
+-				knet_vty_history_prev(vty);
+-				break;
+-			case CONTROL('T'):
+-				knet_vty_transpose_chars(vty);
+-				break;
+-			case CONTROL('U'):
+-				knet_vty_kill_line_from_beginning(vty);
+-				break;
+-			case CONTROL('W'):
+-				knet_vty_backward_kill_word(vty);
+-				break;
+-			case CONTROL('Z'):
+-				vty->node = NODE_CONFIG;
+-				knet_vty_exit_node(vty);
+-				knet_vty_newline(vty);
+-				break;
+-			case '\n':
+-			case '\r':
+-				knet_vty_end_of_line(vty);
+-				knet_vty_write(vty, "%s", telnet_newline);
+-				knet_vty_history_add(vty);
+-				knet_vty_execute_cmd(vty);
+-				knet_vty_reset_buf(vty);
+-				knet_vty_prompt(vty);
+-				break;
+-			case '\t':
+-				knet_vty_end_of_line(vty);
+-				knet_vty_tab_completion(vty);
+-				break;
+-			case '?':
+-				knet_vty_end_of_line(vty);
+-				knet_vty_write(vty, "%s", telnet_newline);
+-				knet_vty_help(vty);
+-				knet_vty_prompt(vty);
+-				knet_vty_write(vty, "%s", vty->line);
+-				break;
+-			case '\033':
+-				vty->escape = VTY_PRE_ESCAPE;
+-				break;
+-			default:
+-				if (buf[i] > 31 && buf[i] < 127)
+-					knet_vty_add_to_buf(vty, buf, i);
+-				break;
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-void knet_vty_cli_bind(struct knet_vty *vty)
+-{
+-	int se_result = 0;
+-	fd_set rfds;
+-	struct timeval tv;
+-	unsigned char buf[VTY_MAX_BUFFER_SIZE];
+-	int readlen;
+-
+-	knet_vty_prompt(vty);
+-
+-	while (se_result >= 0 && !vty->got_epipe) {
+-		FD_ZERO (&rfds);
+-		FD_SET (vty->vty_sock, &rfds);
+-
+-		tv.tv_sec = 1;
+-		tv.tv_usec = 0;
+-
+-		se_result = select((vty->vty_sock + 1), &rfds, 0, 0, &tv);
+-
+-		if ((se_result == -1) || (vty->got_epipe))
+-			goto out_clean;
+-
+-		if ((se_result == 0) || (!FD_ISSET(vty->vty_sock, &rfds)))
+-			continue;
+-
+-		memset(buf, 0 , sizeof(buf));
+-		readlen = knet_vty_read(vty, buf, sizeof(buf));
+-		if (readlen <= 0)
+-			goto out_clean;
+-
+-		if (knet_vty_process_buf(vty, buf, readlen) < 0) {
+-			knet_vty_write(vty, "\nError processing command: command too long\n");
+-			knet_vty_reset_buf(vty);
+-		}
+-	}
+-
+-out_clean:
+-
+-	return;
+-}
+diff --git a/kronosnetd/vty_cli.h b/kronosnetd/vty_cli.h
+deleted file mode 100644
+index fb0adecb..00000000
+--- a/kronosnetd/vty_cli.h
++++ /dev/null
+@@ -1,20 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_VTY_CLI_H__
+-#define __KNETD_VTY_CLI_H__
+-
+-#include "vty.h"
+-
+-static const char telnet_backward_char[] = { 0x08, 0x0 };
+-static const char telnet_newline[] = { '\n', '\r', 0x0 };
+-static const char file_newline[] = { '\n', 0x0 };
+-
+-void knet_vty_cli_bind(struct knet_vty *vty);
+-
+-#endif
+diff --git a/kronosnetd/vty_cli_cmds.c b/kronosnetd/vty_cli_cmds.c
+deleted file mode 100644
+index de68e99d..00000000
+--- a/kronosnetd/vty_cli_cmds.c
++++ /dev/null
+@@ -1,2188 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *          Federico Simoncelli <fsimon@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#include <unistd.h>
+-#include <limits.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-
+-#include "cfg.h"
+-#include "etherfilter.h"
+-#include "logging.h"
+-#include "libnozzle.h"
+-#include "netutils.h"
+-#include "vty.h"
+-#include "vty_cli.h"
+-#include "vty_cli_cmds.h"
+-#include "vty_utils.h"
+-
+-#define KNET_VTY_MAX_MATCHES    64
+-#define KNET_VTY_MATCH_HELP      0
+-#define KNET_VTY_MATCH_EXEC      1
+-#define KNET_VTY_MATCH_EXPAND    2
+-
+-#define CMDS_PARAM_NOMORE        0
+-#define CMDS_PARAM_KNET          1
+-#define CMDS_PARAM_IP            2
+-#define CMDS_PARAM_IP_PREFIX     3
+-#define CMDS_PARAM_IP_PORT       4
+-#define CMDS_PARAM_BOOL          5
+-#define CMDS_PARAM_INT           6
+-#define CMDS_PARAM_NODEID        7
+-#define CMDS_PARAM_NAME          8
+-#define CMDS_PARAM_MTU           9
+-#define CMDS_PARAM_CRYPTO_MODEL 10
+-#define CMDS_PARAM_CRYPTO_TYPE  11
+-#define CMDS_PARAM_HASH_TYPE    12
+-#define CMDS_PARAM_POLICY       13
+-#define CMDS_PARAM_LINK_ID      14
+-#define CMDS_PARAM_LINK_PRI     15
+-#define CMDS_PARAM_LINK_KEEPAL  16
+-#define CMDS_PARAM_LINK_HOLDTI  17
+-#define CMDS_PARAM_LINK_PONG    18
+-#define CMDS_PARAM_VTY_TIMEOUT  19
+-#define CMDS_PARAM_PMTU_FREQ    20
+-#define CMDS_PARAM_LINK_TRANSP  21
+-
+-/*
+- * CLI helper functions - menu/node stuff starts below
+- */
+-
+-
+-/*
+- * return 0 if we find a command in vty->line and cmd/len/no are set
+- * return -1 if we cannot find a command. no can be trusted. cmd/len would be empty
+- */
+-
+-static int get_command(struct knet_vty *vty, char **cmd, int *cmdlen, int *cmdoffset, int *no)
+-{
+-	int start = 0, idx;
+-
+-	for (idx = 0; idx < vty->line_idx; idx++) {
+-		if (vty->line[idx] != ' ')
+-			break;
+-	}
+-
+-	if (!strncmp(&vty->line[idx], "no ", 3)) {
+-		*no = 1;
+-		idx = idx + 3;
+-
+-		for (; idx < vty->line_idx; idx++) {
+-			if (vty->line[idx] != ' ')
+-				break;
+-		}
+-	} else {
+-		*no = 0;
+-	}
+-
+-	start = idx;
+-	if (start == vty->line_idx)
+-		return -1;
+-
+-	*cmd = &vty->line[start];
+-	*cmdoffset = start;
+-
+-	for (idx = start; idx < vty->line_idx; idx++) {
+-		if (vty->line[idx] == ' ')
+-			break;
+-	}
+-
+-	*cmdlen = idx - start;
+-
+-	return 0;
+-}
+-
+-/*
+- * still not sure why I need to count backwards...
+- */
+-static void get_n_word_from_end(struct knet_vty *vty, int n,
+-					char **word, int *wlen, int *woffset)
+-{
+-	int widx;
+-	int idx, end, start;
+-
+-	start = end = vty->line_idx;
+-
+-	for (widx = 0; widx < n; widx++) {
+-		for (idx = start - 1; idx > 0; idx--) {
+-			if (vty->line[idx] != ' ')
+-				break;
+-		}
+-		end = idx;
+-		for (idx = end; idx > 0; idx--) {
+-			if (vty->line[idx-1] == ' ')
+-				break;
+-		}
+-		start = idx;
+-	}
+-
+-	*wlen = (end - start) + 1;
+-	*word = &vty->line[start];
+-	*woffset = start;
+-}
+-
+-static int expected_params(const vty_param_t *params)
+-{
+-	int idx = 0;
+-
+-	while(params[idx].param != CMDS_PARAM_NOMORE)
+-		idx++;
+-
+-	return idx;
+-}
+-
+-static int count_words(struct knet_vty *vty,
+-			 int offset)
+-{
+-	int idx, widx = 0;
+-	int status = 0;
+-
+-	for (idx = offset; idx < vty->line_idx; idx++) {
+-		if (vty->line[idx] == ' ') {
+-			status = 0;
+-			continue;
+-		}
+-		if ((vty->line[idx] != ' ') && (!status)) {
+-			widx++;
+-			status = 1;
+-			continue;
+-		}
+-	}
+-	return widx;
+-}
+-
+-static int param_to_int(const char *param, int paramlen)
+-{
+-	char buf[KNET_VTY_MAX_LINE];
+-
+-	memset(buf, 0, sizeof(buf));
+-	memmove(buf, param, paramlen);
+-	return atoi(buf);
+-}
+-
+-static int param_to_str(char *buf, int bufsize, const char *param, int paramlen)
+-{
+-	if (bufsize < paramlen)
+-		return -1;
+-
+-	memset(buf, 0, bufsize);
+-	memmove(buf, param, paramlen);
+-	return paramlen;
+-}
+-
+-static const vty_node_cmds_t *get_cmds(struct knet_vty *vty, char **cmd, int *cmdlen, int *cmdoffset)
+-{
+-	int no;
+-	const vty_node_cmds_t *cmds =  knet_vty_nodes[vty->node].cmds;
+-
+-	get_command(vty, cmd, cmdlen, cmdoffset, &no);
+-
+-	if (no)
+-		cmds = knet_vty_nodes[vty->node].no_cmds;
+-
+-	return cmds;
+-}
+-
+-static int check_param(struct knet_vty *vty, const int paramtype, char *param, int paramlen)
+-{
+-	int err = 0;
+-	char buf[KNET_VTY_MAX_LINE];
+-	int tmp;
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-
+-	memset(buf, 0, sizeof(buf));
+-
+-	switch(paramtype) {
+-		case CMDS_PARAM_NOMORE:
+-			break;
+-		case CMDS_PARAM_KNET:
+-			if (paramlen >= IFNAMSIZ) {
+-				knet_vty_write(vty, "interface name too long%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_IP:
+-			break;
+-		case CMDS_PARAM_IP_PREFIX:
+-			break;
+-		case CMDS_PARAM_IP_PORT:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 0) || (tmp > 65279)) {
+-				knet_vty_write(vty, "port number must be a value between 0 and 65279%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_BOOL:
+-			break;
+-		case CMDS_PARAM_INT:
+-			break;
+-		case CMDS_PARAM_NODEID:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 0) || (tmp > 255)) {
+-				knet_vty_write(vty, "node id must be a value between 0 and 255%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_NAME:
+-			if (paramlen >= KNET_MAX_HOST_LEN) {
+-				knet_vty_write(vty, "name cannot exceed %d char in len%s", KNET_MAX_HOST_LEN - 1, telnet_newline);
+-			}
+-			break;
+-		case CMDS_PARAM_MTU:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 576) || (tmp > 65536)) {
+-				knet_vty_write(vty, "mtu should be a value between 576 and 65536 (note: max value depends on the media)%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_PMTU_FREQ:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 5) || (tmp > 600)) {
+-				knet_vty_write(vty, "PMTUd frequency should be a value between 5 and 600%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_CRYPTO_MODEL:
+-			param_to_str(buf, KNET_VTY_MAX_LINE, param, paramlen);
+-			if (!strncmp("none", buf, 4))
+-				break;
+-			if (!strncmp("nss", buf, 3))
+-				break;
+-			knet_vty_write(vty, "unknown encryption model: %s. Supported: none/nss%s", param, telnet_newline);
+-			err = -1;
+-			break;
+-		case CMDS_PARAM_CRYPTO_TYPE:
+-			param_to_str(buf, KNET_VTY_MAX_LINE, param, paramlen);
+-			if (!strncmp("none", buf, 4))
+-				break;
+-			if (!strncmp("aes256", buf, 6))
+-				break;
+-			if (!strncmp("aes192", buf, 6))
+-				break;
+-			if (!strncmp("aes128", buf, 6))
+-				break;
+-			if (!strncmp("3des", buf, 4))
+-				break;
+-			knet_vty_write(vty, "unknown encryption method: %s. Supported: none/aes256/aes192/aes128/3des%s", param, telnet_newline);
+-			err = -1;
+-			break;
+-		case CMDS_PARAM_HASH_TYPE:
+-			param_to_str(buf, KNET_VTY_MAX_LINE, param, paramlen);
+-			if (!strncmp("none", buf, 4))
+-				break;
+-			if (!strncmp("md5", buf, 3))
+-				break;
+-			if (!strncmp("sha1", buf, 4))
+-				break;
+-			if (!strncmp("sha256", buf, 6))
+-				break;
+-			if (!strncmp("sha384", buf, 6))
+-				break;
+-			if (!strncmp("sha512", buf, 6))
+-				break;
+-			knet_vty_write(vty, "unknown hash method: %s. Supported none/md5/sha1/sha256/sha384/sha512%s", param, telnet_newline);
+-			err = -1;
+-			break;
+-		case CMDS_PARAM_POLICY:
+-			param_to_str(buf, KNET_VTY_MAX_LINE, param, paramlen);
+-			if (!strncmp("passive", buf, 7))
+-				break;
+-			if (!strncmp("active", buf, 6))
+-				break;
+-			if (!strncmp("round-robin", buf, 11))
+-				break;
+-			knet_vty_write(vty, "unknown switching policy: %s. Supported passive/active/round-robin%s", param, telnet_newline);
+-			err = -1;
+-			break;
+-		case CMDS_PARAM_LINK_ID:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 0) || (tmp > 7)) {
+-				knet_vty_write(vty, "link id should be a value between 0 and 7%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_LINK_TRANSP:
+-			param_to_str(buf, KNET_VTY_MAX_LINE, param, paramlen);
+-			if (knet_handle_get_transport_id_by_name(knet_iface->cfg_ring.knet_h, buf) == KNET_MAX_TRANSPORTS) {
+-				knet_vty_write(vty, "link transport is invalid%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_LINK_PRI:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 0) || (tmp > 255)) {
+-				knet_vty_write(vty, "link priority should be a value between 0 and 256%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_LINK_KEEPAL:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp <= 0) || (tmp > 60000)) {
+-				knet_vty_write(vty, "link keepalive should be a value between 0 and 60000 (milliseconds). Default: 1000%s", telnet_newline);
+-				err = -1;
+-			}
+-			break; 
+-		case CMDS_PARAM_LINK_HOLDTI: 
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp <= 0) || (tmp > 60000)) {
+-				knet_vty_write(vty, "link holdtimer should be a value between 0 and 60000 (milliseconds). Default: 5000%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_LINK_PONG:
+-			tmp = param_to_int(param, paramlen);
+-			if (tmp < 1) {
+-				knet_vty_write(vty, "pong_count must be a value between 0 and 255%s", telnet_newline);
+-				err = -1;
+-			}
+-			break;
+-		case CMDS_PARAM_VTY_TIMEOUT:
+-			tmp = param_to_int(param, paramlen);
+-			if ((tmp < 0) || (tmp > 3600)) {
+-				knet_vty_write(vty, "vty logout timeout should be a value between 0 (disabled) and 3600 seconds. Default: %d%s", KNET_VTY_CLI_TIMEOUT, telnet_newline);
+-			}
+-			break;
+-		default:
+-			knet_vty_write(vty, "CLI ERROR: unknown parameter type%s", telnet_newline);
+-			err = -1;
+-			break;
+-	}
+-	return err;
+-}
+-
+-static void describe_param(struct knet_vty *vty, const int paramtype)
+-{
+-	switch(paramtype) {
+-		case CMDS_PARAM_NOMORE:
+-			knet_vty_write(vty, "no more parameters%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_KNET:
+-			knet_vty_write(vty, "KNET_IFACE_NAME - interface name (max %d chars) eg: kronosnet0%s", IFNAMSIZ, telnet_newline);
+-			break;
+-		case CMDS_PARAM_IP:
+-			knet_vty_write(vty, "IP address - ipv4 or ipv6 address to add/remove%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_IP_PREFIX:
+-			knet_vty_write(vty, "IP prefix len (eg. 24, 64)%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_IP_PORT:
+-			knet_vty_write(vty, "base port (eg: %d) %s", KNET_RING_DEFPORT, telnet_newline);
+-		case CMDS_PARAM_BOOL:
+-			break;
+-		case CMDS_PARAM_INT:
+-			break;
+-		case CMDS_PARAM_NODEID:
+-			knet_vty_write(vty, "NODEID - unique identifier for this interface in this kronos network (value between 0 and 255)%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_NAME:
+-			knet_vty_write(vty, "NAME - unique name identifier for this entity (max %d chars)%s", KNET_MAX_HOST_LEN - 1, telnet_newline);
+-			break;
+-		case CMDS_PARAM_MTU:
+-			knet_vty_write(vty, "MTU - a value between 576 and 65536 (note: max value depends on the media)%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_PMTU_FREQ:
+-			knet_vty_write(vty, "PMTUd frequency - a value in seconds between 5 and 600 (default: 5)%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_CRYPTO_MODEL:
+-			knet_vty_write(vty, "MODEL - define encryption backend: none or nss%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_CRYPTO_TYPE:
+-			knet_vty_write(vty, "CRYPTO - define packets encryption method: none or aes256%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_HASH_TYPE:
+-			knet_vty_write(vty, "HASH - define packets hashing method: none/md5/sha1/sha256/sha384/sha512%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_POLICY:
+-			knet_vty_write(vty, "POLICY - define packets switching policy: passive/active/round-robin%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_LINK_ID:
+-			knet_vty_write(vty, "LINKID - specify the link identification number (0-7)%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_LINK_TRANSP:
+-			knet_vty_write(vty, "TRANSPORT - specify the link transport protocol (UDP/SCTP/..)%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_LINK_PRI:
+-			knet_vty_write(vty, "PRIORITY - specify the link priority for passive switching (0 to 255, default is 0). The higher value is preferred over lower value%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_LINK_KEEPAL:
+-			knet_vty_write(vty, "KEEPALIVE - specify the keepalive interval for this link (0 to 60000 milliseconds, default is 1000).%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_LINK_HOLDTI:
+-			knet_vty_write(vty, "HOLDTIME - specify how much time has to pass without connection before a link is considered dead (0 to 60000 milliseconds, default is 5000).%s", telnet_newline);
+-			break;
+-		case CMDS_PARAM_VTY_TIMEOUT:
+-			knet_vty_write(vty, "VTY_TIMEOUT - specify the number of seconds before a session is automatically closed.%s", telnet_newline);
+-			break;
+-		default: /* this should never happen */
+-			knet_vty_write(vty, "CLI ERROR: unknown parameter type%s", telnet_newline);
+-			break;
+-	}
+-}
+-
+-static void print_help(struct knet_vty *vty, const vty_node_cmds_t *cmds, int idx)
+-{
+-	if ((idx < 0) || (cmds == NULL) || (cmds[idx].cmd == NULL))
+-		return;
+-
+-	if (cmds[idx].help != NULL) {
+-		knet_vty_write(vty, "%s\t%s%s",
+-			cmds[idx].cmd,
+-			cmds[idx].help,
+-			telnet_newline);
+-	} else {
+-		knet_vty_write(vty, "%s\tNo help available for this command%s",
+-			cmds[idx].cmd,
+-			telnet_newline);
+-	}
+-}
+-
+-static int get_param(struct knet_vty *vty, int wanted_paranum,
+-			      char **param, int *paramlen, int *paramoffset)
+-{
+-	int eparams, tparams;
+-	const vty_param_t *params = (const vty_param_t *)vty->param;
+-	int paramstart = vty->paramoffset;
+-
+-	eparams = expected_params(params);
+-	tparams = count_words(vty, paramstart);
+-
+-	if (tparams > eparams)
+-		return -1;
+-
+-	if (wanted_paranum == -1) {
+-		get_n_word_from_end(vty, 1, param, paramlen, paramoffset);
+-		return tparams;
+-	}
+-
+-	if (tparams < wanted_paranum)
+-		return -1;
+-
+-	get_n_word_from_end(vty, (tparams - wanted_paranum) + 1, param, paramlen, paramoffset);
+-	return tparams - wanted_paranum;
+-}
+-
+-
+-static int match_command(struct knet_vty *vty, const vty_node_cmds_t *cmds,
+-			 char *cmd, int cmdlen, int cmdoffset, int mode)
+-{
+-	int idx = 0, found = -1, paramoffset = 0, paramlen = 0, last_param = 0;
+-	char *param = NULL;
+-	int paramstart = cmdlen + cmdoffset;
+-	int matches[KNET_VTY_MAX_MATCHES];
+-
+-	memset(&matches, -1, sizeof(matches));
+-
+-	while ((cmds[idx].cmd != NULL) && (idx < KNET_VTY_MAX_MATCHES)) {
+-		if (!strncmp(cmds[idx].cmd, cmd, cmdlen)) {
+-			found++;
+-			matches[found] = idx;
+-		}
+-		idx++;
+-	}
+-
+-	if (idx >= KNET_VTY_MAX_MATCHES) {
+-		knet_vty_write(vty, "Too many matches for this command%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	if (found < 0) {
+-		knet_vty_write(vty, "There is no such command%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	switch(mode) {
+-		case KNET_VTY_MATCH_HELP:
+-			if (found == 0) {
+-				if ((cmdoffset <= vty->cursor_pos) && (vty->cursor_pos <= paramstart)) {
+-					print_help(vty, cmds, matches[0]);
+-					break;
+-				}
+-				if (cmds[matches[0]].params != NULL) {
+-					vty->param = (void *)cmds[matches[0]].params;
+-					vty->paramoffset = paramstart;
+-					last_param = get_param(vty, -1, &param, &paramlen, &paramoffset);
+-
+-					if ((paramoffset <= vty->cursor_pos) && (vty->cursor_pos <= (paramoffset + paramlen)))
+-						last_param--;
+-
+-					if (last_param >= CMDS_PARAM_NOMORE) {
+-						describe_param(vty, cmds[matches[0]].params[last_param].param);
+-						if (paramoffset > 0)
+-							check_param(vty, cmds[matches[0]].params[last_param].param, param, paramlen);
+-					}
+-					break;
+-				}
+-			}
+-			if (found >= 0) {
+-				idx = 0;
+-				while (matches[idx] >= 0) {
+-					print_help(vty, cmds, matches[idx]);
+-					idx++;
+-				}
+-			}
+-			break;
+-		case KNET_VTY_MATCH_EXEC:
+-			if (found == 0) {
+-				int exec = 0;
+-				if (cmds[matches[0]].params != NULL) {
+-					int eparams, tparams;
+-
+-					eparams = expected_params(cmds[matches[0]].params);
+-					tparams = count_words(vty, paramstart);
+-
+-					if (eparams != tparams) {
+-						exec = -1;
+-						idx = 0;
+-
+-						knet_vty_write(vty, "Parameter required for this command:%s", telnet_newline);
+-
+-						while(cmds[matches[0]].params[idx].param != CMDS_PARAM_NOMORE) {
+-							describe_param(vty, cmds[matches[0]].params[idx].param);
+-							idx++;
+-						}
+-						break;
+-					}
+-
+-					idx = 0;
+-					vty->param = (void *)cmds[matches[0]].params;
+-					vty->paramoffset = paramstart;
+-					while(cmds[matches[0]].params[idx].param != CMDS_PARAM_NOMORE) {
+-						get_param(vty, idx + 1, &param, &paramlen, &paramoffset);
+-						if (check_param(vty, cmds[matches[0]].params[idx].param,
+-								param, paramlen) < 0) {
+-							exec = -1;
+-							if (vty->filemode)
+-								return -1;
+-						}
+-
+-						idx++;
+-					}
+-				}
+-				if (!exec) {
+-					if (cmds[matches[0]].params != NULL) {
+-						vty->param = (void *)cmds[matches[0]].params;
+-						vty->paramoffset = paramstart;
+-					}
+-					if (cmds[matches[0]].func != NULL) {
+-						return cmds[matches[0]].func(vty);
+-					} else { /* this will eventually disappear */
+-						knet_vty_write(vty, "no fn associated to this command%s", telnet_newline);
+-					}
+-				}
+-			}
+-			if (found > 0) {
+-				knet_vty_write(vty, "Ambiguous command.%s", telnet_newline);
+-			}
+-			break;
+-		case KNET_VTY_MATCH_EXPAND:
+-			if (found == 0) {
+-				int cmdreallen;
+-
+-				if (vty->cursor_pos > cmdoffset+cmdlen) /* complete param? */
+-					break;
+-
+-				cmdreallen = strlen(cmds[matches[0]].cmd);
+-				memset(vty->line + cmdoffset, 0, cmdlen);
+-				memmove(vty->line + cmdoffset, cmds[matches[0]].cmd, cmdreallen);
+-				vty->line[cmdreallen + cmdoffset] = ' ';
+-				vty->line_idx = cmdreallen + cmdoffset + 1;
+-				vty->cursor_pos = cmdreallen + cmdoffset + 1;
+-			}
+-			if (found > 0) { /* add completion to string base root */
+-				int count = 0;
+-				idx = 0;
+-				while (matches[idx] >= 0) {
+-					knet_vty_write(vty, "%s\t\t", cmds[matches[idx]].cmd);
+-					idx++;
+-					count++;
+-					if (count == 4) {
+-						knet_vty_write(vty, "%s",telnet_newline);
+-						count = 0;
+-					}
+-				}
+-				knet_vty_write(vty, "%s",telnet_newline);
+-			}
+-			break;
+-		default: /* this should never really happen */
+-			log_info("Unknown match mode");
+-			break;
+-	}
+-	return found;
+-}
+-
+-/* forward declarations */
+-
+-/* common to almost all nodes */
+-static int knet_cmd_logout(struct knet_vty *vty);
+-static int knet_cmd_who(struct knet_vty *vty);
+-static int knet_cmd_exit_node(struct knet_vty *vty);
+-static int knet_cmd_help(struct knet_vty *vty);
+-
+-/* root node */
+-static int knet_cmd_config(struct knet_vty *vty);
+-
+-/* config node */
+-static int knet_cmd_interface(struct knet_vty *vty);
+-static int knet_cmd_no_interface(struct knet_vty *vty);
+-static int knet_cmd_status(struct knet_vty *vty);
+-static int knet_cmd_show_conf(struct knet_vty *vty);
+-static int knet_cmd_write_conf(struct knet_vty *vty);
+-
+-/* interface node */
+-static int knet_cmd_mtu(struct knet_vty *vty);
+-static int knet_cmd_no_mtu(struct knet_vty *vty);
+-static int knet_cmd_ip(struct knet_vty *vty);
+-static int knet_cmd_no_ip(struct knet_vty *vty);
+-static int knet_cmd_peer(struct knet_vty *vty);
+-static int knet_cmd_no_peer(struct knet_vty *vty);
+-static int knet_cmd_start(struct knet_vty *vty);
+-static int knet_cmd_stop(struct knet_vty *vty);
+-static int knet_cmd_crypto(struct knet_vty *vty);
+-static int knet_cmd_pmtufreq(struct knet_vty *vty);
+-static int knet_cmd_no_pmtufreq(struct knet_vty *vty);
+-
+-
+-/* peer node */
+-static int knet_cmd_link(struct knet_vty *vty);
+-static int knet_cmd_no_link(struct knet_vty *vty);
+-static int knet_cmd_switch_policy(struct knet_vty *vty);
+-
+-/* link node */
+-static int knet_cmd_link_pri(struct knet_vty *vty);
+-static int knet_cmd_link_pong(struct knet_vty *vty);
+-static int knet_cmd_link_timer(struct knet_vty *vty);
+-
+-/* vty node */
+-static int knet_cmd_vty(struct knet_vty *vty);
+-static int knet_cmd_vty_timeout(struct knet_vty *vty);
+-
+-/* root node description */
+-vty_node_cmds_t root_cmds[] = {
+-	{ "configure", "enter configuration mode", NULL, knet_cmd_config },
+-	{ "exit", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "help", "display basic help", NULL, knet_cmd_help },
+-	{ "logout", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "status", "display current network status", NULL, knet_cmd_status },
+-	{ "vty", "enter vty configuration mode", NULL, knet_cmd_vty },
+-	{ "who", "display users connected to CLI", NULL, knet_cmd_who },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-/* config node description */
+-vty_param_t no_int_params[] = {
+-	{ CMDS_PARAM_KNET },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t no_config_cmds[] = {
+-	{ "interface", "destroy kronosnet interface", no_int_params, knet_cmd_no_interface },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-vty_param_t int_params[] = {
+-	{ CMDS_PARAM_KNET },
+-	{ CMDS_PARAM_NODEID },
+-	{ CMDS_PARAM_IP_PORT },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t config_cmds[] = {
+-	{ "exit", "exit configuration mode", NULL, knet_cmd_exit_node },
+-	{ "interface", "configure kronosnet interface", int_params, knet_cmd_interface },
+-	{ "show", "show running config", NULL, knet_cmd_show_conf },
+-	{ "help", "display basic help", NULL, knet_cmd_help },
+-	{ "logout", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "no", "revert command", NULL, NULL },
+-	{ "status", "display current network status", NULL, knet_cmd_status },
+-	{ "vty", "enter vty configuration mode", NULL, knet_cmd_vty },
+-	{ "who", "display users connected to CLI", NULL, knet_cmd_who },
+-	{ "write", "write current config to file", NULL, knet_cmd_write_conf },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-/* interface node description */
+-
+-vty_param_t ip_params[] = {
+-	{ CMDS_PARAM_IP },
+-	{ CMDS_PARAM_IP_PREFIX },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t peer_params[] = {
+-	{ CMDS_PARAM_NAME },
+-	{ CMDS_PARAM_NODEID },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t no_interface_cmds[] = {
+-	{ "ip", "remove ip address", ip_params, knet_cmd_no_ip },
+-	{ "mtu", "revert to default MTU", NULL, knet_cmd_no_mtu },
+-	{ "pmtudfreq", "revert to default PMTUd frequency (default: 5)", NULL, knet_cmd_no_pmtufreq },
+-	{ "peer", "remove peer from this interface", peer_params, knet_cmd_no_peer },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-vty_param_t mtu_params[] = {
+-	{ CMDS_PARAM_MTU },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t pmtu_params[] = {
+-	{ CMDS_PARAM_PMTU_FREQ },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t crypto_params[] = {
+-	{ CMDS_PARAM_CRYPTO_MODEL },
+-	{ CMDS_PARAM_CRYPTO_TYPE },
+-	{ CMDS_PARAM_HASH_TYPE },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t interface_cmds[] = {
+-	{ "crypto", "enable crypto/hmac", crypto_params, knet_cmd_crypto },
+-	{ "exit", "exit configuration mode", NULL, knet_cmd_exit_node },
+-	{ "help", "display basic help", NULL, knet_cmd_help },
+-	{ "ip", "add ip address", ip_params, knet_cmd_ip },
+-	{ "logout", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "mtu", "set mtu (default: auto)", mtu_params, knet_cmd_mtu },
+-	{ "pmtudfreq", "PMTUd frequency (default: 5)", pmtu_params, knet_cmd_pmtufreq },
+-	{ "no", "revert command", NULL, NULL },
+-	{ "peer", "add peer endpoint", peer_params, knet_cmd_peer },
+-	{ "show", "show running config", NULL, knet_cmd_show_conf },
+-	{ "start", "start forwarding engine", NULL, knet_cmd_start },
+-	{ "status", "display current network status", NULL, knet_cmd_status },
+-	{ "stop", "stop forwarding engine", NULL, knet_cmd_stop },
+-	{ "who", "display users connected to CLI", NULL, knet_cmd_who },
+-	{ "write", "write current config to file", NULL, knet_cmd_write_conf },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-/* peer node description */
+-
+-vty_param_t nolink_params[] = {
+-	{ CMDS_PARAM_LINK_ID },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t link_params[] = {
+-	{ CMDS_PARAM_LINK_ID },
+-	{ CMDS_PARAM_IP },
+-	{ CMDS_PARAM_IP },
+-	{ CMDS_PARAM_LINK_TRANSP },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t switch_params[] = {
+-	{ CMDS_PARAM_POLICY },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t no_peer_cmds[] = {
+-	{ "link", "remove peer endpoint", nolink_params, knet_cmd_no_link},
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-vty_node_cmds_t peer_cmds[] = {
+-	{ "exit", "exit configuration mode", NULL, knet_cmd_exit_node },
+-	{ "help", "display basic help", NULL, knet_cmd_help },
+-	{ "link", "add peer endpoint", link_params, knet_cmd_link },
+-	{ "logout", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "no", "revert command", NULL, NULL },
+-	{ "show", "show running config", NULL, knet_cmd_show_conf },
+-	{ "status", "display current network status", NULL, knet_cmd_status },
+-	{ "switch-policy", "configure switching policy engine", switch_params, knet_cmd_switch_policy },
+-	{ "who", "display users connected to CLI", NULL, knet_cmd_who },
+-	{ "write", "write current config to file", NULL, knet_cmd_write_conf },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-/* link node description */
+-
+-vty_param_t link_pri_params[] = {
+-	{ CMDS_PARAM_LINK_PRI },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t link_timer_params[] = {
+-	{ CMDS_PARAM_LINK_KEEPAL },
+-	{ CMDS_PARAM_LINK_HOLDTI },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_param_t pong_count_params[] = {
+-	{ CMDS_PARAM_LINK_PONG },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t link_cmds[] = {
+-	{ "exit", "exit configuration mode", NULL, knet_cmd_exit_node },
+-	{ "help", "display basic help", NULL, knet_cmd_help },
+-	{ "logout", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "no", "revert command", NULL, NULL },
+-	{ "pong_count", "set number of pongs to be received before a link is considered alive", pong_count_params, knet_cmd_link_pong },
+-	{ "priority", "set priority of this link for passive switching", link_pri_params, knet_cmd_link_pri },
+-	{ "show", "show running config", NULL, knet_cmd_show_conf },
+-	{ "status", "display current network status", NULL, knet_cmd_status },
+-	{ "timers", "set link keepalive and holdtime", link_timer_params, knet_cmd_link_timer },
+-	{ "who", "display users connected to CLI", NULL, knet_cmd_who },
+-	{ "write", "write current config to file", NULL, knet_cmd_write_conf },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-vty_param_t vty_timeout_params[] = {
+-	{ CMDS_PARAM_VTY_TIMEOUT },
+-	{ CMDS_PARAM_NOMORE },
+-};
+-
+-vty_node_cmds_t vty_cmds[] = {
+-	{ "exit", "exit configuration mode", NULL, knet_cmd_exit_node },
+-	{ "help", "display basic help", NULL, knet_cmd_help },
+-	{ "logout", "exit from CLI", NULL, knet_cmd_logout },
+-	{ "show", "show running config", NULL, knet_cmd_show_conf },
+-	{ "status", "display current network status", NULL, knet_cmd_status },
+-	{ "timeout", "set number of seconds before session is automatically closed", vty_timeout_params, knet_cmd_vty_timeout },
+-	{ "who", "display users connected to CLI", NULL, knet_cmd_who },
+-	{ "write", "write current config to file", NULL, knet_cmd_write_conf },
+-	{ NULL, NULL, NULL, NULL },
+-};
+-
+-/* nodes */
+-vty_nodes_t knet_vty_nodes[] = {
+-	{ NODE_ROOT, "knet", root_cmds, NULL },
+-	{ NODE_CONFIG, "config", config_cmds, no_config_cmds },
+-	{ NODE_INTERFACE, "iface", interface_cmds, no_interface_cmds },
+-	{ NODE_PEER, "peer", peer_cmds, no_peer_cmds },
+-	{ NODE_LINK, "link", link_cmds, NULL },
+-	{ NODE_VTY, "vty", vty_cmds, NULL },
+-	{ -1, NULL, NULL, NULL },
+-};
+-
+-/* command execution */
+-
+-/* vty */
+-static int knet_cmd_vty_timeout(struct knet_vty *vty)
+-{
+-	int paramlen = 0, paramoffset = 0, timeout;
+-	char *param = NULL;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	timeout = param_to_int(param, paramlen);
+-
+-	if ((vty->filemode) || (vty->prevnode == NODE_CONFIG)) {
+-		vty->vty_global_conf->idle_timeout = timeout;
+-	}
+-	vty->idle_timeout = timeout;
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_vty(struct knet_vty *vty)
+-{
+-	vty->prevnode = vty->node;
+-	vty->node = NODE_VTY;
+-	return 0;
+-}
+-
+-/* links */
+-
+-static int knet_cmd_link_pong(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	uint8_t pong_count;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	pong_count = param_to_int(param, paramlen);
+-
+-	knet_link_set_pong_count(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, pong_count);
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_link_timer(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	time_t keepalive, holdtime;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	keepalive = param_to_int(param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	holdtime = param_to_int(param, paramlen);
+-
+-	knet_link_set_ping_timers(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, keepalive, holdtime, 2048);
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_link_pri(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	uint8_t priority;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	priority = param_to_int(param, paramlen);
+-
+-	if (knet_link_set_priority(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, priority)) {
+-		knet_vty_write(vty, "Error: unable to update link priority%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_no_link(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	struct knet_link_status status;
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	vty->link_id = param_to_int(param, paramlen);
+-
+-	knet_link_get_status(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, &status, sizeof(status));
+-
+-	if (status.enabled) {
+-		if (knet_link_set_enable(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, 0)) {
+-			knet_vty_write(vty, "Error: unable to update switching cache%s", telnet_newline);
+-			return -1;
+-		}
+-		knet_link_clear_config(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id);
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_link(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	struct knet_link_status status;
+-	int paramlen = 0, paramoffset = 0, err = 0;
+-	char *param = NULL;
+-	char src_ipaddr[KNET_MAX_HOST_LEN], src_port[KNET_MAX_PORT_LEN], dst_ipaddr[KNET_MAX_HOST_LEN], dst_port[KNET_MAX_PORT_LEN];
+-	struct sockaddr_storage src_addr;
+-	struct sockaddr_storage dst_addr;
+-	struct sockaddr_storage *dst = NULL;
+-	char transport[10];
+-	uint8_t transport_id;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	vty->link_id = param_to_int(param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	param_to_str(src_ipaddr, KNET_MAX_HOST_LEN, param, paramlen);
+-
+-	memset(src_port, 0, sizeof(src_port));
+-	snprintf(src_port, KNET_MAX_PORT_LEN, "%d", knet_iface->cfg_ring.base_port + vty->host_id);
+-
+-	get_param(vty, 3, &param, &paramlen, &paramoffset);
+-	param_to_str(dst_ipaddr, KNET_MAX_HOST_LEN, param, paramlen);
+-
+-	memset(dst_port, 0, sizeof(dst_port));
+-	snprintf(dst_port, KNET_MAX_PORT_LEN, "%d", knet_iface->cfg_ring.base_port + knet_iface->cfg_eth.node_id);
+-
+-	get_param(vty, 4, &param, &paramlen, &paramoffset);
+-	param_to_str(transport, sizeof(transport), param, paramlen);
+-
+-	transport_id = knet_handle_get_transport_id_by_name(knet_iface->cfg_ring.knet_h, transport);
+-
+-	knet_link_get_status(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, &status, sizeof(status));
+-	if (!status.enabled) {
+-		if (knet_strtoaddr(src_ipaddr, src_port, &src_addr, sizeof(struct sockaddr_storage)) != 0) {
+-			knet_vty_write(vty, "Error: unable to convert source ip addr to sockaddr!%s", telnet_newline);
+-			err = -1;
+-			goto out_clean;
+-		}
+-
+-		if (!strncmp(dst_ipaddr, "dynamic", 7)) {
+-			dst = NULL;
+-		} else {
+-			if (knet_strtoaddr(dst_ipaddr, dst_port, &dst_addr, sizeof(struct sockaddr_storage)) != 0) {
+-				knet_vty_write(vty, "Error: unable to convert destination ip addr to sockaddr!%s", telnet_newline);
+-				err = -1;
+-				goto out_clean;
+-			}
+-			dst = &dst_addr;
+-		}
+-
+-		knet_link_set_config(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, transport_id, &src_addr, dst, KNET_LINK_FLAG_TRAFFICHIPRIO);
+-
+-		knet_link_set_ping_timers(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, 1000, 5000, 2048);
+-
+-		knet_link_set_enable(knet_iface->cfg_ring.knet_h, vty->host_id, vty->link_id, 1);
+-	}
+-
+-	vty->node = NODE_LINK;
+-
+-out_clean:
+-	return err;
+-}
+-
+-static int knet_cmd_switch_policy(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0, err = 0;
+-	char *param = NULL;
+-	char policystr[16];
+-	int policy = -1;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(policystr, sizeof(policystr), param, paramlen);
+-
+-	if (!strncmp("passive", policystr, 7))
+-		policy = KNET_LINK_POLICY_PASSIVE;
+-	if (!strncmp("active", policystr, 6))
+-		policy = KNET_LINK_POLICY_ACTIVE;
+-	if (!strncmp("round-robin", policystr, 11))
+-		policy = KNET_LINK_POLICY_RR;
+-
+-	if (policy < 0) {
+-		knet_vty_write(vty, "Error: unknown switching policy method%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	err = knet_host_set_policy(knet_iface->cfg_ring.knet_h, vty->host_id, policy);
+-	if (err)
+-		knet_vty_write(vty, "Error: unable to set switching policy to %s%s", policystr, telnet_newline);
+-
+-	return err;
+-}
+-
+-/*
+- * -1 on internal error
+- *  0 host does not exist
+- *  1 host exists
+- */
+-static int knet_find_host(struct knet_vty *vty,	const char *nodename, const knet_node_id_t requested_node_id)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int have_nodeid, have_name;
+-	knet_node_id_t node_id;
+-	char name[KNET_MAX_HOST_LEN];
+-
+-	have_nodeid = knet_host_get_id_by_host_name(knet_iface->cfg_ring.knet_h, nodename, &node_id);
+-	have_name = knet_host_get_name_by_host_id(knet_iface->cfg_ring.knet_h, requested_node_id, name);
+-
+-	/*
+-	 * host does not exist without a name
+-	 */
+-	if (have_name < 0) {
+-		return 0;
+-	}
+-
+-	/*
+-	 * internal error.. get out
+-	 */
+-	if (have_nodeid < 0) {
+-		knet_vty_write(vty, "Error: unable to query libknet for nodeid info%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	if ((!have_name) && (!have_nodeid)) {
+-		if (!strcmp(name, nodename) && (node_id == requested_node_id))
+-			return 1;
+-	}
+-
+-	knet_vty_write(vty, "Error: requested nodename or id already exists in libknet%s", telnet_newline);
+-
+-	return -1;
+-}
+-
+-static int knet_cmd_no_peer(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0, requested_node_id = 0, err = 0;
+-	char *param = NULL;
+-	char nodename[KNET_MAX_HOST_LEN];
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(nodename, sizeof(nodename), param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	requested_node_id = param_to_int(param, paramlen);
+-
+-	if (requested_node_id == knet_iface->cfg_eth.node_id) {
+-		knet_vty_write(vty, "Error: remote peer id cannot be the same as local id%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	err = knet_find_host(vty, nodename, requested_node_id);
+-	if (err < 0)
+-		goto out_clean;
+-
+-	if (err != 1) {
+-		knet_vty_write(vty, "Error: peer not found in list%s", telnet_newline);
+-		goto out_clean;
+-	}
+-
+-	err = knet_host_remove(knet_iface->cfg_ring.knet_h, requested_node_id);
+-	if (err < 0) {
+-		knet_vty_write(vty, "Error: unable to remove peer from current config%s", telnet_newline);
+-		goto out_clean;
+-	}
+-
+-out_clean:
+-	return err;
+-}
+-
+-static int knet_cmd_peer(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0, requested_node_id = 0, err = 0, host = 0;
+-	char *param = NULL;
+-	char nodename[KNET_MAX_HOST_LEN];
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(nodename, sizeof(nodename), param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	requested_node_id = param_to_int(param, paramlen);
+-
+-	if (requested_node_id == knet_iface->cfg_eth.node_id) {
+-		knet_vty_write(vty, "Error: remote peer id cannot be the same as local id%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	err = knet_find_host(vty, nodename, requested_node_id);
+-	if (err < 0)
+-		goto out_clean;
+-
+-	if (err == 0) {
+-		err = knet_host_add(knet_iface->cfg_ring.knet_h, requested_node_id);
+-		if (err < 0) {
+-			knet_vty_write(vty, "Error: unable to allocate memory for host struct!%s", telnet_newline);
+-			goto out_clean;
+-		}
+-		host = 1;
+-		knet_host_set_name(knet_iface->cfg_ring.knet_h, requested_node_id, nodename);
+-		knet_host_set_policy(knet_iface->cfg_ring.knet_h, requested_node_id, KNET_LINK_POLICY_PASSIVE);
+-	}
+-
+-	vty->host_id = requested_node_id;
+-	vty->node = NODE_PEER;
+-
+-out_clean:
+-	if (err < 0) {
+-		if (host)
+-			knet_host_remove(knet_iface->cfg_ring.knet_h, requested_node_id);
+-	}
+-
+-	return err;
+-}
+-
+-static int knet_cmd_no_ip(struct knet_vty *vty)
+-{
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	char ipaddr[KNET_MAX_HOST_LEN], prefix[4];
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	char *error_string = NULL;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(ipaddr, sizeof(ipaddr), param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	param_to_str(prefix, sizeof(prefix), param, paramlen);
+-
+-	if (tap_del_ip(knet_iface->cfg_eth.tap, ipaddr, prefix, &error_string) < 0) {
+-		knet_vty_write(vty, "Error: Unable to del ip addr %s/%s on device %s%s",
+-				ipaddr, prefix, tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-		if (error_string) {
+-			knet_vty_write(vty, "(%s)%s", error_string, telnet_newline);
+-			free(error_string);
+-		}
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_ip(struct knet_vty *vty)
+-{
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	char ipaddr[512], prefix[4];
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	char *error_string = NULL;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(ipaddr, sizeof(ipaddr), param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	param_to_str(prefix, sizeof(prefix), param, paramlen);
+-
+-	if (tap_add_ip(knet_iface->cfg_eth.tap, ipaddr, prefix, &error_string) < 0) {
+-		knet_vty_write(vty, "Error: Unable to set ip addr %s/%s on device %s%s",
+-				ipaddr, prefix, tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-		if (error_string) {
+-			knet_vty_write(vty, "(%s)%s", error_string, telnet_newline);
+-			free(error_string);
+-		}
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static void knet_cmd_auto_mtu_notify(void *private_data,
+-				     unsigned int data_mtu)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)private_data;
+-
+-	/*
+-	 * 48 is the magic number! yes it is.. it's the magic number...
+-	 */
+-	knet_iface->cfg_ring.data_mtu = data_mtu - 48;
+-
+-	if (!knet_iface->cfg_eth.auto_mtu) {
+-		int mtu = 0;
+-
+-		mtu = tap_get_mtu(knet_iface->cfg_eth.tap);
+-		if (mtu < 0) {
+-			log_debug("Unable to get current MTU?");
+-		} else {
+-			if (data_mtu < (unsigned int)mtu) {
+-				log_debug("Manually configured MTU (%d) is higher than automatically detected MTU (%d)",
+-					  mtu, data_mtu);
+-			}
+-		}
+-
+-		return;
+-	}
+-
+-	if (tap_set_mtu(knet_iface->cfg_eth.tap, knet_iface->cfg_ring.data_mtu) < 0) {
+-		log_warn("Error: Unable to set requested mtu %d on device %s via mtu notify",
+-			 knet_iface->cfg_ring.data_mtu, tap_get_name(knet_iface->cfg_eth.tap));
+-	} else {
+-		log_info("Device %s new mtu: %d (via mtu notify)",
+-			 tap_get_name(knet_iface->cfg_eth.tap), knet_iface->cfg_ring.data_mtu);
+-	}
+-}
+-
+-static int knet_cmd_no_pmtufreq(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-
+-	if (knet_handle_pmtud_setfreq(knet_iface->cfg_ring.knet_h, 5) < 0) {
+-		knet_vty_write(vty, "Error: Unable to reset PMTUd frequency to 5 seconds on device %s%s",
+-				tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_pmtufreq(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0, pmtufreq = 5;
+-	char *param = NULL;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	pmtufreq = param_to_int(param, paramlen);
+-
+-	if (knet_handle_pmtud_setfreq(knet_iface->cfg_ring.knet_h, pmtufreq) < 0) {
+-		knet_vty_write(vty, "Error: Unable to set PMTUd frequency to %d seconds on device %s%s",
+-				pmtufreq, tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_no_mtu(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-
+-	/* allow automatic updates of mtu */
+-	knet_iface->cfg_eth.auto_mtu = 1;
+-
+-	if (knet_iface->cfg_ring.data_mtu > 0) {
+-		if (tap_set_mtu(knet_iface->cfg_eth.tap, knet_iface->cfg_ring.data_mtu) < 0) {
+-			knet_iface->cfg_eth.auto_mtu = 0;
+-			knet_vty_write(vty, "Error: Unable to set auto detected mtu on device %s%s",
+-					tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-			return -1;
+-		}
+-	} else {
+-		if (tap_reset_mtu(knet_iface->cfg_eth.tap) < 0) {
+-			knet_iface->cfg_eth.auto_mtu = 0;
+-			knet_vty_write(vty, "Error: Unable to reset mtu on device %s%s",
+-					tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-			return -1;
+-		}
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_mtu(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0, expected_mtu = 0;
+-	char *param = NULL;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	expected_mtu = param_to_int(param, paramlen);
+-
+-	/* disable mtu auto updates */
+-	knet_iface->cfg_eth.auto_mtu = 0;
+-
+-	if ((knet_iface->cfg_ring.data_mtu) &&
+-	    (expected_mtu > knet_iface->cfg_ring.data_mtu)) {
+-		knet_vty_write(vty, "WARNING: Manually configured MTU (%d) is higher than automatically detected MTU (%d)%s",
+-			       expected_mtu, knet_iface->cfg_ring.data_mtu, telnet_newline);
+-	}
+-
+-	if (tap_set_mtu(knet_iface->cfg_eth.tap, expected_mtu) < 0) {
+-		knet_iface->cfg_eth.auto_mtu = 1;
+-		knet_vty_write(vty, "Error: Unable to set requested mtu %d on device %s%s",
+-				expected_mtu, tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_stop(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	char *error_down = NULL, *error_postdown = NULL;
+-	int err = 0;
+-
+-	err = tap_set_down(knet_iface->cfg_eth.tap, &error_down, &error_postdown);
+-	if (err < 0) {
+-		knet_vty_write(vty, "Error: Unable to set interface %s down!%s", tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-	} else {
+-		if (knet_iface->cfg_ring.knet_h)
+-			knet_handle_setfwd(knet_iface->cfg_ring.knet_h, 0);
+-		knet_iface->active = 0;
+-	}
+-	if (error_down) {
+-		knet_vty_write(vty, "down script output:%s(%s)%s", telnet_newline, error_down, telnet_newline);
+-		free(error_down);
+-	}
+-	if (error_postdown) {
+-		knet_vty_write(vty, "post-down script output:%s(%s)%s", telnet_newline, error_postdown, telnet_newline);
+-		free(error_postdown);
+-	}
+-
+-	return err;
+-}
+-
+-static int knet_cmd_crypto(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	int paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	int err = 0;
+-	struct knet_handle_crypto_cfg knet_handle_crypto_cfg_new;
+-	int fd = -1;
+-	char keyfile[PATH_MAX];
+-	struct stat sb;
+-
+-	if (knet_iface->active) {
+-		knet_vty_write(vty, "Error: Unable to activate encryption while interface is active%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	memset(&knet_handle_crypto_cfg_new, 0, sizeof(struct knet_handle_crypto_cfg));
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(knet_handle_crypto_cfg_new.crypto_model,
+-		     sizeof(knet_handle_crypto_cfg_new.crypto_model), param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	param_to_str(knet_handle_crypto_cfg_new.crypto_cipher_type,
+-		     sizeof(knet_handle_crypto_cfg_new.crypto_cipher_type), param, paramlen);
+-
+-	get_param(vty, 3, &param, &paramlen, &paramoffset);
+-	param_to_str(knet_handle_crypto_cfg_new.crypto_hash_type,
+-		     sizeof(knet_handle_crypto_cfg_new.crypto_hash_type), param, paramlen);
+-
+-	if ((!strncmp("none", knet_handle_crypto_cfg_new.crypto_model, 4)) ||
+-	    ((!strncmp("none", knet_handle_crypto_cfg_new.crypto_cipher_type, 4)) &&
+-	     ((!strncmp("none", knet_handle_crypto_cfg_new.crypto_hash_type, 4)))))
+-		goto no_key;
+-
+-	memset(keyfile, 0, PATH_MAX);
+-	snprintf(keyfile, PATH_MAX - 1, DEFAULT_CONFIG_DIR "/cryptokeys.d/%s", tap_get_name(knet_iface->cfg_eth.tap));
+-
+-	fd = open(keyfile, O_RDONLY);
+-	if (fd < 0) {
+-		knet_vty_write(vty, "Error: Unable to open security key: %s%s", keyfile, telnet_newline);
+-		err = -1;
+-		return -1;
+-	}
+-
+-	if (fstat(fd, &sb)) {
+-		knet_vty_write(vty, "Error: Unable to verify security key: %s%s", keyfile, telnet_newline);
+-		goto key_error;
+-	}
+-
+-	if (!S_ISREG(sb.st_mode)) {
+-		knet_vty_write(vty, "Error: Key %s does not appear to be a regular file%s",
+-			       keyfile, telnet_newline);
+-		goto key_error;
+-	}
+-
+-	knet_handle_crypto_cfg_new.private_key_len = (unsigned int)sb.st_size;
+-	if ((knet_handle_crypto_cfg_new.private_key_len < KNET_MIN_KEY_LEN) ||
+-	    (knet_handle_crypto_cfg_new.private_key_len > KNET_MAX_KEY_LEN)) {
+-		knet_vty_write(vty, "Error: Key %s is %u long. Must be %d <= key_len <= %d%s",
+-			       keyfile, knet_handle_crypto_cfg_new.private_key_len,
+-			       KNET_MIN_KEY_LEN, KNET_MAX_KEY_LEN, telnet_newline);
+-		goto key_error;
+-	}
+-
+-	if (((sb.st_mode & S_IRWXU) != S_IRUSR) ||
+-	    (sb.st_mode & S_IRWXG) ||
+-	    (sb.st_mode & S_IRWXO)) {
+-		knet_vty_write(vty, "Error: Key %s does not have the correct permission (must be user read-only)%s",
+-			       keyfile, telnet_newline);
+-		goto key_error;
+-	}
+-
+-	if (read(fd,
+-		 &knet_handle_crypto_cfg_new.private_key,
+-		 knet_handle_crypto_cfg_new.private_key_len) != knet_handle_crypto_cfg_new.private_key_len) {
+-		knet_vty_write(vty, "Error: Unable to read key %s%s", keyfile, telnet_newline);
+-		goto key_error;
+-	}
+-
+-	close(fd);
+-
+-no_key:
+-	err = knet_handle_crypto(knet_iface->cfg_ring.knet_h,
+-				 &knet_handle_crypto_cfg_new);
+-
+-	if (!err) {
+-		memmove(&knet_iface->knet_handle_crypto_cfg, &knet_handle_crypto_cfg_new, sizeof(struct knet_handle_crypto_cfg));
+-	} else {
+-		knet_vty_write(vty, "Error: Unable to initialize crypto module%s", telnet_newline);
+-	}
+-
+-	return err;
+-
+-key_error:
+-	close(fd);
+-	return -1;
+-}
+-
+-static int knet_cmd_start(struct knet_vty *vty)
+-{
+-	struct knet_cfg *knet_iface = (struct knet_cfg *)vty->iface;
+-	char *error_preup = NULL, *error_up = NULL;
+-	int err = 0;
+-
+-	err = tap_set_up(knet_iface->cfg_eth.tap, &error_preup, &error_up);
+-	if (err < 0) {
+-		knet_vty_write(vty, "Error: Unable to set interface %s up!%s", tap_get_name(knet_iface->cfg_eth.tap), telnet_newline);
+-		knet_handle_setfwd(knet_iface->cfg_ring.knet_h, 0);
+-	} else {
+-		knet_handle_setfwd(knet_iface->cfg_ring.knet_h, 1);
+-		knet_iface->active = 1;
+-	}
+-	if (error_preup) {
+-		knet_vty_write(vty, "pre-up script output:%s(%s)%s", telnet_newline, error_preup, telnet_newline);
+-		free(error_preup);
+-	}
+-	if (error_up) {
+-		knet_vty_write(vty, "up script output:%s(%s)%s", telnet_newline, error_up, telnet_newline);
+-		free(error_up);
+-	}
+-
+-	return err;
+-}
+-
+-static int knet_cmd_no_interface(struct knet_vty *vty)
+-{
+-	int err = 0, paramlen = 0, paramoffset = 0;
+-	char *param = NULL;
+-	char device[IFNAMSIZ];
+-	struct knet_cfg *knet_iface = NULL;
+-	char *ip_list = NULL;
+-	int ip_list_entries = 0, offset = 0;
+-	size_t j, i;
+-	char *error_string = NULL;
+-	knet_node_id_t host_ids[KNET_MAX_HOST];
+-	uint8_t link_ids[KNET_MAX_LINK];
+-	size_t host_ids_entries = 0, link_ids_entries = 0;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(device, IFNAMSIZ, param, paramlen);
+-
+-	knet_iface = knet_get_iface(device, 0);
+-	if (!knet_iface) {
+-		knet_vty_write(vty, "Error: Unable to find requested interface%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	vty->iface = (void *)knet_iface;
+-
+-	/*
+-	 * disable PTMUd notification before shutting down the tap device
+-	 */
+-	knet_handle_enable_pmtud_notify(knet_iface->cfg_ring.knet_h, NULL, NULL);
+-
+-	tap_get_ips(knet_iface->cfg_eth.tap, &ip_list, &ip_list_entries);
+-	if ((ip_list) && (ip_list_entries > 0)) {
+-		for (i = 1; i <= (size_t)ip_list_entries; i++) {
+-			tap_del_ip(knet_iface->cfg_eth.tap,
+-					ip_list + offset,
+-					ip_list + offset + strlen(ip_list + offset) + 1, &error_string);
+-			if (error_string) {
+-				free(error_string);
+-				error_string = NULL;
+-			}
+-			offset = offset + strlen(ip_list) + 1;
+-			offset = offset + strlen(ip_list + offset) + 1;
+-		}
+-		free(ip_list);
+-		ip_list = NULL;
+-		ip_list_entries = 0;
+-	}
+-
+-	knet_host_get_host_list(knet_iface->cfg_ring.knet_h, host_ids, &host_ids_entries);
+-	for (j = 0; j < host_ids_entries; j++) {
+-		knet_link_get_link_list(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids, &link_ids_entries);
+-		for (i = 0; i < link_ids_entries; i++) {
+-			knet_link_set_enable(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], 0);
+-			knet_link_clear_config(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i]);
+-		}
+-		knet_host_remove(knet_iface->cfg_ring.knet_h, host_ids[j]);
+-	}
+-
+-	knet_cmd_stop(vty);
+-
+-	if (knet_iface->cfg_ring.knet_h) {
+-		knet_handle_free(knet_iface->cfg_ring.knet_h);
+-		knet_iface->cfg_ring.knet_h = NULL;
+-	}
+-
+-	if (knet_iface->cfg_eth.tap)
+-		tap_close(knet_iface->cfg_eth.tap);
+-
+-	if (knet_iface)
+-		knet_destroy_iface(knet_iface);
+-
+-	return err;
+-}
+-
+-static void sock_notify_fn(void *private_data, int datafd, int8_t chan, uint8_t tx_rx, int error, int errorno)
+-{
+-	struct knet_vty *vty = (struct knet_vty *)private_data;
+-
+-	knet_vty_write(vty, "Error: received sock notify, datafd: %d channel: %d direction: %u error: %d errno: %d (%s)%s",
+-			datafd, chan, tx_rx, error, errorno, strerror(errorno), telnet_newline);
+-}
+-
+-static int knet_cmd_interface(struct knet_vty *vty)
+-{
+-	int err = 0, paramlen = 0, paramoffset = 0, found = 0, requested_id, tapfd;
+-	uint16_t baseport;
+-	uint8_t *bport = (uint8_t *)&baseport;
+-	char *param = NULL;
+-	char device[IFNAMSIZ];
+-	char mac[18];
+-	struct knet_cfg *knet_iface = NULL;
+-	int8_t channel = 0;
+-
+-	get_param(vty, 1, &param, &paramlen, &paramoffset);
+-	param_to_str(device, IFNAMSIZ, param, paramlen);
+-
+-	get_param(vty, 2, &param, &paramlen, &paramoffset);
+-	requested_id = param_to_int(param, paramlen);
+-
+-	get_param(vty, 3, &param, &paramlen, &paramoffset);
+-	baseport = param_to_int(param, paramlen);
+-
+-	knet_iface = knet_get_iface(device, 1);
+-	if (!knet_iface) {
+-		knet_vty_write(vty, "Error: Unable to allocate memory for config structures%s",
+-				telnet_newline);
+-		return -1;
+-	}
+-
+-	if (knet_iface->cfg_eth.tap) {
+-		found = 1;
+-		goto tap_found;
+-	}
+-
+-	if (!knet_iface->cfg_eth.tap)
+-		knet_iface->cfg_eth.tap = tap_open(device, IFNAMSIZ, DEFAULT_CONFIG_DIR);
+-
+-	if ((!knet_iface->cfg_eth.tap) && (errno == EBUSY)) {
+-		knet_vty_write(vty, "Error: interface %s seems to exist in the system%s",
+-				device, telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (!knet_iface->cfg_eth.tap) {
+-		knet_vty_write(vty, "Error: Unable to create %s system tap device%s",
+-				device, telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-tap_found:
+-
+-	if (knet_iface->cfg_ring.knet_h)
+-		goto knet_found;
+-
+-	knet_iface->cfg_ring.base_port = baseport;
+-
+-	tapfd = tap_get_fd(knet_iface->cfg_eth.tap);
+-
+-	knet_iface->cfg_ring.knet_h = knet_handle_new(requested_id, vty->logfd, vty->loglevel);
+-	if (!knet_iface->cfg_ring.knet_h) {
+-		knet_vty_write(vty, "Error: Unable to create ring handle for device %s%s",
+-				device, telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (knet_handle_enable_sock_notify(knet_iface->cfg_ring.knet_h, &vty, sock_notify_fn)) {
+-		knet_vty_write(vty, "Error: Unable to add sock notify callback to to knet_handle %s%s",
+-				strerror(errno), telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	if (knet_handle_add_datafd(knet_iface->cfg_ring.knet_h, &tapfd, &channel) < 0) {
+-		knet_vty_write(vty, "Error: Unable to add tapfd to knet_handle %s%s",
+-				strerror(errno), telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-	knet_handle_enable_filter(knet_iface->cfg_ring.knet_h, NULL, ether_host_filter_fn);
+-
+-	if (knet_handle_enable_pmtud_notify(knet_iface->cfg_ring.knet_h,
+-					    knet_iface,
+-					    knet_cmd_auto_mtu_notify) < 0) {
+-		knet_vty_write(vty, "Error: Unable to configure auto mtu notification for device %s%s",
+-				device, telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-	knet_iface->cfg_eth.auto_mtu = 1;
+-
+-	/*
+-	 * make this configurable
+-	 */
+-	knet_handle_pmtud_setfreq(knet_iface->cfg_ring.knet_h, 5);
+-
+-knet_found:
+-	if (found) {
+-		if (requested_id == knet_iface->cfg_eth.node_id)
+-			goto out_found;
+-
+-		knet_vty_write(vty, "Error: no interface %s with nodeid %d found%s",
+-				device, requested_id, telnet_newline);
+-		goto out_clean;
+-
+-	} else {
+-		knet_iface->cfg_eth.node_id = requested_id;
+-	}
+-
+-	baseport = htons(baseport);
+-	memset(&mac, 0, sizeof(mac));
+-	snprintf(mac, sizeof(mac) - 1, "54:54:%x:%x:0:%x", bport[0], bport[1], knet_iface->cfg_eth.node_id);
+-	if (tap_set_mac(knet_iface->cfg_eth.tap, mac) < 0) {
+-		knet_vty_write(vty, "Error: Unable to set mac address %s on device %s%s",
+-				mac, device, telnet_newline); 
+-		err = -1;
+-		goto out_clean;
+-	}
+-
+-out_found:
+-
+-	vty->node = NODE_INTERFACE;
+-	vty->iface = (void *)knet_iface;
+-
+-out_clean:
+-	if (err) {
+-		if (knet_iface->cfg_ring.knet_h)
+-			knet_handle_free(knet_iface->cfg_ring.knet_h);
+-
+-		if (knet_iface->cfg_eth.tap)
+-			tap_close(knet_iface->cfg_eth.tap);
+- 
+-		knet_destroy_iface(knet_iface);
+-	}
+-	return err;
+-}
+-
+-static int knet_cmd_exit_node(struct knet_vty *vty)
+-{
+-	knet_vty_exit_node(vty);
+-	return 0;
+-}
+-
+-static int knet_cmd_status(struct knet_vty *vty)
+-{
+-	size_t i, j;
+-	struct knet_cfg *knet_iface = knet_cfg_head.knet_cfg;
+-	struct knet_link_status status;
+-	const char *nl = telnet_newline;
+-	struct timespec now;
+-	char nodename[KNET_MAX_HOST_LEN];
+-	knet_node_id_t host_ids[KNET_MAX_HOST];
+-	uint8_t link_ids[KNET_MAX_LINK];
+-	size_t host_ids_entries = 0, link_ids_entries = 0;
+-	uint8_t policy;
+-
+-	clock_gettime(CLOCK_MONOTONIC, &now);
+-
+-	knet_vty_write(vty, "Current knet status%s", nl);
+-	knet_vty_write(vty, "-------------------%s", nl);
+-
+-	while (knet_iface != NULL) {
+-		knet_vty_write(vty, "interface %s (active: %d)%s", tap_get_name(knet_iface->cfg_eth.tap), knet_iface->active, nl);
+-
+-		knet_host_get_host_list(knet_iface->cfg_ring.knet_h, host_ids, &host_ids_entries);
+-
+-		for (j = 0; j < host_ids_entries; j++) {
+-			knet_host_get_name_by_host_id(knet_iface->cfg_ring.knet_h, host_ids[j], nodename);
+-			knet_vty_write(vty, "  peer %s ", nodename);
+-
+-			knet_host_get_policy(knet_iface->cfg_ring.knet_h, host_ids[j], &policy);
+-			switch (policy) {
+-				case KNET_LINK_POLICY_PASSIVE:
+-					knet_vty_write(vty, "(passive)%s", nl);
+-					break;
+-				case KNET_LINK_POLICY_ACTIVE:
+-					knet_vty_write(vty, "(active)%s", nl);
+-					break;
+-				case KNET_LINK_POLICY_RR:
+-					knet_vty_write(vty, "(round-robin)%s", nl);
+-					break;
+-			}
+-
+-			knet_link_get_link_list(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids, &link_ids_entries);
+-			for (i = 0; i < link_ids_entries; i++) {
+-				uint8_t dynamic, transport;
+-				const char *transport_name;
+-				struct sockaddr_storage src_addr;
+-				struct sockaddr_storage dst_addr;
+-				uint64_t flags;
+-
+-				if (!knet_link_get_config(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &transport, &src_addr, &dst_addr, &dynamic, &flags)) {
+-					transport_name = knet_handle_get_transport_name_by_id(knet_iface->cfg_ring.knet_h, transport);
+-					knet_link_get_status(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &status, sizeof(status));
+-					if (status.enabled == 1) {
+-						if (dynamic) {
+-							knet_vty_write(vty, "    link %s dynamic (%s/connected: %d)%s", status.src_ipaddr, transport_name, status.connected, nl);
+-						} else {
+-							knet_vty_write(vty, "    link %s %s (%s/connected: %d)%s", status.src_ipaddr, status.dst_ipaddr, transport_name, status.connected, nl);
+-						}
+-						if (status.connected) {
+-							knet_vty_write(vty, "      average latency: %llu us%s", status.latency, nl);
+-							if ((dynamic) && (status.dynconnected)) {
+-								knet_vty_write(vty, "      source ip: %s%s", status.dst_ipaddr, nl);
+-							}
+-						} else {
+-							knet_vty_write(vty, "      last heard: ");
+-							if (status.pong_last.tv_sec) {
+-								knet_vty_write(vty, "%lu s ago%s",
+-									(long unsigned int)now.tv_sec - status.pong_last.tv_sec, nl);
+-							} else {
+-								knet_vty_write(vty, "never%s", nl);
+-							}
+-						}
+-					}
+-				}
+-			}
+-		}
+-
+-		knet_iface = knet_iface->next;
+-	}
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_print_conf(struct knet_vty *vty)
+-{
+-	size_t i, j;
+-	struct knet_cfg *knet_iface = knet_cfg_head.knet_cfg;
+-	struct knet_link_status status;
+-	const char *nl = telnet_newline;
+-	char *ip_list = NULL;
+-	int ip_list_entries = 0;
+-	knet_node_id_t host_ids[KNET_MAX_HOST];
+-	uint8_t link_ids[KNET_MAX_LINK];
+-	size_t host_ids_entries = 0, link_ids_entries = 0;
+-	char nodename[KNET_MAX_HOST_LEN];
+-	uint8_t policy;
+-	unsigned int pmtudfreq = 0;
+-
+-	if (vty->filemode)
+-		nl = file_newline;
+-
+-	knet_vty_write(vty, "configure%s", nl);
+-
+-	knet_vty_write(vty, " vty%s", nl);
+-	knet_vty_write(vty, "  timeout %d%s", vty->idle_timeout, nl);
+-	knet_vty_write(vty, "  exit%s", nl);
+-
+-	while (knet_iface != NULL) {
+-		knet_vty_write(vty, " interface %s %d %d%s", tap_get_name(knet_iface->cfg_eth.tap),
+-							     knet_iface->cfg_eth.node_id,
+-							     knet_iface->cfg_ring.base_port, nl);
+-
+-		if (!knet_iface->cfg_eth.auto_mtu)
+-			knet_vty_write(vty, "  mtu %d%s", tap_get_mtu(knet_iface->cfg_eth.tap), nl);
+-
+-		knet_handle_pmtud_getfreq(knet_iface->cfg_ring.knet_h, &pmtudfreq);
+-		if ((pmtudfreq > 0) && (pmtudfreq != 5))
+-			knet_vty_write(vty, "  pmtudfreq %u%s", pmtudfreq, nl);
+-
+-		tap_get_ips(knet_iface->cfg_eth.tap, &ip_list, &ip_list_entries);
+-		if ((ip_list) && (ip_list_entries > 0)) {
+-			char *ipaddr = NULL, *prefix = NULL, *next = ip_list;
+-			for (i = 1; i <= (size_t)ip_list_entries; i++) {
+-				ipaddr = next;
+-				prefix = ipaddr + strlen(ipaddr) + 1;
+-				next = prefix + strlen(prefix) + 1;
+-				knet_vty_write(vty, "  ip %s %s%s", ipaddr, prefix, nl);
+-			}
+-			free(ip_list);
+-			ip_list = NULL;
+-			ip_list_entries = 0;
+-		}
+-
+-		knet_vty_write(vty, "  crypto %s %s %s%s",
+-			       knet_iface->knet_handle_crypto_cfg.crypto_model,
+-			       knet_iface->knet_handle_crypto_cfg.crypto_cipher_type,
+-			       knet_iface->knet_handle_crypto_cfg.crypto_hash_type, nl);
+-
+-		knet_host_get_host_list(knet_iface->cfg_ring.knet_h, host_ids, &host_ids_entries);
+-		for (j = 0; j < host_ids_entries; j++) {
+-			knet_host_get_name_by_host_id(knet_iface->cfg_ring.knet_h, host_ids[j], nodename);
+-			knet_vty_write(vty, "  peer %s %u%s", nodename, host_ids[j], nl);
+-
+-			knet_host_get_policy(knet_iface->cfg_ring.knet_h, host_ids[j], &policy);
+-			switch (policy) {
+-				case KNET_LINK_POLICY_PASSIVE:
+-					knet_vty_write(vty, "   switch-policy passive%s", nl);
+-					break;
+-				case KNET_LINK_POLICY_ACTIVE:
+-					knet_vty_write(vty, "   switch-policy active%s", nl);
+-					break;
+-				case KNET_LINK_POLICY_RR:
+-					knet_vty_write(vty, "   switch-policy round-robin%s", nl);
+-					break;
+-			}
+-
+-			knet_link_get_link_list(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids, &link_ids_entries);
+-			for (i = 0; i < link_ids_entries; i++) {
+-				uint8_t dynamic, transport;
+-				const char *transport_name;
+-				struct sockaddr_storage src_addr;
+-				struct sockaddr_storage dst_addr;
+-				uint64_t flags;
+-
+-				if (!knet_link_get_config(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &transport, &src_addr, &dst_addr, &dynamic, &flags)) {
+-					transport_name = knet_handle_get_transport_name_by_id(knet_iface->cfg_ring.knet_h, transport);
+-					knet_link_get_status(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &status, sizeof(status));
+-					if (status.enabled == 1) {
+-						uint8_t priority, pong_count;
+-						unsigned int precision;
+-						time_t interval, timeout;
+-
+-						if (dynamic) {
+-							knet_vty_write(vty, "   link %d %s dynamic %s%s", link_ids[i], status.src_ipaddr, transport_name, nl);
+-						} else {
+-							knet_vty_write(vty, "   link %d %s %s %s%s", link_ids[i], status.src_ipaddr, status.dst_ipaddr, transport_name, nl);
+-						}
+-						knet_link_get_pong_count(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &pong_count);
+-						knet_vty_write(vty, "    pong_count %u%s", pong_count, nl);
+-						knet_link_get_ping_timers(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &interval, &timeout, &precision);
+-						knet_vty_write(vty, "    timers %llu %llu%s", (unsigned long long)interval, (unsigned long long)timeout, nl);
+-						knet_link_get_priority(knet_iface->cfg_ring.knet_h, host_ids[j], link_ids[i], &priority);
+-						knet_vty_write(vty, "    priority %u%s", priority, nl);
+-						/* print link properties */
+-						knet_vty_write(vty, "    exit%s", nl);
+-					}
+-				}
+-			}
+-			knet_vty_write(vty, "   exit%s", nl);
+-		}
+-
+-		if (knet_iface->active)
+-			knet_vty_write(vty, "  start%s", nl);
+-
+-		knet_vty_write(vty, "  exit%s", nl);
+-		knet_iface = knet_iface->next;
+-	}
+-
+-	knet_vty_write(vty, " exit%sexit%s", nl, nl);
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_show_conf(struct knet_vty *vty)
+-{
+-	return knet_cmd_print_conf(vty);
+-}
+-
+-static int knet_cmd_write_conf(struct knet_vty *vty)
+-{
+-	int fd = 1, vty_sock, err = 0, backup = 1;
+-	char tempfile[PATH_MAX];
+-
+-	memset(tempfile, 0, sizeof(tempfile));
+-
+-	snprintf(tempfile, sizeof(tempfile), "%s.sav", knet_cfg_head.conffile);
+-	err = rename(knet_cfg_head.conffile, tempfile);
+-	if ((err < 0) && (errno != ENOENT)) {
+-		knet_vty_write(vty, "Unable to create backup config file %s %s", tempfile, telnet_newline);
+-		return -1;
+-	}
+-	if ((err < 0) && (errno == ENOENT))
+-		backup = 0;
+-
+-	fd = open(knet_cfg_head.conffile,
+-		  O_RDWR | O_CREAT | O_EXCL | O_TRUNC,
+-		  S_IRUSR | S_IWUSR);
+-	if (fd < 0) {
+-		knet_vty_write(vty, "Error unable to open file%s", telnet_newline);
+-		return -1;
+-	}
+-
+-	vty_sock = vty->vty_sock;
+-	vty->vty_sock = fd;
+-	vty->filemode = 1;
+-	knet_cmd_print_conf(vty);
+-	vty->vty_sock = vty_sock;
+-	vty->filemode = 0;
+-
+-	close(fd);
+-
+-	knet_vty_write(vty, "Configuration saved to %s%s", knet_cfg_head.conffile, telnet_newline);
+-	if (backup)
+-		knet_vty_write(vty, "Old configuration file has been stored in %s%s",
+-				tempfile, telnet_newline);
+-
+-	return err;
+-}
+-
+-static int knet_cmd_config(struct knet_vty *vty)
+-{
+-	int err = 0;
+-
+-	if (!vty->user_can_enable) {
+-		knet_vty_write(vty, "Error: user %s does not have enough privileges to perform config operations%s", vty->username, telnet_newline);
+-		return -1;
+-	}
+-
+-	pthread_mutex_lock(&knet_vty_mutex);
+-	if (knet_vty_config >= 0) {
+-		knet_vty_write(vty, "Error: configuration is currently locked by user %s on vty(%d). Try again later%s", vty->username, knet_vty_config, telnet_newline);
+-		err = -1;
+-		goto out_clean;
+-	}
+-	vty->node = NODE_CONFIG;
+-	knet_vty_config = vty->conn_num;
+-out_clean:
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-	return err;
+-}
+-
+-static int knet_cmd_logout(struct knet_vty *vty)
+-{
+-	vty->got_epipe = 1;
+-	return 0;
+-}
+-
+-static int knet_cmd_who(struct knet_vty *vty)
+-{
+-	int conn_index;
+-
+-	pthread_mutex_lock(&knet_vty_mutex);
+-
+-	for(conn_index = 0; conn_index < KNET_VTY_TOTAL_MAX_CONN; conn_index++) {
+-		if (knet_vtys[conn_index].active) {
+-			knet_vty_write(vty, "User %s connected on vty(%d) from %s%s",
+-				knet_vtys[conn_index].username,
+-				knet_vtys[conn_index].conn_num,
+-				knet_vtys[conn_index].ip,
+-				telnet_newline);
+-		}
+-	}
+-
+-	pthread_mutex_unlock(&knet_vty_mutex);
+-
+-	return 0;
+-}
+-
+-static int knet_cmd_help(struct knet_vty *vty)
+-{
+-	knet_vty_write(vty, PACKAGE "d VTY provides advanced help feature.%s%s"
+-			    "When you need help, anytime at the command line please press '?'.%s%s"
+-			    "If nothing matches, the help list will be empty and you must backup%s"
+-			    " until entering a '?' shows the available options.%s",
+-			    telnet_newline, telnet_newline, telnet_newline, telnet_newline, 
+-			    telnet_newline, telnet_newline);
+-	return 0;
+-}
+-
+-/* exported API to vty_cli.c */
+-
+-int knet_vty_execute_cmd(struct knet_vty *vty)
+-{
+-	const vty_node_cmds_t *cmds = NULL;
+-	char *cmd = NULL;
+-	int cmdlen = 0;
+-	int cmdoffset = 0;
+-
+-	if (knet_vty_is_line_empty(vty))
+-		return 0;
+-
+-	cmds = get_cmds(vty, &cmd, &cmdlen, &cmdoffset);
+-
+-	/* this will eventually disappear. keep it as safeguard for now */
+-	if (cmds == NULL) {
+-		knet_vty_write(vty, "No commands associated to this node%s", telnet_newline);
+-		return 0;
+-	}
+-
+-	return match_command(vty, cmds, cmd, cmdlen, cmdoffset, KNET_VTY_MATCH_EXEC);
+-}
+-
+-void knet_close_down(void)
+-{
+-	struct knet_vty *vty = &knet_vtys[0];
+-	int err, loop = 0;
+-
+-	vty->node = NODE_CONFIG;
+-	vty->vty_sock = 1;
+-	vty->user_can_enable = 1;
+-	vty->filemode = 1;
+-	vty->got_epipe = 0;
+-
+-	while ((knet_cfg_head.knet_cfg) && (loop < 10)) {
+-		memset(vty->line, 0, sizeof(vty->line));
+-		snprintf(vty->line, sizeof(vty->line) - 1, "no interface %s", tap_get_name(knet_cfg_head.knet_cfg->cfg_eth.tap));
+-		vty->line_idx = strlen(vty->line);
+-		err = knet_vty_execute_cmd(vty);
+-		if (err != 0)  {
+-			log_error("error shutting down: %s", vty->line);
+-			break;
+-		}
+-		loop++;
+-	}
+-}
+-
+-int knet_read_conf(void)
+-{
+-	int err = 0, len = 0, line = 0;
+-	struct knet_vty *vty = &knet_vtys[0];
+-	FILE *file = NULL;
+-
+-	file = fopen(knet_cfg_head.conffile, "r");
+-
+-	if ((file == NULL) && (errno != ENOENT)) {
+-		log_error("Unable to open config file for reading %s", knet_cfg_head.conffile);
+-		return -1;
+-	}
+-
+-	if ((file == NULL) && (errno == ENOENT)) {
+-		log_info("Configuration file %s not found, starting with default empty config", knet_cfg_head.conffile);
+-		return 0;
+-	}
+-
+-	vty->vty_sock = 1;
+-	vty->user_can_enable = 1;
+-	vty->filemode = 1;
+-
+-	while(fgets(vty->line, sizeof(vty->line), file) != NULL) {
+-		line++;
+-		len = strlen(vty->line) - 1;
+-		memset(&vty->line[len], 0, 1);
+-		vty->line_idx = len;
+-		err = knet_vty_execute_cmd(vty);
+-		if (err != 0)  {
+-			log_error("line[%d]: %s", line, vty->line);
+-			break;
+-		}
+-	}
+-
+-	fclose(file);
+-
+-	memset(vty, 0, sizeof(*vty));
+-
+-	return err;
+-}
+-
+-void knet_vty_help(struct knet_vty *vty)
+-{
+-	int idx = 0;
+-	const vty_node_cmds_t *cmds = NULL;
+-	char *cmd = NULL;
+-	int cmdlen = 0;
+-	int cmdoffset = 0;
+-
+-	cmds = get_cmds(vty, &cmd, &cmdlen, &cmdoffset);
+-
+-	/* this will eventually disappear. keep it as safeguard for now */
+-	if (cmds == NULL) {
+-		knet_vty_write(vty, "No commands associated to this node%s", telnet_newline);
+-		return;
+-	}
+-
+-	if (knet_vty_is_line_empty(vty) || cmd == NULL) {
+-		while (cmds[idx].cmd != NULL) {
+-			print_help(vty, cmds, idx);
+-			idx++;
+-		}
+-		return;
+-	}
+-
+-	match_command(vty, cmds, cmd, cmdlen, cmdoffset, KNET_VTY_MATCH_HELP);
+-}
+-
+-void knet_vty_tab_completion(struct knet_vty *vty)
+-{
+-	const vty_node_cmds_t *cmds = NULL;
+-	char *cmd = NULL;
+-	int cmdlen = 0;
+-	int cmdoffset = 0;
+-
+-	if (knet_vty_is_line_empty(vty))
+-		return;
+-
+-	knet_vty_write(vty, "%s", telnet_newline);
+-
+-	cmds = get_cmds(vty, &cmd, &cmdlen, &cmdoffset);
+-
+-	/* this will eventually disappear. keep it as safeguard for now */
+-	if (cmds == NULL) {
+-		knet_vty_write(vty, "No commands associated to this node%s", telnet_newline);
+-		return;
+-	}
+-
+-	match_command(vty, cmds, cmd, cmdlen, cmdoffset, KNET_VTY_MATCH_EXPAND);
+-
+-	knet_vty_prompt(vty);
+-	knet_vty_write(vty, "%s", vty->line);
+-}
+diff --git a/kronosnetd/vty_cli_cmds.h b/kronosnetd/vty_cli_cmds.h
+deleted file mode 100644
+index 89ab0ede..00000000
+--- a/kronosnetd/vty_cli_cmds.h
++++ /dev/null
+@@ -1,50 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_VTY_CLI_CMDS_H__
+-#define __KNETD_VTY_CLI_CMDS_H__
+-
+-#include "vty.h"
+-
+-typedef struct {
+-	const int		param;
+-} vty_param_t;
+-
+-typedef struct {
+-	const char		*cmd;
+-	const char		*help;
+-	const vty_param_t	*params;
+-	int (*func) (struct knet_vty *vty);
+-} vty_node_cmds_t;
+-
+-typedef struct {
+-	const int		node_num;
+-	const char		*prompt;
+-	const vty_node_cmds_t	*cmds;
+-	const vty_node_cmds_t	*no_cmds;
+-} vty_nodes_t;
+-
+-enum vty_nodes {
+-	NODE_ROOT = 0,
+-	NODE_CONFIG,
+-	NODE_INTERFACE,
+-	NODE_PEER,
+-	NODE_LINK,
+-	NODE_VTY
+-};
+-
+-int knet_vty_execute_cmd(struct knet_vty *vty);
+-void knet_vty_help(struct knet_vty *vty);
+-void knet_vty_tab_completion(struct knet_vty *vty);
+-
+-int knet_read_conf(void);
+-void knet_close_down(void);
+-
+-extern vty_nodes_t knet_vty_nodes[];
+-
+-#endif
+diff --git a/kronosnetd/vty_utils.c b/kronosnetd/vty_utils.c
+deleted file mode 100644
+index 33b30e4a..00000000
+--- a/kronosnetd/vty_utils.c
++++ /dev/null
+@@ -1,269 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#include "config.h"
+-
+-#include <stdarg.h>
+-#include <arpa/telnet.h>
+-#include <errno.h>
+-#include <string.h>
+-#include <unistd.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <sys/types.h>
+-#include <sys/socket.h>
+-
+-#include "logging.h"
+-#include "vty_cli.h"
+-#include "vty_cli_cmds.h"
+-#include "vty_utils.h"
+-
+-static int check_vty(struct knet_vty *vty)
+-{
+-	if (!vty) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-	if (vty->got_epipe) {
+-		errno = EPIPE;
+-		return -1;
+-	}
+-	return 0;
+-}
+-
+-/*
+- * TODO: implement loopy_write here
+- * should sock be non-blocking?
+- */
+-static int knet_vty_loopy_write(struct knet_vty *vty, const char *buf, size_t bufsize)
+-{
+-	ssize_t writelen;
+-
+-	writelen = write(vty->vty_sock, buf, bufsize);
+-	if (writelen < 0)
+-		vty->got_epipe = 1;
+-
+-	return writelen;
+-}
+-
+-int knet_vty_write(struct knet_vty *vty, const char *format, ...)
+-{
+-	va_list args;
+-	int len = 0;
+-	char buf[VTY_MAX_BUFFER_SIZE];
+-
+-	if (check_vty(vty))
+-		return -1;
+-
+-	va_start (args, format);
+-	len = vsnprintf (buf, VTY_MAX_BUFFER_SIZE, format, args);
+-	va_end (args);
+-
+-	if ((len < 0) || (len > VTY_MAX_BUFFER_SIZE))
+-		return -1;
+-
+-	return knet_vty_loopy_write(vty, buf, len);
+-}
+-
+-static int knet_vty_read_real(struct knet_vty *vty, unsigned char *buf, size_t bufsize,
+-			      int ignore_iac)
+-{
+-	ssize_t readlen;
+-
+-iac_retry:
+-	readlen = recv(vty->vty_sock, buf, bufsize, 0);
+-	if (readlen == 0) {
+-		vty->got_epipe = 1;
+-		goto out_clean;
+-	}
+-	if (readlen < 0)
+-		goto out_clean;
+-
+-	vty->idle = 0;
+-
+-	/* at somepoint we have to add IAC parsing */
+-	if ((buf[0] == IAC) && (ignore_iac))
+-		goto iac_retry;
+-
+-out_clean:
+-	return readlen;
+-}
+-
+-int knet_vty_read(struct knet_vty *vty, unsigned char *buf, size_t bufsize)
+-{
+-	if (check_vty(vty))
+-		return -1;
+-
+-	if ((!buf) || (bufsize == 0)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-	return knet_vty_read_real(vty, buf, bufsize, 1);
+-}
+-
+-static int knet_vty_set_echooff(struct knet_vty *vty)
+-{
+-	unsigned char cmdreply[VTY_MAX_BUFFER_SIZE];
+-	unsigned char cmdechooff[] = { IAC, WILL, TELOPT_ECHO, '\0' };
+-	unsigned char cmdechooffreply[] = { IAC, DO, TELOPT_ECHO, '\0' };
+-	ssize_t readlen;
+-
+-	if (knet_vty_write(vty, "%s", cmdechooff) < 0)
+-		return -1;
+-
+-	readlen = knet_vty_read_real(vty, cmdreply, VTY_MAX_BUFFER_SIZE, 0);
+-	if (readlen < 0)
+-		return readlen;
+-
+-	if (memcmp(&cmdreply, &cmdechooffreply, readlen))
+-		return -1;
+-
+-	return 0;
+-}
+-
+-static int knet_vty_set_echoon(struct knet_vty *vty)
+-{
+-	unsigned char cmdreply[VTY_MAX_BUFFER_SIZE];
+-	unsigned char cmdechoon[] = { IAC, WONT, TELOPT_ECHO, '\0' };
+-	unsigned char cmdechoonreply[] = { IAC, DONT, TELOPT_ECHO, '\0' };
+-	ssize_t readlen;
+-
+-	if (knet_vty_write(vty, "%s", cmdechoon) < 0)
+-		return -1;
+-
+-	readlen = knet_vty_read_real(vty, cmdreply, VTY_MAX_BUFFER_SIZE, 0);
+-	if (readlen < 0)
+-		return readlen;
+-
+-	if (memcmp(&cmdreply, &cmdechoonreply, readlen))
+-		return -1;
+-
+-	return 0;
+-}
+-
+-int knet_vty_set_echo(struct knet_vty *vty, int on)
+-{
+-	if (check_vty(vty))
+-		return -1;
+-
+-	if (on)
+-		return knet_vty_set_echoon(vty);
+-
+-	return knet_vty_set_echooff(vty);
+-}
+-
+-void knet_vty_print_banner(struct knet_vty *vty)
+-{
+-	if (check_vty(vty))
+-		return;
+-
+-	knet_vty_write(vty,
+-		"Welcome to " PACKAGE "d " PACKAGE_VERSION " (built " __DATE__
+-		" " __TIME__ ")\n");
+-}
+-
+-int knet_vty_set_iacs(struct knet_vty *vty)
+-{
+-	unsigned char cmdreply[VTY_MAX_BUFFER_SIZE];
+-	unsigned char cmdsga[] = { IAC, WILL, TELOPT_SGA, '\0' };
+-	unsigned char cmdsgareply[] = { IAC, DO, TELOPT_SGA, '\0' };
+-	unsigned char cmdlm[] = { IAC, DONT, TELOPT_LINEMODE, '\0' };
+-	ssize_t readlen;
+-
+-	if (check_vty(vty))
+-		return -1;
+-
+-	if (knet_vty_set_echo(vty, 0) < 0)
+-		return -1;
+-
+-	if (knet_vty_write(vty, "%s", cmdsga) < 0)
+-		return -1;
+-
+-	readlen = knet_vty_read_real(vty, cmdreply, VTY_MAX_BUFFER_SIZE, 0);
+-	if (readlen < 0)
+-		return readlen;
+-
+-	if (memcmp(&cmdreply, &cmdsgareply, readlen))
+-		return -1;
+-
+-	if (knet_vty_write(vty, "%s", cmdlm) < 0)
+-		return -1;
+-
+-	return 0;
+-}
+-
+-void knet_vty_free_history(struct knet_vty *vty)
+-{
+-	int i;
+-
+-	if (check_vty(vty))
+-		return;
+-
+-	for (i = 0; i < KNET_VTY_MAX_HIST; i++) {
+-		if (vty->history[i]) {
+-			free(vty->history[i]);
+-			vty->history[i] = NULL;
+-		}
+-	}
+-}
+-
+-void knet_vty_exit_node(struct knet_vty *vty)
+-{
+-	switch(vty->node) {
+-		case NODE_VTY:
+-			vty->node = vty->prevnode;
+-			break;
+-		case NODE_LINK:
+-			vty->node = NODE_PEER;
+-			break;
+-		case NODE_PEER:
+-			vty->node = NODE_INTERFACE;
+-			break;
+-		case NODE_INTERFACE:
+-			vty->node = NODE_CONFIG;
+-			break;
+-		case NODE_CONFIG:
+-			pthread_mutex_lock(&knet_vty_mutex);
+-			knet_vty_config = -1;
+-			pthread_mutex_unlock(&knet_vty_mutex);
+-			vty->node = NODE_ROOT;
+-			break;
+-		case NODE_ROOT:
+-			vty->got_epipe = 1;
+-			break;
+-		default:
+-			knet_vty_write(vty, "No idea where to go..%s", telnet_newline);
+-			break;
+-	}
+-}
+-
+-int knet_vty_is_line_empty(struct knet_vty *vty)
+-{
+-	int idx;
+-
+-	for (idx = 0; idx < vty->line_idx; idx++) {
+-		if (vty->line[idx] != ' ')
+-			return 0;
+-	}
+-
+-	return 1;
+-}
+-
+-void knet_vty_prompt(struct knet_vty *vty)
+-{
+-	char buf[3];
+-
+-	if (vty->user_can_enable) {
+-		buf[0] = '#';
+-	} else {
+-		buf[0] = '>';
+-	}
+-	buf[1] = ' ';
+-	buf[2] = 0;
+-	knet_vty_write(vty, "%s%s", knet_vty_nodes[vty->node].prompt, buf);
+-}
+diff --git a/kronosnetd/vty_utils.h b/kronosnetd/vty_utils.h
+deleted file mode 100644
+index 14e7370a..00000000
+--- a/kronosnetd/vty_utils.h
++++ /dev/null
+@@ -1,35 +0,0 @@
+-/*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-#ifndef __KNETD_VTY_UTILS_H__
+-#define __KNETD_VTY_UTILS_H__
+-
+-#include "vty.h"
+-
+-#define VTY_MAX_BUFFER_SIZE	4096
+-
+-int knet_vty_write(struct knet_vty *vty, const char *format, ...)
+-		   __attribute__ ((__format__ (__printf__, 2, 3)));
+-
+-int knet_vty_read(struct knet_vty *vty, unsigned char *buf, size_t bufsize);
+-
+-int knet_vty_set_echo(struct knet_vty *vty, int on);
+-
+-void knet_vty_print_banner(struct knet_vty *vty);
+-
+-int knet_vty_set_iacs(struct knet_vty *vty);
+-
+-void knet_vty_free_history(struct knet_vty *vty);
+-
+-void knet_vty_exit_node(struct knet_vty *vty);
+-
+-int knet_vty_is_line_empty(struct knet_vty *vty);
+-
+-void knet_vty_prompt(struct knet_vty *vty);
+-
+-#endif
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 636e442c..168a226d 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -460,8 +460,6 @@ int knet_send_sync(knet_handle_t knet_h,
+  *    dst_host_ids_entries in the buffer.
+  *  1 packet is broadcast/multicast and is sent all hosts.
+  *    contents of dst_host_ids and dst_host_ids_entries are ignored.
+- *  (see also kronosnetd/etherfilter.* for an example that filters based
+- *   on ether protocol)
+  *
+  * @return
+  * knet_handle_enable_filter returns
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 5223f595..9f3135f9 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -12,7 +12,6 @@ MAINTAINERCLEANFILES	= Makefile.in
+ include $(top_srcdir)/build-aux/check.mk
+ 
+ EXTRA_DIST	= \
+-		  kronosnetd.8 knet-keygen.8 \
+ 		  api-to-man-page-coverage
+ 
+ # Avoid Automake warnings about overriding these user variables.
+@@ -26,10 +25,6 @@ LDFLAGS=$(LDFLAGS_FOR_BUILD)
+ 
+ if BUILD_MAN
+ 
+-if BUILD_KRONOSNETD
+-man8_MANS	= kronosnetd.8 knet-keygen.8
+-endif
+-
+ if BUILD_DOXYXML
+ noinst_PROGRAMS	= doxyxml
+ 
+diff --git a/man/knet-keygen.8 b/man/knet-keygen.8
+deleted file mode 100644
+index 4dca73ad..00000000
+--- a/man/knet-keygen.8
++++ /dev/null
+@@ -1,28 +0,0 @@
+-.\"/*
+-.\" * Copyright (C) 2012-2020 Red Hat, Inc.
+-.\" *
+-.\" * All rights reserved.
+-.\" *
+-.\" * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-.\" *
+-.\" * This software licensed under GPL-2.0+
+-.\" */
+-.TH "KRONOSNETD" "8" "November 2012" "kronosnetd key generator." "System Administration Utilities"
+-
+-.SH "NAME"
+-knet\-keygen \- Tool to generate keys for kronosnetd.
+-
+-.SH "SYNOPSIS"
+-.B knet\-keygen
+-\fB\-o\fR <output_file> [\-s <size>]
+-
+-.SH "OPTIONS"
+-.TP
+-\fB\-o\fR
+-Output file
+-.TP
+-\fB\-s\fR
+-Key size (value between 1024 and 4096 included)
+-
+-.SH "SEE ALSO"
+-kronosnetd(8)
+diff --git a/man/kronosnetd.8 b/man/kronosnetd.8
+deleted file mode 100644
+index 58959904..00000000
+--- a/man/kronosnetd.8
++++ /dev/null
+@@ -1,51 +0,0 @@
+-.\"/*
+-.\" * Copyright (C) 2012-2020 Red Hat, Inc.
+-.\" *
+-.\" * All rights reserved.
+-.\" *
+-.\" * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-.\" *
+-.\" * This software licensed under GPL-2.0+
+-.\" */
+-.TH "KRONOSNETD" "8" "November 2012" "kronosnetd Usage:" "System Administration Utilities"
+-
+-.SH "NAME"
+-kronosnetd \- libknet management daemon
+-
+-.SH "DESCRIPTION"
+-Usage:
+-.PP
+-kronosnetd [options]
+-
+-.SH "OPTIONS"
+-
+-.TP
+-\fB\-a\fR <ipv6_addr>
+-Bind management VTY to ipv6_addr (default: localhost)
+-.TP
+-\fB\-b\fR <ipv4_addr>
+-Bind management VTY to ipv4_addr (default: localhost)
+-.TP
+-\fB\-p\fR <port>
+-Bind management VTY to port (default 50000)
+-.TP
+-\fB\-c\fR <file>
+-Use config file (default /etc/kronosnet/kronosnetd.conf)
+-.TP
+-\fB\-l\fR <file>
+-Use log file (default /var/log//kronosnetd.log)
+-.TP
+-\fB\-f\fR
+-Do not fork in background
+-.TP
+-\fB\-d\fR
+-Enable debugging output
+-.TP
+-\fB\-h\fR
+-This help
+-.TP
+-\fB\-V\fR
+-Print program version information
+-
+-.SH "SEE ALSO"
+-knet-keygen(8)
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0389-cleanup-drop-no-longer-used-poc-code.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0389-cleanup-drop-no-longer-used-poc-code.patch
new file mode 100644
index 000000000..899be732a
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0389-cleanup-drop-no-longer-used-poc-code.patch
@@ -0,0 +1,307 @@ 
+From 64c8d8a6ce00607693c2c958243b0a85df2b781e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 13 Aug 2020 09:41:20 +0200
+Subject: [PATCH] [cleanup] drop no longer used poc-code
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ Makefile.am                   |   4 -
+ configure.ac                  |   7 --
+ poc-code/Makefile.am          |  13 ---
+ poc-code/iov-hash/.gitignore  |   1 -
+ poc-code/iov-hash/Makefile.am |  22 ----
+ poc-code/iov-hash/main.c      | 188 ----------------------------------
+ 6 files changed, 235 deletions(-)
+ delete mode 100644 poc-code/Makefile.am
+ delete mode 100644 poc-code/iov-hash/.gitignore
+ delete mode 100644 poc-code/iov-hash/Makefile.am
+ delete mode 100644 poc-code/iov-hash/main.c
+
+diff --git a/Makefile.am b/Makefile.am
+index ff85e55b..418b4b34 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -33,10 +33,6 @@ if BUILD_MAN
+ SUBDIRS			+= man
+ endif
+ 
+-if BUILD_POC
+-SUBDIRS			+= poc-code
+-endif
+-
+ dist_doc_DATA		= \
+ 			  COPYING.applications \
+ 			  COPYING.libraries \
+diff --git a/configure.ac b/configure.ac
+index d3ff26dd..2ec8fd94 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -146,11 +146,6 @@ AC_ARG_ENABLE([install-tests],
+ 	[ enable_install_tests="no" ])
+ AM_CONDITIONAL([INSTALL_TESTS], [test x$enable_install_tests = xyes])
+ 
+-AC_ARG_ENABLE([poc],
+-	[AS_HELP_STRING([--enable-poc],[enable building poc code])],,
+-	[ enable_poc="no" ])
+-AM_CONDITIONAL([BUILD_POC], [test x$enable_poc = xyes])
+-
+ AC_ARG_ENABLE([runautogen],
+ 	[AS_HELP_STRING([--enable-runautogen],[run autogen.sh])],,
+ 	[ enable_runautogen="no" ])
+@@ -372,8 +367,6 @@ AC_CONFIG_FILES([
+ 		man/Makefile
+ 		man/Doxyfile-knet
+ 		man/Doxyfile-nozzle
+-		poc-code/Makefile
+-		poc-code/iov-hash/Makefile
+ 		])
+ 
+ if test "x$VERSION" = "xUNKNOWN"; then
+diff --git a/poc-code/Makefile.am b/poc-code/Makefile.am
+deleted file mode 100644
+index 6c03b49a..00000000
+--- a/poc-code/Makefile.am
++++ /dev/null
+@@ -1,13 +0,0 @@
+-#
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-MAINTAINERCLEANFILES	= Makefile.in
+-
+-include $(top_srcdir)/build-aux/check.mk
+-
+-SUBDIRS			= iov-hash
+diff --git a/poc-code/iov-hash/.gitignore b/poc-code/iov-hash/.gitignore
+deleted file mode 100644
+index 1f05f557..00000000
+--- a/poc-code/iov-hash/.gitignore
++++ /dev/null
+@@ -1 +0,0 @@
+-nss_hash
+diff --git a/poc-code/iov-hash/Makefile.am b/poc-code/iov-hash/Makefile.am
+deleted file mode 100644
+index ed76e412..00000000
+--- a/poc-code/iov-hash/Makefile.am
++++ /dev/null
+@@ -1,22 +0,0 @@
+-#
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+-#
+-# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+-#
+-# This software licensed under GPL-2.0+
+-#
+-
+-MAINTAINERCLEANFILES	= Makefile.in
+-
+-include $(top_srcdir)/build-aux/check.mk
+-
+-# override global LIBS that pulls in lots of craft we don't need here
+-LIBS			=
+-
+-noinst_PROGRAMS		= nss_hash
+-
+-nss_hash_SOURCES	= main.c
+-
+-nss_hash_CFLAGS		= $(AM_CFLAGS) $(nss_CFLAGS)
+-
+-nss_hash_LDADD		= $(nss_LIBS)
+diff --git a/poc-code/iov-hash/main.c b/poc-code/iov-hash/main.c
+deleted file mode 100644
+index b3efae34..00000000
+--- a/poc-code/iov-hash/main.c
++++ /dev/null
+@@ -1,188 +0,0 @@
+-/*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
+- *
+- * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+- *
+- * This software licensed under GPL-2.0+
+- */
+-
+-/* Example code to illustrate DES enccryption/decryption using NSS.
+- * The example skips the details of obtaining the Key & IV to use, and
+- * just uses a hardcoded Key & IV.
+- * Note: IV is only needed if Cipher Blocking Chaining (CBC) mode of encryption
+- *       is used
+- *
+- * The recommended approach is to store and transport WRAPPED (encrypted)
+- * DES Keys (IVs can be in the clear). However, it is a common (and dangerous)
+- * practice to use raw DES Keys. This example shows the use of a RAW key.
+- */
+-
+-#ifdef BUILDCRYPTONSS
+-#include <nss.h>
+-#include <pk11pub.h>
+-#include <prerror.h>
+-#include <blapit.h>
+-
+-/* example Key & IV */
+-unsigned char gKey[] = {0xe8, 0xa7, 0x7c, 0xe2, 0x05, 0x63, 0x6a, 0x31};
+-unsigned char gIV[] = {0xe4, 0xbb, 0x3b, 0xd3, 0xc3, 0x71, 0x2e, 0x58};
+-
+-int main(int argc, char **argv)
+-{
+-  CK_MECHANISM_TYPE  hashMech;
+-  PK11SlotInfo*      slot = NULL;
+-  PK11SymKey*        SymKey = NULL;
+-  SECItem            SecParam;
+-  PK11Context*       HashContext = NULL;
+-  SECItem            keyItem;
+-  SECStatus          rv, rv1, rv2;
+-  unsigned char      buf1[1024], buf2[1024];
+-  char		     data[1024];
+-  unsigned int	     i;
+-  unsigned int       tmp2_outlen;
+-
+-  /* Initialize NSS
+- *    * If your application code has already initialized NSS, you can skip it
+- *       * here.
+- *          * This code uses the simplest of the Init functions, which does not
+- *             * require a NSS database to exist
+- *                */
+-  rv = NSS_NoDB_Init(".");
+-  if (rv != SECSuccess)
+-  {
+-    fprintf(stderr, "NSS initialization failed (err %d)\n",
+-            PR_GetError());
+-    goto out;
+-  }
+-
+-  /* choose mechanism: CKM_DES_CBC_PAD, CKM_DES3_ECB, CKM_DES3_CBC..... 
+- *    * Note that some mechanisms (*_PAD) imply the padding is handled for you
+- *       * by NSS. If you choose something else, then data padding is the
+- *          * application's responsibility
+- *             */
+-  hashMech = CKM_SHA_1_HMAC;
+-  slot = PK11_GetBestSlot(hashMech, NULL);
+-  /* slot = PK11_GetInternalKeySlot(); is a simpler alternative but in
+- *    * theory, it *may not* return the optimal slot for the operation. For
+- *       * DES ops, Internal slot is typically the best slot
+- *          */
+-  if (slot == NULL)
+-  {
+-    fprintf(stderr, "Unable to find security device (err %d)\n",
+-            PR_GetError());
+-    goto out;
+-  }
+-
+-  /* NSS passes blobs around as SECItems. These contain a pointer to
+- *    * data and a length. Turn the raw key into a SECItem. */
+-  keyItem.type = siBuffer;
+-  keyItem.data = gKey;
+-  keyItem.len = sizeof(gKey);
+-
+-  /* Turn the raw key into a key object. We use PK11_OriginUnwrap
+- *    * to indicate the key was unwrapped - which is what should be done
+- *       * normally anyway - using raw keys isn't a good idea */
+-  SymKey = PK11_ImportSymKey(slot, hashMech, PK11_OriginUnwrap, CKA_SIGN,
+-                             &keyItem, NULL);
+-  if (SymKey == NULL)
+-  {
+-    fprintf(stderr, "Failure to import key into NSS (err %d)\n",
+-            PR_GetError());
+-    goto out;
+-  }
+-
+-  SecParam.type = siBuffer;
+-  SecParam.data = 0;
+-  SecParam.len = 0;
+-
+-  /* sample data we'll hash */
+-  strcpy(data, "Hash me!");
+-  fprintf(stderr, "Clear Data: %s\n", data);
+-
+-  /* ========================= START SECTION ============================= */
+-  /* If using the the same key and iv over and over, stuff before this     */
+-  /* section and after this section needs to be done only ONCE             */
+-
+-  /* Create cipher context */
+-  HashContext = PK11_CreateContextBySymKey(hashMech, CKA_SIGN,
+-                                          SymKey, &SecParam);
+-
+-  if (!HashContext) {
+-    fprintf(stderr, "no hash context today?\n");
+-    goto out;
+-  }
+-
+-  if (PK11_DigestBegin(HashContext) != SECSuccess) {
+-    fprintf(stderr, "hash doesn't begin?\n");
+-    goto out;
+-  }
+-
+-  rv1 = PK11_DigestOp(HashContext, (unsigned char *)data, strlen(data)+1);
+-
+-  rv2 = PK11_DigestFinal(HashContext, buf2, &tmp2_outlen, SHA1_BLOCK_LENGTH);
+-
+-  PK11_DestroyContext(HashContext, PR_TRUE);
+-  if (rv1 != SECSuccess || rv2 != SECSuccess)
+-    goto out;
+-
+-  fprintf(stderr, "Hash Data: ");
+-  for (i=0; i<tmp2_outlen; i++)
+-    fprintf(stderr, "%02x ", buf2[i]);
+-  fprintf(stderr, "\n");
+-
+-  /* =========================== END SECTION ============================= */
+-
+-  /* ========================= START SECTION ============================= */
+-  /* If using the the same key and iv over and over, stuff before this     */
+-  /* section and after this section needs to be done only ONCE             */
+-
+-  memset(buf1, 0, sizeof(buf1));
+-  memset(buf2, 0, sizeof(buf2));
+-
+-  /* Create cipher context */
+-  HashContext = PK11_CreateContextBySymKey(hashMech, CKA_SIGN,
+-                                          SymKey, &SecParam);
+-
+-  if (!HashContext) {
+-    fprintf(stderr, "no hash context today?\n");
+-    goto out;
+-  }
+-
+-  if (PK11_DigestBegin(HashContext) != SECSuccess) {
+-    fprintf(stderr, "hash doesn't begin?\n");
+-    goto out;
+-  }
+-
+-  rv1 = PK11_DigestOp(HashContext, (unsigned char *)data, 5);
+-  rv1 = PK11_DigestOp(HashContext, (unsigned char *)data+5, 4);
+-
+-  rv2 = PK11_DigestFinal(HashContext, buf2, &tmp2_outlen, SHA1_BLOCK_LENGTH);
+-
+-  PK11_DestroyContext(HashContext, PR_TRUE);
+-  if (rv1 != SECSuccess || rv2 != SECSuccess)
+-    goto out;
+-
+-  fprintf(stderr, "Hash Data: ");
+-  for (i=0; i<tmp2_outlen; i++)
+-    fprintf(stderr, "%02x ", buf2[i]);
+-  fprintf(stderr, "\n");
+-
+-  /* =========================== END SECTION ============================= */
+-
+- 
+-out:
+-  if (SymKey)
+-    PK11_FreeSymKey(SymKey);
+-
+- return 0;
+-
+-}
+-#else
+-#include <stdio.h>
+-
+-int main(void)
+-{
+-	printf("you need nss build for this PoC to work\n");
+-	return 0;
+-}
+-#endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0390-threads-make-sure-to-initialize-events.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0390-threads-make-sure-to-initialize-events.patch
new file mode 100644
index 000000000..7cb8cc8f1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0390-threads-make-sure-to-initialize-events.patch
@@ -0,0 +1,60 @@ 
+From 0d4740c17afdcac6c7f9e3cc85cb4940783f3fff Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 13 Aug 2020 12:44:16 +0200
+Subject: [PATCH] [threads] make sure to initialize events
+
+spotted on fedora rawhide + valgrind
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c     | 1 +
+ libknet/threads_tx.c     | 1 +
+ libknet/transport_sctp.c | 4 ++++
+ 3 files changed, 6 insertions(+)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 61e2862d..85fc9965 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -958,6 +958,7 @@ void *_handle_recv_from_links_thread(void *data)
+ 	set_thread_status(knet_h, KNET_THREAD_RX, KNET_THREAD_STARTED);
+ 
+ 	memset(&msg, 0, sizeof(msg));
++	memset(&events, 0, sizeof(events));
+ 
+ 	for (i = 0; i < PCKT_RX_BUFS; i++) {
+ 		iov_in[i].iov_base = (void *)knet_h->recv_from_links_buf[i];
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 852064c2..615c4266 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -665,6 +665,7 @@ void *_handle_send_to_links_thread(void *data)
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_TX, KNET_THREAD_STARTED);
+ 
++	memset(&events, 0, sizeof(events));
+ 	memset(&iov_in, 0, sizeof(iov_in));
+ 	iov_in.iov_base = (void *)knet_h->recv_from_sock_buf->khp_data_userdata;
+ 	iov_in.iov_len = KNET_MAX_PACKET_SIZE;
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 17e2f542..705b6ca7 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -696,6 +696,8 @@ static void *_sctp_connect_thread(void *data)
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_SCTP_CONN, KNET_THREAD_STARTED);
+ 
++	memset(&events, 0, sizeof(events));
++
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		nev = epoll_wait(handle_info->connect_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
+ 
+@@ -956,6 +958,8 @@ static void *_sctp_listen_thread(void *data)
+ 
+ 	set_thread_status(knet_h, KNET_THREAD_SCTP_LISTEN, KNET_THREAD_STARTED);
+ 
++	memset(&events, 0, sizeof(events));
++
+ 	while (!shutdown_in_progress(knet_h)) {
+ 		nev = epoll_wait(handle_info->listen_epollfd, events, KNET_EPOLL_MAX_EVENTS, KNET_THREADS_TIMERES / 1000);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0391-rx-fix-per-link-stats-for-data-packets.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0391-rx-fix-per-link-stats-for-data-packets.patch
new file mode 100644
index 000000000..cc7be90a9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0391-rx-fix-per-link-stats-for-data-packets.patch
@@ -0,0 +1,208 @@ 
+From 99cd9d826dd69976f26d632550fc3285a7184099 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 19 Aug 2020 07:54:54 +0200
+Subject: [PATCH] [rx] fix per link stats for data packets
+
+and cleanup all netutils common functions
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links_acl_ip.c | 10 +-------
+ libknet/netutils.c     | 53 ++++--------------------------------------
+ libknet/netutils.h     | 14 +++++++++--
+ libknet/threads_rx.c   | 33 +++++++++++++++-----------
+ 4 files changed, 37 insertions(+), 73 deletions(-)
+
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 0f269ef1..0f9c0f7e 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -16,6 +16,7 @@
+ #include <stdlib.h>
+ 
+ #include "internals.h"
++#include "netutils.h"
+ #include "logging.h"
+ #include "transports.h"
+ #include "links_acl.h"
+@@ -29,15 +30,6 @@ struct ip_acl_match_entry {
+ 	struct ip_acl_match_entry *next;
+ };
+ 
+-/*
+- * s6_addr32 is not defined in BSD userland, only kernel.
+- * definition is the same as linux and it works fine for
+- * what we need.
+- */
+-#ifndef s6_addr32
+-#define s6_addr32 __u6_addr.__u6_addr32
+-#endif
+-
+ /*
+  * IPv4 See if the address we have matches the current match entry
+  */
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index 754e1984..25bba33f 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -19,65 +19,22 @@
+ #include "internals.h"
+ #include "netutils.h"
+ 
+-static int is_v4_mapped(const struct sockaddr_storage *ss, socklen_t salen)
++int cmpaddr(const struct sockaddr_storage *ss1, const struct sockaddr_storage *ss2)
+ {
+-	char map[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff };
+-	struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) ss;
+-	return memcmp(&addr6->sin6_addr, map, 12);
+-}
+-
+-int cmpaddr(const struct sockaddr_storage *ss1, socklen_t sslen1,
+-	    const struct sockaddr_storage *ss2, socklen_t sslen2)
+-{
+-	int ss1_offset = 0, ss2_offset = 0;
+ 	struct sockaddr_in6 *ss1_addr6 = (struct sockaddr_in6 *)ss1;
+ 	struct sockaddr_in6 *ss2_addr6 = (struct sockaddr_in6 *)ss2;
+ 	struct sockaddr_in *ss1_addr = (struct sockaddr_in *)ss1;
+ 	struct sockaddr_in *ss2_addr = (struct sockaddr_in *)ss2;
+-	char *addr1, *addr2;
+ 
+-	if (ss1->ss_family == ss2->ss_family) {
+-		return memcmp(ss1, ss2, sslen1);
++	if (ss1->ss_family != ss2->ss_family) {
++		return -1;
+ 	}
+ 
+ 	if (ss1->ss_family == AF_INET6) {
+-		if (is_v4_mapped(ss1, sslen1)) {
+-			return 1;
+-		}
+-		addr1 = (char *)&ss1_addr6->sin6_addr;
+-		ss1_offset = 12;
+-	} else {
+-		addr1 = (char *)&ss1_addr->sin_addr;
+-	}
+-
+-	if (ss2->ss_family == AF_INET6) {
+-		if (is_v4_mapped(ss2, sslen2)) {
+-			return 1;
+-		}
+-		addr2 = (char *)&ss2_addr6->sin6_addr;
+-		ss2_offset = 12;
+-	} else {
+-		addr2 = (char *)&ss2_addr->sin_addr;
++		return memcmp(&ss1_addr6->sin6_addr.s6_addr32, &ss2_addr6->sin6_addr.s6_addr32, sizeof(struct in6_addr));
+ 	}
+ 
+-	return memcmp(addr1+ss1_offset, addr2+ss2_offset, 4);
+-}
+-
+-int cpyaddrport(struct sockaddr_storage *dst, const struct sockaddr_storage *src)
+-{
+-	struct sockaddr_in6 *dst_addr6 = (struct sockaddr_in6 *)dst;
+-	struct sockaddr_in6 *src_addr6 = (struct sockaddr_in6 *)src;
+-
+-	memset(dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if (src->ss_family == AF_INET6) {
+-		dst->ss_family = src->ss_family;
+-		memmove(&dst_addr6->sin6_port, &src_addr6->sin6_port, sizeof(in_port_t));
+-		memmove(&dst_addr6->sin6_addr, &src_addr6->sin6_addr, sizeof(struct in6_addr));
+-	} else {
+-		memmove(dst, src, sizeof(struct sockaddr_in));
+-	}
+-	return 0;
++	return memcmp(&ss1_addr->sin_addr.s_addr, &ss2_addr->sin_addr.s_addr, sizeof(struct in_addr));
+ }
+ 
+ socklen_t sockaddr_len(const struct sockaddr_storage *ss)
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index ee10b2b1..6395398e 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -11,9 +11,19 @@
+ #define __KNET_NETUTILS_H__
+ 
+ #include <sys/socket.h>
++#include <netinet/in.h>
+ 
+-int cmpaddr(const struct sockaddr_storage *ss1, socklen_t sslen1, const struct sockaddr_storage *ss2, socklen_t sslen2);
+-int cpyaddrport(struct sockaddr_storage *dst, const struct sockaddr_storage *src);
++/*
++ * s6_addr32 is not defined in BSD userland, only kernel.
++ * definition is the same as linux and it works fine for
++ * what we need.
++ */
++
++#ifndef s6_addr32
++#define s6_addr32 __u6_addr.__u6_addr32
++#endif
++
++int cmpaddr(const struct sockaddr_storage *ss1, const struct sockaddr_storage *ss2);
+ 
+ socklen_t sockaddr_len(const struct sockaddr_storage *ss);
+ #endif
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 85fc9965..95c87aa2 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -244,10 +244,9 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	struct knet_hostinfo *knet_hostinfo;
+ 	struct iovec iov_out[1];
+ 	int8_t channel;
+-	struct sockaddr_storage pckt_src;
+ 	seq_num_t recv_seq_num;
+ 	int wipe_bufs = 0;
+-	int try_decrypt = 0, decrypted = 0, i;
++	int try_decrypt = 0, decrypted = 0, i, found_link = 0;
+ 
+ 	for (i = 1; i <= KNET_MAX_CRYPTO_INSTANCES; i++) {
+ 		if (knet_h->crypto_instance[i]) {
+@@ -303,22 +302,16 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		return;
+ 	}
+ 
+-	src_link = src_host->link +
+-		(inbuf->khp_ping_link % KNET_MAX_LINK);
+ 	if ((inbuf->kh_type & KNET_HEADER_TYPE_PMSK) != 0) {
++		/* be aware this works only for PING / PONG and PMTUd packets! */
++		src_link = src_host->link +
++			(inbuf->khp_ping_link % KNET_MAX_LINK);
+ 		if (src_link->dynamic == KNET_LINK_DYNIP) {
+-			/*
+-			 * cpyaddrport will only copy address and port of the incoming
+-			 * packet and strip extra bits such as flow and scopeid
+-			 */
+-			cpyaddrport(&pckt_src, msg->msg_hdr.msg_name);
+-
+-			if (cmpaddr(&src_link->dst_addr, sockaddr_len(&src_link->dst_addr),
+-				    &pckt_src, sockaddr_len(&pckt_src)) != 0) {
++			if (cmpaddr(&src_link->dst_addr, msg->msg_hdr.msg_name) != 0) {
+ 				log_debug(knet_h, KNET_SUB_RX, "host: %u link: %u appears to have changed ip address",
+ 					  src_host->host_id, src_link->link_id);
+-				memmove(&src_link->dst_addr, &pckt_src, sizeof(struct sockaddr_storage));
+-				if (knet_addrtostr(&src_link->dst_addr, sockaddr_len(msg->msg_hdr.msg_name),
++				memmove(&src_link->dst_addr, msg->msg_hdr.msg_name, sizeof(struct sockaddr_storage));
++				if (knet_addrtostr(&src_link->dst_addr, sockaddr_len(&src_link->dst_addr),
+ 						src_link->status.dst_ipaddr, KNET_MAX_HOST_LEN,
+ 						src_link->status.dst_port, KNET_MAX_PORT_LEN) != 0) {
+ 					log_debug(knet_h, KNET_SUB_RX, "Unable to resolve ???");
+@@ -337,6 +330,18 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 			 */
+ 			transport_link_dyn_connect(knet_h, sockfd, src_link);
+ 		}
++	} else { /* data packet */
++		for (i = 0; i < KNET_MAX_LINK; i++) {
++			src_link = &src_host->link[i];
++			if (cmpaddr(&src_link->dst_addr, msg->msg_hdr.msg_name) == 0) {
++				found_link = 1;
++				break;
++			}
++		}
++		if (!found_link) {
++			log_debug(knet_h, KNET_SUB_RX, "Unable to determine source link for data packet. Discarding packet.");
++			return;
++		}
+ 	}
+ 
+ 	stats_err = pthread_mutex_lock(&src_link->link_stats_mutex);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0392-rx-fix-data-stats-on-RX-to-match-TX-model.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0392-rx-fix-data-stats-on-RX-to-match-TX-model.patch
new file mode 100644
index 000000000..dd69ae947
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0392-rx-fix-data-stats-on-RX-to-match-TX-model.patch
@@ -0,0 +1,89 @@ 
+From 4428524ddabcb85043f1e593f1eb472268572937 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 25 Aug 2020 14:01:20 +0200
+Subject: [PATCH] [rx] fix data stats on RX to match TX model
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_rx.c | 52 ++++++++++++++++++++++++--------------------
+ 1 file changed, 28 insertions(+), 24 deletions(-)
+
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 95c87aa2..644c0ad5 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -354,18 +354,43 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	switch (inbuf->kh_type) {
+ 	case KNET_HEADER_TYPE_HOST_INFO:
+ 	case KNET_HEADER_TYPE_DATA:
++
++		/* data stats at the top for consistency with TX */
++		src_link->status.stats.rx_data_packets++;
++		src_link->status.stats.rx_data_bytes += len;
++
++		if (decrypted) {
++			stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
++			if (stats_err < 0) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
++				log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
++				return;
++			}
++			/* Only update the crypto overhead for data packets. Mainly to be
++			   consistent with TX */
++			if (decrypt_time < knet_h->stats.rx_crypt_time_min) {
++				knet_h->stats.rx_crypt_time_min = decrypt_time;
++			}
++			if (decrypt_time > knet_h->stats.rx_crypt_time_max) {
++				knet_h->stats.rx_crypt_time_max = decrypt_time;
++			}
++			knet_h->stats.rx_crypt_time_ave =
++				(knet_h->stats.rx_crypt_time_ave * knet_h->stats.rx_crypt_packets +
++				 decrypt_time) / (knet_h->stats.rx_crypt_packets+1);
++			knet_h->stats.rx_crypt_packets++;
++			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
++		}
++
+ 		if (!src_host->status.reachable) {
+ 			pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 			log_debug(knet_h, KNET_SUB_RX, "Source host %u not reachable yet. Discarding packet.", src_host->host_id);
+ 			return;
+ 		}
++
+ 		inbuf->khp_data_seq_num = ntohs(inbuf->khp_data_seq_num);
+ 		channel = inbuf->khp_data_channel;
+ 		src_host->got_data = 1;
+ 
+-		src_link->status.stats.rx_data_packets++;
+-		src_link->status.stats.rx_data_bytes += len;
+-
+ 		if (!_seq_num_lookup(src_host, inbuf->khp_data_seq_num, 0, 0)) {
+ 			pthread_mutex_unlock(&src_link->link_stats_mutex);
+ 			if (src_host->link_handler_policy != KNET_LINK_POLICY_ACTIVE) {
+@@ -441,27 +466,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		}
+ 
+ 		if (inbuf->kh_type == KNET_HEADER_TYPE_DATA) {
+-			if (decrypted) {
+-				stats_err = pthread_mutex_lock(&knet_h->handle_stats_mutex);
+-				if (stats_err < 0) {
+-					pthread_mutex_unlock(&src_link->link_stats_mutex);
+-					log_err(knet_h, KNET_SUB_RX, "Unable to get mutex lock: %s", strerror(stats_err));
+-					return;
+-				}
+-				/* Only update the crypto overhead for data packets. Mainly to be
+-				   consistent with TX */
+-				if (decrypt_time < knet_h->stats.rx_crypt_time_min) {
+-					knet_h->stats.rx_crypt_time_min = decrypt_time;
+-				}
+-				if (decrypt_time > knet_h->stats.rx_crypt_time_max) {
+-					knet_h->stats.rx_crypt_time_max = decrypt_time;
+-				}
+-				knet_h->stats.rx_crypt_time_ave =
+-					(knet_h->stats.rx_crypt_time_ave * knet_h->stats.rx_crypt_packets +
+-					 decrypt_time) / (knet_h->stats.rx_crypt_packets+1);
+-				knet_h->stats.rx_crypt_packets++;
+-				pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+-			}
+ 
+ 			if (knet_h->enabled != 1) /* data forward is disabled */
+ 				break;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0393-tests-hide-internal-nss-memory-leak-non-recurring.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0393-tests-hide-internal-nss-memory-leak-non-recurring.patch
new file mode 100644
index 000000000..c138b9045
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0393-tests-hide-internal-nss-memory-leak-non-recurring.patch
@@ -0,0 +1,37 @@ 
+From dfd5f13fa3cbc81ed1039f3f8533031997786553 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 31 Aug 2020 04:46:07 +0200
+Subject: [PATCH] [tests] hide internal nss memory leak (non-recurring)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 06a3ec00..47c6bf07 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -373,3 +373,22 @@
+   fun:test
+   fun:main
+ }
++{
++  nss internal leak (3.55) non recurring (spotted on f34)
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  fun:realpath@@GLIBC_2.3
++  obj:*
++  obj:*
++  obj:*
++  obj:/usr/lib64/libnss3.so
++  fun:SECMOD_LoadModule
++  fun:SECMOD_LoadModule
++  obj:/usr/lib64/libnss3.so
++  fun:NSS_NoDB_Init
++  fun:init_nss
++  fun:nsscrypto_init
++  fun:crypto_init
++  fun:_knet_handle_crypto_set_config
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0394-heartbeat-don-t-send-ping-if-transport-is-not-connec.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0394-heartbeat-don-t-send-ping-if-transport-is-not-connec.patch
new file mode 100644
index 000000000..fea525286
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0394-heartbeat-don-t-send-ping-if-transport-is-not-connec.patch
@@ -0,0 +1,93 @@ 
+From f1d781e0fc9f54ec8a1c89b1a27e7c5363682b16 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 9 Sep 2020 11:20:51 +0200
+Subject: [PATCH] =?UTF-8?q?[heartbeat]=20don=C2=B4t=20send=20ping=20if=20t?=
+ =?UTF-8?q?ransport=20is=20not=20connected?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+this could cause socket buffers to fill up with stale junk and
+generate unecessary errors.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_heartbeat.c | 64 +++++++++++++++++++------------------
+ 1 file changed, 33 insertions(+), 31 deletions(-)
+
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index df3d5d17..0b8cb5e4 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -97,38 +97,40 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		}
+ 
+ retry:
+-		if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+-			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
+-				     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
+-		} else {
+-			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+-		}
+-		savederrno = errno;
+-
+-		dst_link->ping_last = clock_now;
+-		dst_link->status.stats.tx_ping_packets++;
+-		dst_link->status.stats.tx_ping_bytes += outlen;
+-
+-		if (len != outlen) {
+-			err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
+-			switch(err) {
+-				case -1: /* unrecoverable error */
+-					log_debug(knet_h, KNET_SUB_HEARTBEAT,
+-						  "Unable to send ping (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
+-						  dst_link->outsock, savederrno, strerror(savederrno),
+-						  dst_link->status.src_ipaddr, dst_link->status.src_port,
+-						  dst_link->status.dst_ipaddr, dst_link->status.dst_port);
+-					dst_link->status.stats.tx_ping_errors++;
+-					break;
+-				case 0:
+-					break;
+-				case 1:
+-					dst_link->status.stats.tx_ping_retries++;
+-					goto retry;
+-					break;
++		if (dst_link->transport_connected) {
++			if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++				len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
++					     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
++			} else {
++				len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++			}
++			savederrno = errno;
++
++			dst_link->ping_last = clock_now;
++			dst_link->status.stats.tx_ping_packets++;
++			dst_link->status.stats.tx_ping_bytes += outlen;
++
++			if (len != outlen) {
++				err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
++				switch(err) {
++					case -1: /* unrecoverable error */
++						log_debug(knet_h, KNET_SUB_HEARTBEAT,
++							  "Unable to send ping (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
++							  dst_link->outsock, savederrno, strerror(savederrno),
++							  dst_link->status.src_ipaddr, dst_link->status.src_port,
++							  dst_link->status.dst_ipaddr, dst_link->status.dst_port);
++						dst_link->status.stats.tx_ping_errors++;
++						break;
++					case 0:
++						break;
++					case 1:
++						dst_link->status.stats.tx_ping_retries++;
++						goto retry;
++						break;
++				}
++			} else {
++				dst_link->last_ping_size = outlen;
+ 			}
+-		} else {
+-			dst_link->last_ping_size = outlen;
+ 		}
+ 		pthread_mutex_unlock(&dst_link->link_stats_mutex);
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0395-Revert-heartbeat-don-t-send-ping-if-transport-is-not.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0395-Revert-heartbeat-don-t-send-ping-if-transport-is-not.patch
new file mode 100644
index 000000000..7c97dbe53
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0395-Revert-heartbeat-don-t-send-ping-if-transport-is-not.patch
@@ -0,0 +1,92 @@ 
+From 33a44245808567550df228a41c9919c8821273dc Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 9 Sep 2020 13:22:27 +0200
+Subject: [PATCH] =?UTF-8?q?Revert=20"[heartbeat]=20don=C2=B4t=20send=20pin?=
+ =?UTF-8?q?g=20if=20transport=20is=20not=20connected"?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+This reverts commit 2b73aff21f6341cfd00022694c47ff9b47e17a0e.
+
+The same code already exists at the top of the function
+---
+ libknet/threads_heartbeat.c | 64 ++++++++++++++++++-------------------
+ 1 file changed, 31 insertions(+), 33 deletions(-)
+
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 0b8cb5e4..df3d5d17 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -97,40 +97,38 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		}
+ 
+ retry:
+-		if (dst_link->transport_connected) {
+-			if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+-				len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
+-					     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
+-			} else {
+-				len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+-			}
+-			savederrno = errno;
+-
+-			dst_link->ping_last = clock_now;
+-			dst_link->status.stats.tx_ping_packets++;
+-			dst_link->status.stats.tx_ping_bytes += outlen;
+-
+-			if (len != outlen) {
+-				err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
+-				switch(err) {
+-					case -1: /* unrecoverable error */
+-						log_debug(knet_h, KNET_SUB_HEARTBEAT,
+-							  "Unable to send ping (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
+-							  dst_link->outsock, savederrno, strerror(savederrno),
+-							  dst_link->status.src_ipaddr, dst_link->status.src_port,
+-							  dst_link->status.dst_ipaddr, dst_link->status.dst_port);
+-						dst_link->status.stats.tx_ping_errors++;
+-						break;
+-					case 0:
+-						break;
+-					case 1:
+-						dst_link->status.stats.tx_ping_retries++;
+-						goto retry;
+-						break;
+-				}
+-			} else {
+-				dst_link->last_ping_size = outlen;
++		if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
++			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
++				     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
++		} else {
++			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
++		}
++		savederrno = errno;
++
++		dst_link->ping_last = clock_now;
++		dst_link->status.stats.tx_ping_packets++;
++		dst_link->status.stats.tx_ping_bytes += outlen;
++
++		if (len != outlen) {
++			err = transport_tx_sock_error(knet_h, dst_link->transport, dst_link->outsock, len, savederrno);
++			switch(err) {
++				case -1: /* unrecoverable error */
++					log_debug(knet_h, KNET_SUB_HEARTBEAT,
++						  "Unable to send ping (sock: %d) packet (sendto): %d %s. recorded src ip: %s src port: %s dst ip: %s dst port: %s",
++						  dst_link->outsock, savederrno, strerror(savederrno),
++						  dst_link->status.src_ipaddr, dst_link->status.src_port,
++						  dst_link->status.dst_ipaddr, dst_link->status.dst_port);
++					dst_link->status.stats.tx_ping_errors++;
++					break;
++				case 0:
++					break;
++				case 1:
++					dst_link->status.stats.tx_ping_retries++;
++					goto retry;
++					break;
+ 			}
++		} else {
++			dst_link->last_ping_size = outlen;
+ 		}
+ 		pthread_mutex_unlock(&dst_link->link_stats_mutex);
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0396-sctp-check-and-warn-about-internal-fd-tracker.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0396-sctp-check-and-warn-about-internal-fd-tracker.patch
new file mode 100644
index 000000000..f1bd3cf6b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0396-sctp-check-and-warn-about-internal-fd-tracker.patch
@@ -0,0 +1,46 @@ 
+From 27e0c6bb164d2eba7bf44ab6a4d6b1e4cd5d33f7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 17 Sep 2020 17:14:06 +0200
+Subject: [PATCH] [sctp] check and warn about internal fd tracker
+
+fixes new coverity scan error
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_sctp.c | 16 ++++++++++++++--
+ 1 file changed, 14 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 705b6ca7..ecc40c23 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -871,7 +871,13 @@ exit_error:
+ 		if ((i >= 0) && (i < MAX_ACCEPTED_SOCKS)) {
+ 			info->accepted_socks[i] = -1;
+ 		}
+-		_set_fd_tracker(knet_h, new_fd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL);
++		/*
++		 * check the error to make coverity scan happy.
++		 * _set_fd_tracker cannot fail at this stage
++		 */
++		if (_set_fd_tracker(knet_h, new_fd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0){
++			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to update fdtracker for socket %d", new_fd);
++		}
+ 		free(accept_info);
+ 		if (new_fd >= 0) {
+ 			close(new_fd);
+@@ -939,7 +945,13 @@ static void _handle_listen_sctp_errors(knet_handle_t knet_h)
+ 	for (i=0; i<MAX_ACCEPTED_SOCKS; i++) {
+ 		if (sockfd == info->accepted_socks[i]) {
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Closing accepted socket %d", sockfd);
+-			_set_fd_tracker(knet_h, sockfd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL);
++			/*
++			 * check the error to make coverity scan happy.
++			 * _set_fd_tracker cannot fail at this stage
++			 */
++			if (_set_fd_tracker(knet_h, sockfd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0) {
++				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to update fdtracker for socket %d", sockfd);
++			}
+ 			info->accepted_socks[i] = -1;
+ 			free(accept_info);
+ 			close(sockfd);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0397-cleanup-remove-unused-infrastructure-to-send-HOSTINF.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0397-cleanup-remove-unused-infrastructure-to-send-HOSTINF.patch
new file mode 100644
index 000000000..902cf1950
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0397-cleanup-remove-unused-infrastructure-to-send-HOSTINF.patch
@@ -0,0 +1,553 @@ 
+From f7664cef8d229390e17ab2d44a7adf0e164d08e8 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 17 Aug 2020 16:18:36 +0200
+Subject: [PATCH] [cleanup] remove unused infrastructure to send HOSTINFO
+ messages
+
+those messages are unused in 1.x and if necessary they will be
+reintroduced in 2.x
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/handle.c          |  21 -----
+ libknet/host.c            |  21 -----
+ libknet/host.h            |   1 -
+ libknet/internals.h       |   3 -
+ libknet/onwire.h          |  73 -----------------
+ libknet/tests/pckt_test.c |   4 -
+ libknet/threads_rx.c      | 164 ++++++++++++++++----------------------
+ libknet/threads_tx.c      |  56 ++++---------
+ 8 files changed, 86 insertions(+), 257 deletions(-)
+
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 68641d6e..d4bd86c2 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -167,13 +167,6 @@ static int _init_socks(knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
+ 
+-	if (_init_socketpair(knet_h, knet_h->hostsockfd)) {
+-		savederrno = errno;
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize internal hostsockpair: %s",
+-			strerror(savederrno));
+-		goto exit_fail;
+-	}
+-
+ 	if (_init_socketpair(knet_h, knet_h->dstsockfd)) {
+ 		savederrno = errno;
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize internal dstsockpair: %s",
+@@ -191,7 +184,6 @@ exit_fail:
+ static void _close_socks(knet_handle_t knet_h)
+ {
+ 	_close_socketpair(knet_h, knet_h->dstsockfd);
+-	_close_socketpair(knet_h, knet_h->hostsockfd);
+ }
+ 
+ static int _init_buffers(knet_handle_t knet_h)
+@@ -406,18 +398,6 @@ static int _init_epolls(knet_handle_t knet_h)
+ 		goto exit_fail;
+ 	}
+ 
+-	memset(&ev, 0, sizeof(struct epoll_event));
+-	ev.events = EPOLLIN;
+-	ev.data.fd = knet_h->hostsockfd[0];
+-
+-	if (epoll_ctl(knet_h->send_to_links_epollfd,
+-		      EPOLL_CTL_ADD, knet_h->hostsockfd[0], &ev)) {
+-		savederrno = errno;
+-		log_err(knet_h, KNET_SUB_HANDLE, "Unable to add hostsockfd[0] to epoll pool: %s",
+-			strerror(savederrno));
+-		goto exit_fail;
+-	}
+-
+ 	memset(&ev, 0, sizeof(struct epoll_event));
+ 	ev.events = EPOLLIN;
+ 	ev.data.fd = knet_h->dstsockfd[0];
+@@ -453,7 +433,6 @@ static void _close_epolls(knet_handle_t knet_h)
+ 		}
+ 	}
+ 
+-	epoll_ctl(knet_h->send_to_links_epollfd, EPOLL_CTL_DEL, knet_h->hostsockfd[0], &ev);
+ 	epoll_ctl(knet_h->dst_link_handler_epollfd, EPOLL_CTL_DEL, knet_h->dstsockfd[0], &ev);
+ 	close(knet_h->send_to_links_epollfd);
+ 	close(knet_h->recv_from_links_epollfd);
+diff --git a/libknet/host.c b/libknet/host.c
+index cf351798..e9e86eb8 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -527,27 +527,6 @@ int knet_host_enable_status_change_notify(knet_handle_t knet_h,
+ 	return 0;
+ }
+ 
+-int _send_host_info(knet_handle_t knet_h, const void *data, const size_t datalen)
+-{
+-	ssize_t ret = 0;
+-
+-	if (knet_h->fini_in_progress) {
+-		return 0;
+-	}
+-
+-	ret = sendto(knet_h->hostsockfd[1], data, datalen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+-	if (ret < 0) {
+-		log_debug(knet_h, KNET_SUB_HOST, "Unable to write data to hostpipe. Error: %s", strerror(errno));
+-		return -1;
+-	}
+-	if ((size_t)ret != datalen) {
+-		log_debug(knet_h, KNET_SUB_HOST, "Unable to write all data to hostpipe. Expected: %zu, Written: %zd.", datalen, ret);
+-		return -1;
+-	}
+-
+-	return 0;
+-}
+-
+ static void _clear_cbuffers(struct knet_host *host, seq_num_t rx_seq_num)
+ {
+ 	int i;
+diff --git a/libknet/host.h b/libknet/host.h
+index bd2e8a70..3312c8ba 100644
+--- a/libknet/host.h
++++ b/libknet/host.h
+@@ -15,7 +15,6 @@
+ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, int clear_buf);
+ void _seq_num_set(struct knet_host *host, seq_num_t seq_num, int defrag_buf);
+ 
+-int _send_host_info(knet_handle_t knet_h, const void *data, const size_t datalen);
+ int _host_dstcache_update_async(knet_handle_t knet_h, struct knet_host *host);
+ int _host_dstcache_update_sync(knet_handle_t knet_h, struct knet_host *host);
+ 
+diff --git a/libknet/internals.h b/libknet/internals.h
+index cda58a6d..22f654bb 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -37,8 +37,6 @@
+ 
+ #define KNET_EPOLL_MAX_EVENTS KNET_DATAFD_MAX + 1
+ 
+-#define KNET_INTERNAL_DATA_CHANNEL KNET_DATAFD_MAX
+-
+ /*
+  * Size of threads stack. Value is choosen by experimenting, how much is needed
+  * to sucesfully finish test suite, and at the time of writing patch it was
+@@ -172,7 +170,6 @@ struct knet_handle {
+ 	struct knet_sock sockfd[KNET_DATAFD_MAX + 1];
+ 	int logfd;
+ 	uint8_t log_levels[KNET_MAX_SUBSYSTEMS];
+-	int hostsockfd[2];
+ 	int dstsockfd[2];
+ 	int send_to_links_epollfd;
+ 	int recv_from_links_epollfd;
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index e00ad915..1040ea07 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -19,78 +19,6 @@
+ 
+ #include "libknet.h"
+ 
+-#if 0
+-
+-/*
+- * for future protocol extension (re-switching table calculation)
+- */
+-
+-struct knet_hinfo_link {
+-	uint8_t			khl_link_id;
+-	uint8_t			khl_link_dynamic;
+-	uint8_t			khl_link_priority;
+-	uint64_t		khl_link_latency;
+-	char			khl_link_dst_ipaddr[KNET_MAX_HOST_LEN];
+-	char			khl_link_dst_port[KNET_MAX_PORT_LEN];
+-} __attribute__((packed));
+-
+-struct knet_hinfo_link_table {
+-	knet_node_id_t		khlt_node_id;
+-	uint8_t			khlt_local; /* we have this node connected locally */
+-	struct knet_hinfo_link	khlt_link[KNET_MAX_LINK]; /* info we send about each link in the node */
+-} __attribute__((packed));
+-
+-struct link_table {
+-	knet_node_id_t		khdt_host_entries;
+-	uint8_t			khdt_host_maps[0]; /* array of knet_hinfo_link_table[khdt_host_entries] */
+-} __attribute__((packed));
+-#endif
+-
+-#define KNET_HOSTINFO_LINK_STATUS_DOWN 0
+-#define KNET_HOSTINFO_LINK_STATUS_UP   1
+-
+-struct knet_hostinfo_payload_link_status {
+-	uint8_t		khip_link_status_link_id;	/* link id */
+-	uint8_t		khip_link_status_status;	/* up/down status */
+-} __attribute__((packed));
+-
+-/*
+- * union to reference possible individual payloads
+- */
+-
+-union knet_hostinfo_payload {
+-	struct knet_hostinfo_payload_link_status knet_hostinfo_payload_link_status;
+-} __attribute__((packed));
+-
+-/*
+- * due to the nature of knet_hostinfo, we are currently
+- * sending those data as part of knet_header_payload_data.khp_data_userdata
+- * and avoid a union that increses knet_header_payload_data size
+- * unnecessarely.
+- * This might change later on depending on how we implement
+- * host info exchange
+- */
+-
+-#define KNET_HOSTINFO_TYPE_LINK_UP_DOWN 0 // UNUSED
+-#define KNET_HOSTINFO_TYPE_LINK_TABLE   1 // NOT IMPLEMENTED
+-
+-#define KNET_HOSTINFO_UCAST 0	/* send info to a specific host */
+-#define KNET_HOSTINFO_BCAST 1	/* send info to all known / connected hosts */
+-
+-struct knet_hostinfo {
+-	uint8_t				khi_type;	/* type of hostinfo we are sending */
+-	uint8_t				khi_bcast;	/* hostinfo destination bcast/ucast */
+-	knet_node_id_t			khi_dst_node_id;/* used only if in ucast mode */
+-	union knet_hostinfo_payload	khi_payload;
+-} __attribute__((packed));
+-
+-#define KNET_HOSTINFO_ALL_SIZE sizeof(struct knet_hostinfo)
+-#define KNET_HOSTINFO_SIZE (KNET_HOSTINFO_ALL_SIZE - sizeof(union knet_hostinfo_payload))
+-#define KNET_HOSTINFO_LINK_STATUS_SIZE (KNET_HOSTINFO_SIZE + sizeof(struct knet_hostinfo_payload_link_status))
+-
+-#define khip_link_status_status khi_payload.knet_hostinfo_payload_link_status.khip_link_status_status
+-#define khip_link_status_link_id khi_payload.knet_hostinfo_payload_link_status.khip_link_status_link_id
+-
+ /*
+  * typedef uint64_t seq_num_t;
+  * #define SEQ_MAX UINT64_MAX
+@@ -152,7 +80,6 @@ union knet_header_payload {
+ #define KNET_HEADER_VERSION          0x01 /* we currently support only one version */
+ 
+ #define KNET_HEADER_TYPE_DATA        0x00 /* pure data packet */
+-#define KNET_HEADER_TYPE_HOST_INFO   0x01 /* host status information pckt */
+ 
+ #define KNET_HEADER_TYPE_PMSK        0x80 /* packet mask */
+ #define KNET_HEADER_TYPE_PING        0x81 /* heartbeat */
+diff --git a/libknet/tests/pckt_test.c b/libknet/tests/pckt_test.c
+index 9522c187..30798f3c 100644
+--- a/libknet/tests/pckt_test.c
++++ b/libknet/tests/pckt_test.c
+@@ -18,10 +18,6 @@ int main(void)
+ 	printf("KNET_HEADER_PING_SIZE: %zu (%zu)\n", KNET_HEADER_PING_SIZE, sizeof(struct knet_header_payload_ping));
+ 	printf("KNET_HEADER_PMTUD_SIZE: %zu (%zu)\n", KNET_HEADER_PMTUD_SIZE, sizeof(struct knet_header_payload_pmtud));
+ 	printf("KNET_HEADER_DATA_SIZE: %zu (%zu)\n", KNET_HEADER_DATA_SIZE, sizeof(struct knet_header_payload_data));
+-	printf("\n");
+-	printf("KNET_HOSTINFO_ALL_SIZE: %zu\n", KNET_HOSTINFO_ALL_SIZE);
+-	printf("KNET_HOSTINFO_SIZE: %zu\n", KNET_HOSTINFO_SIZE);
+-	printf("KNET_HOSTINFO_LINK_STATUS_SIZE: %zu (%zu)\n", KNET_HOSTINFO_LINK_STATUS_SIZE, sizeof(struct knet_hostinfo_payload_link_status));
+ 
+ 	return 0;
+ }
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 644c0ad5..ac2f46fc 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -241,7 +241,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	struct knet_header *inbuf = msg->msg_hdr.msg_iov->iov_base;
+ 	unsigned char *outbuf = (unsigned char *)msg->msg_hdr.msg_iov->iov_base;
+ 	ssize_t len = msg->msg_len;
+-	struct knet_hostinfo *knet_hostinfo;
+ 	struct iovec iov_out[1];
+ 	int8_t channel;
+ 	seq_num_t recv_seq_num;
+@@ -352,7 +351,6 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 	}
+ 
+ 	switch (inbuf->kh_type) {
+-	case KNET_HEADER_TYPE_HOST_INFO:
+ 	case KNET_HEADER_TYPE_DATA:
+ 
+ 		/* data stats at the top for consistency with TX */
+@@ -465,115 +463,91 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 		}
+ 
+-		if (inbuf->kh_type == KNET_HEADER_TYPE_DATA) {
++		if (knet_h->enabled != 1) /* data forward is disabled */
++			break;
+ 
+-			if (knet_h->enabled != 1) /* data forward is disabled */
+-				break;
++		if (knet_h->dst_host_filter_fn) {
++			size_t host_idx;
++			int found = 0;
++
++			bcast = knet_h->dst_host_filter_fn(
++					knet_h->dst_host_filter_fn_private_data,
++					(const unsigned char *)inbuf->khp_data_userdata,
++					len - KNET_HEADER_DATA_SIZE,
++					KNET_NOTIFY_RX,
++					knet_h->host_id,
++					inbuf->kh_node,
++					&channel,
++					dst_host_ids,
++					&dst_host_ids_entries);
++			if (bcast < 0) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
++				log_debug(knet_h, KNET_SUB_RX, "Error from dst_host_filter_fn: %d", bcast);
++				return;
++			}
+ 
+-			if (knet_h->dst_host_filter_fn) {
+-				size_t host_idx;
+-				int found = 0;
+-
+-				bcast = knet_h->dst_host_filter_fn(
+-						knet_h->dst_host_filter_fn_private_data,
+-						(const unsigned char *)inbuf->khp_data_userdata,
+-						len - KNET_HEADER_DATA_SIZE,
+-						KNET_NOTIFY_RX,
+-						knet_h->host_id,
+-						inbuf->kh_node,
+-						&channel,
+-						dst_host_ids,
+-						&dst_host_ids_entries);
+-				if (bcast < 0) {
+-					pthread_mutex_unlock(&src_link->link_stats_mutex);
+-					log_debug(knet_h, KNET_SUB_RX, "Error from dst_host_filter_fn: %d", bcast);
+-					return;
+-				}
++			if ((!bcast) && (!dst_host_ids_entries)) {
++				pthread_mutex_unlock(&src_link->link_stats_mutex);
++				log_debug(knet_h, KNET_SUB_RX, "Message is unicast but no dst_host_ids_entries");
++				return;
++			}
+ 
+-				if ((!bcast) && (!dst_host_ids_entries)) {
++			/* check if we are dst for this packet */
++			if (!bcast) {
++				if (dst_host_ids_entries > KNET_MAX_HOST) {
+ 					pthread_mutex_unlock(&src_link->link_stats_mutex);
+-					log_debug(knet_h, KNET_SUB_RX, "Message is unicast but no dst_host_ids_entries");
++					log_debug(knet_h, KNET_SUB_RX, "dst_host_filter_fn returned too many destinations");
+ 					return;
+ 				}
+-
+-				/* check if we are dst for this packet */
+-				if (!bcast) {
+-					if (dst_host_ids_entries > KNET_MAX_HOST) {
+-						pthread_mutex_unlock(&src_link->link_stats_mutex);
+-						log_debug(knet_h, KNET_SUB_RX, "dst_host_filter_fn returned too many destinations");
+-						return;
+-					}
+-					for (host_idx = 0; host_idx < dst_host_ids_entries; host_idx++) {
+-						if (dst_host_ids[host_idx] == knet_h->host_id) {
+-							found = 1;
+-							break;
+-						}
+-					}
+-					if (!found) {
+-						pthread_mutex_unlock(&src_link->link_stats_mutex);
+-						log_debug(knet_h, KNET_SUB_RX, "Packet is not for us");
+-						return;
++				for (host_idx = 0; host_idx < dst_host_ids_entries; host_idx++) {
++					if (dst_host_ids[host_idx] == knet_h->host_id) {
++						found = 1;
++						break;
+ 					}
+ 				}
++				if (!found) {
++					pthread_mutex_unlock(&src_link->link_stats_mutex);
++					log_debug(knet_h, KNET_SUB_RX, "Packet is not for us");
++					return;
++				}
+ 			}
+ 		}
+ 
+-		if (inbuf->kh_type == KNET_HEADER_TYPE_DATA) {
+-			if (!knet_h->sockfd[channel].in_use) {
+-				pthread_mutex_unlock(&src_link->link_stats_mutex);
+-				log_debug(knet_h, KNET_SUB_RX,
+-					  "received packet for channel %d but there is no local sock connected",
+-					  channel);
+-				return;
+-			}
++		if (!knet_h->sockfd[channel].in_use) {
++			pthread_mutex_unlock(&src_link->link_stats_mutex);
++			log_debug(knet_h, KNET_SUB_RX,
++				  "received packet for channel %d but there is no local sock connected",
++				  channel);
++			return;
++		}
+ 
+-			outlen = 0;
+-			memset(iov_out, 0, sizeof(iov_out));
++		outlen = 0;
++		memset(iov_out, 0, sizeof(iov_out));
+ 
+ retry:
+-			iov_out[0].iov_base = (void *) inbuf->khp_data_userdata + outlen;
+-			iov_out[0].iov_len = len - (outlen + KNET_HEADER_DATA_SIZE);
+-
+-			outlen = writev(knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], iov_out, 1);
+-			if ((outlen > 0) && (outlen < (ssize_t)iov_out[0].iov_len)) {
+-				log_debug(knet_h, KNET_SUB_RX,
+-					  "Unable to send all data to the application in one go. Expected: %zu Sent: %zd\n",
+-					  iov_out[0].iov_len, outlen);
+-				goto retry;
+-			}
++		iov_out[0].iov_base = (void *) inbuf->khp_data_userdata + outlen;
++		iov_out[0].iov_len = len - (outlen + KNET_HEADER_DATA_SIZE);
+ 
+-			if (outlen <= 0) {
+-				knet_h->sock_notify_fn(knet_h->sock_notify_fn_private_data,
+-						       knet_h->sockfd[channel].sockfd[0],
+-						       channel,
+-						       KNET_NOTIFY_RX,
+-						       outlen,
+-						       errno);
+-				pthread_mutex_unlock(&src_link->link_stats_mutex);
+-				return;
+-			}
+-			if ((size_t)outlen == iov_out[0].iov_len) {
+-				_seq_num_set(src_host, inbuf->khp_data_seq_num, 0);
+-			}
+-		} else { /* HOSTINFO */
+-			knet_hostinfo = (struct knet_hostinfo *)inbuf->khp_data_userdata;
+-			if (knet_hostinfo->khi_bcast == KNET_HOSTINFO_UCAST) {
+-				knet_hostinfo->khi_dst_node_id = ntohs(knet_hostinfo->khi_dst_node_id);
+-			}
+-			if (!_seq_num_lookup(src_host, inbuf->khp_data_seq_num, 0, 0)) {
+-				pthread_mutex_unlock(&src_link->link_stats_mutex);
+-				return;
+-			}
++		outlen = writev(knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], iov_out, 1);
++		if ((outlen > 0) && (outlen < (ssize_t)iov_out[0].iov_len)) {
++			log_debug(knet_h, KNET_SUB_RX,
++				  "Unable to send all data to the application in one go. Expected: %zu Sent: %zd\n",
++				  iov_out[0].iov_len, outlen);
++			goto retry;
++		}
++
++		if (outlen <= 0) {
++			knet_h->sock_notify_fn(knet_h->sock_notify_fn_private_data,
++					       knet_h->sockfd[channel].sockfd[0],
++					       channel,
++					       KNET_NOTIFY_RX,
++					       outlen,
++					       errno);
++			pthread_mutex_unlock(&src_link->link_stats_mutex);
++			return;
++		}
++		if ((size_t)outlen == iov_out[0].iov_len) {
+ 			_seq_num_set(src_host, inbuf->khp_data_seq_num, 0);
+-			switch(knet_hostinfo->khi_type) {
+-				case KNET_HOSTINFO_TYPE_LINK_UP_DOWN:
+-					break;
+-				case KNET_HOSTINFO_TYPE_LINK_TABLE:
+-					break;
+-				default:
+-					log_warn(knet_h, KNET_SUB_RX, "Receiving unknown host info message from host %u", src_host->host_id);
+-					break;
+-			}
+ 		}
+ 		break;
+ 	case KNET_HEADER_TYPE_PING:
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 615c4266..2f69991b 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -150,7 +150,6 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 	knet_node_id_t dst_host_ids[KNET_MAX_HOST];
+ 	size_t dst_host_ids_entries = 0;
+ 	int bcast = 1;
+-	struct knet_hostinfo *knet_hostinfo;
+ 	struct iovec iov_out[PCKT_FRAG_MAX][2];
+ 	int iovcnt_out = 2;
+ 	uint8_t frag_idx;
+@@ -172,8 +171,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 
+ 	inbuf = knet_h->recv_from_sock_buf;
+ 
+-	if ((knet_h->enabled != 1) &&
+-	    (inbuf->kh_type != KNET_HEADER_TYPE_HOST_INFO)) { /* data forward is disabled */
++	if (knet_h->enabled != 1) {
+ 		log_debug(knet_h, KNET_SUB_TX, "Received data packet but forwarding is disabled");
+ 		savederrno = ECANCELED;
+ 		err = -1;
+@@ -259,15 +257,6 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 				}
+ 			}
+ 			break;
+-		case KNET_HEADER_TYPE_HOST_INFO:
+-			knet_hostinfo = (struct knet_hostinfo *)inbuf->khp_data_userdata;
+-			if (knet_hostinfo->khi_bcast == KNET_HOSTINFO_UCAST) {
+-				bcast = 0;
+-				dst_host_ids_temp[0] = knet_hostinfo->khi_dst_node_id;
+-				dst_host_ids_entries_temp = 1;
+-				knet_hostinfo->khi_dst_node_id = htons(knet_hostinfo->khi_dst_node_id);
+-			}
+-			break;
+ 		default:
+ 			log_warn(knet_h, KNET_SUB_TX, "Receiving unknown messages from socket");
+ 			savederrno = ENOMSG;
+@@ -624,25 +613,19 @@ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int
+ 		docallback = 1;
+ 		memset(&ev, 0, sizeof(struct epoll_event));
+ 
+-		if (channel != KNET_INTERNAL_DATA_CHANNEL) {
+-			if (epoll_ctl(knet_h->send_to_links_epollfd,
+-				      EPOLL_CTL_DEL, knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], &ev)) {
+-				log_err(knet_h, KNET_SUB_TX, "Unable to del datafd %d from linkfd epoll pool: %s",
+-					knet_h->sockfd[channel].sockfd[0], strerror(savederrno));
+-			} else {
+-				knet_h->sockfd[channel].has_error = 1;
+-			}
++		if (epoll_ctl(knet_h->send_to_links_epollfd,
++			      EPOLL_CTL_DEL, knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created], &ev)) {
++			log_err(knet_h, KNET_SUB_TX, "Unable to del datafd %d from linkfd epoll pool: %s",
++				knet_h->sockfd[channel].sockfd[0], strerror(savederrno));
++		} else {
++			knet_h->sockfd[channel].has_error = 1;
+ 		}
+-		/*
+-		 * TODO: add error handling for KNET_INTERNAL_DATA_CHANNEL
+-		 *       once we add support for internal knet communication
+-		 */
+ 	} else {
+ 		knet_h->recv_from_sock_buf->kh_type = type;
+ 		_parse_recv_from_sock(knet_h, inlen, channel, 0);
+ 	}
+ 
+-	if ((docallback) && (channel != KNET_INTERNAL_DATA_CHANNEL)) {
++	if (docallback) {
+ 		knet_h->sock_notify_fn(knet_h->sock_notify_fn_private_data,
+ 				       knet_h->sockfd[channel].sockfd[0],
+ 				       channel,
+@@ -735,22 +718,17 @@ void *_handle_send_to_links_thread(void *data)
+ 		}
+ 
+ 		for (i = 0; i < nev; i++) {
+-			if (events[i].data.fd == knet_h->hostsockfd[0]) {
+-				type = KNET_HEADER_TYPE_HOST_INFO;
+-				channel = KNET_INTERNAL_DATA_CHANNEL;
+-			} else {
+-				type = KNET_HEADER_TYPE_DATA;
+-				for (channel = 0; channel < KNET_DATAFD_MAX; channel++) {
+-					if ((knet_h->sockfd[channel].in_use) &&
+-					    (knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created] == events[i].data.fd)) {
+-						break;
+-					}
+-				}
+-				if (channel >= KNET_DATAFD_MAX) {
+-					log_debug(knet_h, KNET_SUB_TX, "No available channels");
+-					continue; /* channel not found */
++			type = KNET_HEADER_TYPE_DATA;
++			for (channel = 0; channel < KNET_DATAFD_MAX; channel++) {
++				if ((knet_h->sockfd[channel].in_use) &&
++				    (knet_h->sockfd[channel].sockfd[knet_h->sockfd[channel].is_created] == events[i].data.fd)) {
++					break;
+ 				}
+ 			}
++			if (channel >= KNET_DATAFD_MAX) {
++				log_debug(knet_h, KNET_SUB_TX, "No available channels");
++				continue; /* channel not found */
++			}
+ 			if (pthread_mutex_lock(&knet_h->tx_mutex) != 0) {
+ 				log_debug(knet_h, KNET_SUB_TX, "Unable to get mutex lock");
+ 				continue;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0398-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0398-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch
new file mode 100644
index 000000000..dfdf419fa
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0398-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch
@@ -0,0 +1,138 @@ 
+From ef86f4c15e866ca7e6ef98ad2849bc401fcdbb43 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 9 Oct 2020 09:12:04 +0200
+Subject: [PATCH] [tests] add more exceptions to deal with Ubuntu latest
+ rebuilds
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 119 ++++++++++++++++++++++++++
+ 1 file changed, 119 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 47c6bf07..042d6c3f 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -392,3 +392,122 @@
+   fun:crypto_init
+   fun:_knet_handle_crypto_set_config
+ }
++{
++  openssl uncoditional jump (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++}
++{
++  openssl uncoditional jump (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++}
++{
++  openssl uncoditional jump (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl uncoditional jump (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl.isra.0
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  ubuntu-devel new toolchain is not stable yet (spotted on Ubuntu devel 10092020)
++  Memcheck:Param
++  socketcall.sendto(msg)
++  fun:sendto
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  ubuntu-devel new toolchain is not stable yet (spotted on Ubuntu devel 10092020)
++  Memcheck:Param
++  socketcall.sendto(msg)
++  fun:sendto
++  fun:send_pong
++  fun:process_ping
++  fun:_parse_recv_from_links
++  fun:_handle_recv_from_links
++  fun:_handle_recv_from_links_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  ubuntu-devel new toolchain is not stable yet (spotted on Ubuntu devel 10092020)
++  Memcheck:Param
++  socketcall.sendto(msg)
++  fun:sendto
++  fun:send_pmtud_reply
++  fun:process_pmtud
++  fun:_parse_recv_from_links
++  fun:_handle_recv_from_links
++  fun:_handle_recv_from_links_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  ubuntu-devel new toolchain is not stable yet (spotted on Ubuntu devel 10092020)
++  Memcheck:Param
++  sendmsg(msg.msg_iov[0])
++  fun:__libc_sendmsg
++  fun:sendmsg
++  fun:_sendmmsg
++  fun:_dispatch_to_links
++  fun:_prep_and_send_msgs
++  fun:_parse_recv_from_sock
++  fun:_handle_send_to_links
++  fun:_handle_send_to_links_thread
++  fun:start_thread
++  fun:clone
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0399-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0399-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch
new file mode 100644
index 000000000..f0bd0e281
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0399-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch
@@ -0,0 +1,86 @@ 
+From eca06fd03dec82bd748bfa25e3f53110a3027d5c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 12 Oct 2020 07:54:55 +0200
+Subject: [PATCH] [tests] add more exceptions to deal with Ubuntu latest
+ rebuilds (clang counterpart)
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 67 +++++++++++++++++++++++++++
+ 1 file changed, 67 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 042d6c3f..e22fceb7 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -511,3 +511,70 @@
+   fun:start_thread
+   fun:clone
+ }
++{
++  openssl uncoditional jump (clang) (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++}
++{
++  openssl uncoditional jump (clang) (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_instantiate
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_get0_public
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++}
++{
++  openssl uncoditional jump (clang) (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
++{
++  openssl uncoditional jump (clang) (spotted on Ubuntu devel 10092020)
++  Memcheck:Cond
++  obj:/usr/lib/x86_64-linux-gnu/libcrypto.so.1.1
++  fun:RAND_DRBG_generate
++  fun:RAND_DRBG_bytes
++  fun:encrypt_openssl
++  fun:opensslcrypto_encrypt_and_signv
++  fun:opensslcrypto_encrypt_and_sign
++  fun:send_ping
++  fun:_send_pings
++  fun:_handle_heartbt_thread
++  fun:start_thread
++  fun:clone
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0400-tests-hide-another-internal-libnss-non-recurring-mem.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0400-tests-hide-another-internal-libnss-non-recurring-mem.patch
new file mode 100644
index 000000000..e2d5bff3c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0400-tests-hide-another-internal-libnss-non-recurring-mem.patch
@@ -0,0 +1,55 @@ 
+From 69e96d31730bab09567d9f5de1521ac826777563 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 23 Dec 2020 08:30:17 +0100
+Subject: [PATCH] [tests] hide another internal libnss non recurring memory
+ leak
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 36 +++++++++++++++++++++++++++
+ 1 file changed, 36 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index e22fceb7..cd09f695 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -578,3 +578,39 @@
+   fun:start_thread
+   fun:clone
+ }
++{
++  nss internal leak (3.59) non recurring (spotted on f34)
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  fun:realpath@@GLIBC_2.3
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:/usr/lib64/libnss3.so
++  fun:SECMOD_LoadModule
++  fun:SECMOD_LoadModule
++  obj:/usr/lib64/libnss3.so
++  fun:NSS_NoDB_Init
++  fun:init_nss
++  fun:nsscrypto_init
++}
++{
++  nss internal leak (3.59) non recurring (spotted on f34)
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  fun:realpath@@GLIBC_2.3
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  fun:init_nss
++  fun:nsscrypto_init
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0401-Drop-travis-support.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0401-Drop-travis-support.patch
new file mode 100644
index 000000000..fd065a6d2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0401-Drop-travis-support.patch
@@ -0,0 +1,79 @@ 
+From df77c77ca23b6dbf441e45e0ae1ac58d7c96d8ca Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 22 Feb 2021 10:31:43 +0100
+Subject: [PATCH] Drop travis support
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ .travis.yml | 62 -----------------------------------------------------
+ 1 file changed, 62 deletions(-)
+ delete mode 100644 .travis.yml
+
+diff --git a/.travis.yml b/.travis.yml
+deleted file mode 100644
+index ab7a66d9..00000000
+--- a/.travis.yml
++++ /dev/null
+@@ -1,62 +0,0 @@
+-sudo: false
+-
+-language: c
+-
+-compiler:
+-  - gcc
+-
+-env:
+-  global:
+-   # The next declaration is the encrypted COVERITY_SCAN_TOKEN, created
+-   #   via the "travis encrypt" command using the project repo's public key
+-   - secure: "UzfmWmjTx8Vq4DBlcbvXiEqWfDoPkoQ63dYgWrdlpvp+JTCb+XYMa/KAt0v8+U2IhixudI6Vuq5ztGFqFL8jnNFHOqfjIqTtdxi5Hen8vRymyqar963HOOhlXQ9+XN6+IztqmJx7jVI26O7m+Pt+CTzhaz8u2eh3yTYq6pIQ0Cs="
+-
+-git:
+-  depth: false
+-
+-before_install:
+-  - echo -n | openssl s_client -connect https://scan.coverity.com:443 | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' | sudo tee -a /etc/ssl/certs/ca-
+-  - ./autogen.sh
+-
+-script: if [ "${COVERITY_SCAN_BRANCH}" != 1 ]; then ./configure && make ; fi
+-
+-branches:
+-  only:
+-    - coverity_scan
+-
+-addons:
+-  coverity_scan:
+-    project:
+-      name: "kronosnet/kronosnet"
+-      description: "Kronosnet, often referred to as knet, is a network abstraction layer designed for High Availability use cases, where redundancy, security, fault tolerance and fast fail-over are the core requirements of your application."
+-    notification_email: fdinitto@redhat.com
+-    build_command_prepend: "./configure"
+-    build_command: "make"
+-    branch_pattern: coverity_scan
+-  apt:
+-    packages:
+-      - build-essential
+-      - libtool-bin
+-      - make
+-      - git
+-      - gcc
+-      - clang
+-      - autoconf
+-      - autotools-dev
+-      - libtool
+-      - libnss3-dev
+-      - libnspr4-dev
+-      - libssl-dev
+-      - pkg-config
+-      - zlib1g-dev
+-      - liblz4-dev
+-      - liblzo2-dev
+-      - liblzma-dev
+-      - libbz2-dev
+-      - libsctp-dev
+-      - libqb-dev
+-      - libxml2-dev
+-      - doxygen
+-      - libzstd-dev
+-      - libnl-3-dev
+-      - libnl-route-3-dev
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0402-tests-Fix-some-random-CI-failures.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0402-tests-Fix-some-random-CI-failures.patch
new file mode 100644
index 000000000..ec4d88b55
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0402-tests-Fix-some-random-CI-failures.patch
@@ -0,0 +1,83 @@ 
+From 491f5334e2cbaaa5e142c0c690389a9233944dae Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 25 Feb 2021 14:54:50 +0000
+Subject: [PATCH] tests: Fix some random CI failures.
+
+---
+ libknet/tests/fun_config_crypto.c |  2 +-
+ libknet/tests/test-common.c       | 30 ++++++++----------------------
+ 2 files changed, 9 insertions(+), 23 deletions(-)
+
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+index 2a4b5df1..ac9deb6a 100644
+--- a/libknet/tests/fun_config_crypto.c
++++ b/libknet/tests/fun_config_crypto.c
+@@ -30,7 +30,7 @@ static void test(const char *model)
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 	int i,x,j;
+-	int seconds = 5;
++	int seconds = 10;
+ 
+ 	if (is_memcheck() || is_helgrind()) {
+ 		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 0906bac5..39b7c7ab 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -610,6 +610,8 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ {
+ 	uint8_t i, x, j;
+ 	struct sockaddr_storage src, dst;
++	int offset = 0;
++	int res;
+ 
+ 	for (i = 1; i <= numnodes; i++) {
+ 		for (j = 1; j <= numnodes; j++) {
+@@ -629,40 +631,24 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ 			}
+ 
+ 			for (x = 0; x < numlinks; x++) {
+-				if (family == AF_INET6) {
+-					if (make_local_sockaddr6(&src, i + x) < 0) {
++				res = -1;
++				offset = 0;
++				while (i + x + offset++ < 65535 && res != 0) {
++					if (_make_local_sockaddr(&src, i + x + offset, family) < 0) {
+ 						printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+ 						knet_handle_stop_nodes(knet_h, numnodes);
+ 						exit(FAIL);
+ 					}
+ 
+-					if (make_local_sockaddr6(&dst, j + x) < 0) {
++					if (_make_local_sockaddr(&dst, j + x + offset, family) < 0) {
+ 						printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+ 						knet_handle_stop_nodes(knet_h, numnodes);
+ 						exit(FAIL);
+ 					}
+-				} else {
+-					if (make_local_sockaddr(&src, i + x) < 0) {
+-						printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-						knet_handle_stop_nodes(knet_h, numnodes);
+-						exit(FAIL);
+-					}
+ 
+-					if (make_local_sockaddr(&dst, j + x) < 0) {
+-						printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-						knet_handle_stop_nodes(knet_h, numnodes);
+-						exit(FAIL);
+-					}
++					res = knet_link_set_config(knet_h[i], j, x, transport, &src, &dst, 0);
+ 				}
+-
+ 				printf("joining node %u with node %u via link %u src offset: %u dst offset: %u\n", i, j, x, i+x, j+x);
+-
+-				if (knet_link_set_config(knet_h[i], j, x, transport, &src, &dst, 0) < 0) {
+-					printf("unable to configure link: %s\n", strerror(errno));
+-					knet_handle_stop_nodes(knet_h, numnodes);
+-					exit(FAIL);
+-				}
+-
+ 				if (knet_link_set_enable(knet_h[i], j, x, 1) < 0) {
+ 					printf("unable to enable link: %s\n", strerror(errno));
+ 					knet_handle_stop_nodes(knet_h, numnodes);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0403-tests-use-callbacks-to-wait-for-nodes.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0403-tests-use-callbacks-to-wait-for-nodes.patch
new file mode 100644
index 000000000..17e0be157
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0403-tests-use-callbacks-to-wait-for-nodes.patch
@@ -0,0 +1,216 @@ 
+From e0abdbc502b22b7c358a67da1fe479004ae8b846 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 11 Mar 2021 10:37:54 +0000
+Subject: [PATCH] tests: use callbacks to wait for nodes
+
+Rather than just wait for a arbitrary amount of time for
+nodes to come online while testing, use the knet callback
+mechanism. This should not only save some time in the running
+of the tests, but also make them less susceptible to slowness
+on the CI machines.
+---
+ libknet/tests/test-common.c | 168 ++++++++++++++++++++++++++++--------
+ libknet/tests/test-common.h |   3 +
+ 2 files changed, 136 insertions(+), 35 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 39b7c7ab..551bea57 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -508,28 +508,6 @@ void test_sleep(knet_handle_t knet_h, int seconds)
+ 	sleep(seconds);
+ }
+ 
+-int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std)
+-{
+-	int i = 0;
+-
+-	if (is_memcheck() || is_helgrind()) {
+-		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
+-		seconds = seconds * 16;
+-	}
+-
+-	while (i < seconds) {
+-		flush_logs(logfd, std);
+-		if (knet_h->host_index[host_id]->status.reachable == 1) {
+-			printf("Waiting for host to settle\n");
+-			test_sleep(knet_h, 1);
+-			return 0;
+-		}
+-		printf("waiting host %u to be reachable for %d more seconds\n", host_id, seconds - i);
+-		sleep(1);
+-		i++;
+-	}
+-	return -1;
+-}
+ 
+ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd, int logfd, FILE *std)
+ {
+@@ -659,21 +637,141 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ 	}
+ 
+ 	for (i = 1; i <= numnodes; i++) {
+-		for (j = 1; j <= numnodes; j++) {
+-			/*
+-			 * don´t wait for self
+-			 */
+-			if (j == i) {
+-				continue;
+-			}
++		wait_for_nodes_state(knet_h[i], numnodes, 1, 600, knet_h[1]->logfd, stdout);
++	}
++	return;
++}
+ 
+-			if (wait_for_host(knet_h[i], j, (10 * numnodes) , knet_h[i]->logfd, stdout) < 0) {
+-					printf("Cannot connect node %u to node %u: %s\n", i, j, strerror(errno));
+-					knet_handle_stop_nodes(knet_h, numnodes);
+-					exit(FAIL);
+-			}
++
++static int target=0;
++static pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER;
++static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER;
++
++static int count_nodes(knet_handle_t knet_h)
++{
++	int nodes = 0;
++	int i;
++
++	for (i=0; i< KNET_MAX_HOST; i++) {
++		if (knet_h->host_index[i] && knet_h->host_index[i]->status.reachable == 1) {
++			nodes++;
+ 		}
+ 	}
++	return nodes;
++}
+ 
+-	return;
++static void nodes_notify_callback(void *private_data,
++				  knet_node_id_t host_id,
++				  uint8_t reachable, uint8_t remote, uint8_t external)
++{
++	knet_handle_t knet_h = (knet_handle_t) private_data;
++	int nodes;
++
++	nodes = count_nodes(knet_h);
++
++	if (nodes == target) {
++		pthread_cond_signal(&wait_cond);
++	}
++}
++
++static void host_notify_callback(void *private_data,
++				 knet_node_id_t host_id,
++				 uint8_t reachable, uint8_t remote, uint8_t external)
++{
++	knet_handle_t knet_h = (knet_handle_t) private_data;
++
++	if (knet_h->host_index[host_id]->status.reachable == 1) {
++		pthread_cond_signal(&wait_cond);
++	}
++}
++
++/* Wait for a cluster of 'numnodes' to come up/go down */
++int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
++			 uint8_t state, uint32_t timeout,
++			 int logfd, FILE *std)
++{
++	struct timespec ts;
++	int res;
++
++	if (state) {
++		target = numnodes-1; /* exclude us */
++	} else {
++		target = 0; /* Wait for all to go down */
++	}
++
++	/* Set this before checking existing status or there's a race condition */
++	knet_host_enable_status_change_notify(knet_h,
++					      (void *)(long)knet_h,
++					      nodes_notify_callback);
++
++	/* Check we haven't already got all the nodes in the correct state */
++	if (count_nodes(knet_h) == target) {
++		fprintf(stderr, "target already reached\n");
++		knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
++		flush_logs(logfd, std);
++		return 0;
++	}
++
++	clock_gettime(CLOCK_REALTIME, &ts);
++	ts.tv_sec += timeout;
++	if (pthread_mutex_lock(&wait_mutex)) {
++		fprintf(stderr, "unable to get nodewait mutex: %s\n", strerror(errno));
++		return -1;
++	}
++	res = pthread_cond_timedwait(&wait_cond, &wait_mutex, &ts);
++	if (res == -1 && errno == ETIMEDOUT) {
++		fprintf(stderr, "Timed-out\n");
++	}
++	pthread_mutex_unlock(&wait_mutex);
++
++	knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
++	flush_logs(logfd, std);
++	return res;
++}
++
++/* Wait for a single node to come up */
++int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std)
++{
++	int res;
++	struct timespec ts;
++
++	if (is_memcheck() || is_helgrind()) {
++		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
++		seconds = seconds * 16;
++	}
++
++	/* Set this before checking existing status or there's a race condition */
++	knet_host_enable_status_change_notify(knet_h,
++					      (void *)(long)knet_h,
++					      host_notify_callback);
++
++	/* Check it's not already reachable */
++	if (knet_h->host_index[host_id]->status.reachable == 1) {
++		knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
++		flush_logs(logfd, std);
++		return 0;
++	}
++
++	clock_gettime(CLOCK_REALTIME, &ts);
++	ts.tv_sec += seconds;
++	if (pthread_mutex_lock(&wait_mutex)) {
++		fprintf(stderr, "unable to get nodewait mutex: %s\n", strerror(errno));
++		return -1;
++	}
++	res = pthread_cond_timedwait(&wait_cond, &wait_mutex, &ts);
++	if (res == -1 && errno == ETIMEDOUT) {
++		fprintf(stderr, "Timed-out\n");
++		knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
++		pthread_mutex_unlock(&wait_mutex);
++		flush_logs(logfd, std);
++		return -1;
++	}
++	pthread_mutex_unlock(&wait_mutex);
++
++	knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
++
++	/* Still wait for it to settle */
++	flush_logs(logfd, std);
++	test_sleep(knet_h, 1);
++	return 0;
+ }
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index cc31e62c..4be816e6 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -87,5 +87,8 @@ int make_local_sockaddr6(struct sockaddr_storage *lo, int offset);
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std);
+ int wait_for_packet(knet_handle_t knet_h, int seconds, int datafd, int logfd, FILE *std);
+ void test_sleep(knet_handle_t knet_h, int seconds);
++int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
++			 uint8_t state, uint32_t timeout,
++			 int logfd, FILE *std);
+ 
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0404-Add-some-more-uses-for-event-based-tests.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0404-Add-some-more-uses-for-event-based-tests.patch
new file mode 100644
index 000000000..a6043197d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0404-Add-some-more-uses-for-event-based-tests.patch
@@ -0,0 +1,99 @@ 
+From ec6690f8ac6182c02e215b1ab473dc3d7b1937cd Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 12 Mar 2021 14:25:33 +0000
+Subject: [PATCH] Add some more uses for event-based tests
+
+This gets time for the whole test suite (on my machine) down
+from 10m25 to 5.56 (make check) and
+from >120m* to 55m29 (make check-memcheck)
+
+* I accidentally hit ^C on these tests after 2 hours so it's
+probably much longer
+---
+ libknet/tests/fun_config_crypto.c | 51 +++----------------------------
+ 1 file changed, 4 insertions(+), 47 deletions(-)
+
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+index ac9deb6a..1cabbcd7 100644
+--- a/libknet/tests/fun_config_crypto.c
++++ b/libknet/tests/fun_config_crypto.c
+@@ -29,7 +29,7 @@ static void test(const char *model)
+ 	knet_handle_t knet_h[TESTNODES + 1];
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+-	int i,x,j;
++	int i,x;
+ 	int seconds = 10;
+ 
+ 	if (is_memcheck() || is_helgrind()) {
+@@ -115,23 +115,8 @@ static void test(const char *model)
+ 			close_logpipes(logfds);
+ 			exit(FAIL);
+ 		}
+-		for (x = 0; x < seconds; x++){
+-			flush_logs(logfds[0], stdout);
+-			sleep(1);
+-		}
+ 		for (x = 1; x <= TESTNODES; x++) {
+-			for (j = 1; j <= TESTNODES; j++) {
+-				if (j == x) {
+-					continue;
+-				}
+-				if (knet_h[x]->host_index[j]->status.reachable != 1) {
+-					printf("knet failed to switch config for host %d\n", x);
+-					knet_handle_stop_nodes(knet_h, TESTNODES);
+-					flush_logs(logfds[0], stdout);
+-					close_logpipes(logfds);
+-					exit(FAIL);
+-				}
+-			}
++			wait_for_nodes_state(knet_h[x], TESTNODES, 1, 600, knet_h[1]->logfd, stdout);
+ 		}
+ 	}
+ 
+@@ -147,24 +132,7 @@ static void test(const char *model)
+ 			close_logpipes(logfds);
+ 			exit(FAIL);
+ 		}
+-		for (x = 0; x < seconds; x++){
+-			flush_logs(logfds[0], stdout);
+-			sleep(1);
+-		}
+-		for (x = 1; x <= TESTNODES; x++) {
+-			for (j = 1; j <= TESTNODES; j++) {
+-				if (j == x) {
+-					continue;
+-				}
+-				if (knet_h[x]->host_index[j]->status.reachable != 1) {
+-					printf("knet failed to switch config for host %d\n", x);
+-					knet_handle_stop_nodes(knet_h, TESTNODES);
+-					flush_logs(logfds[0], stdout);
+-					close_logpipes(logfds);
+-					exit(FAIL);
+-				}
+-			}
+-		}
++		wait_for_nodes_state(knet_h[i], TESTNODES, 1, 600, knet_h[1]->logfd, stdout);
+ 	}
+ 
+ 	printf("Testing disable crypto config and allow clear traffic\n");
+@@ -232,18 +200,7 @@ static void test(const char *model)
+ 			sleep(1);
+ 		}
+ 		for (x = 1; x <= TESTNODES; x++) {
+-			for (j = 1; j <= TESTNODES; j++) {
+-				if (j == x) {
+-					continue;
+-				}
+-				if (knet_h[x]->host_index[j]->status.reachable != 1) {
+-					printf("knet failed to switch config for host %d\n", x);
+-					knet_handle_stop_nodes(knet_h, TESTNODES);
+-					flush_logs(logfds[0], stdout);
+-					close_logpipes(logfds);
+-					exit(FAIL);
+-				}
+-			}
++			wait_for_nodes_state(knet_h[x], TESTNODES, 1, 600, knet_h[1]->logfd, stdout);
+ 		}
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0405-openssl-port-knet-top-openssl3.0-alpha13.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0405-openssl-port-knet-top-openssl3.0-alpha13.patch
new file mode 100644
index 000000000..0a3b05c41
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0405-openssl-port-knet-top-openssl3.0-alpha13.patch
@@ -0,0 +1,81 @@ 
+From dd8598656ffcff7062db43ef37ce8312f2e071c4 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 7 Apr 2021 06:13:12 +0200
+Subject: [PATCH] [openssl] port knet top openssl3.0-alpha13
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+openssl 3.0 is not GA yet and there are still API changes around.
+it´s currently only available in Debian experimental and while
+not critical for knet, we continue to keep knet updated and be ready
+for 3.0 GA.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 17 +++--------------
+ 1 file changed, 3 insertions(+), 14 deletions(-)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index e3618e90..47814c56 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -17,8 +17,6 @@
+ #include <openssl/evp.h>
+ #if (OPENSSL_VERSION_NUMBER < 0x30000000L)
+ #include <openssl/hmac.h>
+-#else
+-#include <openssl/mac.h>
+ #endif
+ #include <openssl/rand.h>
+ #include <openssl/err.h>
+@@ -44,7 +42,6 @@
+  */
+ #if (OPENSSL_VERSION_NUMBER >= 0x30000000L)
+ static const char *hash = "digest";
+-static const char *key = "key";
+ #endif
+ 
+ struct opensslcrypto_instance {
+@@ -350,7 +347,7 @@ static int calculate_openssl_hash(
+ 	int err = 0;
+ 	size_t outlen = 0;
+ 
+-	ctx = EVP_MAC_new_ctx(instance->crypto_hash_mac);
++	ctx = EVP_MAC_CTX_new(instance->crypto_hash_mac);
+ 	if (!ctx) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+ 		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to allocate openssl context: %s", sslerr);
+@@ -358,14 +355,7 @@ static int calculate_openssl_hash(
+ 		goto out_err;
+ 	}
+ 
+-	if (EVP_MAC_set_ctx_params(ctx, instance->params) < 0) {
+-		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+-		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to set openssl context parameters: %s", sslerr);
+-		err = -1;
+-		goto out_err;
+-	}
+-
+-	if (!EVP_MAC_init(ctx)) {
++	if (!EVP_MAC_init(ctx, instance->private_key, instance->private_key_len, instance->params)) {
+ 		ERR_error_string_n(ERR_get_error(), sslerr, sizeof(sslerr));
+ 		log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Unable to set openssl context parameters: %s", sslerr);
+ 		err = -1;
+@@ -388,7 +378,7 @@ static int calculate_openssl_hash(
+ 
+ out_err:
+ 	if (ctx) {
+-		EVP_MAC_free_ctx(ctx);
++		EVP_MAC_CTX_free(ctx);
+ 	}
+ 
+ 	return err;
+@@ -694,7 +684,6 @@ static int opensslcrypto_init(
+ 		memmove(opensslcrypto_instance->hash_type, knet_handle_crypto_cfg->crypto_hash_type, sizeof(opensslcrypto_instance->hash_type));
+ 
+ 		opensslcrypto_instance->params[params_n++] = OSSL_PARAM_construct_utf8_string(hash, opensslcrypto_instance->hash_type, 0);
+-		opensslcrypto_instance->params[params_n++] = OSSL_PARAM_construct_octet_string(key, opensslcrypto_instance->private_key, opensslcrypto_instance->private_key_len);
+ 		opensslcrypto_instance->params[params_n] = OSSL_PARAM_construct_end();
+ #endif
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0406-docs-Update-README-for-BSD-section.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0406-docs-Update-README-for-BSD-section.patch
new file mode 100644
index 000000000..33b22cede
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0406-docs-Update-README-for-BSD-section.patch
@@ -0,0 +1,30 @@ 
+From 20269125d18f41dd9a811206bb1ad7844f9ea5d0 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 9 Apr 2021 06:21:32 +0200
+Subject: [PATCH] [docs] Update README for BSD section
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ README | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/README b/README
+index edbbbbcc..47089579 100644
+--- a/README
++++ b/README
+@@ -33,8 +33,14 @@ knet requires big socket buffers and you need to set:
+ kern.ipc.maxsockbuf=18388608
+ in /etc/sysctl.conf or knet will fail to run.
+ 
+-currently, knet requires also:
++For version 12 (or lower), knet requires also:
+ net.inet.sctp.blackhole=1
+ in /etc/sysctl.conf or knet will fail to work with SCTP.
++This sysctl is obsoleted in version 13.
+ 
+ libnozzle requires if_tap.ko loaded in the kernel.
++
++Please avoid to use ifconfig_DEFAULT in /etc/rc.conf to use
++DHCP for all interfaces or the dhclient will interfere with
++libnozzle interface management, causing errors on some
++operations such as "ifconfig tap down".
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0407-global-Update-copyright.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0407-global-Update-copyright.patch
new file mode 100644
index 000000000..b77fafbbc
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0407-global-Update-copyright.patch
@@ -0,0 +1,2296 @@ 
+From b9be9bffc46ce271ea48346465a72060bbbab3c5 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 9 Apr 2021 10:40:34 +0200
+Subject: [PATCH] [global] Update copyright
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ COPYRIGHT                                                     | 2 +-
+ Makefile.am                                                   | 2 +-
+ README                                                        | 2 +-
+ autogen.sh                                                    | 2 +-
+ build-aux/check.mk                                            | 2 +-
+ build-aux/git-version-gen                                     | 2 +-
+ build-aux/release.mk                                          | 2 +-
+ configure.ac                                                  | 2 +-
+ kronosnet.spec.in                                             | 2 +-
+ libknet/Makefile.am                                           | 2 +-
+ libknet/common.c                                              | 2 +-
+ libknet/common.h                                              | 2 +-
+ libknet/compat.c                                              | 2 +-
+ libknet/compat.h                                              | 2 +-
+ libknet/compress.c                                            | 2 +-
+ libknet/compress.h                                            | 2 +-
+ libknet/compress_bzip2.c                                      | 2 +-
+ libknet/compress_lz4.c                                        | 2 +-
+ libknet/compress_lz4hc.c                                      | 2 +-
+ libknet/compress_lzma.c                                       | 2 +-
+ libknet/compress_lzo2.c                                       | 2 +-
+ libknet/compress_model.h                                      | 2 +-
+ libknet/compress_zlib.c                                       | 2 +-
+ libknet/compress_zstd.c                                       | 2 +-
+ libknet/crypto.c                                              | 2 +-
+ libknet/crypto.h                                              | 2 +-
+ libknet/crypto_model.h                                        | 2 +-
+ libknet/crypto_nss.c                                          | 2 +-
+ libknet/crypto_openssl.c                                      | 2 +-
+ libknet/handle.c                                              | 2 +-
+ libknet/handle_api.c                                          | 2 +-
+ libknet/host.c                                                | 2 +-
+ libknet/host.h                                                | 2 +-
+ libknet/internals.h                                           | 2 +-
+ libknet/libknet.h                                             | 4 ++--
+ libknet/libknet.pc.in                                         | 2 +-
+ libknet/libknet_exported_syms                                 | 2 +-
+ libknet/links.c                                               | 2 +-
+ libknet/links.h                                               | 2 +-
+ libknet/links_acl.c                                           | 2 +-
+ libknet/links_acl.h                                           | 2 +-
+ libknet/links_acl_ip.c                                        | 2 +-
+ libknet/links_acl_ip.h                                        | 2 +-
+ libknet/links_acl_loopback.c                                  | 2 +-
+ libknet/links_acl_loopback.h                                  | 2 +-
+ libknet/logging.c                                             | 2 +-
+ libknet/logging.h                                             | 2 +-
+ libknet/netutils.c                                            | 2 +-
+ libknet/netutils.h                                            | 2 +-
+ libknet/onwire.c                                              | 2 +-
+ libknet/onwire.h                                              | 2 +-
+ libknet/tests/Makefile.am                                     | 2 +-
+ libknet/tests/api-check.mk                                    | 2 +-
+ libknet/tests/api-test-coverage                               | 2 +-
+ libknet/tests/api_knet_addrtostr.c                            | 2 +-
+ libknet/tests/api_knet_get_compress_list.c                    | 2 +-
+ libknet/tests/api_knet_get_crypto_list.c                      | 2 +-
+ libknet/tests/api_knet_get_transport_id_by_name.c             | 2 +-
+ libknet/tests/api_knet_get_transport_list.c                   | 2 +-
+ libknet/tests/api_knet_get_transport_name_by_id.c             | 2 +-
+ libknet/tests/api_knet_handle_add_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_clear_stats.c                   | 2 +-
+ libknet/tests/api_knet_handle_compress.c                      | 2 +-
+ libknet/tests/api_knet_handle_crypto.c                        | 2 +-
+ libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c       | 2 +-
+ libknet/tests/api_knet_handle_crypto_set_config.c             | 2 +-
+ libknet/tests/api_knet_handle_crypto_use_config.c             | 2 +-
+ libknet/tests/api_knet_handle_enable_access_lists.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_filter.c                 | 2 +-
+ libknet/tests/api_knet_handle_enable_pmtud_notify.c           | 2 +-
+ libknet/tests/api_knet_handle_enable_sock_notify.c            | 2 +-
+ libknet/tests/api_knet_handle_free.c                          | 2 +-
+ libknet/tests/api_knet_handle_get_channel.c                   | 2 +-
+ libknet/tests/api_knet_handle_get_datafd.c                    | 2 +-
+ libknet/tests/api_knet_handle_get_stats.c                     | 2 +-
+ .../tests/api_knet_handle_get_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_new.c                           | 2 +-
+ libknet/tests/api_knet_handle_new_limit.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_get.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_getfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_pmtud_set.c                     | 2 +-
+ libknet/tests/api_knet_handle_pmtud_setfreq.c                 | 2 +-
+ libknet/tests/api_knet_handle_remove_datafd.c                 | 2 +-
+ .../tests/api_knet_handle_set_transport_reconnect_interval.c  | 2 +-
+ libknet/tests/api_knet_handle_setfwd.c                        | 2 +-
+ libknet/tests/api_knet_host_add.c                             | 2 +-
+ libknet/tests/api_knet_host_enable_status_change_notify.c     | 2 +-
+ libknet/tests/api_knet_host_get_host_list.c                   | 2 +-
+ libknet/tests/api_knet_host_get_id_by_host_name.c             | 2 +-
+ libknet/tests/api_knet_host_get_name_by_host_id.c             | 2 +-
+ libknet/tests/api_knet_host_get_policy.c                      | 2 +-
+ libknet/tests/api_knet_host_get_status.c                      | 2 +-
+ libknet/tests/api_knet_host_remove.c                          | 2 +-
+ libknet/tests/api_knet_host_set_name.c                        | 2 +-
+ libknet/tests/api_knet_host_set_policy.c                      | 2 +-
+ libknet/tests/api_knet_link_add_acl.c                         | 2 +-
+ libknet/tests/api_knet_link_clear_acl.c                       | 2 +-
+ libknet/tests/api_knet_link_clear_config.c                    | 2 +-
+ libknet/tests/api_knet_link_get_config.c                      | 2 +-
+ libknet/tests/api_knet_link_get_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_get_link_list.c                   | 2 +-
+ libknet/tests/api_knet_link_get_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_get_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_get_priority.c                    | 2 +-
+ libknet/tests/api_knet_link_get_status.c                      | 2 +-
+ libknet/tests/api_knet_link_insert_acl.c                      | 2 +-
+ libknet/tests/api_knet_link_rm_acl.c                          | 2 +-
+ libknet/tests/api_knet_link_set_config.c                      | 2 +-
+ libknet/tests/api_knet_link_set_enable.c                      | 2 +-
+ libknet/tests/api_knet_link_set_ping_timers.c                 | 2 +-
+ libknet/tests/api_knet_link_set_pong_count.c                  | 2 +-
+ libknet/tests/api_knet_link_set_priority.c                    | 2 +-
+ libknet/tests/api_knet_log_get_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_id.c                  | 2 +-
+ libknet/tests/api_knet_log_get_loglevel_name.c                | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_id.c                 | 2 +-
+ libknet/tests/api_knet_log_get_subsystem_name.c               | 2 +-
+ libknet/tests/api_knet_log_set_loglevel.c                     | 2 +-
+ libknet/tests/api_knet_recv.c                                 | 2 +-
+ libknet/tests/api_knet_send.c                                 | 2 +-
+ libknet/tests/api_knet_send_compress.c                        | 2 +-
+ libknet/tests/api_knet_send_crypto.c                          | 2 +-
+ libknet/tests/api_knet_send_loopback.c                        | 2 +-
+ libknet/tests/api_knet_send_sync.c                            | 2 +-
+ libknet/tests/api_knet_strtoaddr.c                            | 2 +-
+ libknet/tests/fun_config_crypto.c                             | 2 +-
+ libknet/tests/fun_pmtud_crypto.c                              | 2 +-
+ libknet/tests/int_links_acl_ip.c                              | 2 +-
+ libknet/tests/int_timediff.c                                  | 2 +-
+ libknet/tests/knet_bench.c                                    | 2 +-
+ libknet/tests/pckt_test.c                                     | 2 +-
+ libknet/tests/test-common.c                                   | 2 +-
+ libknet/tests/test-common.h                                   | 2 +-
+ libknet/threads_common.c                                      | 2 +-
+ libknet/threads_common.h                                      | 2 +-
+ libknet/threads_dsthandler.c                                  | 2 +-
+ libknet/threads_dsthandler.h                                  | 2 +-
+ libknet/threads_heartbeat.c                                   | 2 +-
+ libknet/threads_heartbeat.h                                   | 2 +-
+ libknet/threads_pmtud.c                                       | 2 +-
+ libknet/threads_pmtud.h                                       | 2 +-
+ libknet/threads_rx.c                                          | 2 +-
+ libknet/threads_rx.h                                          | 2 +-
+ libknet/threads_tx.c                                          | 2 +-
+ libknet/threads_tx.h                                          | 2 +-
+ libknet/transport_common.c                                    | 2 +-
+ libknet/transport_common.h                                    | 2 +-
+ libknet/transport_loopback.c                                  | 2 +-
+ libknet/transport_loopback.h                                  | 2 +-
+ libknet/transport_sctp.c                                      | 2 +-
+ libknet/transport_sctp.h                                      | 2 +-
+ libknet/transport_udp.c                                       | 2 +-
+ libknet/transport_udp.h                                       | 2 +-
+ libknet/transports.c                                          | 2 +-
+ libknet/transports.h                                          | 2 +-
+ libnozzle/Makefile.am                                         | 2 +-
+ libnozzle/internals.c                                         | 2 +-
+ libnozzle/internals.h                                         | 2 +-
+ libnozzle/libnozzle.c                                         | 2 +-
+ libnozzle/libnozzle.h                                         | 4 ++--
+ libnozzle/libnozzle.pc.in                                     | 2 +-
+ libnozzle/libnozzle_exported_syms                             | 2 +-
+ libnozzle/tests/Makefile.am                                   | 2 +-
+ libnozzle/tests/api-test-coverage                             | 2 +-
+ libnozzle/tests/api_nozzle_add_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_close.c                            | 2 +-
+ libnozzle/tests/api_nozzle_del_ip.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_fd.c                           | 2 +-
+ libnozzle/tests/api_nozzle_get_handle_by_name.c               | 2 +-
+ libnozzle/tests/api_nozzle_get_ips.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_get_name_by_handle.c               | 2 +-
+ libnozzle/tests/api_nozzle_open.c                             | 2 +-
+ libnozzle/tests/api_nozzle_run_updown.c                       | 2 +-
+ libnozzle/tests/api_nozzle_set_down.c                         | 2 +-
+ libnozzle/tests/api_nozzle_set_mac.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_mtu.c                          | 2 +-
+ libnozzle/tests/api_nozzle_set_up.c                           | 2 +-
+ libnozzle/tests/int_execute_bin_sh_command.c                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_false                  | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_true                   | 2 +-
+ libnozzle/tests/test-common.c                                 | 2 +-
+ libnozzle/tests/test-common.h                                 | 2 +-
+ man/Doxyfile-knet.in                                          | 2 +-
+ man/Doxyfile-nozzle.in                                        | 2 +-
+ man/Makefile.am                                               | 2 +-
+ man/api-to-man-page-coverage                                  | 2 +-
+ 188 files changed, 190 insertions(+), 190 deletions(-)
+
+diff --git a/COPYRIGHT b/COPYRIGHT
+index a6834ee2..6e23bea7 100644
+--- a/COPYRIGHT
++++ b/COPYRIGHT
+@@ -1,4 +1,4 @@
+-Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ 
+ Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+          Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/Makefile.am b/Makefile.am
+index 418b4b34..36680dcf 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/README b/README
+index 47089579..b8143f48 100644
+--- a/README
++++ b/README
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/autogen.sh b/autogen.sh
+index 073beddc..9707ec27 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index 7b8911f5..3eec3797 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index ff0c5347..d2318513 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -2,7 +2,7 @@
+ # Print a version string.
+ scriptversion=2018-08-31.20; # UTC
+ 
+-# Copyright (C) 2012-2020 Red Hat, Inc.
++# Copyright (C) 2012-2021 Red Hat, Inc.
+ # Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ #
+ # This program is free software: you can redistribute it and/or modify
+diff --git a/build-aux/release.mk b/build-aux/release.mk
+index 52db79e0..81c7ff8f 100644
+--- a/build-aux/release.mk
++++ b/build-aux/release.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/configure.ac b/configure.ac
+index 2ec8fd94..78a12786 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 12ea00a5..629e2353 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -1,7 +1,7 @@
+ ###############################################################################
+ ###############################################################################
+ ##
+-##  Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++##  Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+ ##
+ ##  This copyrighted material is made available to anyone wishing to use,
+ ##  modify, copy, or redistribute it subject to the terms and conditions
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index dd16fd40..ba4b5ad2 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/common.c b/libknet/common.c
+index 3cfd5042..08151fad 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/common.h b/libknet/common.h
+index 129be4c1..3d826ba4 100644
+--- a/libknet/common.h
++++ b/libknet/common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/compat.c b/libknet/compat.c
+index c31e85d7..8707250c 100644
+--- a/libknet/compat.c
++++ b/libknet/compat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compat.h b/libknet/compat.h
+index c2e0453d..201e1cac 100644
+--- a/libknet/compat.h
++++ b/libknet/compat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compress.c b/libknet/compress.c
+index ec6f16d8..21a665ed 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress.h b/libknet/compress.h
+index c0f28f19..b7adaa95 100644
+--- a/libknet/compress.h
++++ b/libknet/compress.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c
+index 70362157..d188e957 100644
+--- a/libknet/compress_bzip2.c
++++ b/libknet/compress_bzip2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c
+index 2a3a07d6..37cf5881 100644
+--- a/libknet/compress_lz4.c
++++ b/libknet/compress_lz4.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c
+index 607ec47e..c09d1e53 100644
+--- a/libknet/compress_lz4hc.c
++++ b/libknet/compress_lz4hc.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
+index ab9aa206..3d6ee886 100644
+--- a/libknet/compress_lzma.c
++++ b/libknet/compress_lzma.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c
+index bb109517..5dc560bc 100644
+--- a/libknet/compress_lzo2.c
++++ b/libknet/compress_lzo2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_model.h b/libknet/compress_model.h
+index 6a4ee6f9..2f9668f2 100644
+--- a/libknet/compress_model.h
++++ b/libknet/compress_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c
+index 5bb6003f..16e8c14d 100644
+--- a/libknet/compress_zlib.c
++++ b/libknet/compress_zlib.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index e64ff042..7e4b0027 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 28d29ef3..b97ba01d 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index 864ceba3..d84287cd 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index 0e6ccb4e..7a6425bd 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index d0b5e4f2..b2887ed8 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 47814c56..5c079428 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/handle.c b/libknet/handle.c
+index d4bd86c2..1691803b 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/handle_api.c b/libknet/handle_api.c
+index bf4324f5..443e26c9 100644
+--- a/libknet/handle_api.c
++++ b/libknet/handle_api.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.c b/libknet/host.c
+index e9e86eb8..97bb41a3 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.h b/libknet/host.h
+index 3312c8ba..ce61f46e 100644
+--- a/libknet/host.h
++++ b/libknet/host.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 22f654bb..5891f8fb 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 168a226d..ab4dbf25 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+@@ -19,7 +19,7 @@
+ /**
+  * @file libknet.h
+  * @brief kronosnet API include file
+- * @copyright Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Kronosnet is an advanced VPN system for High Availability applications.
+  */
+diff --git a/libknet/libknet.pc.in b/libknet/libknet.pc.in
+index e9960560..5962e8ab 100644
+--- a/libknet/libknet.pc.in
++++ b/libknet/libknet.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Federico Simoncelli <fsimon@kronosnet.org>
+ #
+diff --git a/libknet/libknet_exported_syms b/libknet/libknet_exported_syms
+index f2254b05..a8a7f284 100644
+--- a/libknet/libknet_exported_syms
++++ b/libknet/libknet_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libknet.so
+ #
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/links.c b/libknet/links.c
+index a127144a..75382f70 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links.h b/libknet/links.h
+index 1ba2b70a..f19f83ec 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index a24ea978..1612f15e 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 6f4f0263..9901c956 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 0f9c0f7e..68050bfc 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index 6d22daaa..6b208abb 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index 10092489..6bf35c6c 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index 78cc6bf8..baebee8c 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/logging.c b/libknet/logging.c
+index c01886dc..7a0f6483 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/logging.h b/libknet/logging.h
+index 2ee0da46..13b9e48a 100644
+--- a/libknet/logging.h
++++ b/libknet/logging.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index 25bba33f..7e19104c 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index 6395398e..0c0c6e34 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/onwire.c b/libknet/onwire.c
+index 146baa19..0e58513f 100644
+--- a/libknet/onwire.c
++++ b/libknet/onwire.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index 1040ea07..87bbcff1 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index aa948218..0c2b2c01 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 97afcfbe..7ef8b025 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-test-coverage b/libknet/tests/api-test-coverage
+index 4b6e223a..4d140b98 100755
+--- a/libknet/tests/api-test-coverage
++++ b/libknet/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index f7031082..3621bb57 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/api_knet_get_compress_list.c b/libknet/tests/api_knet_get_compress_list.c
+index 3db7ad9f..f393967f 100644
+--- a/libknet/tests/api_knet_get_compress_list.c
++++ b/libknet/tests/api_knet_get_compress_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_crypto_list.c b/libknet/tests/api_knet_get_crypto_list.c
+index 600fee69..3527ac35 100644
+--- a/libknet/tests/api_knet_get_crypto_list.c
++++ b/libknet/tests/api_knet_get_crypto_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_id_by_name.c b/libknet/tests/api_knet_get_transport_id_by_name.c
+index e30f7f8e..9adcefa3 100644
+--- a/libknet/tests/api_knet_get_transport_id_by_name.c
++++ b/libknet/tests/api_knet_get_transport_id_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_list.c b/libknet/tests/api_knet_get_transport_list.c
+index bdb57bc2..08c6c761 100644
+--- a/libknet/tests/api_knet_get_transport_list.c
++++ b/libknet/tests/api_knet_get_transport_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_name_by_id.c b/libknet/tests/api_knet_get_transport_name_by_id.c
+index ff6e325c..1957e994 100644
+--- a/libknet/tests/api_knet_get_transport_name_by_id.c
++++ b/libknet/tests/api_knet_get_transport_name_by_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_add_datafd.c b/libknet/tests/api_knet_handle_add_datafd.c
+index bf8d0d50..9bc4e4d1 100644
+--- a/libknet/tests/api_knet_handle_add_datafd.c
++++ b/libknet/tests/api_knet_handle_add_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index e87b3c39..6dd10396 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 3dbd1dd8..02c3882d 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index e02e9041..ff02451e 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+index cbd87e22..e9f048b0 100644
+--- a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
++++ b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto_set_config.c b/libknet/tests/api_knet_handle_crypto_set_config.c
+index b4e398ba..829d7bf1 100644
+--- a/libknet/tests/api_knet_handle_crypto_set_config.c
++++ b/libknet/tests/api_knet_handle_crypto_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_crypto_use_config.c b/libknet/tests/api_knet_handle_crypto_use_config.c
+index d9dd0040..29ed53fc 100644
+--- a/libknet/tests/api_knet_handle_crypto_use_config.c
++++ b/libknet/tests/api_knet_handle_crypto_use_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_access_lists.c b/libknet/tests/api_knet_handle_enable_access_lists.c
+index d80a2e25..f5e0e7ac 100644
+--- a/libknet/tests/api_knet_handle_enable_access_lists.c
++++ b/libknet/tests/api_knet_handle_enable_access_lists.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_filter.c b/libknet/tests/api_knet_handle_enable_filter.c
+index bc0a479a..50689ffc 100644
+--- a/libknet/tests/api_knet_handle_enable_filter.c
++++ b/libknet/tests/api_knet_handle_enable_filter.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_pmtud_notify.c b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+index 828df6fa..1152f740 100644
+--- a/libknet/tests/api_knet_handle_enable_pmtud_notify.c
++++ b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_enable_sock_notify.c b/libknet/tests/api_knet_handle_enable_sock_notify.c
+index eb71b018..d2b73a9c 100644
+--- a/libknet/tests/api_knet_handle_enable_sock_notify.c
++++ b/libknet/tests/api_knet_handle_enable_sock_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_free.c b/libknet/tests/api_knet_handle_free.c
+index 7344ea29..58aee851 100644
+--- a/libknet/tests/api_knet_handle_free.c
++++ b/libknet/tests/api_knet_handle_free.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_channel.c b/libknet/tests/api_knet_handle_get_channel.c
+index 3cab4a84..5d4ef8dc 100644
+--- a/libknet/tests/api_knet_handle_get_channel.c
++++ b/libknet/tests/api_knet_handle_get_channel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_datafd.c b/libknet/tests/api_knet_handle_get_datafd.c
+index a2fd6954..ea68af0b 100644
+--- a/libknet/tests/api_knet_handle_get_datafd.c
++++ b/libknet/tests/api_knet_handle_get_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_stats.c b/libknet/tests/api_knet_handle_get_stats.c
+index 38d3f081..010d8db0 100644
+--- a/libknet/tests/api_knet_handle_get_stats.c
++++ b/libknet/tests/api_knet_handle_get_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+index 7bd773c0..1912cc57 100644
+--- a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_new.c b/libknet/tests/api_knet_handle_new.c
+index eac7b6f3..c22450eb 100644
+--- a/libknet/tests/api_knet_handle_new.c
++++ b/libknet/tests/api_knet_handle_new.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_new_limit.c b/libknet/tests/api_knet_handle_new_limit.c
+index 840a6a6f..7b674131 100644
+--- a/libknet/tests/api_knet_handle_new_limit.c
++++ b/libknet/tests/api_knet_handle_new_limit.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_get.c b/libknet/tests/api_knet_handle_pmtud_get.c
+index 0e54f12b..376befa2 100644
+--- a/libknet/tests/api_knet_handle_pmtud_get.c
++++ b/libknet/tests/api_knet_handle_pmtud_get.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_getfreq.c b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+index 64ea6e1a..271051c2 100644
+--- a/libknet/tests/api_knet_handle_pmtud_getfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+index c0db7af2..0d808a33 100644
+--- a/libknet/tests/api_knet_handle_pmtud_set.c
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_setfreq.c b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+index 7023215a..c0fe2e78 100644
+--- a/libknet/tests/api_knet_handle_pmtud_setfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_remove_datafd.c b/libknet/tests/api_knet_handle_remove_datafd.c
+index a7b81376..0682c5d8 100644
+--- a/libknet/tests/api_knet_handle_remove_datafd.c
++++ b/libknet/tests/api_knet_handle_remove_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+index 3b929bb2..f8265e1f 100644
+--- a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_setfwd.c b/libknet/tests/api_knet_handle_setfwd.c
+index 2408b97b..3d2b9d50 100644
+--- a/libknet/tests/api_knet_handle_setfwd.c
++++ b/libknet/tests/api_knet_handle_setfwd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_add.c b/libknet/tests/api_knet_host_add.c
+index e6d66603..e6130e24 100644
+--- a/libknet/tests/api_knet_host_add.c
++++ b/libknet/tests/api_knet_host_add.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_enable_status_change_notify.c b/libknet/tests/api_knet_host_enable_status_change_notify.c
+index 6a81bb9e..fb694f7a 100644
+--- a/libknet/tests/api_knet_host_enable_status_change_notify.c
++++ b/libknet/tests/api_knet_host_enable_status_change_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_host_list.c b/libknet/tests/api_knet_host_get_host_list.c
+index 3a5988e4..a9c821fb 100644
+--- a/libknet/tests/api_knet_host_get_host_list.c
++++ b/libknet/tests/api_knet_host_get_host_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_id_by_host_name.c b/libknet/tests/api_knet_host_get_id_by_host_name.c
+index c3920510..356a9ac0 100644
+--- a/libknet/tests/api_knet_host_get_id_by_host_name.c
++++ b/libknet/tests/api_knet_host_get_id_by_host_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_name_by_host_id.c b/libknet/tests/api_knet_host_get_name_by_host_id.c
+index 81d39836..a4d7a069 100644
+--- a/libknet/tests/api_knet_host_get_name_by_host_id.c
++++ b/libknet/tests/api_knet_host_get_name_by_host_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_policy.c b/libknet/tests/api_knet_host_get_policy.c
+index 1fc025d4..da785c08 100644
+--- a/libknet/tests/api_knet_host_get_policy.c
++++ b/libknet/tests/api_knet_host_get_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_get_status.c b/libknet/tests/api_knet_host_get_status.c
+index 65dca278..d1861401 100644
+--- a/libknet/tests/api_knet_host_get_status.c
++++ b/libknet/tests/api_knet_host_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_remove.c b/libknet/tests/api_knet_host_remove.c
+index 13be5661..345151b1 100644
+--- a/libknet/tests/api_knet_host_remove.c
++++ b/libknet/tests/api_knet_host_remove.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_set_name.c b/libknet/tests/api_knet_host_set_name.c
+index c9261465..f390702e 100644
+--- a/libknet/tests/api_knet_host_set_name.c
++++ b/libknet/tests/api_knet_host_set_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_host_set_policy.c b/libknet/tests/api_knet_host_set_policy.c
+index 17780001..c15f4d25 100644
+--- a/libknet/tests/api_knet_host_set_policy.c
++++ b/libknet/tests/api_knet_host_set_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index 54b8208b..4f6f8c91 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index ce11071c..9b5cfbb8 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_clear_config.c b/libknet/tests/api_knet_link_clear_config.c
+index 0e98f2af..b7c7b14b 100644
+--- a/libknet/tests/api_knet_link_clear_config.c
++++ b/libknet/tests/api_knet_link_clear_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_config.c b/libknet/tests/api_knet_link_get_config.c
+index 6dc91244..441be547 100644
+--- a/libknet/tests/api_knet_link_get_config.c
++++ b/libknet/tests/api_knet_link_get_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_enable.c b/libknet/tests/api_knet_link_get_enable.c
+index 2098c9d0..fa14a240 100644
+--- a/libknet/tests/api_knet_link_get_enable.c
++++ b/libknet/tests/api_knet_link_get_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_link_list.c b/libknet/tests/api_knet_link_get_link_list.c
+index d59f4f7a..45000bb2 100644
+--- a/libknet/tests/api_knet_link_get_link_list.c
++++ b/libknet/tests/api_knet_link_get_link_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_ping_timers.c b/libknet/tests/api_knet_link_get_ping_timers.c
+index 889b4536..9853de5d 100644
+--- a/libknet/tests/api_knet_link_get_ping_timers.c
++++ b/libknet/tests/api_knet_link_get_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_pong_count.c b/libknet/tests/api_knet_link_get_pong_count.c
+index 2fa41572..856a19b2 100644
+--- a/libknet/tests/api_knet_link_get_pong_count.c
++++ b/libknet/tests/api_knet_link_get_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_priority.c b/libknet/tests/api_knet_link_get_priority.c
+index 16272964..b748dfb9 100644
+--- a/libknet/tests/api_knet_link_get_priority.c
++++ b/libknet/tests/api_knet_link_get_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_get_status.c b/libknet/tests/api_knet_link_get_status.c
+index 5a590383..b6517ce1 100644
+--- a/libknet/tests/api_knet_link_get_status.c
++++ b/libknet/tests/api_knet_link_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index 8b53019c..c0a4de3e 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index 180eaa4a..b3300dd1 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index fd0ecd93..2aab41b3 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_enable.c b/libknet/tests/api_knet_link_set_enable.c
+index b62acb35..2ddd311c 100644
+--- a/libknet/tests/api_knet_link_set_enable.c
++++ b/libknet/tests/api_knet_link_set_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_ping_timers.c b/libknet/tests/api_knet_link_set_ping_timers.c
+index ea5879e1..ca9b6eff 100644
+--- a/libknet/tests/api_knet_link_set_ping_timers.c
++++ b/libknet/tests/api_knet_link_set_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_pong_count.c b/libknet/tests/api_knet_link_set_pong_count.c
+index 151b6df4..c77572d0 100644
+--- a/libknet/tests/api_knet_link_set_pong_count.c
++++ b/libknet/tests/api_knet_link_set_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_link_set_priority.c b/libknet/tests/api_knet_link_set_priority.c
+index 003a900e..1f885881 100644
+--- a/libknet/tests/api_knet_link_set_priority.c
++++ b/libknet/tests/api_knet_link_set_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel.c b/libknet/tests/api_knet_log_get_loglevel.c
+index 09db26ab..1725bff0 100644
+--- a/libknet/tests/api_knet_log_get_loglevel.c
++++ b/libknet/tests/api_knet_log_get_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_id.c b/libknet/tests/api_knet_log_get_loglevel_id.c
+index 31d82f24..f4212124 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_id.c
++++ b/libknet/tests/api_knet_log_get_loglevel_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_name.c b/libknet/tests/api_knet_log_get_loglevel_name.c
+index 3375f214..713060d4 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_name.c
++++ b/libknet/tests/api_knet_log_get_loglevel_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_id.c b/libknet/tests/api_knet_log_get_subsystem_id.c
+index d631300c..0dd0ee0c 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_id.c
++++ b/libknet/tests/api_knet_log_get_subsystem_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_name.c b/libknet/tests/api_knet_log_get_subsystem_name.c
+index 08165c71..37bfa8b3 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_name.c
++++ b/libknet/tests/api_knet_log_get_subsystem_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_set_loglevel.c b/libknet/tests/api_knet_log_set_loglevel.c
+index f2501c5a..b5d75358 100644
+--- a/libknet/tests/api_knet_log_set_loglevel.c
++++ b/libknet/tests/api_knet_log_set_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_recv.c b/libknet/tests/api_knet_recv.c
+index 10419c8f..09718bdc 100644
+--- a/libknet/tests/api_knet_recv.c
++++ b/libknet/tests/api_knet_recv.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index e999d617..f4ffb3df 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index 64d174d8..36b9160f 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index 4b2982c9..2460afd3 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index 18aae92a..c3ef5047 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 2b5359a4..2e81e325 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index bcdf1cf3..235c1d51 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+index 1cabbcd7..7843664e 100644
+--- a/libknet/tests/fun_config_crypto.c
++++ b/libknet/tests/fun_config_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/fun_pmtud_crypto.c b/libknet/tests/fun_pmtud_crypto.c
+index bbd31451..e340f8d4 100644
+--- a/libknet/tests/fun_pmtud_crypto.c
++++ b/libknet/tests/fun_pmtud_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+index 945b349f..29a85a43 100644
+--- a/libknet/tests/int_links_acl_ip.c
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/tests/int_timediff.c b/libknet/tests/int_timediff.c
+index 5ec0ac20..40ac919c 100644
+--- a/libknet/tests/int_timediff.c
++++ b/libknet/tests/int_timediff.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index de68cc8a..a368efcf 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/pckt_test.c b/libknet/tests/pckt_test.c
+index 30798f3c..c43b27a8 100644
+--- a/libknet/tests/pckt_test.c
++++ b/libknet/tests/pckt_test.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 551bea57..06933010 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 4be816e6..6574b18d 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 029b2c6f..6af6826a 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index 56a9d759..dabef9f1 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 6e9b2492..9c9b269b 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.h b/libknet/threads_dsthandler.h
+index 5f43db07..084f9b67 100644
+--- a/libknet/threads_dsthandler.h
++++ b/libknet/threads_dsthandler.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index df3d5d17..6684952e 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.h b/libknet/threads_heartbeat.h
+index 11280555..da8b4b67 100644
+--- a/libknet/threads_heartbeat.h
++++ b/libknet/threads_heartbeat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index d49827aa..09f08b28 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.h b/libknet/threads_pmtud.h
+index c2c2c7b7..88d60df0 100644
+--- a/libknet/threads_pmtud.h
++++ b/libknet/threads_pmtud.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index ac2f46fc..75015ba2 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.h b/libknet/threads_rx.h
+index 95113c69..63f9571b 100644
+--- a/libknet/threads_rx.h
++++ b/libknet/threads_rx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 2f69991b..486dbe13 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.h b/libknet/threads_tx.h
+index 5f3513f0..958f4f8e 100644
+--- a/libknet/threads_tx.h
++++ b/libknet/threads_tx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 00036974..69cd0227 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 8360ed9f..120e4760 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index dfd6384d..34e7c980 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index 636034bb..f8e4e5a7 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index ecc40c23..f3a03f16 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index 3cd9740d..74f6023a 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index fe6c0968..7bdd5f18 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index e2aa2dcd..69a84995 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 1ec0aafc..e9a858cf 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 51063864..7dfe63ee 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 63757635..bb84f24a 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index be943e44..ce9dc293 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 6f7ab3af..43794de1 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 5e9d6e44..da17e2bd 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index 64bf8094..d8e644a1 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -16,7 +16,7 @@
+  *
+  * @file libnozzle.h
+  * @brief tap interfaces management API include file
+- * @copyright Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+diff --git a/libnozzle/libnozzle.pc.in b/libnozzle/libnozzle.pc.in
+index 910a36a4..724a3f5d 100644
+--- a/libnozzle/libnozzle.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/libnozzle_exported_syms b/libnozzle/libnozzle_exported_syms
+index bb7b36d2..c44980f0 100644
+--- a/libnozzle/libnozzle_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libnozzle.so
+ #
+-# Copyright (C) 2011-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2011-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 8da00dd5..b5e605ee 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index e6d762d7..0b5b2fc2 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+index af588c49..8491e25e 100644
+--- a/libnozzle/tests/api_nozzle_add_ip.c
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index e7b456b4..27885b02 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+index 85bc3c0e..9f67a3ee 100644
+--- a/libnozzle/tests/api_nozzle_del_ip.c
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index b84013ba..6b12724b 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+index 8984ce86..5db12936 100644
+--- a/libnozzle/tests/api_nozzle_get_handle_by_name.c
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index f306ccc8..ff96698b 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index c835ab65..3c99bf5f 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 1790172f..9f009042 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index 896266ef..942f997d 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index be26df46..dccaf8b4 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index d470515f..b7522765 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index 2ee9bdcb..c0eb6db2 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index 65a89219..31ebb4cf 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index 3e295297..b69d1ecf 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index b2f891a3..6d30fcd9 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index 91a2e01f..8fb10828 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_false b/libnozzle/tests/nozzle_run_updown_exit_false
+index 2ef4ee90..7da20628 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_false
++++ b/libnozzle/tests/nozzle_run_updown_exit_false
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_true b/libnozzle/tests/nozzle_run_updown_exit_true
+index 8eda37d8..c40177bb 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_true
++++ b/libnozzle/tests/nozzle_run_updown_exit_true
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+ #
+-# Copyright (C) 2010-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index 2a9a8a29..21663b18 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index dc2ea89f..b96349ff 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/man/Doxyfile-knet.in b/man/Doxyfile-knet.in
+index e703d757..b7c27dc6 100644
+--- a/man/Doxyfile-knet.in
++++ b/man/Doxyfile-knet.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Doxyfile-nozzle.in b/man/Doxyfile-nozzle.in
+index bcc4f9f7..65c68bff 100644
+--- a/man/Doxyfile-nozzle.in
++++ b/man/Doxyfile-nozzle.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 9f3135f9..7852ef67 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+index 76729367..a60886e0 100755
+--- a/man/api-to-man-page-coverage
++++ b/man/api-to-man-page-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2019-2020 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0408-handle-validate-handle-in-public-API.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0408-handle-validate-handle-in-public-API.patch
new file mode 100644
index 000000000..d3562131e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0408-handle-validate-handle-in-public-API.patch
@@ -0,0 +1,902 @@ 
+From fd286950331f99606987c6f30b4065cfb580d3e7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 11 Apr 2021 17:09:59 +0200
+Subject: [PATCH] [handle] validate handle in public API
+
+- add _is_valid_handle() function to verify if a handle
+  is known, via qb_list*
+
+- change all (and only) public API to use _is_valid_handle().
+
+- move library config bits to lib_config.c and keep
+  header bit in internal.h.
+  this is more of a commodity need to simplify
+  accessability of above function to the test suite
+  at link time.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/Makefile.am                  |  1 +
+ libknet/compress.c                   |  3 +-
+ libknet/crypto.c                     |  9 +--
+ libknet/handle.c                     | 57 +++++-------------
+ libknet/handle_api.c                 | 30 ++++------
+ libknet/host.c                       | 30 ++++------
+ libknet/internals.h                  | 15 +++++
+ libknet/lib_config.c                 | 86 ++++++++++++++++++++++++++++
+ libknet/links.c                      | 51 ++++++-----------
+ libknet/logging.c                    |  6 +-
+ libknet/tests/Makefile.am            | 11 +++-
+ libknet/tests/api_knet_handle_free.c | 11 +++-
+ libknet/threads_pmtud.c              | 15 ++---
+ libknet/threads_rx.c                 |  3 +-
+ libknet/threads_tx.c                 |  6 +-
+ libknet/transports.c                 |  6 +-
+ 16 files changed, 188 insertions(+), 152 deletions(-)
+ create mode 100644 libknet/lib_config.c
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index ba4b5ad2..7b2b6777 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -31,6 +31,7 @@ sources			= \
+ 			  handle.c \
+ 			  handle_api.c \
+ 			  host.c \
++			  lib_config.c \
+ 			  links.c \
+ 			  links_acl.c \
+ 			  links_acl_ip.c \
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 21a665ed..d1673ca5 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -490,8 +490,7 @@ int knet_handle_compress(knet_handle_t knet_h, struct knet_handle_compress_cfg *
+ 	int savederrno = 0;
+ 	int err = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index b97ba01d..22759f31 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -299,8 +299,7 @@ static int _knet_handle_crypto_set_config(knet_handle_t knet_h,
+ 	int savederrno = 0;
+ 	int err = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -378,8 +377,7 @@ int knet_handle_crypto_rx_clear_traffic(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -413,8 +411,7 @@ int knet_handle_crypto_use_config(knet_handle_t knet_h,
+ 	int savederrno = 0;
+ 	int err = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 1691803b..0c88716d 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -34,40 +34,6 @@
+ #include "transport_common.h"
+ #include "logging.h"
+ 
+-static pthread_mutex_t handle_config_mutex = PTHREAD_MUTEX_INITIALIZER;
+-
+-pthread_rwlock_t shlib_rwlock;
+-static uint8_t shlib_wrlock_init = 0;
+-
+-static uint32_t knet_ref = 0;
+-
+-static int _init_shlib_tracker(knet_handle_t knet_h)
+-{
+-	int savederrno = 0;
+-
+-	if (!shlib_wrlock_init) {
+-		savederrno = pthread_rwlock_init(&shlib_rwlock, NULL);
+-		if (savederrno) {
+-			log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize shared lib rwlock: %s",
+-				strerror(savederrno));
+-			errno = savederrno;
+-			return -1;
+-		}
+-		shlib_wrlock_init = 1;
+-	}
+-
+-	return 0;
+-}
+-
+-static void _fini_shlib_tracker(void)
+-{
+-	if (knet_ref == 0) {
+-		pthread_rwlock_destroy(&shlib_rwlock);
+-		shlib_wrlock_init = 0;
+-	}
+-	return;
+-}
+-
+ static int _init_locks(knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
+@@ -632,7 +598,7 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 	knet_h->stats.rx_crypt_time_min = UINT64_MAX;
+ 
+ 	/*
+-	 * init global shlib tracker
++	 * init global shared bits
+ 	 */
+ 	savederrno = pthread_mutex_lock(&handle_config_mutex);
+ 	if (savederrno) {
+@@ -644,8 +610,16 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 		return NULL;
+ 	}
+ 
+-	knet_ref++;
++	if (!handle_list_init) {
++		qb_list_init(&handle_list.head);
++		handle_list_init = 1;
++	}
++
++	qb_list_add(&knet_h->list, &handle_list.head);
+ 
++	/*
++	 * init global shlib tracker
++	 */
+ 	if (_init_shlib_tracker(knet_h) < 0) {
+ 		savederrno = errno;
+ 		log_err(knet_h, KNET_SUB_HANDLE, "Unable to init handle tracker: %s",
+@@ -738,8 +712,7 @@ int knet_handle_free(knet_handle_t knet_h)
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -774,14 +747,14 @@ int knet_handle_free(knet_handle_t knet_h)
+ 	compress_fini(knet_h, 1);
+ 	_destroy_locks(knet_h);
+ 
+-	free(knet_h);
+-	knet_h = NULL;
+-
+ 	(void)pthread_mutex_lock(&handle_config_mutex);
+-	knet_ref--;
++	qb_list_del(&knet_h->list);
+ 	_fini_shlib_tracker();
+ 	pthread_mutex_unlock(&handle_config_mutex);
+ 
++	free(knet_h);
++	knet_h = NULL;
++
+ 	errno = 0;
+ 	return 0;
+ }
+diff --git a/libknet/handle_api.c b/libknet/handle_api.c
+index 443e26c9..30fec2cf 100644
+--- a/libknet/handle_api.c
++++ b/libknet/handle_api.c
+@@ -35,8 +35,7 @@ int knet_handle_enable_sock_notify(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -68,8 +67,7 @@ int knet_handle_add_datafd(knet_handle_t knet_h, int *datafd, int8_t *channel)
+ 	int i;
+ 	struct epoll_event ev;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -210,8 +208,7 @@ int knet_handle_remove_datafd(knet_handle_t knet_h, int datafd)
+ 	int i;
+ 	struct epoll_event ev;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -271,8 +268,7 @@ int knet_handle_get_datafd(knet_handle_t knet_h, const int8_t channel, int *data
+ {
+ 	int err = 0, savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -313,8 +309,7 @@ int knet_handle_get_channel(knet_handle_t knet_h, const int datafd, int8_t *chan
+ 	int err = 0, savederrno = 0;
+ 	int i;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -373,8 +368,7 @@ int knet_handle_enable_filter(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -404,8 +398,7 @@ int knet_handle_setfwd(knet_handle_t knet_h, unsigned int enabled)
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -481,8 +474,7 @@ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats,
+ {
+ 	int err = 0, savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -536,8 +528,7 @@ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option)
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -569,8 +560,7 @@ int knet_handle_enable_access_lists(knet_handle_t knet_h, unsigned int enabled)
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/host.c b/libknet/host.c
+index 97bb41a3..46183b84 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -37,8 +37,7 @@ int knet_host_add(knet_handle_t knet_h, knet_node_id_t host_id)
+ 	struct knet_host *host = NULL;
+ 	uint8_t link_idx;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -117,8 +116,7 @@ int knet_host_remove(knet_handle_t knet_h, knet_node_id_t host_id)
+ 	struct knet_host *host, *removed;
+ 	uint8_t link_idx;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -188,8 +186,7 @@ int knet_host_set_name(knet_handle_t knet_h, knet_node_id_t host_id, const char
+ 	int savederrno = 0, err = 0;
+ 	struct knet_host *host;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -248,8 +245,7 @@ int knet_host_get_name_by_host_id(knet_handle_t knet_h, knet_node_id_t host_id,
+ {
+ 	int savederrno = 0, err = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -287,8 +283,7 @@ int knet_host_get_id_by_host_name(knet_handle_t knet_h, const char *name,
+ 	int savederrno = 0, err = 0, found = 0;
+ 	struct knet_host *host;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -333,8 +328,7 @@ int knet_host_get_host_list(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -364,8 +358,7 @@ int knet_host_set_policy(knet_handle_t knet_h, knet_node_id_t host_id,
+ 	int savederrno = 0, err = 0;
+ 	uint8_t old_policy;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -414,8 +407,7 @@ int knet_host_get_policy(knet_handle_t knet_h, knet_node_id_t host_id,
+ {
+ 	int savederrno = 0, err = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -454,8 +446,7 @@ int knet_host_get_status(knet_handle_t knet_h, knet_node_id_t host_id,
+ 	int savederrno = 0, err = 0;
+ 	struct knet_host *host;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -500,8 +491,7 @@ int knet_host_enable_status_change_notify(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 5891f8fb..69d520f0 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -267,9 +267,24 @@ struct knet_handle {
+ 		int errorno);
+ 	int fini_in_progress;
+ 	uint64_t flags;
++	struct qb_list_head list;
+ };
+ 
++struct handle_tracker {
++	struct qb_list_head head;
++};
++
++/*
++ * lib_config stuff shared across everything
++ */
+ extern pthread_rwlock_t shlib_rwlock;       /* global shared lib load lock */
++extern pthread_mutex_t handle_config_mutex;
++
++extern struct handle_tracker handle_list;
++extern uint8_t handle_list_init;
++int _is_valid_handle(knet_handle_t knet_h);
++int _init_shlib_tracker(knet_handle_t knet_h);
++void _fini_shlib_tracker(void);
+ 
+ /*
+  * NOTE: every single operation must be implementend
+diff --git a/libknet/lib_config.c b/libknet/lib_config.c
+new file mode 100644
+index 00000000..b7d28590
+--- /dev/null
++++ b/libknet/lib_config.c
+@@ -0,0 +1,86 @@
++/*
++ * Copyright (C) 2021 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
++ *
++ * This software licensed under LGPL-2.0+
++ */
++
++#include "config.h"
++
++#include <pthread.h>
++#include <string.h>
++#include <errno.h>
++
++#include "internals.h"
++#include "logging.h"
++
++pthread_mutex_t handle_config_mutex = PTHREAD_MUTEX_INITIALIZER;
++
++struct handle_tracker handle_list;
++uint8_t handle_list_init = 0;
++
++int _is_valid_handle(knet_handle_t knet_h)
++{
++	int found = 0;
++	int savederrno = 0;
++	knet_handle_t temp = NULL;
++
++	/*
++	 * we are validating the handle, hence we cannot use
++	 * the handle for logging purposes
++	 */
++	savederrno = pthread_mutex_lock(&handle_config_mutex);
++	if (savederrno) {
++		errno = savederrno;
++		return 0;
++	}
++
++	errno = EINVAL;
++	/*
++	 * this is to protect against knet_handle_free being called
++	 * before knet_handle_new that initialize the list struct
++	 */
++	if (handle_list_init) {
++		qb_list_for_each_entry(temp, &handle_list.head, list) {
++			if (temp == knet_h) {
++				found = 1;
++				errno = 0;
++			}
++		}
++	}
++
++	pthread_mutex_unlock(&handle_config_mutex);
++
++	return found;
++}
++
++pthread_rwlock_t shlib_rwlock;
++static uint8_t shlib_wrlock_init = 0;
++
++int _init_shlib_tracker(knet_handle_t knet_h)
++{
++	int savederrno = 0;
++
++	if (!shlib_wrlock_init) {
++		savederrno = pthread_rwlock_init(&shlib_rwlock, NULL);
++		if (savederrno) {
++			log_err(knet_h, KNET_SUB_HANDLE, "Unable to initialize shared lib rwlock: %s",
++				strerror(savederrno));
++			errno = savederrno;
++			return -1;
++		}
++		shlib_wrlock_init = 1;
++	}
++
++	return 0;
++}
++
++void _fini_shlib_tracker(void)
++{
++	if (qb_list_empty(&handle_list.head)) {
++		pthread_rwlock_destroy(&shlib_rwlock);
++		shlib_wrlock_init = 0;
++	}
++	return;
++}
+diff --git a/libknet/links.c b/libknet/links.c
+index 75382f70..91aeff48 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -106,8 +106,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -339,8 +338,7 @@ int knet_link_get_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -428,8 +426,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	int sock;
+ 	uint8_t transport;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -543,8 +540,7 @@ int knet_link_set_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -613,8 +609,7 @@ int knet_link_get_enable(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -670,8 +665,7 @@ int knet_link_set_pong_count(knet_handle_t knet_h, knet_node_id_t host_id, uint8
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -731,8 +725,7 @@ int knet_link_get_pong_count(knet_handle_t knet_h, knet_node_id_t host_id, uint8
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -788,8 +781,7 @@ int knet_link_set_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -861,8 +853,7 @@ int knet_link_get_ping_timers(knet_handle_t knet_h, knet_node_id_t host_id, uint
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -931,8 +922,7 @@ int knet_link_set_priority(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	struct knet_link *link;
+ 	uint8_t old_priority;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1004,8 +994,7 @@ int knet_link_get_priority(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1061,8 +1050,7 @@ int knet_link_get_link_list(knet_handle_t knet_h, knet_node_id_t host_id,
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1117,8 +1105,7 @@ int knet_link_get_status(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1221,8 +1208,7 @@ int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1316,8 +1302,7 @@ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1410,8 +1395,7 @@ int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -1501,8 +1485,7 @@ int knet_link_clear_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t li
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 7a0f6483..3f5379f6 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -138,8 +138,7 @@ int knet_log_set_loglevel(knet_handle_t knet_h, uint8_t subsystem,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -173,8 +172,7 @@ int knet_log_get_loglevel(knet_handle_t knet_h, uint8_t subsystem,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 0c2b2c01..60c83bda 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -87,7 +87,8 @@ int_links_acl_ip_test_SOURCES = int_links_acl_ip.c \
+ 				../transport_udp.c \
+ 				../links_acl.c \
+ 				../links_acl_ip.c \
+-				../links_acl_loopback.c
++				../links_acl_loopback.c \
++				../lib_config.c
+ 
+ int_timediff_test_SOURCES = int_timediff.c
+ 
+@@ -98,11 +99,15 @@ knet_bench_test_SOURCES	= knet_bench.c \
+ 			  ../compat.c \
+ 			  ../transport_common.c \
+ 			  ../threads_common.c \
+-			  ../onwire.c
++			  ../onwire.c \
++			  ../lib_config.c
+ 
+ fun_pmtud_crypto_test_SOURCES = fun_pmtud_crypto.c \
+ 				test-common.c \
+-				../onwire.c
++				../onwire.c \
++				../logging.c \
++				../threads_common.c \
++				../lib_config.c
+ 
+ fun_config_crypto_test_SOURCES = fun_config_crypto.c \
+ 				 test-common.c
+diff --git a/libknet/tests/api_knet_handle_free.c b/libknet/tests/api_knet_handle_free.c
+index 58aee851..5e1d2053 100644
+--- a/libknet/tests/api_knet_handle_free.c
++++ b/libknet/tests/api_knet_handle_free.c
+@@ -26,7 +26,7 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	printf("Test knet_handle_free with invalid knet_h\n");
++	printf("Test knet_handle_free with invalid knet_h (part 1)\n");
+ 
+ 	if ((!knet_handle_free(NULL)) || (errno != EINVAL)) {
+ 		printf("knet_handle_free failed to detect invalid parameter\n");
+@@ -62,6 +62,15 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
++	printf("Test knet_handle_free with invalid knet_h (part 2)\n");
++
++	if ((!knet_handle_free(knet_h + 1)) || (errno != EINVAL)) {
++		printf("knet_handle_free failed to detect invalid parameter\n");
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	if (knet_handle_free(knet_h) < 0) {
+ 		printf("knet_handle_free failed: %s\n", strerror(errno));
+ 		flush_logs(logfds[0], stdout);
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 09f08b28..4aba9330 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -645,8 +645,7 @@ int knet_handle_pmtud_getfreq(knet_handle_t knet_h, unsigned int *interval)
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -675,8 +674,7 @@ int knet_handle_pmtud_setfreq(knet_handle_t knet_h, unsigned int interval)
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -710,8 +708,7 @@ int knet_handle_enable_pmtud_notify(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -742,8 +739,7 @@ int knet_handle_pmtud_set(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -777,8 +773,7 @@ int knet_handle_pmtud_get(knet_handle_t knet_h,
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 75015ba2..d03ed35e 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -990,8 +990,7 @@ ssize_t knet_recv(knet_handle_t knet_h, char *buff, const size_t buff_len, const
+ 	ssize_t err = 0;
+ 	struct iovec iov_in;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 486dbe13..9f16706f 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -749,8 +749,7 @@ int knet_send_sync(knet_handle_t knet_h, const char *buff, const size_t buff_len
+ {
+ 	int savederrno = 0, err = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -821,8 +820,7 @@ ssize_t knet_send(knet_handle_t knet_h, const char *buff, const size_t buff_len,
+ 	ssize_t err = 0;
+ 	struct iovec iov_out[1];
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+diff --git a/libknet/transports.c b/libknet/transports.c
+index e9a858cf..2f18ec81 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -234,8 +234,7 @@ int knet_handle_set_transport_reconnect_interval(knet_handle_t knet_h, uint32_t
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
+@@ -271,8 +270,7 @@ int knet_handle_get_transport_reconnect_interval(knet_handle_t knet_h, uint32_t
+ {
+ 	int savederrno = 0;
+ 
+-	if (!knet_h) {
+-		errno = EINVAL;
++	if (!_is_valid_handle(knet_h)) {
+ 		return -1;
+ 	}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0409-nozzle-Remove-inet_ntoa-call.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0409-nozzle-Remove-inet_ntoa-call.patch
new file mode 100644
index 000000000..c7a66ecdd
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0409-nozzle-Remove-inet_ntoa-call.patch
@@ -0,0 +1,32 @@ 
+From efac048993237e9141d588b980ba8a251992e038 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 19 Apr 2021 09:43:51 +0100
+Subject: [PATCH] [nozzle] Remove inet_ntoa() call
+
+inet_ntoa() is deprecated in favour of inet_ntop() (see man page for
+inet_ntop()).
+---
+ libnozzle/internals.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index ce9dc293..4df50d7b 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -141,6 +141,7 @@ char *generate_v4_broadcast(const char *ipaddr, const char *prefix)
+ 	struct in_addr mask;
+ 	struct in_addr broadcast;
+ 	struct in_addr address;
++	char buf[INET6_ADDRSTRLEN];
+ 
+ 	prefix_len = atoi(prefix);
+ 
+@@ -155,7 +156,7 @@ char *generate_v4_broadcast(const char *ipaddr, const char *prefix)
+ 	memset(&broadcast, 0, sizeof(broadcast));
+ 	broadcast.s_addr = (address.s_addr & mask.s_addr) | ~mask.s_addr;
+ 
+-	return strdup(inet_ntoa(broadcast));
++	return strdup(inet_ntop(AF_INET, (void *)&broadcast, buf, sizeof(buf)));
+ }
+ 
+ int find_ip(nozzle_t nozzle,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0410-lib-Don-t-use-rpath.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0410-lib-Don-t-use-rpath.patch
new file mode 100644
index 000000000..5169cad15
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0410-lib-Don-t-use-rpath.patch
@@ -0,0 +1,237 @@ 
+From ede55247d0bf1aa200b166cc378bdc1a7b1fc2de Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Fri, 23 Apr 2021 08:17:36 +0100
+Subject: [PATCH] [lib] Don't use -rpath
+
+rpath seems, understandably, to annoy some analysis tools. We
+use it to locate the crypto & compression plugins but libknet also needs
+to use the plugins from the build-tree when running tests.
+
+A simple way to do this is have the plugin directory as part of the knet
+handle then we can override it in the test suite, which already does
+'illegal' accesses to some handle fields.
+
+OK, it's not the MOST elegant way of doing this perhaps, but it is
+simple and effective.
+---
+ libknet/Makefile.am         |   4 +-
+ libknet/common.c            |   5 +-
+ libknet/handle.c            |   5 ++
+ libknet/internals.h         |   1 +
+ libknet/tests/test-common.c | 101 ++++++++++++++++++++++++++++++++++++
+ 5 files changed, 113 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 7b2b6777..555a6c52 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -91,13 +91,13 @@ libknet_la_SOURCES	= $(sources)
+ 
+ AM_CFLAGS		+= $(libqb_CFLAGS)
+ 
+-libknet_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS)
++libknet_la_CFLAGS	= $(AM_CFLAGS) $(PTHREAD_CFLAGS) \
++			  -DPLUGINPATH="\"$(pkglibdir)\""
+ 
+ EXTRA_libknet_la_DEPENDENCIES	= $(SYMFILE)
+ 
+ libknet_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 			  -Wl,--version-script=$(srcdir)/$(SYMFILE) \
+-			  -Wl,-rpath=$(pkglibdir) \
+ 			  -version-info $(libversion)
+ 
+ libknet_la_LIBADD	= $(PTHREAD_LIBS) $(dl_LIBS) $(rt_LIBS) $(m_LIBS)
+diff --git a/libknet/common.c b/libknet/common.c
+index 08151fad..9bc3396e 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -91,8 +91,11 @@ static void *open_lib(knet_handle_t knet_h, const char *libname, int extra_flags
+ 	 * clear any pending error
+ 	 */
+ 	dlerror();
++	strncpy(path, knet_h->plugin_path, sizeof(path)-1);
++	strncat(path, "/", sizeof(path)-1);
++	strncat(path, libname, sizeof(path)-strlen(knet_h->plugin_path)-2);
+ 
+-	ret = dlopen(libname, RTLD_NOW | RTLD_GLOBAL | extra_flags);
++	ret = dlopen(path, RTLD_NOW | RTLD_GLOBAL | extra_flags);
+ 	if (!ret) {
+ 		error = dlerror();
+ 		if (error) {
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 0c88716d..54edf1b9 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -588,6 +588,11 @@ knet_handle_t knet_handle_new_ex(knet_node_id_t host_id,
+ 	 */
+ 	knet_h->reconnect_int = KNET_TRANSPORT_DEFAULT_RECONNECT_INTERVAL;
+ 
++	/*
++	 * Set the default path for plugins
++	 */
++	knet_h->plugin_path = PLUGINPATH;
++
+ 	/*
+ 	 * Set 'min' stats to the maximum value so the
+ 	 * first value we get is always less
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 69d520f0..6c26965d 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -268,6 +268,7 @@ struct knet_handle {
+ 	int fini_in_progress;
+ 	uint64_t flags;
+ 	struct qb_list_head list;
++	const char *plugin_path;
+ };
+ 
+ struct handle_tracker {
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 06933010..e55f5f73 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -1,3 +1,4 @@
++
+ /*
+  * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
+  *
+@@ -17,6 +18,7 @@
+ #include <sys/wait.h>
+ #include <fcntl.h>
+ #include <pthread.h>
++#include <dirent.h>
+ #include <sys/select.h>
+ 
+ #include "libknet.h"
+@@ -33,6 +35,7 @@ struct log_thread_data {
+ 	FILE *std;
+ };
+ static struct log_thread_data data;
++static char plugin_path[PATH_MAX];
+ 
+ static int _read_pipe(int fd, char **file, size_t *length)
+ {
+@@ -348,11 +351,104 @@ int start_logging(FILE *std)
+ 	return log_fds[1];
+ }
+ 
++static int dir_filter(const struct dirent *dname)
++{
++	if ( (strcmp(dname->d_name + strlen(dname->d_name)-3, ".so") == 0) &&
++	    ((strncmp(dname->d_name,"crypto", 6) == 0) ||
++	     (strncmp(dname->d_name,"compress", 8) == 0))) {
++		return 1;
++	}
++	return 0;
++}
++
++/* Make sure the proposed plugin path has at least 1 of each plugin available
++   - just as a sanity check really */
++static int contains_plugins(char *path)
++{
++	struct dirent **namelist;
++	int n,i;
++	size_t j;
++	struct knet_compress_info compress_list[256];
++	struct knet_crypto_info crypto_list[256];
++	size_t num_compress, num_crypto;
++	size_t compress_found = 0;
++	size_t crypto_found = 0;
++
++	if (knet_get_compress_list(compress_list, &num_compress) == -1) {
++		return 0;
++	}
++	if (knet_get_crypto_list(crypto_list, &num_crypto) == -1) {
++		return 0;
++	}
++
++	n = scandir(path, &namelist, dir_filter, alphasort);
++	if (n == -1) {
++		return 0;
++	}
++
++	/* Look for plugins in the list */
++	for (i=0; i<n; i++) {
++		for (j=0; j<num_crypto; j++) {
++			if (strlen(namelist[i]->d_name) >= 7 &&
++			    strncmp(crypto_list[j].name, namelist[i]->d_name+7,
++				    strlen(crypto_list[j].name)) == 0) {
++				crypto_found++;
++			}
++		}
++		for (j=0; j<num_compress; j++) {
++			if (strlen(namelist[i]->d_name) >= 9 &&
++			    strncmp(compress_list[j].name, namelist[i]->d_name+9,
++				    strlen(compress_list[j].name)) == 0) {
++				compress_found++;
++			}
++		}
++		free(namelist[i]);
++	}
++	free(namelist);
++	/* If at least one plugin was found (or none were built) */
++	if ((crypto_found || num_crypto == 0) &&
++	    (compress_found || num_compress == 0)) {
++		return 1;
++	} else {
++		return 0;
++	}
++}
++
++
++/* libtool sets LD_LIBRARY_PATH to the build tree when running test in-tree */
++static char *find_plugins_path(void)
++{
++	char *ld_libs_env = getenv("LD_LIBRARY_PATH");
++	if (ld_libs_env) {
++		char *ld_libs = strdup(ld_libs_env);
++		char *str = strtok(ld_libs, ":");
++		while (str) {
++			if (contains_plugins(str)) {
++				strncpy(plugin_path, str, sizeof(plugin_path)-1);
++				free(ld_libs);
++				printf("Using plugins from %s\n", plugin_path);
++				return plugin_path;
++			}
++			str = strtok(NULL, ":");
++		}
++		free(ld_libs);
++	}
++	return NULL;
++}
++
++
+ knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level)
+ {
+ 	knet_handle_t knet_h = knet_handle_new_ex(1, logfds[1], log_level, 0);
++	char *plugins_path;
+ 
+ 	if (knet_h) {
++		printf("knet_handle_new at %p\n", knet_h);
++		plugins_path = find_plugins_path();
++		/* Use plugins from the build tree */
++		if (plugins_path) {
++			knet_h->plugin_path = plugins_path;
++		}
+ 		return knet_h;
+ 	} else {
+ 		printf("knet_handle_new failed: %s\n", strerror(errno));
+@@ -553,6 +649,7 @@ try_again:
+ void knet_handle_start_nodes(knet_handle_t knet_h[], uint8_t numnodes, int logfds[2], uint8_t log_level)
+ {
+ 	uint8_t i;
++	char *plugins_path = find_plugins_path();
+ 
+ 	for (i = 1; i <= numnodes; i++) {
+ 		knet_h[i] = knet_handle_new_ex(i, logfds[1], log_level, 0);
+@@ -562,6 +659,10 @@ void knet_handle_start_nodes(knet_handle_t knet_h[], uint8_t numnodes, int logfd
+ 		} else {
+ 			printf("knet_h[%u] at %p\n", i, knet_h[i]);
+ 		}
++		/* Use plugins from the build tree */
++		if (plugins_path) {
++			knet_h[i]->plugin_path = plugins_path;
++		}
+ 	}
+ 
+ 	if (i < numnodes) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0411-nozzle-fix-nozzle_up-on-FreeBSD.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0411-nozzle-fix-nozzle_up-on-FreeBSD.patch
new file mode 100644
index 000000000..f63aef0f3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0411-nozzle-fix-nozzle_up-on-FreeBSD.patch
@@ -0,0 +1,64 @@ 
+From cc30328c8dffdd298ee9d13607e902c686143dac Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 26 Apr 2021 14:38:10 +0100
+Subject: [PATCH] [nozzle] fix nozzle_up() on FreeBSD
+
+TBH I'm not sure how this ever worked, as we never seemed to call
+SIOCIFCREATE, but this also fixes the race when the tests are run -j4
+(or higher)
+---
+ libnozzle/libnozzle.c | 18 ++++++++++++++++++
+ 1 file changed, 18 insertions(+)
+
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index da17e2bd..9e259d1c 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -42,6 +42,7 @@
+ #endif
+ #ifdef KNET_BSD
+ #include <net/if_dl.h>
++#include <sys/sockio.h>
+ #endif
+ 
+ #include "libnozzle.h"
+@@ -394,6 +395,7 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ 	uint16_t i;
+ 	long int nozzlenum = 0;
+ 	char curnozzle[IFNAMSIZ];
++	struct ifreq ifr;
+ #endif
+ 
+ 	if (devname == NULL) {
+@@ -505,15 +507,31 @@ nozzle_t nozzle_open(char *devname, size_t devname_size, const char *updownpath)
+ #else
+ 		for (i = 0; i < 256; i++) {
+ #endif
++			memset(&ifr, 0, sizeof(struct ifreq));
++
++			snprintf(curnozzle, sizeof(curnozzle) - 1, "tap%u", i);
++			memmove(ifr.ifr_name, curnozzle, IFNAMSIZ);
++			if (ioctl(lib_cfg.ioctlfd, SIOCIFCREATE2, &ifr) < 0) {
++			        continue;
++			}
++
+ 			snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/tap%u", i);
+ 			nozzle->fd = open(curnozzle, O_RDWR);
+ 			savederrno = errno;
+ 			if (nozzle->fd > 0) {
+ 				break;
+ 			}
++			/* For some reason we can't open that device, keep trying
++			   but don't leave debris */
++			(void)ioctl(lib_cfg.ioctlfd, SIOCIFDESTROY, &ifr);
+ 		}
+ 		snprintf(curnozzle, sizeof(curnozzle) -1 , "tap%u", i);
+ 	} else {
++		memmove(ifr.ifr_name, devname, IFNAMSIZ);
++		if (ioctl(lib_cfg.ioctlfd, SIOCIFCREATE2, &ifr) < 0) {
++			goto out_error;
++		}
++
+ 		snprintf(curnozzle, sizeof(curnozzle) - 1, "/dev/%s", devname);
+ 		nozzle->fd = open(curnozzle, O_RDWR);
+ 		savederrno = errno;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0412-coverity-fix-2-buffer-initialization-potential-issue.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0412-coverity-fix-2-buffer-initialization-potential-issue.patch
new file mode 100644
index 000000000..cba44a9ba
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0412-coverity-fix-2-buffer-initialization-potential-issue.patch
@@ -0,0 +1,39 @@ 
+From 254bcc407596c1a62215b14dbfafdc3d141ca021 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 5 May 2021 20:13:30 +0200
+Subject: [PATCH] [coverity] fix 2 buffer initialization (potential) issues
+
+discovered by latest coverity scan update
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_openssl.c | 2 ++
+ libknet/transport_sctp.c | 2 ++
+ 2 files changed, 4 insertions(+)
+
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 5c079428..10821a81 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -456,6 +456,8 @@ static int opensslcrypto_authenticate_and_decrypt (
+ 		unsigned char tmp_hash[crypto_instance->sec_hash_size];
+ 		ssize_t temp_buf_len = buf_in_len - crypto_instance->sec_hash_size;
+ 
++		memset(tmp_hash, 0, sizeof(tmp_hash));
++
+ 		if ((temp_buf_len <= 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
+ 			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Incorrect packet size.");
+ 			return -1;
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index f3a03f16..3e712946 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -775,6 +775,8 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 	char port_str[KNET_MAX_PORT_LEN];
+ 	sctp_accepted_link_info_t *accept_info = NULL;
+ 
++	memset(&ss, 0, sizeof(ss));
++
+ 	new_fd = accept(listen_sock, (struct sockaddr *)&ss, &sock_len);
+ 	if (new_fd < 0) {
+ 		savederrno = errno;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0413-docs-IRC-channel-is-now-on-Libera-Chat.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0413-docs-IRC-channel-is-now-on-Libera-Chat.patch
new file mode 100644
index 000000000..77ed15a3d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0413-docs-IRC-channel-is-now-on-Libera-Chat.patch
@@ -0,0 +1,23 @@ 
+From 732928641b8b9cf2f845759cbe08384ff6c5fa47 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Wed, 2 Jun 2021 17:11:17 +0200
+Subject: [PATCH] [docs] IRC channel is now on Libera Chat
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ README | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/README b/README
+index b8143f48..f1fc011a 100644
+--- a/README
++++ b/README
+@@ -18,7 +18,7 @@ https://lists.kronosnet.org/mailman/listinfo/users
+ https://lists.kronosnet.org/mailman/listinfo/devel
+ https://lists.kronosnet.org/mailman/listinfo/commits
+ https://kronosnet.org/ (web 0.1 style)
+-IRC: #kronosnet on Freenode
++IRC: #kronosnet on Libera.Chat
+ 
+ Architecture
+ ------------
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0414-send-correct-sockaddr-lengths-to-socket-calls.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0414-send-correct-sockaddr-lengths-to-socket-calls.patch
new file mode 100644
index 000000000..e1fb560c1
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0414-send-correct-sockaddr-lengths-to-socket-calls.patch
@@ -0,0 +1,270 @@ 
+From 14fbcdd7974d5360518e1e845cdb872b8628f2de Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 10 Jun 2021 10:32:00 +0100
+Subject: [PATCH] send 'correct' sockaddr lengths to socket calls
+
+FreeBSD-devel insists that the length passed into socket calls
+matches the expected length of the sockaddr it describes.
+So, eg, when passing a sockaddr_in, the length must be sizeof(sockaddr_in)
+rather than sizeof(sockaddr_storage) which we were using
+
+Signed-Off-By: Chrissie Caulfield <ccaulfie@redhat.com>
+---
+ libknet/internals.h         |  1 +
+ libknet/threads_heartbeat.c |  3 ++-
+ libknet/threads_pmtud.c     |  3 ++-
+ libknet/threads_rx.c        |  8 ++++----
+ libknet/threads_tx.c        |  8 +++++++-
+ libknet/transport_common.c  |  3 ++-
+ libknet/transport_common.h  |  2 +-
+ libknet/transport_sctp.c    | 18 ++++++++++--------
+ libknet/transport_udp.c     |  4 ++--
+ 9 files changed, 31 insertions(+), 19 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 6c26965d..64c94fec 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -147,6 +147,7 @@ struct knet_fd_trackers {
+ 	uint8_t transport;		    /* transport type (UDP/SCTP...) */
+ 	uint8_t data_type;		    /* internal use for transport to define what data are associated
+ 					     * with this fd */
++	socklen_t sockaddr_len;             /* Size of sockaddr_in[6] structure for this socket */
+ 	void *data;			    /* pointer to the data */
+ 	void *access_list_match_entry_head; /* pointer to access list match_entry list head */
+ };
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 6684952e..45d5c326 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -99,7 +99,8 @@ static void _handle_check_each(knet_handle_t knet_h, struct knet_host *dst_host,
+ retry:
+ 		if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL,
+-				     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
++				     (struct sockaddr *) &dst_link->dst_addr,
++				     knet_h->knet_transport_fd_tracker[dst_link->outsock].sockaddr_len);
+ 		} else {
+ 			len = sendto(dst_link->outsock, outbuf, outlen,	MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+ 		}
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 4aba9330..735d3a64 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -205,7 +205,8 @@ restart:
+ retry:
+ 	if (transport_get_connection_oriented(knet_h, dst_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 		len = sendto(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL,
+-			     (struct sockaddr *) &dst_link->dst_addr, sizeof(struct sockaddr_storage));
++			     (struct sockaddr *) &dst_link->dst_addr,
++			     knet_h->knet_transport_fd_tracker[dst_link->outsock].sockaddr_len);
+ 	} else {
+ 		len = sendto(dst_link->outsock, outbuf, data_len, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+ 	}
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index d03ed35e..1b4921ab 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -620,7 +620,7 @@ retry_pong:
+ 		if (src_link->transport_connected) {
+ 			if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+-					     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
++					     (struct sockaddr *) &src_link->dst_addr, knet_h->knet_transport_fd_tracker[src_link->outsock].sockaddr_len);
+ 			} else {
+ 				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+ 			}
+@@ -747,7 +747,7 @@ retry_pmtud:
+ 		if (src_link->transport_connected) {
+ 			if (transport_get_connection_oriented(knet_h, src_link->transport) == TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED) {
+ 				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL,
+-					     (struct sockaddr *) &src_link->dst_addr, sizeof(struct sockaddr_storage));
++					     (struct sockaddr *) &src_link->dst_addr, knet_h->knet_transport_fd_tracker[src_link->outsock].sockaddr_len);
+ 			} else {
+ 				len = sendto(src_link->outsock, outbuf, outlen, MSG_DONTWAIT | MSG_NOSIGNAL, NULL, 0);
+ 			}
+@@ -832,7 +832,7 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 	 */
+ 
+ 	for (i = 0; i < PCKT_RX_BUFS; i++) {
+-		msg[i].msg_hdr.msg_namelen = sizeof(struct sockaddr_storage);
++		msg[i].msg_hdr.msg_namelen = knet_h->knet_transport_fd_tracker[sockfd].sockaddr_len;
+ 	}
+ 
+ 	msg_recv = _recvmmsg(sockfd, &msg[0], PCKT_RX_BUFS, MSG_DONTWAIT | MSG_NOSIGNAL);
+@@ -950,7 +950,7 @@ void *_handle_recv_from_links_thread(void *data)
+ 		memset(&msg[i].msg_hdr, 0, sizeof(struct msghdr));
+ 
+ 		msg[i].msg_hdr.msg_name = &address[i];
+-		msg[i].msg_hdr.msg_namelen = sizeof(struct sockaddr_storage);
++		msg[i].msg_hdr.msg_namelen = sizeof(struct sockaddr_storage); /* Real value filled in before actual use */
+ 		msg[i].msg_hdr.msg_iov = &iov_in[i];
+ 		msg[i].msg_hdr.msg_iovlen = 1;
+ 	}
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 9f16706f..f610ada2 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -63,6 +63,7 @@ static int _dispatch_to_links(knet_handle_t knet_h, struct knet_host *dst_host,
+ 		msg_idx = 0;
+ 		while (msg_idx < msgs_to_send) {
+ 			msg[msg_idx].msg_hdr.msg_name = &cur_link->dst_addr;
++			msg[msg_idx].msg_hdr.msg_namelen = knet_h->knet_transport_fd_tracker[cur_link->outsock].sockaddr_len;
+ 
+ 			/* Cast for Linux/BSD compatibility */
+ 			for (i=0; i<(unsigned int)msg[msg_idx].msg_hdr.msg_iovlen; i++) {
+@@ -553,7 +554,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 	msg_idx = 0;
+ 
+ 	while (msg_idx < msgs_to_send) {
+-		msg[msg_idx].msg_hdr.msg_namelen = sizeof(struct sockaddr_storage);
++		msg[msg_idx].msg_hdr.msg_namelen = sockaddr_len((const struct sockaddr_storage *)&msg[msg_idx].msg_hdr.msg_name);
+ 		msg[msg_idx].msg_hdr.msg_iov = &iov_out[msg_idx][0];
+ 		msg[msg_idx].msg_hdr.msg_iovlen = iovcnt_out;
+ 		msg_idx++;
+@@ -591,6 +592,11 @@ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int
+ 	ssize_t inlen = 0;
+ 	int savederrno = 0, docallback = 0;
+ 
++	/*
++	 * make sure BSD gets the right size
++	 */
++	msg->msg_namelen = knet_h->knet_transport_fd_tracker[sockfd].sockaddr_len;
++
+ 	if ((channel >= 0) &&
+ 	    (channel < KNET_DATAFD_MAX) &&
+ 	    (!knet_h->sockfd[channel].is_socket)) {
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 69cd0227..5f187c0b 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -426,7 +426,7 @@ int _is_valid_fd(knet_handle_t knet_h, int sockfd)
+  * must be called with global write lock
+  */
+ 
+-int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t data_type, void *data)
++int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t data_type, socklen_t socklen, void *data)
+ {
+ 	if (sockfd < 0) {
+ 		errno = EINVAL;
+@@ -440,6 +440,7 @@ int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t
+ 
+ 	knet_h->knet_transport_fd_tracker[sockfd].transport = transport;
+ 	knet_h->knet_transport_fd_tracker[sockfd].data_type = data_type;
++	knet_h->knet_transport_fd_tracker[sockfd].sockaddr_len = socklen;
+ 	knet_h->knet_transport_fd_tracker[sockfd].data = data;
+ 
+ 	return 0;
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 120e4760..95c1ee58 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -15,7 +15,7 @@ int _configure_transport_socket(knet_handle_t knet_h, int sock, struct sockaddr_
+ int _init_socketpair(knet_handle_t knet_h, int *sock);
+ void _close_socketpair(knet_handle_t knet_h, int *sock);
+ 
+-int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t data_type, void *data);
++int _set_fd_tracker(knet_handle_t knet_h, int sockfd, uint8_t transport, uint8_t data_type, socklen_t socklen, void *data);
+ int _is_valid_fd(knet_handle_t knet_h, int sockfd);
+ 
+ int _sendmmsg(int sockfd, int connection_oriented, struct knet_mmsghdr *msgvec, unsigned int vlen, unsigned int flags);
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 3e712946..94891f93 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -118,7 +118,7 @@ static int _close_connect_socket(knet_handle_t knet_h, struct knet_link *kn_link
+ 			info->on_rx_epoll = 0;
+ 		}
+ 
+-		if (_set_fd_tracker(knet_h, info->connect_sock, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0) {
++		if (_set_fd_tracker(knet_h, info->connect_sock, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, 0, NULL) < 0) {
+ 			savederrno = errno;
+ 			err = -1;
+ 			log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+@@ -258,7 +258,7 @@ static int _create_connect_socket(knet_handle_t knet_h, struct knet_link *kn_lin
+ 		goto exit_error;
+ 	}
+ 
+-	if (_set_fd_tracker(knet_h, connect_sock, KNET_TRANSPORT_SCTP, SCTP_CONNECT_LINK_INFO, info) < 0) {
++	if (_set_fd_tracker(knet_h, connect_sock, KNET_TRANSPORT_SCTP, SCTP_CONNECT_LINK_INFO, sockaddr_len(&kn_link->src_addr), info) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+@@ -845,7 +845,9 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 
+ 	accept_info->link_info = info;
+ 
+-	if (_set_fd_tracker(knet_h, new_fd, KNET_TRANSPORT_SCTP, SCTP_ACCEPTED_LINK_INFO, accept_info) < 0) {
++	if (_set_fd_tracker(knet_h, new_fd, KNET_TRANSPORT_SCTP, SCTP_ACCEPTED_LINK_INFO,
++			    knet_h->knet_transport_fd_tracker[listen_sock].sockaddr_len,
++			    accept_info) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+@@ -877,7 +879,7 @@ exit_error:
+ 		 * check the error to make coverity scan happy.
+ 		 * _set_fd_tracker cannot fail at this stage
+ 		 */
+-		if (_set_fd_tracker(knet_h, new_fd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0){
++		if (_set_fd_tracker(knet_h, new_fd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, 0, NULL) < 0){
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to update fdtracker for socket %d", new_fd);
+ 		}
+ 		free(accept_info);
+@@ -951,7 +953,7 @@ static void _handle_listen_sctp_errors(knet_handle_t knet_h)
+ 			 * check the error to make coverity scan happy.
+ 			 * _set_fd_tracker cannot fail at this stage
+ 			 */
+-			if (_set_fd_tracker(knet_h, sockfd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0) {
++			if (_set_fd_tracker(knet_h, sockfd, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, 0, NULL) < 0) {
+ 				log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to update fdtracker for socket %d", sockfd);
+ 			}
+ 			info->accepted_socks[i] = -1;
+@@ -1087,7 +1089,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 		goto exit_error;
+ 	}
+ 
+-	if (_set_fd_tracker(knet_h, listen_sock, KNET_TRANSPORT_SCTP, SCTP_LISTENER_LINK_INFO, info) < 0) {
++	if (_set_fd_tracker(knet_h, listen_sock, KNET_TRANSPORT_SCTP, SCTP_LISTENER_LINK_INFO, sockaddr_len(&kn_link->src_addr), info) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+@@ -1192,7 +1194,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		info->on_listener_epoll = 0;
+ 	}
+ 
+-	if (_set_fd_tracker(knet_h, info->listen_sock, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0) {
++	if (_set_fd_tracker(knet_h, info->listen_sock, KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, 0, NULL) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+@@ -1216,7 +1218,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 			info->on_rx_epoll = 0;
+ 			free(knet_h->knet_transport_fd_tracker[info->accepted_socks[i]].data);
+ 			close(info->accepted_socks[i]);
+-			if (_set_fd_tracker(knet_h, info->accepted_socks[i], KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, NULL) < 0) {
++			if (_set_fd_tracker(knet_h, info->accepted_socks[i], KNET_MAX_TRANSPORTS, SCTP_NO_LINK_INFO, 0, NULL) < 0) {
+ 				savederrno = errno;
+ 				err = -1;
+ 				log_err(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to set fd tracker: %s",
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 7bdd5f18..9feac970 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -143,7 +143,7 @@ int udp_transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_lin
+ 
+ 	info->on_epoll = 1;
+ 
+-	if (_set_fd_tracker(knet_h, sock, KNET_TRANSPORT_UDP, 0, info) < 0) {
++	if (_set_fd_tracker(knet_h, sock, KNET_TRANSPORT_UDP, 0, sockaddr_len(&kn_link->src_addr), info) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_UDP, "Unable to set fd tracker: %s",
+@@ -218,7 +218,7 @@ int udp_transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_l
+ 		info->on_epoll = 0;
+ 	}
+ 
+-	if (_set_fd_tracker(knet_h, info->socket_fd, KNET_MAX_TRANSPORTS, 0, NULL) < 0) {
++	if (_set_fd_tracker(knet_h, info->socket_fd, KNET_MAX_TRANSPORTS, 0, sockaddr_len(&kn_link->src_addr), NULL) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+ 		log_err(knet_h, KNET_SUB_TRANSP_UDP, "Unable to set fd tracker: %s",
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0415-tx-minor-optimizations-to-avoid-recalculating-socksi.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0415-tx-minor-optimizations-to-avoid-recalculating-socksi.patch
new file mode 100644
index 000000000..b3174e46b
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0415-tx-minor-optimizations-to-avoid-recalculating-socksi.patch
@@ -0,0 +1,24 @@ 
+From f69dad6b4a3f2d798ffbb527165d6c71bc6b3470 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 11 Jun 2021 08:41:27 +0200
+Subject: [PATCH] [tx] minor optimizations to avoid recalculating socksize over
+ and over
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index f610ada2..0431aeeb 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -554,7 +554,7 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 	msg_idx = 0;
+ 
+ 	while (msg_idx < msgs_to_send) {
+-		msg[msg_idx].msg_hdr.msg_namelen = sockaddr_len((const struct sockaddr_storage *)&msg[msg_idx].msg_hdr.msg_name);
++		msg[msg_idx].msg_hdr.msg_namelen = sizeof(struct sockaddr_storage); /* this will set properly in _dispatch_to_links() */
+ 		msg[msg_idx].msg_hdr.msg_iov = &iov_out[msg_idx][0];
+ 		msg[msg_idx].msg_hdr.msg_iovlen = iovcnt_out;
+ 		msg_idx++;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0416-Require-make-utility.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0416-Require-make-utility.patch
new file mode 100644
index 000000000..9372e0faa
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0416-Require-make-utility.patch
@@ -0,0 +1,22 @@ 
+From 29acb6f9d341cb2fbe767ed2c7c995f7c4e1f1fa Mon Sep 17 00:00:00 2001
+From: Chris Walker <cwalker@cray.com>
+Date: Sat, 12 Jun 2021 20:12:38 -0400
+Subject: [PATCH] Require make utility
+
+---
+ kronosnet.spec.in | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 629e2353..712c895c 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -48,7 +48,7 @@ URL: https://kronosnet.org
+ Source0: https://kronosnet.org/releases/%{name}-%{version}%{?numcomm:.%{numcomm}}%{?alphatag:-%{alphatag}}%{?dirty:-%{dirty}}.tar.gz
+ 
+ # Build dependencies
+-BuildRequires: gcc libqb-devel
++BuildRequires: gcc libqb-devel make
+ # required to build man pages
+ %if %{with buildman}
+ BuildRequires: libxml2-devel doxygen
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0417-Update-copyright-around.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0417-Update-copyright-around.patch
new file mode 100644
index 000000000..28e8e6861
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0417-Update-copyright-around.patch
@@ -0,0 +1,105 @@ 
+From 0b7643c4414e76be74f45c3eb7874a1e8e88e25a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 23 Jun 2021 05:39:31 +0200
+Subject: [PATCH] Update copyright around
+
+manual backport from master/rust-bindings branches
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ NOTES_TO_PACKAGE_MAINTAINERS          | 6 ++++++
+ build-aux/knet_valgrind_helgrind.supp | 6 ++++++
+ build-aux/knet_valgrind_memcheck.supp | 6 ++++++
+ build-aux/update-copyright.sh         | 4 ++--
+ m4/pkg_check_var.m4                   | 6 ++++++
+ man/doxyxml.c                         | 2 +-
+ 6 files changed, 27 insertions(+), 3 deletions(-)
+
+diff --git a/NOTES_TO_PACKAGE_MAINTAINERS b/NOTES_TO_PACKAGE_MAINTAINERS
+index fd931f4b..b6396260 100644
+--- a/NOTES_TO_PACKAGE_MAINTAINERS
++++ b/NOTES_TO_PACKAGE_MAINTAINERS
+@@ -1,3 +1,9 @@
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+
++
+ To: distribution package maintainers
+ 
+ Those are a few things about this project that you should know.
+diff --git a/build-aux/knet_valgrind_helgrind.supp b/build-aux/knet_valgrind_helgrind.supp
+index 116ee4cf..d3976c29 100644
+--- a/build-aux/knet_valgrind_helgrind.supp
++++ b/build-aux/knet_valgrind_helgrind.supp
+@@ -1,3 +1,9 @@
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+
++
+ {
+    link enable/disable known race (safe to ignore)
+    Helgrind:Race
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index cd09f695..76b666cf 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -1,3 +1,9 @@
++# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+
++
+ {
+   lzma internals (spotted on Debian 9 and Ubuntu 18.04 LTS x86-64)
+   Memcheck:Cond
+diff --git a/build-aux/update-copyright.sh b/build-aux/update-copyright.sh
+index 62c449c8..9bb9ff14 100755
+--- a/build-aux/update-copyright.sh
++++ b/build-aux/update-copyright.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2017-2019 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+@@ -11,7 +11,7 @@
+ 
+ enddate=$(date +%Y)
+ 
+-input=$(grep -ril -e "Copyright.*Red Hat" |grep -v .swp |grep -v update-copyright |grep -v doxyxml.c)
++input=$(grep -ril -e "Copyright.*Red Hat" |grep -v .swp |grep -v update-copyright)
+ for i in $input; do
+ 	startdate=$(git log --follow "$i" | grep ^Date: | tail -n 1 | awk '{print $6}')
+ 	if [ "$startdate" != "$enddate" ]; then
+diff --git a/m4/pkg_check_var.m4 b/m4/pkg_check_var.m4
+index ae1bf222..fa3f5df3 100644
+--- a/m4/pkg_check_var.m4
++++ b/m4/pkg_check_var.m4
+@@ -1,3 +1,9 @@
++# Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
++#
++# Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
++#
++# This software licensed under GPL-2.0+
++
+ # PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
+ # [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
+ # -------------------------------------------
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 880734a1..72fda764 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2020 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0418-Sanitise-sockaddr_storage-structs-coming-in-the-API.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0418-Sanitise-sockaddr_storage-structs-coming-in-the-API.patch
new file mode 100644
index 000000000..d2fab9723
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0418-Sanitise-sockaddr_storage-structs-coming-in-the-API.patch
@@ -0,0 +1,94 @@ 
+From e59875f2fb4b7d67dee916ec7af26a4777f714fb Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 24 Jun 2021 14:38:13 +0100
+Subject: [PATCH] Sanitise sockaddr_storage structs coming in the API
+
+Before we used to copy the whole sockaddr_storage from
+the API into our structs. This meant that any junk left
+at the end by the caller got into them and could
+cause trouble with some comparisons.
+
+This patch zeros out the extra bits of the sockaddr_storage
+that are not valid.
+---
+ libknet/links.c        | 5 +++--
+ libknet/links_acl_ip.c | 4 ++--
+ libknet/netutils.c     | 7 +++++++
+ libknet/netutils.h     | 2 ++
+ 4 files changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 91aeff48..204401b9 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -14,6 +14,7 @@
+ #include <string.h>
+ #include <pthread.h>
+ 
++#include "netutils.h"
+ #include "internals.h"
+ #include "logging.h"
+ #include "links.h"
+@@ -191,7 +192,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		goto exit_unlock;
+ 	}
+ 
+-	memmove(&link->src_addr, src_addr, sizeof(struct sockaddr_storage));
++	copy_sockaddr(&link->src_addr, src_addr);
+ 
+ 	err = knet_addrtostr(src_addr, sizeof(struct sockaddr_storage),
+ 			     link->status.src_ipaddr, KNET_MAX_HOST_LEN,
+@@ -218,7 +219,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 
+ 		link->dynamic = KNET_LINK_STATIC;
+ 
+-		memmove(&link->dst_addr, dst_addr, sizeof(struct sockaddr_storage));
++		copy_sockaddr(&link->dst_addr, dst_addr);
+ 		err = knet_addrtostr(dst_addr, sizeof(struct sockaddr_storage),
+ 				     link->status.dst_ipaddr, KNET_MAX_HOST_LEN,
+ 				     link->status.dst_port, KNET_MAX_PORT_LEN);
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 68050bfc..ea1755f2 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -253,8 +253,8 @@ int ipcheck_addip(void *fd_tracker_match_entry_head, int index,
+ 		return -1;
+ 	}
+ 
+-	memmove(&new_match_entry->addr1, ss1, sizeof(struct sockaddr_storage));
+-	memmove(&new_match_entry->addr2, ss2, sizeof(struct sockaddr_storage));
++	copy_sockaddr(&new_match_entry->addr1, ss1);
++	copy_sockaddr(&new_match_entry->addr2, ss2);
+ 	new_match_entry->type = type;
+ 	new_match_entry->acceptreject = acceptreject;
+ 	new_match_entry->next = NULL;
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index 7e19104c..03f01650 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -46,6 +46,13 @@ socklen_t sockaddr_len(const struct sockaddr_storage *ss)
+ 	}
+ }
+ 
++/* Only copy the valid parts of a sockaddr* */
++void copy_sockaddr(struct sockaddr_storage *sout, const struct sockaddr_storage *sin)
++{
++	memset(sout, 0, sizeof(struct sockaddr_storage));
++	memmove(sout, sin, sockaddr_len(sin));
++}
++
+ /*
+  * exported APIs
+  */
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index 0c0c6e34..b9e5f4b7 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -25,5 +25,7 @@
+ 
+ int cmpaddr(const struct sockaddr_storage *ss1, const struct sockaddr_storage *ss2);
+ 
++void copy_sockaddr(struct sockaddr_storage *sout, const struct sockaddr_storage *sin);
++
+ socklen_t sockaddr_len(const struct sockaddr_storage *ss);
+ #endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0419-Add-comment-about-log_fd-in-knet_handle_new.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0419-Add-comment-about-log_fd-in-knet_handle_new.patch
new file mode 100644
index 000000000..bbf3023d2
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0419-Add-comment-about-log_fd-in-knet_handle_new.patch
@@ -0,0 +1,22 @@ 
+From 9e4529ff3596bb9601f9d90a70ca14d9c1dd8067 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 24 Jun 2021 09:24:43 +0100
+Subject: [PATCH] Add comment about log_fd in knet_handle_new()
+
+---
+ libknet/libknet.h | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index ab4dbf25..1e61515f 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -115,6 +115,8 @@ typedef struct knet_handle *knet_handle_t;
+  *            It is strongly encouraged to use pipes (ex: pipe(2) or pipe2(2)) for
+  *            logging fds due to the atomic nature of writes between fds.
+  *            See also libknet test suite for reference and guidance.
++ *            The caller is responsible for management of the FD. eg. knet will not
++ *            close it when knet_handle_free(3) is called
+  *
+  * default_log_level -
+  *            If logfd is specified, it will initialize all subsystems to log
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0420-spec-cleanup-some-krosnonetd-leftovers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0420-spec-cleanup-some-krosnonetd-leftovers.patch
new file mode 100644
index 000000000..efea1b709
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0420-spec-cleanup-some-krosnonetd-leftovers.patch
@@ -0,0 +1,34 @@ 
+From a186c16c213a41d3e6730453b5ccc42ed3db3b37 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 24 Jun 2021 10:17:43 +0200
+Subject: [PATCH] [spec] cleanup some krosnonetd leftovers
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ kronosnet.spec.in | 7 ++-----
+ 1 file changed, 2 insertions(+), 5 deletions(-)
+
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index 712c895c..b764f605 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -168,12 +168,10 @@ BuildRequires: autoconf automake libtool
+ 	--disable-compress-zstd \
+ %endif
+ %if %{with libnozzle}
+-	--enable-libnozzle \
++	--enable-libnozzle
+ %else
+-	--disable-libnozzle \
++	--disable-libnozzle
+ %endif
+-	--with-initdefaultdir=%{_sysconfdir}/sysconfig/ \
+-	--with-systemddir=%{_unitdir}
+ 
+ make %{_smp_mflags}
+ 
+@@ -458,4 +456,3 @@ Requires: libknet1%{_isa} = %{version}-%{release}
+ %changelog
+ * @date@ Autotools generated version <nobody@nowhere.org> - @version@-1-@numcomm@.@alphatag@.@dirty@
+ - These aren't the droids you're looking for.
+-
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0421-tests-suppress-more-libnss3-errors.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0421-tests-suppress-more-libnss3-errors.patch
new file mode 100644
index 000000000..f63917391
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0421-tests-suppress-more-libnss3-errors.patch
@@ -0,0 +1,30 @@ 
+From 8a042d947c5df75655865d5da78d0dfab7a7e24d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 24 Jun 2021 10:14:31 +0200
+Subject: [PATCH] [tests] suppress more libnss3 errors
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 76b666cf..2416c318 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -620,3 +620,15 @@
+   fun:init_nss
+   fun:nsscrypto_init
+ }
++{
++  nss internal leak non recurring (spotted on rhel8.4 and clang)
++  Memcheck:Leak
++  match-leak-kinds: possible
++  fun:malloc
++  fun:realpath@@GLIBC_2.3
++  ...
++  obj:/usr/lib64/libnss3.so
++  fun:SECMOD_LoadModule
++  fun:SECMOD_LoadModule
++  obj:/usr/lib64/libnss3.so
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0422-link-don-t-leak-resources-if-link-configuration-fail.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0422-link-don-t-leak-resources-if-link-configuration-fail.patch
new file mode 100644
index 000000000..603581527
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0422-link-don-t-leak-resources-if-link-configuration-fail.patch
@@ -0,0 +1,98 @@ 
+From 2caf249745fb22beb15c43d6da0c8d835057a93b Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 30 Jun 2021 06:46:34 +0200
+Subject: [PATCH] =?UTF-8?q?[link]=20don=C2=B4t=20leak=20resources=20if=20l?=
+ =?UTF-8?q?ink=20configuration=20fails?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 41 ++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 38 insertions(+), 3 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 204401b9..7301de32 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -103,7 +103,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 			 struct sockaddr_storage *dst_addr,
+ 			 uint64_t flags)
+ {
+-	int savederrno = 0, err = 0, i;
++	int savederrno = 0, err = 0, i, wipelink = 0;
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 
+@@ -192,6 +192,12 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		goto exit_unlock;
+ 	}
+ 
++	/*
++	 * errors happening after this point should trigger
++	 * a memset of the link
++	 */
++	wipelink = 1;
++
+ 	copy_sockaddr(&link->src_addr, src_addr);
+ 
+ 	err = knet_addrtostr(src_addr, sizeof(struct sockaddr_storage),
+@@ -261,7 +267,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	if (transport_link_set_config(knet_h, link, transport) < 0) {
+ 		savederrno = errno;
+ 		err = -1;
+-		goto exit_unlock;
++		goto exit_transport_err;
+ 	}
+ 
+ 	/*
+@@ -279,10 +285,13 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+ 			savederrno = errno;
+ 			err = -1;
+-			goto exit_unlock;
++			goto exit_acl_error;
+ 		}
+ 	}
+ 
++	/*
++	 * no errors should happen after link is configured
++	 */
+ 	link->configured = 1;
+ 	log_debug(knet_h, KNET_SUB_LINK, "host: %u link: %u is configured",
+ 		  host_id, link_id);
+@@ -322,7 +331,33 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		link->has_valid_mtu = 1;
+ 	}
+ 
++exit_acl_error:
++	/*
++	 * if creating access lists has error, we only need to clean
++	 * the transport and the stuff below.
++	 */
++	if (err < 0) {
++		if ((transport_link_clear_config(knet_h, link) < 0)  &&
++		    (errno != EBUSY)) {
++			log_warn(knet_h, KNET_SUB_LINK, "Failed to deconfigure transport for host %u link %u: %s", host_id, link_id, strerror(errno));
++		}
++	}
++exit_transport_err:
++	/*
++	 * if transport has errors, transport will clean after itself
++	 * and we only need to clean the mutex
++	 */
++	if (err < 0) {
++		pthread_mutex_destroy(&link->link_stats_mutex);
++	}
+ exit_unlock:
++	/*
++	 * re-init the link on error
++	 */
++	if ((err < 0) && (wipelink)) {
++		memset(link, 0, sizeof(struct knet_link));
++		link->link_id = link_id;
++	}
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+ 	errno = err ? savederrno : 0;
+ 	return err;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0423-link-use-previously-cached-value-as-link-info-might-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0423-link-use-previously-cached-value-as-link-info-might-.patch
new file mode 100644
index 000000000..30ad00149
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0423-link-use-previously-cached-value-as-link-info-might-.patch
@@ -0,0 +1,24 @@ 
+From 59d18055b162127b8cde417089c7b752bcacc1cf Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 30 Jun 2021 06:48:42 +0200
+Subject: [PATCH] [link] use previously cached value as link info might not be
+ accurate
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 7301de32..16ef211b 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -543,7 +543,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 * remove any other access lists when the socket is no
+ 	 * longer in use by the transport.
+ 	 */
+-	if ((transport_get_acl_type(knet_h, link->transport) == USE_GENERIC_ACL) &&
++	if ((transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL) &&
+ 	    (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS)) {
+ 		check_rmall(knet_h, sock, transport);
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0424-link-don-t-allow-mix-of-dynamic-and-static-links.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0424-link-don-t-allow-mix-of-dynamic-and-static-links.patch
new file mode 100644
index 000000000..29cfe838d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0424-link-don-t-allow-mix-of-dynamic-and-static-links.patch
@@ -0,0 +1,85 @@ 
+From f3e2fd4a3f72ae1e98736112cef70a74bd1092dc Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 30 Jun 2021 07:54:54 +0200
+Subject: [PATCH] =?UTF-8?q?[link]=20don=C2=B4t=20allow=20mix=20of=20dynami?=
+ =?UTF-8?q?c=20and=20static=20links?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+with same source address/port.
+
+The configuration doesn´t make sense in itself and confuses ACL.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c                          | 26 ++++++++++++++++++++++--
+ libknet/tests/api_knet_link_set_config.c | 11 ++++++++++
+ 2 files changed, 35 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index 16ef211b..fa63fd17 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -103,8 +103,8 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 			 struct sockaddr_storage *dst_addr,
+ 			 uint64_t flags)
+ {
+-	int savederrno = 0, err = 0, i, wipelink = 0;
+-	struct knet_host *host;
++	int savederrno = 0, err = 0, i, wipelink = 0, link_idx;
++	struct knet_host *host, *tmp_host;
+ 	struct knet_link *link;
+ 
+ 	if (!_is_valid_handle(knet_h)) {
+@@ -257,6 +257,28 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	link->latency_cur_samples = 0;
+ 	link->flags = flags;
+ 
++	/*
++	 * check for DYNIP vs STATIC collisions.
++	 * example: link0 is static, user attempts to configure link1 as dynamic with the same source
++	 * address/port.
++	 * This configuration is invalid and would cause ACL collisions.
++	 */
++	for (tmp_host = knet_h->host_head; tmp_host != NULL; tmp_host = tmp_host->next) {
++		for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) {
++			if (&tmp_host->link[link_idx] == link)
++				continue;
++
++			if ((!memcmp(&tmp_host->link[link_idx].src_addr, &link->src_addr, sizeof(struct sockaddr_storage))) &&
++			    (tmp_host->link[link_idx].dynamic != link->dynamic)) {
++				savederrno = EINVAL;
++				err = -1;
++				log_err(knet_h, KNET_SUB_LINK, "Failed to configure host %u link %u dyn %u. Conflicts with host %u link %u dyn %u: %s",
++					host_id, link_id, link->dynamic, tmp_host->host_id, link_idx, tmp_host->link[link_idx].dynamic, strerror(savederrno));
++				goto exit_unlock;
++			}
++		}
++	}
++
+ 	savederrno = pthread_mutex_init(&link->link_stats_mutex, NULL);
+ 	if (savederrno) {
+ 		log_err(knet_h, KNET_SUB_LINK, "Unable to initialize link stats mutex: %s", strerror(savederrno));
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index 2aab41b3..402b51c6 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -173,6 +173,17 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_link_set_config with dynamic link (0) and static link (1)\n");
++
++	if (!knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_UDP, &lo, &lo, 0) || (errno != EINVAL)) {
++		printf("knet_link_set_config accepted request mixed static/dynamic request or returned incorrect error: %s\n", strerror(errno));
++		knet_host_remove(knet_h, 1);
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	printf("Test knet_link_set_config with already configured link\n");
+ 	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) || (errno != EBUSY))) {
+ 		printf("knet_link_set_config accepted request while link configured or returned incorrect error: %s\n", strerror(errno));
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0425-doc-Add-comments-to-structure-members.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0425-doc-Add-comments-to-structure-members.patch
new file mode 100644
index 000000000..1b195a58d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0425-doc-Add-comments-to-structure-members.patch
@@ -0,0 +1,500 @@ 
+From 4e801ef37449ede8f589d4ab70ce02bb907d924f Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Wed, 30 Jun 2021 10:49:57 +0100
+Subject: [PATCH] [doc] Add comments to structure members
+
+Removes doxygen warnings at build time
+
+Needs the latest doxygen2man to actually print anything in the
+man pages.
+
+Signed-Off-By: Christine Caulfield <ccaulfie@redhat.com>
+---
+ libknet/libknet.h     | 231 +++++++++++++++++++++++++++++++++++-------
+ libnozzle/libnozzle.h |  17 +++-
+ man/Makefile.am       |   4 +-
+ 3 files changed, 209 insertions(+), 43 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 1e61515f..2c8e52b1 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -30,12 +30,15 @@
+  * libknet limits
+  */
+ 
++
++/** typedef for a knet node */
++typedef uint16_t knet_node_id_t;
++
++
+ /*
+  * Maximum number of hosts
+  */
+ 
+-typedef uint16_t knet_node_id_t;
+-
+ #define KNET_MAX_HOST 65536
+ 
+ /*
+@@ -88,6 +91,11 @@ typedef uint16_t knet_node_id_t;
+ 
+ #define KNET_HANDLE_FLAG_PRIVILEGED (1ULL << 0)
+ 
++/**
++ * Opaque handle for this knet connection, created with knet_handle_new() and
++ * freed with knet_handle_free()
++ */
++
+ typedef struct knet_handle *knet_handle_t;
+ 
+ /*
+@@ -662,11 +670,21 @@ int knet_handle_pmtud_get(knet_handle_t knet_h,
+ #define KNET_MIN_KEY_LEN  128
+ #define KNET_MAX_KEY_LEN 4096
+ 
++
++/**
++ * Structure passed into knet_handle_set_crypto_config() to determine
++ * the crypto options to use for the current communications handle
++ */
+ struct knet_handle_crypto_cfg {
++	/** Model to use. nss, openssl, etc */
+ 	char		crypto_model[16];
++	/** Cipher type name for encryption. aes 256 etc */
+ 	char		crypto_cipher_type[16];
++	/** Hash type for digest. sha512 etc */
+ 	char		crypto_hash_type[16];
++	/** Private key */
+ 	unsigned char	private_key[KNET_MAX_KEY_LEN];
++	/** Length of private key */
+ 	unsigned int	private_key_len;
+ };
+ 
+@@ -836,9 +854,19 @@ int knet_handle_crypto(knet_handle_t knet_h,
+ 
+ #define KNET_COMPRESS_THRESHOLD 100
+ 
++
++/**
++ * Structure passed into knet_handle_compress()
++ * to tell knet what type of compression to use
++ * for this communiction
++ */
++
+ struct knet_handle_compress_cfg {
++	/** Compression library to use, bzip2 etc... */
+ 	char	 compress_model[16];
++	/** Threshold. Packets smaller than this will not be compressed */
+ 	uint32_t compress_threshold;
++	/** Passed into the compression library as an indication of the level of compression to apply */
+ 	int	 compress_level;
+ };
+ 
+@@ -901,35 +929,59 @@ int knet_handle_compress(knet_handle_t knet_h,
+ 			 struct knet_handle_compress_cfg *knet_handle_compress_cfg);
+ 
+ 
++/**
++ * Detailed stats for this knet handle as returned by knet_handle_get_stats()
++ */
+ 
+ struct knet_handle_stats {
++	/** Size of the structure. set this to sizeof(struct knet_handle_stats) before calling */
+ 	size_t   size;
+-
++	/** Number of uncompressed packets sent */
+ 	uint64_t tx_uncompressed_packets;
++	/** Number of compressed packets sent */
+ 	uint64_t tx_compressed_packets;
++	/** Number of bytes sent (as if uncompressed, ie actual data bytes) */
+ 	uint64_t tx_compressed_original_bytes;
++	/** Number of bytes sent on the wire after compresion */
+ 	uint64_t tx_compressed_size_bytes;
++	/** Average(mean) time take to compress transmitted packets */
+ 	uint64_t tx_compress_time_ave;
++	/** Minumum time taken to compress transmitted packets */
+ 	uint64_t tx_compress_time_min;
++	/** Maximum time taken to compress transmitted packets */
+ 	uint64_t tx_compress_time_max;
+ 
++	/** Number of compressed packets received */
+ 	uint64_t rx_compressed_packets;
++	/** Number of bytes received - after decompression */
+ 	uint64_t rx_compressed_original_bytes;
++	/** Number of compressed bytes received before decompression */
+ 	uint64_t rx_compressed_size_bytes;
++	/** Average(mean) time take to decompress received packets */
+ 	uint64_t rx_compress_time_ave;
++	/** Minimum time take to decompress received packets */
+ 	uint64_t rx_compress_time_min;
++	/** Maximum time take to decompress received packets */
+ 	uint64_t rx_compress_time_max;
+ 
+-	/* Overhead times, measured in usecs */
++	/** Number of encrypted packets sent */
+ 	uint64_t tx_crypt_packets;
++	/** Cumulative byte overhead of encrypted traffic */
+ 	uint64_t tx_crypt_byte_overhead;
++	/** Average(mean) time take to encrypt packets in usecs */
+ 	uint64_t tx_crypt_time_ave;
++	/** Minimum time take to encrypto packets in usecs */
+ 	uint64_t tx_crypt_time_min;
++	/** Maximum time take to encrypto packets in usecs */
+ 	uint64_t tx_crypt_time_max;
+ 
++	/** Number of encrypted packets received */
+ 	uint64_t rx_crypt_packets;
++	/** Average(mean) time take to decrypt received packets */
+ 	uint64_t rx_crypt_time_ave;
++	/** Minimum time take to decrypt received packets in usecs */
+ 	uint64_t rx_crypt_time_min;
++	/** Maximum time take to decrypt received packets in usecs */
+ 	uint64_t rx_crypt_time_max;
+ };
+ 
+@@ -986,11 +1038,18 @@ int knet_handle_get_stats(knet_handle_t knet_h, struct knet_handle_stats *stats,
+ int knet_handle_clear_stats(knet_handle_t knet_h, int clear_option);
+ 
+ 
++/**
++ * Structure returned from get_crypto_list() containing
++ * information about the installed cryptographic systems
++ */
+ 
+ struct knet_crypto_info {
+-	const char *name; /* openssl,nss,etc.. */
+-	uint8_t properties; /* currently unused */
+-	char pad[256];      /* currently unused */
++	/** Name of the crypto library/ openssl, nss,etc .. */
++	const char *name;
++	/** Properties - currently unused */
++	uint8_t properties;
++	/** Currently unused padding */
++	char pad[256];
+ };
+ 
+ /**
+@@ -1018,10 +1077,17 @@ int knet_get_crypto_list(struct knet_crypto_info *crypto_list,
+ 
+ 
+ 
++/**
++ * Structure returned from get_compress_list() containing
++ * information about the installed compression systems
++ */
+ struct knet_compress_info {
+-	const char *name; /* bzip2, lz4, etc.. */
+-	uint8_t properties; /* currently unused */
+-	char pad[256];      /* currently unused */
++	/** Name of the compression type  bzip2, lz4, etc.. */
++	const char *name;
++	/** Properties - currently unused */
++	uint8_t properties;
++	/** Currently unused padding */
++	char pad[256];
+ };
+ 
+ /**
+@@ -1293,9 +1359,15 @@ int knet_host_enable_status_change_notify(knet_handle_t knet_h,
+  *                       1 host_id has been received via another host_id
+  */
+ 
++/**
++ * status of a knet host, returned from knet_host_get_status()
++ */
+ struct knet_host_status {
++	/** Whether the host is currently reachable */
+ 	uint8_t reachable;
++	/** Whether the host is a remote node (not currently implemented) */
+ 	uint8_t remote;
++	/** Whether the host is external (not currently implemented) */
+ 	uint8_t external;
+ 	/* add host statistics */
+ };
+@@ -1409,11 +1481,19 @@ int knet_addrtostr(const struct sockaddr_storage *ss, socklen_t sslen,
+  * local host.
+  */
+ 
++
++/**
++ * Transport information returned from knet_get_transport_list()
++ */
+ struct knet_transport_info {
+-	const char *name;   /* UDP/SCTP/etc... */
+-	uint8_t id;         /* value that can be used for link_set_config */
+-	uint8_t properties; /* currently unused */
+-	char pad[256];      /* currently unused */
++	/** Transport name. UDP, SCTP, etc... */
++	const char *name;
++	/** value that can be used for knet_link_set_config() */
++	uint8_t id;
++	/** currently unused */
++	uint8_t properties;
++	/** currently unused */
++	char pad[256];
+ };
+ 
+ /**
+@@ -2016,86 +2096,152 @@ int knet_link_get_link_list(knet_handle_t knet_h, knet_node_id_t host_id,
+ 
+ #define MAX_LINK_EVENTS 16
+ 
++/**
++ * Stats for a knet link
++ * returned from knet_link_get_status() as part of a knet_link_status structure
++ * link stats are 'onwire', ie they indicate the number of actual bytes/packets
++ * sent including overheads, not just data packets.
++ */
+ struct knet_link_stats {
+-	/* onwire values */
++	/** Number of data packets sent */
+ 	uint64_t tx_data_packets;
++	/** Number of data packets received */
+ 	uint64_t rx_data_packets;
++	/** Number of data bytes sent */
+ 	uint64_t tx_data_bytes;
++	/** Number of data bytes received */
+ 	uint64_t rx_data_bytes;
++	/** Number of ping packets sent */
+ 	uint64_t rx_ping_packets;
++	/** Number of ping packets received */
+ 	uint64_t tx_ping_packets;
++	/** Number of ping bytes sent */
+ 	uint64_t rx_ping_bytes;
++	/** Number of ping bytes received */
+ 	uint64_t tx_ping_bytes;
++	/** Number of pong packets sent */
+ 	uint64_t rx_pong_packets;
++	/** Number of pong packets received */
+ 	uint64_t tx_pong_packets;
++	/** Number of pong bytes sent */
+ 	uint64_t rx_pong_bytes;
++	/** Number of pong bytes received */
+ 	uint64_t tx_pong_bytes;
++	/** Number of pMTU packets sent */
+ 	uint64_t rx_pmtu_packets;
++	/** Number of pMTU packets received */
+ 	uint64_t tx_pmtu_packets;
++	/** Number of pMTU bytes sent */
+ 	uint64_t rx_pmtu_bytes;
++	/** Number of pMTU bytes received */
+ 	uint64_t tx_pmtu_bytes;
+ 
+-	/* Only filled in when requested */
++	/* These are only filled in when requested
++	   ie. they are not collected in realtime */
++	/** Total of all packets sent */
+ 	uint64_t tx_total_packets;
++	/** Total of all packets received */
+ 	uint64_t rx_total_packets;
++	/** Total number of bytes sent */
+ 	uint64_t tx_total_bytes;
++	/** Total number of bytes received */
+ 	uint64_t rx_total_bytes;
++	/** Total number of errors that occurred while sending */
+ 	uint64_t tx_total_errors;
++	/** Total number of retries that occurred while sending */
+ 	uint64_t tx_total_retries;
+ 
++	/** Total number of errors that occurred while sending pMTU packets */
+ 	uint32_t tx_pmtu_errors;
++	/** Total number of retries that occurred while sending pMTU packets */
+ 	uint32_t tx_pmtu_retries;
++	/** Total number of errors that occurred while sending ping packets */
+ 	uint32_t tx_ping_errors;
++	/** Total number of retries that occurred while sending ping packets */
+ 	uint32_t tx_ping_retries;
++	/** Total number of errors that occurred while sending pong packets */
+ 	uint32_t tx_pong_errors;
++	/** Total number of retries that occurred while sending pong packets */
+ 	uint32_t tx_pong_retries;
++	/** Total number of errors that occurred while sending data packets */
+ 	uint32_t tx_data_errors;
++	/** Total number of retries that occurred while sending data packets */
+ 	uint32_t tx_data_retries;
+ 
+-	/* measured in usecs */
++	/** Minimum latency measured in usecs */
+ 	uint32_t latency_min;
++	/** Maximum latency measured in usecs */
+ 	uint32_t latency_max;
++	/** Average(mean) latency measured in usecs */
+ 	uint32_t latency_ave;
++	/** Number of samples used to calculate latency */
+ 	uint32_t latency_samples;
+ 
+-	/* how many times the link has been going up/down */
++	/** How many times the link has gone down */
+ 	uint32_t down_count;
++	/** How many times the link has come up */
+ 	uint32_t up_count;
+ 
+-	/*
+-	 * circular buffer of time_t structs collecting the history
+-	 * of up/down events on this link.
+-	 * the index indicates current/last event.
++	/**
++	 * A circular buffer of time_t structs collecting the history
++	 * of up events on this link.
++	 * The index indicates current/last event.
+ 	 * it is safe to walk back the history by decreasing the index
+ 	 */
+ 	time_t   last_up_times[MAX_LINK_EVENTS];
++	/**
++	 * A circular buffer of time_t structs collecting the history
++	 * of down events on this link.
++	 * The index indicates current/last event.
++	 * it is safe to walk back the history by decreasing the index
++	 */
+ 	time_t   last_down_times[MAX_LINK_EVENTS];
++	/** Index of last element in the last_up_times[] array */
+ 	int8_t   last_up_time_index;
++	/** Index of last element in the last_down_times[] array */
+ 	int8_t   last_down_time_index;
+ 	/* Always add new stats at the end */
+ };
+ 
++
++/**
++ * Status of a knet link as returned from knet_link_get_status()
++ */
+ struct knet_link_status {
+-	size_t size;                    /* For ABI checking */
++	/** Size of the structure for ABI checking, set this to sizeof(knet_link_status) before calling knet_link_get_status() */
++	size_t size;
++	/** Local IP address as a string*/
+ 	char src_ipaddr[KNET_MAX_HOST_LEN];
++	/** Local IP port as a string */
+ 	char src_port[KNET_MAX_PORT_LEN];
++	/** Remote IP address as a string */
+ 	char dst_ipaddr[KNET_MAX_HOST_LEN];
++	/** Remote IP port as a string*/
+ 	char dst_port[KNET_MAX_PORT_LEN];
+-	uint8_t enabled;	        /* link is configured and admin enabled for traffic */
+-	uint8_t connected;              /* link is connected for data (local view) */
+-	uint8_t dynconnected;	        /* link has been activated by remote dynip */
+-	unsigned long long latency;	/* average latency computed by fix/exp */
++	/** Link is configured and admin enabled for traffic */
++	uint8_t enabled;
++	/** Link is connected for data (local view) */
++	uint8_t connected;
++	/** Link has been activated by remote dynip */
++	uint8_t dynconnected;
++	/** average latency computed by fix/exp */
++	unsigned long long latency;
++	/** Timestamp of the past pong received */
+ 	struct timespec pong_last;
+-	unsigned int mtu;		/* current detected MTU on this link */
+-	unsigned int proto_overhead;    /* contains the size of the IP protocol, knet headers and
+-					 * crypto headers (if configured). This value is filled in
+-					 * ONLY after the first PMTUd run on that given link,
+-					 * and can change if link configuration or crypto configuration
+-					 * changes at runtime.
+-					 * WARNING: in general mtu + proto_overhead might or might
+-					 * not match the output of ifconfig mtu due to crypto
+-					 * requirements to pad packets to some specific boundaries. */
+-	/* Link statistics */
++	/** Currently detected MTU on this link */
++	unsigned int mtu;
++	/**
++	 * Contains the size of the IP protocol, knet headers and
++	 * crypto headers (if configured). This value is filled in
++	 * ONLY after the first PMTUd run on that given link,
++	 * and can change if link configuration or crypto configuration
++	 * changes at runtime.
++	 * WARNING: in general mtu + proto_overhead might or might
++	 * not match the output of ifconfig mtu due to crypto
++	 * requirements to pad packets to some specific boundaries.
++	 */
++	unsigned int proto_overhead;
++	/** Link statistics */
+ 	struct knet_link_stats stats;
+ };
+ 
+@@ -2250,10 +2396,17 @@ uint8_t knet_log_get_loglevel_id(const char *name);
+ #error KNET_MAX_LOG_MSG_SIZE cannot be bigger than PIPE_BUF for guaranteed system atomic writes
+ #endif
+ 
++
++/**
++ * Structure of a log message sent to the logging fd
++ */
+ struct knet_log_msg {
++	/** Text of the log message */
+ 	char	msg[KNET_MAX_LOG_MSG_SIZE];
+-	uint8_t	subsystem;	/* KNET_SUB_* */
+-	uint8_t msglevel;	/* KNET_LOG_* */
++	/** Subsystem that sent this message. KNET_SUB_* */
++	uint8_t	subsystem;
++	/** Logging level of this message. KNET_LOG_* */
++	uint8_t msglevel;
+ };
+ 
+ /**
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index d8e644a1..dae44e1a 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -21,6 +21,11 @@
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+ 
++/**
++ * An opaque handle returned from nozzle_open(), this should be
++ * passed into all other nozzle API calls and closed with nozzle_close()
++ * when finished with.
++ */
+ typedef struct nozzle_iface *nozzle_t;
+ 
+ /**
+@@ -42,7 +47,7 @@ typedef struct nozzle_iface *nozzle_t;
+  * updownpath - nozzle supports the typical filesystem structure to execute
+  *              actions for: down.d  post-down.d  pre-up.d  up.d
+  *              in the form of:
+- *              updownpath/<action>/<interface_name>
++ *              updownpath/\<action\>/\<interface_name\>
+  *              updownpath specifies where to find those directories on the
+  *              filesystem and it must be an absolute path.
+  *
+@@ -169,10 +174,18 @@ int nozzle_del_ip(nozzle_t nozzle, const char *ipaddr, const char *prefix);
+ #define IPADDR_CHAR_MAX	128
+ #define PREFIX_CHAR_MAX	  4
+ 
++/**
++ * Info about an IP address on a nozzle interface
++ * as returned from nozzle_get_ips
++ */
+ struct nozzle_ip {
++	/** The IP address */
+ 	char ipaddr[IPADDR_CHAR_MAX + 1];
++	/** Prefix - eg "24" */
+ 	char prefix[PREFIX_CHAR_MAX + 1];
+-	int  domain;	/* AF_INET or AF_INET6 */
++	/** AF_INET or AF_INET6 */
++	int  domain;
++	/** Pointer to next struct or NULL */
+ 	struct nozzle_ip *next;
+ };
+ 
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 7852ef67..4bcafefd 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -129,14 +129,14 @@ man3_MANS = $(knet_man3_MANS) $(nozzle_man3_MANS)
+ $(MANS): doxyfile-knet.stamp doxyfile-nozzle.stamp
+ 
+ doxyfile-knet.stamp: $(noinst_PROGRAMS) Doxyfile-knet $(top_srcdir)/libknet/libknet.h
+-	$(DOXYGEN) Doxyfile-knet
++	$(DOXYGEN) Doxyfile-knet 2>&1 | $(EGREP) -v 'warning.*macro definition'
+ 	$(DOXYGEN2MAN) -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-knet/ libknet_8h.xml
+ 	touch doxyfile-knet.stamp
+ 
+ doxyfile-nozzle.stamp: $(noinst_PROGRAMS) Doxyfile-nozzle $(top_srcdir)/libnozzle/libnozzle.h
+ if BUILD_LIBNOZZLE
+-	$(DOXYGEN) Doxyfile-nozzle
++	$(DOXYGEN) Doxyfile-nozzle 2>&1 | $(EGREP) -v 'warning.*macro definition'
+ 	$(DOXYGEN2MAN) -m -P -o $(builddir) -s 3 -p @PACKAGE_NAME@ -H "Kronosnet Programmer's Manual" \
+ 		$$($(UTC_DATE_AT)$(SOURCE_EPOCH) +"-D %F -Y %Y") -d $(builddir)/xml-nozzle/ libnozzle_8h.xml
+ endif
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0426-man-update-doxygen2man-to-latest-from-libqb.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0426-man-update-doxygen2man-to-latest-from-libqb.patch
new file mode 100644
index 000000000..3fa92f3ef
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0426-man-update-doxygen2man-to-latest-from-libqb.patch
@@ -0,0 +1,973 @@ 
+From 09a37b2843266292051b071ea81658eeff708f75 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 2 Jul 2021 05:47:36 +0200
+Subject: [PATCH] [man] update doxygen2man to latest from libqb
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ man/Makefile.am |   3 +-
+ man/cstring.c   | 131 ++++++++++++++++
+ man/cstring.h   |  15 ++
+ man/doxyxml.c   | 404 ++++++++++++++++++++++++++++++++++++++----------
+ 4 files changed, 467 insertions(+), 86 deletions(-)
+ create mode 100644 man/cstring.c
+ create mode 100644 man/cstring.h
+
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 4bcafefd..2ff160be 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -27,8 +27,9 @@ if BUILD_MAN
+ 
+ if BUILD_DOXYXML
+ noinst_PROGRAMS	= doxyxml
++noinst_HEADERS  = cstring.h
+ 
+-doxyxml_SOURCES = doxyxml.c
++doxyxml_SOURCES = doxyxml.c cstring.c
+ doxyxml_CFLAGS = $(AM_CFLAGS) $(libqb_BUILD_CFLAGS) $(libxml_BUILD_CFLAGS)
+ doxyxml_LDADD = $(libqb_BUILD_LIBS) $(libxml_BUILD_LIBS)
+ endif
+diff --git a/man/cstring.c b/man/cstring.c
+new file mode 100644
+index 00000000..23ba31d3
+--- /dev/null
++++ b/man/cstring.c
+@@ -0,0 +1,131 @@
++/* A really basic expanding/appendable string type */
++
++#include <stdlib.h>
++#include <sys/time.h>
++#include <sys/stat.h>
++#include <time.h>
++#include <assert.h>
++#include <stdio.h>
++#include <limits.h>
++#include <string.h>
++#include <getopt.h>
++#include <errno.h>
++#include "cstring.h"
++
++#define INITIAL_SIZE 1024
++#define INCREMENT    1024
++#define CHECKER_WORD 0xbcd6712a
++
++struct cstring_header
++{
++	size_t checker;
++	size_t allocated;
++	size_t used;
++	char the_string[];
++};
++
++cstring_t cstring_alloc(void)
++{
++	char *cstring = malloc(INITIAL_SIZE);
++	if (cstring) {
++		struct cstring_header *h = (struct cstring_header *)cstring;
++		h->checker = CHECKER_WORD;
++		h->allocated = INITIAL_SIZE;
++		h->used = 0;
++		h->the_string[0] = '\0';
++		return cstring;
++	} else {
++		return NULL;
++	}
++}
++
++char *cstring_to_chars(cstring_t cstring)
++{
++	struct cstring_header *h = (struct cstring_header *)cstring;
++
++	if (!h) {
++		return NULL;
++	}
++
++	assert(h->checker == CHECKER_WORD);
++	return strdup(h->the_string);
++}
++
++size_t cstring_len(cstring_t cstring)
++{
++	struct cstring_header *h = (struct cstring_header *)cstring;
++
++	if (!h) {
++		return 0;
++	}
++
++	assert(h->checker == CHECKER_WORD);
++	return h->used;
++}
++
++
++cstring_t cstring_append_chars(cstring_t cstring, const char *newstring)
++{
++	struct cstring_header *h = (struct cstring_header *)cstring;
++	size_t newlen;
++
++	if (!h) {
++		return NULL;
++	}
++
++	assert(h->checker == CHECKER_WORD);
++	if (!newstring) {
++		return NULL;
++	}
++
++	newlen = h->used + strlen(newstring)+1 + sizeof(struct cstring_header);
++	if (newlen > h->allocated) {
++		size_t new_allocsize = (newlen + 2048) & 0xFFFFFC00;
++		char *tmp = realloc(cstring, new_allocsize);
++		if (!tmp) {
++			return cstring;
++		}
++
++		cstring = tmp;
++		h = (struct cstring_header *)cstring;
++		h->allocated = new_allocsize;
++	}
++	strncat(h->the_string, newstring, h->allocated - h->used -1);
++	h->used += strlen(newstring);
++	return cstring;
++}
++
++cstring_t cstring_append_cstring(cstring_t cstring, cstring_t newstring)
++{
++	/* Just check the newstring - cstring_append_chars() will check the target */
++	struct cstring_header *h = (struct cstring_header *)newstring;
++
++	if (!h) {
++		return NULL;
++	}
++
++	assert(h->checker == CHECKER_WORD);
++	return cstring_append_chars(cstring, h->the_string);
++}
++
++cstring_t cstring_from_chars(const char* chars)
++{
++	cstring_t new_string = cstring_alloc();
++	if (!new_string) {
++		return NULL;
++	}
++	return cstring_append_chars(new_string, chars);
++}
++
++void cstring_free(cstring_t cstring)
++{
++	struct cstring_header *h = (struct cstring_header *)cstring;
++
++	if (!h) {
++		return;
++	}
++	assert(h->checker == CHECKER_WORD);
++	free(cstring);
++}
++
++
+diff --git a/man/cstring.h b/man/cstring.h
+new file mode 100644
+index 00000000..172a4e6b
+--- /dev/null
++++ b/man/cstring.h
+@@ -0,0 +1,15 @@
++#ifndef __CSTRING_H__
++#define __CSTRING_H__
++
++typedef void* cstring_t;
++
++cstring_t cstring_alloc(void);
++cstring_t cstring_from_chars(const char* chars);
++cstring_t cstring_dup(cstring_t string);
++char *cstring_to_chars(cstring_t cstring);
++cstring_t cstring_append_chars(cstring_t cstring, const char *newstring);
++cstring_t cstring_append_cstring(cstring_t cstring, cstring_t newstring);
++void cstring_free(cstring_t cstring);
++size_t cstring_len(cstring_t cstring);
++
++#endif
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 72fda764..73f705d3 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -17,6 +17,7 @@
+ 
+ #define _DEFAULT_SOURCE
+ #define _BSD_SOURCE
++#define _GNU_SOURCE
+ #define _XOPEN_SOURCE
+ #define _XOPEN_SOURCE_EXTENDED
+ #include <stdlib.h>
+@@ -32,6 +33,7 @@
+ #include <libxml/tree.h>
+ #include <qb/qblist.h>
+ #include <qb/qbmap.h>
++#include "cstring.h"
+ 
+ /*
+  * This isn't a maximum size, it just defines how long a parameter
+@@ -41,12 +43,16 @@
+  */
+ #define LINE_LENGTH 80
+ 
++/* Similar - but for structure member comments */
++#define STRUCT_COMMENT_LENGTH 50
++
+ static int print_ascii = 1;
+ static int print_man = 0;
+ static int print_params = 0;
+ static int print_general = 0;
+ static int num_functions = 0;
+-static int quiet=0;
++static int quiet = 0;
++static int use_header_copyright = 0;
+ static const char *man_section="3";
+ static const char *package_name="Package";
+ static const char *header="Programmer's Manual";
+@@ -57,6 +63,8 @@ static const char *xml_file;
+ static const char *manpage_date = NULL;
+ static const char *headerfile = NULL;
+ static const char *header_prefix = "";
++static const char *header_src_dir = "./";
++static char header_copyright[256] = "\0";
+ static long manpage_year = LONG_MIN;
+ static long start_year = 2010;
+ static struct qb_list_head params_list;
+@@ -82,8 +90,10 @@ struct struct_info {
+ 	struct qb_list_head list;
+ };
+ 
+-static char *get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext);
++static cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext, int add_nl);
+ static void traverse_node(xmlNode *parentnode, const char *leafname, void (do_members(xmlNode*, void*)), void *arg);
++static cstring_t get_text(xmlNode *cur_node, char **returntext, char **notetext);
++static void man_print_long_string(FILE *manfile, char *text);
+ 
+ static void free_paraminfo(struct param_info *pi)
+ {
+@@ -105,11 +115,11 @@ static char *get_attr(xmlNode *node, const char *tag)
+ 	return NULL;
+ }
+ 
+-static char *get_child(xmlNode *node, const char *tag)
++static cstring_t get_child(xmlNode *node, const char *tag)
+ {
+-	xmlNode *this_node;
+-	xmlNode *child;
+-	char buffer[1024] = {'\0'};
++        xmlNode *this_node;
++        xmlNode *child;
++        cstring_t buffer = cstring_alloc();
+ 	char *refid = NULL;
+ 	char *declname = NULL;
+ 
+@@ -122,12 +132,12 @@ static char *get_child(xmlNode *node, const char *tag)
+ 			refid = NULL;
+ 			for (child = this_node->children; child; child = child->next) {
+ 				if (child->content) {
+-					strncat(buffer, (char *)child->content, sizeof(buffer)-1);
++					buffer = cstring_append_chars(buffer, (char *)child->content);
+ 				}
+ 
+ 				if ((strcmp( (char*)child->name, "ref") == 0)) {
+ 					if (child->children->content) {
+-						strncat(buffer,(char *)child->children->content, sizeof(buffer)-1);
++						buffer = cstring_append_chars(buffer, (char *)child->children->content);
+ 					}
+ 					refid = get_attr(child, "refid");
+ 				}
+@@ -137,7 +147,7 @@ static char *get_child(xmlNode *node, const char *tag)
+ 			qb_map_put(used_structures_map, refid, declname);
+ 		}
+ 	}
+-	return strdup(buffer);
++	return buffer;
+ }
+ 
+ static struct param_info *find_param_by_name(struct qb_list_head *list, const char *name)
+@@ -183,7 +193,8 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
+ 				sub_tag->children->next->children) {
+ 				paramname = (char*)sub_tag->children->next->children->content;
+ 			}
+-			if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "parameterdescription") == 0 &&
++			if (sub_tag->type == XML_ELEMENT_NODE &&
++			    strcmp((char *)sub_tag->name, "parameterdescription") == 0 &&
+ 			    paramname && sub_tag->children->next->children) {
+ 				paramdesc = (char*)sub_tag->children->next->children->content;
+ 
+@@ -197,7 +208,7 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
+ 					if (pi) {
+ 						pi->paramname = paramname;
+ 						pi->paramdesc = paramdesc;
+-						pi->paramtype = NULL; /* retval */
++						pi->paramtype = NULL; /* it's a retval */
+ 						qb_list_add_tail(&pi->list, list);
+ 					}
+ 				}
+@@ -206,61 +217,152 @@ static void get_param_info(xmlNode *cur_node, struct qb_list_head *list)
+ 	}
+ }
+ 
+-static char *get_text(xmlNode *cur_node, char **returntext, char **notetext)
++static cstring_t get_codeline(xmlNode *this_tag)
++{
++	cstring_t buffer = cstring_alloc();
++	xmlNode *sub_tag;
++
++	for (sub_tag = this_tag; sub_tag; sub_tag = sub_tag->next) {
++		if (strcmp((char*)sub_tag->name, "sp") == 0) {
++			buffer = cstring_append_chars(buffer, " ");
++		}
++		if (strcmp((char*)sub_tag->name, "text") == 0) {
++			// If the line starts with a dot then escape the first one to
++			// stop nroff thinking it's a macro
++			char *tmp = (char*)sub_tag->content;
++			if (tmp[0] == '.') {
++				buffer = cstring_append_chars(buffer, (char*)"\\[char46]");
++				tmp += 1;
++			}
++			buffer = cstring_append_chars(buffer, tmp);
++		}
++		if (strcmp((char*)sub_tag->name, "ref") == 0) {
++			// Handled by the child recusion below
++		}
++		if (sub_tag->children) {
++			char *tmp = get_codeline(sub_tag->children);
++			buffer = cstring_append_cstring(buffer, tmp);
++			cstring_free(tmp);
++		}
++	}
++	return buffer;
++}
++
++static cstring_t get_codetree(xmlNode *cur_node)
++{
++	xmlNode *this_tag;
++	cstring_t buffer = cstring_alloc();
++	cstring_t tmp;
++
++	if (print_man) {
++		buffer = cstring_append_chars(buffer, "\n.nf\n");
++	}
++
++	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
++		if (strcmp((char*)this_tag->name, "codeline") == 0) {
++
++			tmp = get_codeline(this_tag->children);
++			buffer = cstring_append_cstring(buffer, tmp);
++			cstring_free(tmp);
++		}
++		if (strcmp((char*)this_tag->name, "text") == 0) {
++			buffer = cstring_append_chars(buffer, (char*)this_tag->content);
++		}
++	}
++
++	if (print_man) {
++		buffer = cstring_append_chars(buffer, ".fi\n");
++	}
++
++	return buffer;
++}
++
++
++static cstring_t get_text(xmlNode *cur_node, char **returntext, char **notetext)
+ {
+ 	xmlNode *this_tag;
+ 	xmlNode *sub_tag;
+ 	char *kind;
+-	char buffer[4096] = {'\0'};
++	cstring_t buffer = cstring_alloc();
+ 
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 		if (this_tag->type == XML_TEXT_NODE && strcmp((char *)this_tag->name, "text") == 0) {
+ 			if (not_all_whitespace((char*)this_tag->content)) {
+-				strncat(buffer, (char*)this_tag->content, sizeof(buffer)-1);
++				buffer = cstring_append_chars(buffer, (char*)this_tag->content);
+ 			}
+ 		}
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "emphasis") == 0) {
+ 			if (print_man) {
+-				strncat(buffer, "\\fB", sizeof(buffer)-1);
++				buffer = cstring_append_chars(buffer, "\\fB");
+ 			}
+-			strncat(buffer, (char*)this_tag->children->content, sizeof(buffer)-1);
++			buffer = cstring_append_chars(buffer, (char*)this_tag->children->content);
+ 			if (print_man) {
+-				strncat(buffer, "\\fR", sizeof(buffer)-1);
++				buffer = cstring_append_chars(buffer, "\\fR");
+ 			}
+ 		}
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "ref") == 0) {
+ 			if (print_man) {
+-				strncat(buffer, "\\fI", sizeof(buffer)-1);
++				buffer = cstring_append_chars(buffer, "\\fI");
++			}
++			buffer = cstring_append_chars(buffer, (char*)this_tag->children->content);
++			if (print_man) {
++				buffer = cstring_append_chars(buffer, "\\fR");
++			}
++		}
++		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "computeroutput") == 0) {
++			if (print_man) {
++				buffer = cstring_append_chars(buffer, "\\fB");
+ 			}
+-			strncat(buffer, (char*)this_tag->children->content, sizeof(buffer)-1);
++			buffer = cstring_append_chars(buffer, (char*)this_tag->children->content);
+ 			if (print_man) {
+-				strncat(buffer, "\\fR", sizeof(buffer)-1);
++				buffer = cstring_append_chars(buffer, "\\fP");
+ 			}
+ 		}
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "itemizedlist") == 0) {
+ 			for (sub_tag = this_tag->children; sub_tag; sub_tag = sub_tag->next) {
+-				if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "listitem") == 0) {
+-					strncat(buffer, (char*)sub_tag->children->children->content, sizeof(buffer)-1);
+-					strncat(buffer, "\n", sizeof(buffer)-1);
++				if (sub_tag->type == XML_ELEMENT_NODE && strcmp((char *)sub_tag->name, "listitem") == 0
++				    && sub_tag->children->children->content) {
++					buffer = cstring_append_chars(buffer, (char*)sub_tag->children->children->content);
++					buffer = cstring_append_chars(buffer, "\n");
+ 				}
+ 			}
+ 		}
+ 
++		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "programlisting") == 0) {
++			cstring_t tmp = get_codetree(this_tag);
++			buffer = cstring_append_cstring(buffer, tmp);
++			buffer = cstring_append_chars(buffer, "\n");
++			cstring_free(tmp);
++		}
++
+ 		/* Look for subsections - return value & params */
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "simplesect") == 0) {
+-			char *tmp;
++			cstring_t tmp;
+ 
+ 			kind = get_attr(this_tag, "kind");
+ 			tmp = get_text(this_tag->children, NULL, NULL);
+ 
+ 			if (returntext && strcmp(kind, "return") == 0) {
+-				*returntext = tmp;
++				*returntext = cstring_to_chars(tmp);
+ 			}
+ 			if (notetext && strcmp(kind, "note") == 0) {
+-				*notetext = tmp;
++				*notetext = cstring_to_chars(tmp);
++			}
++			if (notetext && strcmp(kind, "par") == 0) {
++				int type;
++
++				tmp = get_child(this_tag, "title");
++				buffer = cstring_append_cstring(buffer, tmp);
++				buffer = cstring_append_chars(buffer, "\n");
++				cstring_free(tmp);
++
++				tmp = get_texttree(&type,this_tag, NULL, NULL, 1);
++				buffer = cstring_append_cstring(buffer, tmp);
++				buffer = cstring_append_chars(buffer, "\n");
+ 			}
++			cstring_free(tmp);
+ 		}
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "parameterlist") == 0) {
+@@ -273,7 +375,7 @@ static char *get_text(xmlNode *cur_node, char **returntext, char **notetext)
+ 			}
+ 		}
+ 	}
+-	return strdup(buffer);
++	return buffer;
+ }
+ 
+ static void read_structname(xmlNode *cur_node, void *arg)
+@@ -295,16 +397,13 @@ static void read_structdesc(xmlNode *cur_node, void *arg)
+ 
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 		if (strcmp((char*)this_tag->name, "detaileddescription") == 0) {
+-			char *desc = get_texttree(NULL, this_tag, NULL, NULL);
+-			if (desc) {
+-				si->description = strdup((char*)desc);
+-			}
++			cstring_t desc = get_texttree(NULL, this_tag, NULL, NULL, 1);
++			si->description = cstring_to_chars(desc);
++			cstring_free(desc);
+ 		}
+ 		if (strcmp((char*)this_tag->name, "briefdescription") == 0) {
+-			char *brief = get_texttree(NULL, this_tag, NULL, NULL);
+-			if (brief) {
+-				si->brief_description = brief;
+-			}
++			cstring_t brief = get_texttree(NULL, this_tag, NULL, NULL, 1);
++			si->brief_description = cstring_to_chars(brief);
+ 		}
+ 	}
+ }
+@@ -328,10 +427,11 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ {
+ 	xmlNode *this_tag;
+ 	struct struct_info *si=arg;
+-	struct param_info *pi;
++	struct param_info *pi = NULL;
+ 	char fullname[1024];
+ 	char *type = NULL;
+ 	char *name = NULL;
++	char *desc = NULL;
+ 	const char *args="";
+ 
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+@@ -339,7 +439,9 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ 			type = (char*)this_tag->children->content;
+ 			/* If type is NULL then look for a ref - it's probably an external struct or typedef */
+ 			if (type == NULL) {
+-				type = get_child(this_tag, "ref");
++				cstring_t tmp = get_child(this_tag, "ref");
++				type = cstring_to_chars(tmp);
++				cstring_free(tmp);
+ 			}
+ 		}
+ 		if (strcmp((char*)this_tag->name, "name") == 0) {
+@@ -348,6 +450,13 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ 		if (this_tag->children && strcmp((char*)this_tag->name, "argsstring") == 0) {
+ 			args = (char*)this_tag->children->content;
+ 		}
++		if (this_tag->children && strcmp((char*)this_tag->name, "detaileddescription") == 0) {
++			cstring_t *desc_cs = get_texttree(NULL, this_tag, NULL, NULL, 0);
++			if (cstring_len(desc_cs) > 1) {
++				desc = cstring_to_chars(desc_cs);
++			}
++			cstring_free(desc_cs);
++		}
+ 	}
+ 
+ 	if (name) {
+@@ -356,10 +465,14 @@ static void read_struct(xmlNode *cur_node, void *arg)
+ 			snprintf(fullname, sizeof(fullname), "%s%s", name, args);
+ 			pi->paramtype = type?strdup(type):strdup("");
+ 			pi->paramname = strdup(fullname);
+-			pi->paramdesc = NULL;
++			pi->paramdesc = desc;
+ 			qb_list_add_tail(&pi->list, &si->params_list);
+ 		}
+ 	}
++	/* Tidy */
++	if (!name || !pi) {
++		free(desc);
++	}
+ }
+ 
+ static int read_structure_from_xml(const char *refid, const char *name)
+@@ -408,17 +521,44 @@ static int read_structure_from_xml(const char *refid, const char *name)
+ 
+ static char *allcaps(const char *name)
+ {
+-	static char buffer[1024] = {'\0'};
++	static char buffer[4096] = {'\0'};
+ 	size_t i;
+ 
+-	for (i=0; i< strlen(name); i++) {
+-		buffer[i] = toupper(name[i]);
++	if (name) {
++		size_t len = strnlen(name, 4096);
++		for (i=0; i< len; i++) {
++			buffer[i] = toupper(name[i]);
++		}
++		buffer[len] = '\0';
+ 	}
+-	buffer[strlen(name)] = '\0';
+ 	return buffer;
+ }
+ 
+-static void print_param(FILE *manfile, struct param_info *pi, int field_width, int bold, const char *delimiter)
++/*
++ * Print a structure comment that would be too long
++ * to fit after the structure member, in a style ...
++ * well, in a style like this!
++ */
++static void print_long_structure_comment(FILE *manfile, char *comment)
++{
++	char *ptr = strtok(comment, " ");
++	int column = 7;
++
++	fprintf(manfile, "\\fP    /*");
++	fprintf(manfile, "\n     *");
++	while (ptr) {
++		column += strlen(ptr)+1;
++		if (column > 80) {
++			fprintf(manfile, "\n     *");
++			column = 7;
++		}
++		fprintf(manfile, " %s", ptr);
++		ptr = strtok(NULL, " ");
++	}
++	fprintf(manfile, "\n     */\n");
++}
++
++static void print_param(FILE *manfile, struct param_info *pi, int type_field_width, int name_field_width, int bold, const char *delimiter)
+ {
+ 	const char *asterisks = "  ";
+ 	char *type = pi->paramtype;
+@@ -443,9 +583,32 @@ static void print_param(FILE *manfile, struct param_info *pi, int field_width, i
+ 		}
+ 	}
+ 
+-	fprintf(manfile, "    %s%-*s%s%s\\fI%s\\fP%s\n",
+-		bold?"\\fB":"", field_width, type,
+-		asterisks, bold?"\\fP":"", pi->paramname, delimiter);
++	/* Print structure description if available */
++	if (pi->paramdesc) {
++		/* Too long to go on the same line? */
++		if (strlen(pi->paramdesc) > STRUCT_COMMENT_LENGTH) {
++			print_long_structure_comment(manfile, pi->paramdesc);
++			fprintf(manfile, "    %s%-*s%s%s\\fI%s\\fP%s\n",
++				bold?"\\fB":"", type_field_width, type,
++				asterisks, bold?"\\fP":"",
++				pi->paramname?pi->paramname:"", delimiter);
++		} else {
++			/* Pad out so they all line up */
++			int pad_length = name_field_width -
++				(pi->paramname?strlen(pi->paramname):0) + 1;
++			fprintf(manfile, "    %s%-*s%s%s\\fI%s\\fP%s\\fR%*s/* %s*/\n",
++				bold?"\\fB":"", type_field_width, type,
++				asterisks, bold?"\\fP":"",
++				pi->paramname?pi->paramname:"", delimiter,
++				pad_length, " ",
++				pi->paramdesc);
++		}
++	} else {
++		fprintf(manfile, "    %s%-*s%s%s\\fI%s\\fP%s\n",
++			bold?"\\fB":"", type_field_width, type,
++			asterisks, bold?"\\fP":"",
++			pi->paramname?pi->paramname:"", delimiter);
++	}
+ 
+ 	if (type != pi->paramtype) {
+ 		free(type);
+@@ -457,9 +620,9 @@ static void print_structure(FILE *manfile, struct struct_info *si)
+ 	struct param_info *pi;
+ 	struct qb_list_head *iter;
+ 	unsigned int max_param_length=0;
++	unsigned int max_param_name_length=0;
+ 
+ 	fprintf(manfile, ".nf\n");
+-	fprintf(manfile, "\\fB\n");
+ 
+ 	if (si->brief_description) {
+ 		fprintf(manfile, "%s\n", si->brief_description);
+@@ -473,8 +636,12 @@ static void print_structure(FILE *manfile, struct struct_info *si)
+ 		if (strlen(pi->paramtype) > max_param_length) {
+ 			max_param_length = strlen(pi->paramtype);
+ 		}
++		if (strlen(pi->paramname) > max_param_name_length) {
++			max_param_name_length = strlen(pi->paramname);
++		}
+ 	}
+ 
++	fprintf(manfile, "\\fB\n");
+ 	if (si->kind == STRUCTINFO_STRUCT) {
+ 		fprintf(manfile, "struct %s {\n", si->structname);
+ 	} else if (si->kind == STRUCTINFO_ENUM) {
+@@ -482,10 +649,12 @@ static void print_structure(FILE *manfile, struct struct_info *si)
+ 	} else {
+ 		fprintf(manfile, "%s {\n", si->structname);
+ 	}
++	fprintf(manfile, "\\fR\n");
+ 
+ 	qb_list_for_each(iter, &si->params_list) {
++		fprintf(manfile, "\\fB\n");
+ 		pi = qb_list_entry(iter, struct param_info, list);
+-		print_param(manfile, pi, max_param_length, 0,";");
++		print_param(manfile, pi, max_param_length, max_param_name_length, 1, ";");
+ 	}
+ 	fprintf(manfile, "};\n");
+ 
+@@ -493,27 +662,25 @@ static void print_structure(FILE *manfile, struct struct_info *si)
+ 	fprintf(manfile, ".fi\n");
+ }
+ 
+-char *get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext)
++cstring_t get_texttree(int *type, xmlNode *cur_node, char **returntext, char **notetext, int add_nl)
+ {
+ 	xmlNode *this_tag;
+-	char *tmp = NULL;
+-	char buffer[4096] = {'\0'};
++	cstring_t tmp;
++	cstring_t buffer = cstring_alloc();
+ 
+ 	for (this_tag = cur_node->children; this_tag; this_tag = this_tag->next) {
+ 
+ 		if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "para") == 0) {
+ 			tmp = get_text(this_tag, returntext, notetext);
+-			strncat(buffer, tmp, sizeof(buffer)-1);
+-			strncat(buffer, "\n", sizeof(buffer)-1);
+-			free(tmp);
+-		}
+-	}
++			buffer = cstring_append_cstring(buffer, tmp);
++			if (add_nl) {
++				buffer = cstring_append_chars(buffer, "\n");
++			}
+ 
+-	if (buffer[0]) {
+-		return strdup(buffer);
+-	} else {
+-		return NULL;
++			cstring_free(tmp);
++		}
+ 	}
++	return buffer;
+ }
+ 
+ /* The text output is VERY basic and just a check that it's working really */
+@@ -554,12 +721,29 @@ static void man_print_long_string(FILE *manfile, char *text)
+ {
+ 	char *next_nl;
+ 	char *current = text;
++	int in_prog = 0;
+ 
+ 	next_nl = strchr(text, '\n');
+ 	while (next_nl && *next_nl != '\0') {
+ 		*next_nl = '\0';
+-		if (strlen(current)) {
+-			fprintf(manfile, ".PP\n%s\n", current);
++
++		// Don't format @code blocks
++		if (strncmp(current, ".nf", 3) == 0) {
++			in_prog = 1;
++			fprintf(manfile, "\n");
++		}
++
++		if (in_prog) {
++			fprintf(manfile, "%s\n", current);
++		} else {
++			if (strlen(current)) {
++				fprintf(manfile, ".PP\n%s\n", current);
++			}
++		}
++
++		if (strncmp(current, ".fi", 3) == 0) {
++			in_prog = 0;
++			fprintf(manfile, "\n");
+ 		}
+ 
+ 		*next_nl = '\n';
+@@ -568,7 +752,7 @@ static void man_print_long_string(FILE *manfile, char *text)
+ 	}
+ 
+ 	/* The bit at the end */
+-	if (strlen(current)) {
++	if (strlen(current) && !in_prog) {
+ 		fprintf(manfile, ".PP\n%s\n", current);
+ 	}
+ }
+@@ -622,7 +806,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	max_param_name_len = 0;
+ 	num_param_descs = 0;
+ 
+-	qb_list_for_each(iter, &params_list) {
++	qb_list_for_each(iter, param_map) {
+ 		pi = qb_list_entry(iter, struct param_info, list);
+ 
+ 		/* It's mainly macros that break this,
+@@ -638,7 +822,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 		if (strlen(pi->paramname) > max_param_name_len) {
+ 			max_param_name_len = strlen(pi->paramname);
+ 		}
+-		if (pi->paramdesc) {
++		if (pi->paramdesc && pi->paramtype[0] != '\0') {
+ 			num_param_descs++;
+ 		}
+ 		param_count++;
+@@ -650,7 +834,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	fprintf(manfile, ".TH %s %s %s \"%s\" \"%s\"\n", allcaps(name), man_section, dateptr, package_name, header);
+ 
+ 	fprintf(manfile, ".SH NAME\n");
+-	if (brief) {
++	if (brief && not_all_whitespace(brief)) {
+ 		fprintf(manfile, "%s \\- %s\n", name, brief);
+ 	} else {
+ 		fprintf(manfile, "%s\n", name);
+@@ -663,10 +847,12 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 		fprintf(manfile, ".sp\n");
+ 		fprintf(manfile, "\\fB%s\\fP(\n", def);
+ 
+-		qb_list_for_each(iter, &params_list) {
++		qb_list_for_each(iter, param_map) {
+ 			pi = qb_list_entry(iter, struct param_info, list);
+ 
+-			print_param(manfile, pi, max_param_type_len, 1, ++param_num < param_count?",":"");
++			if (pi->paramtype[0] != '\0') {
++				print_param(manfile, pi, max_param_type_len, 0, 1, ++param_num < param_count?",":"");
++			}
+ 		}
+ 
+ 		fprintf(manfile, ");\n");
+@@ -677,7 +863,7 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 		fprintf(manfile, ".SH PARAMS\n");
+ 
+ 		qb_list_for_each(iter, &params_list) {
+-		pi = qb_list_entry(iter, struct param_info, list);
++			pi = qb_list_entry(iter, struct param_info, list);
+ 			fprintf(manfile, "\\fB%-*s \\fP\\fI%s\\fP\n", (int)max_param_name_len, pi->paramname,
+ 				pi->paramdesc);
+ 			fprintf(manfile, ".PP\n");
+@@ -721,9 +907,11 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 		fprintf(manfile, ".RE\n");
+ 	}
+ 
+-	if (returntext) {
++	if (returntext || !qb_list_empty(&retval_list)) {
+ 		fprintf(manfile, ".SH RETURN VALUE\n");
+-		man_print_long_string(manfile, returntext);
++		if (returntext) {
++			man_print_long_string(manfile, returntext);
++		}
+ 		fprintf(manfile, ".PP\n");
+ 	}
+ 
+@@ -763,7 +951,11 @@ static void print_manpage(char *name, char *def, char *brief, char *args, char *
+ 	fprintf(manfile, ".hy\n");
+ 	fprintf(manfile, ".SH \"COPYRIGHT\"\n");
+ 	fprintf(manfile, ".PP\n");
+-	fprintf(manfile, "Copyright (C) %4ld-%4ld %s, Inc. All rights reserved.\n", start_year, manpage_year, company);
++	if (header_copyright[0] == 'C') {
++		fprintf(manfile, "%s", header_copyright); /* String already contains trailing NL */
++	} else {
++		fprintf(manfile, "Copyright (C) %4ld-%4ld %s, Inc. All rights reserved.\n", start_year, manpage_year, company);
++	}
+ 	fclose(manfile);
+ 
+ 	/* Free the params & retval info */
+@@ -854,6 +1046,8 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ {
+ 	xmlNode *this_tag;
+ 
++	qb_list_init(&params_list);
++
+ 	/* if arg == NULL then we're generating a page for the whole header file */
+ 	if ((cur_node->name && (strcmp((char *)cur_node->name, "memberdef") == 0)) ||
+ 	    ((arg == NULL) && cur_node->name && strcmp((char *)cur_node->name, "compounddef")) == 0) {
+@@ -884,26 +1078,31 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 				name = strdup((char *)this_tag->children->content);
+ 
+ 			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "briefdescription") == 0) {
+-				brief = get_texttree(&type, this_tag, &returntext, &notetext);
+-				if (brief) {
+-					/*
+-					 * apparently brief text contains extra trailing space and a \n.
+-					 * remove them.
+-					 */
+-					brief[strlen(brief) - 2] = '\0';
++				cstring_t tmp = get_texttree(&type, this_tag, &returntext, &notetext, 1);
++				if (!brief) {
++					brief = cstring_to_chars(tmp);
++				} else {
++					fprintf(stderr, "ERROR function %s has 2 briefdescription tags\n", name?name:"unknown");
+ 				}
++				cstring_free(tmp);
+ 			}
+ 			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "detaileddescription") == 0) {
+-				detailed = get_texttree(&type, this_tag, &returntext, &notetext);
++				cstring_t tmp = get_texttree(&type, this_tag, &returntext, &notetext, 1);
++				if (!detailed) {
++					detailed = cstring_to_chars(tmp);
++				} else {
++					fprintf(stderr, "ERROR function %s has 2 detaileddescription tags\n", name?name:"unknown");
++				}
++				cstring_free(tmp);
+ 			}
+ 			/* Get all the params */
+ 			if (this_tag->type == XML_ELEMENT_NODE && strcmp((char *)this_tag->name, "param") == 0) {
+-				char *param_type = get_child(this_tag, "type");
+-				char *param_name = get_child(this_tag, "declname");
++				cstring_t param_type = get_child(this_tag, "type");
++				cstring_t param_name = get_child(this_tag, "declname");
+ 				struct param_info *pi = malloc(sizeof(struct param_info));
+ 				if (pi) {
+-					pi->paramname = param_name;
+-					pi->paramtype = param_type;
++					pi->paramname = cstring_to_chars(param_name);
++					pi->paramtype = cstring_to_chars(param_type);
+ 					pi->paramdesc = NULL;
+ 					qb_list_add_tail(&pi->list, &params_list);
+ 				}
+@@ -951,6 +1150,8 @@ static void traverse_members(xmlNode *cur_node, void *arg)
+ 		free(def);
+ 		free(args);
+ 		free(name);
++		free(brief);
++		free(detailed);
+ 	}
+ }
+ 
+@@ -993,6 +1194,8 @@ static void usage(char *name)
+ 	printf("       -m            Write man page files to <output dir>\n");
+ 	printf("       -P            Print PARAMS section\n");
+ 	printf("       -g            Print general man page for the whole header file\n");
++	printf("       -c            Use the Copyright date from the header file (if one can be found)\n");
++	printf("       -O <dir>      Directory for the orignal header file. Often needed by -c above\n");
+ 	printf("       -s <s>        Write man pages into section <s> <default 3)\n");
+ 	printf("       -p <package>  Use <package> name. default <Package>\n");
+ 	printf("       -H <header>   Set header (default \"Programmer's Manual\"\n");
+@@ -1029,7 +1232,7 @@ int main(int argc, char *argv[])
+ 	int opt;
+ 	char xml_filename[PATH_MAX];
+ 
+-	while ( (opt = getopt_long(argc, argv, "H:amqgPD:Y:s:S:d:o:p:f:I:i:C:h?", NULL, NULL)) != EOF)
++	while ( (opt = getopt_long(argc, argv, "H:amqgcPD:Y:s:S:d:o:p:f:I:i:C:O:h?", NULL, NULL)) != EOF)
+ 	{
+ 		switch(opt)
+ 		{
+@@ -1050,6 +1253,9 @@ int main(int argc, char *argv[])
+ 			case 'q':
+ 				quiet = 1;
+ 				break;
++			case 'c':
++				use_header_copyright = 1;
++				break;
+ 			case 'I':
+ 				headerfile = optarg;
+ 				break;
+@@ -1089,6 +1295,9 @@ int main(int argc, char *argv[])
+ 			case 'o':
+ 				output_dir = optarg;
+ 				break;
++			case 'O':
++			        header_src_dir = optarg;
++				break;
+ 			case '?':
+ 			case 'h':
+ 				usage(argv[0]);
+@@ -1126,7 +1335,32 @@ int main(int argc, char *argv[])
+ 	/* Get our header file name */
+ 	if (!headerfile) {
+ 		traverse_node(rootdoc, "compounddef", read_headername, &headerfile);
++
++		if (use_header_copyright) {
++			/* And get the copyright line from this file if we can */
++			char file_path[PATH_MAX];
++			char file_line[256];
++			FILE *hfile;
++			int lineno = 0;
++
++			snprintf(file_path, sizeof(file_path), "%s/%s", header_src_dir, headerfile);
++			hfile = fopen(file_path, "r");
++			if (hfile) {
++				/* Don't look too far, this should be at the top */
++				while (!feof(hfile) && (lineno++ < 10)) {
++					if (fgets(file_line, sizeof(file_line)-1, hfile)) {
++						if (strncmp(file_line, " * Copyright", 12) == 0) {
++							/* Keep the NL at the end of the buffer, it save us printing one */
++							strncpy(header_copyright, file_line+3, sizeof(header_copyright)-1);
++							break;
++						}
++					}
++				}
++				fclose(hfile);
++			}
++		}
+ 	}
++
+ 	/* Default to *something* if it all goes wrong */
+ 	if (!headerfile) {
+ 		headerfile = "unknown.h";
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0427-rx-increase-defrag-buffers-to-better-deal-with-netwo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0427-rx-increase-defrag-buffers-to-better-deal-with-netwo.patch
new file mode 100644
index 000000000..024e2d559
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0427-rx-increase-defrag-buffers-to-better-deal-with-netwo.patch
@@ -0,0 +1,93 @@ 
+From 229457366bc1e57dc35c2acdc586e19241ac1b7a Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 5 Aug 2021 10:08:46 +0200
+Subject: [PATCH] [rx] increase defrag buffers to better deal with network
+ jitter
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c       | 6 +++---
+ libknet/internals.h  | 3 ++-
+ libknet/threads_rx.c | 6 +++---
+ 3 files changed, 8 insertions(+), 7 deletions(-)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index 46183b84..96f19365 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -526,7 +526,7 @@ static void _clear_cbuffers(struct knet_host *host, seq_num_t rx_seq_num)
+ 
+ 	memset(host->circular_buffer_defrag, 0, KNET_CBUFFER_SIZE);
+ 
+-	for (i = 0; i < KNET_MAX_LINK; i++) {
++	for (i = 0; i < KNET_DEFRAG_BUFFERS; i++) {
+ 		memset(&host->defrag_buf[i], 0, sizeof(struct knet_host_defrag_buf));
+ 	}
+ }
+@@ -537,12 +537,12 @@ static void _reclaim_old_defrag_bufs(struct knet_host *host, seq_num_t seq_num)
+ 	int i;
+ 
+ 	head = seq_num + 1;
+-	tail = seq_num - (KNET_MAX_LINK + 1);
++	tail = seq_num - (KNET_DEFRAG_BUFFERS + 1);
+ 
+ 	/*
+ 	 * expire old defrag buffers
+ 	 */
+-	for (i = 0; i < KNET_MAX_LINK; i++) {
++	for (i = 0; i < KNET_DEFRAG_BUFFERS; i++) {
+ 		if (host->defrag_buf[i].in_use) {
+ 			/*
+ 			 * head has done a rollover to 0+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 64c94fec..7527c3fd 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -95,6 +95,7 @@ struct knet_link {
+ 	uint8_t has_valid_mtu;
+ };
+ 
++#define KNET_DEFRAG_BUFFERS 32
+ #define KNET_CBUFFER_SIZE 4096
+ 
+ struct knet_host_defrag_buf {
+@@ -124,7 +125,7 @@ struct knet_host {
+ 	seq_num_t timed_rx_seq_num;
+ 	uint8_t got_data;
+ 	/* defrag/reassembly buffers */
+-	struct knet_host_defrag_buf defrag_buf[KNET_MAX_LINK];
++	struct knet_host_defrag_buf defrag_buf[KNET_DEFRAG_BUFFERS];
+ 	char circular_buffer_defrag[KNET_CBUFFER_SIZE];
+ 	/* link stuff */
+ 	struct knet_link link[KNET_MAX_LINK];
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 1b4921ab..d671a845 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -70,7 +70,7 @@ static int find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_header *inbuf)
+ 	/*
+ 	 * check if there is a buffer already in use handling the same seq_num
+ 	 */
+-	for (i = 0; i < KNET_MAX_LINK; i++) {
++	for (i = 0; i < KNET_DEFRAG_BUFFERS; i++) {
+ 		if (src_host->defrag_buf[i].in_use) {
+ 			if (src_host->defrag_buf[i].pckt_seq == inbuf->khp_data_seq_num) {
+ 				return i;
+@@ -98,7 +98,7 @@ static int find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_header *inbuf)
+ 	/*
+ 	 * see if there is a free buffer
+ 	 */
+-	for (i = 0; i < KNET_MAX_LINK; i++) {
++	for (i = 0; i < KNET_DEFRAG_BUFFERS; i++) {
+ 		if (!src_host->defrag_buf[i].in_use) {
+ 			return i;
+ 		}
+@@ -112,7 +112,7 @@ static int find_pckt_defrag_buf(knet_handle_t knet_h, struct knet_header *inbuf)
+ 
+ 	oldest = 0;
+ 
+-	for (i = 0; i < KNET_MAX_LINK; i++) {
++	for (i = 0; i < KNET_DEFRAG_BUFFERS; i++) {
+ 		if (timecmp(src_host->defrag_buf[i].last_update, src_host->defrag_buf[oldest].last_update) < 0) {
+ 			oldest = i;
+ 		}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0428-host-use-correct-seq_num-to-reclaim-buffers.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0428-host-use-correct-seq_num-to-reclaim-buffers.patch
new file mode 100644
index 000000000..1f1423b8e
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0428-host-use-correct-seq_num-to-reclaim-buffers.patch
@@ -0,0 +1,29 @@ 
+From 10021626510c4143b96aceab97c1da6555dd6178 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 5 Aug 2021 05:56:38 +0200
+Subject: [PATCH] [host] use correct seq_num to reclaim buffers
+
+we cannot use incoming packet seq_num to reclaim buffers as that causes
+havoc.
+
+use latest recorded (highest) packet number instead that follows the
+reclaiming window
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index 96f19365..ec73c0df 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -577,7 +577,7 @@ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, i
+ 		_clear_cbuffers(host, seq_num);
+ 	}
+ 
+-	_reclaim_old_defrag_bufs(host, seq_num);
++	_reclaim_old_defrag_bufs(host, *dst_seq_num);
+ 
+ 	if (seq_num < *dst_seq_num) {
+ 		seq_dist =  (SEQ_MAX - seq_num) + *dst_seq_num;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0429-acl-make-knet_link_add_acl-a-wrapper-to-knet_link_in.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0429-acl-make-knet_link_add_acl-a-wrapper-to-knet_link_in.patch
new file mode 100644
index 000000000..06c574b05
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0429-acl-make-knet_link_add_acl-a-wrapper-to-knet_link_in.patch
@@ -0,0 +1,133 @@ 
+From 593ae10301295c546b33e99c3db041eb772dc6e6 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 2 Jul 2021 06:57:05 +0200
+Subject: [PATCH] [acl] make knet_link_add_acl a wrapper to
+ knet_link_insert_acl
+
+remove lots of duplicated code
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/links.c | 102 +++++-------------------------------------------
+ 1 file changed, 9 insertions(+), 93 deletions(-)
+
+diff --git a/libknet/links.c b/libknet/links.c
+index fa63fd17..2e41bdb1 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1257,99 +1257,6 @@ exit_unlock:
+ 	return err;
+ }
+ 
+-int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+-		      struct sockaddr_storage *ss1,
+-		      struct sockaddr_storage *ss2,
+-		      check_type_t type, check_acceptreject_t acceptreject)
+-{
+-	int savederrno = 0, err = 0;
+-	struct knet_host *host;
+-	struct knet_link *link;
+-
+-	if (!_is_valid_handle(knet_h)) {
+-		return -1;
+-	}
+-
+-	if (!ss1) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((type != CHECK_TYPE_ADDRESS) &&
+-	    (type != CHECK_TYPE_MASK) &&
+-	    (type != CHECK_TYPE_RANGE)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((acceptreject != CHECK_ACCEPT) &&
+-	    (acceptreject != CHECK_REJECT)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((type != CHECK_TYPE_ADDRESS) && (!ss2)) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	if ((type == CHECK_TYPE_RANGE) &&
+-	    (ss1->ss_family != ss2->ss_family)) {
+-			errno = EINVAL;
+-			return -1;
+-	}
+-
+-	if (link_id >= KNET_MAX_LINK) {
+-		errno = EINVAL;
+-		return -1;
+-	}
+-
+-	savederrno = get_global_wrlock(knet_h);
+-	if (savederrno) {
+-		log_err(knet_h, KNET_SUB_LINK, "Unable to get write lock: %s",
+-			strerror(savederrno));
+-		errno = savederrno;
+-		return -1;
+-	}
+-
+-	host = knet_h->host_index[host_id];
+-	if (!host) {
+-		err = -1;
+-		savederrno = EINVAL;
+-		log_err(knet_h, KNET_SUB_LINK, "Unable to find host %u: %s",
+-			host_id, strerror(savederrno));
+-		goto exit_unlock;
+-	}
+-
+-	link = &host->link[link_id];
+-
+-	if (!link->configured) {
+-		err = -1;
+-		savederrno = EINVAL;
+-		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is not configured: %s",
+-			host_id, link_id, strerror(savederrno));
+-		goto exit_unlock;
+-	}
+-
+-	if (link->dynamic != KNET_LINK_DYNIP) {
+-		err = -1;
+-		savederrno = EINVAL;
+-		log_err(knet_h, KNET_SUB_LINK, "host %u link %u is a point to point connection: %s",
+-			host_id, link_id, strerror(savederrno));
+-		goto exit_unlock;
+-	}
+-
+-	err = check_add(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport, -1,
+-			ss1, ss2, type, acceptreject);
+-	savederrno = errno;
+-
+-exit_unlock:
+-	pthread_rwlock_unlock(&knet_h->global_rwlock);
+-
+-	errno = savederrno;
+-	return err;
+-}
+-
+ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 			 int index,
+ 			 struct sockaddr_storage *ss1,
+@@ -1444,6 +1351,15 @@ exit_unlock:
+ 	return err;
+ }
+ 
++int knet_link_add_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++		      struct sockaddr_storage *ss1,
++		      struct sockaddr_storage *ss2,
++		      check_type_t type, check_acceptreject_t acceptreject)
++{
++	return knet_link_insert_acl(knet_h, host_id, link_id, -1, ss1, ss2, type, acceptreject);
++}
++
++
+ int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
+ 		     struct sockaddr_storage *ss1,
+ 		     struct sockaddr_storage *ss2,
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0430-acl-major-internal-rework.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0430-acl-major-internal-rework.patch
new file mode 100644
index 000000000..4c18061e6
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0430-acl-major-internal-rework.patch
@@ -0,0 +1,1037 @@ 
+From 1ce5fbba0644020775059fea2435da42a4c6a70e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 5 Jul 2021 09:03:12 +0200
+Subject: [PATCH] [acl] major internal rework
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+ACL internal management was somewhat broken and didn´t really
+do what was advertised for dynamic links.
+
+- fix ACL to be truely per host/link as public API advertise
+- move ACL checking when host/link are known
+- add extensive tests
+- fix various minor bugs that went undetected for a bit
+- enable access list testings on more tests
+
+Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h                      |   2 +-
+ libknet/links.c                          |  12 +-
+ libknet/links_acl.c                      |  26 +-
+ libknet/links_acl.h                      |  13 +-
+ libknet/links_acl_ip.c                   |   9 +-
+ libknet/tests/Makefile.am                |   6 +-
+ libknet/tests/api_knet_link_add_acl.c    |   4 +-
+ libknet/tests/api_knet_link_clear_acl.c  |   6 +-
+ libknet/tests/api_knet_link_insert_acl.c |   4 +-
+ libknet/tests/api_knet_link_rm_acl.c     |   4 +-
+ libknet/tests/api_knet_link_set_config.c |   4 +-
+ libknet/tests/api_knet_send.c            |   8 +
+ libknet/tests/fun_acl_check.c            | 409 +++++++++++++++++++++++
+ libknet/tests/test-common.c              |  19 +-
+ libknet/threads_rx.c                     |  63 ++--
+ libknet/transport_sctp.c                 |  38 ++-
+ 16 files changed, 552 insertions(+), 75 deletions(-)
+ create mode 100644 libknet/tests/fun_acl_check.c
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 7527c3fd..48f25949 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -69,6 +69,7 @@ struct knet_link {
+ 	unsigned int latency_cur_samples;
+ 	uint8_t pong_count;			/* how many ping/pong to send/receive before link is up */
+ 	uint64_t flags;
++	void *access_list_match_entry_head;	/* pointer to access list match_entry list head */
+ 	/* status */
+ 	struct knet_link_status status;
+ 	/* internals */
+@@ -150,7 +151,6 @@ struct knet_fd_trackers {
+ 					     * with this fd */
+ 	socklen_t sockaddr_len;             /* Size of sockaddr_in[6] structure for this socket */
+ 	void *data;			    /* pointer to the data */
+-	void *access_list_match_entry_head; /* pointer to access list match_entry list head */
+ };
+ 
+ #define KNET_MAX_FDS KNET_MAX_HOST * KNET_MAX_LINK * 4
+diff --git a/libknet/links.c b/libknet/links.c
+index 2e41bdb1..8cb1621b 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -301,7 +301,7 @@ int knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+ 		log_debug(knet_h, KNET_SUB_LINK, "Configuring default access lists for host: %u link: %u socket: %d",
+ 			  host_id, link_id, link->outsock);
+-		if ((check_add(knet_h, link->outsock, transport, -1,
++		if ((check_add(knet_h, link, -1,
+ 			       &link->dst_addr, &link->dst_addr,
+ 			       CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 			log_warn(knet_h, KNET_SUB_LINK, "Failed to configure default access lists for host: %u link: %u", host_id, link_id);
+@@ -536,7 +536,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 */
+ 	if ((transport_get_acl_type(knet_h, link->transport) == USE_GENERIC_ACL) &&
+ 	    (link->dynamic == KNET_LINK_STATIC)) {
+-		if ((check_rm(knet_h, link->outsock, link->transport,
++		if ((check_rm(knet_h, link,
+ 			      &link->dst_addr, &link->dst_addr,
+ 			      CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != ENOENT)) {
+ 			err = -1;
+@@ -567,7 +567,7 @@ int knet_link_clear_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ 	 */
+ 	if ((transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL) &&
+ 	    (knet_h->knet_transport_fd_tracker[sock].transport == KNET_MAX_TRANSPORTS)) {
+-		check_rmall(knet_h, sock, transport);
++		check_rmall(knet_h, link);
+ 	}
+ 
+ 	pthread_mutex_destroy(&link->link_stats_mutex);
+@@ -1340,7 +1340,7 @@ int knet_link_insert_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t l
+ 		goto exit_unlock;
+ 	}
+ 
+-	err = check_add(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport, index,
++	err = check_add(knet_h, link, index,
+ 			ss1, ss2, type, acceptreject);
+ 	savederrno = errno;
+ 
+@@ -1442,7 +1442,7 @@ int knet_link_rm_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_
+ 		goto exit_unlock;
+ 	}
+ 
+-	err = check_rm(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport,
++	err = check_rm(knet_h, link,
+ 		       ss1, ss2, type, acceptreject);
+ 	savederrno = errno;
+ 
+@@ -1503,7 +1503,7 @@ int knet_link_clear_acl(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t li
+ 		goto exit_unlock;
+ 	}
+ 
+-	check_rmall(knet_h, transport_link_get_acl_fd(knet_h, link), link->transport);
++	check_rmall(knet_h, link);
+ 
+ exit_unlock:
+ 	pthread_rwlock_unlock(&knet_h->global_rwlock);
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 1612f15e..66faf244 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -31,35 +31,37 @@ static check_ops_t proto_check_modules_cmds[] = {
+  * protocol specific functions
+  */
+ 
+-int check_add(knet_handle_t knet_h, int sock, uint8_t transport, int index,
++int check_add(knet_handle_t knet_h, struct knet_link *kn_link,
++	      int index,
+ 	      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	      check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_add(
+-			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head, index,
++	return proto_check_modules_cmds[transport_get_proto(knet_h, kn_link->transport)].protocheck_add(
++			&kn_link->access_list_match_entry_head, index,
+ 			ss1, ss2, type, acceptreject);
+ }
+ 
+-int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
++int check_rm(knet_handle_t knet_h, struct knet_link *kn_link,
+ 	     struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	     check_type_t type, check_acceptreject_t acceptreject)
+ {
+-	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_rm(
+-			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head,
++	return proto_check_modules_cmds[transport_get_proto(knet_h, kn_link->transport)].protocheck_rm(
++			&kn_link->access_list_match_entry_head,
+ 			ss1, ss2, type, acceptreject);
+ }
+ 
+-void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport)
++void check_rmall(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+-	proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_rmall(
+-		&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head);
++	proto_check_modules_cmds[transport_get_proto(knet_h, kn_link->transport)].protocheck_rmall(
++		&kn_link->access_list_match_entry_head);
+ }
+ 
+ /*
+  * return 0 to reject and 1 to accept a packet
+  */
+-int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct sockaddr_storage *checkip)
++int check_validate(knet_handle_t knet_h, struct knet_link *kn_link,
++		   struct sockaddr_storage *checkip)
+ {
+-	return proto_check_modules_cmds[transport_get_proto(knet_h, transport)].protocheck_validate(
+-			&knet_h->knet_transport_fd_tracker[sock].access_list_match_entry_head, checkip);
++	return proto_check_modules_cmds[transport_get_proto(knet_h, kn_link->transport)].protocheck_validate(
++			&kn_link->access_list_match_entry_head, checkip);
+ }
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 9901c956..3b9fd35e 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -27,13 +27,18 @@ typedef struct {
+ 	void (*protocheck_rmall)	(void *fd_tracker_match_entry_head);
+ } check_ops_t;
+ 
+-int check_add(knet_handle_t knet_h, int sock, uint8_t transport, int index,
++int check_add(knet_handle_t knet_h, struct knet_link *kn_link,
++	      int index,
+ 	      struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	      check_type_t type, check_acceptreject_t acceptreject);
+-int check_rm(knet_handle_t knet_h, int sock, uint8_t transport,
++
++int check_rm(knet_handle_t knet_h, struct knet_link *kn_link,
+ 	     struct sockaddr_storage *ss1, struct sockaddr_storage *ss2,
+ 	     check_type_t type, check_acceptreject_t acceptreject);
+-void check_rmall(knet_handle_t knet_h, int sock, uint8_t transport);
+-int check_validate(knet_handle_t knet_h, int sock, uint8_t transport, struct sockaddr_storage *checkip);
++
++void check_rmall(knet_handle_t knet_h, struct knet_link *kn_link);
++
++int check_validate(knet_handle_t knet_h, struct knet_link *kn_link,
++		   struct sockaddr_storage *checkip);
+ 
+ #endif
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index ea1755f2..8d562c58 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -183,8 +183,9 @@ static struct ip_acl_match_entry *ipcheck_findmatch(struct ip_acl_match_entry **
+ 	struct ip_acl_match_entry *match_entry = *match_entry_head;
+ 
+ 	while (match_entry) {
+-		if ((!memcmp(&match_entry->addr1, ss1, sizeof(struct sockaddr_storage))) &&
+-		    (!memcmp(&match_entry->addr2, ss2, sizeof(struct sockaddr_storage))) &&
++		if ((!memcmp(&match_entry->addr1, ss1, sockaddr_len(ss1))) &&
++		    ((match_entry->type == CHECK_TYPE_ADDRESS) ||
++		     ((match_entry->type != CHECK_TYPE_ADDRESS) && ss2 && !memcmp(&match_entry->addr2, ss2, sockaddr_len(ss1)))) &&
+ 		    (match_entry->type == type) &&
+ 		    (match_entry->acceptreject == acceptreject)) {
+ 			return match_entry;
+@@ -254,7 +255,9 @@ int ipcheck_addip(void *fd_tracker_match_entry_head, int index,
+ 	}
+ 
+ 	copy_sockaddr(&new_match_entry->addr1, ss1);
+-	copy_sockaddr(&new_match_entry->addr2, ss2);
++	if (ss2) {
++		copy_sockaddr(&new_match_entry->addr2, ss2);
++	}
+ 	new_match_entry->type = type;
+ 	new_match_entry->acceptreject = acceptreject;
+ 	new_match_entry->next = NULL;
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 60c83bda..16e2e89b 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -37,7 +37,8 @@ int_checks		= \
+ 			  int_timediff_test
+ 
+ fun_checks		= \
+-			  fun_config_crypto_test
++			  fun_config_crypto_test \
++			  fun_acl_check_test
+ 
+ # checks below need to be executed manually
+ # or with a specifi environment
+@@ -111,3 +112,6 @@ fun_pmtud_crypto_test_SOURCES = fun_pmtud_crypto.c \
+ 
+ fun_config_crypto_test_SOURCES = fun_config_crypto.c \
+ 				 test-common.c
++
++fun_acl_check_test_SOURCES = fun_acl_check.c \
++			     test-common.c
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index 4f6f8c91..759afdc2 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -200,7 +200,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("match list not empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -220,7 +220,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (!link->access_list_match_entry_head) {
+ 		printf("match list empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index 9b5cfbb8..d2a6d8d5 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -125,7 +125,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("match list NOT empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -145,7 +145,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (!link->access_list_match_entry_head) {
+ 		printf("match list empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -165,7 +165,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("match list NOT empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index c0a4de3e..a5de2378 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -200,7 +200,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("match list not empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -220,7 +220,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (!link->access_list_match_entry_head) {
+ 		printf("match list empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index b3300dd1..7af3fd0a 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -200,7 +200,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("match list not empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -230,7 +230,7 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("match list NOT empty!");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index 402b51c6..14025649 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -137,7 +137,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (link->access_list_match_entry_head) {
+ 		printf("found access lists for dynamic dst_addr!\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+@@ -260,7 +260,7 @@ static void test(void)
+ 	host = knet_h->host_index[1];
+ 	link = &host->link[0];
+ 
+-	if (!knet_h->knet_transport_fd_tracker[link->outsock].access_list_match_entry_head) {
++	if (!link->access_list_match_entry_head) {
+ 		printf("Unable to find default access lists for static dst_addr!\n");
+ 		knet_link_clear_config(knet_h, 1, 0);
+ 		knet_host_remove(knet_h, 1);
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index f4ffb3df..a3b5aa49 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -60,6 +60,14 @@ static void test(uint8_t transport)
+ 
+ 	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+ 
++	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
++		printf("Cannot enable access lists: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
+ 	printf("Test knet_send with no send_buff\n");
+ 
+ 	if ((!knet_send(knet_h, NULL, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+diff --git a/libknet/tests/fun_acl_check.c b/libknet/tests/fun_acl_check.c
+new file mode 100644
+index 00000000..55cf09bb
+--- /dev/null
++++ b/libknet/tests/fun_acl_check.c
+@@ -0,0 +1,409 @@
++/*
++ * Copyright (C) 2021 Red Hat, Inc.  All rights reserved.
++ *
++ * Authors: Christine Caulfield <ccaulfie@redhat.com>
++ *
++ * This software licensed under GPL-2.0+
++ */
++
++#include "config.h"
++
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <unistd.h>
++#include <inttypes.h>
++#include <pthread.h>
++#include <poll.h>
++
++#include "libknet.h"
++
++#include "internals.h"
++#include "netutils.h"
++#include "test-common.h"
++
++
++/*
++ * Keep track of how many messages got through:
++ * clean + 3xACLs + QUIT
++ */
++#define CORRECT_NUM_MSGS 5
++static int msgs_recvd = 0;
++
++#define TESTNODES 2
++
++static pthread_mutex_t recv_mutex = PTHREAD_MUTEX_INITIALIZER;
++static int quit_recv_thread = 0;
++
++static int reply_pipe[2];
++
++#define FAIL_ON_ERR(fn) \
++	printf("FOE: %s\n", #fn);			  \
++	if ((res = fn) != 0) {				  \
++	  int savederrno = errno;			  \
++	  pthread_mutex_lock(&recv_mutex);		  \
++	  quit_recv_thread = 1;				  \
++	  pthread_mutex_unlock(&recv_mutex);		  \
++	  if (recv_thread) {				  \
++		  pthread_join(recv_thread, (void**)&thread_err); \
++	  }						  \
++	  knet_handle_stop_nodes(knet_h, TESTNODES);	  \
++	  stop_logthread();				  \
++	  flush_logs(logfds[0], stdout);		  \
++	  close_logpipes(logfds);			  \
++	  close(reply_pipe[0]);				  \
++	  close(reply_pipe[1]);				  \
++	  if (res == -2) {				  \
++		  exit(SKIP);				  \
++	  } else {					  \
++		  printf("*** FAIL on line %d %s failed: %s\n", __LINE__ , #fn, strerror(savederrno)); \
++		  exit(FAIL);				  \
++	  }						  \
++	}
++
++static int knet_send_str(knet_handle_t knet_h, char *str)
++{
++	return knet_send_sync(knet_h, str, strlen(str)+1, 0);
++}
++
++/*
++ * lo0 is filled in with the local address on return.
++ * lo1 is expected to be provided - it's the actual remote address to connect to.
++ */
++int dyn_knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t link_id,
++			     uint8_t transport, uint64_t flags, int family, int dynamic,
++			     struct sockaddr_storage *lo0, struct sockaddr_storage *lo1)
++{
++	int err = 0, savederrno = 0;
++	uint32_t port;
++	char portstr[32];
++
++	for (port = 1025; port < 65536; port++) {
++		sprintf(portstr, "%u", port);
++		memset(lo0, 0, sizeof(struct sockaddr_storage));
++		if (family == AF_INET6) {
++			err = knet_strtoaddr("::1", portstr, lo0, sizeof(struct sockaddr_storage));
++		} else {
++			err = knet_strtoaddr("127.0.0.1", portstr, lo0, sizeof(struct sockaddr_storage));
++		}
++		if (err < 0) {
++			printf("Unable to convert loopback to sockaddr: %s\n", strerror(errno));
++			goto out;
++		}
++		errno = 0;
++		if (dynamic) {
++			err = knet_link_set_config(knet_h, host_id, link_id, transport, lo0, NULL, flags);
++		} else {
++			err = knet_link_set_config(knet_h, host_id, link_id, transport, lo0, lo1, flags);
++		}
++		savederrno = errno;
++		if ((err < 0) && (savederrno != EADDRINUSE)) {
++			if (savederrno == EPROTONOSUPPORT && transport == KNET_TRANSPORT_SCTP) {
++				return -2;
++			} else {
++				printf("Unable to configure link: %s\n", strerror(savederrno));
++				goto out;
++			}
++		}
++		if (!err) {
++			printf("Using port %u\n", port);
++			goto out;
++		}
++	}
++
++	if (err) {
++		printf("No more ports available\n");
++	}
++out:
++	errno = savederrno;
++	return err;
++}
++
++static void *recv_messages(void *handle)
++{
++	knet_handle_t knet_h = (knet_handle_t)handle;
++	char buf[4096];
++	ssize_t len;
++	static int err = 0;
++	int savederrno = 0, quit = 0;
++
++	while ((len = knet_recv(knet_h, buf, sizeof(buf), 0)) && (!quit)) {
++		savederrno = errno;
++		pthread_mutex_lock(&recv_mutex);
++		quit = quit_recv_thread;
++		pthread_mutex_unlock(&recv_mutex);
++		if (quit) {
++			printf(" *** recv thread was requested to exit via FOE\n");
++			err = 1;
++			return &err;
++		}
++		if (len > 0) {
++			int res;
++
++			printf("recv: (%ld) %s\n", (long)len, buf);
++			msgs_recvd++;
++			if (strcmp("QUIT", buf) == 0) {
++				break;
++			}
++			if (buf[0] == '0') { /* We should not have received this! */
++				printf(" *** FAIL received packet that should have been blocked\n");
++				err = 1;
++				return &err;
++			}
++			/* Tell the main thread we have received something */
++			res = write(reply_pipe[1], ".", 1);
++			if (res != 1) {
++				printf(" *** FAIL to send response back to main thread\n");
++				err = 1;
++				return &err;
++			}
++		}
++		usleep(1000);
++		if (len < 0 && savederrno != EAGAIN) {
++			break;
++		}
++	}
++	printf("-- recv thread finished: %zd %d %s\n", len, errno, strerror(savederrno));
++	return &err;
++}
++
++static void notify_fn(void *private_data,
++		     int datafd,
++		     int8_t channel,
++		     uint8_t tx_rx,
++		     int error,
++		     int errorno)
++{
++	printf("NOTIFY fn called\n");
++}
++
++/* A VERY basic filter because all data traffic is going to one place */
++static int dhost_filter(void *pvt_data,
++			const unsigned char *outdata,
++			ssize_t outdata_len,
++			uint8_t tx_rx,
++			knet_node_id_t this_host_id,
++			knet_node_id_t src_host_id,
++			int8_t *dst_channel,
++			knet_node_id_t *dst_host_ids,
++			size_t *dst_host_ids_entries)
++{
++	dst_host_ids[0] = 1;
++	*dst_host_ids_entries = 1;
++	return 0;
++}
++
++/* This used to be a pthread condition variable, but
++   there was a race where it could be triggered before
++   the main thread was waiting for it.
++   Go old-fashioned.
++*/
++static int wait_for_reply(int seconds)
++{
++	int res;
++	struct pollfd pfds;
++	char tmpbuf[32];
++
++	pfds.fd = reply_pipe[0];
++	pfds.events = POLLIN | POLLERR | POLLHUP;
++	pfds.revents = 0;
++
++	res = poll(&pfds, 1, seconds*1000);
++	if (res == 1) {
++		if (pfds.revents & POLLIN) {
++			res = read(reply_pipe[0], tmpbuf, sizeof(tmpbuf));
++			if (res > 0) {
++				return 0;
++			}
++		} else {
++			printf("Error on pipe poll revent = 0x%x\n", pfds.revents);
++			errno = EIO;
++		}
++	}
++	if (res == 0) {
++		errno = ETIMEDOUT;
++		return -1;
++	}
++
++	return -1;
++}
++
++static void test(int transport)
++{
++	knet_handle_t knet_h[TESTNODES+1];
++	int logfds[2];
++	struct sockaddr_storage lo0, lo1;
++	struct sockaddr_storage ss1, ss2;
++	int res;
++	pthread_t recv_thread = 0;
++	int *thread_err;
++	int datafd;
++	int8_t channel;
++	int seconds = 90; // dynamic tests take longer than normal tests
++
++	if (is_memcheck() || is_helgrind()) {
++		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
++		seconds = seconds * 16;
++	}
++
++	memset(knet_h, 0, sizeof(knet_h));
++	memset(reply_pipe, 0, sizeof(reply_pipe));
++	memset(logfds, 0, sizeof(logfds));
++
++	FAIL_ON_ERR(pipe(reply_pipe));
++
++	// Initial setup gubbins
++	msgs_recvd = 0;
++	setup_logpipes(logfds);
++	start_logthread(logfds[1], stdout);
++	knet_handle_start_nodes(knet_h, TESTNODES, logfds, KNET_LOG_DEBUG);
++
++	FAIL_ON_ERR(knet_host_add(knet_h[2], 1));
++	FAIL_ON_ERR(knet_host_add(knet_h[1], 2));
++
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h[2], NULL, dhost_filter));
++
++	// Create the dynamic (receiving) link
++	FAIL_ON_ERR(dyn_knet_link_set_config(knet_h[1], 2, 0, transport, 0, AF_INET, 1, &lo0, NULL));
++
++	// Connect to the dynamic link
++	FAIL_ON_ERR(dyn_knet_link_set_config(knet_h[2], 1, 0, transport, 0, AF_INET, 0, &lo1, &lo0));
++
++	// All the rest of the setup gubbins
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h[1], 0, &notify_fn));
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h[2], 0, &notify_fn));
++
++	channel = datafd = 0;
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h[1], &datafd, &channel));
++	channel = datafd = 0;
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h[2], &datafd, &channel));
++
++	FAIL_ON_ERR(knet_link_set_enable(knet_h[1], 2, 0, 1));
++	FAIL_ON_ERR(knet_link_set_enable(knet_h[2], 1, 0, 1));
++
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h[1], 1));
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h[2], 1));
++
++	// Start receive thread
++	FAIL_ON_ERR(pthread_create(&recv_thread, NULL, recv_messages, (void *)knet_h[1]));
++
++	// Let everything settle down
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++
++	/*
++	 * TESTING STARTS HERE
++	 * strings starting '1' should reach the receiving thread
++	 * strings starting '0' should not
++	 */
++
++	// No ACL
++	printf("Testing No ACL - this should get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "1No ACL - this should get through"));
++	FAIL_ON_ERR(wait_for_reply(seconds))
++
++	// Block traffic from this address.
++	memset(&ss1, 0, sizeof(ss1));
++	memset(&ss2, 0, sizeof(ss1));
++	knet_strtoaddr("127.0.0.1","0", &ss1, sizeof(ss1));
++	FAIL_ON_ERR(knet_link_add_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
++	// Accept ACL for when we remove them
++	FAIL_ON_ERR(knet_link_add_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
++
++	// This needs to go after the first ACLs are added
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h[1], 1));
++
++	printf("Testing Address blocked - this should NOT get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "0Address blocked - this should NOT get through"));
++
++	// Unblock and check again
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++
++	printf("Testing Address unblocked - this should get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "1Address unblocked - this should get through"));
++	FAIL_ON_ERR(wait_for_reply(seconds));
++
++	// Block traffic using a netmask
++	knet_strtoaddr("127.0.0.1","0", &ss1, sizeof(ss1));
++	knet_strtoaddr("255.0.0.1","0", &ss2, sizeof(ss2));
++	FAIL_ON_ERR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
++
++	printf("Testing Netmask blocked - this should NOT get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "0Netmask blocked - this should NOT get through"));
++
++	// Unblock and check again
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++
++	printf("Testing Netmask unblocked - this should get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "1Netmask unblocked - this should get through"));
++	FAIL_ON_ERR(wait_for_reply(seconds));
++
++	// Block traffic from a range
++	knet_strtoaddr("127.0.0.0", "0", &ss1, sizeof(ss1));
++	knet_strtoaddr("127.0.0.9", "0", &ss2, sizeof(ss2));
++	FAIL_ON_ERR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
++
++	printf("Testing Range blocked - this should NOT get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "0Range blocked - this should NOT get through"));
++
++	// Unblock and check again
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++
++	printf("Testing Range unblocked - this should get through\n");
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "1Range unblocked - this should get through"));
++	FAIL_ON_ERR(wait_for_reply(seconds));
++
++	// Finish up - disable ACLS to make sure the QUIT message gets through
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h[1], 0));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++
++	FAIL_ON_ERR(knet_send_str(knet_h[2], "QUIT"));
++
++	// Check return from the receiving thread
++	pthread_join(recv_thread, (void**)&thread_err);
++	if (*thread_err) {
++		printf("Thread returned %d\n", *thread_err);
++		exit(FAIL);
++	}
++
++	//  Tidy Up
++	knet_handle_stop_nodes(knet_h, TESTNODES);
++
++	stop_logthread();
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++	close(reply_pipe[0]);
++	close(reply_pipe[1]);
++
++	if (msgs_recvd != CORRECT_NUM_MSGS) {
++		printf("*** FAIL Recv thread got %d messages, expected %d\n", msgs_recvd, CORRECT_NUM_MSGS);
++		exit(FAIL);
++	}
++}
++
++int main(int argc, char *argv[])
++{
++	printf("Testing with UDP\n");
++	test(KNET_TRANSPORT_UDP);
++
++#ifdef HAVE_NETINET_SCTP_H
++	printf("Testing with SCTP currently disabled\n");
++	//test(KNET_TRANSPORT_SCTP);
++#endif
++
++	return PASS;
++}
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index e55f5f73..2729f551 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -678,8 +678,10 @@ void knet_handle_stop_nodes(knet_handle_t knet_h[], uint8_t numnodes)
+ 	uint8_t i;
+ 
+ 	for (i = 1; i <= numnodes; i++) {
+-		printf("stopping handle %u at %p\n", i, knet_h[i]);
+-		knet_handle_stop(knet_h[i]);
++		if (knet_h[i]) {
++			printf("stopping handle %u at %p\n", i, knet_h[i]);
++			knet_handle_stop(knet_h[i]);
++		}
+ 	}
+ 
+ 	return;
+@@ -792,7 +794,7 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
+ 			 int logfd, FILE *std)
+ {
+ 	struct timespec ts;
+-	int res;
++	int res, savederrno = 0;
+ 
+ 	if (state) {
+ 		target = numnodes-1; /* exclude us */
+@@ -819,14 +821,23 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
+ 		fprintf(stderr, "unable to get nodewait mutex: %s\n", strerror(errno));
+ 		return -1;
+ 	}
++
+ 	res = pthread_cond_timedwait(&wait_cond, &wait_mutex, &ts);
+-	if (res == -1 && errno == ETIMEDOUT) {
++	if (res != 0 && res != ETIMEDOUT) {
++		fprintf(stderr, "pthread_cond_timedwait fatal error\n");
++		errno = res;
++		return -1;
++	}
++	if (res == ETIMEDOUT) {
+ 		fprintf(stderr, "Timed-out\n");
++		savederrno = ETIMEDOUT;
++		res = -1;
+ 	}
+ 	pthread_mutex_unlock(&wait_mutex);
+ 
+ 	knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
+ 	flush_logs(logfd, std);
++	errno = savederrno;
+ 	return res;
+ }
+ 
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index d671a845..213860fd 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -226,6 +226,32 @@ static int pckt_defrag(knet_handle_t knet_h, struct knet_header *inbuf, ssize_t
+ 	return 1;
+ }
+ 
++/*
++ * processing incoming packets vs access lists
++ */
++static int _check_rx_acl(knet_handle_t knet_h, struct knet_link *src_link, const struct knet_mmsghdr *msg)
++{
++	if (knet_h->use_access_lists) {
++		if (!check_validate(knet_h, src_link, msg->msg_hdr.msg_name)) {
++			char src_ipaddr[KNET_MAX_HOST_LEN];
++			char src_port[KNET_MAX_PORT_LEN];
++			
++			memset(src_ipaddr, 0, KNET_MAX_HOST_LEN);
++			memset(src_port, 0, KNET_MAX_PORT_LEN);
++			if (knet_addrtostr(msg->msg_hdr.msg_name, sockaddr_len(msg->msg_hdr.msg_name),
++					   src_ipaddr, KNET_MAX_HOST_LEN,
++					   src_port, KNET_MAX_PORT_LEN) < 0) {
++
++				log_debug(knet_h, KNET_SUB_RX, "Packet rejected: unable to resolve host/port");
++			} else {
++				log_debug(knet_h, KNET_SUB_RX, "Packet rejected from %s/%s", src_ipaddr, src_port);
++			}
++			return 0;
++		}
++	}
++	return 1;
++}
++
+ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struct knet_mmsghdr *msg)
+ {
+ 	int err = 0, savederrno = 0, stats_err = 0;
+@@ -305,6 +331,9 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 		/* be aware this works only for PING / PONG and PMTUd packets! */
+ 		src_link = src_host->link +
+ 			(inbuf->khp_ping_link % KNET_MAX_LINK);
++		if (!_check_rx_acl(knet_h, src_link, msg)) {
++			return;
++		}
+ 		if (src_link->dynamic == KNET_LINK_DYNIP) {
+ 			if (cmpaddr(&src_link->dst_addr, msg->msg_hdr.msg_name) != 0) {
+ 				log_debug(knet_h, KNET_SUB_RX, "host: %u link: %u appears to have changed ip address",
+@@ -337,7 +366,14 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 				break;
+ 			}
+ 		}
+-		if (!found_link) {
++		if (found_link) {
++			/*
++			 * this check is currently redundant.. Keep it here for now
++			 */
++			if (!_check_rx_acl(knet_h, src_link, msg)) {
++				return;
++			}
++		} else {
+ 			log_debug(knet_h, KNET_SUB_RX, "Unable to determine source link for data packet. Discarding packet.");
+ 			return;
+ 		}
+@@ -888,31 +924,6 @@ static void _handle_recv_from_links(knet_handle_t knet_h, int sockfd, struct kne
+ 				goto exit_unlock;
+ 				break;
+ 			case KNET_TRANSPORT_RX_IS_DATA: /* packet is data and should be parsed as such */
+-				/*
+-				 * processing incoming packets vs access lists
+-				 */
+-				if ((knet_h->use_access_lists) &&
+-				    (transport_get_acl_type(knet_h, transport) == USE_GENERIC_ACL)) {
+-					if (!check_validate(knet_h, sockfd, transport, msg[i].msg_hdr.msg_name)) {
+-						char src_ipaddr[KNET_MAX_HOST_LEN];
+-						char src_port[KNET_MAX_PORT_LEN];
+-
+-						memset(src_ipaddr, 0, KNET_MAX_HOST_LEN);
+-						memset(src_port, 0, KNET_MAX_PORT_LEN);
+-						if (knet_addrtostr(msg[i].msg_hdr.msg_name, sockaddr_len(msg[i].msg_hdr.msg_name),
+-								   src_ipaddr, KNET_MAX_HOST_LEN,
+-								   src_port, KNET_MAX_PORT_LEN) < 0) {
+-
+-							log_debug(knet_h, KNET_SUB_RX, "Packet rejected: unable to resolve host/port");
+-						} else {
+-							log_debug(knet_h, KNET_SUB_RX, "Packet rejected from %s/%s", src_ipaddr, src_port);
+-						}
+-						/*
+-						 * continue processing the other packets
+-						 */
+-						continue;
+-					}
+-				}
+ 				_parse_recv_from_links(knet_h, sockfd, &msg[i]);
+ 				break;
+ 			case KNET_TRANSPORT_RX_OOB_DATA_CONTINUE:
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 94891f93..b505f429 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -774,6 +774,12 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 	char addr_str[KNET_MAX_HOST_LEN];
+ 	char port_str[KNET_MAX_PORT_LEN];
+ 	sctp_accepted_link_info_t *accept_info = NULL;
++	struct knet_host *host;
++	struct knet_link *kn_link;
++	int link_idx;
++	sctp_connect_link_info_t *this_link_connect_info;
++	sctp_listen_link_info_t *this_link_listen_info;
++	int pass_acl = 0;
+ 
+ 	memset(&ss, 0, sizeof(ss));
+ 
+@@ -796,8 +802,27 @@ static void _handle_incoming_sctp(knet_handle_t knet_h, int listen_sock)
+ 
+ 	log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Incoming: received connection from: %s port: %s",
+ 						addr_str, port_str);
++
+ 	if (knet_h->use_access_lists) {
+-		if (!check_validate(knet_h, listen_sock, KNET_TRANSPORT_SCTP, &ss)) {
++		for (host = knet_h->host_head; host != NULL; host = host->next) {
++			for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) {
++				kn_link = &host->link[link_idx];
++
++				if ((kn_link->configured) && (kn_link->transport == KNET_TRANSPORT_SCTP)) {
++					this_link_connect_info = kn_link->transport_link;
++					this_link_listen_info = this_link_connect_info->listener;
++					if ((this_link_listen_info->listen_sock == listen_sock) &&
++					    (check_validate(knet_h, kn_link, &ss))) {
++						pass_acl = 1;
++						break;
++					}
++				}
++			}
++			if (pass_acl) {
++				break;
++			}
++		}
++		if (!pass_acl) {
+ 			savederrno = EINVAL;
+ 			log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Connection rejected from %s/%s", addr_str, port_str);
+ 			close(new_fd);
+@@ -1039,7 +1064,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 	 */
+ 	qb_list_for_each_entry(info, &handle_info->listen_links_list, list) {
+ 		if (memcmp(&info->src_address, &kn_link->src_addr, sizeof(struct sockaddr_storage)) == 0) {
+-			if ((check_add(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP, -1,
++			if ((check_add(knet_h, kn_link, -1,
+ 				       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 				return NULL;
+ 			}
+@@ -1097,7 +1122,7 @@ static sctp_listen_link_info_t *sctp_link_listener_start(knet_handle_t knet_h, s
+ 		goto exit_error;
+ 	}
+ 
+-	if ((check_add(knet_h, listen_sock, KNET_TRANSPORT_SCTP, -1,
++	if ((check_add(knet_h, kn_link, -1,
+ 		       &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != EEXIST)) {
+ 		savederrno = errno;
+ 		err = -1;
+@@ -1129,7 +1154,7 @@ exit_error:
+ 			epoll_ctl(handle_info->listen_epollfd, EPOLL_CTL_DEL, listen_sock, &ev);
+ 		}
+ 		if (listen_sock >= 0) {
+-			check_rmall(knet_h, listen_sock, KNET_TRANSPORT_SCTP);
++			check_rmall(knet_h, kn_link);
+ 			close(listen_sock);
+ 		}
+ 		if (info) {
+@@ -1167,7 +1192,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		}
+ 	}
+ 
+-	if ((check_rm(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP,
++	if ((check_rm(knet_h, kn_link,
+ 		      &kn_link->dst_addr, &kn_link->dst_addr, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) && (errno != ENOENT)) {
+ 		log_debug(knet_h, KNET_SUB_TRANSP_SCTP, "Unable to remove default access lists for %d", info->listen_sock);
+ 	}
+@@ -1202,8 +1227,7 @@ static int sctp_link_listener_stop(knet_handle_t knet_h, struct knet_link *kn_li
+ 		goto exit_error;
+ 	}
+ 
+-	check_rmall(knet_h, info->listen_sock, KNET_TRANSPORT_SCTP);
+-
++	check_rmall(knet_h, kn_link);
+ 	close(info->listen_sock);
+ 
+ 	for (i=0; i< MAX_ACCEPTED_SOCKS; i++) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0431-transports-remove-unused-internal-ACL-API.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0431-transports-remove-unused-internal-ACL-API.patch
new file mode 100644
index 000000000..a4c7ec503
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0431-transports-remove-unused-internal-ACL-API.patch
@@ -0,0 +1,167 @@ 
+From d2b6db18a7d80b87ef56bb36232df7b7ec90fb55 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 26 Jul 2021 08:59:24 +0200
+Subject: [PATCH] [transports] remove unused internal ACL API
+
+with the new ACL code, this internal API is no longer used
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/internals.h          |  5 -----
+ libknet/transport_loopback.c |  5 -----
+ libknet/transport_loopback.h |  1 -
+ libknet/transport_sctp.c     |  7 -------
+ libknet/transport_sctp.h     |  1 -
+ libknet/transport_udp.c      |  5 -----
+ libknet/transport_udp.h      |  1 -
+ libknet/transports.c         | 13 ++++---------
+ libknet/transports.h         |  1 -
+ 9 files changed, 4 insertions(+), 35 deletions(-)
+
+diff --git a/libknet/internals.h b/libknet/internals.h
+index 48f25949..a3477280 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -376,11 +376,6 @@ typedef struct knet_transport_ops {
+ 	int (*transport_link_dyn_connect)(knet_handle_t knet_h, int sockfd, struct knet_link *link);
+ 
+ 
+-/*
+- * return the fd to use for access lists
+- */
+-	int (*transport_link_get_acl_fd)(knet_handle_t knet_h, struct knet_link *link);
+-
+ /*
+  * per transport error handling of recvmmsg
+  * (see _handle_recv_from_links comments for details)
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index 34e7c980..99a1db95 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -74,11 +74,6 @@ int loopback_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct
+ 	return 0;
+ }
+ 
+-int loopback_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
+-{
+-	return 0;
+-}
+-
+ int loopback_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+ 	return 0;
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index f8e4e5a7..861c1776 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -23,7 +23,6 @@ int loopback_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_
+ int loopback_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno);
+ int loopback_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int loopback_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+-int loopback_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ int loopback_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index b505f429..36485e75 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1636,11 +1636,4 @@ int sctp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct kne
+ 	kn_link->transport_connected = 1;
+ 	return 0;
+ }
+-
+-int sctp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
+-{
+-	sctp_connect_link_info_t *this_link_info = kn_link->transport_link;
+-	sctp_listen_link_info_t *info = this_link_info->listener;
+-	return info->listen_sock;
+-}
+ #endif
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index 74f6023a..b60b038e 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -31,7 +31,6 @@ int sctp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int sctp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno);
+ int sctp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int sctp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+-int sctp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ int sctp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 9feac970..482c99b1 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -434,11 +434,6 @@ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet
+ 	return 0;
+ }
+ 
+-int udp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
+-{
+-	return kn_link->outsock;
+-}
+-
+ int udp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
+ 	return 0;
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index 69a84995..40d162a8 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -23,7 +23,6 @@ int udp_transport_rx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err, int recv_errno);
+ int udp_transport_rx_is_data(knet_handle_t knet_h, int sockfd, struct knet_mmsghdr *msg);
+ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+-int udp_transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ int udp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link);
+ 
+ #endif
+diff --git a/libknet/transports.c b/libknet/transports.c
+index 2f18ec81..a113d5f2 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -27,14 +27,14 @@
+ #include "transport_sctp.h"
+ #include "threads_common.h"
+ 
+-#define empty_module 0, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
++#define empty_module 0, -1, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL },
+ 
+ static knet_transport_ops_t transport_modules_cmd[KNET_MAX_TRANSPORTS] = {
+-	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_link_get_acl_fd, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data, loopback_transport_link_is_down },
+-	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_link_get_acl_fd, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data, udp_transport_link_is_down },
++	{ "LOOPBACK", KNET_TRANSPORT_LOOPBACK, 1, TRANSPORT_PROTO_LOOPBACK, USE_NO_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_LOOPBACK_OVERHEAD, loopback_transport_init, loopback_transport_free, loopback_transport_link_set_config, loopback_transport_link_clear_config, loopback_transport_link_dyn_connect, loopback_transport_rx_sock_error, loopback_transport_tx_sock_error, loopback_transport_rx_is_data, loopback_transport_link_is_down },
++	{ "UDP", KNET_TRANSPORT_UDP, 1, TRANSPORT_PROTO_IP_PROTO, USE_GENERIC_ACL, TRANSPORT_PROTO_NOT_CONNECTION_ORIENTED, KNET_PMTUD_UDP_OVERHEAD, udp_transport_init, udp_transport_free, udp_transport_link_set_config, udp_transport_link_clear_config, udp_transport_link_dyn_connect, udp_transport_rx_sock_error, udp_transport_tx_sock_error, udp_transport_rx_is_data, udp_transport_link_is_down },
+ 	{ "SCTP", KNET_TRANSPORT_SCTP,
+ #ifdef HAVE_NETINET_SCTP_H
+-				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_link_get_acl_fd, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data, sctp_transport_link_is_down },
++				       1, TRANSPORT_PROTO_IP_PROTO, USE_PROTO_ACL, TRANSPORT_PROTO_IS_CONNECTION_ORIENTED, KNET_PMTUD_SCTP_OVERHEAD, sctp_transport_init, sctp_transport_free, sctp_transport_link_set_config, sctp_transport_link_clear_config, sctp_transport_link_dyn_connect, sctp_transport_rx_sock_error, sctp_transport_tx_sock_error, sctp_transport_rx_is_data, sctp_transport_link_is_down },
+ #else
+ empty_module
+ #endif
+@@ -103,11 +103,6 @@ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_lin
+ 	return transport_modules_cmd[kn_link->transport].transport_link_dyn_connect(knet_h, sockfd, kn_link);
+ }
+ 
+-int transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link)
+-{
+-	return transport_modules_cmd[kn_link->transport].transport_link_get_acl_fd(knet_h, kn_link);
+-}
+-
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno)
+ {
+ 	return transport_modules_cmd[transport].transport_rx_sock_error(knet_h, sockfd, recv_err, recv_errno);
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 7dfe63ee..6626ec25 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -22,7 +22,6 @@ void stop_all_transports(knet_handle_t knet_h);
+ int transport_link_set_config(knet_handle_t knet_h, struct knet_link *kn_link, uint8_t transport);
+ int transport_link_clear_config(knet_handle_t knet_h, struct knet_link *kn_link);
+ int transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet_link *kn_link);
+-int transport_link_get_acl_fd(knet_handle_t knet_h, struct knet_link *kn_link);
+ int transport_rx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_tx_sock_error(knet_handle_t knet_h, uint8_t transport, int sockfd, int recv_err, int recv_errno);
+ int transport_rx_is_data(knet_handle_t knet_h, uint8_t transport, int sockfd, struct knet_mmsghdr *msg);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0432-send-Fix-send_sync.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0432-send-Fix-send_sync.patch
new file mode 100644
index 000000000..57e8852a9
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0432-send-Fix-send_sync.patch
@@ -0,0 +1,98 @@ 
+From ba86d833815b0dc565ef8c058c57b1f4d9376912 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Wed, 11 Aug 2021 13:01:15 +0100
+Subject: [PATCH] send: Fix send_sync()
+
+send_sync needs a filter to work - enforce this
+Clear out some arrays that could have random values
+---
+ libknet/libknet.h                  |  1 +
+ libknet/tests/api_knet_send_sync.c | 28 ++++++++++++++++++++--------
+ libknet/threads_tx.c               |  9 +++++++++
+ 3 files changed, 30 insertions(+), 8 deletions(-)
+
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 2c8e52b1..790bc227 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -428,6 +428,7 @@ ssize_t knet_send(knet_handle_t knet_h,
+  * @retval EHOSTDOWN - unicast pckt cannot be delivered because dest host is not connected yet
+  * @retval ECHILD    - crypto failed
+  * @retval EAGAIN    - sendmmsg was unable to send all messages and there was no progress during retry
++ * @retval ENETDOWN  - a packet filter was not installed (necessary for knet_send_sync, but not knet_send)
+  */
+ 
+ int knet_send_sync(knet_handle_t knet_h,
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 2e81e325..9994c36e 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -178,6 +178,26 @@ static void test(void)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
++	printf("Test knet_send_sync with no filter configured\n");
++
++	channel = 1;
++	if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != ENETDOWN)) {
++		printf("knet_send_sync Did not return ENETDOWN for no filter installed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
++		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
++		knet_handle_free(knet_h);
++		flush_logs(logfds[0], stdout);
++		close_logpipes(logfds);
++		exit(FAIL);
++	}
++
++
+ 	printf("Test knet_send_sync with unconfigured channel\n");
+ 
+ 	channel = 0;
+@@ -233,14 +253,6 @@ static void test(void)
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+ 	dhost_filter_ret = -1;
+ 
+ 	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EFAULT)) {
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 0431aeeb..404bfc73 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -179,6 +179,9 @@ static int _parse_recv_from_sock(knet_handle_t knet_h, size_t inlen, int8_t chan
+ 		goto out_unlock;
+ 	}
+ 
++	memset(dst_host_ids_temp, 0, sizeof(dst_host_ids_temp));
++	memset(dst_host_ids, 0, sizeof(dst_host_ids));
++
+ 	/*
+ 	 * move this into a separate function to expand on
+ 	 * extra switching rules
+@@ -792,6 +795,12 @@ int knet_send_sync(knet_handle_t knet_h, const char *buff, const size_t buff_len
+ 		return -1;
+ 	}
+ 
++	if (!knet_h->dst_host_filter_fn) {
++		savederrno = ENETDOWN;
++		err = -1;
++		goto out;
++	}
++
+ 	if (!knet_h->sockfd[channel].in_use) {
+ 		savederrno = EINVAL;
+ 		err = -1;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0433-tests-make-execution-of-functional-testing-optionals.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0433-tests-make-execution-of-functional-testing-optionals.patch
new file mode 100644
index 000000000..3a8b33a72
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0433-tests-make-execution-of-functional-testing-optionals.patch
@@ -0,0 +1,56 @@ 
+From 3277a1a139c455b916918527bdc2ff96e760caa7 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 26 Jul 2021 09:14:00 +0200
+Subject: [PATCH] [tests] make execution of functional testing optionals
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac              |  5 +++++
+ libknet/tests/Makefile.am | 11 ++++++++---
+ 2 files changed, 13 insertions(+), 3 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 78a12786..c1e5d761 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -109,6 +109,11 @@ AC_ARG_ENABLE([libknet-sctp],
+ 	[ enable_libknet_sctp="yes" ])
+ AM_CONDITIONAL([BUILD_SCTP], [test x$enable_libknet_sctp = xyes])
+ 
++AC_ARG_ENABLE([functional-tests],
++	[AS_HELP_STRING([--disable-functional-tests],[disable execution of functional tests, useful for old and slow arches])],,
++	[ enable_functional_tests="yes" ])
++AM_CONDITIONAL([RUN_FUN_TESTS], [test x$enable_functional_tests = xyes])
++
+ AC_ARG_ENABLE([crypto-all],
+ 	[AS_HELP_STRING([--disable-crypto-all],[disable libknet all crypto modules support])],,
+ 	[ enable_crypto_all="yes" ])
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 16e2e89b..38794433 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -29,8 +29,11 @@ noinst_HEADERS		= \
+ 
+ check_PROGRAMS		= \
+ 			  $(api_checks) \
+-			  $(int_checks) \
+-			  $(fun_checks)
++			  $(int_checks)
++
++if RUN_FUN_TESTS
++check_PROGRAMS		+= $(fun_checks)
++endif
+ 
+ int_checks		= \
+ 			  int_links_acl_ip_test \
+@@ -54,7 +57,9 @@ noinst_PROGRAMS		= \
+ 			  pckt_test \
+ 			  $(benchmarks) \
+ 			  $(long_run_checks) \
+-			  $(check_PROGRAMS)
++			  $(api_checks) \
++			  $(int_checks) \
++			  $(fun_checks)
+ 
+ noinst_SCRIPTS		= \
+ 			  api-test-coverage
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0434-test-Use-a-pipe-to-synchronise-wait_for_xxx-events.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0434-test-Use-a-pipe-to-synchronise-wait_for_xxx-events.patch
new file mode 100644
index 000000000..9442e7f95
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0434-test-Use-a-pipe-to-synchronise-wait_for_xxx-events.patch
@@ -0,0 +1,234 @@ 
+From 0582a01ad7f88323696c0b4225845d7f92cd160c Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 26 Aug 2021 12:16:51 +0100
+Subject: [PATCH] test: Use a pipe to synchronise wait_for_xxx events
+
+The condition variable thing clearly not working for us.
+---
+ libknet/tests/test-common.c | 143 ++++++++++++++++++++++++++----------
+ 1 file changed, 103 insertions(+), 40 deletions(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 2729f551..86b76b0c 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -20,6 +20,7 @@
+ #include <pthread.h>
+ #include <dirent.h>
+ #include <sys/select.h>
++#include <sys/poll.h>
+ 
+ #include "libknet.h"
+ #include "test-common.h"
+@@ -747,8 +748,9 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ 
+ 
+ static int target=0;
+-static pthread_mutex_t wait_mutex = PTHREAD_MUTEX_INITIALIZER;
+-static pthread_cond_t wait_cond = PTHREAD_COND_INITIALIZER;
++
++static int state_wait_pipe[2] = {0,0};
++static int host_wait_pipe[2] = {0,0};
+ 
+ static int count_nodes(knet_handle_t knet_h)
+ {
+@@ -769,11 +771,30 @@ static void nodes_notify_callback(void *private_data,
+ {
+ 	knet_handle_t knet_h = (knet_handle_t) private_data;
+ 	int nodes;
++	int res;
+ 
+ 	nodes = count_nodes(knet_h);
+ 
+ 	if (nodes == target) {
+-		pthread_cond_signal(&wait_cond);
++		res = write(state_wait_pipe[1], ".", 1);
++		if (res != 1) {
++			printf("***FAILed to signal wait_for_nodes_state: %s\n", strerror(errno));
++		}
++	}
++}
++
++/* Called atexit() */
++static void finish_state_pipes()
++{
++	if (state_wait_pipe[0] != 0) {
++		close(state_wait_pipe[0]);
++		close(state_wait_pipe[1]);
++		state_wait_pipe[0] = 0;
++	}
++	if (host_wait_pipe[0] != 0) {
++		close(host_wait_pipe[0]);
++		close(host_wait_pipe[1]);
++		host_wait_pipe[0] = 0;
+ 	}
+ }
+ 
+@@ -782,10 +803,44 @@ static void host_notify_callback(void *private_data,
+ 				 uint8_t reachable, uint8_t remote, uint8_t external)
+ {
+ 	knet_handle_t knet_h = (knet_handle_t) private_data;
++	int res;
+ 
+ 	if (knet_h->host_index[host_id]->status.reachable == 1) {
+-		pthread_cond_signal(&wait_cond);
++		res = write(host_wait_pipe[1], ".", 1);
++		if (res != 1) {
++			printf("***FAILed to signal wait_for_host: %s\n", strerror(errno));
++		}
++	}
++}
++
++static int wait_for_reply(int seconds, int pipefd)
++{
++	int res;
++	struct pollfd pfds;
++	char tmpbuf[32];
++
++	pfds.fd = pipefd;
++	pfds.events = POLLIN | POLLERR | POLLHUP;
++	pfds.revents = 0;
++
++	res = poll(&pfds, 1, seconds*1000);
++	if (res == 1) {
++		if (pfds.revents & POLLIN) {
++			res = read(pipefd, tmpbuf, sizeof(tmpbuf));
++			if (res > 0) {
++				return 0;
++			}
++		} else {
++			printf("Error on pipe poll revent = 0x%x\n", pfds.revents);
++			errno = EIO;
++		}
+ 	}
++	if (res == 0) {
++		errno = ETIMEDOUT;
++		return -1;
++	}
++
++	return -1;
+ }
+ 
+ /* Wait for a cluster of 'numnodes' to come up/go down */
+@@ -793,9 +848,24 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
+ 			 uint8_t state, uint32_t timeout,
+ 			 int logfd, FILE *std)
+ {
+-	struct timespec ts;
+ 	int res, savederrno = 0;
+ 
++	if (state_wait_pipe[0] == 0) {
++		res = pipe(state_wait_pipe);
++		if (res == -1) {
++			savederrno = errno;
++			printf("Error creating host reply pipe: %s\n", strerror(errno));
++			errno = savederrno;
++			return -1;
++		}
++		if (atexit(finish_state_pipes)) {
++			printf("Unable to register atexit handler to close pipes: %s\n",
++			       strerror(errno));
++			exit(FAIL);
++		}
++
++	}
++
+ 	if (state) {
+ 		target = numnodes-1; /* exclude us */
+ 	} else {
+@@ -815,25 +885,11 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
+ 		return 0;
+ 	}
+ 
+-	clock_gettime(CLOCK_REALTIME, &ts);
+-	ts.tv_sec += timeout;
+-	if (pthread_mutex_lock(&wait_mutex)) {
+-		fprintf(stderr, "unable to get nodewait mutex: %s\n", strerror(errno));
+-		return -1;
+-	}
+-
+-	res = pthread_cond_timedwait(&wait_cond, &wait_mutex, &ts);
+-	if (res != 0 && res != ETIMEDOUT) {
+-		fprintf(stderr, "pthread_cond_timedwait fatal error\n");
+-		errno = res;
+-		return -1;
+-	}
+-	if (res == ETIMEDOUT) {
+-		fprintf(stderr, "Timed-out\n");
+-		savederrno = ETIMEDOUT;
+-		res = -1;
++	res = wait_for_reply(timeout, state_wait_pipe[0]);
++	if (res == -1) {
++		savederrno = errno;
++		printf("Error waiting for nodes status reply: %s\n", strerror(errno));
+ 	}
+-	pthread_mutex_unlock(&wait_mutex);
+ 
+ 	knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
+ 	flush_logs(logfd, std);
+@@ -844,14 +900,30 @@ int wait_for_nodes_state(knet_handle_t knet_h, size_t numnodes,
+ /* Wait for a single node to come up */
+ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd, FILE *std)
+ {
+-	int res;
+-	struct timespec ts;
++	int res = 0;
++	int savederrno = 0;
+ 
+ 	if (is_memcheck() || is_helgrind()) {
+ 		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
+ 		seconds = seconds * 16;
+ 	}
+ 
++	if (host_wait_pipe[0] == 0) {
++		res = pipe(host_wait_pipe);
++		if (res == -1) {
++			savederrno = errno;
++			printf("Error creating host reply pipe: %s\n", strerror(errno));
++			errno = savederrno;
++			return -1;
++		}
++		if (atexit(finish_state_pipes)) {
++			printf("Unable to register atexit handler to close pipes: %s\n",
++			       strerror(errno));
++			exit(FAIL);
++		}
++
++	}
++
+ 	/* Set this before checking existing status or there's a race condition */
+ 	knet_host_enable_status_change_notify(knet_h,
+ 					      (void *)(long)knet_h,
+@@ -864,26 +936,17 @@ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd
+ 		return 0;
+ 	}
+ 
+-	clock_gettime(CLOCK_REALTIME, &ts);
+-	ts.tv_sec += seconds;
+-	if (pthread_mutex_lock(&wait_mutex)) {
+-		fprintf(stderr, "unable to get nodewait mutex: %s\n", strerror(errno));
+-		return -1;
+-	}
+-	res = pthread_cond_timedwait(&wait_cond, &wait_mutex, &ts);
+-	if (res == -1 && errno == ETIMEDOUT) {
+-		fprintf(stderr, "Timed-out\n");
+-		knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
+-		pthread_mutex_unlock(&wait_mutex);
+-		flush_logs(logfd, std);
+-		return -1;
++	res = wait_for_reply(seconds, host_wait_pipe[0]);
++	if (res == -1) {
++		savederrno = errno;
++		printf("Error waiting for host status reply: %s\n", strerror(errno));
+ 	}
+-	pthread_mutex_unlock(&wait_mutex);
+ 
+ 	knet_host_enable_status_change_notify(knet_h, (void *)(long)0, NULL);
+ 
+ 	/* Still wait for it to settle */
+ 	flush_logs(logfd, std);
+ 	test_sleep(knet_h, 1);
+-	return 0;
++	errno = savederrno;
++	return res;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0435-nozzle-skip-tests-if-TUN-support-is-not-available.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0435-nozzle-skip-tests-if-TUN-support-is-not-available.patch
new file mode 100644
index 000000000..404aa88be
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0435-nozzle-skip-tests-if-TUN-support-is-not-available.patch
@@ -0,0 +1,263 @@ 
+From 494f3b8d657828448c35ed40a64c84cc07bd6e56 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Sun, 29 Aug 2021 20:53:45 +0200
+Subject: [PATCH] nozzle: skip tests if TUN support is not available
+
+---
+ libnozzle/tests/api_nozzle_add_ip.c           |  1 +
+ libnozzle/tests/api_nozzle_close.c            |  1 +
+ libnozzle/tests/api_nozzle_del_ip.c           |  1 +
+ libnozzle/tests/api_nozzle_get_fd.c           |  1 +
+ .../tests/api_nozzle_get_handle_by_name.c     |  1 +
+ libnozzle/tests/api_nozzle_get_ips.c          |  1 +
+ libnozzle/tests/api_nozzle_get_mac.c          |  1 +
+ libnozzle/tests/api_nozzle_get_mtu.c          |  1 +
+ .../tests/api_nozzle_get_name_by_handle.c     |  1 +
+ libnozzle/tests/api_nozzle_open.c             |  1 +
+ libnozzle/tests/api_nozzle_run_updown.c       |  1 +
+ libnozzle/tests/api_nozzle_set_down.c         |  1 +
+ libnozzle/tests/api_nozzle_set_mac.c          |  1 +
+ libnozzle/tests/api_nozzle_set_mtu.c          |  1 +
+ libnozzle/tests/api_nozzle_set_up.c           |  1 +
+ libnozzle/tests/test-common.c                 | 21 +++++++++++++++++--
+ libnozzle/tests/test-common.h                 |  1 +
+ 17 files changed, 35 insertions(+), 2 deletions(-)
+
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+index 8491e25e..017d8f21 100644
+--- a/libnozzle/tests/api_nozzle_add_ip.c
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -283,6 +283,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index 27885b02..2d4e1ab8 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -117,6 +117,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+index 9f67a3ee..ed1fadf9 100644
+--- a/libnozzle/tests/api_nozzle_del_ip.c
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -256,6 +256,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index 6b12724b..1e8f2a11 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -69,6 +69,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+index 5db12936..49b06dd1 100644
+--- a/libnozzle/tests/api_nozzle_get_handle_by_name.c
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -77,6 +77,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index ff96698b..d8100dae 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -172,6 +172,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index 3c99bf5f..0e2a46f2 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -122,6 +122,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 9f009042..3f8ffd39 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -90,6 +90,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index 942f997d..cbb1739a 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -70,6 +70,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index dccaf8b4..ebf1fcb4 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -191,6 +191,7 @@ static int test(void)
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index b7522765..b4b5a86a 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -398,6 +398,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index c0eb6db2..946b3116 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -118,6 +118,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index 31ebb4cf..7c50f949 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -150,6 +150,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index b69d1ecf..752a55cb 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -284,6 +284,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	make_local_ips(testipv4_1, testipv4_2, testipv6_1, testipv6_2);
+ 
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index 6d30fcd9..6c9e23d7 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -92,6 +92,7 @@ out_clean:
+ int main(void)
+ {
+ 	need_root();
++	need_tun();
+ 
+ 	if (test() < 0)
+ 		return FAIL;
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index 21663b18..d2bbde0b 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -8,8 +8,10 @@
+ 
+ #include "config.h"
+ 
++#include <errno.h>
++#include <fcntl.h>
+ #include <string.h>
+-#include <sys/types.h>
++#include <sys/stat.h>
+ #include <ifaddrs.h>
+ #include <limits.h>
+ #include <unistd.h>
+@@ -27,13 +29,28 @@ void need_root(void)
+ 	}
+ }
+ 
++void need_tun(void)
++{
++#ifdef KNET_LINUX
++	const char *tundev = "/dev/net/tun";
++#else
++	const char *tundev = "/dev/tun";
++#endif
++	int fd = open(tundev, O_RDWR);
++	if (fd < 0) {
++		printf("Failed to open %s (errno=%d); this test requires TUN support\n", tundev, errno);
++		exit(SKIP);
++	}
++	close(fd);
++}
++
+ int test_iface(char *name, size_t size, const char *updownpath)
+ {
+ 	nozzle_t nozzle;
+ 
+ 	nozzle=nozzle_open(name, size, updownpath);
+ 	if (!nozzle) {
+-		printf("Unable to open nozzle.\n");
++		printf("Unable to open nozzle (errno=%d).\n", errno);
+ 		return -1;
+ 	}
+ 	printf("Created interface: %s\n", name);
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index b96349ff..04645b64 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -28,6 +28,7 @@
+ #define IPBUFSIZE 1024
+ 
+ void need_root(void);
++void need_tun(void);
+ int test_iface(char *name, size_t size, const char *updownpath);
+ int is_if_in_system(char *name);
+ int get_random_byte(void);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0436-nozzle-preserve-test-result-across-cleanup.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0436-nozzle-preserve-test-result-across-cleanup.patch
new file mode 100644
index 000000000..34a7c7d49
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0436-nozzle-preserve-test-result-across-cleanup.patch
@@ -0,0 +1,23 @@ 
+From 80bddd070a5da8762e4c62e14ea56820c46e7467 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Ferenc=20W=C3=A1gner?= <wferi@debian.org>
+Date: Sun, 29 Aug 2021 22:12:52 +0200
+Subject: [PATCH] nozzle: preserve test result across cleanup
+
+---
+ libnozzle/tests/api_nozzle_run_updown.c | 3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index b4b5a86a..5c8e8326 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -380,8 +380,7 @@ out_clean:
+ 	if (tmpdir) {
+ 		snprintf(tmpstr, sizeof(tmpstr) - 1, "rm -rf %s", tmpdir);
+ 		printf("Removing temporary dir: %s\n", tmpstr);
+-		err = execute_bin_sh_command(tmpstr, &error_string);
+-		if (err) {
++		if (execute_bin_sh_command(tmpstr, &error_string)) {
+ 			printf("Error removing directory: %s\n", error_string);
+ 		}
+ 		if (error_string) {
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0437-nozzle-fix-tests-on-machines-that-don-t-have-bash.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0437-nozzle-fix-tests-on-machines-that-don-t-have-bash.patch
new file mode 100644
index 000000000..98bdf64e8
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0437-nozzle-fix-tests-on-machines-that-don-t-have-bash.patch
@@ -0,0 +1,35 @@ 
+From 6f125b6717b7e3eddbed64e5d93571a11cb0bdc3 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 10 Sep 2021 05:00:09 +0200
+Subject: [PATCH] =?UTF-8?q?[nozzle]=20fix=20tests=20on=20machines=20that?=
+ =?UTF-8?q?=20don=C2=B4t=20have=20bash?=
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libnozzle/tests/nozzle_run_updown_exit_false | 2 +-
+ libnozzle/tests/nozzle_run_updown_exit_true  | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_false b/libnozzle/tests/nozzle_run_updown_exit_false
+index 7da20628..4ff2b727 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_false
++++ b/libnozzle/tests/nozzle_run_updown_exit_false
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ 
+ #
+ # Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_true b/libnozzle/tests/nozzle_run_updown_exit_true
+index c40177bb..c1e94682 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_true
++++ b/libnozzle/tests/nozzle_run_updown_exit_true
+@@ -1,4 +1,4 @@
+-#!/bin/bash
++#!/bin/sh
+ 
+ #
+ # Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0438-build-Add-annobin-build-check-support.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0438-build-Add-annobin-build-check-support.patch
new file mode 100644
index 000000000..a951bcc4c
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0438-build-Add-annobin-build-check-support.patch
@@ -0,0 +1,244 @@ 
+From 7920e2c83282dc783d48bb2781cc33cd66659580 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 10 May 2021 13:00:58 +0100
+Subject: [PATCH] [build] Add annobin build/check support
+
+the annobin check is enabled only if all compiler flags, linker flags
+and annocheck binary are available.
+
+the build will use as many of the hardening options required to pass
+the annocheck regardless.
+
+the check is performed / enabled only with gcc. clang currently suffers
+from some limitations to automatically detect the annobin plugin, that
+would increase drastacally the complexity of the build system
+unnecessarely.
+
+implementation based on:
+- https://bugzilla.redhat.com/show_bug.cgi?id=1961686
+- https://developers.redhat.com/blog/2019/02/04/annocheck-examining-the-contents-of-binary-files#
+- https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/8/html/developing_c_and_cpp_applications_in_rhel_8/annobin_toolsets
+
+Original idea by Christine Caulfield <ccaulfie@redhat.com>
+
+CentOS Stream CI insists on this but it's generally a 'good thing'
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/check.mk          | 31 ++++++++++++++++
+ configure.ac                | 73 +++++++++++++++++++++++++++++++++++--
+ libknet/Makefile.am         |  2 +
+ libknet/tests/Makefile.am   |  2 +-
+ libnozzle/Makefile.am       |  2 +
+ libnozzle/tests/Makefile.am |  2 +-
+ 6 files changed, 106 insertions(+), 6 deletions(-)
+
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index 3eec3797..f61baf30 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -49,3 +49,34 @@ endif
+ else
+ 	@echo cov-build not available on this platform
+ endif
++
++check-annocheck-libs:
++if HAS_ANNOCHECK
++	@echo Running annocheck libs test
++	if ! $(ANNOCHECK_EXEC) --quiet .libs/*.so; then \
++		$(ANNOCHECK_EXEC) --verbose .libs/*.so; \
++		echo annocheck libs test: FAILED; \
++		exit 1; \
++	else \
++		echo annocheck libs test: PASS; \
++	fi
++else
++	@echo Annocheck build or binary not available
++endif
++
++# we cannot check run-path because CI builds with specific prefix/user_prefix
++# and the only binaries affected are the test suite.
++
++check-annocheck-bins:
++if HAS_ANNOCHECK
++	@echo Running annocheck binaries test
++	if ! $(ANNOCHECK_EXEC) --skip-run-path --quiet .libs/*; then \
++		$(ANNOCHECK_EXEC) --skip-run-path --verbose .libs/*; \
++		echo annocheck binaries test: FAILED; \
++		exit 1; \
++	else \
++		echo annocheck binaries test: PASS; \
++	fi
++else
++	@echo Annocheck build or binary not available
++endif
+diff --git a/configure.ac b/configure.ac
+index c1e5d761..6e9b88b5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -32,7 +32,6 @@ AX_CHECK_LINK_FLAG([-Wl,--enable-new-dtags],
+ 		   [AC_MSG_ERROR(["Linker support for --enable-new-dtags is required"])])
+ AX_CHECK_LINK_FLAG([-Wl,--as-needed], [AM_LDFLAGS="$AM_LDFLAGS -Wl,--as-needed"])
+ 
+-AC_SUBST([AM_LDFLAGS])
+ saved_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$AM_LDFLAGS $LDFLAGS"
+ LT_INIT
+@@ -169,6 +168,23 @@ AC_ARG_ENABLE([libnozzle],
+ 
+ AM_CONDITIONAL([BUILD_LIBNOZZLE], [test x$enable_libnozzle = xyes])
+ 
++## local helper functions
++# this function checks if CC support options passed as
++# args. Global CPPFLAGS are ignored during this test.
++cc_supports_flag() {
++	saveCPPFLAGS="$CPPFLAGS"
++	CPPFLAGS="$@"
++	if echo $CC | grep -q clang; then
++		CPPFLAGS="-Werror $CPPFLAGS"
++	fi
++	AC_MSG_CHECKING([whether $CC supports "$@"])
++	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
++			  [RC=0; AC_MSG_RESULT([yes])],
++			  [RC=1; AC_MSG_RESULT([no])])
++	CPPFLAGS="$saveCPPFLAGS"
++	return $RC
++}
++
+ # Checks for libraries.
+ AX_PTHREAD(,[AC_MSG_ERROR([POSIX threads support is required])])
+ saved_LIBS="$LIBS"
+@@ -288,6 +304,10 @@ fi
+ AC_ARG_ENABLE([debug],
+ 	[AS_HELP_STRING([--enable-debug],[enable debug build])])
+ 
++AC_ARG_ENABLE([hardening],
++	[AS_HELP_STRING([--disable-hardening],[disable hardening build flags])],,
++	[ enable_hardening="yes" ])
++
+ AC_ARG_WITH([testdir],
+ 	[AS_HELP_STRING([--with-testdir=DIR],[path to /usr/lib../kronosnet/tests/ dir where to install the test suite])],
+ 	[ TESTDIR="$withval" ],
+@@ -297,6 +317,50 @@ AC_ARG_WITH([testdir],
+ 
+ AC_SUBST([TESTDIR])
+ 
++# Check for availablility of hardening options
++
++annocheck=no
++
++if test "x${enable_hardening}" = xyes; then
++	# support only gcc for now
++	if echo $CC | grep -q gcc; then
++		ANNOPLUGIN="-fplugin=annobin"
++		annocheck=yes
++	fi
++
++	HARDENING_CFLAGS_ANNOCHECK="$ANNOPLUGIN -fPIC -DPIC -pie -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fexceptions -D_GLIBCXX_ASSERTIONS -Wl,-z,now"
++	HARDENING_CFLAGS="-fstack-clash-protection -fcf-protection=full -mcet -mstackrealign"
++	EXTRA_HARDENING_CFLAGS=""
++
++	# check for annobin required cflags/ldflags
++	for j in $HARDENING_CFLAGS_ANNOCHECK; do
++		if cc_supports_flag $j; then
++			EXTRA_HARDENING_CFLAGS="$EXTRA_HARDENING_CFLAGS $j"
++		else
++			annocheck=no
++		fi
++	done
++
++	# check for other hardening cflags/ldflags
++	for j in $HARDENING_CFLAGS; do
++		if cc_supports_flag $j; then
++			EXTRA_HARDENING_CFLAGS="$EXTRA_HARDENING_CFLAGS $j"
++		fi
++	done
++
++	# check if annocheck binary is available
++	if test "x${annocheck}" = xyes; then
++		AC_CHECK_PROGS([ANNOCHECK_EXEC], [annocheck])
++		if test "x${ANNOCHECK_EXEC}" = x; then
++			annocheck=no
++		fi
++	fi
++
++	AM_LDFLAGS="$AM_LDFLAGS $EXTRA_HARDENING_CFLAGS"
++fi
++
++AM_CONDITIONAL([HAS_ANNOCHECK], [test "x$annocheck" = "xyes"])
++
+ # debug build stuff
+ if test "x${enable_debug}" = xyes; then
+ 	AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
+@@ -307,9 +371,9 @@ fi
+ 
+ # gdb flags
+ if test "x${GCC}" = xyes; then
+-	GDB_FLAGS="-ggdb3"
++	GDB_CFLAGS="-ggdb3"
+ else
+-	GDB_FLAGS="-g"
++	GDB_CFLAGS="-g"
+ fi
+ 
+ DEFAULT_CFLAGS="-Werror -Wall -Wextra"
+@@ -318,7 +382,8 @@ DEFAULT_CFLAGS="-Werror -Wall -Wextra"
+ # generates too much noise for stub APIs
+ UNWANTED_CFLAGS="-Wno-unused-parameter"
+ 
+-AC_SUBST([AM_CFLAGS],["$OPT_CFLAGS $GDB_FLAGS $DEFAULT_CFLAGS $UNWANTED_CFLAGS"])
++AC_SUBST([AM_CFLAGS],["$OPT_CFLAGS $GDB_CFLAGS $DEFAULT_CFLAGS $EXTRA_HARDENING_CFLAGS $UNWANTED_CFLAGS"])
++AC_SUBST([AM_LDFLAGS])
+ 
+ AX_PROG_DATE
+ AS_IF([test "$ax_cv_prog_date_gnu_date:$ax_cv_prog_date_gnu_utc" = yes:yes],
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index 555a6c52..ecb4beeb 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -102,6 +102,8 @@ libknet_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 
+ libknet_la_LIBADD	= $(PTHREAD_LIBS) $(dl_LIBS) $(rt_LIBS) $(m_LIBS)
+ 
++check-local: check-annocheck-libs
++
+ # Prepare empty value for appending
+ pkglib_LTLIBRARIES	=
+ 
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 38794433..22821928 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -71,7 +71,7 @@ testsuitedir		= $(TESTDIR)
+ testsuite_PROGRAMS	= $(noinst_PROGRAMS)
+ endif
+ 
+-check-local: check-api-test-coverage
++check-local: check-api-test-coverage check-annocheck-bins
+ 
+ check-api-test-coverage:
+ 	chmod u+x $(top_srcdir)/libknet/tests/api-test-coverage
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index bb84f24a..4c742e4d 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -46,4 +46,6 @@ libnozzle_la_LDFLAGS	= $(AM_LDFLAGS) \
+ 
+ libnozzle_la_LIBADD	= $(PTHREAD_LIBS) $(libnl_LIBS) $(libnlroute_LIBS)
+ 
++check-local: check-annocheck-libs
++
+ endif
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index b5e605ee..6e66a748 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -63,7 +63,7 @@ testsuitedir		= $(TESTDIR)
+ testsuite_PROGRAMS	= $(noinst_PROGRAMS)
+ endif
+ 
+-check-local: check-api-test-coverage
++check-local: check-api-test-coverage check-annocheck-bins
+ 
+ check-api-test-coverage:
+ 	chmod u+x $(top_srcdir)/libnozzle/tests/api-test-coverage
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0439-tests-temporary-disable-annobin-lto-check-for-centos.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0439-tests-temporary-disable-annobin-lto-check-for-centos.patch
new file mode 100644
index 000000000..d8f99acca
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0439-tests-temporary-disable-annobin-lto-check-for-centos.patch
@@ -0,0 +1,40 @@ 
+From 45c242ebf437c225012ce6a11a090bd5931a5a1e Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 18 Oct 2021 09:05:48 +0200
+Subject: [PATCH] [tests] temporary disable annobin lto check for centos8
+ failure
+
+adding -flto as suggested, triggers other annobin internal failures on
+centos8.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/check.mk | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index f61baf30..d33dc8d6 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -53,8 +53,8 @@ endif
+ check-annocheck-libs:
+ if HAS_ANNOCHECK
+ 	@echo Running annocheck libs test
+-	if ! $(ANNOCHECK_EXEC) --quiet .libs/*.so; then \
+-		$(ANNOCHECK_EXEC) --verbose .libs/*.so; \
++	if ! $(ANNOCHECK_EXEC) --skip-lto --quiet .libs/*.so; then \
++		$(ANNOCHECK_EXEC) --skip-lto --verbose .libs/*.so; \
+ 		echo annocheck libs test: FAILED; \
+ 		exit 1; \
+ 	else \
+@@ -70,8 +70,8 @@ endif
+ check-annocheck-bins:
+ if HAS_ANNOCHECK
+ 	@echo Running annocheck binaries test
+-	if ! $(ANNOCHECK_EXEC) --skip-run-path --quiet .libs/*; then \
+-		$(ANNOCHECK_EXEC) --skip-run-path --verbose .libs/*; \
++	if ! $(ANNOCHECK_EXEC) --skip-run-path --skip-lto --quiet .libs/*; then \
++		$(ANNOCHECK_EXEC) --skip-run-path --skip-lto --verbose .libs/*; \
+ 		echo annocheck binaries test: FAILED; \
+ 		exit 1; \
+ 	else \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0440-libknet-tests-Correct-include-path-for-poll.h.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0440-libknet-tests-Correct-include-path-for-poll.h.patch
new file mode 100644
index 000000000..a9e82e6fb
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0440-libknet-tests-Correct-include-path-for-poll.h.patch
@@ -0,0 +1,28 @@ 
+From fccdfb349d29fdc53092beaad41e687875d0b123 Mon Sep 17 00:00:00 2001
+From: Khem Raj <raj.khem@gmail.com>
+Date: Tue, 12 Oct 2021 20:35:53 -0700
+Subject: [PATCH] libknet/tests: Correct include path for poll.h
+
+Fixes
+/usr/include/sys/poll.h:1:2: error: redirec
+ting incorrect #include <sys/poll.h> to <poll.h> [-Werror,-W#warnings]
+| #warning redirecting incorrect #include <sys/poll.h> to <poll.h>
+
+Signed-off-by: Khem Raj <raj.khem@gmail.com>
+---
+ libknet/tests/test-common.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 86b76b0c..8f8b6ca7 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -20,7 +20,7 @@
+ #include <pthread.h>
+ #include <dirent.h>
+ #include <sys/select.h>
+-#include <sys/poll.h>
++#include <poll.h>
+ 
+ #include "libknet.h"
+ #include "test-common.h"
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0441-build-fix-debug-build-vs-annocheck-parameters.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0441-build-fix-debug-build-vs-annocheck-parameters.patch
new file mode 100644
index 000000000..b55680fac
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0441-build-fix-debug-build-vs-annocheck-parameters.patch
@@ -0,0 +1,62 @@ 
+From 473fd5987d7148e40746f70cacd7f842d9387825 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 21 Oct 2021 14:21:18 +0200
+Subject: [PATCH] [build] fix debug build vs annocheck parameters
+
+FORTIFY_SOURCE requires -O1 or higher
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac | 22 ++++++++++++++--------
+ 1 file changed, 14 insertions(+), 8 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 6e9b88b5..6f94475e 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -317,6 +317,16 @@ AC_ARG_WITH([testdir],
+ 
+ AC_SUBST([TESTDIR])
+ 
++# debug build stuff
++if test "x${enable_debug}" = xyes; then
++	AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
++	OPT_CFLAGS="-O0"
++	FORTIFY_CFLAGS=""
++else
++	OPT_CFLAGS="-O3"
++	FORTIFY_CFLAGS="-D_FORTIFY_SOURCE=2"
++fi
++
+ # Check for availablility of hardening options
+ 
+ annocheck=no
+@@ -328,7 +338,7 @@ if test "x${enable_hardening}" = xyes; then
+ 		annocheck=yes
+ 	fi
+ 
+-	HARDENING_CFLAGS_ANNOCHECK="$ANNOPLUGIN -fPIC -DPIC -pie -D_FORTIFY_SOURCE=2 -fstack-protector-strong -fexceptions -D_GLIBCXX_ASSERTIONS -Wl,-z,now"
++	HARDENING_CFLAGS_ANNOCHECK="$ANNOPLUGIN -fPIC -DPIC -pie $FORTIFY_CFLAGS -fstack-protector-strong -fexceptions -D_GLIBCXX_ASSERTIONS -Wl,-z,now"
+ 	HARDENING_CFLAGS="-fstack-clash-protection -fcf-protection=full -mcet -mstackrealign"
+ 	EXTRA_HARDENING_CFLAGS=""
+ 
+@@ -359,16 +369,12 @@ if test "x${enable_hardening}" = xyes; then
+ 	AM_LDFLAGS="$AM_LDFLAGS $EXTRA_HARDENING_CFLAGS"
+ fi
+ 
+-AM_CONDITIONAL([HAS_ANNOCHECK], [test "x$annocheck" = "xyes"])
+-
+-# debug build stuff
+ if test "x${enable_debug}" = xyes; then
+-	AC_DEFINE_UNQUOTED([DEBUG], [1], [Compiling Debugging code])
+-	OPT_CFLAGS="-O0"
+-else
+-	OPT_CFLAGS="-O3"
++	annocheck=no
+ fi
+ 
++AM_CONDITIONAL([HAS_ANNOCHECK], [test "x$annocheck" = "xyes"])
++
+ # gdb flags
+ if test "x${GCC}" = xyes; then
+ 	GDB_CFLAGS="-ggdb3"
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0442-crypto-fix-nss-crypto-buffer-boundaries-usage.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0442-crypto-fix-nss-crypto-buffer-boundaries-usage.patch
new file mode 100644
index 000000000..cba1e1305
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0442-crypto-fix-nss-crypto-buffer-boundaries-usage.patch
@@ -0,0 +1,32 @@ 
+From bffe456f2df4772e5b840eedffa7be082a0080bf Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 22 Oct 2021 08:06:22 +0200
+Subject: [PATCH] [crypto] fix nss crypto buffer boundaries usage
+
+this issue was detected by temporary increasing knet header size
+for debugging purposes, and was generating incorrect crypto data
+by PK11_CipherOp because the new size was overriding the old data.
+
+this issue does not affect onwire_v1 or stable1 as it is.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_nss.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index b2887ed8..f9e96def 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -394,9 +394,9 @@ static int encrypt_nss(
+ 	}
+ 
+ 	for (i=0; i<iovcnt; i++) {
+-		if (PK11_CipherOp(crypt_context, data,
++		if (PK11_CipherOp(crypt_context, data + tmp1_outlen,
+ 				  &tmp_outlen,
+-				  KNET_DATABUFSIZE_CRYPT,
++				  KNET_DATABUFSIZE_CRYPT - tmp1_outlen,
+ 				  (unsigned char *)iov[i].iov_base,
+ 				  iov[i].iov_len) != SECSuccess) {
+ 			log_err(knet_h, KNET_SUB_NSSCRYPTO, "PK11_CipherOp failed (encrypt) crypt_type=%d (err %d): %s",
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0443-host-fix-dst_seq_num-initialization-race-condition.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0443-host-fix-dst_seq_num-initialization-race-condition.patch
new file mode 100644
index 000000000..78c741328
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0443-host-fix-dst_seq_num-initialization-race-condition.patch
@@ -0,0 +1,46 @@ 
+From bbb39ebedf08555d03ced044543594f94954419b Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Mon, 8 Nov 2021 09:14:22 +0100
+Subject: [PATCH] [host] fix dst_seq_num initialization race condition
+
+There is a potential race condition where the sender
+is overloaded, sending data packets before pings
+can kick in and set the correct dst_seq_num.
+
+if this node is starting up (dst_seq_num = 0),
+it can start rejecing valid packets and get stuck.
+
+Set the dst_seq_num to the first seen packet and
+use that as reference instead.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/host.c | 15 +++++++++++++++
+ 1 file changed, 15 insertions(+)
+
+diff --git a/libknet/host.c b/libknet/host.c
+index ec73c0df..6fca01f8 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -573,6 +573,21 @@ int _seq_num_lookup(struct knet_host *host, seq_num_t seq_num, int defrag_buf, i
+ 	char *dst_cbuf_defrag = host->circular_buffer_defrag;
+ 	seq_num_t *dst_seq_num = &host->rx_seq_num;
+ 
++	/*
++	 * There is a potential race condition where the sender
++	 * is overloaded, sending data packets before pings
++	 * can kick in and set the correct dst_seq_num.
++	 *
++	 * if this node is starting up (dst_seq_num = 0),
++	 * it can start rejecing valid packets and get stuck.
++	 *
++	 * Set the dst_seq_num to the first seen packet and
++	 * use that as reference instead.
++	 */
++	if (!*dst_seq_num) {
++		*dst_seq_num = seq_num;
++	}
++
+ 	if (clear_buf) {
+ 		_clear_cbuffers(host, seq_num);
+ 	}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0444-udp-use-ICMP-error-messages-to-trigger-faster-link-d.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0444-udp-use-ICMP-error-messages-to-trigger-faster-link-d.patch
new file mode 100644
index 000000000..8ce41bb57
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0444-udp-use-ICMP-error-messages-to-trigger-faster-link-d.patch
@@ -0,0 +1,85 @@ 
+From 6a102b32b2373ca52b2f839e354738f75f101500 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Sun, 7 Nov 2021 17:02:05 +0100
+Subject: [PATCH] [udp] use ICMP error messages to trigger faster link down
+ detection
+
+this solves a possible race condition when:
+
+- node1 is running
+- node2 very fast
+- node1 does NOT have enough time to detect that node2 has gone
+  and reset the local seq numbers / buffers
+- node1 will start rejecting valid packets from node2
+
+There is still a potential minor race condition where app
+can restart so fast that kernel / network don't have time
+to generate an ICMP error. This will be addressed using
+instance id in onwire v2 protocol, as suggested by Jan F.
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/transport_udp.c | 44 +++++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 44 insertions(+)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 482c99b1..a1419c89 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -364,6 +364,46 @@ static int read_errs_from_sock(knet_handle_t knet_h, int sockfd)
+ 									log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from %s: %s destination unknown", addr_str, strerror(sock_err->ee_errno));
+ 								} else {
+ 									log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Received ICMP error from %s: %s %s", addr_str, strerror(sock_err->ee_errno), addr_remote_str);
++									if ((sock_err->ee_errno == ECONNREFUSED) || /* knet is not running on the other node */
++									    (sock_err->ee_errno == ECONNABORTED) || /* local kernel closed the socket */
++									    (sock_err->ee_errno == ENONET)       || /* network does not exist */
++									    (sock_err->ee_errno == ENETUNREACH)  || /* network unreachable */
++									    (sock_err->ee_errno == EHOSTUNREACH) || /* host unreachable */
++									    (sock_err->ee_errno == EHOSTDOWN)    || /* host down (from kernel/net/ipv4/icmp.c */
++									    (sock_err->ee_errno == ENETDOWN)) {     /* network down */
++										struct knet_host *host = NULL;
++										struct knet_link *kn_link = NULL;
++										int link_idx, found = 0;
++
++										for (host = knet_h->host_head; host != NULL; host = host->next) {
++											for (link_idx = 0; link_idx < KNET_MAX_LINK; link_idx++) {
++												kn_link = &host->link[link_idx];
++												if (kn_link->outsock == sockfd) {
++													if (!cmpaddr(&remote, &kn_link->dst_addr)) {
++														found = 1;
++														break;
++													}
++												}
++											}
++											if (found) {
++												break;
++											}
++										}
++
++										if ((host) && (kn_link) &&
++										    (kn_link->status.connected)) {
++											log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Setting down host %u link %i", host->host_id, kn_link->link_id);
++											/*
++											 * setting transport_connected = 0 will trigger
++											 * thread_heartbeat link_down process.
++											 *
++											 * the process terminates calling into transport_link_down
++											 * below that will set transport_connected = 1
++											 */
++											kn_link->transport_connected = 0;
++										}
++
++									}
+ 								}
+ 							}
+ 							break;
+@@ -436,5 +476,9 @@ int udp_transport_link_dyn_connect(knet_handle_t knet_h, int sockfd, struct knet
+ 
+ int udp_transport_link_is_down(knet_handle_t knet_h, struct knet_link *kn_link)
+ {
++	/*
++	 * see comments about handling ICMP error messages
++	 */
++	kn_link->transport_connected = 1;
+ 	return 0;
+ }
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0445-crypto-improve-logging-when-failing-to-decrypt-packe.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0445-crypto-improve-logging-when-failing-to-decrypt-packe.patch
new file mode 100644
index 000000000..424ae4312
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0445-crypto-improve-logging-when-failing-to-decrypt-packe.patch
@@ -0,0 +1,117 @@ 
+From c9a1dd20e9375c605b8c2cdf05b3561236aa1a13 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 10 Nov 2021 18:50:41 +0100
+Subject: [PATCH] [crypto] improve logging when failing to decrypt packets
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/crypto_nss.c     |  6 +++---
+ libknet/crypto_openssl.c |  6 +++---
+ libknet/threads_rx.c     | 22 +++++++++++++++++-----
+ 3 files changed, 23 insertions(+), 11 deletions(-)
+
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index f9e96def..73a9929f 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -728,7 +728,7 @@ static int nsscrypto_authenticate_and_decrypt (
+ 		ssize_t temp_buf_len = buf_in_len - nsshash_len[instance->crypto_hash_type];
+ 
+ 		if ((temp_buf_len <= 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
+-			log_err(knet_h, KNET_SUB_NSSCRYPTO, "Incorrect packet size.");
++			log_debug(knet_h, KNET_SUB_NSSCRYPTO, "Received incorrect packet size: %zu for hash size: %zu", buf_in_len, nsshash_len[instance->crypto_hash_type]);
+ 			return -1;
+ 		}
+ 
+@@ -738,9 +738,9 @@ static int nsscrypto_authenticate_and_decrypt (
+ 
+ 		if (memcmp(tmp_hash, buf_in + temp_buf_len, nsshash_len[instance->crypto_hash_type]) != 0) {
+ 			if (log_level == KNET_LOG_DEBUG) {
+-				log_debug(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match");
++				log_debug(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match. Check crypto key and configuration.");
+ 			} else {
+-				log_err(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match");
++				log_err(knet_h, KNET_SUB_NSSCRYPTO, "Digest does not match. Check crypto key and configuration.");
+ 			}
+ 			return -1;
+ 		}
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 10821a81..8bc306d8 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -459,7 +459,7 @@ static int opensslcrypto_authenticate_and_decrypt (
+ 		memset(tmp_hash, 0, sizeof(tmp_hash));
+ 
+ 		if ((temp_buf_len <= 0) || (temp_buf_len > KNET_MAX_PACKET_SIZE)) {
+-			log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Incorrect packet size.");
++			log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Received incorrect packet size: %zu for hash size: %zu", buf_in_len, crypto_instance->sec_hash_size);
+ 			return -1;
+ 		}
+ 
+@@ -469,9 +469,9 @@ static int opensslcrypto_authenticate_and_decrypt (
+ 
+ 		if (memcmp(tmp_hash, buf_in + temp_buf_len, crypto_instance->sec_hash_size) != 0) {
+ 			if (log_level == KNET_LOG_DEBUG) {
+-				log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match");
++				log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match. Check crypto key and configuration.");
+ 			} else {
+-				log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match");
++				log_err(knet_h, KNET_SUB_OPENSSLCRYPTO, "Digest does not match. Check crypto key and configuration.");
+ 			}
+ 			return -1;
+ 		}
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index 213860fd..f2bf2e06 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -242,9 +242,9 @@ static int _check_rx_acl(knet_handle_t knet_h, struct knet_link *src_link, const
+ 					   src_ipaddr, KNET_MAX_HOST_LEN,
+ 					   src_port, KNET_MAX_PORT_LEN) < 0) {
+ 
+-				log_debug(knet_h, KNET_SUB_RX, "Packet rejected: unable to resolve host/port");
++				log_warn(knet_h, KNET_SUB_RX, "Packet rejected: unable to resolve host/port");
+ 			} else {
+-				log_debug(knet_h, KNET_SUB_RX, "Packet rejected from %s/%s", src_ipaddr, src_port);
++				log_warn(knet_h, KNET_SUB_RX, "Packet rejected from %s:%s", src_ipaddr, src_port);
+ 			}
+ 			return 0;
+ 		}
+@@ -297,6 +297,18 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 						    &outlen) < 0) {
+ 			log_debug(knet_h, KNET_SUB_RX, "Unable to decrypt/auth packet");
+ 			if (knet_h->crypto_only == KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
++				char src_ipaddr[KNET_MAX_HOST_LEN];
++				char src_port[KNET_MAX_PORT_LEN];
++
++				memset(src_ipaddr, 0, KNET_MAX_HOST_LEN);
++				memset(src_port, 0, KNET_MAX_PORT_LEN);
++				if (knet_addrtostr(msg->msg_hdr.msg_name, sockaddr_len(msg->msg_hdr.msg_name),
++						   src_ipaddr, KNET_MAX_HOST_LEN,
++						   src_port, KNET_MAX_PORT_LEN) < 0) {
++					log_err(knet_h, KNET_SUB_RX, "Unable to decrypt packet from unknown host/port (size %zu)!", len);
++				} else {
++					log_err(knet_h, KNET_SUB_RX, "Unable to decrypt packet from %s:%s (size %zu)!", src_ipaddr, src_port, len);
++				}
+ 				return;
+ 			}
+ 			log_debug(knet_h, KNET_SUB_RX, "Attempting to process packet as clear data");
+@@ -347,7 +359,7 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 					snprintf(src_link->status.dst_port, KNET_MAX_PORT_LEN - 1, "??");
+ 				} else {
+ 					log_info(knet_h, KNET_SUB_RX,
+-						 "host: %u link: %u new connection established from: %s %s",
++						 "host: %u link: %u new connection established from: %s:%s",
+ 						 src_host->host_id, src_link->link_id,
+ 						 src_link->status.dst_ipaddr, src_link->status.dst_port);
+ 				}
+@@ -492,8 +504,8 @@ static void _parse_recv_from_links(knet_handle_t knet_h, int sockfd, const struc
+ 			} else {
+ 				pthread_mutex_unlock(&knet_h->handle_stats_mutex);
+ 				pthread_mutex_unlock(&src_link->link_stats_mutex);
+-				log_warn(knet_h, KNET_SUB_COMPRESS, "Unable to decompress packet (%d): %s",
+-					 err, strerror(errno));
++				log_err(knet_h, KNET_SUB_COMPRESS, "Unable to decompress packet (%d): %s",
++					err, strerror(errno));
+ 				return;
+ 			}
+ 			pthread_mutex_unlock(&knet_h->handle_stats_mutex);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0446-logging-slow-down-knet-a-bit-when-log-socket-is-busy.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0446-logging-slow-down-knet-a-bit-when-log-socket-is-busy.patch
new file mode 100644
index 000000000..c36f33547
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0446-logging-slow-down-knet-a-bit-when-log-socket-is-busy.patch
@@ -0,0 +1,58 @@ 
+From bbec1aa85339480799f6da4c9f40551d628c1191 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Thu, 11 Nov 2021 16:42:09 +0100
+Subject: [PATCH] [logging] slow down knet a bit when log socket is busy
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/logging.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 3f5379f6..6e2f570b 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -208,6 +208,7 @@ void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
+ 	struct knet_log_msg msg;
+ 	size_t byte_cnt = 0;
+ 	int len;
++	int retry_loop = 0;
+ 
+ 	if ((!knet_h) ||
+ 	    (subsystem == KNET_MAX_SUBSYSTEMS) ||
+@@ -232,9 +233,35 @@ void log_msg(knet_handle_t knet_h, uint8_t subsystem, uint8_t msglevel,
+ #endif
+ 	va_end(ap);
+ 
++retry:
+ 	while (byte_cnt < sizeof(struct knet_log_msg)) {
+ 		len = write(knet_h->logfd, &msg, sizeof(struct knet_log_msg) - byte_cnt);
+ 		if (len <= 0) {
++			if (errno == EAGAIN) {
++				struct timeval tv;
++
++				/*
++				 * those 3 lines are the equivalent of usleep(1)
++				 * but usleep makes some static code analizers very
++				 * unhappy.
++				 *
++				 * this version is somewhat stolen from gnulib
++				 * nanosleep implementation
++				 */
++				tv.tv_sec = 0;
++				tv.tv_usec = 1;
++				select(0, NULL, NULL, NULL, &tv);
++
++				retry_loop++;
++				/*
++				 * arbitrary amount of retries.
++				 * tested with fun_log_bench, 10 retries was never hit
++				 */
++				if (retry_loop >= 100) {
++					goto out;
++				}
++				goto retry;
++			}
+ 			goto out;
+ 		}
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0447-doc-update-links-to-mailing-lists-and-drop-obsolete-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0447-doc-update-links-to-mailing-lists-and-drop-obsolete-.patch
new file mode 100644
index 000000000..9075ade1d
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0447-doc-update-links-to-mailing-lists-and-drop-obsolete-.patch
@@ -0,0 +1,29 @@ 
+From a4fac9f53e175ad59610ce8b60eda31188d23a30 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Wed, 17 Nov 2021 06:26:15 +0100
+Subject: [PATCH] [doc] update links to mailing lists and drop obsolete test
+ suite
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ README | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+diff --git a/README b/README
+index f1fc011a..1602092f 100644
+--- a/README
++++ b/README
+@@ -13,10 +13,9 @@ https://github.com/kronosnet/kronosnet/
+ https://ci.kronosnet.org/
+ https://trello.com/kronosnet (TODO list and activities tracking)
+ https://goo.gl/9ZvkLS (google shared drive)
+-https://github.com/kronosnet/knet-ansible-ci
+-https://lists.kronosnet.org/mailman/listinfo/users
+-https://lists.kronosnet.org/mailman/listinfo/devel
+-https://lists.kronosnet.org/mailman/listinfo/commits
++https://lists.kronosnet.org/mailman3/postorius/lists/users.lists.kronosnet.org/
++https://lists.kronosnet.org/mailman3/postorius/lists/devel.lists.kronosnet.org/
++https://lists.kronosnet.org/mailman3/postorius/lists/commits.lists.kronosnet.org/
+ https://kronosnet.org/ (web 0.1 style)
+ IRC: #kronosnet on Libera.Chat
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0448-build-fix-flag-detections-for-gcc.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0448-build-fix-flag-detections-for-gcc.patch
new file mode 100644
index 000000000..293f74796
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0448-build-fix-flag-detections-for-gcc.patch
@@ -0,0 +1,28 @@ 
+From 4d6458fbe68ff8d2d1fb7a5192d0281442577a18 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 30 Nov 2021 10:32:18 +0100
+Subject: [PATCH] [build] fix flag detections for gcc
+
+Resolves: https://github.com/kronosnet/kronosnet/issues/371
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ configure.ac | 5 +----
+ 1 file changed, 1 insertion(+), 4 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 6f94475e..c6e97d4c 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -173,10 +173,7 @@ AM_CONDITIONAL([BUILD_LIBNOZZLE], [test x$enable_libnozzle = xyes])
+ # args. Global CPPFLAGS are ignored during this test.
+ cc_supports_flag() {
+ 	saveCPPFLAGS="$CPPFLAGS"
+-	CPPFLAGS="$@"
+-	if echo $CC | grep -q clang; then
+-		CPPFLAGS="-Werror $CPPFLAGS"
+-	fi
++	CPPFLAGS="-Werror $@"
+ 	AC_MSG_CHECKING([whether $CC supports "$@"])
+ 	AC_COMPILE_IFELSE([AC_LANG_PROGRAM([])],
+ 			  [RC=0; AC_MSG_RESULT([yes])],
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0449-UDP-Check-for-EHOSTUNREACH.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0449-UDP-Check-for-EHOSTUNREACH.patch
new file mode 100644
index 000000000..eac88d6d0
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0449-UDP-Check-for-EHOSTUNREACH.patch
@@ -0,0 +1,26 @@ 
+From e95776d9943057caa0d8e6cc446bcb1211d380d7 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Mon, 13 Dec 2021 14:46:46 +0000
+Subject: [PATCH] [UDP] Check for EHOSTUNREACH
+
+EHOSTUNREACH seems to have been missed from the list of errors
+checked at transmit time, so add it. Without this,
+knet can spin under some conditions. (see issue #373)
+---
+ libknet/transport_udp.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index a1419c89..13f6d96b 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -438,7 +438,8 @@ int udp_transport_tx_sock_error(knet_handle_t knet_h, int sockfd, int recv_err,
+ 			return 0;
+ 		}
+ 		if ((recv_errno == EINVAL) || (recv_errno == EPERM) ||
+-		    (recv_errno == ENETUNREACH) || (recv_errno == ENETDOWN)) {
++		    (recv_errno == ENETUNREACH) || (recv_errno == ENETDOWN) ||
++		    (recv_errno == EHOSTUNREACH)) {
+ #ifdef DEBUG
+ 			if ((recv_errno == ENETUNREACH) || (recv_errno == ENETDOWN)) {
+ 				log_debug(knet_h, KNET_SUB_TRANSP_UDP, "Sock: %d is unreachable.", sockfd);
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0450-tests-move-all-tests-to-new-infrastructure.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0450-tests-move-all-tests-to-new-infrastructure.patch
new file mode 100644
index 000000000..1d97476ea
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0450-tests-move-all-tests-to-new-infrastructure.patch
@@ -0,0 +1,12692 @@ 
+From bc5cd0e224c1f0c485c1e01e26422b3f7cbc6a43 Mon Sep 17 00:00:00 2001
+From: Christine Caulfield <ccaulfie@redhat.com>
+Date: Thu, 24 Feb 2022 11:17:34 +0000
+Subject: [PATCH] tests: move all tests to new infrastructure
+
+and update copyright years
+---
+ COPYRIGHT                                     |   2 +-
+ Makefile.am                                   |   2 +-
+ NOTES_TO_PACKAGE_MAINTAINERS                  |   2 +-
+ README                                        |   2 +-
+ autogen.sh                                    |   2 +-
+ build-aux/check.mk                            |   2 +-
+ build-aux/git-version-gen                     |   2 +-
+ build-aux/knet_valgrind_helgrind.supp         |   2 +-
+ build-aux/knet_valgrind_memcheck.supp         |   2 +-
+ build-aux/release.mk                          |   2 +-
+ build-aux/update-copyright.sh                 |   2 +-
+ configure.ac                                  |   2 +-
+ kronosnet.spec.in                             |   2 +-
+ libknet/Makefile.am                           |   2 +-
+ libknet/common.c                              |   2 +-
+ libknet/common.h                              |   2 +-
+ libknet/compat.c                              |   2 +-
+ libknet/compat.h                              |   2 +-
+ libknet/compress.c                            |   2 +-
+ libknet/compress.h                            |   2 +-
+ libknet/compress_bzip2.c                      |   2 +-
+ libknet/compress_lz4.c                        |   2 +-
+ libknet/compress_lz4hc.c                      |   2 +-
+ libknet/compress_lzma.c                       |   2 +-
+ libknet/compress_lzo2.c                       |   2 +-
+ libknet/compress_model.h                      |   2 +-
+ libknet/compress_zlib.c                       |   2 +-
+ libknet/compress_zstd.c                       |   2 +-
+ libknet/crypto.c                              |   2 +-
+ libknet/crypto.h                              |   2 +-
+ libknet/crypto_model.h                        |   2 +-
+ libknet/crypto_nss.c                          |   2 +-
+ libknet/crypto_openssl.c                      |   2 +-
+ libknet/handle.c                              |   2 +-
+ libknet/handle_api.c                          |   2 +-
+ libknet/host.c                                |   2 +-
+ libknet/host.h                                |   2 +-
+ libknet/internals.h                           |   2 +-
+ libknet/lib_config.c                          |   2 +-
+ libknet/libknet.h                             |   4 +-
+ libknet/libknet.pc.in                         |   2 +-
+ libknet/libknet_exported_syms                 |   2 +-
+ libknet/links.c                               |   2 +-
+ libknet/links.h                               |   2 +-
+ libknet/links_acl.c                           |   2 +-
+ libknet/links_acl.h                           |   2 +-
+ libknet/links_acl_ip.c                        |   2 +-
+ libknet/links_acl_ip.h                        |   2 +-
+ libknet/links_acl_loopback.c                  |   2 +-
+ libknet/links_acl_loopback.h                  |   2 +-
+ libknet/logging.c                             |   2 +-
+ libknet/logging.h                             |   2 +-
+ libknet/netutils.c                            |   2 +-
+ libknet/netutils.h                            |   2 +-
+ libknet/onwire.c                              |   2 +-
+ libknet/onwire.h                              |   2 +-
+ libknet/tests/Makefile.am                     |   2 +-
+ libknet/tests/api-check.mk                    |   2 +-
+ libknet/tests/api-test-coverage               |   2 +-
+ libknet/tests/api_knet_addrtostr.c            |   2 +-
+ libknet/tests/api_knet_get_compress_list.c    |   2 +-
+ libknet/tests/api_knet_get_crypto_list.c      |   2 +-
+ .../tests/api_knet_get_transport_id_by_name.c |   2 +-
+ libknet/tests/api_knet_get_transport_list.c   |   2 +-
+ .../tests/api_knet_get_transport_name_by_id.c |   2 +-
+ libknet/tests/api_knet_handle_add_datafd.c    | 134 +-------
+ libknet/tests/api_knet_handle_clear_stats.c   | 178 ++--------
+ libknet/tests/api_knet_handle_compress.c      | 120 +------
+ libknet/tests/api_knet_handle_crypto.c        | 180 ++--------
+ .../api_knet_handle_crypto_rx_clear_traffic.c |  64 +---
+ .../tests/api_knet_handle_crypto_set_config.c | 282 +++------------
+ .../tests/api_knet_handle_crypto_use_config.c | 167 ++-------
+ .../api_knet_handle_enable_access_lists.c     |  59 +---
+ libknet/tests/api_knet_handle_enable_filter.c |  89 +----
+ .../api_knet_handle_enable_pmtud_notify.c     |  91 +----
+ .../api_knet_handle_enable_sock_notify.c      |  80 +----
+ libknet/tests/api_knet_handle_free.c          |  55 +--
+ libknet/tests/api_knet_handle_get_channel.c   |  83 +----
+ libknet/tests/api_knet_handle_get_datafd.c    |  81 +----
+ libknet/tests/api_knet_handle_get_stats.c     |  49 +--
+ ..._handle_get_transport_reconnect_interval.c |  39 +--
+ libknet/tests/api_knet_handle_new.c           |  52 ++-
+ libknet/tests/api_knet_handle_new_limit.c     |   2 +-
+ libknet/tests/api_knet_handle_pmtud_get.c     |  37 +-
+ libknet/tests/api_knet_handle_pmtud_getfreq.c |  36 +-
+ libknet/tests/api_knet_handle_pmtud_set.c     | 149 ++------
+ libknet/tests/api_knet_handle_pmtud_setfreq.c |  47 +--
+ libknet/tests/api_knet_handle_remove_datafd.c |  64 +---
+ ..._handle_set_transport_reconnect_interval.c |  40 +--
+ libknet/tests/api_knet_handle_setfwd.c        |  59 +---
+ libknet/tests/api_knet_host_add.c             |  58 +---
+ ...pi_knet_host_enable_status_change_notify.c |  92 +----
+ libknet/tests/api_knet_host_get_host_list.c   |  91 +----
+ .../tests/api_knet_host_get_id_by_host_name.c |  68 +---
+ .../tests/api_knet_host_get_name_by_host_id.c |  56 +--
+ libknet/tests/api_knet_host_get_policy.c      |  74 +---
+ libknet/tests/api_knet_host_get_status.c      |  56 +--
+ libknet/tests/api_knet_host_remove.c          | 103 +-----
+ libknet/tests/api_knet_host_set_name.c        | 118 ++-----
+ libknet/tests/api_knet_host_set_policy.c      |  66 +---
+ libknet/tests/api_knet_link_add_acl.c         | 186 ++--------
+ libknet/tests/api_knet_link_clear_acl.c       | 141 +-------
+ libknet/tests/api_knet_link_clear_config.c    | 115 +------
+ libknet/tests/api_knet_link_get_config.c      | 233 ++-----------
+ libknet/tests/api_knet_link_get_enable.c      | 136 +-------
+ libknet/tests/api_knet_link_get_link_list.c   | 110 +-----
+ libknet/tests/api_knet_link_get_ping_timers.c | 125 +------
+ libknet/tests/api_knet_link_get_pong_count.c  | 110 +-----
+ libknet/tests/api_knet_link_get_priority.c    | 110 +-----
+ libknet/tests/api_knet_link_get_status.c      |  93 +----
+ libknet/tests/api_knet_link_insert_acl.c      | 182 ++--------
+ libknet/tests/api_knet_link_rm_acl.c          | 195 ++---------
+ libknet/tests/api_knet_link_set_config.c      | 247 ++-----------
+ libknet/tests/api_knet_link_set_enable.c      | 254 ++------------
+ libknet/tests/api_knet_link_set_ping_timers.c | 131 +------
+ libknet/tests/api_knet_link_set_pong_count.c  | 102 +-----
+ libknet/tests/api_knet_link_set_priority.c    |  89 +----
+ libknet/tests/api_knet_log_get_loglevel.c     |  51 +--
+ libknet/tests/api_knet_log_get_loglevel_id.c  |   2 +-
+ .../tests/api_knet_log_get_loglevel_name.c    |   2 +-
+ libknet/tests/api_knet_log_get_subsystem_id.c |   2 +-
+ .../tests/api_knet_log_get_subsystem_name.c   |   2 +-
+ libknet/tests/api_knet_log_set_loglevel.c     |  60 +---
+ libknet/tests/api_knet_recv.c                 | 124 +------
+ libknet/tests/api_knet_send.c                 | 267 ++-------------
+ libknet/tests/api_knet_send_compress.c        | 166 ++-------
+ libknet/tests/api_knet_send_crypto.c          | 164 ++-------
+ libknet/tests/api_knet_send_loopback.c        | 324 +++---------------
+ libknet/tests/api_knet_send_sync.c            | 264 ++------------
+ libknet/tests/api_knet_strtoaddr.c            |   2 +-
+ libknet/tests/fun_acl_check.c                 | 129 ++++---
+ libknet/tests/fun_config_crypto.c             |  81 +----
+ libknet/tests/fun_pmtud_crypto.c              | 124 ++-----
+ libknet/tests/int_links_acl_ip.c              |   2 +-
+ libknet/tests/int_timediff.c                  |   2 +-
+ libknet/tests/knet_bench.c                    |   7 +-
+ libknet/tests/pckt_test.c                     |   2 +-
+ libknet/tests/test-common.c                   | 122 ++++---
+ libknet/tests/test-common.h                   |  72 +++-
+ libknet/threads_common.c                      |   2 +-
+ libknet/threads_common.h                      |   2 +-
+ libknet/threads_dsthandler.c                  |   2 +-
+ libknet/threads_dsthandler.h                  |   2 +-
+ libknet/threads_heartbeat.c                   |   2 +-
+ libknet/threads_heartbeat.h                   |   2 +-
+ libknet/threads_pmtud.c                       |   2 +-
+ libknet/threads_pmtud.h                       |   2 +-
+ libknet/threads_rx.c                          |   2 +-
+ libknet/threads_rx.h                          |   2 +-
+ libknet/threads_tx.c                          |   2 +-
+ libknet/threads_tx.h                          |   2 +-
+ libknet/transport_common.c                    |   2 +-
+ libknet/transport_common.h                    |   2 +-
+ libknet/transport_loopback.c                  |   2 +-
+ libknet/transport_loopback.h                  |   2 +-
+ libknet/transport_sctp.c                      |   2 +-
+ libknet/transport_sctp.h                      |   2 +-
+ libknet/transport_udp.c                       |   2 +-
+ libknet/transport_udp.h                       |   2 +-
+ libknet/transports.c                          |   2 +-
+ libknet/transports.h                          |   2 +-
+ libnozzle/Makefile.am                         |   2 +-
+ libnozzle/internals.c                         |   2 +-
+ libnozzle/internals.h                         |   2 +-
+ libnozzle/libnozzle.c                         |   2 +-
+ libnozzle/libnozzle.h                         |   4 +-
+ libnozzle/libnozzle.pc.in                     |   2 +-
+ libnozzle/libnozzle_exported_syms             |   2 +-
+ libnozzle/tests/Makefile.am                   |   2 +-
+ libnozzle/tests/api-test-coverage             |   2 +-
+ libnozzle/tests/api_nozzle_add_ip.c           |   2 +-
+ libnozzle/tests/api_nozzle_close.c            |   2 +-
+ libnozzle/tests/api_nozzle_del_ip.c           |   2 +-
+ libnozzle/tests/api_nozzle_get_fd.c           |   2 +-
+ .../tests/api_nozzle_get_handle_by_name.c     |   2 +-
+ libnozzle/tests/api_nozzle_get_ips.c          |   2 +-
+ libnozzle/tests/api_nozzle_get_mac.c          |   2 +-
+ libnozzle/tests/api_nozzle_get_mtu.c          |   2 +-
+ .../tests/api_nozzle_get_name_by_handle.c     |   2 +-
+ libnozzle/tests/api_nozzle_open.c             |   2 +-
+ libnozzle/tests/api_nozzle_run_updown.c       |   2 +-
+ libnozzle/tests/api_nozzle_set_down.c         |   2 +-
+ libnozzle/tests/api_nozzle_set_mac.c          |   2 +-
+ libnozzle/tests/api_nozzle_set_mtu.c          |   2 +-
+ libnozzle/tests/api_nozzle_set_up.c           |   2 +-
+ libnozzle/tests/int_execute_bin_sh_command.c  |   2 +-
+ libnozzle/tests/nozzle_run_updown_exit_false  |   2 +-
+ libnozzle/tests/nozzle_run_updown_exit_true   |   2 +-
+ libnozzle/tests/test-common.c                 |   2 +-
+ libnozzle/tests/test-common.h                 |   2 +-
+ m4/pkg_check_var.m4                           |   2 +-
+ man/Doxyfile-knet.in                          |   2 +-
+ man/Doxyfile-nozzle.in                        |   2 +-
+ man/Makefile.am                               |   2 +-
+ man/api-to-man-page-coverage                  |   2 +-
+ man/doxyxml.c                                 |   2 +-
+ 196 files changed, 1420 insertions(+), 6377 deletions(-)
+
+diff --git a/COPYRIGHT b/COPYRIGHT
+index 6e23bea7..8adbb0b1 100644
+--- a/COPYRIGHT
++++ b/COPYRIGHT
+@@ -1,4 +1,4 @@
+-Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ 
+ Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+          Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/Makefile.am b/Makefile.am
+index 36680dcf..efdeb5bd 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/NOTES_TO_PACKAGE_MAINTAINERS b/NOTES_TO_PACKAGE_MAINTAINERS
+index b6396260..946d88b7 100644
+--- a/NOTES_TO_PACKAGE_MAINTAINERS
++++ b/NOTES_TO_PACKAGE_MAINTAINERS
+@@ -1,4 +1,4 @@
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/README b/README
+index 1602092f..f71405b4 100644
+--- a/README
++++ b/README
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/autogen.sh b/autogen.sh
+index 9707ec27..0efd9f1b 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index d33dc8d6..2bb5dcab 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/git-version-gen b/build-aux/git-version-gen
+index d2318513..94e78bc4 100755
+--- a/build-aux/git-version-gen
++++ b/build-aux/git-version-gen
+@@ -2,7 +2,7 @@
+ # Print a version string.
+ scriptversion=2018-08-31.20; # UTC
+ 
+-# Copyright (C) 2012-2021 Red Hat, Inc.
++# Copyright (C) 2012-2022 Red Hat, Inc.
+ # Copyright (C) 2007-2016 Free Software Foundation, Inc.
+ #
+ # This program is free software: you can redistribute it and/or modify
+diff --git a/build-aux/knet_valgrind_helgrind.supp b/build-aux/knet_valgrind_helgrind.supp
+index d3976c29..2336a316 100644
+--- a/build-aux/knet_valgrind_helgrind.supp
++++ b/build-aux/knet_valgrind_helgrind.supp
+@@ -1,4 +1,4 @@
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 2416c318..6214fc5e 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -1,4 +1,4 @@
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/release.mk b/build-aux/release.mk
+index 81c7ff8f..32ad5939 100644
+--- a/build-aux/release.mk
++++ b/build-aux/release.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/build-aux/update-copyright.sh b/build-aux/update-copyright.sh
+index 9bb9ff14..3a63c6f3 100755
+--- a/build-aux/update-copyright.sh
++++ b/build-aux/update-copyright.sh
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/configure.ac b/configure.ac
+index c6e97d4c..4a6c1cf7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/kronosnet.spec.in b/kronosnet.spec.in
+index b764f605..706dcdfb 100644
+--- a/kronosnet.spec.in
++++ b/kronosnet.spec.in
+@@ -1,7 +1,7 @@
+ ###############################################################################
+ ###############################################################################
+ ##
+-##  Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++##  Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+ ##
+ ##  This copyrighted material is made available to anyone wishing to use,
+ ##  modify, copy, or redistribute it subject to the terms and conditions
+diff --git a/libknet/Makefile.am b/libknet/Makefile.am
+index ecb4beeb..3fc35f34 100644
+--- a/libknet/Makefile.am
++++ b/libknet/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/common.c b/libknet/common.c
+index 9bc3396e..62a99dd8 100644
+--- a/libknet/common.c
++++ b/libknet/common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/common.h b/libknet/common.h
+index 3d826ba4..d6078c49 100644
+--- a/libknet/common.h
++++ b/libknet/common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/compat.c b/libknet/compat.c
+index 8707250c..74e72133 100644
+--- a/libknet/compat.c
++++ b/libknet/compat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compat.h b/libknet/compat.h
+index 201e1cac..b5fdb2f0 100644
+--- a/libknet/compat.h
++++ b/libknet/compat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Jan Friesse <jfriesse@redhat.com>
+  *
+diff --git a/libknet/compress.c b/libknet/compress.c
+index d1673ca5..43900135 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress.h b/libknet/compress.h
+index b7adaa95..21ec4ebe 100644
+--- a/libknet/compress.h
++++ b/libknet/compress.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_bzip2.c b/libknet/compress_bzip2.c
+index d188e957..4132ad1a 100644
+--- a/libknet/compress_bzip2.c
++++ b/libknet/compress_bzip2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4.c b/libknet/compress_lz4.c
+index 37cf5881..cf2bebcd 100644
+--- a/libknet/compress_lz4.c
++++ b/libknet/compress_lz4.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lz4hc.c b/libknet/compress_lz4hc.c
+index c09d1e53..aecad904 100644
+--- a/libknet/compress_lz4hc.c
++++ b/libknet/compress_lz4hc.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzma.c b/libknet/compress_lzma.c
+index 3d6ee886..baf40337 100644
+--- a/libknet/compress_lzma.c
++++ b/libknet/compress_lzma.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_lzo2.c b/libknet/compress_lzo2.c
+index 5dc560bc..e451e8a4 100644
+--- a/libknet/compress_lzo2.c
++++ b/libknet/compress_lzo2.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_model.h b/libknet/compress_model.h
+index 2f9668f2..1da8d792 100644
+--- a/libknet/compress_model.h
++++ b/libknet/compress_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zlib.c b/libknet/compress_zlib.c
+index 16e8c14d..a9872e8b 100644
+--- a/libknet/compress_zlib.c
++++ b/libknet/compress_zlib.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/compress_zstd.c b/libknet/compress_zstd.c
+index 7e4b0027..6b77fd24 100644
+--- a/libknet/compress_zstd.c
++++ b/libknet/compress_zstd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index 22759f31..f1e4b3d0 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto.h b/libknet/crypto.h
+index d84287cd..fd49e20e 100644
+--- a/libknet/crypto.h
++++ b/libknet/crypto.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_model.h b/libknet/crypto_model.h
+index 7a6425bd..eca7f095 100644
+--- a/libknet/crypto_model.h
++++ b/libknet/crypto_model.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 73a9929f..075cf118 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 8bc306d8..5c55fe22 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/handle.c b/libknet/handle.c
+index 54edf1b9..bd60e502 100644
+--- a/libknet/handle.c
++++ b/libknet/handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/handle_api.c b/libknet/handle_api.c
+index 30fec2cf..65825258 100644
+--- a/libknet/handle_api.c
++++ b/libknet/handle_api.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.c b/libknet/host.c
+index 6fca01f8..6ee13fa2 100644
+--- a/libknet/host.c
++++ b/libknet/host.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/host.h b/libknet/host.h
+index ce61f46e..31cb68d1 100644
+--- a/libknet/host.h
++++ b/libknet/host.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/internals.h b/libknet/internals.h
+index a3477280..ed635222 100644
+--- a/libknet/internals.h
++++ b/libknet/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/lib_config.c b/libknet/lib_config.c
+index b7d28590..8659d2eb 100644
+--- a/libknet/lib_config.c
++++ b/libknet/lib_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2021-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/libknet.h b/libknet/libknet.h
+index 790bc227..429dab24 100644
+--- a/libknet/libknet.h
++++ b/libknet/libknet.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+@@ -19,7 +19,7 @@
+ /**
+  * @file libknet.h
+  * @brief kronosnet API include file
+- * @copyright Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Kronosnet is an advanced VPN system for High Availability applications.
+  */
+diff --git a/libknet/libknet.pc.in b/libknet/libknet.pc.in
+index 5962e8ab..4114a609 100644
+--- a/libknet/libknet.pc.in
++++ b/libknet/libknet.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Federico Simoncelli <fsimon@kronosnet.org>
+ #
+diff --git a/libknet/libknet_exported_syms b/libknet/libknet_exported_syms
+index a8a7f284..de770ce9 100644
+--- a/libknet/libknet_exported_syms
++++ b/libknet/libknet_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libknet.so
+ #
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/links.c b/libknet/links.c
+index 8cb1621b..37ecb433 100644
+--- a/libknet/links.c
++++ b/libknet/links.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links.h b/libknet/links.h
+index f19f83ec..a6c3c3e4 100644
+--- a/libknet/links.h
++++ b/libknet/links.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/links_acl.c b/libknet/links_acl.c
+index 66faf244..73381b03 100644
+--- a/libknet/links_acl.c
++++ b/libknet/links_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl.h b/libknet/links_acl.h
+index 3b9fd35e..63f4c0ed 100644
+--- a/libknet/links_acl.h
++++ b/libknet/links_acl.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.c b/libknet/links_acl_ip.c
+index 8d562c58..83e4bbe1 100644
+--- a/libknet/links_acl_ip.c
++++ b/libknet/links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_ip.h b/libknet/links_acl_ip.h
+index 6b208abb..6416a330 100644
+--- a/libknet/links_acl_ip.h
++++ b/libknet/links_acl_ip.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.c b/libknet/links_acl_loopback.c
+index 6bf35c6c..1d26e5d4 100644
+--- a/libknet/links_acl_loopback.c
++++ b/libknet/links_acl_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/links_acl_loopback.h b/libknet/links_acl_loopback.h
+index baebee8c..d22caded 100644
+--- a/libknet/links_acl_loopback.h
++++ b/libknet/links_acl_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/logging.c b/libknet/logging.c
+index 6e2f570b..ed2bbfab 100644
+--- a/libknet/logging.c
++++ b/libknet/logging.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/logging.h b/libknet/logging.h
+index 13b9e48a..c492eada 100644
+--- a/libknet/logging.h
++++ b/libknet/logging.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.c b/libknet/netutils.c
+index 03f01650..ed582da1 100644
+--- a/libknet/netutils.c
++++ b/libknet/netutils.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/netutils.h b/libknet/netutils.h
+index b9e5f4b7..988b1304 100644
+--- a/libknet/netutils.h
++++ b/libknet/netutils.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/onwire.c b/libknet/onwire.c
+index 0e58513f..1e9c0a87 100644
+--- a/libknet/onwire.c
++++ b/libknet/onwire.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/onwire.h b/libknet/onwire.h
+index 87bbcff1..06965c6e 100644
+--- a/libknet/onwire.h
++++ b/libknet/onwire.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/Makefile.am b/libknet/tests/Makefile.am
+index 22821928..5d14c028 100644
+--- a/libknet/tests/Makefile.am
++++ b/libknet/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-check.mk b/libknet/tests/api-check.mk
+index 7ef8b025..b7133888 100644
+--- a/libknet/tests/api-check.mk
++++ b/libknet/tests/api-check.mk
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api-test-coverage b/libknet/tests/api-test-coverage
+index 4d140b98..84288d6f 100755
+--- a/libknet/tests/api-test-coverage
++++ b/libknet/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libknet/tests/api_knet_addrtostr.c b/libknet/tests/api_knet_addrtostr.c
+index 3621bb57..3a0f2bc8 100644
+--- a/libknet/tests/api_knet_addrtostr.c
++++ b/libknet/tests/api_knet_addrtostr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/api_knet_get_compress_list.c b/libknet/tests/api_knet_get_compress_list.c
+index f393967f..4e02218d 100644
+--- a/libknet/tests/api_knet_get_compress_list.c
++++ b/libknet/tests/api_knet_get_compress_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_crypto_list.c b/libknet/tests/api_knet_get_crypto_list.c
+index 3527ac35..c3665fff 100644
+--- a/libknet/tests/api_knet_get_crypto_list.c
++++ b/libknet/tests/api_knet_get_crypto_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_id_by_name.c b/libknet/tests/api_knet_get_transport_id_by_name.c
+index 9adcefa3..10922888 100644
+--- a/libknet/tests/api_knet_get_transport_id_by_name.c
++++ b/libknet/tests/api_knet_get_transport_id_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_list.c b/libknet/tests/api_knet_get_transport_list.c
+index 08c6c761..c7c3f571 100644
+--- a/libknet/tests/api_knet_get_transport_list.c
++++ b/libknet/tests/api_knet_get_transport_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_get_transport_name_by_id.c b/libknet/tests/api_knet_get_transport_name_by_id.c
+index 1957e994..44978c52 100644
+--- a/libknet/tests/api_knet_get_transport_name_by_id.c
++++ b/libknet/tests/api_knet_get_transport_name_by_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_add_datafd.c b/libknet/tests/api_knet_handle_add_datafd.c
+index 9bc4e4d1..eef793fd 100644
+--- a/libknet/tests/api_knet_handle_add_datafd.c
++++ b/libknet/tests/api_knet_handle_add_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -33,7 +33,9 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h[2];
++	knet_handle_t knet_h1;
++	int res;
+ 	int logfds[2];
+ 	int datafd = 0, i;
+ 	int8_t channel = 0;
+@@ -49,162 +51,62 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_add_datafd with no datafd\n");
+-
+-	if ((!knet_handle_add_datafd(knet_h, NULL, &channel)) || (errno != EINVAL)) {
+-		printf("knet_handle_add_datafd accepted invalid datafd or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, NULL, &channel), EINVAL);
+ 
+ 	printf("Test knet_handle_add_datafd with no channel\n");
+-
+-	if ((!knet_handle_add_datafd(knet_h, &datafd, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_add_datafd accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, &datafd, NULL), EINVAL);
+ 
+ 	printf("Test knet_handle_add_datafd with invalid channel\n");
+-
+ 	channel = KNET_DATAFD_MAX;
+ 
+-	if ((!knet_handle_add_datafd(knet_h, &datafd, &channel)) || (errno != EINVAL)) {
+-		printf("knet_handle_add_datafd accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, &datafd, &channel), EINVAL);
+ 
+-	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_handle_add_datafd with no socknotify\n");
+-
+ 	datafd = 0;
+ 	channel = -1;
+-
+-	if ((!knet_handle_add_datafd(knet_h, &datafd, &channel)) || (errno != EINVAL)) {
+-		printf("knet_handle_add_datafd accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, &datafd, &channel), EINVAL);
+ 
+ 	printf("Test knet_handle_add_datafd with automatic config values\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 	printf("got datafd: %d channel: %d\n", datafd, channel);
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_add_datafd with duplicated datafd\n");
+-
+-	if ((!knet_handle_add_datafd(knet_h, &datafd, &channel)) || (errno != EEXIST)) {
+-		printf("knet_handle_add_datafd accepted duplicated datafd or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, &datafd, &channel), EEXIST);
+ 
+ 	printf("Test knet_handle_add_datafd with busy channel\n");
+-
+ 	datafd = datafd + 1;
+-
+-	if ((!knet_handle_add_datafd(knet_h, &datafd, &channel)) || (errno != EBUSY)) {
+-		printf("knet_handle_add_datafd accepted duplicated datafd or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, &datafd, &channel), EBUSY);
+ 
+ 	datafd = datafd - 1;
+ 
+-	if (knet_handle_remove_datafd(knet_h, datafd) < 0) {
+-		printf("knet_handle_remove_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_remove_datafd(knet_h1, datafd));
+ 
+ 	printf("Test knet_handle_add_datafd with no available channels\n");
+-
+ 	for (i = 0; i < KNET_DATAFD_MAX; i++) {
+ 		datafdmax[i] = 0;
+ 		channels[i] = -1;
+-		if (knet_handle_add_datafd(knet_h, &datafdmax[i], &channels[i]) < 0) {
+-			printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-			knet_handle_free(knet_h);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafdmax[i], &channels[i]));
+ 	}
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if ((!knet_handle_add_datafd(knet_h, &datafd, &channel)) || (errno != EBUSY)) {
+-		printf("knet_handle_add_datafd accepted entry with no available channels or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_handle_add_datafd(knet_h1, &datafd, &channel), EBUSY);
+ 
+ 	for (i = 0; i < KNET_DATAFD_MAX; i++) {
+-		if (knet_handle_remove_datafd(knet_h, datafdmax[i]) < 0) {
+-			printf("knet_handle_remove_datafd failed: %s\n", strerror(errno));
+-			knet_handle_free(knet_h);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_remove_datafd(knet_h1, datafdmax[i]));
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_clear_stats.c b/libknet/tests/api_knet_handle_clear_stats.c
+index 6dd10396..37df5d48 100644
+--- a/libknet/tests/api_knet_handle_clear_stats.c
++++ b/libknet/tests/api_knet_handle_clear_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -35,7 +35,7 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -45,6 +45,7 @@ static void test(void)
+ 	ssize_t send_len = 0;
+ 	int recv_len = 0;
+ 	int savederrno;
++	int res;
+ 	struct sockaddr_storage lo;
+ 
+ 	memset(send_buff, 0, sizeof(send_buff));
+@@ -58,153 +59,57 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_send with valid data\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
+ 
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
+ 
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
+ 
+-	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 10, logfds[0], stdout));
+ 
+-	send_len = knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel);
++	send_len = knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (send_len <= 0) {
+ 		printf("knet_send failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (send_len != sizeof(send_buff)) {
+-		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(wait_for_packet(knet_h1, 10, datafd, logfds[0], stdout));
+ 
+-	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+-		printf("Error waiting for packet: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	savederrno = errno;
+ 	if (recv_len != send_len) {
+ 		printf("knet_recv received only %d bytes: %s (errno: %d)\n", recv_len, strerror(errno), errno);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
++
+ 		if ((is_helgrind()) && (recv_len == -1) && (savederrno == EAGAIN)) {
+ 			printf("helgrind exception. this is normal due to possible timeouts\n");
+-			exit(PASS);
++			CLEAN_EXIT(PASS);
+ 		}
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("recv and send buffers are different!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	/* A sanity check on the stats */
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(link_status)) < 0) {
+-		printf("knet_link_get_status failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(link_status)));
+ 
+ 	if (link_status.stats.tx_data_packets != 2 ||
+ 	    link_status.stats.rx_data_packets != 2 ||
+@@ -220,29 +125,10 @@ static void test(void)
+ 	}
+ 
+ 	printf("Test knet_clear_stats (link)\n");
+-	if (knet_handle_clear_stats(knet_h, KNET_CLEARSTATS_HANDLE_AND_LINK) < 0) {
+-		printf("knet_link_clear_stats failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_handle_clear_stats(knet_h1, KNET_CLEARSTATS_HANDLE_AND_LINK));
+ 
+ /* Check they've been cleared */
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(link_status)) < 0) {
+-		printf("knet_link_get_status failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(link_status)));
+ 
+ 	if (link_status.stats.tx_data_packets != 0 ||
+ 	    link_status.stats.rx_data_packets != 0 ||
+@@ -256,23 +142,9 @@ static void test(void)
+ 		       link_status.stats.rx_data_packets,
+ 		       link_status.stats.rx_data_bytes);
+ 
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_compress.c b/libknet/tests/api_knet_handle_compress.c
+index 02c3882d..51c5bdbe 100644
+--- a/libknet/tests/api_knet_handle_compress.c
++++ b/libknet/tests/api_knet_handle_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,65 +21,34 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	struct knet_handle_compress_cfg knet_handle_compress_cfg;
+ 
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
++	setup_logpipes(logfds);
+ 
+ 	printf("Test knet_handle_compress incorrect knet_h\n");
+-
+ 	if ((!knet_handle_compress(NULL, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
+ 		printf("knet_handle_compress accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+-	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_compress with invalid cfg\n");
+-
+-	if ((!knet_handle_compress(knet_h, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_compress accepted invalid cfg or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_compress(knet_h1, NULL), EINVAL);
+ 
+ 	printf("Test knet_handle_compress with un-initialized cfg\n");
+-
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+-
+-	if ((!knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_compress accepted invalid un-initialized cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_compress(knet_h1, &knet_handle_compress_cfg), EINVAL);
+ 
+ 	printf("Test knet_handle_compress with none compress model (disable compress)\n");
+ 
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+ 	strncpy(knet_handle_compress_cfg.compress_model, "none", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+-
+-	if (knet_handle_compress(knet_h, &knet_handle_compress_cfg) != 0) {
+-		printf("knet_handle_compress did not accept none compress mode cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_compress(knet_h1, &knet_handle_compress_cfg));
+ 
+ #if WITH_COMPRESS_BZIP2 > 0
+ 	printf("Test knet_handle_compress with bzip2 (no default) with negative level (-3)\n");
+@@ -87,101 +56,42 @@ static void test(void)
+         strncpy(knet_handle_compress_cfg.compress_model, "bzip2", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+         knet_handle_compress_cfg.compress_level = -3;
+ 
+-        if((!knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
+-                printf("knet_handle_compress accepted invalid (-3) compress level and for bzip2, which is no default defined\n");
+-                knet_handle_free(knet_h);
+-                flush_logs(logfds[0], stdout);
+-                close_logpipes(logfds);
+-                exit(FAIL);
+-        }
+-
+-	flush_logs(logfds[0], stdout);
++        FAIL_ON_SUCCESS(knet_handle_compress(knet_h1, &knet_handle_compress_cfg), EINVAL);
+ #endif
+-
+ 	printf("Test knet_handle_compress with zlib compress and not effective compression level (0)\n");
+-
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+ 	strncpy(knet_handle_compress_cfg.compress_model, "zlib", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+ 	knet_handle_compress_cfg.compress_level = 0;
+-
+-	if((knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno == EINVAL)) {
+-		printf("knet_handle_compress failed to compress with default compression level\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_compress(knet_h1, &knet_handle_compress_cfg));
+ 
+ 	printf("Test knet_handle_compress with zlib compress and negative level (-2)\n");
+-
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+ 	strncpy(knet_handle_compress_cfg.compress_model, "zlib", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+ 	knet_handle_compress_cfg.compress_level = -2;
+-
+-	if ((!knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_compress accepted invalid (-2) compress level for zlib\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_compress(knet_h1, &knet_handle_compress_cfg), EINVAL);
+ 
+ 	printf("Test knet_handle_compress with zlib compress and excessive compress level\n");
+-
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+ 	strncpy(knet_handle_compress_cfg.compress_model, "zlib", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+ 	knet_handle_compress_cfg.compress_level = 10;
++	FAIL_ON_SUCCESS(knet_handle_compress(knet_h1, &knet_handle_compress_cfg), EINVAL);
+ 
+-	if ((!knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_compress accepted invalid (10) compress level for zlib\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_handle_compress with zlib compress and excessive compress threshold\n");
+-
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+ 	strncpy(knet_handle_compress_cfg.compress_model, "zlib", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+ 	knet_handle_compress_cfg.compress_level = 1;
+ 	knet_handle_compress_cfg.compress_threshold = KNET_MAX_PACKET_SIZE +1;
+-
+-	if ((!knet_handle_compress(knet_h, &knet_handle_compress_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_compress accepted invalid compress threshold\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_compress(knet_h1, &knet_handle_compress_cfg), EINVAL);
+ 
+ 	printf("Test knet_handle_compress with zlib compress model normal compress level and threshold\n");
+-
+ 	memset(&knet_handle_compress_cfg, 0, sizeof(struct knet_handle_compress_cfg));
+ 	strncpy(knet_handle_compress_cfg.compress_model, "zlib", sizeof(knet_handle_compress_cfg.compress_model) - 1);
+ 	knet_handle_compress_cfg.compress_level = 1;
+ 	knet_handle_compress_cfg.compress_threshold = 64;
++	FAIL_ON_ERR(knet_handle_compress(knet_h1, &knet_handle_compress_cfg));
+ 
+-	if (knet_handle_compress(knet_h, &knet_handle_compress_cfg) != 0) {
+-		printf("knet_handle_compress did not accept zlib compress mode with compress level 1 cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_crypto.c b/libknet/tests/api_knet_handle_crypto.c
+index ff02451e..13e66bea 100644
+--- a/libknet/tests/api_knet_handle_crypto.c
++++ b/libknet/tests/api_knet_handle_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -22,12 +22,15 @@
+ 
+ static void test(const char *model, const char *model2)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h[2];
++	knet_handle_t knet_h1;
++	int res;
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 	struct crypto_instance *current = NULL;
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
++	setup_logpipes(logfds);
+ 
+ 	printf("Test knet_handle_crypto incorrect knet_h\n");
+ 
+@@ -36,35 +39,15 @@ static void test(const char *model, const char *model2)
+ 		exit(FAIL);
+ 	}
+ 
+-	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_crypto with invalid cfg\n");
+ 
+-	if ((!knet_handle_crypto(knet_h, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto accepted invalid cfg or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto(knet_h1, NULL), EINVAL)
+ 
+ 	printf("Test knet_handle_crypto with un-initialized cfg\n");
+ 
+-	if ((!knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto accepted invalid un-initialized cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg), EINVAL)
+ 
+ 	printf("Test knet_handle_crypto with none crypto model (disable crypto)\n");
+ 
+@@ -73,15 +56,7 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg) != 0) {
+-		printf("knet_handle_crypto did not accept none crypto mode cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+ 	printf("Test knet_handle_crypto with none crypto cipher and hash (disable crypto)\n");
+ 
+@@ -90,15 +65,7 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg) != 0) {
+-		printf("knet_handle_crypto did not accept none crypto cipher and hash cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+ 	printf("Test knet_handle_crypto with %s/aes128/sha1 and too short key\n", model);
+ 
+@@ -108,15 +75,7 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 10;
+ 
+-	if ((!knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto accepted too short private key\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg), EINVAL)
+ 
+ 	printf("Test knet_handle_crypto with %s/aes128/sha1 and too long key\n", model);
+ 
+@@ -126,15 +85,7 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 10000;
+ 
+-	if ((!knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto accepted too long private key\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg), EINVAL)
+ 
+ 	printf("Test knet_handle_crypto with %s/aes128/sha1 and normal key\n", model);
+ 
+@@ -144,19 +95,11 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+ 	printf("Test knet_handle_crypto reconfig with %s/aes128/sha1 and normal key\n", model2);
+ 
+-	current = knet_h->crypto_instance[1];
++	current = knet_h1->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -164,29 +107,16 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+-	if (current == knet_h->crypto_instance[1]) {
++	if (current == knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto failed to install new correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto reconfig with %s/aes128/sha1 and normal key\n", model);
+ 
+-	current = knet_h->crypto_instance[1];
++	current = knet_h1->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -194,29 +124,16 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+-	if (current == knet_h->crypto_instance[1]) {
++	if (current == knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto failed to install new correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto reconfig with %s/aes129/sha1 and normal key\n", model);
+ 
+-	current = knet_h->crypto_instance[1];
++	current = knet_h1->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -224,26 +141,13 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (!knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto failed to detect incorrect config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg), 0)
+ 
+-	if (current != knet_h->crypto_instance[1]) {
++	if (current != knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto failed to restore correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto with %s/aes128/none and normal key\n", model);
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+@@ -252,15 +156,7 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (!knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto accepted crypto without hashing\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg), 0)
+ 
+ 	printf("Test knet_handle_crypto with %s/aes128/sha1 and key where (key_len %% wrap_key_block_size != 0)\n", model);
+ 
+@@ -273,15 +169,7 @@ static void test(const char *model, const char *model2)
+ 	 */
+ 	knet_handle_crypto_cfg.private_key_len = 2003;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg) < 0) {
+-		printf("knet_handle_crypto doesn't accept private_ley with len 2003: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+ 	printf("Shutdown crypto\n");
+ 
+@@ -291,19 +179,9 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg) < 0) {
+-		printf("Unable to shutdown crypto: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
+ 
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+index e9f048b0..5a7da4ea 100644
+--- a/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
++++ b/libknet/tests/api_knet_handle_crypto_rx_clear_traffic.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -22,7 +22,8 @@
+ 
+ static void test()
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_handle_crypto_rx_clear_traffic incorrect knet_h\n");
+@@ -33,66 +34,25 @@ static void test()
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_crypto_rx_clear_traffic with invalid value\n");
+-
+-	if ((!knet_handle_crypto_rx_clear_traffic(knet_h, 2)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_rx_clear_traffic accepted invalid value (%u) or returned incorrect error: %s\n", 2, strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_rx_clear_traffic(knet_h1, 2), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_rx_clear_traffic with valid value KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC\n");
+-
+-	if ((knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC)) < 0) {
+-		printf("knet_handle_crypto_rx_clear_traffic did not accept valid value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->crypto_only != KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC) {
++	FAIL_ON_ERR(knet_handle_crypto_rx_clear_traffic(knet_h1, KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC));
++	if (knet_h1->crypto_only != KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC) {
+ 		printf("knet_handle_crypto_rx_clear_traffic failed to set correct value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto_rx_clear_traffic with valid value KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC\n");
+-
+-	if ((knet_handle_crypto_rx_clear_traffic(knet_h, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC)) < 0) {
+-		printf("knet_handle_crypto_rx_clear_traffic did not accept valid value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->crypto_only != KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
++	FAIL_ON_ERR(knet_handle_crypto_rx_clear_traffic(knet_h1, KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC));
++	if (knet_h1->crypto_only != KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC) {
+ 		printf("knet_handle_crypto_rx_clear_traffic failed to set correct value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_crypto_set_config.c b/libknet/tests/api_knet_handle_crypto_set_config.c
+index 829d7bf1..cff7c83d 100644
+--- a/libknet/tests/api_knet_handle_crypto_set_config.c
++++ b/libknet/tests/api_knet_handle_crypto_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -22,7 +22,8 @@
+ 
+ static void test(const char *model, const char *model2)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 	struct crypto_instance *current = NULL;
+@@ -37,138 +38,62 @@ static void test(const char *model, const char *model2)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_crypto_set_config with invalid cfg\n");
+-
+-	if ((!knet_handle_crypto_set_config(knet_h, NULL, 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_set_config accepted invalid cfg or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, NULL, 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with invalid config num\n");
+-
+-	if ((!knet_handle_crypto_set_config(knet_h, NULL, KNET_MAX_CRYPTO_INSTANCES + 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_set_config accepted invalid config num (%u) or returned incorrect error: %s\n", KNET_MAX_CRYPTO_INSTANCES + 1, strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, NULL, KNET_MAX_CRYPTO_INSTANCES + 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with un-initialized cfg\n");
+-
+-	if ((!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_set_config accepted invalid un-initialized cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with none crypto model (disable crypto)\n");
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, "none", sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) != 0) {
+-		printf("knet_handle_crypto_set_config did not accept none crypto mode cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+ 	printf("Test knet_handle_crypto_set_config with none crypto cipher and hash (disable crypto)\n");
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) != 0) {
+-		printf("knet_handle_crypto_set_config did not accept none crypto cipher and hash cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+ 	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and too short key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 10;
+ 
+-	if ((!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_set_config accepted too short private key\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and too long key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 10000;
+ 
+-	if ((!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_set_config accepted too long private key\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and normal key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
+-		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+ 	printf("Test knet_handle_crypto_set_config reconfig with %s/aes128/sha1 and normal key\n", model2);
+-
+-	current = knet_h->crypto_instance[1];
++	current = knet_h1->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -176,29 +101,15 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
+-		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+-	if (current == knet_h->crypto_instance[1]) {
++	if (current == knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto_set_config failed to install new correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto_set_config reconfig with %s/aes128/sha1 and normal key\n", model);
+-
+-	current = knet_h->crypto_instance[1];
++	current = knet_h1->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -206,29 +117,15 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
+-		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+-	if (current == knet_h->crypto_instance[1]) {
++	if (current == knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto_set_config failed to install new correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto_set_config reconfig with %s/aes129/sha1 and normal key\n", model);
+-
+-	current = knet_h->crypto_instance[1];
++	current = knet_h1->crypto_instance[1];
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+@@ -236,46 +133,22 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
+-		printf("knet_handle_crypto_set_config failed to detect incorrect config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (current != knet_h->crypto_instance[1]) {
++	FAIL_ON_ERR_ONLY(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
++	if (current != knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto_set_config failed to restore correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_crypto_set_config with %s/aes128/none and normal key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
+-		printf("knet_handle_crypto_set_config accepted crypto without hashing\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and key where (key_len %% wrap_key_block_size != 0)\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+@@ -285,125 +158,52 @@ static void test(const char *model, const char *model2)
+ 	 */
+ 	knet_handle_crypto_cfg.private_key_len = 2003;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) < 0) {
+-		printf("knet_handle_crypto_set_config doesn't accept private_ley with len 2003: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+ 	printf("Test knet_handle_crypto_set_config second with %s/aes128/sha1 and normal key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) < 0) {
+-		printf("knet_handle_crypto_set_config failed to install second config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (!knet_h->crypto_instance[2]) {
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 2));
++	if (!knet_h1->crypto_instance[2]) {
+ 		printf("knet_handle_crypto_set_config failed to install second config but reported success\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_h->crypto_instance[1] == knet_h->crypto_instance[2]) {
++	if (knet_h1->crypto_instance[1] == knet_h1->crypto_instance[2]) {
+ 		printf("knet_handle_crypto_set_config failed to install second config and assigned to first\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Test knet_handle_crypto_set_config second config BUSY test\n");
+-
+-	if (knet_handle_crypto_use_config(knet_h, 2) < 0) {
+-		printf("knet_handle_crypto_use_config failed to enable second config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (!knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) && (errno != EBUSY)) {
+-		printf("knet_handle_crypto_set_config failed to detect second config in use: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_crypto_use_config(knet_h, 0) < 0) {
+-		printf("knet_handle_crypto_use_config failed to enable second config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h1, 2));
++	FAIL_ON_SUCCESS(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 2), EBUSY);
++	FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h1, 0));
+ 
+ 	printf("Shutdown crypto\n");
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, "none", sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "none", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) < 0) {
+-		printf("Unable to shutdown crypto: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+-	if (knet_h->crypto_instance[1]) {
++	if (knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) < 0) {
+-		printf("Unable to shutdown crypto: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 2));
+ 
+-	if (knet_h->crypto_instance[2]) {
++	if (knet_h1->crypto_instance[2]) {
+ 		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_crypto_use_config.c b/libknet/tests/api_knet_handle_crypto_use_config.c
+index 29ed53fc..3fcf4003 100644
+--- a/libknet/tests/api_knet_handle_crypto_use_config.c
++++ b/libknet/tests/api_knet_handle_crypto_use_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -22,7 +22,8 @@
+ 
+ static void test(const char *model, const char *model2)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 
+@@ -36,143 +37,50 @@ static void test(const char *model, const char *model2)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_crypto_use_config with invalid config num\n");
+-
+-	if ((!knet_handle_crypto_use_config(knet_h, KNET_MAX_CRYPTO_INSTANCES + 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_use_config accepted invalid config num (%u) or returned incorrect error: %s\n", KNET_MAX_CRYPTO_INSTANCES + 1, strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_use_config(knet_h1, KNET_MAX_CRYPTO_INSTANCES + 1), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_use_config with un-initialized cfg\n");
+-
+-	if ((!knet_handle_crypto_use_config(knet_h, 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_use_config accepted invalid un-initialized cfg (1): %d\n", errno);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if ((!knet_handle_crypto_use_config(knet_h, 2)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_use_config accepted invalid un-initialized cfg (2)\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_use_config(knet_h1, 1), EINVAL);
++	FAIL_ON_SUCCESS(knet_handle_crypto_use_config(knet_h1, 2), EINVAL);
+ 
+ 	printf("Test knet_handle_crypto_set_config with %s/aes128/sha1 and normal key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+-
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1)) {
+-		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
+ 
+ 	printf("Test knet_handle_crypto_use_config with un-initialized cfg (part 2)\n");
+-
+-	if ((!knet_handle_crypto_use_config(knet_h, 2)) || (errno != EINVAL)) {
+-		printf("knet_handle_crypto_use_config accepted invalid un-initialized cfg (2)\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if ((knet_handle_crypto_use_config(knet_h, 1)) < 0) {
+-		printf("knet_handle_crypto_use_config did not accept valid config (1)\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_crypto_use_config(knet_h1, 2), EINVAL);
++	FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h1, 1));
+ 
+ 	printf("Test knet_handle_crypto_set_config for second config with %s/aes128/sha1 and normal key\n", model);
+-
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+ 	strncpy(knet_handle_crypto_cfg.crypto_model, model, sizeof(knet_handle_crypto_cfg.crypto_model) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_cipher_type, "aes128", sizeof(knet_handle_crypto_cfg.crypto_cipher_type) - 1);
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha1", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+-
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2)) {
+-		printf("knet_handle_crypto_set_config failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 2));
+ 
+ 	printf("Test knet_handle_crypto_use_config with valid data\n");
+-
+-	if ((knet_handle_crypto_use_config(knet_h, 2)) < 0) {
+-		printf("knet_handle_crypto_use_config did not accept valid config (1)\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_h->crypto_in_use_config != 2) {
++	FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h1, 2));
++	if (knet_h1->crypto_in_use_config != 2) {
+ 		printf("knet_handle_crypto_set_config failed to set crypto in-use config to 2\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Shutdown crypto\n");
+ 
+ 	printf("Test knet_handle_crypto_use_config with valid data\n");
+ 
+-	if ((knet_handle_crypto_use_config(knet_h, 0)) < 0) {
+-		printf("knet_handle_crypto_use_config did not accept valid config (1)\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_h->crypto_in_use_config != 0) {
++	FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h1, 0));
++	if (knet_h1->crypto_in_use_config != 0) {
+ 		printf("knet_handle_crypto_set_config failed to set crypto in-use config to 2\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	memset(&knet_handle_crypto_cfg, 0, sizeof(struct knet_handle_crypto_cfg));
+@@ -181,45 +89,18 @@ static void test(const char *model, const char *model2)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "none", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 1) < 0) {
+-		printf("Unable to shutdown crypto: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_h->crypto_instance[1]) {
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 1));
++	if (knet_h1->crypto_instance[1]) {
+ 		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_handle_crypto_set_config(knet_h, &knet_handle_crypto_cfg, 2) < 0) {
+-		printf("Unable to shutdown crypto: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_h->crypto_instance[2]) {
++	FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h1, &knet_handle_crypto_cfg, 2));
++	if (knet_h1->crypto_instance[2]) {
+ 		printf("knet_handle_crypto_set_config failed to wipe first config but reported success\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_enable_access_lists.c b/libknet/tests/api_knet_handle_enable_access_lists.c
+index f5e0e7ac..f226b90d 100644
+--- a/libknet/tests/api_knet_handle_enable_access_lists.c
++++ b/libknet/tests/api_knet_handle_enable_access_lists.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 
+ 	printf("Test knet_handle_enable_access_lists with invalid knet_h\n");
+ 
+@@ -34,62 +35,26 @@ static void test(void)
+ 	setup_logpipes(logfds);
+ 
+ 	printf("Test knet_handle_enable_access_lists with invalid param (2) \n");
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	if ((!knet_handle_enable_access_lists(knet_h, 2)) || (errno != EINVAL)) {
+-		printf("knet_handle_enable_access_lists accepted invalid param for enabled: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
++	FAIL_ON_SUCCESS(knet_handle_enable_access_lists(knet_h1, 2), EINVAL);
+ 
+ 	printf("Test knet_handle_enable_access_lists with valid param (1) \n");
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h1, 1));
+ 
+-	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
+-		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->use_access_lists != 1) {
++	if (knet_h1->use_access_lists != 1) {
+ 		printf("knet_handle_enable_access_lists failed to set correct value");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_access_lists with valid param (0) \n");
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h1, 0));
+ 
+-	if (knet_handle_enable_access_lists(knet_h, 0) < 0) {
+-		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->use_access_lists != 0) {
++	if (knet_h1->use_access_lists != 0) {
+ 		printf("knet_handle_enable_access_lists failed to set correct value");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_enable_filter.c b/libknet/tests/api_knet_handle_enable_filter.c
+index 50689ffc..c481c662 100644
+--- a/libknet/tests/api_knet_handle_enable_filter.c
++++ b/libknet/tests/api_knet_handle_enable_filter.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -36,7 +36,8 @@ static int dhost_filter(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_handle_enable_filter incorrect knet_h\n");
+@@ -48,97 +49,41 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_enable_filter with no private_data\n");
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h1, NULL, dhost_filter));
+ 
+-	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->dst_host_filter_fn_private_data != NULL) {
++	if (knet_h1->dst_host_filter_fn_private_data != NULL) {
+ 		printf("knet_handle_enable_filter failed to unset private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_filter with private_data\n");
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h1, &private_data, NULL));
+ 
+-	if (knet_handle_enable_filter(knet_h, &private_data, NULL) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->dst_host_filter_fn_private_data != &private_data) {
++	if (knet_h1->dst_host_filter_fn_private_data != &private_data) {
+ 		printf("knet_handle_enable_filter failed to set private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_filter with no dhost_filter fn\n");
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h1, NULL, NULL));
+ 
+-	if (knet_handle_enable_filter(knet_h, NULL, NULL) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->dst_host_filter_fn != NULL) {
++	if (knet_h1->dst_host_filter_fn != NULL) {
+ 		printf("knet_handle_enable_filter failed to unset dhost_filter fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_filter with dhost_filter fn\n");
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h1, NULL, dhost_filter));
+ 
+-	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->dst_host_filter_fn != &dhost_filter) {
++	if (knet_h1->dst_host_filter_fn != &dhost_filter) {
+ 		printf("knet_handle_enable_filter failed to set dhost_filter fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_enable_pmtud_notify.c b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+index 1152f740..df8383c4 100644
+--- a/libknet/tests/api_knet_handle_enable_pmtud_notify.c
++++ b/libknet/tests/api_knet_handle_enable_pmtud_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -29,8 +29,9 @@ static void pmtud_notify(void *priv_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 
+ 	printf("Test knet_handle_enable_pmtud_notify incorrect knet_h\n");
+ 
+@@ -41,95 +42,37 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_enable_pmtud_notify with no private_data\n");
+-
+-	if (knet_handle_enable_pmtud_notify(knet_h, NULL, pmtud_notify) < 0) {
+-		printf("knet_handle_enable_pmtud_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->pmtud_notify_fn_private_data != NULL) {
++	FAIL_ON_ERR(knet_handle_enable_pmtud_notify(knet_h1, NULL, pmtud_notify));
++	if (knet_h1->pmtud_notify_fn_private_data != NULL) {
+ 		printf("knet_handle_enable_pmtud_notify failed to unset private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_pmtud_notify with private_data\n");
+-
+-	if (knet_handle_enable_pmtud_notify(knet_h, &private_data, NULL) < 0) {
+-		printf("knet_handle_enable_pmtud_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->pmtud_notify_fn_private_data != &private_data) {
++	FAIL_ON_ERR(knet_handle_enable_pmtud_notify(knet_h1, &private_data, NULL));
++	if (knet_h1->pmtud_notify_fn_private_data != &private_data) {
+ 		printf("knet_handle_enable_pmtud_notify failed to set private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_pmtud_notify with no pmtud_notify fn\n");
+-
+-	if (knet_handle_enable_pmtud_notify(knet_h, NULL, NULL) < 0) {
+-		printf("knet_handle_enable_pmtud_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->pmtud_notify_fn != NULL) {
++	FAIL_ON_ERR(knet_handle_enable_pmtud_notify(knet_h1, NULL, NULL));
++	if (knet_h1->pmtud_notify_fn != NULL) {
+ 		printf("knet_handle_enable_pmtud_notify failed to unset pmtud_notify fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_pmtud_notify with pmtud_notify fn\n");
++	FAIL_ON_ERR(knet_handle_enable_pmtud_notify(knet_h1, NULL, pmtud_notify));
+ 
+-	if (knet_handle_enable_pmtud_notify(knet_h, NULL, pmtud_notify) < 0) {
+-		printf("knet_handle_enable_pmtud_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->pmtud_notify_fn != &pmtud_notify) {
++	if (knet_h1->pmtud_notify_fn != &pmtud_notify) {
+ 		printf("knet_handle_enable_pmtud_notify failed to set pmtud_notify fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_enable_sock_notify.c b/libknet/tests/api_knet_handle_enable_sock_notify.c
+index d2b73a9c..c06f1d2d 100644
+--- a/libknet/tests/api_knet_handle_enable_sock_notify.c
++++ b/libknet/tests/api_knet_handle_enable_sock_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -33,7 +33,8 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_handle_enable_sock_notify incorrect knet_h\n");
+@@ -45,86 +46,35 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_enable_sock_notify with no private_data\n");
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, NULL, sock_notify));
+ 
+-	if (knet_handle_enable_sock_notify(knet_h, NULL, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->sock_notify_fn_private_data != NULL) {
++	if (knet_h1->sock_notify_fn_private_data != NULL) {
+ 		printf("knet_handle_enable_sock_notify failed to unset private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_sock_notify with private_data\n");
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->sock_notify_fn_private_data != &private_data) {
++	if (knet_h1->sock_notify_fn_private_data != &private_data) {
+ 		printf("knet_handle_enable_sock_notify failed to set private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_enable_sock_notify with no sock_notify fn\n");
+-
+-	if ((!knet_handle_enable_sock_notify(knet_h, NULL, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_enable_sock_notify accepted invalid sock_notify or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_enable_sock_notify(knet_h1, NULL, NULL), EINVAL);
+ 
+ 	printf("Test knet_handle_enable_sock_notify with sock_notify fn\n");
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, NULL, sock_notify));
+ 
+-	if (knet_handle_enable_sock_notify(knet_h, NULL, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++	if (knet_h1->sock_notify_fn != &sock_notify) {
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_h->sock_notify_fn != &sock_notify) {
+-		printf("knet_handle_enable_sock_notify failed to set sock_notify fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_free.c b/libknet/tests/api_knet_handle_free.c
+index 5e1d2053..359181f8 100644
+--- a/libknet/tests/api_knet_handle_free.c
++++ b/libknet/tests/api_knet_handle_free.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -19,67 +19,38 @@
+ 
+ #include "test-common.h"
+ 
++#define TESTNODES 1
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 
+ 	setup_logpipes(logfds);
+ 
+ 	printf("Test knet_handle_free with invalid knet_h (part 1)\n");
+-
+ 	if ((!knet_handle_free(NULL)) || (errno != EINVAL)) {
+ 		printf("knet_handle_free failed to detect invalid parameter\n");
+ 		exit(FAIL);
+ 	}
+ 
+-	printf("Test knet_handle_free with one host configured\n");
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add new knet_host: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	printf("Test knet_handle_free with one host configured\n");
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+-	if ((!knet_handle_free(knet_h)) || (errno != EBUSY)) {
+-		printf("knet_handle_free didn't return error or correct errno with one host configured: %s\n", strerror(errno));
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++	if ((!knet_handle_free(knet_h1)) || (errno != EBUSY)) {
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_host_remove(knet_h, 1) < 0) {
+-		printf("Unable to remove knet_host: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_remove(knet_h1, 1));
+ 
+ 	printf("Test knet_handle_free with invalid knet_h (part 2)\n");
++	FAIL_ON_SUCCESS(knet_handle_free(knet_h1 + 1), EINVAL);
+ 
+-	if ((!knet_handle_free(knet_h + 1)) || (errno != EINVAL)) {
+-		printf("knet_handle_free failed to detect invalid parameter\n");
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_free(knet_h) < 0) {
+-		printf("knet_handle_free failed: %s\n", strerror(errno));
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_free(knet_h1));
+ 
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_get_channel.c b/libknet/tests/api_knet_handle_get_channel.c
+index 5d4ef8dc..d2b48f42 100644
+--- a/libknet/tests/api_knet_handle_get_channel.c
++++ b/libknet/tests/api_knet_handle_get_channel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -33,13 +33,13 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0, old_channel = 0;
+ 
+ 	printf("Test knet_handle_get_channel incorrect knet_h\n");
+-
+ 	if ((!knet_handle_get_channel(NULL, datafd, &channel)) || (errno != EINVAL)) {
+ 		printf("knet_handle_get_channel accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+@@ -47,92 +47,33 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_get_channel with invalid datafd\n");
+-
+ 	datafd = 0;
+-
+-	if ((!knet_handle_get_channel(knet_h, datafd, &channel)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_channel accepted invalid datafd or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_channel(knet_h1, datafd, &channel), EINVAL);
+ 
+ 	printf("Test knet_handle_get_channel with invalid channel\n");
+-
+ 	datafd = 10;
+-
+-	if ((!knet_handle_get_channel(knet_h, datafd, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_channel accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_channel(knet_h1, datafd, NULL), EINVAL);
+ 
+ 	printf("Test knet_handle_get_channel with unconfigured datafd/channel\n");
+-
+ 	datafd = 10;
+-
+-	if ((!knet_handle_get_channel(knet_h, datafd, &channel)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_channel accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_channel(knet_h1, datafd, &channel), EINVAL);
+ 
+ 	printf("Test knet_handle_get_channel with valid datafd\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	old_channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &old_channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_get_channel(knet_h, datafd, &channel) < 0) {
+-		printf("knet_handle_get_channel failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &old_channel));
+ 
++	FAIL_ON_ERR(knet_handle_get_channel(knet_h1, datafd, &channel));
+ 	if (old_channel != channel) {
+-		printf("knet_handle_get_channel got incorrect channel\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_get_datafd.c b/libknet/tests/api_knet_handle_get_datafd.c
+index ea68af0b..0fa6f811 100644
+--- a/libknet/tests/api_knet_handle_get_datafd.c
++++ b/libknet/tests/api_knet_handle_get_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -33,10 +33,11 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0, old_datafd;
+ 	int8_t channel = 0;
++	int res;
+ 
+ 	printf("Test knet_handle_get_datafd incorrect knet_h\n");
+ 
+@@ -47,92 +48,34 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_get_datafd with invalid channel (< 0)\n");
+-
+ 	channel = 0;
+-
+-	if ((!knet_handle_get_datafd(knet_h, channel, &datafd)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_datafd accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_datafd(knet_h1, channel, &datafd), EINVAL);
+ 
+ 	printf("Test knet_handle_get_datafd with invalid channel (KNET_DATAFD_MAX)\n");
+-
+ 	channel = KNET_DATAFD_MAX;
+-
+-	if ((!knet_handle_get_datafd(knet_h, channel, &datafd)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_datafd accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_datafd(knet_h1, channel, &datafd), EINVAL);
+ 
+ 	printf("Test knet_handle_get_datafd with unconfigured datafd/channel\n");
+-
+ 	channel = 10;
+-
+-	if ((!knet_handle_get_datafd(knet_h, channel, &datafd)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_datafd accepted unconfigured channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_datafd(knet_h1, channel, &datafd), EINVAL);
+ 
+ 	printf("Test knet_handle_get_datafd with valid datafd\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	old_datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &old_datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &old_datafd, &channel));
+ 
+-	if (knet_handle_get_datafd(knet_h, channel, &datafd) < 0) {
+-		printf("knet_handle_get_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_get_datafd(knet_h1, channel, &datafd));
+ 
+ 	if (old_datafd != datafd) {
+-		printf("knet_handle_get_datafd got incorrect channel\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_get_stats.c b/libknet/tests/api_knet_handle_get_stats.c
+index 010d8db0..6d3dd36f 100644
+--- a/libknet/tests/api_knet_handle_get_stats.c
++++ b/libknet/tests/api_knet_handle_get_stats.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,11 +23,12 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	struct knet_handle_stats test_byte_array[2];
+ 	struct knet_handle_stats ref_byte_array[2];
+ 	struct knet_handle_stats stats;
++	int res;
+ 
+ 	printf("Test knet_handle_get_stats incorrect knet_h\n");
+ 
+@@ -40,57 +41,25 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_get_stats with NULL structure pointer\n");
+-
+-	if ((!knet_handle_get_stats(knet_h, NULL, 0) || (errno != EINVAL))) {
+-		printf("knet_handle_get_stats accepted invalid stats address or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_stats(knet_h1, NULL, 0), EINVAL);
+ 
+ 	printf("Test knet_handle_get_stats with small structure size\n");
+-
+ 	memset(test_byte_array, 0x55, sizeof(struct knet_handle_stats) * 2);
+ 	memset(ref_byte_array, 0x55, sizeof(struct knet_handle_stats) * 2);
+-	if (knet_handle_get_stats(knet_h, (struct knet_handle_stats *)test_byte_array, sizeof(size_t)) < 0) {
+-		printf("knet_handle_get_stats failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_get_stats(knet_h1, (struct knet_handle_stats *)test_byte_array, sizeof(size_t)));
+ 
+ 	if (memcmp(&test_byte_array[1], ref_byte_array, sizeof(struct knet_handle_stats))) {
+ 		printf("knet_handle_get_stats corrupted memory after stats structure\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_get_stats with valid input\n");
++	FAIL_ON_ERR(knet_handle_get_stats(knet_h1, &stats, sizeof(struct knet_handle_stats)));
+ 
+-	if (knet_handle_get_stats(knet_h, &stats, sizeof(struct knet_handle_stats)) < 0) {
+-		printf("knet_handle_get_stats failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+index 1912cc57..d4154345 100644
+--- a/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_get_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	uint32_t msecs = 0;
+ 
+ 	printf("Test knet_handle_get_transport_reconnect_interval with incorrect knet_h\n");
+@@ -34,43 +35,19 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_get_transport_reconnect_interval with incorrect msecs\n");
+-
+-	if ((!knet_handle_get_transport_reconnect_interval(knet_h, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_get_transport_reconnect_interval accepted invalid msecs or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_get_transport_reconnect_interval(knet_h1, NULL), EINVAL);
+ 
+ 	printf("Test knet_handle_get_transport_reconnect_interval with correct values\n");
+-
+-	if (knet_handle_get_transport_reconnect_interval(knet_h, &msecs) < 0) {
+-		printf("knet_handle_get_transport_reconnect_interval failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_get_transport_reconnect_interval(knet_h1, &msecs));
+ 
+ 	if (msecs != KNET_TRANSPORT_DEFAULT_RECONNECT_INTERVAL) {
+ 		printf("knet_handle_get_transport_reconnect_interval failed to set correct value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_new.c b/libknet/tests/api_knet_handle_new.c
+index c22450eb..6a74d4c5 100644
+--- a/libknet/tests/api_knet_handle_new.c
++++ b/libknet/tests/api_knet_handle_new.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,27 +23,27 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	struct rlimit cur;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_handle_new hostid 1, no logging\n");
+ 
+-	knet_h = knet_handle_new_ex(1, 0, 0, 0);
+-	if (!knet_h) {
++	knet_h1 = knet_handle_new_ex(1, 0, 0, 0);
++	if (!knet_h1) {
+ 		printf("Unable to init knet_handle! err: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_handle_free(knet_h) != 0) {
++	if (knet_handle_free(knet_h1) != 0) {
+ 		printf("Unable to free knet_handle\n");
+ 		exit(FAIL);
+ 	}
+ 
+ 	printf("Test knet_handle_new hostid -1, no logging\n");
+ 
+-	knet_h = knet_handle_new_ex(-1, 0, 0, 0);
+-	if (!knet_h) {
++	knet_h1 = knet_handle_new_ex(-1, 0, 0, 0);
++	if (!knet_h1) {
+ 		printf("Unable to init knet_handle! err: %s\n", strerror(errno));
+ 		exit(FAIL);
+ 	}
+@@ -52,13 +52,13 @@ static void test(void)
+ 	 * -1 == knet_node_id_t 65535
+ 	 */
+ 
+-	if (knet_h->host_id != 65535) {
++	if (knet_h1->host_id != 65535) {
+ 		printf("host_id size might have changed!\n");
+-		knet_handle_free(knet_h);
++		knet_handle_free(knet_h1);
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_handle_free(knet_h) != 0) {
++	if (knet_handle_free(knet_h1) != 0) {
+ 		printf("Unable to free knet_handle\n");
+ 		exit(FAIL);
+ 	}
+@@ -73,16 +73,16 @@ static void test(void)
+ 	 */
+ 	printf("Test knet_handle_new hostid 1, incorrect log_fd (-1)\n");
+ 
+-	knet_h = knet_handle_new(1, -1, 0);
++	knet_h1 = knet_handle_new(1, -1, 0);
+ 
+-	if ((!knet_h) && (errno != EINVAL)) {
++	if ((!knet_h1) && (errno != EINVAL)) {
+ 		printf("knet_handle_new returned incorrect errno on incorrect log_fd\n");
+ 		exit(FAIL);
+ 	}
+ 
+-	if (knet_h) {
++	if (knet_h1) {
+ 		printf("knet_handle_new accepted an incorrect (-1) log_fd\n");
+-		knet_handle_free(knet_h);
++		knet_handle_free(knet_h1);
+ 		exit(FAIL);
+ 	}
+ 
+@@ -91,11 +91,11 @@ static void test(void)
+ 	 */
+ 	printf("Test knet_handle_new hostid 1, incorrect log_fd (max_fd + 1)\n");
+ 
+-	knet_h = knet_handle_new(1, (int) cur.rlim_max, 0);
++	knet_h1 = knet_handle_new(1, (int) cur.rlim_max, 0);
+ 
+-	if ((knet_h) || (errno != EINVAL)) {
++	if ((knet_h1) || (errno != EINVAL)) {
+ 		printf("knet_handle_new accepted an incorrect (max_fd + 1) log_fd or returned incorrect errno on incorrect log_fd: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
++		knet_handle_free(knet_h1);
+ 		exit(FAIL);
+ 	}
+ 
+@@ -103,23 +103,17 @@ static void test(void)
+ 
+ 	printf("Test knet_handle_new hostid 1, proper log_fd, invalid log level (DEBUG + 1)\n");
+ 
+-	knet_h = knet_handle_new(1, logfds[1], KNET_LOG_DEBUG + 1);
+-
+-	if ((knet_h) || (errno != EINVAL)) {
++	knet_h1 = knet_handle_new(1, logfds[1], KNET_LOG_DEBUG + 1);
++	if ((knet_h1) || (errno != EINVAL)) {
+ 		printf("knet_handle_new accepted an incorrect log level or returned incorrect errno on incorrect log level: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		knet_h[1] = knet_h1;
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Test knet_handle_new hostid 1, proper log_fd, proper log level (DEBUG)\n");
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_new_limit.c b/libknet/tests/api_knet_handle_new_limit.c
+index 7b674131..0412f0bc 100644
+--- a/libknet/tests/api_knet_handle_new_limit.c
++++ b/libknet/tests/api_knet_handle_new_limit.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_handle_pmtud_get.c b/libknet/tests/api_knet_handle_pmtud_get.c
+index 376befa2..57adb5ac 100644
+--- a/libknet/tests/api_knet_handle_pmtud_get.c
++++ b/libknet/tests/api_knet_handle_pmtud_get.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	unsigned int data_mtu;
+ 
+ 	printf("Test knet_handle_pmtud_get incorrect knet_h\n");
+@@ -34,40 +35,20 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_handle_pmtud_get with no data_mtu\n");
+-	if ((!knet_handle_pmtud_get(knet_h, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_pmtud_get accepted invalid data_mtu or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_handle_pmtud_get(knet_h1, NULL), EINVAL);
+ 
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_pmtud_get(knet_h1, &data_mtu));
+ 
+-	if (knet_handle_pmtud_get(knet_h, &data_mtu) < 0) {
+-		printf("knet_handle_pmtud_get failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->data_mtu != data_mtu) {
++	if (knet_h1->data_mtu != data_mtu) {
+ 		printf("knet_handle_pmtud_get failed to set the value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_pmtud_getfreq.c b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+index 271051c2..400d984a 100644
+--- a/libknet/tests/api_knet_handle_pmtud_getfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_getfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	unsigned int interval;
+ 
+ 	printf("Test knet_handle_pmtud_getfreq incorrect knet_h\n");
+@@ -34,40 +35,21 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_handle_pmtud_getfreq with no interval\n");
+-	if ((!knet_handle_pmtud_getfreq(knet_h, NULL)) || (errno != EINVAL)) {
+-		printf("knet_handle_pmtud_getfreq accepted invalid interval or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_pmtud_getfreq(knet_h1, NULL), EINVAL);
+ 
+-	if (knet_handle_pmtud_getfreq(knet_h, &interval) < 0) {
+-		printf("knet_handle_pmtud_getfreq failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_pmtud_getfreq(knet_h1, &interval));
+ 
+-	if (knet_h->pmtud_interval != interval) {
++	if (knet_h1->pmtud_interval != interval) {
+ 		printf("knet_handle_pmtud_getfreq failed to set the value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_pmtud_set.c b/libknet/tests/api_knet_handle_pmtud_set.c
+index 0d808a33..4898986e 100644
+--- a/libknet/tests/api_knet_handle_pmtud_set.c
++++ b/libknet/tests/api_knet_handle_pmtud_set.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -33,7 +33,8 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	unsigned int iface_mtu = 0, data_mtu;
+ 	int datafd = 0;
+@@ -49,98 +50,32 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	iface_mtu = KNET_PMTUD_SIZE_V4 + 1;
+-	printf("Test knet_handle_pmtud_set with wrong iface_mtu\n");
+-	if ((!knet_handle_pmtud_set(knet_h, iface_mtu)) || (errno != EINVAL)) {
+-		printf("knet_handle_pmtud_set accepted invalid data_mtu or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+ 
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	printf("Test knet_handle_pmtud_set with wrong iface_mtu\n");
++	FAIL_ON_SUCCESS(knet_handle_pmtud_set(knet_h1, iface_mtu), EINVAL);
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
+ 
+-	if (knet_link_set_pong_count(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_pong_count failed: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_pong_count(knet_h1, 1, 0, 1));
+ 
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
+ 
+-	if (wait_for_host(knet_h, 1, 4, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 4, logfds[0], stdout));
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_handle_pmtud_get(knet_h, &data_mtu) < 0) {
+-		printf("knet_handle_pmtud_get failed error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_pmtud_get(knet_h1, &data_mtu));
+ 
+ 	/*
+ 	 * 28 = IP (20) + UDP (8)
+@@ -148,69 +83,33 @@ static void test(void)
+ 	iface_mtu = data_mtu + 28 + KNET_HEADER_ALL_SIZE - 64;
+ 	printf("Test knet_handle_pmtud_set with iface_mtu %u\n", iface_mtu);
+ 
+-	if (knet_handle_pmtud_set(knet_h, iface_mtu) < 0) {
+-		printf("knet_handle_pmtud_set failed error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_pmtud_set(knet_h1, iface_mtu));
+ 
+ 	/*
+ 	 * wait for PMTUd to pick up the change
+ 	 */
+-	test_sleep(knet_h, 1);
++	test_sleep(knet_h1, 1);
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (knet_h->data_mtu != data_mtu - 64) {
++	if (knet_h1->data_mtu != data_mtu - 64) {
+ 		printf("knet_handle_pmtud_set failed to set the value\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Test knet_handle_pmtud_set with iface_mtu 0\n");
+-	if (knet_handle_pmtud_set(knet_h, 0) < 0) {
+-		printf("knet_handle_pmtud_set failed error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_pmtud_set(knet_h1, 0));
+ 
+ 	/*
+ 	 * wait for PMTUd to pick up the change
+ 	 */
+-	test_sleep(knet_h, 1);
++	test_sleep(knet_h1, 1);
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (knet_h->data_mtu != data_mtu) {
+-		printf("knet_handle_pmtud_set failed to redetect MTU: detected mtu: %u data_mtu: %u \n", knet_h->data_mtu, data_mtu);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++	if (knet_h1->data_mtu != data_mtu) {
++		printf("knet_handle_pmtud_set failed to redetect MTU: detected mtu: %u data_mtu: %u \n", knet_h1->data_mtu, data_mtu);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_pmtud_setfreq.c b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+index c0fe2e78..9b9f997c 100644
+--- a/libknet/tests/api_knet_handle_pmtud_setfreq.c
++++ b/libknet/tests/api_knet_handle_pmtud_setfreq.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,7 +21,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_handle_pmtud_setfreq incorrect knet_h\n");
+@@ -33,52 +34,24 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_handle_pmtud_setfreq with 0 (incorrect)\n");
+-	if ((!knet_handle_pmtud_setfreq(NULL, 0)) || (errno != EINVAL)) {
+-		printf("knet_handle_pmtud_setfreq accepted invalid PTMUd freq or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_pmtud_setfreq(NULL, 0), EINVAL);
+ 
+ 	printf("Test knet_handle_pmtud_setfreq with 86401 (incorrect)\n");
+-	if ((!knet_handle_pmtud_setfreq(NULL, 86401)) || (errno != EINVAL)) {
+-		printf("knet_handle_pmtud_setfreq accepted invalid PTMUd freq or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_pmtud_setfreq(NULL, 86401), EINVAL);
+ 
+ 	printf("Test knet_handle_pmtud_setfreq with 1 (correct)\n");
+-	if (knet_handle_pmtud_setfreq(knet_h, 1) < 0) {
+-		printf("knet_handle_pmtud_setfreq failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_pmtud_setfreq(knet_h1, 1));
+ 
+-	if (knet_h->pmtud_interval != 1) {
++	if (knet_h1->pmtud_interval != 1) {
+ 		printf("knet_handle_pmtud_setfreq failed to set the value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_remove_datafd.c b/libknet/tests/api_knet_handle_remove_datafd.c
+index 0682c5d8..091bdba2 100644
+--- a/libknet/tests/api_knet_handle_remove_datafd.c
++++ b/libknet/tests/api_knet_handle_remove_datafd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -33,7 +33,8 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -47,70 +48,25 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_remove_datafd with no datafd\n");
+-
+ 	datafd = 0;
+-
+-	if ((!knet_handle_remove_datafd(knet_h, datafd)) || (errno != EINVAL)) {
+-		printf("knet_handle_remove_datafd accepted invalid datafd or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_remove_datafd(knet_h1, datafd), EINVAL);
+ 
+ 	printf("Test knet_handle_remove_datafd with invalid datafd\n");
+-
+ 	datafd = 10;
+-
+-	if ((!knet_handle_remove_datafd(knet_h, datafd)) || (errno != EINVAL)) {
+-		printf("knet_handle_remove_datafd accepted invalid channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_remove_datafd(knet_h1, datafd), EINVAL);
+ 
+ 	printf("Test knet_handle_remove_datafd with valid datafd\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
+-
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 	datafd = 0;
+ 	channel = -1;
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_remove_datafd(knet_h, datafd) < 0) {
+-		printf("knet_handle_remove_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_remove_datafd(knet_h1, datafd));
+ 
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+index f8265e1f..dd03974a 100644
+--- a/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
++++ b/libknet/tests/api_knet_handle_set_transport_reconnect_interval.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,7 +21,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_handle_set_transport_reconnect_interval with incorrect knet_h\n");
+@@ -33,43 +34,20 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_handle_set_transport_reconnect_interval with incorrect msecs\n");
+-
+-	if ((!knet_handle_set_transport_reconnect_interval(knet_h, 0)) || (errno != EINVAL)) {
+-		printf("knet_handle_set_transport_reconnect_interval accepted invalid msecs or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_handle_set_transport_reconnect_interval(knet_h1, 0), EINVAL);
+ 
+ 	printf("Test knet_handle_set_transport_reconnect_interval with correct values\n");
++	FAIL_ON_ERR(knet_handle_set_transport_reconnect_interval(knet_h1, 2000));
+ 
+-	if (knet_handle_set_transport_reconnect_interval(knet_h, 2000) < 0) {
+-		printf("knet_handle_set_transport_reconnect_interval failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_h->reconnect_int != 2000) {
++	if (knet_h1->reconnect_int != 2000) {
+ 		printf("knet_handle_set_transport_reconnect_interval failed to set correct value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_handle_setfwd.c b/libknet/tests/api_knet_handle_setfwd.c
+index 3d2b9d50..d29039d4 100644
+--- a/libknet/tests/api_knet_handle_setfwd.c
++++ b/libknet/tests/api_knet_handle_setfwd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 
+ 	printf("Test knet_handle_setfwd with invalid knet_h\n");
+ 
+@@ -34,62 +35,26 @@ static void test(void)
+ 	setup_logpipes(logfds);
+ 
+ 	printf("Test knet_handle_setfwd with invalid param (2) \n");
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
+-
+-	if ((!knet_handle_setfwd(knet_h, 2)) || (errno != EINVAL)) {
+-		printf("knet_handle_setfwd accepted invalid param for enabled: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
++	FAIL_ON_SUCCESS(knet_handle_setfwd(knet_h1, 2), EINVAL);
+ 
+ 	printf("Test knet_handle_setfwd with valid param (1) \n");
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
+ 
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->enabled != 1) {
++	if (knet_h1->enabled != 1) {
+ 		printf("knet_handle_setfwd failed to set correct value");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_handle_setfwd with valid param (0) \n");
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
+ 
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->enabled != 0) {
++	if (knet_h1->enabled != 0) {
+ 		printf("knet_handle_setfwd failed to set correct value");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_add.c b/libknet/tests/api_knet_host_add.c
+index e6130e24..c1af2e23 100644
+--- a/libknet/tests/api_knet_host_add.c
++++ b/libknet/tests/api_knet_host_add.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -20,8 +20,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	size_t host_ids_entries;
+ 
+@@ -34,67 +35,28 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_add with hostid 1\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+ 	printf("Test verify host_id 1 is in the host list\n");
+-
+-	if (knet_host_get_host_list(knet_h, host_ids, &host_ids_entries) < 0) {
+-		printf("Unable to get host list: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_host_get_host_list(knet_h1, host_ids, &host_ids_entries));
+ 	if (host_ids_entries != 1) {
+ 		printf("Too many hosts?\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+ 	if (host_ids[0] != 1) {
+ 		printf("Unable to find host id 1 in host list\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_add adding host 1 again\n");
++	FAIL_ON_SUCCESS(knet_host_add(knet_h1, 1), EEXIST);
+ 
+-	if ((!knet_host_add(knet_h, 1)) || (errno != EEXIST)) {
+-		printf("knet_host_add accepted duplicated host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_enable_status_change_notify.c b/libknet/tests/api_knet_host_enable_status_change_notify.c
+index fb694f7a..c3dbb3cd 100644
+--- a/libknet/tests/api_knet_host_enable_status_change_notify.c
++++ b/libknet/tests/api_knet_host_enable_status_change_notify.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -32,7 +32,8 @@ static void host_notify(void *priv_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_host_enable_status_change_notify incorrect knet_h\n");
+@@ -44,95 +45,36 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_host_enable_status_change_notify with no private_data\n");
+-
+-	if (knet_host_enable_status_change_notify(knet_h, NULL, host_notify) < 0) {
+-		printf("knet_host_enable_status_change_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_status_change_notify_fn_private_data != NULL) {
++	FAIL_ON_ERR(knet_host_enable_status_change_notify(knet_h1, NULL, host_notify));
++	if (knet_h1->host_status_change_notify_fn_private_data != NULL) {
+ 		printf("knet_host_enable_status_change_notify failed to unset private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_enable_status_change_notify with private_data\n");
+-
+-	if (knet_host_enable_status_change_notify(knet_h, &private_data, NULL) < 0) {
+-		printf("knet_host_enable_status_change_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_status_change_notify_fn_private_data != &private_data) {
++	FAIL_ON_ERR(knet_host_enable_status_change_notify(knet_h1, &private_data, NULL));
++	if (knet_h1->host_status_change_notify_fn_private_data != &private_data) {
+ 		printf("knet_host_enable_status_change_notify failed to set private_data");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_enable_status_change_notify with no host_notify fn\n");
+-
+-	if (knet_host_enable_status_change_notify(knet_h, NULL, NULL) < 0) {
+-		printf("knet_host_enable_status_change_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_status_change_notify_fn != NULL) {
++	FAIL_ON_ERR(knet_host_enable_status_change_notify(knet_h1, NULL, NULL));
++	if (knet_h1->host_status_change_notify_fn != NULL) {
+ 		printf("knet_host_enable_status_change_notify failed to unset host_notify fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_enable_status_change_notify with host_notify fn\n");
+-
+-	if (knet_host_enable_status_change_notify(knet_h, NULL, host_notify) < 0) {
+-		printf("knet_host_enable_status_change_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_status_change_notify_fn != &host_notify) {
++	FAIL_ON_ERR(knet_host_enable_status_change_notify(knet_h1, NULL, host_notify));
++	if (knet_h1->host_status_change_notify_fn != &host_notify) {
+ 		printf("knet_host_enable_status_change_notify failed to set host_notify fn");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_get_host_list.c b/libknet/tests/api_knet_host_get_host_list.c
+index a9c821fb..f80587fb 100644
+--- a/libknet/tests/api_knet_host_get_host_list.c
++++ b/libknet/tests/api_knet_host_get_host_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -20,7 +20,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	size_t host_ids_entries;
+@@ -34,101 +35,37 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_get_host_list incorrect host_ids\n");
+-
+-	if ((!knet_host_get_host_list(knet_h, NULL, &host_ids_entries)) || (errno != EINVAL)) {
+-		printf("knet_host_get_host_list accepted invalid host_ids or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_host_list(knet_h1, NULL, &host_ids_entries), EINVAL);
+ 
+ 	printf("Test knet_host_get_host_list incorrect host_ids_entries\n");
+-
+-	if ((!knet_host_get_host_list(knet_h, host_ids, NULL)) || (errno != EINVAL)) {
+-		printf("knet_host_get_host_list accepted invalid host_ids or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_host_list(knet_h1, host_ids, NULL), EINVAL);
+ 
+ 	printf("Test knet_host_get_host_list with one host\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_get_host_list(knet_h, host_ids, &host_ids_entries) < 0) {
+-		printf("Unable to get host list: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(knet_host_get_host_list(knet_h1, host_ids, &host_ids_entries));
+ 	if (host_ids_entries != 1) {
+ 		printf("Too many hosts?\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+ 	if (host_ids[0] != 1) {
+ 		printf("Unable to find host id 1 in host list\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_get_host_list with zero hosts\n");
+-
+-	if (knet_host_remove(knet_h, 1) < 0) {
+-		printf("knet_host_remove failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_get_host_list(knet_h, host_ids, &host_ids_entries) < 0) {
+-		printf("Unable to get host list: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_remove(knet_h1, 1));
++	FAIL_ON_ERR(knet_host_get_host_list(knet_h1, host_ids, &host_ids_entries));
+ 
+ 	if (host_ids_entries != 0) {
+ 		printf("Too many hosts?\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_get_id_by_host_name.c b/libknet/tests/api_knet_host_get_id_by_host_name.c
+index 356a9ac0..9896a610 100644
+--- a/libknet/tests/api_knet_host_get_id_by_host_name.c
++++ b/libknet/tests/api_knet_host_get_id_by_host_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,7 +21,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	knet_node_id_t host_id;
+ 
+@@ -34,73 +35,24 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_get_id_by_host_name with incorrect name 1\n");
+-
+-	if ((!knet_host_get_id_by_host_name(knet_h, NULL, &host_id)) || (errno != EINVAL)) {
+-		printf("knet_host_get_id_by_host_name accepted invalid name or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_id_by_host_name(knet_h1, NULL, &host_id), EINVAL);
+ 
+ 	printf("Test knet_host_get_id_by_host_name with incorrect host_id\n");
+-
+-	if ((!knet_host_get_id_by_host_name(knet_h, "1", NULL)) || (errno != EINVAL)) {
+-		printf("knet_host_get_id_by_host_name accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_id_by_host_name(knet_h1, "1", NULL), EINVAL);
+ 
+ 	printf("Test knet_host_get_id_by_host_name with incorrect values for name\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_host_get_id_by_host_name(knet_h, "test", &host_id)) || (errno != ENOENT)) {
+-		printf("knet_host_get_id_by_host_name returned invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_host_get_id_by_host_name(knet_h1, "test", &host_id), ENOENT);
+ 
+ 	printf("Test knet_host_get_id_by_host_name with correct values\n");
++	FAIL_ON_ERR(knet_host_get_id_by_host_name(knet_h1, "1", &host_id));
+ 
+-	if (knet_host_get_id_by_host_name(knet_h, "1", &host_id) < 0) {
+-		printf("knet_host_get_id_by_host_name could not get id for known name: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_get_name_by_host_id.c b/libknet/tests/api_knet_host_get_name_by_host_id.c
+index a4d7a069..155a67b8 100644
+--- a/libknet/tests/api_knet_host_get_name_by_host_id.c
++++ b/libknet/tests/api_knet_host_get_name_by_host_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,7 +21,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	char name[KNET_MAX_HOST_LEN];
+ 
+@@ -34,62 +35,23 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_get_name_by_host_id with incorrect hostid 1\n");
+-
+-	if ((!knet_host_get_name_by_host_id(knet_h, 1, name)) || (errno != EINVAL)) {
+-		printf("knet_host_get_name_by_host_id accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_name_by_host_id(knet_h1, 1, name), EINVAL);
+ 
+ 	printf("Test knet_host_get_name_by_host_id with incorrect name\n");
+-
+-	if ((!knet_host_get_name_by_host_id(knet_h, 1, NULL)) || (errno != EINVAL)) {
+-		printf("knet_host_get_name_by_host_id accepted invalid name or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_name_by_host_id(knet_h1, 1, NULL), EINVAL);
+ 
+ 	printf("Test knet_host_get_name_by_host_id with correct values for hostid 1: ");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_get_name_by_host_id(knet_h, 1, name) < 0) {
+-		printf("knet_host_get_name_by_host_id faild to retrieve name: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(knet_host_get_name_by_host_id(knet_h1, 1, name));
+ 
+ 	printf("%s\n", name);
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_get_policy.c b/libknet/tests/api_knet_host_get_policy.c
+index da785c08..68637409 100644
+--- a/libknet/tests/api_knet_host_get_policy.c
++++ b/libknet/tests/api_knet_host_get_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,7 +21,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	uint8_t policy;
+ 
+@@ -34,78 +35,25 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_get_policy incorrect host_id\n");
+-
+-	if ((!knet_host_get_policy(knet_h, 1, &policy)) || (errno != EINVAL)) {
+-		printf("knet_host_get_policy accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_policy(knet_h1, 1, &policy), EINVAL);
+ 
+ 	printf("Test knet_host_get_policy incorrect policy\n");
+-
+-	if ((!knet_host_get_policy(knet_h, 1, NULL)) || (errno != EINVAL)) {
+-		printf("knet_host_get_policy accepted invalid policy or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_policy(knet_h1, 1, NULL), EINVAL);
+ 
+ 	printf("Test knet_host_get_policy correct policy\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_set_policy(knet_h, 1, KNET_LINK_POLICY_RR) < 0) {
+-		printf("knet_host_set_policy failed to set RR policy for host 1: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_get_policy(knet_h, 1, &policy) < 0) {
+-		printf("knet_host_get_policy failed for host 1: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(knet_host_set_policy(knet_h1, 1, KNET_LINK_POLICY_RR));
++	FAIL_ON_ERR(knet_host_get_policy(knet_h1, 1, &policy));
+ 	if (policy != KNET_LINK_POLICY_RR) {
+ 		printf("knet_host_get_policy policy for host 1 does not appear to be correct\n");
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_get_status.c b/libknet/tests/api_knet_host_get_status.c
+index d1861401..9fd05005 100644
+--- a/libknet/tests/api_knet_host_get_status.c
++++ b/libknet/tests/api_knet_host_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -22,7 +22,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_host_status status;
+ 
+@@ -37,58 +38,19 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_host_get_status with unconfigured host_id\n");
+-
+-	if ((!knet_host_get_status(knet_h, 1, &status)) || (errno != EINVAL)) {
+-		printf("knet_host_get_status accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_get_status(knet_h1, 1, &status), EINVAL);
+ 
+ 	printf("Test knet_host_get_status with incorrect status\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_host_get_status(knet_h, 1, NULL)) || (errno != EINVAL)) {
+-		printf("knet_host_get_status accepted invalid status or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_host_get_status(knet_h1, 1, NULL), EINVAL);
+ 
+ 	printf("Test knet_host_get_status with correct values\n");
++	FAIL_ON_ERR(knet_host_get_status(knet_h1, 1, &status));
+ 
+-	if (knet_host_get_status(knet_h, 1, &status) < 0) {
+-		printf("knet_host_get_status failed: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_remove.c b/libknet/tests/api_knet_host_remove.c
+index 345151b1..0262adc3 100644
+--- a/libknet/tests/api_knet_host_remove.c
++++ b/libknet/tests/api_knet_host_remove.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+ 	size_t host_ids_entries;
+ 	struct sockaddr_storage lo;
+@@ -36,109 +37,37 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_remove with unconfigured host_id\n");
+-
+-	if ((!knet_host_remove(knet_h, 1)) || (errno != EINVAL)) {
+-		printf("knet_host_remove accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_remove(knet_h1, 1), EINVAL);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+ 	printf("Test knet_host_remove with configured host_id and links\n");
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo));
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("Unable to enable link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_host_remove(knet_h, 1)) || (errno != EBUSY)) {
++	if ((!knet_host_remove(knet_h1, 1)) || (errno != EBUSY)) {
+ 		printf("knet_host_remove accepted invalid request to remove host with link enabled or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 0) < 0) {
+-		printf("Unable to disable link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Unable to clear link config: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 0));
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+ 	printf("Test knet_host_remove with configured host_id (no links)\n");
++	FAIL_ON_ERR(knet_host_remove(knet_h1, 1));
+ 
+-	if (knet_host_remove(knet_h, 1) < 0) {
+-		printf("knet_host_remove didn't remove host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_get_host_list(knet_h, host_ids, &host_ids_entries) < 0) {
+-		printf("Unable to get host list: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_get_host_list(knet_h1, host_ids, &host_ids_entries));
+ 
+ 	if (host_ids_entries) {
+ 		printf("Too many hosts?\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_set_name.c b/libknet/tests/api_knet_host_set_name.c
+index f390702e..72fc2f51 100644
+--- a/libknet/tests/api_knet_host_set_name.c
++++ b/libknet/tests/api_knet_host_set_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,8 +21,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	char longhostname[KNET_MAX_HOST_LEN+2];
+ 
+ 	printf("Test knet_host_set_name incorrect knet_h\n");
+@@ -34,109 +35,40 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_set_name with incorrect hostid 1\n");
+-
+-	if ((!knet_host_set_name(knet_h, 2, "test")) || (errno != EINVAL)) {
+-		printf("knet_host_set_name accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_set_name(knet_h1, 2, "test"), EINVAL);
+ 
+ 	printf("Test knet_host_set_name with correct values\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_set_name(knet_h, 1, "test") < 0) {
+-		printf("knet_host_set_name failed: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (strcmp("test", knet_h->host_index[1]->name)) {
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(knet_host_set_name(knet_h1, 1, "test"));
++	if (strcmp("test", knet_h1->host_index[1]->name)) {
+ 		printf("knet_host_set_name failed to copy name\n");
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_set_name with correct values (name change)\n");
+-
+-	if (knet_host_set_name(knet_h, 1, "tes") < 0) {
+-		printf("knet_host_set_name failed: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (strcmp("tes", knet_h->host_index[1]->name)) {
++	FAIL_ON_ERR(knet_host_set_name(knet_h1, 1, "tes"));
++	if (strcmp("tes", knet_h1->host_index[1]->name)) {
+ 		printf("knet_host_set_name failed to change name\n");
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_host_set_name with NULL name\n");
+-
+-	if ((!knet_host_set_name(knet_h, 1, NULL)) || (errno != EINVAL)) {
+-		printf("knet_host_set_name accepted invalid name or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_set_name(knet_h1, 1, NULL), EINVAL);
+ 
+ 	printf("Test knet_host_set_name with duplicate name\n");
++	FAIL_ON_ERR(knet_host_add(knet_h1, 2));
+ 
+-	if (knet_host_add(knet_h, 2) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_host_set_name(knet_h, 2, "tes")) || (errno != EEXIST)) {
++	if ((!knet_host_set_name(knet_h1, 2, "tes")) || (errno != EEXIST)) {
+ 		printf("knet_host_set_name accepted duplicated name or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 2);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_host_remove(knet_h, 2);
++	knet_host_remove(knet_h1, 2);
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_set_name with (too) long name\n");
+@@ -144,22 +76,12 @@ static void test(void)
+ 	memset(longhostname, 'a', sizeof(longhostname));
+ 	longhostname[KNET_MAX_HOST_LEN] = '\0';
+ 
+-	if ((!knet_host_set_name(knet_h, 1, longhostname)) || (errno != EINVAL)) {
++	if ((!knet_host_set_name(knet_h1, 1, longhostname)) || (errno != EINVAL)) {
+ 		printf("knet_host_set_name accepted invalid (too long) name or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_host_set_policy.c b/libknet/tests/api_knet_host_set_policy.c
+index c15f4d25..c04287b3 100644
+--- a/libknet/tests/api_knet_host_set_policy.c
++++ b/libknet/tests/api_knet_host_set_policy.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -21,7 +21,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_host_set_policy incorrect knet_h\n");
+@@ -33,69 +34,24 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_host_set_policy incorrect host_id\n");
+-
+-	if ((!knet_host_set_policy(knet_h, 1, KNET_LINK_POLICY_PASSIVE)) || (errno != EINVAL)) {
+-		printf("knet_host_set_policy accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_set_policy(knet_h1, 1, KNET_LINK_POLICY_PASSIVE), EINVAL);
+ 
+ 	printf("Test knet_host_set_policy incorrect policy\n");
+-
+-	if ((!knet_host_set_policy(knet_h, 1, KNET_LINK_POLICY_RR + 1)) || (errno != EINVAL)) {
+-		printf("knet_host_set_policy accepted invalid policy or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_host_set_policy(knet_h1, 1, KNET_LINK_POLICY_RR + 1), EINVAL);
+ 
+ 	printf("Test knet_host_set_policy correct policy\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_set_policy(knet_h, 1, KNET_LINK_POLICY_RR) < 0) {
+-		printf("knet_host_set_policy failed to set RR policy for host 1: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link_handler_policy != KNET_LINK_POLICY_RR) {
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(knet_host_set_policy(knet_h1, 1, KNET_LINK_POLICY_RR));
++	if (knet_h1->host_index[1]->link_handler_policy != KNET_LINK_POLICY_RR) {
+ 		printf("knet_host_set_policy failed to set RR policy for host 1: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_host_remove(knet_h, 1);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_add_acl.c b/libknet/tests/api_knet_link_add_acl.c
+index 759afdc2..28326974 100644
+--- a/libknet/tests/api_knet_link_add_acl.c
++++ b/libknet/tests/api_knet_link_add_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+@@ -47,195 +48,52 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_add_acl with unconfigured host\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with unconfigured link\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with invalid link\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, KNET_MAX_LINK, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, KNET_MAX_LINK, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with invalid ss1\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted invalid ss1 or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with invalid ss2\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted invalid ss2 or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with non matching families\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted non matching families or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with wrong check_type\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with wrong acceptreject\n");
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1), EINVAL);
+ 
+ 	printf("Test knet_link_add_acl with point to point link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_add_acl accepted point to point link or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
++	FAIL_ON_ERR (_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_SUCCESS(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+ 	printf("Test knet_link_add_acl with dynamic link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	host = knet_h->host_index[1];
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo));
++	host = knet_h1->host_index[1];
+ 	link = &host->link[0];
+-
+ 	if (link->access_list_match_entry_head) {
+ 		printf("match list not empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+-		printf("knet_link_add_acl did not accept dynamic link error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
++	FAIL_ON_ERR(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
+ 	if (!link->access_list_match_entry_head) {
+ 		printf("match list empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_clear_acl.c b/libknet/tests/api_knet_link_clear_acl.c
+index d2a6d8d5..c2230d75 100644
+--- a/libknet/tests/api_knet_link_clear_acl.c
++++ b/libknet/tests/api_knet_link_clear_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+@@ -37,150 +38,46 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_clear_acl with unconfigured host\n");
+-
+-	if ((!knet_link_clear_acl(knet_h, 1, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_clear_acl(knet_h1, 1, 0), EINVAL);
+ 
+ 	printf("Test knet_link_clear_acl with unconfigured link\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_clear_acl(knet_h, 1, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_clear_acl(knet_h1, 1, 0), EINVAL);
+ 
+ 	printf("Test knet_link_clear_acl with invalid link\n");
+-
+-	if ((!knet_link_clear_acl(knet_h, 1, KNET_MAX_LINK)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_clear_acl(knet_h1, 1, KNET_MAX_LINK), EINVAL);
+ 
+ 	printf("Test knet_link_clear_acl with point to point link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_clear_acl(knet_h, 1, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_SUCCESS(knet_link_clear_acl(knet_h1, 1, 0), EINVAL);
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+ 	printf("Test knet_link_clear_acl with dynamic link\n");
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	host = knet_h->host_index[1];
++	host = knet_h1->host_index[1];
+ 	link = &host->link[0];
+ 
+ 	if (link->access_list_match_entry_head) {
+ 		printf("match list NOT empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+-		printf("knet_link_clear_acl did not accept dynamic link error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
++	FAIL_ON_ERR(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
+ 	if (!link->access_list_match_entry_head) {
+ 		printf("match list empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_clear_acl(knet_h, 1, 0) < 0) {
+-		printf("knet_link_clear_acl failed to clear. error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
++	FAIL_ON_ERR(knet_link_clear_acl(knet_h1, 1, 0));
+ 	if (link->access_list_match_entry_head) {
+ 		printf("match list NOT empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_clear_config.c b/libknet/tests/api_knet_link_clear_config.c
+index b7c7b14b..20f83ff5 100644
+--- a/libknet/tests/api_knet_link_clear_config.c
++++ b/libknet/tests/api_knet_link_clear_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,8 +23,9 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
++	int res;
+ 	struct sockaddr_storage lo;
+ 
+ 	printf("Test knet_link_clear_config incorrect knet_h\n");
+@@ -35,116 +36,28 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_clear_config with unconfigured host_id\n");
+-
+-	if ((!knet_link_clear_config(knet_h, 1, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_config accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_clear_config(knet_h1, 1, 0), EINVAL);
+ 
+ 	printf("Test knet_link_clear_config with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_clear_config(knet_h, 1, KNET_MAX_LINK)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_config accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_clear_config(knet_h1, 1, KNET_MAX_LINK), EINVAL);
+ 
+ 	printf("Test knet_link_clear_config with unconfigured linkid\n");
+-
+-	if ((!knet_link_clear_config(knet_h, 1, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_clear_config accepted unconfigured linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_clear_config(knet_h1, 1, 0), EINVAL);
+ 
+ 	printf("Test knet_link_clear_config with enabled linkid\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("Unable to enable link: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_clear_config(knet_h, 1, 0) || (errno != EBUSY))) {
+-		printf("knet_link_clear_config accepted invalid enabled link or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	FAIL_ON_SUCCESS(knet_link_clear_config(knet_h1, 1, 0), EBUSY);
+ 
+ 	printf("Test knet_link_clear_config with correct data\n");
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 0));
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+-	if (knet_link_set_enable(knet_h, 1, 0, 0) < 0) {
+-		printf("Unable to disable link: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Unable to clear link config: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_config.c b/libknet/tests/api_knet_link_get_config.c
+index 441be547..d3326c7e 100644
+--- a/libknet/tests/api_knet_link_get_config.c
++++ b/libknet/tests/api_knet_link_get_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct sockaddr_storage lo, get_src, get_dst;
+ 	uint8_t dynamic = 0, transport = 0;
+@@ -41,270 +42,88 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_config with unconfigured host_id\n");
+-
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if ((!knet_link_get_config(knet_h, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags), EINVAL);
+ 
+ 	printf("Test knet_link_get_config with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if ((!knet_link_get_config(knet_h, 1, KNET_MAX_LINK, &transport, &get_src, &get_dst, &dynamic, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, KNET_MAX_LINK, &transport, &get_src, &get_dst, &dynamic, &flags), EINVAL);
+ 
+ 	printf("Test knet_link_get_config with incorrect src_addr\n");
+-
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if ((!knet_link_get_config(knet_h, 1, 0, &transport, NULL, &get_dst, &dynamic, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted invalid src_addr or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, 0, &transport, NULL, &get_dst, &dynamic, &flags), EINVAL);
+ 
+ 	printf("Test knet_link_get_config with incorrect dynamic\n");
+-
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if ((!knet_link_get_config(knet_h, 1, 0, &transport, &get_src, &get_dst, NULL, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted invalid dynamic or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, &get_dst, NULL, &flags), EINVAL);
+ 
+ 	printf("Test knet_link_get_config with unconfigured link\n");
+-
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if ((!knet_link_get_config(knet_h, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags), EINVAL);
+ 
+ 	printf("Test knet_link_get_config with incorrect dst_addr\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if ((!knet_link_get_config(knet_h, 1, 0, &transport, &get_src, NULL, &dynamic, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted invalid dst_addr or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, NULL, &dynamic, &flags), EINVAL);
+ 
+ 	if (dynamic) {
+ 		printf("knet_link_get_config returned invalid dynamic status\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_link_get_config with correct parameters for static link\n");
+-
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if (knet_link_get_config(knet_h, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags) < 0) {
+-		printf("knet_link_get_config failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags));
+ 
+ 	if (transport != KNET_TRANSPORT_UDP) {
+ 		printf("knet_link_get_config returned incorrect transport: %d\n", transport);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if ((dynamic) ||
+ 	    (memcmp(&lo, &get_src, sizeof(struct sockaddr_storage))) ||
+ 	    (memcmp(&lo, &get_dst, sizeof(struct sockaddr_storage)))) {
+ 		printf("knet_link_get_config returned invalid data\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_link_get_config with correct parameters for dynamic link\n");
+-
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Unable to deconfigure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo));
+ 	memset(&get_src, 0, sizeof(struct sockaddr_storage));
+ 	memset(&get_dst, 0, sizeof(struct sockaddr_storage));
+-
+-	if (knet_link_get_config(knet_h, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags) < 0) {
+-		printf("knet_link_get_config failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags));
+ 
+ 	if ((!dynamic) ||
+ 	    (memcmp(&lo, &get_src, sizeof(struct sockaddr_storage)))) {
+ 		printf("knet_link_get_config returned invalid data\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Test knet_link_get_config NULL transport ptr\n");
+-
+-	if ((!knet_link_get_config(knet_h, 1, 0, NULL, &get_src, &get_dst, &dynamic, &flags)) || (errno != EINVAL)) {
+-		printf("knet_link_get_config accepted NULL &transport or returned incorrect error: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_link_get_config(knet_h1, 1, 0, NULL, &get_src, &get_dst, &dynamic, &flags), EINVAL);
+ 
+ 	printf("Test knet_link_get_config with flags\n");
+-
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Unable to deconfigure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, KNET_LINK_FLAG_TRAFFICHIPRIO, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_config(knet_h, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags) < 0) {
+-		printf("knet_link_get_config failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, KNET_LINK_FLAG_TRAFFICHIPRIO, AF_INET, 1, &lo));
++	FAIL_ON_ERR(knet_link_get_config(knet_h1, 1, 0, &transport, &get_src, &get_dst, &dynamic, &flags));
+ 	if (flags != KNET_LINK_FLAG_TRAFFICHIPRIO) {
+ 		printf("knet_link_get_config returned no flags\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_enable.c b/libknet/tests/api_knet_link_get_enable.c
+index fa14a240..49067d44 100644
+--- a/libknet/tests/api_knet_link_get_enable.c
++++ b/libknet/tests/api_knet_link_get_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	unsigned int enabled;
+ 	struct sockaddr_storage lo;
+@@ -36,142 +37,37 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_enable with unconfigured host_id\n");
+-
+-	if ((!knet_link_get_enable(knet_h, 1, 0, &enabled)) || (errno != EINVAL)) {
+-		printf("knet_link_get_enable accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_enable(knet_h1, 1, 0, &enabled), EINVAL);
+ 
+ 	printf("Test knet_link_get_enable with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_get_enable(knet_h, 1, KNET_MAX_LINK, &enabled)) || (errno != EINVAL)) {
+-		printf("knet_link_get_enable accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_get_enable(knet_h1, 1, KNET_MAX_LINK, &enabled), EINVAL);
+ 
+ 	printf("Test knet_link_get_enable with unconfigured link\n");
+-
+-	if ((!knet_link_get_enable(knet_h, 1, 0, &enabled)) || (errno != EINVAL)) {
+-		printf("knet_link_get_enable accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_enable(knet_h1, 1, 0, &enabled), EINVAL);
+ 
+ 	printf("Test knet_link_get_enable without enabled\n");
+-
+-	if ((!knet_link_get_enable(knet_h, 1, 0, NULL)) || (errno != EINVAL)) {
+-		printf("knet_link_get_enable accepted NULL enabled or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_enable(knet_h1, 1, 0, NULL), EINVAL);
+ 
+ 	printf("Test knet_link_get_enable with disabled link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_enable(knet_h, 1, 0, &enabled) < 0) {
+-		printf("knet_link_get_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_get_enable(knet_h1, 1, 0, &enabled));
+ 	if (enabled) {
+ 		printf("knet_link_get_enable returned incorrect value");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_link_get_enable with enabled link\n");
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_get_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_enable(knet_h, 1, 0, &enabled) < 0) {
+-		printf("knet_link_get_enable failed: %s\n", strerror(errno));
+-		knet_link_get_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	FAIL_ON_ERR(knet_link_get_enable(knet_h1, 1, 0, &enabled));
+ 	if (!enabled) {
+ 		printf("knet_link_get_enable returned incorrect value");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_link_list.c b/libknet/tests/api_knet_link_get_link_list.c
+index 45000bb2..248e2e76 100644
+--- a/libknet/tests/api_knet_link_get_link_list.c
++++ b/libknet/tests/api_knet_link_get_link_list.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	uint8_t link_ids[KNET_MAX_LINK];
+ 	size_t link_ids_entries = 0;
+@@ -39,116 +40,33 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_link_list with unconfigured host_id\n");
+-
+-	if ((!knet_link_get_link_list(knet_h, 1, link_ids, &link_ids_entries)) || (errno != EINVAL)) {
+-		printf("knet_link_get_link_list accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_link_list(knet_h1, 1, link_ids, &link_ids_entries), EINVAL);
+ 
+ 	printf("Test knet_link_get_link_list with incorrect link_id\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_get_link_list(knet_h, 1, NULL, &link_ids_entries)) || (errno != EINVAL)) {
+-		printf("knet_link_get_link_list accepted invalid link_ids or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_get_link_list(knet_h1, 1, NULL, &link_ids_entries), EINVAL);
+ 
+ 	printf("Test knet_link_get_link_list with incorrect link_ids_entries\n");
+-
+-	if ((!knet_link_get_link_list(knet_h, 1, link_ids, NULL)) || (errno != EINVAL)) {
+-		printf("knet_link_get_link_list accepted invalid link_ids_entries or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_link_list(knet_h1, 1, link_ids, NULL), EINVAL);
+ 
+ 	printf("Test knet_link_get_link_list with no links\n");
+-
+-	if (knet_link_get_link_list(knet_h, 1, link_ids, &link_ids_entries) < 0) {
+-		printf("knet_link_get_link_list failed: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_link_get_link_list(knet_h1, 1, link_ids, &link_ids_entries));
+ 	if (link_ids_entries != 0) {
+ 		printf("knet_link_get_link_list returned incorrect number of links");
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_link_get_link_list with 1 link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_link_list(knet_h, 1, link_ids, &link_ids_entries) < 0) {
+-		printf("knet_link_get_link_list failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_get_link_list(knet_h1, 1, link_ids, &link_ids_entries));
+ 	if ((link_ids_entries != 1) || (link_ids[0] != 0)) {
+ 		printf("knet_link_get_link_list returned incorrect values");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_ping_timers.c b/libknet/tests/api_knet_link_get_ping_timers.c
+index 9853de5d..7a5af7ca 100644
+--- a/libknet/tests/api_knet_link_get_ping_timers.c
++++ b/libknet/tests/api_knet_link_get_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	time_t interval = 0, timeout = 0;
+ 	unsigned int precision = 0;
+@@ -38,135 +39,39 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_ping_timers with unconfigured host_id\n");
+-
+-	if ((!knet_link_get_ping_timers(knet_h, 1, 0, &interval, &timeout, &precision)) || (errno != EINVAL)) {
+-		printf("knet_link_get_ping_timers accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_ping_timers(knet_h1, 1, 0, &interval, &timeout, &precision), EINVAL);
+ 
+ 	printf("Test knet_link_get_ping_timers with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_get_ping_timers(knet_h, 1, KNET_MAX_LINK, &interval, &timeout, &precision)) || (errno != EINVAL)) {
+-		printf("knet_link_get_ping_timers accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_get_ping_timers(knet_h1, 1, KNET_MAX_LINK, &interval, &timeout, &precision), EINVAL);
+ 
+ 	printf("Test knet_link_get_ping_timers with incorrect interval\n");
+-
+-	if ((!knet_link_get_ping_timers(knet_h, 1, 0, NULL, &timeout, &precision)) || (errno != EINVAL)) {
+-		printf("knet_link_get_ping_timers accepted invalid interval or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_ping_timers(knet_h1, 1, 0, NULL, &timeout, &precision), EINVAL);
+ 
+ 	printf("Test knet_link_get_ping_timers with incorrect timeout\n");
+-
+-	if ((!knet_link_get_ping_timers(knet_h, 1, 0, &interval, NULL, &precision)) || (errno != EINVAL)) {
+-		printf("knet_link_get_ping_timers accepted invalid timeout or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_ping_timers(knet_h1, 1, 0, &interval, NULL, &precision), EINVAL);
+ 
+ 	printf("Test knet_link_get_ping_timers with incorrect interval\n");
+-
+-	if ((!knet_link_get_ping_timers(knet_h, 1, 0, &interval, &timeout, NULL)) || (errno != EINVAL)) {
+-		printf("knet_link_get_ping_timers accepted invalid interval or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_ping_timers(knet_h1, 1, 0, &interval, &timeout, NULL), EINVAL);
+ 
+ 	printf("Test knet_link_get_ping_timers with unconfigured link\n");
+-
+-	if ((!knet_link_get_ping_timers(knet_h, 1, 0, &interval, &timeout, &precision)) || (errno != EINVAL)) {
+-		printf("knet_link_get_ping_timers accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_ping_timers(knet_h1, 1, 0, &interval, &timeout, &precision), EINVAL);
+ 
+ 	printf("Test knet_link_get_ping_timers with correct values\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_ping_timers(knet_h, 1, 0, &interval, &timeout, &precision) < 0) {
+-		printf("knet_link_get_ping_timers failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_get_ping_timers(knet_h1, 1, 0, &interval, &timeout, &precision));
+ 
+ 	printf("DEFAULT: int: %ld timeout: %ld prec: %u\n", (long int)interval, (long int)timeout, precision);
+-
+ 	if ((interval != KNET_LINK_DEFAULT_PING_INTERVAL) ||
+ 	    (timeout != KNET_LINK_DEFAULT_PING_TIMEOUT) ||
+ 	    (precision != KNET_LINK_DEFAULT_PING_PRECISION)) {
+ 		printf("knet_link_get_ping_timers failed to set values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_pong_count.c b/libknet/tests/api_knet_link_get_pong_count.c
+index 856a19b2..313797b3 100644
+--- a/libknet/tests/api_knet_link_get_pong_count.c
++++ b/libknet/tests/api_knet_link_get_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	uint8_t pong_count = 0;
+ 	struct sockaddr_storage lo;
+@@ -36,114 +37,31 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_pong_count with unconfigured host_id\n");
+-
+-	if ((!knet_link_get_pong_count(knet_h, 1, 0, &pong_count)) || (errno != EINVAL)) {
+-		printf("knet_link_get_pong_count accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_pong_count(knet_h1, 1, 0, &pong_count), EINVAL);
+ 
+ 	printf("Test knet_link_get_pong_count with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_get_pong_count(knet_h, 1, KNET_MAX_LINK, &pong_count)) || (errno != EINVAL)) {
+-		printf("knet_link_get_pong_count accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_get_pong_count(knet_h1, 1, KNET_MAX_LINK, &pong_count), EINVAL);
+ 
+ 	printf("Test knet_link_get_pong_count with incorrect pong count\n");
+-
+-	if ((!knet_link_get_pong_count(knet_h, 1, 0, NULL)) || (errno != EINVAL)) {
+-		printf("knet_link_get_pong_count accepted invalid pong count or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_pong_count(knet_h1, 1, 0, NULL), EINVAL);
+ 
+ 	printf("Test knet_link_get_pong_count with unconfigured link\n");
+-
+-	if ((!knet_link_get_pong_count(knet_h, 1, 0, &pong_count)) || (errno != EINVAL)) {
+-		printf("knet_link_get_pong_count accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_pong_count(knet_h1, 1, 0, &pong_count), EINVAL);
+ 
+ 	printf("Test knet_link_get_pong_count with correct values\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_pong_count(knet_h, 1, 0, 3) < 0) {
+-		printf("knet_link_set_pong_count failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_pong_count(knet_h, 1, 0, &pong_count) < 0) {
+-		printf("knet_link_get_pong_count failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_set_pong_count(knet_h1, 1, 0, 3));
++	FAIL_ON_ERR(knet_link_get_pong_count(knet_h1, 1, 0, &pong_count));
+ 	if (pong_count != 3) {
+ 		printf("knet_link_get_pong_count failed to get correct values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_priority.c b/libknet/tests/api_knet_link_get_priority.c
+index b748dfb9..95efb42f 100644
+--- a/libknet/tests/api_knet_link_get_priority.c
++++ b/libknet/tests/api_knet_link_get_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	uint8_t priority = 0;
+ 	struct sockaddr_storage lo;
+@@ -36,114 +37,31 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_priority with unconfigured host_id\n");
+-
+-	if ((!knet_link_get_priority(knet_h, 1, 0, &priority)) || (errno != EINVAL)) {
+-		printf("knet_link_get_priority accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_priority(knet_h1, 1, 0, &priority), EINVAL);
+ 
+ 	printf("Test knet_link_get_priority with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_get_priority(knet_h, 1, KNET_MAX_LINK, &priority)) || (errno != EINVAL)) {
+-		printf("knet_link_get_priority accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_get_priority(knet_h1, 1, KNET_MAX_LINK, &priority), EINVAL);
+ 
+ 	printf("Test knet_link_get_priority with unconfigured link\n");
+-
+-	if ((!knet_link_get_priority(knet_h, 1, 0, &priority)) || (errno != EINVAL)) {
+-		printf("knet_link_get_priority accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_priority(knet_h1, 1, 0, &priority), EINVAL);
+ 
+ 	printf("Test knet_link_get_priority with incorrect priority\n");
+-
+-	if ((!knet_link_get_priority(knet_h, 1, 0, NULL)) || (errno != EINVAL)) {
+-		printf("knet_link_get_priority accepted incorrect priority or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_priority(knet_h1, 1, 0, NULL), EINVAL);
+ 
+ 	printf("Test knet_link_get_priority with correct values\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_priority(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_priority failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_priority(knet_h, 1, 0, &priority) < 0) {
+-		printf("knet_link_get_priority failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_set_priority(knet_h1, 1, 0, 1));
++	FAIL_ON_ERR(knet_link_get_priority(knet_h1, 1, 0, &priority));
+ 	if (priority != 1) {
+ 		printf("knet_link_get_priority failed to get correct values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_get_status.c b/libknet/tests/api_knet_link_get_status.c
+index b6517ce1..ce0a9c65 100644
+--- a/libknet/tests/api_knet_link_get_status.c
++++ b/libknet/tests/api_knet_link_get_status.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_link_status status;
+ 	struct sockaddr_storage lo;
+@@ -38,96 +39,26 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_get_status with unconfigured host_id\n");
+-
+-	if ((!knet_link_get_status(knet_h, 1, 0, &status, sizeof(struct knet_link_status))) || (errno != EINVAL)) {
+-		printf("knet_link_get_status accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_status(knet_h1, 1, 0, &status, sizeof(struct knet_link_status)), EINVAL);
+ 
+ 	printf("Test knet_link_get_status with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_get_status(knet_h, 1, KNET_MAX_LINK, &status, sizeof(struct knet_link_status))) || (errno != EINVAL)) {
+-		printf("knet_link_get_status accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_get_status(knet_h1, 1, KNET_MAX_LINK, &status, sizeof(struct knet_link_status)), EINVAL);
+ 
+ 	printf("Test knet_link_get_status with incorrect status\n");
+-
+-	if ((!knet_link_get_status(knet_h, 1, 0, NULL, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_get_status accepted invalid status or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_status(knet_h1, 1, 0, NULL, 0), EINVAL);
+ 
+ 	printf("Test knet_link_get_status with unconfigured link\n");
+-
+-	if ((!knet_link_get_status(knet_h, 1, 0, &status, sizeof(struct knet_link_status))) || (errno != EINVAL)) {
+-		printf("knet_link_get_status accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_get_status(knet_h1, 1, 0, &status, sizeof(struct knet_link_status)), EINVAL);
+ 
+ 	printf("Test knet_link_get_status with correct values\n");
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &status, sizeof(struct knet_link_status)));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_status(knet_h, 1, 0, &status, sizeof(struct knet_link_status)) < 0) {
+-		printf("knet_link_get_status failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_insert_acl.c b/libknet/tests/api_knet_link_insert_acl.c
+index a5de2378..498e23e5 100644
+--- a/libknet/tests/api_knet_link_insert_acl.c
++++ b/libknet/tests/api_knet_link_insert_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+@@ -47,195 +48,56 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_insert_acl with unconfigured host\n");
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with unconfigured link\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with invalid link\n");
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, KNET_MAX_LINK, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, KNET_MAX_LINK, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with invalid ss1\n");
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted invalid ss1 or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with invalid ss2\n");
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted invalid ss2 or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with non matching families\n");
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted non matching families or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with wrong check_type\n");
+ 
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with wrong acceptreject\n");
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1), EINVAL);
+ 
+ 	printf("Test knet_link_insert_acl with point to point link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_insert_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_SUCCESS(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+ 	printf("Test knet_link_insert_acl with dynamic link\n");
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	host = knet_h->host_index[1];
++	host = knet_h1->host_index[1];
+ 	link = &host->link[0];
+ 
+ 	if (link->access_list_match_entry_head) {
+ 		printf("match list not empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_insert_acl(knet_h, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+-		printf("knet_link_insert_acl did not accept dynamic link error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
++	FAIL_ON_ERR(knet_link_insert_acl(knet_h1, 1, 0, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
+ 	if (!link->access_list_match_entry_head) {
+ 		printf("match list empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_rm_acl.c b/libknet/tests/api_knet_link_rm_acl.c
+index 7af3fd0a..13272bbf 100644
+--- a/libknet/tests/api_knet_link_rm_acl.c
++++ b/libknet/tests/api_knet_link_rm_acl.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+@@ -47,205 +48,55 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_rm_acl with unconfigured host\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted unconfigured host or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with unconfigured link\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with invalid link\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, KNET_MAX_LINK, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted invalid link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, KNET_MAX_LINK, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with invalid ss1\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted invalid ss1 or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, NULL, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with invalid ss2\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted invalid ss2 or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, NULL, CHECK_TYPE_RANGE, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with non matching families\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted non matching families or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo6, CHECK_TYPE_RANGE, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with wrong check_type\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_RANGE + CHECK_TYPE_MASK + CHECK_TYPE_ADDRESS + 1, CHECK_ACCEPT), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with wrong acceptreject\n");
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted incorrect check_type or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT + CHECK_REJECT + 1), EINVAL);
+ 
+ 	printf("Test knet_link_rm_acl with point to point link\n");
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT)) || (errno != EINVAL)) {
+-		printf("knet_link_rm_acl accepted point ot point link or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_SUCCESS(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT), EINVAL);
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+ 	printf("Test knet_link_rm_acl with dynamic link\n");
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 1, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	host = knet_h->host_index[1];
++	host = knet_h1->host_index[1];
+ 	link = &host->link[0];
+-
+ 	if (link->access_list_match_entry_head) {
+ 		printf("match list not empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_add_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+-		printf("Failed to add an access list: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_rm_acl(knet_h, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT) < 0) {
+-		printf("knet_link_rm_acl did not accept dynamic link error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
++	FAIL_ON_ERR(knet_link_add_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
++	FAIL_ON_ERR(knet_link_rm_acl(knet_h1, 1, 0, &lo, &lo, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
+ 	if (link->access_list_match_entry_head) {
+ 		printf("match list NOT empty!");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_set_config.c b/libknet/tests/api_knet_link_set_config.c
+index 14025649..01d450b1 100644
+--- a/libknet/tests/api_knet_link_set_config.c
++++ b/libknet/tests/api_knet_link_set_config.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	struct knet_host *host;
+ 	struct knet_link *link;
+ 	int logfds[2];
+@@ -46,263 +47,81 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_set_config with unconfigured host_id\n");
+-
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_set_config accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_config with bad transport type\n");
+-
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_MAX_TRANSPORTS, &lo, &lo, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_set_config accepted invalid transport or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 0, KNET_MAX_TRANSPORTS, &lo, &lo, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_config with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_config(knet_h, 1, KNET_MAX_LINK, KNET_TRANSPORT_UDP, &lo, &lo, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_set_config accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, KNET_MAX_LINK, KNET_TRANSPORT_UDP, &lo, &lo, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_config with incorrect src_addr\n");
+-
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, NULL, &lo, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_set_config accepted invalid src_addr or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, NULL, &lo, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_config with conflicting address families\n");
+-
+-	if (make_local_sockaddr6(&lo6, -1) < 0) {
+-		printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo6, 0) == 0) {
+-		printf("knet_link_set_config accepted invalid address families: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(make_local_sockaddr6(&lo6, -1));
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo6, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_config with dynamic dst_addr\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	host = knet_h->host_index[1];
++	FAIL_ON_ERR(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0));
++	host = knet_h1->host_index[1];
+ 	link = &host->link[0];
+-
+ 	if (link->access_list_match_entry_head) {
+ 		printf("found access lists for dynamic dst_addr!\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(struct knet_link_status)) < 0) {
+-		printf("Unable to get link status: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(struct knet_link_status)));
+ 
+ 	if ((link_status.enabled != 0) ||
+ 	    (strcmp(link_status.src_ipaddr, "127.0.0.1")) ||
+ 	    (strcmp(link_status.src_port, lo_portstr)) ||
+-	    (knet_h->host_index[1]->link[0].dynamic != KNET_LINK_DYNIP)) {
++	    (knet_h1->host_index[1]->link[0].dynamic != KNET_LINK_DYNIP)) {
+ 		printf("knet_link_set_config failed to set configuration. enabled: %d src_addr %s src_port %s dynamic %u\n",
+-		       link_status.enabled, link_status.src_ipaddr, link_status.src_port, knet_h->host_index[1]->link[0].dynamic);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		       link_status.enabled, link_status.src_ipaddr, link_status.src_port, knet_h1->host_index[1]->link[0].dynamic);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_link_set_config with dynamic link (0) and static link (1)\n");
+-
+-	if (!knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_UDP, &lo, &lo, 0) || (errno != EINVAL)) {
+-		printf("knet_link_set_config accepted request mixed static/dynamic request or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 1, KNET_TRANSPORT_UDP, &lo, &lo, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_config with already configured link\n");
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0) || (errno != EBUSY))) {
+-		printf("knet_link_set_config accepted request while link configured or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0), EBUSY);
+ 
+ 	printf("Test knet_link_set_config with link enabled\n");
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("Unable to enable link: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(struct knet_link_status)) < 0) {
+-		printf("Unable to get link status: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0)) || (errno != EBUSY)) {
+-		printf("knet_link_set_config accepted request while link enabled or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 0) < 0) {
+-		printf("Unable to disable link: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Unable to clear link config: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(struct knet_link_status)));
++	FAIL_ON_SUCCESS(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &lo, NULL, 0), EBUSY);
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 0));
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
+ 
+ 	printf("Test knet_link_set_config with static dst_addr\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	host = knet_h->host_index[1];
++	FAIL_ON_ERR(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &lo, &lo, 0));
++	host = knet_h1->host_index[1];
+ 	link = &host->link[0];
+-
+ 	if (!link->access_list_match_entry_head) {
+ 		printf("Unable to find default access lists for static dst_addr!\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(struct knet_link_status)) < 0) {
+-		printf("Unable to get link status: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(struct knet_link_status)));
+ 
+ 	if ((link_status.enabled != 0) ||
+ 	    (strcmp(link_status.src_ipaddr, "127.0.0.1")) ||
+ 	    (strcmp(link_status.src_port, lo_portstr)) ||
+ 	    (strcmp(link_status.dst_ipaddr, "127.0.0.1")) ||
+ 	    (strcmp(link_status.dst_port, lo_portstr)) ||
+-	    (knet_h->host_index[1]->link[0].dynamic != KNET_LINK_STATIC)) {
++	    (knet_h1->host_index[1]->link[0].dynamic != KNET_LINK_STATIC)) {
+ 		printf("knet_link_set_config failed to set configuration. enabled: %d src_addr %s src_port %s dst_addr %s dst_port %s dynamic %u\n",
+-		       link_status.enabled, link_status.src_ipaddr, link_status.src_port, link_status.dst_ipaddr, link_status.dst_port, knet_h->host_index[1]->link[0].dynamic);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		       link_status.enabled, link_status.src_ipaddr, link_status.src_port, link_status.dst_ipaddr, link_status.dst_port, knet_h1->host_index[1]->link[0].dynamic);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_set_enable.c b/libknet/tests/api_knet_link_set_enable.c
+index 2ddd311c..e18acb5e 100644
+--- a/libknet/tests/api_knet_link_set_enable.c
++++ b/libknet/tests/api_knet_link_set_enable.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test_udp(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct sockaddr_storage src, dst;
+ 
+@@ -45,136 +46,43 @@ static void test_udp(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_set_enable with unconfigured host_id\n");
+-
+-	if ((!knet_link_set_enable(knet_h, 1, 0, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, 0, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_enable(knet_h, 1, KNET_MAX_LINK, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, KNET_MAX_LINK, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with unconfigured link\n");
+-
+-	if ((!knet_link_set_enable(knet_h, 1, 0, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, 0, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with incorrect values\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_enable(knet_h, 1, 0, 2)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted incorrect value for enabled or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0));
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, 0, 2), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with correct values (1)\n");
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link[0].status.enabled != 1) {
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	if (knet_h1->host_index[1]->link[0].status.enabled != 1) {
+ 		printf("knet_link_set_enable failed to set correct values\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Test knet_link_set_enable with correct values (0)\n");
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 0) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link[0].status.enabled != 0) {
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 0));
++	if (knet_h1->host_index[1]->link[0].status.enabled != 0) {
+ 		printf("knet_link_set_enable failed to set correct values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ #ifdef HAVE_NETINET_SCTP_H
+ static void test_sctp(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct sockaddr_storage src, dst;
+ 
+@@ -196,134 +104,42 @@ static void test_sctp(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_set_enable with unconfigured host_id\n");
+-
+-	if ((!knet_link_set_enable(knet_h, 1, 0, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, 0, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_enable(knet_h, 1, KNET_MAX_LINK, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, KNET_MAX_LINK, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with unconfigured link\n");
+-
+-	if ((!knet_link_set_enable(knet_h, 1, 0, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, 0, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with incorrect values\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_SCTP, &src, &dst, 0) < 0) {
+-		int exit_status = errno == EPROTONOSUPPORT ? SKIP : FAIL;
++	if (knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_SCTP, &src, &dst, 0) < 0) {
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(exit_status);
+-	}
+-
+-	if ((!knet_link_set_enable(knet_h, 1, 0, 2)) || (errno != EINVAL)) {
+-		printf("knet_link_set_enable accepted incorrect value for enabled or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(SKIP);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_enable(knet_h1, 1, 0, 2), EINVAL);
+ 
+ 	printf("Test knet_link_set_enable with correct values (1)\n");
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link[0].status.enabled != 1) {
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	if (knet_h1->host_index[1]->link[0].status.enabled != 1) {
+ 		printf("knet_link_set_enable failed to set correct values\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	printf("Wait 2 seconds for sockets to connect\n");
+-	test_sleep(knet_h, 2);
++	test_sleep(knet_h1, 2);
+ 
+ 	printf("Test knet_link_set_enable with correct values (0)\n");
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 0) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link[0].status.enabled != 0) {
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 0));
++	if (knet_h1->host_index[1]->link[0].status.enabled != 0) {
+ 		printf("knet_link_set_enable failed to set correct values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ #endif
+ 
+diff --git a/libknet/tests/api_knet_link_set_ping_timers.c b/libknet/tests/api_knet_link_set_ping_timers.c
+index ca9b6eff..fd94e3c0 100644
+--- a/libknet/tests/api_knet_link_set_ping_timers.c
++++ b/libknet/tests/api_knet_link_set_ping_timers.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct sockaddr_storage src, dst;
+ 
+@@ -46,133 +47,37 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_set_ping_timers with unconfigured host_id\n");
+-
+-	if ((!knet_link_set_ping_timers(knet_h, 1, 0, 1000, 2000, 2048)) || (errno != EINVAL)) {
+-		printf("knet_link_set_ping_timers accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_ping_timers(knet_h1, 1, 0, 1000, 2000, 2048), EINVAL);
+ 
+ 	printf("Test knet_link_set_ping_timers with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_ping_timers(knet_h, 1, KNET_MAX_LINK, 1000, 2000, 2048)) || (errno != EINVAL)) {
+-		printf("knet_link_set_ping_timers accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_set_ping_timers(knet_h1, 1, KNET_MAX_LINK, 1000, 2000, 2048), EINVAL);
+ 
+ 	printf("Test knet_link_set_ping_timers with incorrect interval\n");
+-
+-	if ((!knet_link_set_ping_timers(knet_h, 1, 0, 0, 2000, 2048)) || (errno != EINVAL)) {
+-		printf("knet_link_set_ping_timers accepted invalid interval or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_ping_timers(knet_h1, 1, 0, 0, 2000, 2048), EINVAL);
+ 
+ 	printf("Test knet_link_set_ping_timers with 0 timeout\n");
+-
+-	if ((!knet_link_set_ping_timers(knet_h, 1, 0, 1000, 0, 2048)) || (errno != ENOSYS)) {
+-		printf("knet_link_set_ping_timers accepted invalid timeout or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_ping_timers(knet_h1, 1, 0, 1000, 0, 2048), ENOSYS);
+ 
+ 	printf("Test knet_link_set_ping_timers with incorrect interval\n");
+-
+-	if ((!knet_link_set_ping_timers(knet_h, 1, 0, 1000, 2000, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_set_ping_timers accepted invalid interval or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_ping_timers(knet_h1, 1, 0, 1000, 2000, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_ping_timers with unconfigured link\n");
+-
+-	if ((!knet_link_set_ping_timers(knet_h, 1, 0, 1000, 2000, 2048)) || (errno != EINVAL)) {
+-		printf("knet_link_set_ping_timers accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_ping_timers(knet_h1, 1, 0, 1000, 2000, 2048), EINVAL);
+ 
+ 	printf("Test knet_link_set_ping_timers with correct values\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_ping_timers(knet_h, 1, 0, 1000, 2000, 2048) < 0) {
+-		printf("knet_link_set_ping_timers failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((knet_h->host_index[1]->link[0].ping_interval != 1000000) ||
+-	    (knet_h->host_index[1]->link[0].pong_timeout != 2000000) ||
+-	    (knet_h->host_index[1]->link[0].latency_max_samples != 2048)) {
++	FAIL_ON_ERR(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0));
++	FAIL_ON_ERR(knet_link_set_ping_timers(knet_h1, 1, 0, 1000, 2000, 2048));
++	if ((knet_h1->host_index[1]->link[0].ping_interval != 1000000) ||
++	    (knet_h1->host_index[1]->link[0].pong_timeout != 2000000) ||
++	    (knet_h1->host_index[1]->link[0].latency_max_samples != 2048)) {
+ 		printf("knet_link_set_ping_timers failed to set values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_set_pong_count.c b/libknet/tests/api_knet_link_set_pong_count.c
+index c77572d0..9463c1e1 100644
+--- a/libknet/tests/api_knet_link_set_pong_count.c
++++ b/libknet/tests/api_knet_link_set_pong_count.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct sockaddr_storage src, dst;
+ 
+@@ -45,104 +46,29 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_set_pong_count with unconfigured host_id\n");
+-
+-	if ((!knet_link_set_pong_count(knet_h, 1, 0, 2)) || (errno != EINVAL)) {
+-		printf("knet_link_set_pong_count accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_pong_count(knet_h1, 1, 0, 2), EINVAL);
+ 
+ 	printf("Test knet_link_set_pong_count with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_pong_count(knet_h, 1, KNET_MAX_LINK, 2)) || (errno != EINVAL)) {
+-		printf("knet_link_set_pong_count accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_set_pong_count(knet_h1, 1, KNET_MAX_LINK, 2), EINVAL);
+ 
+ 	printf("Test knet_link_set_pong_count with incorrect pong count\n");
+-
+-	if ((!knet_link_set_pong_count(knet_h, 1, 0, 0)) || (errno != EINVAL)) {
+-		printf("knet_link_set_pong_count accepted invalid pong count or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_pong_count(knet_h1, 1, 0, 0), EINVAL);
+ 
+ 	printf("Test knet_link_set_pong_count with unconfigured link\n");
+-
+-	if ((!knet_link_set_pong_count(knet_h, 1, 0, 2)) || (errno != EINVAL)) {
+-		printf("knet_link_set_pong_count accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_pong_count(knet_h1, 1, 0, 2), EINVAL);
+ 
+ 	printf("Test knet_link_set_pong_count with correct values\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_pong_count(knet_h, 1, 0, 3) < 0) {
+-		printf("knet_link_set_pong_count failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link[0].pong_count != 3) {
++	FAIL_ON_ERR(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0));
++	FAIL_ON_ERR(knet_link_set_pong_count(knet_h1, 1, 0, 3));
++	if (knet_h1->host_index[1]->link[0].pong_count != 3) {
+ 		printf("knet_link_set_pong_count failed to set correct values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_link_set_priority.c b/libknet/tests/api_knet_link_set_priority.c
+index 1f885881..875b7174 100644
+--- a/libknet/tests/api_knet_link_set_priority.c
++++ b/libknet/tests/api_knet_link_set_priority.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 	struct sockaddr_storage src, dst;
+ 
+@@ -46,90 +47,26 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_link_set_priority with unconfigured host_id\n");
+-
+-	if ((!knet_link_set_priority(knet_h, 1, 0, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_priority accepted invalid host_id or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_priority(knet_h1, 1, 0, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_priority with incorrect linkid\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("Unable to add host_id 1: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if ((!knet_link_set_priority(knet_h, 1, KNET_MAX_LINK, 2)) || (errno != EINVAL)) {
+-		printf("knet_link_set_priority accepted invalid linkid or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_SUCCESS(knet_link_set_priority(knet_h1, 1, KNET_MAX_LINK, 2), EINVAL);
+ 
+ 	printf("Test knet_link_set_priority with unconfigured link\n");
+-
+-	if ((!knet_link_set_priority(knet_h, 1, 0, 1)) || (errno != EINVAL)) {
+-		printf("knet_link_set_priority accepted unconfigured link or returned incorrect error: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_link_set_priority(knet_h1, 1, 0, 1), EINVAL);
+ 
+ 	printf("Test knet_link_set_priority with correct values\n");
+-
+-	if (knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_priority(knet_h, 1, 0, 3) < 0) {
+-		printf("knet_link_set_priority failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->host_index[1]->link[0].priority != 3) {
++	FAIL_ON_ERR(knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, &src, &dst, 0));
++	FAIL_ON_ERR(knet_link_set_priority(knet_h1, 1, 0, 3));
++	if (knet_h1->host_index[1]->link[0].priority != 3) {
+ 		printf("knet_link_set_priority failed to set correct values\n");
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_log_get_loglevel.c b/libknet/tests/api_knet_log_get_loglevel.c
+index 1725bff0..40d1d545 100644
+--- a/libknet/tests/api_knet_log_get_loglevel.c
++++ b/libknet/tests/api_knet_log_get_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	uint8_t level;
+ 	int logfds[2];
+ 
+@@ -35,54 +36,22 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_INFO, knet_h);
+ 
+ 	printf("Test knet_log_get_loglevel incorrect subsystem\n");
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_INFO);
+-
+-	if ((!knet_log_get_loglevel(knet_h, KNET_SUB_UNKNOWN - 1, &level)) || (errno != EINVAL)) {
+-		printf("knet_log_get_loglevel accepted invalid subsystem or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_log_get_loglevel(knet_h1, KNET_SUB_UNKNOWN - 1, &level), EINVAL);
+ 
+ 	printf("Test knet_log_get_loglevel incorrect log level\n");
+-
+-	if ((!knet_log_get_loglevel(knet_h, KNET_SUB_UNKNOWN, NULL)) || (errno != EINVAL)) {
+-		printf("knet_log_get_loglevel accepted invalid log level or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_log_get_loglevel(knet_h1, KNET_SUB_UNKNOWN, NULL), EINVAL);
+ 
+ 	printf("Test knet_log_get_loglevel with valid parameters\n");
+-
+-	if (knet_log_get_loglevel(knet_h, KNET_SUB_UNKNOWN, &level ) < 0) {
+-		printf("knet_log_get_loglevel failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_h->log_levels[KNET_SUB_UNKNOWN] != level) {
++	FAIL_ON_ERR(knet_log_get_loglevel(knet_h1, KNET_SUB_UNKNOWN, &level));
++	if (knet_h1->log_levels[KNET_SUB_UNKNOWN] != level) {
+ 		printf("knet_log_get_loglevel failed to get the right value\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_log_get_loglevel_id.c b/libknet/tests/api_knet_log_get_loglevel_id.c
+index f4212124..8d474a4d 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_id.c
++++ b/libknet/tests/api_knet_log_get_loglevel_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_loglevel_name.c b/libknet/tests/api_knet_log_get_loglevel_name.c
+index 713060d4..dce9ad77 100644
+--- a/libknet/tests/api_knet_log_get_loglevel_name.c
++++ b/libknet/tests/api_knet_log_get_loglevel_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_id.c b/libknet/tests/api_knet_log_get_subsystem_id.c
+index 0dd0ee0c..8f9c89ed 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_id.c
++++ b/libknet/tests/api_knet_log_get_subsystem_id.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_get_subsystem_name.c b/libknet/tests/api_knet_log_get_subsystem_name.c
+index 37bfa8b3..b82d6d4b 100644
+--- a/libknet/tests/api_knet_log_get_subsystem_name.c
++++ b/libknet/tests/api_knet_log_get_subsystem_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/api_knet_log_set_loglevel.c b/libknet/tests/api_knet_log_set_loglevel.c
+index b5d75358..a0753564 100644
+--- a/libknet/tests/api_knet_log_set_loglevel.c
++++ b/libknet/tests/api_knet_log_set_loglevel.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -23,7 +23,8 @@
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
++	int res;
+ 	int logfds[2];
+ 
+ 	printf("Test knet_log_set_loglevel incorrect knet_h\n");
+@@ -34,62 +35,25 @@ static void test(void)
+ 	}
+ 
+ 	setup_logpipes(logfds);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_INFO, knet_h);
+ 
+ 	printf("Test knet_log_set_loglevel incorrect subsystem\n");
+-
+-	knet_h = knet_handle_start(logfds, KNET_LOG_INFO);
+-
+-	if ((!knet_log_set_loglevel(knet_h, KNET_SUB_UNKNOWN - 1, KNET_LOG_DEBUG)) || (errno != EINVAL)) {
+-		printf("knet_log_set_loglevel accepted invalid subsystem or returned incorrect error: %s\n", strerror(errno));
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		knet_handle_free(knet_h);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_log_set_loglevel(knet_h1, KNET_SUB_UNKNOWN - 1, KNET_LOG_DEBUG), EINVAL);
+ 
+ 	printf("Test knet_log_set_loglevel incorrect log level\n");
+-
+-	if ((!knet_log_set_loglevel(knet_h, KNET_SUB_UNKNOWN, KNET_LOG_DEBUG + 1)) || (errno != EINVAL)) {
+-		printf("knet_log_set_loglevel accepted invalid log level or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_log_set_loglevel(knet_h1, KNET_SUB_UNKNOWN, KNET_LOG_DEBUG + 1), EINVAL);
+ 
+ 	printf("Test knet_log_set_loglevel with valid parameters\n");
+-
+-	if (knet_h->log_levels[KNET_SUB_UNKNOWN] != KNET_LOG_INFO) {
++	if (knet_h1->log_levels[KNET_SUB_UNKNOWN] != KNET_LOG_INFO) {
+ 		printf("knet_handle_new did not init log_levels correctly?\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_log_set_loglevel(knet_h, KNET_SUB_UNKNOWN, KNET_LOG_DEBUG) < 0) {
+-		printf("knet_log_set_loglevel failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	if (knet_h->log_levels[KNET_SUB_UNKNOWN] != KNET_LOG_DEBUG) {
++	FAIL_ON_ERR(knet_log_set_loglevel(knet_h1, KNET_SUB_UNKNOWN, KNET_LOG_DEBUG));
++	if (knet_h1->log_levels[KNET_SUB_UNKNOWN] != KNET_LOG_DEBUG) {
+ 		printf("knet_log_set_loglevel did not set log level correctly\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_recv.c b/libknet/tests/api_knet_recv.c
+index 09718bdc..1bf3e843 100644
+--- a/libknet/tests/api_knet_recv.c
++++ b/libknet/tests/api_knet_recv.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -34,17 +34,17 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+ 	char recv_buff[KNET_MAX_PACKET_SIZE];
+ 	char send_buff[KNET_MAX_PACKET_SIZE];
+ 	ssize_t recv_len = 0;
++	int res;
+ 	struct iovec iov_out[1];
+ 
+ 	printf("Test knet_recv incorrect knet_h\n");
+-
+ 	if ((!knet_recv(NULL, recv_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+ 		printf("knet_recv accepted invalid knet_h or returned incorrect error: %s\n", strerror(errno));
+ 		exit(FAIL);
+@@ -52,106 +52,37 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_recv with no recv_buff\n");
+-
+-	if ((!knet_recv(knet_h, NULL, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_recv accepted invalid recv_buff or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_recv(knet_h1, NULL, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_recv with invalid recv_buff len (0)\n");
+-
+-	if ((!knet_recv(knet_h, recv_buff, 0, channel)) || (errno != EINVAL)) {
+-		printf("knet_recv accepted invalid recv_buff len (0) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_recv(knet_h1, recv_buff, 0, channel), EINVAL);
+ 
+ 	printf("Test knet_recv with invalid recv_buff len (> KNET_MAX_PACKET_SIZE)\n");
+-
+-	if ((!knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE + 1, channel)) || (errno != EINVAL)) {
+-		printf("knet_recv accepted invalid recv_buff len (> KNET_MAX_PACKET_SIZE) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE + 1, channel), EINVAL);
+ 
+ 	printf("Test knet_recv with invalid channel (-1)\n");
+-
+ 	channel = -1;
+-
+-	if ((!knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_recv accepted invalid channel (-1) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_recv with invalid channel (KNET_DATAFD_MAX)\n");
+-
+ 	channel = KNET_DATAFD_MAX;
+-
+-	if ((!knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_recv accepted invalid channel (KNET_DATAFD_MAX) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_recv with unconfigured channel\n");
+-
+ 	channel = 0;
+ 
+-	if ((!knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_recv accepted invalid unconfigured channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_recv with valid data\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+ 	memset(recv_buff, 0, KNET_MAX_PACKET_SIZE);
+ 	memset(send_buff, 1, sizeof(send_buff));
+@@ -159,44 +90,27 @@ static void test(void)
+ 	iov_out[0].iov_base = (void *)send_buff;
+ 	iov_out[0].iov_len = sizeof(send_buff);
+ 
+-	if (writev(knet_h->sockfd[channel].sockfd[1], iov_out, 1) != sizeof(send_buff)) {
++	if (writev(knet_h1->sockfd[channel].sockfd[1], iov_out, 1) != sizeof(send_buff)) {
+ 		printf("Unable to write data: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (recv_len <= 0) {
+ 		printf("knet_recv failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (recv_len != sizeof(send_buff)) {
+ 		printf("knet_recv received only %zd bytes: %s\n", recv_len, strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("knet_recv received bad data\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_send.c b/libknet/tests/api_knet_send.c
+index a3b5aa49..f15b59ae 100644
+--- a/libknet/tests/api_knet_send.c
++++ b/libknet/tests/api_knet_send.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -35,7 +35,7 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(uint8_t transport)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -45,6 +45,7 @@ static void test(uint8_t transport)
+ 	ssize_t send_len = 0;
+ 	int recv_len = 0;
+ 	int savederrno;
++	int res;
+ 	struct sockaddr_storage lo;
+ 
+ 	memset(send_buff, 0, sizeof(send_buff));
+@@ -58,259 +59,82 @@ static void test(uint8_t transport)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+-	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
+-		printf("Cannot enable access lists: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h1, 1));
+ 
+ 	printf("Test knet_send with no send_buff\n");
+-
+-	if ((!knet_send(knet_h, NULL, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send accepted invalid send_buff or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send(knet_h1, NULL, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send with invalid send_buff len (0)\n");
+-
+-	if ((!knet_send(knet_h, send_buff, 0, channel)) || (errno != EINVAL)) {
+-		printf("knet_send accepted invalid send_buff len (0) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send(knet_h1, send_buff, 0, channel), EINVAL);
+ 
+ 	printf("Test knet_send with invalid send_buff len (> KNET_MAX_PACKET_SIZE)\n");
+-
+-	if ((!knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE + 1, channel)) || (errno != EINVAL)) {
+-		printf("knet_send accepted invalid send_buff len (> KNET_MAX_PACKET_SIZE) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE + 1, channel), EINVAL);
+ 
+ 	printf("Test knet_send with invalid channel (-1)\n");
+-
+ 	channel = -1;
+-
+-	if ((!knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send accepted invalid channel (-1) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send with invalid channel (KNET_DATAFD_MAX)\n");
+-
+ 	channel = KNET_DATAFD_MAX;
+-
+-	if ((!knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send accepted invalid channel (KNET_DATAFD_MAX) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send with unconfigured channel\n");
+-
+ 	channel = 0;
+-
+-	if ((!knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send accepted invalid unconfigured channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send with valid data\n");
+-
+-	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
+-		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h1, 1));
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, transport, 0, AF_INET, 0, &lo) < 0 ) {
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	if (_knet_link_set_config(knet_h1, 1, 0, transport, 0, AF_INET, 0, &lo) < 0 ) {
+ 		int exit_status = transport == KNET_TRANSPORT_SCTP && errno == EPROTONOSUPPORT ? SKIP : FAIL;
+ 		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(exit_status);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(exit_status);
+ 	}
+ 
+-	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 10, logfds[0], stdout));
+ 
+-	send_len = knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel);
++	send_len = knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (send_len <= 0) {
+ 		printf("knet_send failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (send_len != sizeof(send_buff) - 1) {
+ 		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+-		printf("Error waiting for packet: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
++	FAIL_ON_ERR(wait_for_packet(knet_h1, 10, datafd, logfds[0], stdout));
+ 
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	savederrno = errno;
+ 	if (recv_len != send_len) {
+ 		printf("knet_recv received only %d bytes: %s (errno: %d)\n", recv_len, strerror(errno), errno);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+ 		if ((is_helgrind()) && (recv_len == -1) && (savederrno == EAGAIN)) {
+ 			printf("helgrind exception. this is normal due to possible timeouts\n");
+-			exit(PASS);
++			CLEAN_EXIT(PASS);
+ 		}
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("recv and send buffers are different!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	/* A sanity check on the stats */
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(link_status)) < 0) {
+-		printf("knet_link_get_status failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(link_status)));
+ 
+ 	if (link_status.stats.tx_data_packets != 2 ||
+ 	    link_status.stats.rx_data_packets != 2 ||
+@@ -325,41 +149,18 @@ static void test(uint8_t transport)
+ 		   link_status.stats.rx_data_bytes);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
+ 
+ 	printf("try to send big packet to local datafd (bypass knet_send)\n");
+ 	if (write(datafd, &send_buff, sizeof(send_buff)) != KNET_MAX_PACKET_SIZE + 1) {
+ 		printf("Error writing to datafd: %s\n", strerror(errno));
+ 	}
+ 
+-	if (!wait_for_packet(knet_h, 2, datafd, logfds[0], stdout)) {
++	if (!wait_for_packet(knet_h1, 2, datafd, logfds[0], stdout)) {
+ 		printf("Received unexpected packet!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_send_compress.c b/libknet/tests/api_knet_send_compress.c
+index 36b9160f..4758170b 100644
+--- a/libknet/tests/api_knet_send_compress.c
++++ b/libknet/tests/api_knet_send_compress.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -36,7 +36,7 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(const char *model)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -46,6 +46,7 @@ static void test(const char *model)
+ 	ssize_t send_len = 0;
+ 	int recv_len = 0;
+ 	int savederrno;
++	int res;
+ 	struct sockaddr_storage lo;
+ 	struct knet_handle_compress_cfg knet_handle_compress_cfg;
+ 
+@@ -53,7 +54,7 @@ static void test(const char *model)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+@@ -64,170 +65,58 @@ static void test(const char *model)
+ 	knet_handle_compress_cfg.compress_level = 4;
+ 	knet_handle_compress_cfg.compress_threshold = 0;
+ 
+-	if (knet_handle_compress(knet_h, &knet_handle_compress_cfg) < 0) {
+-		printf("knet_handle_compress did not accept zlib compress mode with compress level 1 cfg\n");
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_compress(knet_h1, &knet_handle_compress_cfg));
++
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
+ 
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
+ 
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
+ 
+-	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 10, logfds[0], stdout));
+ 
+-	send_len = knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel);
++	send_len = knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (send_len <= 0) {
+ 		printf("knet_send failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (send_len != sizeof(send_buff)) {
+ 		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
+ 
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_packet(knet_h1, 10, datafd, logfds[0], stdout));
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+-		printf("Error waiting for packet: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	savederrno = errno;
+ 	if (recv_len != send_len) {
+ 		printf("knet_recv received only %d bytes: %s (errno: %d)\n", recv_len, strerror(errno), errno);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+ 		if ((is_helgrind()) && (recv_len == -1) && (savederrno == EAGAIN)) {
+ 			printf("helgrind exception. this is normal due to possible timeouts\n");
+-			exit(PASS);
++			CLEAN_EXIT(PASS);
+ 		}
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("recv and send buffers are different!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	/* A sanity check on the stats */
+-	if (knet_handle_get_stats(knet_h, &stats, sizeof(stats)) < 0) {
+-		printf("knet_handle_get_stats failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_get_stats(knet_h1, &stats, sizeof(stats)));
+ 
+ 	if (strcmp(model, "none") == 0) {
+ 		if (stats.tx_compressed_packets != 0 ||
+@@ -256,14 +145,7 @@ static void test(const char *model)
+ 
+ 		}
+ 	}
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_send_crypto.c b/libknet/tests/api_knet_send_crypto.c
+index 2460afd3..d5ff3302 100644
+--- a/libknet/tests/api_knet_send_crypto.c
++++ b/libknet/tests/api_knet_send_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -36,7 +36,7 @@ static void sock_notify(void *pvt_data,
+ 
+ static void test(const char *model)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -46,6 +46,7 @@ static void test(const char *model)
+ 	ssize_t send_len = 0;
+ 	int recv_len = 0;
+ 	int savederrno;
++	int res;
+ 	struct sockaddr_storage lo;
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 
+@@ -53,7 +54,7 @@ static void test(const char *model)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+@@ -65,167 +66,60 @@ static void test(const char *model)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, "sha256", sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_crypto(knet_h1, &knet_handle_crypto_cfg))
++
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
+ 
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
+ 
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
+ 
+-	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 10, logfds[0], stdout));
+ 
+-	send_len = knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel);
++	send_len = knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (send_len <= 0) {
+ 		printf("knet_send failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (send_len != sizeof(send_buff)) {
+ 		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
+ 
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+-		printf("Error waiting for packet: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_packet(knet_h1, 10, datafd, logfds[0], stdout));
+ 
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	savederrno = errno;
+ 	if (recv_len != send_len) {
+ 		printf("knet_recv received only %d bytes: %s (errno: %d)\n", recv_len, strerror(errno), errno);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+ 		if ((is_helgrind()) && (recv_len == -1) && (savederrno == EAGAIN)) {
+ 			printf("helgrind exception. this is normal due to possible timeouts\n");
+-			exit(PASS);
++			CLEAN_EXIT(PASS);
+ 		}
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("recv and send buffers are different!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	/* A sanity check on the stats */
+-	if (knet_handle_get_stats(knet_h, &stats, sizeof(stats)) < 0) {
++	if (knet_handle_get_stats(knet_h1, &stats, sizeof(stats)) < 0) {
+ 		printf("knet_handle_get_stats failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (stats.tx_crypt_packets >= 1 ||
+@@ -234,15 +128,7 @@ static void test(const char *model)
+ 		       stats.tx_crypt_packets,
+ 		       stats.rx_crypt_packets);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_send_loopback.c b/libknet/tests/api_knet_send_loopback.c
+index c3ef5047..cf2d33c6 100644
+--- a/libknet/tests/api_knet_send_loopback.c
++++ b/libknet/tests/api_knet_send_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -52,7 +52,7 @@ static int dhost_filter(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -62,252 +62,88 @@ static void test(void)
+ 	ssize_t send_len = 0;
+ 	int recv_len = 0;
+ 	int savederrno;
++	int res;
+ 	struct sockaddr_storage lo;
+ 
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test configuring multiple links with loopback\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) == 0) {
++	if (_knet_link_set_config(knet_h1, 1, 1, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) == 0) {
+ 		printf("Managed to configure two LOOPBACK links - this is wrong\n");
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+ 	printf("Test configuring UDP link after loopback\n");
+ 
+-	if (_knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) == 0) {
++	if (_knet_link_set_config(knet_h1, 1, 1, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) == 0) {
+ 		printf("Managed to configure UDP and LOOPBACK links together: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+ 	printf("Test configuring UDP link before loopback\n");
+-
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Failed to clear existing LOOPBACK link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Failed to configure UDP link for testing: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 1, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) == 0) {
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	if (_knet_link_set_config(knet_h1, 1, 1, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) == 0) {
+ 		printf("Managed to configure LOOPBACK link after UDP: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+-
+-	flush_logs(logfds[0], stdout);
+ 	printf("Test knet_send with valid data\n");
+ 
+-	if (knet_handle_enable_access_lists(knet_h, 1) < 0) {
+-		printf("knet_handle_enable_access_lists failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_clear_config(knet_h, 1, 0) < 0) {
+-		printf("Failed to clear existing UDP link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Failed configure LOOPBACK link for sending: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h1, 1));
++	FAIL_ON_ERR(knet_link_clear_config(knet_h1, 1, 0));
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_LOOPBACK, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 10, logfds[0], stdout));
+ 
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	send_len = knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel);
++	send_len = knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (send_len <= 0) {
+ 		printf("knet_send failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (send_len != sizeof(send_buff)) {
+ 		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
+ 
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_packet(knet_h1, 10, datafd, logfds[0], stdout))
+ 
+-	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+-		printf("Error waiting for packet: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	savederrno = errno;
+ 	if (recv_len != send_len) {
+ 		printf("knet_recv received only %d bytes: %s (errno: %d)\n", recv_len, strerror(errno), errno);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+ 		if ((is_helgrind()) && (recv_len == -1) && (savederrno == EAGAIN)) {
+ 			printf("helgrind exception. this is normal due to possible timeouts\n");
+-			exit(PASS);
++			CLEAN_EXIT(PASS);
+ 		}
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("recv and send buffers are different!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	/* A sanity check on the stats */
+-	if (knet_link_get_status(knet_h, 1, 0, &link_status, sizeof(link_status)) < 0) {
+-		printf("knet_link_get_status failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_get_status(knet_h1, 1, 0, &link_status, sizeof(link_status)));
+ 
+ 	if (link_status.stats.tx_data_packets != 1 ||
+ 	    link_status.stats.rx_data_packets != 0 ||
+@@ -319,113 +155,41 @@ static void test(void)
+ 		   link_status.stats.rx_data_bytes);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+-
+ 	printf("Test knet_send with only localhost\n");
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h1, NULL, dhost_filter));
+ 
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-	send_len = knet_send(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel);
++	send_len = knet_send(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	if (send_len <= 0) {
+ 		printf("knet_send failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (send_len != sizeof(send_buff)) {
+ 		printf("knet_send sent only %zd bytes: %s\n", send_len, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	if (wait_for_packet(knet_h, 10, datafd, logfds[0], stdout)) {
+-		printf("Error waiting for packet: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
++	FAIL_ON_ERR(wait_for_packet(knet_h1, 10, datafd, logfds[0], stdout));
+ 
+-	recv_len = knet_recv(knet_h, recv_buff, KNET_MAX_PACKET_SIZE, channel);
++	recv_len = knet_recv(knet_h1, recv_buff, KNET_MAX_PACKET_SIZE, channel);
+ 	savederrno = errno;
+ 	if (recv_len != send_len) {
+ 		printf("knet_recv received only %d bytes: %s (errno: %d)\n", recv_len, strerror(errno), errno);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+ 		if ((is_helgrind()) && (recv_len == -1) && (savederrno == EAGAIN)) {
+ 			printf("helgrind exception. this is normal due to possible timeouts\n");
+-			exit(PASS);
++			CLEAN_EXIT(PASS);
+ 		}
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+ 	if (memcmp(recv_buff, send_buff, KNET_MAX_PACKET_SIZE)) {
+ 		printf("recv and send buffers are different!\n");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_send_sync.c b/libknet/tests/api_knet_send_sync.c
+index 9994c36e..5f916499 100644
+--- a/libknet/tests/api_knet_send_sync.c
++++ b/libknet/tests/api_knet_send_sync.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -94,12 +94,13 @@ static int dhost_filter(void *pvt_data,
+ 
+ static void test(void)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h1, knet_h[2];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+ 	char send_buff[KNET_MAX_PACKET_SIZE];
+ 	struct sockaddr_storage lo;
++	int res;
+ 
+ 	memset(send_buff, 0, sizeof(send_buff));
+ 
+@@ -112,293 +113,96 @@ static void test(void)
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h1 = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	printf("Test knet_send_sync with no send_buff\n");
+-
+-	if ((!knet_send_sync(knet_h, NULL, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send_sync accepted invalid send_buff or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, NULL, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send_sync with invalid send_buff len (0)\n");
+-
+-	if ((!knet_send_sync(knet_h, send_buff, 0, channel)) || (errno != EINVAL)) {
+-		printf("knet_send_sync accepted invalid send_buff len (0) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, send_buff, 0, channel), EINVAL);
+ 
+ 	printf("Test knet_send_sync with invalid send_buff len (> KNET_MAX_PACKET_SIZE)\n");
+-
+-	if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE + 1, channel)) || (errno != EINVAL)) {
+-		printf("knet_send_sync accepted invalid send_buff len (> KNET_MAX_PACKET_SIZE) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE + 1, channel), EINVAL);
+ 
+ 	printf("Test knet_send_sync with invalid channel (-1)\n");
+-
+ 	channel = -1;
+-
+-	if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send_sync accepted invalid channel (-1) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send_sync with invalid channel (KNET_DATAFD_MAX)\n");
+-
+ 	channel = KNET_DATAFD_MAX;
+-
+-	if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send_sync accepted invalid channel (KNET_DATAFD_MAX) or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send_sync with no filter configured\n");
+-
+ 	channel = 1;
+-	if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != ENETDOWN)) {
+-		printf("knet_send_sync Did not return ENETDOWN for no filter installed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_handle_enable_filter(knet_h, NULL, dhost_filter) < 0) {
+-		printf("knet_handle_enable_filter failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), ENETDOWN);
++	FAIL_ON_ERR(knet_handle_enable_filter(knet_h1, NULL, dhost_filter));
+ 
+ 
+ 	printf("Test knet_send_sync with unconfigured channel\n");
+-
+ 	channel = 0;
+-
+-	if ((!knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel)) || (errno != EINVAL)) {
+-		printf("knet_send_sync accepted invalid unconfigured channel or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
++	FAIL_ON_SUCCESS(knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel), EINVAL);
+ 
+ 	printf("Test knet_send_sync with data forwarding disabled\n");
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h1, &private_data, sock_notify));
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h1, &datafd, &channel));
+ 
+-	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != ECANCELED)) {
++	if ((knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != ECANCELED)) {
+ 		printf("knet_send_sync didn't detect datafwd disabled or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_send_sync with broken dst_host_filter\n");
+-
+-	if (knet_handle_setfwd(knet_h, 1) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 1));
+ 	dhost_filter_ret = -1;
+-
+-	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EFAULT)) {
++	if ((knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EFAULT)) {
+ 		printf("knet_send_sync didn't detect fatal error from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_send_sync with dst_host_filter returning no host_ids_entries\n");
+-
+ 	dhost_filter_ret = 0;
+-
+-	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EINVAL)) {
++	if ((knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EINVAL)) {
+ 		printf("knet_send_sync didn't detect 0 host_ids from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_send_sync with host down\n");
+-
+ 	dhost_filter_ret = 1;
+-
+-	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EHOSTDOWN)) {
++	if ((knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != EHOSTDOWN)) {
+ 		printf("knet_send_sync didn't detect hostdown or returned incorrect error: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_send_sync with dst_host_filter returning too many host_ids_entries\n");
+-
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	if (wait_for_host(knet_h, 1, 10, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
++	FAIL_ON_ERR(knet_host_add(knet_h1, 1));
++	FAIL_ON_ERR(_knet_link_set_config(knet_h1, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
++	FAIL_ON_ERR(knet_link_set_enable(knet_h1, 1, 0, 1));
++	FAIL_ON_ERR(wait_for_host(knet_h1, 1, 10, logfds[0], stdout));
+ 	dhost_filter_ret = 2;
+-
+-	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != E2BIG)) {
++	if ((knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != E2BIG)) {
+ 		printf("knet_send_sync didn't detect 2+ host_ids from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+-
+ 	printf("Test knet_send_sync with dst_host_filter returning mcast packets\n");
+-
+ 	dhost_filter_ret = 3;
+-
+-	if ((knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != E2BIG)) {
++	if ((knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel) == sizeof(send_buff)) || (errno != E2BIG)) {
+ 		printf("knet_send_sync didn't detect mcast packet from dst_host_filter or returned incorrect error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
++		CLEAN_EXIT(FAIL);
+ 	}
+ 
+-	flush_logs(logfds[0], stdout);
+ 
+ 	printf("Test knet_send_sync with valid data\n");
+-
+ 	dhost_filter_ret = 1;
++	FAIL_ON_ERR(knet_send_sync(knet_h1, send_buff, KNET_MAX_PACKET_SIZE, channel));
+ 
+-	if (knet_send_sync(knet_h, send_buff, KNET_MAX_PACKET_SIZE, channel) < 0) {
+-		printf("knet_send_sync failed: %d %s\n", errno, strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
+-
+-	flush_logs(logfds[0], stdout);
+-
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_setfwd(knet_h1, 0));
+ 
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
++	CLEAN_EXIT(CONTINUE);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/api_knet_strtoaddr.c b/libknet/tests/api_knet_strtoaddr.c
+index 235c1d51..b058266e 100644
+--- a/libknet/tests/api_knet_strtoaddr.c
++++ b/libknet/tests/api_knet_strtoaddr.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/fun_acl_check.c b/libknet/tests/fun_acl_check.c
+index 55cf09bb..8de50f77 100644
+--- a/libknet/tests/fun_acl_check.c
++++ b/libknet/tests/fun_acl_check.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2021-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Christine Caulfield <ccaulfie@redhat.com>
+  *
+@@ -31,6 +31,7 @@
+ #define CORRECT_NUM_MSGS 5
+ static int msgs_recvd = 0;
+ 
++#undef TESTNODES
+ #define TESTNODES 2
+ 
+ static pthread_mutex_t recv_mutex = PTHREAD_MUTEX_INITIALIZER;
+@@ -38,7 +39,8 @@ static int quit_recv_thread = 0;
+ 
+ static int reply_pipe[2];
+ 
+-#define FAIL_ON_ERR(fn) \
++/* Our local version of FOE that also tidies up the threads */
++#define FAIL_ON_ERR_THR(fn) \
+ 	printf("FOE: %s\n", #fn);			  \
+ 	if ((res = fn) != 0) {				  \
+ 	  int savederrno = errno;			  \
+@@ -46,9 +48,9 @@ static int reply_pipe[2];
+ 	  quit_recv_thread = 1;				  \
+ 	  pthread_mutex_unlock(&recv_mutex);		  \
+ 	  if (recv_thread) {				  \
+-		  pthread_join(recv_thread, (void**)&thread_err); \
++		  pthread_join(recv_thread, (void**)&thread_err);	\
+ 	  }						  \
+-	  knet_handle_stop_nodes(knet_h, TESTNODES);	  \
++	  knet_handle_stop_everything(knet_h, TESTNODES); \
+ 	  stop_logthread();				  \
+ 	  flush_logs(logfds[0], stdout);		  \
+ 	  close_logpipes(logfds);			  \
+@@ -62,6 +64,7 @@ static int reply_pipe[2];
+ 	  }						  \
+ 	}
+ 
++
+ static int knet_send_str(knet_handle_t knet_h, char *str)
+ {
+ 	return knet_send_sync(knet_h, str, strlen(str)+1, 0);
+@@ -251,7 +254,7 @@ static void test(int transport)
+ 	memset(reply_pipe, 0, sizeof(reply_pipe));
+ 	memset(logfds, 0, sizeof(logfds));
+ 
+-	FAIL_ON_ERR(pipe(reply_pipe));
++	FAIL_ON_ERR_THR(pipe(reply_pipe));
+ 
+ 	// Initial setup gubbins
+ 	msgs_recvd = 0;
+@@ -259,38 +262,38 @@ static void test(int transport)
+ 	start_logthread(logfds[1], stdout);
+ 	knet_handle_start_nodes(knet_h, TESTNODES, logfds, KNET_LOG_DEBUG);
+ 
+-	FAIL_ON_ERR(knet_host_add(knet_h[2], 1));
+-	FAIL_ON_ERR(knet_host_add(knet_h[1], 2));
++	FAIL_ON_ERR_THR(knet_host_add(knet_h[2], 1));
++	FAIL_ON_ERR_THR(knet_host_add(knet_h[1], 2));
+ 
+-	FAIL_ON_ERR(knet_handle_enable_filter(knet_h[2], NULL, dhost_filter));
++	FAIL_ON_ERR_THR(knet_handle_enable_filter(knet_h[2], NULL, dhost_filter));
+ 
+ 	// Create the dynamic (receiving) link
+-	FAIL_ON_ERR(dyn_knet_link_set_config(knet_h[1], 2, 0, transport, 0, AF_INET, 1, &lo0, NULL));
++	FAIL_ON_ERR_THR(dyn_knet_link_set_config(knet_h[1], 2, 0, transport, 0, AF_INET, 1, &lo0, NULL));
+ 
+ 	// Connect to the dynamic link
+-	FAIL_ON_ERR(dyn_knet_link_set_config(knet_h[2], 1, 0, transport, 0, AF_INET, 0, &lo1, &lo0));
++	FAIL_ON_ERR_THR(dyn_knet_link_set_config(knet_h[2], 1, 0, transport, 0, AF_INET, 0, &lo1, &lo0));
+ 
+ 	// All the rest of the setup gubbins
+-	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h[1], 0, &notify_fn));
+-	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h[2], 0, &notify_fn));
++	FAIL_ON_ERR_THR(knet_handle_enable_sock_notify(knet_h[1], 0, &notify_fn));
++	FAIL_ON_ERR_THR(knet_handle_enable_sock_notify(knet_h[2], 0, &notify_fn));
+ 
+ 	channel = datafd = 0;
+-	FAIL_ON_ERR(knet_handle_add_datafd(knet_h[1], &datafd, &channel));
++	FAIL_ON_ERR_THR(knet_handle_add_datafd(knet_h[1], &datafd, &channel));
+ 	channel = datafd = 0;
+-	FAIL_ON_ERR(knet_handle_add_datafd(knet_h[2], &datafd, &channel));
++	FAIL_ON_ERR_THR(knet_handle_add_datafd(knet_h[2], &datafd, &channel));
+ 
+-	FAIL_ON_ERR(knet_link_set_enable(knet_h[1], 2, 0, 1));
+-	FAIL_ON_ERR(knet_link_set_enable(knet_h[2], 1, 0, 1));
++	FAIL_ON_ERR_THR(knet_link_set_enable(knet_h[1], 2, 0, 1));
++	FAIL_ON_ERR_THR(knet_link_set_enable(knet_h[2], 1, 0, 1));
+ 
+-	FAIL_ON_ERR(knet_handle_setfwd(knet_h[1], 1));
+-	FAIL_ON_ERR(knet_handle_setfwd(knet_h[2], 1));
++	FAIL_ON_ERR_THR(knet_handle_setfwd(knet_h[1], 1));
++	FAIL_ON_ERR_THR(knet_handle_setfwd(knet_h[2], 1));
+ 
+ 	// Start receive thread
+-	FAIL_ON_ERR(pthread_create(&recv_thread, NULL, recv_messages, (void *)knet_h[1]));
++	FAIL_ON_ERR_THR(pthread_create(&recv_thread, NULL, recv_messages, (void *)knet_h[1]));
+ 
+ 	// Let everything settle down
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
+ 
+ 	/*
+ 	 * TESTING STARTS HERE
+@@ -300,99 +303,91 @@ static void test(int transport)
+ 
+ 	// No ACL
+ 	printf("Testing No ACL - this should get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "1No ACL - this should get through"));
+-	FAIL_ON_ERR(wait_for_reply(seconds))
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "1No ACL - this should get through"));
++	FAIL_ON_ERR_THR(wait_for_reply(seconds))
+ 
+ 	// Block traffic from this address.
+ 	memset(&ss1, 0, sizeof(ss1));
+ 	memset(&ss2, 0, sizeof(ss1));
+ 	knet_strtoaddr("127.0.0.1","0", &ss1, sizeof(ss1));
+-	FAIL_ON_ERR(knet_link_add_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
++	FAIL_ON_ERR_THR(knet_link_add_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
+ 	// Accept ACL for when we remove them
+-	FAIL_ON_ERR(knet_link_add_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
++	FAIL_ON_ERR_THR(knet_link_add_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_ACCEPT));
+ 
+ 	// This needs to go after the first ACLs are added
+-	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h[1], 1));
++	FAIL_ON_ERR_THR(knet_handle_enable_access_lists(knet_h[1], 1));
+ 
+ 	printf("Testing Address blocked - this should NOT get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "0Address blocked - this should NOT get through"));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "0Address blocked - this should NOT get through"));
+ 
+ 	// Unblock and check again
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, NULL, CHECK_TYPE_ADDRESS, CHECK_REJECT));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
+ 
+ 	printf("Testing Address unblocked - this should get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "1Address unblocked - this should get through"));
+-	FAIL_ON_ERR(wait_for_reply(seconds));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "1Address unblocked - this should get through"));
++	FAIL_ON_ERR_THR(wait_for_reply(seconds));
+ 
+ 	// Block traffic using a netmask
+ 	knet_strtoaddr("127.0.0.1","0", &ss1, sizeof(ss1));
+ 	knet_strtoaddr("255.0.0.1","0", &ss2, sizeof(ss2));
+-	FAIL_ON_ERR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
++	FAIL_ON_ERR_THR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
+ 
+ 	printf("Testing Netmask blocked - this should NOT get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "0Netmask blocked - this should NOT get through"));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "0Netmask blocked - this should NOT get through"));
+ 
+ 	// Unblock and check again
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_MASK, CHECK_REJECT));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
+ 
+ 	printf("Testing Netmask unblocked - this should get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "1Netmask unblocked - this should get through"));
+-	FAIL_ON_ERR(wait_for_reply(seconds));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "1Netmask unblocked - this should get through"));
++	FAIL_ON_ERR_THR(wait_for_reply(seconds));
+ 
+ 	// Block traffic from a range
+ 	knet_strtoaddr("127.0.0.0", "0", &ss1, sizeof(ss1));
+ 	knet_strtoaddr("127.0.0.9", "0", &ss2, sizeof(ss2));
+-	FAIL_ON_ERR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
++	FAIL_ON_ERR_THR(knet_link_insert_acl(knet_h[1], 2, 0, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
+ 
+ 	printf("Testing Range blocked - this should NOT get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "0Range blocked - this should NOT get through"));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "0Range blocked - this should NOT get through"));
+ 
+ 	// Unblock and check again
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 0, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(knet_link_rm_acl(knet_h[1], 2, 0, &ss1, &ss2, CHECK_TYPE_RANGE, CHECK_REJECT));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
+ 
+ 	printf("Testing Range unblocked - this should get through\n");
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "1Range unblocked - this should get through"));
+-	FAIL_ON_ERR(wait_for_reply(seconds));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "1Range unblocked - this should get through"));
++	FAIL_ON_ERR_THR(wait_for_reply(seconds));
+ 
+ 	// Finish up - disable ACLS to make sure the QUIT message gets through
+-	FAIL_ON_ERR(knet_handle_enable_access_lists(knet_h[1], 0));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
+-	FAIL_ON_ERR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(knet_handle_enable_access_lists(knet_h[1], 0));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[1], TESTNODES, 1, seconds, logfds[0], stdout));
++	FAIL_ON_ERR_THR(wait_for_nodes_state(knet_h[2], TESTNODES, 1, seconds, logfds[0], stdout));
+ 
+-	FAIL_ON_ERR(knet_send_str(knet_h[2], "QUIT"));
++	FAIL_ON_ERR_THR(knet_send_str(knet_h[2], "QUIT"));
+ 
+ 	// Check return from the receiving thread
+ 	pthread_join(recv_thread, (void**)&thread_err);
+ 	if (*thread_err) {
+ 		printf("Thread returned %d\n", *thread_err);
+-		exit(FAIL);
++		clean_exit(knet_h, TESTNODES, logfds, FAIL);
+ 	}
+ 
+-	//  Tidy Up
+-	knet_handle_stop_nodes(knet_h, TESTNODES);
+-
+-	stop_logthread();
+-	flush_logs(logfds[0], stdout);
+-	close_logpipes(logfds);
+-	close(reply_pipe[0]);
+-	close(reply_pipe[1]);
+-
+ 	if (msgs_recvd != CORRECT_NUM_MSGS) {
+ 		printf("*** FAIL Recv thread got %d messages, expected %d\n", msgs_recvd, CORRECT_NUM_MSGS);
+-		exit(FAIL);
++		clean_exit(knet_h, TESTNODES, logfds, FAIL);
+ 	}
++	clean_exit(knet_h, TESTNODES, logfds, PASS);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/fun_config_crypto.c b/libknet/tests/fun_config_crypto.c
+index 7843664e..cfacb78d 100644
+--- a/libknet/tests/fun_config_crypto.c
++++ b/libknet/tests/fun_config_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2020-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -22,6 +22,7 @@
+ #include "netutils.h"
+ #include "test-common.h"
+ 
++#undef TESTNODES
+ #define TESTNODES 2
+ 
+ static void test(const char *model)
+@@ -31,6 +32,7 @@ static void test(const char *model)
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 	int i,x;
+ 	int seconds = 10;
++	int res;
+ 
+ 	if (is_memcheck() || is_helgrind()) {
+ 		printf("Test suite is running under valgrind, adjusting wait_for_host timeout\n");
+@@ -54,29 +56,10 @@ static void test(const char *model)
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+ 	for (i = 1; i <= TESTNODES; i++) {
+-		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 1) < 0) {
+-			printf("knet_handle_crypto_set_config (1) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
+-		if (knet_handle_crypto_use_config(knet_h[i], 1) < 0) {
+-			printf("knet_handle_crypto_use_config (1) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
+-		if (knet_handle_crypto_rx_clear_traffic(knet_h[i], KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC)) {
+-			printf("knet_handle_crypto_rx_clear_traffic failed: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 1));
++		FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h[i], 1));
++		FAIL_ON_ERR(knet_handle_crypto_rx_clear_traffic(knet_h[i], KNET_CRYPTO_RX_DISALLOW_CLEAR_TRAFFIC));
+ 	}
+-
+ 	flush_logs(logfds[0], stdout);
+ 
+ 	knet_handle_join_nodes(knet_h, TESTNODES, 1, AF_INET, KNET_TRANSPORT_UDP);
+@@ -96,10 +79,7 @@ static void test(const char *model)
+ 	for (i = 1; i <= TESTNODES; i++) {
+ 		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 2) < 0) {
+ 			printf("knet_handle_crypto_set_config (2) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
++			clean_exit(knet_h, TESTNODES, logfds, FAIL);
+ 		}
+ 	}
+ 
+@@ -110,10 +90,7 @@ static void test(const char *model)
+ 	for (i = 1; i <= TESTNODES; i++) {
+ 		if (knet_handle_crypto_use_config(knet_h[i], 2) < 0) {
+ 			printf("knet_handle_crypto_use_config (2) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
++			clean_exit(knet_h, TESTNODES, logfds, FAIL);
+ 		}
+ 		for (x = 1; x <= TESTNODES; x++) {
+ 			wait_for_nodes_state(knet_h[x], TESTNODES, 1, 600, knet_h[1]->logfd, stdout);
+@@ -125,13 +102,7 @@ static void test(const char *model)
+ 	printf("Testing crypto config switch from 2 to 1\n");
+ 
+ 	for (i = 1; i <= TESTNODES; i++) {
+-		if (knet_handle_crypto_use_config(knet_h[i], 1) < 0) {
+-			printf("knet_handle_crypto_use_config (1) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h[i], 1));
+ 		wait_for_nodes_state(knet_h[i], TESTNODES, 1, 600, knet_h[1]->logfd, stdout);
+ 	}
+ 
+@@ -148,36 +119,18 @@ static void test(const char *model)
+ 		/*
+ 		 * config2 is no longer in use
+ 		 */
+-		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 2) < 0) {
+-			printf("knet_handle_crypto_set_config (2) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 2));
+ 		/*
+ 		 * allow clear traffic on RX on all nodes, before we change config to clear traffic
+ 		 */
+-		if (knet_handle_crypto_rx_clear_traffic(knet_h[i], KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC)) {
+-			printf("knet_handle_crypto_rx_clear_traffic failed: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_crypto_rx_clear_traffic(knet_h[i], KNET_CRYPTO_RX_ALLOW_CLEAR_TRAFFIC));
+ 	}
+ 
+ 	for (i = 1; i <= TESTNODES; i++) {
+ 		/*
+ 		 * switch to clear traffic on RX on all nodes
+ 		 */
+-		if (knet_handle_crypto_use_config(knet_h[i], 0) < 0) {
+-			printf("knet_handle_crypto_use_config (0) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_crypto_use_config(knet_h[i], 0));
+ 	}
+ 
+ 
+@@ -185,13 +138,7 @@ static void test(const char *model)
+ 		/*
+ 		 * config1 is no longer in use
+ 		 */
+-		if (knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 1) < 0) {
+-			printf("knet_handle_crypto_set_config (2) failed with correct config: %s\n", strerror(errno));
+-			knet_handle_stop_nodes(knet_h, TESTNODES);
+-			flush_logs(logfds[0], stdout);
+-			close_logpipes(logfds);
+-			exit(FAIL);
+-		}
++		FAIL_ON_ERR(knet_handle_crypto_set_config(knet_h[i], &knet_handle_crypto_cfg, 1));
+ 	}
+ 
+ 	for (i = 1; i <= TESTNODES; i++) {
+@@ -206,7 +153,7 @@ static void test(const char *model)
+ 
+ 	flush_logs(logfds[0], stdout);
+ 	close_logpipes(logfds);
+-	knet_handle_stop_nodes(knet_h, TESTNODES);
++	knet_handle_stop_everything(knet_h, TESTNODES);
+ }
+ 
+ int main(int argc, char *argv[])
+diff --git a/libknet/tests/fun_pmtud_crypto.c b/libknet/tests/fun_pmtud_crypto.c
+index e340f8d4..3c1d65f7 100644
+--- a/libknet/tests/fun_pmtud_crypto.c
++++ b/libknet/tests/fun_pmtud_crypto.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -95,17 +95,18 @@ out_clean:
+ 	return err;
+ }
+ 
+-static int exit_local(int code)
++static void exit_local(int exit_code)
+ {
+ 	set_iface_mtu(default_mtu);
+ 	close(iface_fd);
+ 	iface_fd = 0;
+-	exit(code);
++	exit(exit_code);
+ }
+ 
++#define TESTNODES 1
+ static void test_mtu(const char *model, const char *crypto, const char *hash)
+ {
+-	knet_handle_t knet_h;
++	knet_handle_t knet_h[TESTNODES+1];
+ 	int logfds[2];
+ 	int datafd = 0;
+ 	int8_t channel = 0;
+@@ -113,10 +114,11 @@ static void test_mtu(const char *model, const char *crypto, const char *hash)
+ 	struct knet_handle_crypto_cfg knet_handle_crypto_cfg;
+ 	unsigned int data_mtu, expected_mtu;
+ 	size_t calculated_iface_mtu = 0, detected_iface_mtu = 0;
++	int res;
+ 
+ 	setup_logpipes(logfds);
+ 
+-	knet_h = knet_handle_start(logfds, KNET_LOG_DEBUG);
++	knet_h[1] = knet_handle_start(logfds, KNET_LOG_DEBUG, knet_h);
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+@@ -128,127 +130,47 @@ static void test_mtu(const char *model, const char *crypto, const char *hash)
+ 	strncpy(knet_handle_crypto_cfg.crypto_hash_type, hash, sizeof(knet_handle_crypto_cfg.crypto_hash_type) - 1);
+ 	knet_handle_crypto_cfg.private_key_len = 2000;
+ 
+-	if (knet_handle_crypto(knet_h, &knet_handle_crypto_cfg)) {
+-		printf("knet_handle_crypto failed with correct config: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-        }
+-
+-	if (knet_handle_enable_sock_notify(knet_h, &private_data, sock_notify) < 0) {
+-		printf("knet_handle_enable_sock_notify failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-        }
++	FAIL_ON_ERR(knet_handle_crypto(knet_h[1], &knet_handle_crypto_cfg));
++
++	FAIL_ON_ERR(knet_handle_enable_sock_notify(knet_h[1], &private_data, sock_notify)); // CHECK cond was <0 not !=0
+ 
+ 	datafd = 0;
+ 	channel = -1;
+ 
+-	if (knet_handle_add_datafd(knet_h, &datafd, &channel) < 0) {
+-		printf("knet_handle_add_datafd failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_add_datafd(knet_h[1], &datafd, &channel));
+ 
+-	if (knet_host_add(knet_h, 1) < 0) {
+-		printf("knet_host_add failed: %s\n", strerror(errno));
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(knet_host_add(knet_h[1], 1));
+ 
+-	if (_knet_link_set_config(knet_h, 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo) < 0) {
+-		printf("Unable to configure link: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(_knet_link_set_config(knet_h[1], 1, 0, KNET_TRANSPORT_UDP, 0, AF_INET, 0, &lo));
+ 
+-	if (knet_link_set_pong_count(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_pong_count failed: %s\n", strerror(errno));
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_pong_count(knet_h[1], 1, 0, 1));
+ 
+-	if (knet_link_set_enable(knet_h, 1, 0, 1) < 0) {
+-		printf("knet_link_set_enable failed: %s\n", strerror(errno));
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(knet_link_set_enable(knet_h[1], 1, 0, 1));
+ 
+-	if (wait_for_host(knet_h, 1, 4, logfds[0], stdout) < 0) {
+-		printf("timeout waiting for host to be reachable");
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(wait_for_host(knet_h[1], 1, 4, logfds[0], stdout));
+ 
+ 	flush_logs(logfds[0], stdout);
+ 
+-	if (knet_handle_pmtud_get(knet_h, &data_mtu) < 0) {
+-		printf("knet_handle_pmtud_get failed error: %s\n", strerror(errno));
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
+-	}
++	FAIL_ON_ERR(knet_handle_pmtud_get(knet_h[1], &data_mtu));
+ 
+-	calculated_iface_mtu = calc_data_outlen(knet_h, data_mtu + KNET_HEADER_ALL_SIZE) + 28;
++	calculated_iface_mtu = calc_data_outlen(knet_h[1], data_mtu + KNET_HEADER_ALL_SIZE) + 28;
+ 	detected_iface_mtu = get_iface_mtu();
+ 	/*
+ 	 * 28 = 20 IP header + 8 UDP header
+ 	 */
+-	expected_mtu = calc_max_data_outlen(knet_h, detected_iface_mtu - 28);
++	expected_mtu = calc_max_data_outlen(knet_h[1], detected_iface_mtu - 28);
+ 
+ 	if (expected_mtu != data_mtu) {
+ 		printf("Wrong MTU detected! interface mtu: %zu knet mtu: %u expected mtu: %u\n", detected_iface_mtu, data_mtu, expected_mtu);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
++		clean_exit(knet_h, TESTNODES, logfds, FAIL);
+ 	}
+ 
+-	if ((detected_iface_mtu - calculated_iface_mtu) >= knet_h->sec_block_size) {
++	if ((detected_iface_mtu - calculated_iface_mtu) >= knet_h[1]->sec_block_size) {
+ 		printf("Wrong MTU detected! real iface mtu: %zu calculated: %zu\n", detected_iface_mtu, calculated_iface_mtu);
+-		knet_link_set_enable(knet_h, 1, 0, 0);
+-		knet_link_clear_config(knet_h, 1, 0);
+-		knet_host_remove(knet_h, 1);
+-		knet_handle_free(knet_h);
+-		flush_logs(logfds[0], stdout);
+-		close_logpipes(logfds);
+-		exit_local(FAIL);
++		clean_exit(knet_h, TESTNODES, logfds, FAIL);
+ 	}
+ 
+-	knet_link_set_enable(knet_h, 1, 0, 0);
+-	knet_link_clear_config(knet_h, 1, 0);
+-	knet_host_remove(knet_h, 1);
+-	knet_handle_free(knet_h);
+-	flush_logs(logfds[0], stdout);
++	knet_handle_stop_everything(knet_h, TESTNODES);
+ 	close_logpipes(logfds);
+ }
+ 
+diff --git a/libknet/tests/int_links_acl_ip.c b/libknet/tests/int_links_acl_ip.c
+index 29a85a43..83d206eb 100644
+--- a/libknet/tests/int_links_acl_ip.c
++++ b/libknet/tests/int_links_acl_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/tests/int_timediff.c b/libknet/tests/int_timediff.c
+index 40ac919c..20f96e7f 100644
+--- a/libknet/tests/int_timediff.c
++++ b/libknet/tests/int_timediff.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/tests/knet_bench.c b/libknet/tests/knet_bench.c
+index a368efcf..f798f867 100644
+--- a/libknet/tests/knet_bench.c
++++ b/libknet/tests/knet_bench.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -1297,6 +1297,8 @@ static void send_perf_data_by_time(void)
+ 
+ static void cleanup_all(void)
+ {
++	knet_handle_t knet_h_tmp[2];
++
+ 	if (pthread_mutex_lock(&shutdown_mutex)) {
+ 		return;
+ 	}
+@@ -1313,7 +1315,8 @@ static void cleanup_all(void)
+ 	if (rx_thread) {
+ 		stop_rx_thread();
+ 	}
+-	knet_handle_stop(knet_h);
++	knet_h_tmp[1] = knet_h;
++	knet_handle_stop_everything(knet_h_tmp, 1);
+ }
+ 
+ static void sigint_handler(int signum)
+diff --git a/libknet/tests/pckt_test.c b/libknet/tests/pckt_test.c
+index c43b27a8..d6b28d8a 100644
+--- a/libknet/tests/pckt_test.c
++++ b/libknet/tests/pckt_test.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/tests/test-common.c b/libknet/tests/test-common.c
+index 8f8b6ca7..86eb54ed 100644
+--- a/libknet/tests/test-common.c
++++ b/libknet/tests/test-common.c
+@@ -1,6 +1,6 @@
+ 
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -417,7 +417,7 @@ static int contains_plugins(char *path)
+ 
+ 
+ /* libtool sets LD_LIBRARY_PATH to the build tree when running test in-tree */
+-static char *find_plugins_path(void)
++char *find_plugins_path(void)
+ {
+ 	char *ld_libs_env = getenv("LD_LIBRARY_PATH");
+ 	if (ld_libs_env) {
+@@ -438,7 +438,7 @@ static char *find_plugins_path(void)
+ }
+ 
+ 
+-knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level)
++knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level, knet_handle_t knet_h_array[])
+ {
+ 	knet_handle_t knet_h = knet_handle_new_ex(1, logfds[1], log_level, 0);
+ 	char *plugins_path;
+@@ -450,6 +450,8 @@ knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level)
+ 		if (plugins_path) {
+ 			knet_h->plugin_path = plugins_path;
+ 		}
++		knet_h_array[1] = knet_h;
++		flush_logs(logfds[0], stdout);
+ 		return knet_h;
+ 	} else {
+ 		printf("knet_handle_new failed: %s\n", strerror(errno));
+@@ -459,7 +461,7 @@ knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level)
+ 	}
+ }
+ 
+-int knet_handle_stop(knet_handle_t knet_h)
++int knet_handle_reconnect_links(knet_handle_t knet_h)
+ {
+ 	size_t i, j;
+ 	knet_node_id_t host_ids[KNET_MAX_HOST];
+@@ -472,11 +474,6 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 		return -1;
+ 	}
+ 
+-	if (knet_handle_setfwd(knet_h, 0) < 0) {
+-		printf("knet_handle_setfwd failed: %s\n", strerror(errno));
+-		return -1;
+-	}
+-
+ 	if (knet_host_get_host_list(knet_h, host_ids, &host_ids_entries) < 0) {
+ 		printf("knet_host_get_host_list failed: %s\n", strerror(errno));
+ 		return -1;
+@@ -492,26 +489,15 @@ int knet_handle_stop(knet_handle_t knet_h)
+ 				printf("knet_link_get_enable failed: %s\n", strerror(errno));
+ 				return -1;
+ 			}
+-			if (enabled) {
+-				if (knet_link_set_enable(knet_h, host_ids[i], j, 0)) {
++			if (!enabled) {
++				if (knet_link_set_enable(knet_h, host_ids[i], j, 1)) {
+ 					printf("knet_link_set_enable failed: %s\n", strerror(errno));
+ 					return -1;
+ 				}
+ 			}
+-			printf("clearing config for: %p host: %u link: %zu\n", knet_h, host_ids[i], j);
+-			knet_link_clear_config(knet_h, host_ids[i], j);
+-		}
+-		if (knet_host_remove(knet_h, host_ids[i]) < 0) {
+-			printf("knet_host_remove failed: %s\n", strerror(errno));
+-			return -1;
+ 		}
+ 	}
+ 
+-	if (knet_handle_free(knet_h)) {
+-		printf("knet_handle_free failed: %s\n", strerror(errno));
+-		return -1;
+-	}
+-
+ 	return 0;
+ }
+ 
+@@ -667,27 +653,13 @@ void knet_handle_start_nodes(knet_handle_t knet_h[], uint8_t numnodes, int logfd
+ 	}
+ 
+ 	if (i < numnodes) {
+-		knet_handle_stop_nodes(knet_h, i);
++		knet_handle_stop_everything(knet_h, i);
+ 		exit(FAIL);
+ 	}
+ 
+ 	return;
+ }
+ 
+-void knet_handle_stop_nodes(knet_handle_t knet_h[], uint8_t numnodes)
+-{
+-	uint8_t i;
+-
+-	for (i = 1; i <= numnodes; i++) {
+-		if (knet_h[i]) {
+-			printf("stopping handle %u at %p\n", i, knet_h[i]);
+-			knet_handle_stop(knet_h[i]);
+-		}
+-	}
+-
+-	return;
+-}
+-
+ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t numlinks, int family, uint8_t transport)
+ {
+ 	uint8_t i, x, j;
+@@ -708,7 +680,7 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ 
+ 			if (knet_host_add(knet_h[i], j) < 0) {
+ 				printf("Unable to add host: %s\n", strerror(errno));
+-				knet_handle_stop_nodes(knet_h, numnodes);
++				knet_handle_stop_everything(knet_h, numnodes);
+ 				exit(FAIL);
+ 			}
+ 
+@@ -718,13 +690,13 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ 				while (i + x + offset++ < 65535 && res != 0) {
+ 					if (_make_local_sockaddr(&src, i + x + offset, family) < 0) {
+ 						printf("Unable to convert src to sockaddr: %s\n", strerror(errno));
+-						knet_handle_stop_nodes(knet_h, numnodes);
++						knet_handle_stop_everything(knet_h, numnodes);
+ 						exit(FAIL);
+ 					}
+ 
+ 					if (_make_local_sockaddr(&dst, j + x + offset, family) < 0) {
+ 						printf("Unable to convert dst to sockaddr: %s\n", strerror(errno));
+-						knet_handle_stop_nodes(knet_h, numnodes);
++						knet_handle_stop_everything(knet_h, numnodes);
+ 						exit(FAIL);
+ 					}
+ 
+@@ -733,7 +705,7 @@ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t nu
+ 				printf("joining node %u with node %u via link %u src offset: %u dst offset: %u\n", i, j, x, i+x, j+x);
+ 				if (knet_link_set_enable(knet_h[i], j, x, 1) < 0) {
+ 					printf("unable to enable link: %s\n", strerror(errno));
+-					knet_handle_stop_nodes(knet_h, numnodes);
++					knet_handle_stop_everything(knet_h, numnodes);
+ 					exit(FAIL);
+ 				}
+ 			}
+@@ -950,3 +922,71 @@ int wait_for_host(knet_handle_t knet_h, uint16_t host_id, int seconds, int logfd
+ 	errno = savederrno;
+ 	return res;
+ }
++
++void clean_exit(knet_handle_t *knet_h, int testnodes, int *logfds, int exit_status)
++{
++	knet_handle_stop_everything(knet_h, testnodes);
++	stop_logthread();
++	flush_logs(logfds[0], stdout);
++	close_logpipes(logfds);
++	if (exit_status != CONTINUE) {
++		exit(exit_status);
++	}
++}
++
++/* Shutdown all nodes and links attached to an array of knet handles.
++ * Mostly stolen from corosync code (that I wrote, before anyone complains about licences)
++ */
++void knet_handle_stop_everything(knet_handle_t knet_h[], uint8_t numnodes)
++{
++	int res = 0;
++	int h;
++	size_t i,j;
++	static knet_node_id_t nodes[KNET_MAX_HOST]; /* static to save stack */
++	uint8_t links[KNET_MAX_LINK];
++	size_t num_nodes;
++	size_t num_links;
++
++	for (h=1; h<numnodes+1; h++) {
++		res = knet_handle_setfwd(knet_h[h], 0);
++		if (res) {
++			perror("knet_handle_setfwd failed");
++		}
++
++		res = knet_host_get_host_list(knet_h[h], nodes, &num_nodes);
++		if (res) {
++			perror("Cannot get knet node list for shutdown");
++			continue;
++		}
++
++		/* Tidily shut down all nodes & links. */
++		for (i=0; i<num_nodes; i++) {
++
++			res = knet_link_get_link_list(knet_h[h], nodes[i], links, &num_links);
++			if (res) {
++				fprintf(stderr, "Cannot get knet link list for node %u  %s\n", nodes[i], strerror(errno));
++				goto finalise_error;
++			}
++			for (j=0; j<num_links; j++) {
++				res = knet_link_set_enable(knet_h[h], nodes[i], links[j], 0);
++				if (res) {
++					fprintf(stderr, "knet_link_set_enable(node %u, link %d) failed: %s\n", nodes[i], links[j], strerror(errno));
++				}
++				res = knet_link_clear_config(knet_h[h], nodes[i], links[j]);
++				if (res) {
++					fprintf(stderr, "knet_link_clear_config(node %u, link %d) failed: %s\n", nodes[i], links[j], strerror(errno));
++				}
++			}
++			res = knet_host_remove(knet_h[h], nodes[i]);
++			if (res) {
++				fprintf(stderr, "knet_host_remove(node %u) failed: %s\n", nodes[i], strerror(errno));
++			}
++		}
++
++	finalise_error:
++		res = knet_handle_free(knet_h[h]);
++		if (res) {
++			fprintf(stderr, "knet_handle_free failed: %s\n", strerror(errno));
++		}
++	}
++}
+diff --git a/libknet/tests/test-common.h b/libknet/tests/test-common.h
+index 6574b18d..4b10088c 100644
+--- a/libknet/tests/test-common.h
++++ b/libknet/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -20,6 +20,8 @@
+ #define SKIP	77
+ #define ERROR	99
+ #define FAIL	-1
++/* Extra for us to continue while still using the cleanup code */
++#define CONTINUE 101
+ 
+ /* For *BSD compatibility */
+ #ifndef s6_addr16
+@@ -31,6 +33,65 @@
+ /*
+  * common facilities
+  */
++#define TESTNODES 1
++
++#define FAIL_ON_ERR(fn)					  \
++	printf("FOE: %s\n", #fn);			  \
++	if ((res = fn) != 0) {				  \
++	  int savederrno = errno;			  \
++	  knet_handle_stop_everything(knet_h, TESTNODES); \
++	  stop_logthread();				  \
++	  flush_logs(logfds[0], stdout);		  \
++	  close_logpipes(logfds);			  \
++	  if (res == -2) {				  \
++		  exit(SKIP);				  \
++	  } else {					  \
++		  printf("*** FAIL on line %d. %s failed: %s\n", __LINE__ , #fn, strerror(savederrno)); \
++		  exit(FAIL);				  \
++	  }						  \
++	} else {					  \
++		flush_logs(logfds[0], stdout);		  \
++	}
++
++/* As above but allow a SKIP to continue */
++#define FAIL_ON_ERR_ONLY(fn)				  \
++	printf("FOEO: %s\n", #fn);			  \
++	if ((res = fn) == -1) {				  \
++	  int savederrno = errno;			  \
++	  knet_handle_stop_everything(knet_h, TESTNODES); \
++	  stop_logthread();				  \
++	  flush_logs(logfds[0], stdout);		  \
++	  close_logpipes(logfds);			  \
++	  printf("*** FAIL on line %d. %s failed: %s\n", __LINE__ , #fn, strerror(savederrno)); \
++	  exit(FAIL);							\
++	} else {					  \
++		flush_logs(logfds[0], stdout);		  \
++	}
++
++/* Voted "Best macro name of 2022" */
++#define FAIL_ON_SUCCESS(fn, errcode)			  \
++	printf("FOS: %s\n", #fn);			  \
++	if (((res = fn) == 0) ||			  \
++	    ((res == -1) && (errno != errcode))) {	  \
++	  int savederrno = errno;			  \
++	  knet_handle_stop_everything(knet_h, TESTNODES); \
++	  stop_logthread();				  \
++	  flush_logs(logfds[0], stdout);		  \
++	  close_logpipes(logfds);			  \
++	  if (res == -2) {				  \
++		  exit(SKIP);				  \
++	  } else {					  \
++		  printf("*** FAIL on line %d. %s did not return correct error: %s\n", __LINE__ , #fn, strerror(savederrno)); \
++		  exit(FAIL);				  \
++	  }						  \
++	} else {					  \
++		flush_logs(logfds[0], stdout);		  \
++	}
++
++#define CLEAN_EXIT(r)					\
++	clean_exit(knet_h, TESTNODES, logfds, r)
++
++void clean_exit(knet_handle_t *knet_h, int testnodes, int *logfds, int exit_status);
+ 
+ int execute_shell(const char *command, char **error_string);
+ 
+@@ -39,12 +100,7 @@ int is_helgrind(void);
+ 
+ void set_scheduler(int policy);
+ 
+-knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level);
+-
+-/*
+- * consider moving this one as official API
+- */
+-int knet_handle_stop(knet_handle_t knet_h);
++knet_handle_t knet_handle_start(int logfds[2], uint8_t log_level, knet_handle_t knet_h_array[]);
+ 
+ /*
+  * knet_link_set_config wrapper required to find a free port
+@@ -57,8 +113,8 @@ int _knet_link_set_config(knet_handle_t knet_h, knet_node_id_t host_id, uint8_t
+ /*
+  * functional test helpers
+  */
++void knet_handle_stop_everything(knet_handle_t knet_h[], uint8_t numnodes);
+ void knet_handle_start_nodes(knet_handle_t knet_h[], uint8_t numnodes, int logfds[2], uint8_t log_level);
+-void knet_handle_stop_nodes(knet_handle_t knet_h[], uint8_t numnodes);
+ void knet_handle_join_nodes(knet_handle_t knet_h[], uint8_t numnodes, uint8_t numlinks, int family, uint8_t transport);
+ 
+ /*
+diff --git a/libknet/threads_common.c b/libknet/threads_common.c
+index 6af6826a..bd847460 100644
+--- a/libknet/threads_common.c
++++ b/libknet/threads_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_common.h b/libknet/threads_common.h
+index dabef9f1..057723a8 100644
+--- a/libknet/threads_common.h
++++ b/libknet/threads_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.c b/libknet/threads_dsthandler.c
+index 9c9b269b..424c5dfa 100644
+--- a/libknet/threads_dsthandler.c
++++ b/libknet/threads_dsthandler.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_dsthandler.h b/libknet/threads_dsthandler.h
+index 084f9b67..7ec675f5 100644
+--- a/libknet/threads_dsthandler.h
++++ b/libknet/threads_dsthandler.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.c b/libknet/threads_heartbeat.c
+index 45d5c326..5d0ddd9d 100644
+--- a/libknet/threads_heartbeat.c
++++ b/libknet/threads_heartbeat.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_heartbeat.h b/libknet/threads_heartbeat.h
+index da8b4b67..e643d7a2 100644
+--- a/libknet/threads_heartbeat.h
++++ b/libknet/threads_heartbeat.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.c b/libknet/threads_pmtud.c
+index 735d3a64..ab1e435e 100644
+--- a/libknet/threads_pmtud.c
++++ b/libknet/threads_pmtud.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2015-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2015-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_pmtud.h b/libknet/threads_pmtud.h
+index 88d60df0..712df011 100644
+--- a/libknet/threads_pmtud.h
++++ b/libknet/threads_pmtud.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.c b/libknet/threads_rx.c
+index f2bf2e06..94174f81 100644
+--- a/libknet/threads_rx.c
++++ b/libknet/threads_rx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_rx.h b/libknet/threads_rx.h
+index 63f9571b..f21679cf 100644
+--- a/libknet/threads_rx.h
++++ b/libknet/threads_rx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index 404bfc73..ce52df6c 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/threads_tx.h b/libknet/threads_tx.h
+index 958f4f8e..3115e859 100644
+--- a/libknet/threads_tx.h
++++ b/libknet/threads_tx.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2012-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2012-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/libknet/transport_common.c b/libknet/transport_common.c
+index 5f187c0b..feee70c4 100644
+--- a/libknet/transport_common.c
++++ b/libknet/transport_common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_common.h b/libknet/transport_common.h
+index 95c1ee58..7cd99fb3 100644
+--- a/libknet/transport_common.h
++++ b/libknet/transport_common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_loopback.c b/libknet/transport_loopback.c
+index 99a1db95..870d19bd 100644
+--- a/libknet/transport_loopback.c
++++ b/libknet/transport_loopback.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_loopback.h b/libknet/transport_loopback.h
+index 861c1776..805a9e40 100644
+--- a/libknet/transport_loopback.h
++++ b/libknet/transport_loopback.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_sctp.c b/libknet/transport_sctp.c
+index 36485e75..43bb0158 100644
+--- a/libknet/transport_sctp.c
++++ b/libknet/transport_sctp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_sctp.h b/libknet/transport_sctp.h
+index b60b038e..5f7117fa 100644
+--- a/libknet/transport_sctp.h
++++ b/libknet/transport_sctp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transport_udp.c b/libknet/transport_udp.c
+index 13f6d96b..f0257997 100644
+--- a/libknet/transport_udp.c
++++ b/libknet/transport_udp.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
+diff --git a/libknet/transport_udp.h b/libknet/transport_udp.h
+index 40d162a8..433809a7 100644
+--- a/libknet/transport_udp.h
++++ b/libknet/transport_udp.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.c b/libknet/transports.c
+index a113d5f2..874e4236 100644
+--- a/libknet/transports.c
++++ b/libknet/transports.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libknet/transports.h b/libknet/transports.h
+index 6626ec25..22623cfc 100644
+--- a/libknet/transports.h
++++ b/libknet/transports.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/Makefile.am b/libnozzle/Makefile.am
+index 4c742e4d..738e0ed3 100644
+--- a/libnozzle/Makefile.am
++++ b/libnozzle/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/internals.c b/libnozzle/internals.c
+index 4df50d7b..897478eb 100644
+--- a/libnozzle/internals.c
++++ b/libnozzle/internals.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/internals.h b/libnozzle/internals.h
+index 43794de1..4e2214f3 100644
+--- a/libnozzle/internals.h
++++ b/libnozzle/internals.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.c b/libnozzle/libnozzle.c
+index 9e259d1c..1699b525 100644
+--- a/libnozzle/libnozzle.c
++++ b/libnozzle/libnozzle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/libnozzle.h b/libnozzle/libnozzle.h
+index dae44e1a..4a6daf2c 100644
+--- a/libnozzle/libnozzle.h
++++ b/libnozzle/libnozzle.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+@@ -16,7 +16,7 @@
+  *
+  * @file libnozzle.h
+  * @brief tap interfaces management API include file
+- * @copyright Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * @copyright Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * nozzle is a commodity library to manage tap (ethernet) interfaces
+  */
+diff --git a/libnozzle/libnozzle.pc.in b/libnozzle/libnozzle.pc.in
+index 724a3f5d..a4fd7ab6 100644
+--- a/libnozzle/libnozzle.pc.in
++++ b/libnozzle/libnozzle.pc.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/libnozzle_exported_syms b/libnozzle/libnozzle_exported_syms
+index c44980f0..9ec56340 100644
+--- a/libnozzle/libnozzle_exported_syms
++++ b/libnozzle/libnozzle_exported_syms
+@@ -1,6 +1,6 @@
+ # Version and symbol export for libnozzle.so
+ #
+-# Copyright (C) 2011-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2011-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/Makefile.am b/libnozzle/tests/Makefile.am
+index 6e66a748..2f692250 100644
+--- a/libnozzle/tests/Makefile.am
++++ b/libnozzle/tests/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api-test-coverage b/libnozzle/tests/api-test-coverage
+index 0b5b2fc2..2e20a553 100755
+--- a/libnozzle/tests/api-test-coverage
++++ b/libnozzle/tests/api-test-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2016-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2016-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/api_nozzle_add_ip.c b/libnozzle/tests/api_nozzle_add_ip.c
+index 017d8f21..c19fcbf1 100644
+--- a/libnozzle/tests/api_nozzle_add_ip.c
++++ b/libnozzle/tests/api_nozzle_add_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_close.c b/libnozzle/tests/api_nozzle_close.c
+index 2d4e1ab8..82dc83b6 100644
+--- a/libnozzle/tests/api_nozzle_close.c
++++ b/libnozzle/tests/api_nozzle_close.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_del_ip.c b/libnozzle/tests/api_nozzle_del_ip.c
+index ed1fadf9..dfd494d8 100644
+--- a/libnozzle/tests/api_nozzle_del_ip.c
++++ b/libnozzle/tests/api_nozzle_del_ip.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_fd.c b/libnozzle/tests/api_nozzle_get_fd.c
+index 1e8f2a11..2755a4a4 100644
+--- a/libnozzle/tests/api_nozzle_get_fd.c
++++ b/libnozzle/tests/api_nozzle_get_fd.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_handle_by_name.c b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+index 49b06dd1..743e3fa6 100644
+--- a/libnozzle/tests/api_nozzle_get_handle_by_name.c
++++ b/libnozzle/tests/api_nozzle_get_handle_by_name.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_ips.c b/libnozzle/tests/api_nozzle_get_ips.c
+index d8100dae..c4b4ff64 100644
+--- a/libnozzle/tests/api_nozzle_get_ips.c
++++ b/libnozzle/tests/api_nozzle_get_ips.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mac.c b/libnozzle/tests/api_nozzle_get_mac.c
+index 0e2a46f2..e3f66b2a 100644
+--- a/libnozzle/tests/api_nozzle_get_mac.c
++++ b/libnozzle/tests/api_nozzle_get_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_mtu.c b/libnozzle/tests/api_nozzle_get_mtu.c
+index 3f8ffd39..288eeb6e 100644
+--- a/libnozzle/tests/api_nozzle_get_mtu.c
++++ b/libnozzle/tests/api_nozzle_get_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_get_name_by_handle.c b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+index cbb1739a..724f1f1a 100644
+--- a/libnozzle/tests/api_nozzle_get_name_by_handle.c
++++ b/libnozzle/tests/api_nozzle_get_name_by_handle.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_open.c b/libnozzle/tests/api_nozzle_open.c
+index ebf1fcb4..631e8d47 100644
+--- a/libnozzle/tests/api_nozzle_open.c
++++ b/libnozzle/tests/api_nozzle_open.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_run_updown.c b/libnozzle/tests/api_nozzle_run_updown.c
+index 5c8e8326..985fe044 100644
+--- a/libnozzle/tests/api_nozzle_run_updown.c
++++ b/libnozzle/tests/api_nozzle_run_updown.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_down.c b/libnozzle/tests/api_nozzle_set_down.c
+index 946b3116..93d91fc3 100644
+--- a/libnozzle/tests/api_nozzle_set_down.c
++++ b/libnozzle/tests/api_nozzle_set_down.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mac.c b/libnozzle/tests/api_nozzle_set_mac.c
+index 7c50f949..f9da1d6f 100644
+--- a/libnozzle/tests/api_nozzle_set_mac.c
++++ b/libnozzle/tests/api_nozzle_set_mac.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_mtu.c b/libnozzle/tests/api_nozzle_set_mtu.c
+index 752a55cb..60da1416 100644
+--- a/libnozzle/tests/api_nozzle_set_mtu.c
++++ b/libnozzle/tests/api_nozzle_set_mtu.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/api_nozzle_set_up.c b/libnozzle/tests/api_nozzle_set_up.c
+index 6c9e23d7..f500c194 100644
+--- a/libnozzle/tests/api_nozzle_set_up.c
++++ b/libnozzle/tests/api_nozzle_set_up.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/int_execute_bin_sh_command.c b/libnozzle/tests/int_execute_bin_sh_command.c
+index 8fb10828..d7bbab70 100644
+--- a/libnozzle/tests/int_execute_bin_sh_command.c
++++ b/libnozzle/tests/int_execute_bin_sh_command.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_false b/libnozzle/tests/nozzle_run_updown_exit_false
+index 4ff2b727..24581ca1 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_false
++++ b/libnozzle/tests/nozzle_run_updown_exit_false
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ 
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/nozzle_run_updown_exit_true b/libnozzle/tests/nozzle_run_updown_exit_true
+index c1e94682..94d5d4d2 100755
+--- a/libnozzle/tests/nozzle_run_updown_exit_true
++++ b/libnozzle/tests/nozzle_run_updown_exit_true
+@@ -1,7 +1,7 @@
+ #!/bin/sh
+ 
+ #
+-# Copyright (C) 2010-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2010-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/libnozzle/tests/test-common.c b/libnozzle/tests/test-common.c
+index d2bbde0b..469b4f25 100644
+--- a/libnozzle/tests/test-common.c
++++ b/libnozzle/tests/test-common.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/libnozzle/tests/test-common.h b/libnozzle/tests/test-common.h
+index 04645b64..87a86257 100644
+--- a/libnozzle/tests/test-common.h
++++ b/libnozzle/tests/test-common.h
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+  *
+diff --git a/m4/pkg_check_var.m4 b/m4/pkg_check_var.m4
+index fa3f5df3..a238fb6e 100644
+--- a/m4/pkg_check_var.m4
++++ b/m4/pkg_check_var.m4
+@@ -1,4 +1,4 @@
+-# Copyright (C) 2020-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2020-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/man/Doxyfile-knet.in b/man/Doxyfile-knet.in
+index b7c27dc6..f2c11408 100644
+--- a/man/Doxyfile-knet.in
++++ b/man/Doxyfile-knet.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Doxyfile-nozzle.in b/man/Doxyfile-nozzle.in
+index 65c68bff..a3428933 100644
+--- a/man/Doxyfile-nozzle.in
++++ b/man/Doxyfile-nozzle.in
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #         Christine Caulfield <ccaulfie@redhat.com>
+diff --git a/man/Makefile.am b/man/Makefile.am
+index 2ff160be..51cab580 100644
+--- a/man/Makefile.am
++++ b/man/Makefile.am
+@@ -1,5 +1,5 @@
+ #
+-# Copyright (C) 2017-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2017-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Authors: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #          Federico Simoncelli <fsimon@kronosnet.org>
+diff --git a/man/api-to-man-page-coverage b/man/api-to-man-page-coverage
+index a60886e0..4e588786 100755
+--- a/man/api-to-man-page-coverage
++++ b/man/api-to-man-page-coverage
+@@ -1,6 +1,6 @@
+ #!/bin/sh
+ #
+-# Copyright (C) 2019-2021 Red Hat, Inc.  All rights reserved.
++# Copyright (C) 2019-2022 Red Hat, Inc.  All rights reserved.
+ #
+ # Author: Fabio M. Di Nitto <fabbione@kronosnet.org>
+ #
+diff --git a/man/doxyxml.c b/man/doxyxml.c
+index 73f705d3..35e03191 100644
+--- a/man/doxyxml.c
++++ b/man/doxyxml.c
+@@ -1,5 +1,5 @@
+ /*
+- * Copyright (C) 2018-2021 Red Hat, Inc.  All rights reserved.
++ * Copyright (C) 2018-2022 Red Hat, Inc.  All rights reserved.
+  *
+  * Author: Christine Caulfield <ccaulfie@redhat.com>
+  *
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0451-tests-update-memcheck-exceptions.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0451-tests-update-memcheck-exceptions.patch
new file mode 100644
index 000000000..3f5502370
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0451-tests-update-memcheck-exceptions.patch
@@ -0,0 +1,75 @@ 
+From 44215d273b5a0d1d571cd0ae81ba406d2757fd3c Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 4 Mar 2022 05:49:00 +0100
+Subject: [PATCH] [tests] update memcheck exceptions
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/knet_valgrind_memcheck.supp | 57 +++++++++++++++++++++++++++
+ 1 file changed, 57 insertions(+)
+
+diff --git a/build-aux/knet_valgrind_memcheck.supp b/build-aux/knet_valgrind_memcheck.supp
+index 6214fc5e..7c33591d 100644
+--- a/build-aux/knet_valgrind_memcheck.supp
++++ b/build-aux/knet_valgrind_memcheck.supp
+@@ -632,3 +632,60 @@
+   fun:SECMOD_LoadModule
+   obj:/usr/lib64/libnss3.so
+ }
++{
++  glibc2.34 dlopen internal memory leak
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  ...
++  fun:_dl_catch_exception
++  fun:_dl_catch_error
++  fun:_dlerror_run
++  fun:dlopen_implementation
++  fun:dlopen@@GLIBC_2.34
++}
++{
++  glibc2.34 dlopen internal memory leak
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  fun:_dl_find_object_update
++  ...
++  fun:_dl_catch_error
++  fun:_dlerror_run
++  fun:dlopen@@GLIBC_2.34
++}
++{
++  glibc2.34 dlopen internal memory leak
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  ...
++  fun:_rtld_catch_error
++  fun:_dlerror_run
++}
++{
++  glibc2.34
++  Memcheck:Cond
++  fun:strcmp
++  ...
++  fun:_rtld_catch_error
++  fun:_dlerror_run
++}
++{
++  powerpc specific leak (in crypto code)
++  Memcheck:Leak
++  match-leak-kinds: definite
++  fun:malloc
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++  obj:*
++}
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0452-tests-deal-with-new-annocheck-symlink-checks.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0452-tests-deal-with-new-annocheck-symlink-checks.patch
new file mode 100644
index 000000000..f24388136
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0452-tests-deal-with-new-annocheck-symlink-checks.patch
@@ -0,0 +1,41 @@ 
+From 0881cff551c24ac398332e794292835fb96ba87d Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Fri, 18 Mar 2022 13:35:20 +0100
+Subject: [PATCH] [tests] deal with new annocheck symlink checks
+
+command line has changed between f35 and rawhide, so go for
+a neutral solution
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ build-aux/check.mk | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/build-aux/check.mk b/build-aux/check.mk
+index 2bb5dcab..9addf1ad 100644
+--- a/build-aux/check.mk
++++ b/build-aux/check.mk
+@@ -53,8 +53,9 @@ endif
+ check-annocheck-libs:
+ if HAS_ANNOCHECK
+ 	@echo Running annocheck libs test
+-	if ! $(ANNOCHECK_EXEC) --skip-lto --quiet .libs/*.so; then \
+-		$(ANNOCHECK_EXEC) --skip-lto --verbose .libs/*.so; \
++	TESTLIBS="$(shell find .libs/ -type f -name "*.so.*")"; \
++	if ! $(ANNOCHECK_EXEC) --skip-lto --quiet $$TESTLIBS; then \
++		$(ANNOCHECK_EXEC) --skip-lto --verbose $$TESTLIBS; \
+ 		echo annocheck libs test: FAILED; \
+ 		exit 1; \
+ 	else \
+@@ -70,8 +71,9 @@ endif
+ check-annocheck-bins:
+ if HAS_ANNOCHECK
+ 	@echo Running annocheck binaries test
+-	if ! $(ANNOCHECK_EXEC) --skip-run-path --skip-lto --quiet .libs/*; then \
+-		$(ANNOCHECK_EXEC) --skip-run-path --skip-lto --verbose .libs/*; \
++	TESTBINS="$(shell find .libs/ -type f)"; \
++	if ! $(ANNOCHECK_EXEC) --skip-run-path --skip-lto --quiet $$TESTBINS; then \
++		$(ANNOCHECK_EXEC) --skip-run-path --skip-lto --verbose $$TESTBINS; \
+ 		echo annocheck binaries test: FAILED; \
+ 		exit 1; \
+ 	else \
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0453-tx-fix-epoll-event-size-to-cope-with-extra-event-on-.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0453-tx-fix-epoll-event-size-to-cope-with-extra-event-on-.patch
new file mode 100644
index 000000000..f35bd3bea
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0453-tx-fix-epoll-event-size-to-cope-with-extra-event-on-.patch
@@ -0,0 +1,26 @@ 
+From 79c6f5103b3605546bd4b2003abd598da7743b20 Mon Sep 17 00:00:00 2001
+From: "Fabio M. Di Nitto" <fdinitto@redhat.com>
+Date: Tue, 22 Mar 2022 15:40:42 +0100
+Subject: [PATCH] [tx] fix epoll event size to cope with extra event on send to
+ link
+
+spotted by -Werror=stringop-overflow= new gcc feature
+
+Signed-off-by: Fabio M. Di Nitto <fdinitto@redhat.com>
+---
+ libknet/threads_tx.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/libknet/threads_tx.c b/libknet/threads_tx.c
+index ce52df6c..9b8a9ebe 100644
+--- a/libknet/threads_tx.c
++++ b/libknet/threads_tx.c
+@@ -647,7 +647,7 @@ static void _handle_send_to_links(knet_handle_t knet_h, struct msghdr *msg, int
+ void *_handle_send_to_links_thread(void *data)
+ {
+ 	knet_handle_t knet_h = (knet_handle_t) data;
+-	struct epoll_event events[KNET_EPOLL_MAX_EVENTS];
++	struct epoll_event events[KNET_EPOLL_MAX_EVENTS + 1]; /* see _init_epolls for + 1 */
+ 	int i, nev, type;
+ 	int flush, flush_queue_limit;
+ 	int8_t channel;
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0454-logging-Fix-Initializing-typo.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0454-logging-Fix-Initializing-typo.patch
new file mode 100644
index 000000000..07b965495
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0454-logging-Fix-Initializing-typo.patch
@@ -0,0 +1,65 @@ 
+From 4b309ff45bea9af6825beed47b4b11ec37960aec Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfriesse@redhat.com>
+Date: Thu, 31 Mar 2022 11:39:54 +0200
+Subject: [PATCH] [logging] Fix Initializing typo
+
+Signed-off-by: Jan Friesse <jfriesse@redhat.com>
+---
+ libknet/compress.c       | 2 +-
+ libknet/crypto.c         | 2 +-
+ libknet/crypto_nss.c     | 2 +-
+ libknet/crypto_openssl.c | 2 +-
+ 4 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/libknet/compress.c b/libknet/compress.c
+index 43900135..122fe9fe 100644
+--- a/libknet/compress.c
++++ b/libknet/compress.c
+@@ -288,7 +288,7 @@ static int compress_cfg(
+ 	}
+ 
+ 	log_debug(knet_h, KNET_SUB_COMPRESS,
+-		  "Initizializing compress module [%s/%d/%u]",
++		  "Initializing compress module [%s/%d/%u]",
+ 		  knet_handle_compress_cfg->compress_model, knet_handle_compress_cfg->compress_level, knet_handle_compress_cfg->compress_threshold);
+ 
+ 	if (cmp_model > 0) {
+diff --git a/libknet/crypto.c b/libknet/crypto.c
+index f1e4b3d0..032a13e3 100644
+--- a/libknet/crypto.c
++++ b/libknet/crypto.c
+@@ -199,7 +199,7 @@ static int crypto_init(
+ 	}
+ 
+ 	log_debug(knet_h, KNET_SUB_CRYPTO,
+-		  "Initizializing crypto module [%s/%s/%s]",
++		  "Initializing crypto module [%s/%s/%s]",
+ 		  knet_handle_crypto_cfg->crypto_model,
+ 		  knet_handle_crypto_cfg->crypto_cipher_type,
+ 		  knet_handle_crypto_cfg->crypto_hash_type);
+diff --git a/libknet/crypto_nss.c b/libknet/crypto_nss.c
+index 075cf118..e61a7be3 100644
+--- a/libknet/crypto_nss.c
++++ b/libknet/crypto_nss.c
+@@ -792,7 +792,7 @@ static int nsscrypto_init(
+ 	int savederrno;
+ 
+ 	log_debug(knet_h, KNET_SUB_NSSCRYPTO,
+-		  "Initizializing nss crypto module [%s/%s]",
++		  "Initializing nss crypto module [%s/%s]",
+ 		  knet_handle_crypto_cfg->crypto_cipher_type,
+ 		  knet_handle_crypto_cfg->crypto_hash_type);
+ 
+diff --git a/libknet/crypto_openssl.c b/libknet/crypto_openssl.c
+index 5c55fe22..76609f3c 100644
+--- a/libknet/crypto_openssl.c
++++ b/libknet/crypto_openssl.c
+@@ -606,7 +606,7 @@ static int opensslcrypto_init(
+ #endif
+ 
+ 	log_debug(knet_h, KNET_SUB_OPENSSLCRYPTO,
+-		  "Initizializing openssl crypto module [%s/%s]",
++		  "Initializing openssl crypto module [%s/%s]",
+ 		  knet_handle_crypto_cfg->crypto_cipher_type,
+ 		  knet_handle_crypto_cfg->crypto_hash_type);
+ 
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet/0455-doc-To-Do-list-moved-to-projects.clusterlabs.org-379.patch b/meta-networking/recipes-extended/kronosnet/kronosnet/0455-doc-To-Do-list-moved-to-projects.clusterlabs.org-379.patch
new file mode 100644
index 000000000..f403a7937
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet/0455-doc-To-Do-list-moved-to-projects.clusterlabs.org-379.patch
@@ -0,0 +1,22 @@ 
+From 14d2e130cd5b3dabb2d33b34ac06ee65f092423a Mon Sep 17 00:00:00 2001
+From: Chrissie Caulfield <ccaulfie@redhat.com>
+Date: Fri, 29 Apr 2022 07:32:56 +0100
+Subject: [PATCH] [doc] To Do list moved to projects.clusterlabs.org (#379)
+
+---
+ README | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/README b/README
+index f71405b4..bd5f75f4 100644
+--- a/README
++++ b/README
+@@ -11,7 +11,7 @@ Upstream resources
+ 
+ https://github.com/kronosnet/kronosnet/
+ https://ci.kronosnet.org/
+-https://trello.com/kronosnet (TODO list and activities tracking)
++https://projects.clusterlabs.org/project/board/86/ (TODO list and activities tracking)
+ https://goo.gl/9ZvkLS (google shared drive)
+ https://lists.kronosnet.org/mailman3/postorius/lists/users.lists.kronosnet.org/
+ https://lists.kronosnet.org/mailman3/postorius/lists/devel.lists.kronosnet.org/
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet_1.24.bb b/meta-networking/recipes-extended/kronosnet/kronosnet_1.24.bb
deleted file mode 100644
index cbd5e7a0f..000000000
--- a/meta-networking/recipes-extended/kronosnet/kronosnet_1.24.bb
+++ /dev/null
@@ -1,32 +0,0 @@ 
-# Copyright (C) 2020 Khem Raj <raj.khem@gmail.com>
-# Released under the MIT license (see COPYING.MIT for the terms)
-
-SUMMARY = "Kronosnet, often referred to as knet, is a network abstraction layer \
-           designed for High Availability use cases, where redundancy, security, \
-           fault tolerance and fast fail-over are the core requirements of your application."
-HOMEPAGE = "https://kronosnet.org/"
-LICENSE = "GPL-2.0-or-later & LGPL-2.1-only"
-LIC_FILES_CHKSUM = "file://COPYING.applications;md5=751419260aa954499f7abaabaa882bbe \
-                    file://COPYING.libraries;md5=2d5025d4aa3495befef8f17206a5b0a1"
-SECTION = "libs"
-DEPENDS = "doxygen-native libqb-native libxml2-native bzip2 libqb libxml2 libnl lksctp-tools lz4 lzo openssl nss xz zlib zstd"
-
-SRCREV = "f8f80fd7f9b85f2626d2c6452612962ad8efca9e"
-SRC_URI = "git://github.com/kronosnet/kronosnet;protocol=https;branch=stable1 \
-           file://0001-links.c-Fix-build-with-gcc-12.patch \
-           "
-
-UPSTREAM_CHECK_URI = "https://github.com/kronosnet/kronosnet/releases"
-
-inherit autotools pkgconfig
-
-S = "${WORKDIR}/git"
-
-# libknet/transport_udp.c:326:48: error: comparison of integers of different signs: 'unsigned long' and 'int' [-Werror,-Wsign-compare]
-# for (cmsg = CMSG_FIRSTHDR(&msg);cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
-#                                                             ^~~~~~~~~~~~~~~~~~~~~~~
-CFLAGS:append:toolchain-clang = " -Wno-sign-compare"
-
-PACKAGECONFIG[man] = "enable_man="yes", --disable-man, "
-
-PACKAGECONFIG:remove = "man"
diff --git a/meta-networking/recipes-extended/kronosnet/kronosnet_1.90.bb b/meta-networking/recipes-extended/kronosnet/kronosnet_1.90.bb
new file mode 100644
index 000000000..d94c61ff3
--- /dev/null
+++ b/meta-networking/recipes-extended/kronosnet/kronosnet_1.90.bb
@@ -0,0 +1,487 @@ 
+# Copyright (C) 2020 Khem Raj <raj.khem@gmail.com>
+# Released under the MIT license (see COPYING.MIT for the terms)
+
+SUMMARY = "Kronosnet, often referred to as knet, is a network abstraction layer \
+           designed for High Availability use cases, where redundancy, security, \
+           fault tolerance and fast fail-over are the core requirements of your application."
+HOMEPAGE = "https://kronosnet.org/"
+LICENSE = "GPL-2.0-or-later & LGPL-2.1-only"
+LIC_FILES_CHKSUM = "file://COPYING.applications;md5=751419260aa954499f7abaabaa882bbe \
+                    file://COPYING.libraries;md5=2d5025d4aa3495befef8f17206a5b0a1"
+SECTION = "libs"
+DEPENDS = "doxygen-native libqb-native libxml2-native bzip2 libqb libxml2 libnl lksctp-tools lz4 lzo openssl nss xz zlib zstd"
+
+SRCREV = "f843f7d8154d2dadc158519ccb2deec8f7003fc1"
+SRC_URI = "git://github.com/kronosnet/kronosnet;protocol=https;branch=main \
+           file://0001-links.c-Fix-build-with-gcc-12.patch \
+           file://0001-build-determine-SOURCE_EPOCH-during-configuration.patch \
+           file://0002-build-distribute-the-source_epoch-file.patch \
+           file://0003-man-Add-date-year-options-to-doxyxml.patch \
+           file://0004-man-use-new-doxyxml-date-options-to-build-man-pages.patch \
+           file://0005-spec-use-the-source-epoch-here-as-well.patch \
+           file://0006-build-accomodate-to-the-actual-date-utility.patch \
+           file://0007-build-git-C-is-a-relatively-new-option-avoid-it.patch \
+           file://0008-build-fail-and-provide-proper-error-if-source-tree-v.patch \
+           file://0009-build-check-for-SOURCE_DATE_EPOCH-before-turning-to-.patch \
+           file://0010-build-look-for-source_epoch-in-srcdir.patch \
+           file://0011-crypto-improve-checks-around-RX-packet-size.patch \
+           file://0012-crypto-NSS_NoDB_Init-the-parameter-is-reserved-must-.patch \
+           file://0013-flush_logs-remove-redundant-condition.patch \
+           file://0014-flush_logs-the-reads-will-overwrite-the-entire-msg-s.patch \
+           file://0015-flush_logs-don-t-repeat-the-type-of-msg.patch \
+           file://0016-flush_logs-a-for-loop-is-more-straightforward-here.patch \
+           file://0017-flush_logs-while-loop-instead-of-goto.patch \
+           file://0018-flush_logs-don-t-ever-print-past-the-message-buffer.patch \
+           file://0019-_logthread-select-returns-the-number-of-set-bits-as-.patch \
+           file://0020-_logthread-while-loop-instead-of-goto.patch \
+           file://0021-knet_log_msg-fix-documentation-the-closing-newline-i.patch \
+           file://0022-log_msg-no-point-in-putting-NL-after-the-final-NUL.patch \
+           file://0023-coding-style-add-parentheses-after-the-sizeof-operat.patch \
+           file://0024-tests-add-another-lzma-exception.patch \
+           file://0025-tests-reference-correct-library-in-memcheck-comments.patch \
+           file://0026-tests-ignore-nss-internal-memory-leak-3.38-non-recur.patch \
+           file://0027-handle-drop-call-to-log_msg-that-would-have-no-effec.patch \
+           file://0028-logging-drop-locking-inside-log_msg-part-1.patch \
+           file://0029-handle-drop-init_lock_done-as-it-was-used-only-by-lo.patch \
+           file://0030-logging-report-error-in-case-logging-buffer-is-bigge.patch \
+           file://0031-handle-reduce-usage-of-handle_config_mutex-to-wrap-o.patch \
+           file://0032-tests-adds-more-overrides-for-fedora28-arm-glibc.patch \
+           file://0033-tests-don-t-redefine-symbols-from-the-main-library.patch \
+           file://0034-threads-use-internal-array-to-track-status-of-thread.patch \
+           file://0035-tests-cleanup-nss-memcheck-supports.patch \
+           file://0036-tests-drop-arm-exceptions-as-they-have-been-fixed-in.patch \
+           file://0037-Support-for-git-archive-stored-tags.patch \
+           file://0038-Do-not-match-lightweight-tags-in-git-version-gen.patch \
+           file://0039-git-version-gen-fail-on-UNKNOWN-version.patch \
+           file://0040-Use-gitarchive-version-for-spec-file.patch \
+           file://0041-threads-make-it-easier-to-debug-thread-startup-stop-.patch \
+           file://0042-tests-fix-select-2-handling-mostly-affects-slow-mach.patch \
+           file://0043-tests-clear-errno-to-avoid-incorrect-propagation-fro.patch \
+           file://0044-Import-key-with-length-not-dividable-by-wrap-key-blo.patch \
+           file://0045-links-Don-t-close-loopback-link.patch \
+           file://0046-misc-keep-covscan-happy.patch \
+           file://0047-man-update-XML-directory-in-doxyxml.c.patch \
+           file://0048-fix-typo.patch \
+           file://0049-tests-fix-output-message.patch \
+           file://0050-build-fix-supported-compiler-warning-detection.patch \
+           file://0051-transports-fix-transport_modules_cmd-array-out-of-ra.patch \
+           file://0052-Add-static-qualifier-to-compress-crypto-transport-_m.patch \
+           file://0053-tx-remove-goto-statement-to-improve-readability.patch \
+           file://0054-rx-fix-incorrect-packet-length-in-_parse_recv_from_l.patch \
+           file://0055-tx-fix-tx_uncompressed_packets-stats-collect-in-_par.patch \
+           file://0056-openssl-fix-return-type-for-pthread_self.patch \
+           file://0057-clear-the-errno-in-each-exported-API-when-the-call-s.patch \
+           file://0058-tests-fix-check-condition-in-api_knet_-addrtostr-str.patch \
+           file://0059-tests-update-error-message-in-api_knet_-addrtostr-st.patch \
+           file://0060-misc-fix-a-few-typos-stylistics.patch \
+           file://0061-UDP-Cope-with-EPERM-returned-from-sendmsg-sendto.patch \
+           file://0062-libtap-tests-allow-random-localhost-IPs-for-testing.patch \
+           file://0063-libtap-tests-add-better-IPv6-private-address-space-r.patch \
+           file://0064-libtap-port-to-freebsd-and-fix-a-bunch-of-small-bugs.patch \
+           file://0065-libtap-update-README-for-BSD.patch \
+           file://0066-libtap-define-IFNAMSIZ-for-applications-that-don-t-n.patch \
+           file://0067-libtap-BSD-switch-to-ioctl-to-destroy-tap-devices.patch \
+           file://0068-libnozzle-rename-libtap-to-libnozzle-part-1.patch \
+           file://0069-nozzle-add-Doxygen-header.patch \
+           file://0070-nozzle-include-net-if.h-to-define-IFNAMSIZ-instead-o.patch \
+           file://0071-nozzle-rename-tap_t-to-nozzle_t.patch \
+           file://0072-nozzle-rename-struct-_iface-to-nozzle_iface-looks-be.patch \
+           file://0073-nozzle-fix-pkg-config-to-point-to-nozzle.patch \
+           file://0074-nozzle-rename-API-from-tap_-to-nozzle_.patch \
+           file://0075-nozzle-rename-last-tap-bits-to-nozzle.patch \
+           file://0076-nozzle-cleanup-nozzle_open-coding-style-and-return-c.patch \
+           file://0077-nozzle-start-to-cleanup-nozzle_close-to-be-more-info.patch \
+           file://0078-nozzle-cleanup-and-document-nozzle_set_up.patch \
+           file://0079-nozzle-cleanup-and-document-nozzle_set_down.patch \
+           file://0080-nozzle-re-order-functions-in-order-of-importance.patch \
+           file://0081-nozzle-cleanup-and-document-nozzle_add_ip.patch \
+           file://0082-nozzle-cleanup-and-document-nozzle_del_ip.patch \
+           file://0083-nozzle-cleanup-and-document-nozzle_get_ips-part-1.patch \
+           file://0084-nozzle-fix-test-on-BSD.patch \
+           file://0085-nozzle-cleanup-and-document-nozzle_get_mtu.patch \
+           file://0086-nozzle-cleanup-and-document-nozzle_set_mtu-and-nozzl.patch \
+           file://0087-Tidy-some-English.patch \
+           file://0088-nozzle-cleanup-and-document-nozzle_get_mac.patch \
+           file://0089-nozzle-cleanup-and-document-nozzle_-re-set_mac.patch \
+           file://0090-nozzle-cleanup-and-document-nozzle_get_handle_by_nam.patch \
+           file://0091-nozzle-cleanup-and-document-nozzle_get_name_by_handl.patch \
+           file://0092-nozzle-cleanup-and-document-nozzle_get_fd.patch \
+           file://0093-cleanup-start-splitting-the-code-across-multiple-fil.patch \
+           file://0094-nozzle-rename-_config-to-nozzle_lib_config.patch \
+           file://0095-cleanup-rename-struct-_ip-to-struct-nozzle_ip-and-cl.patch \
+           file://0096-cleanup-rename-sockfd-to-ioctlfd.patch \
+           file://0097-cleanup-rename-ip_addr-to-ipaddr.patch \
+           file://0098-cleanup-document-nozzle_iface-struct-drop-unnecessar.patch \
+           file://0099-build-fix-build-on-BSD.patch \
+           file://0100-nozzle-rename-lib_mutex-to-config_mutex.patch \
+           file://0101-build-split-tests-man-pages-and-build-dirs.patch \
+           file://0102-nozzle-split-code-around-to-separate-libnozzle-and-t.patch \
+           file://0103-nozzle-start-cleaning-internal-function-names.patch \
+           file://0104-nozzle-be-more-explicit-on-function-naming.patch \
+           file://0105-nozzle-be-more-explicit-on-function-naming-part-2.patch \
+           file://0106-nozzle-rename-_check-to-is_valid_nozzle-make-it-more.patch \
+           file://0107-nozzle-move-code-around-to-reflect-completion-and-dr.patch \
+           file://0108-nozzle-move-code-around-to-reflect-public-API-and-in.patch \
+           file://0109-nozzle-cleanup-mac-address-functions.patch \
+           file://0110-nozzle-move-ipv4-broadcast-to-internals.patch \
+           file://0111-nozzle-move-find_ip-to-internals.patch \
+           file://0112-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch \
+           file://0113-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch \
+           file://0114-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch \
+           file://0115-nozzle-decouple-running-pre-up.d-up.d-down.d-post-do.patch \
+           file://0116-nozzle-move-set-up-and-down-to-the-stable-API-sectio.patch \
+           file://0117-nozzle-nozzle_open-and-nozzle_close-should-be-stable.patch \
+           file://0118-nozzle-fix-build-on-BSD.patch \
+           file://0119-nozzle-propagate-errors-all-the-way.patch \
+           file://0120-nozzle-fix-man-page-generation.patch \
+           file://0121-nozzle-move-man-pages-to-top-level-dir.patch \
+           file://0122-nozzle-enable-libnozzle-build-by-default.patch \
+           file://0123-nozzle-drop-duplicated-code.patch \
+           file://0124-nozzle-expand-buffers-to-deal-with-strncpy-and-Werro.patch \
+           file://0125-libnozzle-whitespace-cleanup.patch \
+           file://0126-libnozzle-Use-libnl3.0-for-ip-address-management-on-.patch \
+           file://0127-libnozzle-enable-libnl3-3.3-build-workaround.patch \
+           file://0128-tests-remove-debugging-sleep.patch \
+           file://0129-tests-properly-check-symbols-on-PPC64.patch \
+           file://0130-libtap-move-nozzle_run_updown-to-completed-section.patch \
+           file://0131-libnozzle-remove-error_string-requirement-from-many-.patch \
+           file://0132-libnozzle-fix-build-on-BSD.patch \
+           file://0133-libnozzle-Update-copyright.patch \
+           file://0134-global-Update-copyright-across.patch \
+           file://0135-libnozzle-fix-whitespaces.patch \
+           file://0136-libnozzle-cleanup-nozzle_get_ips-public-API.patch \
+           file://0137-libnozzle-add-comment-about-BSD-ip_add-status.patch \
+           file://0138-libnozzle-re-instate-error-checking-in-nozzle_get_ip.patch \
+           file://0139-libnozzle-add-per-API-call-test-coverage-check.patch \
+           file://0140-libnozzle-fix-API-check-paths.patch \
+           file://0141-libnozzle-prepare-Makefile.am-to-explode-with-API-te.patch \
+           file://0142-libnozzle-add-api_nozzle_open-test.patch \
+           file://0143-libnozzle-fix-test-suite-build-on-BSD.patch \
+           file://0144-libnozzle-add-api_nozzle_close_test.patch \
+           file://0145-libnozzle-drop-redundant-check.patch \
+           file://0146-libnozzle-drop-unnecessary-indirection-to-call-set_d.patch \
+           file://0147-libnozzle-add-api_nozzle_set_-up-down-tests.patch \
+           file://0148-libnozzle-improve-set_down-test.patch \
+           file://0149-libnozzle-clean-up-code-in-set_up-test.patch \
+           file://0150-libnozzle-move-multi-nozzle-device-test-to-api_nozzl.patch \
+           file://0151-libnozzle-add-nozzle_get_mtu-nozzle_set_mtu-nozzle_r.patch \
+           file://0152-libnozzle-add-nozzle_get_mac-nozzle_set_mac-nozzle_r.patch \
+           file://0153-libnozzle-add-nozzle_get_handle_by_name-tests.patch \
+           file://0154-libnozzle-add-nozzle_get_name_by_handle-test.patch \
+           file://0155-libnozzle-add-nozzle_get_fd-test.patch \
+           file://0156-libnozzle-cleanup-tests-Makefile.am.patch \
+           file://0157-libnozzle-add-internal-execute_bin_sh_command-test.patch \
+           file://0158-libnozzle-add-api_nozzle_run_updown-tests.patch \
+           file://0159-libnozzle-add-nozzle_add_ip-tests.patch \
+           file://0160-libnozzle-fix-del_ip-removal-of-Ipv6-addresses-when-.patch \
+           file://0161-libnozzle-add-nozzle_del_ip-tests.patch \
+           file://0162-libnozzle-add-nozzle_get_ips-tests-and-kill-nozzle_t.patch \
+           file://0163-global-fix-copyright-across.patch \
+           file://0164-libnozzle-fix-variable-assignment-order.patch \
+           file://0165-Use-the-kernel-struct-size-for-SCTP-event-subscripti.patch \
+           file://0166-Tabify.patch \
+           file://0167-global-update-notes-to-package-maintainers.patch \
+           file://0168-knet-fix-build-with-older-openssl-versions.patch \
+           file://0169-Install-the-nozzle-man-pages.patch \
+           file://0170-Fix-typos.patch \
+           file://0171-rpm-ship-libnozzle-man-pages.patch \
+           file://0172-Fix-nozzle-man-dates-to-SOURCE_EPOCH-just-like-we-fi.patch \
+           file://0173-Skip-SCTP-event-initialization-if-the-protocol-is-no.patch \
+           file://0174-libknet-expose-API-version-in-libknet.h-to-make-it-e.patch \
+           file://0175-build-enable-all-compilers-warnings-at-once.patch \
+           file://0176-libknet-allow-better-handling-of-internal-threads.patch \
+           file://0177-common-fix-not-reporting-a-true-dlinfo-error-cause.patch \
+           file://0178-man-add-test-to-make-sure-all-generated-man-pages-ar.patch \
+           file://0179-doxyxml-Don-t-crash-if-there-s-no-doxygen-stanza-for.patch \
+           file://0180-tests-fix-knet_bench-help-text.patch \
+           file://0181-man-fix-libnozzle-man-page-generation-target.patch \
+           file://0182-tests-add-ability-to-create-ipv6-sockets.patch \
+           file://0183-man-fix-man-page-build-dependency-for-BSD-Make.patch \
+           file://0184-transport-don-t-specify-destination-address-for-conn.patch \
+           file://0185-host-increase-log-level-for-currently-used-links.patch \
+           file://0186-tests-allow-shipping-of-the-test-suite.patch \
+           file://0187-manpages-Document-enums-206.patch \
+           file://0188-tests-test-rpm-should-match-currently-installed-vers.patch \
+           file://0189-transports-fix-usage-after-free-of-transport-info-me.patch \
+           file://0190-link-Check-address-families-on-a-link-always-match.patch \
+           file://0191-global-update-copyright-across-the-board.patch \
+           file://0192-build-add-another-exception-to-valgrind-nss-combo.patch \
+           file://0193-reduce-minimum-crypto-key-size-to-1024bit.patch \
+           file://0194-crypto-remove-libnss-3des-support.patch \
+           file://0195-man-Tidy-manpages-215.patch \
+           file://0196-man-Tidy-more-man-pages.patch \
+           file://0197-man-fix-knet_host_set_policy-parameters-order.patch \
+           file://0198-tests-add-man-page-check-to-verify-doxy-header-order.patch \
+           file://0199-man-fix-libknet.h-for-errors-detected-by-newly-added.patch \
+           file://0200-udp-use-defines-vs-hardcoded-numbers.patch \
+           file://0201-udp-improve-error-message-decoding-from-ICMP-errors.patch \
+           file://0202-acl-move-poc-code-into-libknet-dir-and-rename-to-lin.patch \
+           file://0203-acl-add-knet_handle_enable_access_lists-api-call.patch \
+           file://0204-transports-add-information-about-the-nature-of-the-t.patch \
+           file://0205-access-lists-make-code-more-generic-to-accept-more-t.patch \
+           file://0206-handle-properly-initialize-fd-tracker-buffers.patch \
+           file://0207-access-lists-automatically-add-and-remove-point-to-p.patch \
+           file://0208-access-lists-add-tests-for-default-access-lists.patch \
+           file://0209-access-lists-allow-knet_bench-to-enable-disable-acce.patch \
+           file://0210-access-lists-enable-access-lists-for-GENERIC_ACL-pro.patch \
+           file://0211-access-lists-enable-generic-access-lists-only-for-pr.patch \
+           file://0212-access-lists-add-access-lists-support-to-sctp.patch \
+           file://0213-access-lists-fix-build-on-freebsd.patch \
+           file://0214-access-lists-move-all-acl-wrappers-to-links_acl-and-.patch \
+           file://0215-access-lists-move-access-lists-structs-and-data-type.patch \
+           file://0216-access-lists-more-use-of-generic-wrappers-and-remove.patch \
+           file://0217-access-lists-cleanup-API-a-bit.patch \
+           file://0218-access-lists-remove-2-unnecessary-wrappers.patch \
+           file://0219-links-rename-transport_type-to-transport-to-avoid-co.patch \
+           file://0220-links-rename-tranport_type-to-transport-to-avoid-con.patch \
+           file://0221-access-lists-make-internal-API-consistent.patch \
+           file://0222-access-lists-fix-build-on-BSD-and-add-some-include-f.patch \
+           file://0223-access-lists-add-errno-around-and-start-using-them.patch \
+           file://0224-access-lists-confine-access-lists-data-structs-withi.patch \
+           file://0225-access-lists-use-better-name-for-fd_tracker-structur.patch \
+           file://0226-access-lists-use-arrays-to-access-per-protocol-funct.patch \
+           file://0227-access-lists-rename-ip1-2-to-ss1-2-to-keep-it-more-g.patch \
+           file://0228-transports-access-list-add-internal-API-to-gather-wh.patch \
+           file://0229-access-lists-add-documentation-for-enable_access_lis.patch \
+           file://0230-access-lists-add-external-API-calls-to-manage-access.patch \
+           file://0231-access-lists-test-implicit-access-lists-management-f.patch \
+           file://0232-access-lists-improve-checks-on-various-data-types.patch \
+           file://0233-access-lists-add-public-API-tests.patch \
+           file://0234-acl-Fix-English-in-commments.patch \
+           file://0235-access-lists-add-more-extensive-test-for-links_acl_i.patch \
+           file://0236-logging-fix-log-target-of-recently-added-API-calls.patch \
+           file://0237-tests-remove-stray-comment.patch \
+           file://0238-manpages-Document-enums-206.patch \
+           file://0239-compress-add-support-for-libzstd.patch \
+           file://0240-tests-hide-an-arm-internal-memory-leak-non-recurring.patch \
+           file://0241-tests-improve-wait-for-packet-implementation-to-flus.patch \
+           file://0242-man-fix-libknet.h-for-errors-detected-by-newly-added.patch \
+           file://0243-global-update-copyright-across-the-board.patch \
+           file://0244-build-bump-soname-to-indicate-new-API-calls.patch \
+           file://0245-spec-fix-upstream-URLs-to-point-to-https-and-officia.patch \
+           file://0246-spec-use-distro-conditionals-to-determine-BuildRequi.patch \
+           file://0247-spec-be-more-strict-about-plugins-version-and-archit.patch \
+           file://0248-spec-clean-up-useless-conditionals-and-defines.patch \
+           file://0249-spec-reconciliate-fedora-spec-file-into-upstream-spe.patch \
+           file://0250-spec-fix-a-bunch-of-rpmlint-errors.patch \
+           file://0251-spec-drop-support-for-init-scripts.patch \
+           file://0252-spec-use-ldconfig_scriptlets-only-when-defined.patch \
+           file://0253-misc-some-coverity-fixes.patch \
+           file://0254-misc-Fix-more-covscan-warnings.patch \
+           file://0255-crypto-make-sure-to-clear-all-security-info-on-crypt.patch \
+           file://0256-PMTUd-create-common-shared-code-to-trigger-PMTUd-rer.patch \
+           file://0257-crypto-make-sure-to-trigger-a-PMTUd-rerun-on-each-go.patch \
+           file://0258-crypto-rework-knet_handle_crypto-external-API-to-be-.patch \
+           file://0259-PMTUd-extend-internal-rerun-API-to-allow-full-PMTUd-.patch \
+           file://0260-crypto-fix-openssl1.0-initialization-code.patch \
+           file://0261-transports-fix-incorrect-merge-when-cherry-picking-7.patch \
+           file://0262-crypto-openssl-error-strings-release.patch \
+           file://0263-crypto-openssl-drop-calls-to-RAND_seed-as-they-don-t.patch \
+           file://0264-crypto-hide-errors-generated-by-openssl-1.1.1c.patch \
+           file://0265-doc-fix-a-merge-oversight-from-541d7faf9068d10e12b42.patch \
+           file://0266-global-clarify-license-entry-per-file-to-match-READM.patch \
+           file://0267-global-update-copyrights.patch \
+           file://0268-tests-ignore-libnss-errors-from-OpenSuse-15.patch \
+           file://0269-tests-ignore-libnss-errors-from-OpenSuse-Tumbleweed.patch \
+           file://0270-threads-allow-knet_handle_setfwd-to-flush-socket-que.patch \
+           file://0271-crypto-fix-log-information.patch \
+           file://0272-udp-log-information-about-detected-kernel-MTU.patch \
+           file://0273-docs-add-knet-packet-layout.patch \
+           file://0274-PMTUd-fix-MTU-calculation-when-using-crypto-and-add-.patch \
+           file://0275-PMTUd-rework-the-whole-math-to-calculate-MTU.patch \
+           file://0276-PMTUd-add-dynamic-pong-timeout-when-using-crypto.patch \
+           file://0277-PMTUd-add-ability-to-manually-override-MTU-and-disab.patch \
+           file://0278-build-bump-soname-to-indicate-new-API-call.patch \
+           file://0279-Default-compress-level-use.patch \
+           file://0280-compress-Default-compression-level-use.patch \
+           file://0281-compress-fix-a-few-minor-space-vs-tab-and-code-forma.patch \
+           file://0282-compress-fix-if-def-around-BZIP2-testing.patch \
+           file://0283-coverity-add-.travis.yml-to-integrate-CI-with-coveri.patch \
+           file://0284-sctp-fix-deference-after-null-check.patch \
+           file://0285-sctp-free-access-list-only-if-the-socket-is-valid.patch \
+           file://0286-rx-align-data-types.patch \
+           file://0287-handle-make-sure-that-the-pmtud-buf-contains-at-leas.patch \
+           file://0288-sctp-revalidate-fd-to-make-coverity-scan-happy.patch \
+           file://0289-tests-fix-knet_bench-coverity-errors.patch \
+           file://0290-common-fix-dlopen-error-handling.patch \
+           file://0291-rx-better-error-report-if-we-can-t-resolve-hostname-.patch \
+           file://0292-acl-avoid-forward-null-deferencing.patch \
+           file://0293-sctp-cleanup-bugs-detected-in-error-paths-by-coverit.patch \
+           file://0294-nozzle-fix-negative-return-detected-by-coverity-scan.patch \
+           file://0295-nozzle-don-t-leak-memory-on-error.patch \
+           file://0296-compress-don-t-leak-memory-in-case-of-errors-during-.patch \
+           file://0297-logging-make-sure-not-to-overrun-buffers-by-pre-allo.patch \
+           file://0298-compress-do-not-overrun-allocated-array-for-compress.patch \
+           file://0299-coverity-add-test-targets-to-run-coverity-automatica.patch \
+           file://0300-PMTUd-do-not-double-unlock-global-read-lock.patch \
+           file://0301-nozzle-avoid-tons-of-possible-buffer-overruns.patch \
+           file://0302-test-simplify-flush-log.patch \
+           file://0303-common-make-sure-string-is-null-terminated.patch \
+           file://0304-tx-drop-unnecessary-usleep-when-sending-to-localhost.patch \
+           file://0305-nozzle-fix-a-few-coverity-errors-in-the-test-suite.patch \
+           file://0306-tx-clean-up-channel-management-code-for-internal-com.patch \
+           file://0307-sctp-retry-locking-in-case-of-failure.patch \
+           file://0308-man-Fix-priority-description-of-POLICY_PASSIVE.patch \
+           file://0309-common-Include-correct-errno.h.patch \
+           file://0310-common-Conditionalize-RTLD_DI_ORIGIN.patch \
+           file://0311-handle-Set-thread-stack-size-on-create.patch \
+           file://0312-links-stabilize-latency-calculation-when-nodes-are-n.patch \
+           file://0313-pmtud-switch-to-use-async-version-of-dstcache-update.patch \
+           file://0314-nozzle-fix-tapX-range-on-newer-FreeBSD.patch \
+           file://0315-tests-fix-ip-generation-boundaries.patch \
+           file://0316-tests-give-PMTUd-more-time-to-redetect-MTU.patch \
+           file://0317-links-fix-memory-corryption-of-link-structure.patch \
+           file://0318-tests-skip-the-SCTP-test-if-SCTP-is-not-supported-by.patch \
+           file://0319-Fix-typo-trasport-transport.patch \
+           file://0320-tests-add-common-function-to-sleep-based-on-how-the-.patch \
+           file://0321-host-rename-variables-to-make-it-easier-to-read-the-.patch \
+           file://0322-host-fix-defrag-buffers-reclaim-logic.patch \
+           file://0323-rx-copy-data-into-the-defrag-buffer-only-if-we-know-.patch \
+           file://0324-test-add-ability-to-knet_bench-to-specify-a-fixed-pa.patch \
+           file://0325-PMTUd-invalidate-MTU-for-a-link-if-the-value-is-lowe.patch \
+           file://0326-test-add-packet-verification-option-to-knet_bench.patch \
+           file://0327-test-append-newline-to-knet_send-timeout-message.patch \
+           file://0328-build-fix-openssl-version-detection-when-not-using-p.patch \
+           file://0329-RX-Discard-incoming-packets-if-knet-cannot-reply-bac.patch \
+           file://0330-RX-handle-short-write-to-the-application-properly.patch \
+           file://0331-TX-discard-too-big-packets-when-reading-from-socketp.patch \
+           file://0332-RX-silence-defrag-buffer-expiration-debug-error.patch \
+           file://0333-handle-make-sure-to-unlock-config-handle-on-failure.patch \
+           file://0334-handle-fix-typo-in-error-log-message.patch \
+           file://0335-tests-mark-array-as-static.patch \
+           file://0336-host-use-KNET_MAX_HOST_LEN-consistently.patch \
+           file://0337-nozzle-use-interface-name-size-consistently-and-drop.patch \
+           file://0338-udp-don-t-make-socket-spin-if-a-network-I-F-is-down.patch \
+           file://0339-udp-simplify-code-same-logic.patch \
+           file://0340-udp-Better-fix-for-ENETUNREACH.patch \
+           file://0341-latency-fix-incorrect-math-that-could-lead-to-bad-la.patch \
+           file://0342-rx-unify-latency-values-to-a-capped-value-to-link-pr.patch \
+           file://0343-rx-send-reply-packets-only-when-transport-is-connect.patch \
+           file://0344-rx-Don-t-return-512-EOF-messages-from-_recvmmsg.patch \
+           file://0345-tx-Don-t-Clear-out-msghdr-for-all-transports.patch \
+           file://0346-rx-use-defines-to-determine-RX-data-types-vs-random-.patch \
+           file://0347-sctp-major-surgery-to-use-only-SCTP-events-to-determ.patch \
+           file://0348-global-Update-copyright-across-the-board.patch \
+           file://0349-man-Fix-covscan-reports-in-doxyxml.c.patch \
+           file://0350-man-Change-strcat-to-strncat.patch \
+           file://0351-man-Enhance-prio-description-of-POLICY_PASSIVE.patch \
+           file://0352-transports-use-SO_REUSEADDR-only-for-sctp.patch \
+           file://0353-tests-rework-test-suite-link-port-allocation.patch \
+           file://0354-rx-kill-unused-variable.patch \
+           file://0355-stats-allow-knet_handle_get_stats-to-operate-in-a-re.patch \
+           file://0356-stats-allow-knet_link_get_status-to-operate-in-readl.patch \
+           file://0357-tests-fix-return-code-from-wait_for_packet.patch \
+           file://0358-lists-fix-build-with-recent-gcc-changes.patch \
+           file://0359-lists-drop-internal-implementation-and-use-libqb-one.patch \
+           file://0360-lists-add-missing-build-CFLAGS-for-test-suite.patch \
+           file://0361-build-make-sure-to-use-correct-libqb-include-files-a.patch \
+           file://0362-man-use-libqb-version-of-doxygen2man-when-available.patch \
+           file://0363-sctp-make-sure-outgoing-connections-are-bound-to-a-s.patch \
+           file://0364-links-fix-spacing.patch \
+           file://0365-netutils-move-sockaddr_len-definition-where-it-belon.patch \
+           file://0366-sctp-fix-ifup-ifdown-handling-for-connected-sockets.patch \
+           file://0367-transport-notify-transports-that-a-link-is-down.patch \
+           file://0368-Always-define-the-Automake-conditional.patch \
+           file://0369-tests-strip-extra-symbol-information-generated-by-ne.patch \
+           file://0370-openssl-allow-use-of-deprecated-HMAC-interface-with-.patch \
+           file://0371-man-sync-doxygen2man-from-libqb-master.patch \
+           file://0372-build-Fix-fallback-handling-in-git-version-gen.patch \
+           file://0373-build-Use-git-version-gen-during-specfile-build.patch \
+           file://0374-tests-remove-unnecessary-shutdown-locking.patch \
+           file://0375-tests-use-link_get_enable-instead-of-get_status.patch \
+           file://0376-tests-add-basic-framework-to-create-join-and-stop-ma.patch \
+           file://0377-tests-sets-defaults-for-coverity-scan-check-to-match.patch \
+           file://0378-build-update-valgrind-memcheck-exception-file.patch \
+           file://0379-crypto-add-support-for-live-reconfiguration.patch \
+           file://0380-Update-copyright.patch \
+           file://0381-tests-fix-variable-increment-logic-detected-by-clang.patch \
+           file://0382-tests-ignore-openssl-errors-triggered-when-building-.patch \
+           file://0383-tests-more-ignore-list-of-nss-internal-stuff.patch \
+           file://0384-man-fix-type-comparison.patch \
+           file://0385-f6b11c05112c520ccda3b28e7676acbc6b8a7938.patch \
+           file://0386-crypto-add-support-for-openssl-3.0.patch \
+           file://0387-cleanup-Move-public-APIs-calls-to-more-suitable-loca.patch \
+           file://0388-cleanup-kill-all-unsupported-kronosnetd-code.patch \
+           file://0389-cleanup-drop-no-longer-used-poc-code.patch \
+           file://0390-threads-make-sure-to-initialize-events.patch \
+           file://0391-rx-fix-per-link-stats-for-data-packets.patch \
+           file://0392-rx-fix-data-stats-on-RX-to-match-TX-model.patch \
+           file://0393-tests-hide-internal-nss-memory-leak-non-recurring.patch \
+           file://0394-heartbeat-don-t-send-ping-if-transport-is-not-connec.patch \
+           file://0395-Revert-heartbeat-don-t-send-ping-if-transport-is-not.patch \
+           file://0396-sctp-check-and-warn-about-internal-fd-tracker.patch \
+           file://0397-cleanup-remove-unused-infrastructure-to-send-HOSTINF.patch \
+           file://0398-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch \
+           file://0399-tests-add-more-exceptions-to-deal-with-Ubuntu-latest.patch \
+           file://0400-tests-hide-another-internal-libnss-non-recurring-mem.patch \
+           file://0401-Drop-travis-support.patch \
+           file://0402-tests-Fix-some-random-CI-failures.patch \
+           file://0403-tests-use-callbacks-to-wait-for-nodes.patch \
+           file://0404-Add-some-more-uses-for-event-based-tests.patch \
+           file://0405-openssl-port-knet-top-openssl3.0-alpha13.patch \
+           file://0406-docs-Update-README-for-BSD-section.patch \
+           file://0407-global-Update-copyright.patch \
+           file://0408-handle-validate-handle-in-public-API.patch \
+           file://0409-nozzle-Remove-inet_ntoa-call.patch \
+           file://0410-lib-Don-t-use-rpath.patch \
+           file://0411-nozzle-fix-nozzle_up-on-FreeBSD.patch \
+           file://0412-coverity-fix-2-buffer-initialization-potential-issue.patch \
+           file://0413-docs-IRC-channel-is-now-on-Libera-Chat.patch \
+           file://0414-send-correct-sockaddr-lengths-to-socket-calls.patch \
+           file://0415-tx-minor-optimizations-to-avoid-recalculating-socksi.patch \
+           file://0416-Require-make-utility.patch \
+           file://0417-Update-copyright-around.patch \
+           file://0418-Sanitise-sockaddr_storage-structs-coming-in-the-API.patch \
+           file://0419-Add-comment-about-log_fd-in-knet_handle_new.patch \
+           file://0420-spec-cleanup-some-krosnonetd-leftovers.patch \
+           file://0421-tests-suppress-more-libnss3-errors.patch \
+           file://0422-link-don-t-leak-resources-if-link-configuration-fail.patch \
+           file://0423-link-use-previously-cached-value-as-link-info-might-.patch \
+           file://0424-link-don-t-allow-mix-of-dynamic-and-static-links.patch \
+           file://0425-doc-Add-comments-to-structure-members.patch \
+           file://0426-man-update-doxygen2man-to-latest-from-libqb.patch \
+           file://0427-rx-increase-defrag-buffers-to-better-deal-with-netwo.patch \
+           file://0428-host-use-correct-seq_num-to-reclaim-buffers.patch \
+           file://0429-acl-make-knet_link_add_acl-a-wrapper-to-knet_link_in.patch \
+           file://0430-acl-major-internal-rework.patch \
+           file://0431-transports-remove-unused-internal-ACL-API.patch \
+           file://0432-send-Fix-send_sync.patch \
+           file://0433-tests-make-execution-of-functional-testing-optionals.patch \
+           file://0434-test-Use-a-pipe-to-synchronise-wait_for_xxx-events.patch \
+           file://0435-nozzle-skip-tests-if-TUN-support-is-not-available.patch \
+           file://0436-nozzle-preserve-test-result-across-cleanup.patch \
+           file://0437-nozzle-fix-tests-on-machines-that-don-t-have-bash.patch \
+           file://0438-build-Add-annobin-build-check-support.patch \
+           file://0439-tests-temporary-disable-annobin-lto-check-for-centos.patch \
+           file://0440-libknet-tests-Correct-include-path-for-poll.h.patch \
+           file://0441-build-fix-debug-build-vs-annocheck-parameters.patch \
+           file://0442-crypto-fix-nss-crypto-buffer-boundaries-usage.patch \
+           file://0443-host-fix-dst_seq_num-initialization-race-condition.patch \
+           file://0444-udp-use-ICMP-error-messages-to-trigger-faster-link-d.patch \
+           file://0445-crypto-improve-logging-when-failing-to-decrypt-packe.patch \
+           file://0446-logging-slow-down-knet-a-bit-when-log-socket-is-busy.patch \
+           file://0447-doc-update-links-to-mailing-lists-and-drop-obsolete-.patch \
+           file://0448-build-fix-flag-detections-for-gcc.patch \
+           file://0449-UDP-Check-for-EHOSTUNREACH.patch \
+           file://0450-tests-move-all-tests-to-new-infrastructure.patch \
+           file://0451-tests-update-memcheck-exceptions.patch \
+           file://0452-tests-deal-with-new-annocheck-symlink-checks.patch \
+           file://0453-tx-fix-epoll-event-size-to-cope-with-extra-event-on-.patch \
+           file://0454-logging-Fix-Initializing-typo.patch \
+           file://0455-doc-To-Do-list-moved-to-projects.clusterlabs.org-379.patch \
+           "
+
+UPSTREAM_CHECK_URI = "https://github.com/kronosnet/kronosnet/releases"
+
+inherit autotools pkgconfig
+
+S = "${WORKDIR}/git"
+
+# libknet/transport_udp.c:326:48: error: comparison of integers of different signs: 'unsigned long' and 'int' [-Werror,-Wsign-compare]
+# for (cmsg = CMSG_FIRSTHDR(&msg);cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+#                                                             ^~~~~~~~~~~~~~~~~~~~~~~
+CFLAGS:append:toolchain-clang = " -Wno-sign-compare"
+
+PACKAGECONFIG[man] = "enable_man="yes", --disable-man, "
+
+PACKAGECONFIG:remove = "man"