From 2921348a98cf49b36a07689172aed0a2258a640c Mon Sep 17 00:00:00 2001 From: Denis Fondras Date: Sat, 5 Nov 2022 12:06:54 +0100 Subject: [PATCH] add support for Mikrotik ROSv7 filters (#72) * add support for Mikrotik ROSv7 filters * Rework Mikrotik ROSv7 option - Use same option key with a modifier - avoid some code duplication * update doc Co-authored-by: Denis --- README.md | 6 +++++- bgpq4.8 | 4 +++- extern.h | 3 ++- main.c | 23 ++++++++++++++++------- printer.c | 45 +++++++++++++++++++++++++++++++++++++++++---- 5 files changed, 67 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index efca8a0..cc7f84d 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,11 @@ It's options are as follows: **-K** -> generate config for Mikrotik (default: Cisco). +> generate config for Mikrotik ROSv6 (default: Cisco). + +**-K7** + +> generate config for Mikrotik ROSv7 (default: Cisco). **-l** *name* diff --git a/bgpq4.8 b/bgpq4.8 index 65d3602..bd2aabb 100644 --- a/bgpq4.8 +++ b/bgpq4.8 @@ -95,7 +95,9 @@ generate config for Juniper (default: Cisco). .It Fl j generate output in JSON format (default: Cisco). .It Fl K -generate config for Mikrotik (default: Cisco). +generate config for Mikrotik ROSv6 (default: Cisco). +.It Fl K7 +generate config for Mikrotik ROSv7 (default: Cisco). .It Fl l Ar name name of generated entry. .It Fl L Ar limit diff --git a/extern.h b/extern.h index b729df7..c64e755 100644 --- a/extern.h +++ b/extern.h @@ -59,7 +59,8 @@ typedef enum { V_NOKIA, V_HUAWEI, V_HUAWEI_XPL, - V_MIKROTIK, + V_MIKROTIK6, + V_MIKROTIK7, V_NOKIA_MD, V_ARISTA } bgpq_vendor_t; diff --git a/main.c b/main.c index aa7b008..ad59652 100644 --- a/main.c +++ b/main.c @@ -59,7 +59,8 @@ usage(int ecode) printf(" -u : Huawei XPL\n"); printf(" -j : JSON\n"); printf(" -J : Juniper Junos\n"); - printf(" -K : MikroTik RouterOS\n"); + printf(" -K : MikroTik RouterOSv6\n"); + printf(" -K7 : MikroTik RouterOSv7\n"); printf(" -b : NIC.CZ BIRD\n"); printf(" -N : Nokia SR OS (Classic CLI)\n"); printf(" -n : Nokia SR OS (MD-CLI)\n"); @@ -132,9 +133,9 @@ static void vendor_exclusive(void) { fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (Junos)," - " -j (JSON), -N (Nokia SR OS Classic), -n (Nokia SR OS MD-CLI)," - " -U (Huawei), -u (Huawei XPL), -e (Arista) and -X (IOS XR) options " - " are mutually exclusive\n"); + " -j (JSON), -K[7] (Microtik ROS), -N (Nokia SR OS Classic)," + " -n (Nokia SR OS MD-CLI), -U (Huawei), -u (Huawei XPL)," + "-e (Arista) and -X (IOS XR) options are mutually exclusive\n"); exit(1); } @@ -196,7 +197,7 @@ main(int argc, char* argv[]) expander.sources=getenv("IRRD_SOURCES"); while ((c = getopt(argc, argv, - "46a:AbBdDEeF:S:jJKf:l:L:m:M:NnW:r:R:G:H:tTh:UuwXsvz")) != EOF) { + "467a:AbBdDEeF:S:jJKf:l:L:m:M:NnW:r:R:G:H:tTh:UuwXsvz")) != EOF) { switch (c) { case '4': /* do nothing, expander already configured for IPv4 */ @@ -217,6 +218,13 @@ main(int argc, char* argv[]) expander.family = AF_INET6; expander.tree->family = AF_INET6; break; + case '7': + if (expander.vendor != V_MIKROTIK6) { + sx_report(SX_FATAL, "'7' can only be used after -K\n"); + exit(1); + } + expander.vendor = V_MIKROTIK7; + break; case 'a': parseasnumber(&expander, optarg); break; @@ -296,7 +304,7 @@ main(int argc, char* argv[]) case 'K': if (expander.vendor) vendor_exclusive(); - expander.vendor = V_MIKROTIK; + expander.vendor = V_MIKROTIK6; break; case 'r': refineLow = strtoul(optarg, NULL, 10); @@ -447,7 +455,8 @@ main(int argc, char* argv[]) switch (vendor) { case V_ARISTA: case V_CISCO: - case V_MIKROTIK: + case V_MIKROTIK6: + case V_MIKROTIK7: expander.aswidth = 4; break; case V_CISCO_XR: diff --git a/printer.c b/printer.c index 310527d..93fed63 100644 --- a/printer.c +++ b/printer.c @@ -1717,7 +1717,7 @@ bgpq4_print_nokia_md_ipprefixlist(FILE *f, struct bgpq_expander *b) } static void -bgpq4_print_kprefix(struct sx_radix_node *n, void *ff) +bgpq4_print_k6prefix(struct sx_radix_node *n, void *ff) { char prefix[128]; FILE *f = (FILE*)ff; @@ -1745,16 +1745,52 @@ bgpq4_print_kprefix(struct sx_radix_node *n, void *ff) checkSon: if (n->son) - bgpq4_print_kprefix(n->son, ff); + bgpq4_print_k6prefix(n->son, ff); +} + +static void +bgpq4_print_k7prefix(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), "/"); + + if (n->isAggregate) + fprintf(f,"/routing filter rule add chain=\"" + "%s-%s\" rule=\"if (dst in %s && dst-len in %d-%d) {accept}\"\n", + bname ? bname : "NN", + n->prefix->family == AF_INET ? "V4" : "V6", + prefix, n->aggregateLow, n->aggregateHi); + else + fprintf(f,"/routing filter rule add chain=\"" + "%s-%s\" rule=\"if (dst=%s) {accept}\"\n", + bname ? bname : "NN", + n->prefix->family == AF_INET ? "V4" : "V6", + prefix); + +checkSon: + if (n->son) + bgpq4_print_k7prefix(n->son, ff); } static void bgpq4_print_mikrotik_prefixlist(FILE *f, struct bgpq_expander *b) { bname = b->name ? b->name : "NN"; + void *cbfunc = bgpq4_print_k6prefix; + + if (b->vendor == V_MIKROTIK7) + cbfunc = bgpq4_print_k7prefix; if (!sx_radix_tree_empty(b->tree)) { - sx_radix_tree_foreach(b->tree, bgpq4_print_kprefix, f); + sx_radix_tree_foreach(b->tree, cbfunc, f); } else { fprintf(f, "# generated prefix-list %s is empty\n", bname); } @@ -1797,7 +1833,8 @@ bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b) case V_HUAWEI_XPL: bgpq4_print_huawei_xpl_prefixlist(f, b); break; - case V_MIKROTIK: + case V_MIKROTIK6: + case V_MIKROTIK7: bgpq4_print_mikrotik_prefixlist(f, b); break; case V_ARISTA: