From ddb77204b3aae8cdcc3530237b0dc84f63329b47 Mon Sep 17 00:00:00 2001 From: Jiaxun Yang Date: Wed, 22 Nov 2023 16:11:00 +0000 Subject: [PATCH] Implement firewall address-list output for MikroTik In RouterOS v7 we can setup filters based on firewall address-list. Thus output prefixes into address-list can be very useful. Semantics of firewall address-list remain the same in RouterOS v6 as well. -E option is selected for firewall address-list function. Ref: https://help.mikrotik.com/docs/display/ROS/Address-lists Signed-off-by: Jiaxun Yang --- main.c | 15 ++++++++++++--- printer.c | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/main.c b/main.c index bb8b3c6..7a19996 100644 --- a/main.c +++ b/main.c @@ -85,9 +85,10 @@ usage(int ecode) printf(" -3 : assume that your device is asn32-safe (default)\n"); printf(" -A : try to aggregate prefix-lists/route-filters\n"); printf(" -E : generate extended access-list (Cisco), " - "route-filter (Juniper)\n" - " [ip|ipv6]-prefix-list (Nokia) or prefix-set " - "(OpenBGPD)\n"); + "route-filter (Juniper),\n" + " [ip|ipv6]-prefix-list (Nokia), " + "prefix-set (OpenBGPD),\n" + " or firewall address-list (MikroTik)\n"); printf(" -f number : generate input as-path access-list\n"); printf(" -G number : generate output as-path access-list\n"); printf(" -H number : generate origin as-lists (JunOS only)\n"); @@ -582,6 +583,14 @@ main(int argc, char* argv[]) exit(1); } + if (aggregate + && (expander.vendor == V_MIKROTIK6 || expander.vendor == V_MIKROTIK7) + && expander.generation == T_EACL) { + sx_report(SX_FATAL, "Sorry, aggregation (-A) is not supported with " + "firewall address-list (-E) on MikroTik.\n"); + exit(1); + } + if (refine && (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA || expander.vendor == V_NOKIA_SRL) && expander.generation != T_PREFIXLIST) { diff --git a/printer.c b/printer.c index d97cb71..8466d97 100644 --- a/printer.c +++ b/printer.c @@ -1896,6 +1896,41 @@ bgpq4_print_mikrotik_prefixlist(FILE *f, struct bgpq_expander *b) } } +static void +bgpq4_print_mikrotik_address(struct sx_radix_node *n, void *ff) +{ + char prefix[128]; + FILE *f = (FILE*)ff; + + if (!f) + f = stdout; + + if (n->isGlue) + goto checkSon; + + sx_prefix_snprintf_sep(n->prefix, prefix, sizeof(prefix), "/"); + + fprintf(f,"/%s firewall address-list add list=\"%s\" address=%s\n", + n->prefix->family == AF_INET ? "ip" : "ipv6", + bname, prefix); + +checkSon: + if (n->son) + bgpq4_print_mikrotik_address(n->son, ff); +} + +static void +bgpq4_print_mikrotik_addresslist(FILE *f, struct bgpq_expander *b) +{ + bname = b->name ? b->name : "NN"; + + if (!sx_radix_tree_empty(b->tree)) { + sx_radix_tree_foreach(b->tree, bgpq4_print_mikrotik_address, f); + } else { + fprintf(f, "# generated prefix-list %s is empty\n", bname); + } +} + void bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b) { @@ -1969,6 +2004,10 @@ bgpq4_print_eacl(FILE *f, struct bgpq_expander *b) case V_NOKIA_SRL: bgpq4_print_nokia_srl_aclipfilter(f, b); break; + case V_MIKROTIK6: + case V_MIKROTIK7: + bgpq4_print_mikrotik_addresslist(f, b); + break; default: sx_report(SX_FATAL, "unreachable point\n"); }