Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

zebra: add PBR script wrapper framework to interact with script #2025

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,8 @@ AC_ARG_ENABLE([clippy-only],
AS_HELP_STRING([--enable-clippy-only], [Only build clippy]))
AC_ARG_ENABLE([numeric_version],
AS_HELP_STRING([--enable-numeric-version], [Only numeric digits allowed in version (for Alpine)]))
AC_ARG_ENABLE(wrap_script,
AS_HELP_STRING([--enable-wrap-script], [enable Usage of Script Wrapping Layer]))

AS_IF([test "${enable_clippy_only}" != "yes"], [
AC_CHECK_HEADERS(json-c/json.h)
Expand Down Expand Up @@ -495,6 +497,7 @@ if test "${enable_shell_access}" = "yes"; then
fi

AM_CONDITIONAL([FPM], [test "x$enable_fpm" = "xyes"])
AM_CONDITIONAL([WRAP_SCRIPT], [test "x$enable_wrap_script" = "xyes"])

#
# Python for clippy
Expand Down
26 changes: 26 additions & 0 deletions doc/user/basic.rst
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,32 @@ specifying the encapsulation to use. ``Netlink`` is the default, and
``protobuf`` may not be available if the module was built without protobuf
support. Refer to :ref:`zebra-fib-push-interface` for more information.

The Script WRAP Module
----------------------

If Wrap Script is enabled during compile-time and installed as part of the
package, the ``wrap_script`` module can be loaded for the *Zebra* daemon. This
provides the *Zebra* Script Wrapper interface to be available for handling
underlying firewall elements. Specifically, if the system where FRR is is Linux,
default firewall used is `Linux netfilters`. Note that the interface terminology
is tightly linked with `Linux netfilters` main objects, that is to say `iptables`
and `ipset`. But we will see that that module can configure or monitor other
similar objects.
Instead of using ioctl() operations, this wrap interface permits using either
underlying shell commands ( from where the FRR is based on) or custom scripts. This
can be done by using a vty command to configure which execution path to call for
`iptables` or `ipset` object. The vty commands can directly configure the native
Linux netfilter tools. Or the vty commands can reference external shell script that
will be called. This second case may be used for non Linux systems, or for users
that do not want to use netfilters, but want to use an other set of tools like `eBPF`
or `NFTables`.
The wrap script module proposes configuration APIs to create `ipset` and `iptables`
objects. Monitoring APIs will first return a json like format based on the output
of the 2 underlying objects. Here too, the format analysed is tightly linked with
the Linux format of `ipset` and `iptables`. However, even if the tools used are not
based on `Netfilter`, it will still be possible to use a strict to return json format
output similar to `ipset` and `iptables`.

.. _virtual-terminal-interfaces:

Virtual Terminal Interfaces
Expand Down
1 change: 1 addition & 0 deletions lib/command.c
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ const char *node_names[] = {
*/
"bgp ipv6 flowspec", /* BGP_FLOWSPECV6_NODE
*/
"Wrap Script", /* WRAP_SCRIPT_NODE */
};
/* clang-format on */

Expand Down
1 change: 1 addition & 0 deletions lib/command.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,7 @@ enum node_type {
connections.*/
BGP_FLOWSPECV4_NODE, /* BGP IPv4 FLOWSPEC Address-Family */
BGP_FLOWSPECV6_NODE, /* BGP IPv6 FLOWSPEC Address-Family */
WRAP_SCRIPT_NODE, /* Wrap Script Config commands */
NODE_TYPE_MAX, /* maximum */
};

Expand Down
2 changes: 1 addition & 1 deletion vtysh/vtysh_config.c
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ void vtysh_config_parse_line(void *arg, const char *line)
|| (I) == ACCESS_IPV6_NODE || (I) == ACCESS_MAC_NODE \
|| (I) == PREFIX_IPV6_NODE || (I) == FORWARDING_NODE \
|| (I) == DEBUG_NODE || (I) == AAA_NODE || (I) == VRF_DEBUG_NODE \
|| (I) == MPLS_NODE)
|| (I) == MPLS_NODE || (I) == WRAP_SCRIPT_NODE)

/* Display configuration to file pointer. */
void vtysh_config_dump(FILE *fp)
Expand Down
6 changes: 6 additions & 0 deletions zebra/rule_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,12 @@ static int netlink_rule_update(int cmd, struct zebra_pbr_rule *rule)
&rule->rule.filter.dst_ip.u.prefix, bytelen);
}

/* fwmark, if specified */
if (IS_RULE_FILTERING_ON_FWMARK(rule)) {
addattr32(&req.n, sizeof(req), FRA_FWMARK,
rule->rule.filter.fwmark);
}

/* Route table to use to forward, if filter criteria matches. */
if (rule->rule.action.table < 256)
req.frh.table = rule->rule.action.table;
Expand Down
9 changes: 9 additions & 0 deletions zebra/subdir.am
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ if FPM
module_LTLIBRARIES += zebra/zebra_fpm.la
endif

if WRAP_SCRIPT
module_LTLIBRARIES += zebra/zebra_wrap_script.la
endif

## endif ZEBRA
endif

Expand Down Expand Up @@ -142,6 +146,11 @@ zebra_zebra_fpm_la_SOURCES += zebra/zebra_fpm_dt.c
endif
endif

if WRAP_SCRIPT
zebra_zebra_wrap_script_la_SOURCES = zebra/zebra_wrap_script.c
zebra_zebra_wrap_script_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
endif

EXTRA_DIST += \
zebra/GNOME-SMI \
zebra/GNOME-PRODUCT-ZEBRA-MIB \
Expand Down
2 changes: 2 additions & 0 deletions zebra/zapi_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -2798,6 +2798,7 @@ static inline void zread_ipset(ZAPI_HANDLER_ARGS)
memset(&zpi, 0, sizeof(zpi));

zpi.sock = client->sock;
zpi.vrf_id = zvrf->vrf->vrf_id;
STREAM_GETL(s, zpi.unique);
STREAM_GETL(s, zpi.type);
STREAM_GET(&zpi.ipset_name, s, ZEBRA_IPSET_NAME_SIZE);
Expand Down Expand Up @@ -2865,6 +2866,7 @@ static inline void zread_iptable(ZAPI_HANDLER_ARGS)
memset(&zpi, 0, sizeof(zpi));

zpi.sock = client->sock;
zpi.vrf_id = zvrf->vrf->vrf_id;
STREAM_GETL(s, zpi.unique);
STREAM_GETL(s, zpi.type);
STREAM_GETL(s, zpi.filter_bm);
Expand Down
4 changes: 2 additions & 2 deletions zebra/zebra_ns.c
Original file line number Diff line number Diff line change
Expand Up @@ -262,10 +262,10 @@ int zebra_ns_disable(ns_id_t ns_id, void **info)

hash_clean(zns->rules_hash, zebra_pbr_rules_free);
hash_free(zns->rules_hash);
hash_clean(zns->ipset_hash, zebra_pbr_ipset_free);
hash_free(zns->ipset_hash);
hash_clean(zns->ipset_entry_hash,
zebra_pbr_ipset_entry_free),
hash_clean(zns->ipset_hash, zebra_pbr_ipset_free);
hash_free(zns->ipset_hash);
hash_free(zns->ipset_entry_hash);
hash_clean(zns->iptable_hash,
zebra_pbr_iptable_free);
Expand Down
Loading