Huawei XPL format support (#45)

Add Huawei XPL format support
This commit is contained in:
Stefan Marti
2021-09-02 22:45:45 +02:00
committed by GitHub
parent d285db3c81
commit 2aed3f9e67
5 changed files with 147 additions and 3 deletions

View File

@@ -163,6 +163,10 @@ The options are as follows:
> generate config for Huawei devices (Cisco IOS by default)
**-u**
> generate output in Huawei XPL format.
**-X**
> generate config for Cisco IOS XR devices (plain IOS by default).

View File

@@ -124,6 +124,8 @@ disable pipelining (not recommended).
generate as-path strings of no more than len items (use 0 for inifinity).
.It Fl U
generate config for Huawei devices (Cisco IOS by default)
.It Fl u
generate config for Huawei devices in XPL format (Cisco IOS by default)
.It Fl X
generate config for Cisco IOS XR devices (plain IOS by default).
.It Fl z

View File

@@ -58,6 +58,7 @@ typedef enum {
V_FORMAT,
V_NOKIA,
V_HUAWEI,
V_HUAWEI_XPL,
V_MIKROTIK,
V_NOKIA_MD,
V_ARISTA

12
main.c
View File

@@ -59,6 +59,7 @@ usage(int ecode)
printf(" no option : Cisco IOS Classic (default)\n");
printf(" -X : Cisco IOS XR\n");
printf(" -U : Huawei\n");
printf(" -u : Huawei XPL\n");
printf(" -j : JSON\n");
printf(" -J : Juniper Junos\n");
printf(" -K : MikroTik RouterOS\n");
@@ -134,8 +135,8 @@ 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), -e (Arista) and -X (IOS XR) options are mutually"
" exclusive\n");
" -U (Huawei), -u (Huawei XPL), -e (Arista) and -X (IOS XR) options "
" are mutually exclusive\n");
exit(1);
}
@@ -197,7 +198,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:pr:R:G:tTh:UwXsvz")) != EOF) {
"46a:AbBdDEeF:S:jJKf:l:L:m:M:NnW:pr:R:G:tTh:UuwXsvz")) != EOF) {
switch (c) {
case '4':
/* do nothing, expander already configured for IPv4 */
@@ -402,6 +403,11 @@ main(int argc, char* argv[])
exclusive();
expander.vendor = V_HUAWEI;
break;
case 'u':
if (expander.vendor)
exclusive();
expander.vendor = V_HUAWEI_XPL;
break;
case 'W':
expander.aswidth = atoi(optarg);
if (expander.aswidth < 0) {

131
printer.c
View File

@@ -406,6 +406,43 @@ bgpq4_print_huawei_aspath(FILE *f, struct bgpq_expander *b)
fprintf(f, ")$\n");
}
static void
bgpq4_print_huawei_xpl_aspath(FILE *f, struct bgpq_expander *b)
{
int nc = 0, comma = 1;
struct asn_entry *asne, find, *res;
fprintf(f, "xpl as-path-list %s", b->name);
find.asn = b->asnumber;
if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) {
fprintf(f, "\n regular ^%u(_%u)*$", res->asn, res->asn);
RB_REMOVE(asn_tree, &b->asnlist, res);
}
RB_FOREACH(asne, asn_tree, &b->asnlist) {
if (!nc) {
fprintf(f, "%s\n regular ^%u(_[0-9]+)*_(%u",
comma ? "," : "",
b->asnumber,
asne->asn);
comma = 1;
} else
fprintf(f, "|%u", asne->asn);
nc++;
if (nc == b->aswidth) {
fprintf(f, ")$");
nc = 0;
}
}
if (nc)
fprintf(f, ")$");
fprintf(f, "\nend-list\n");
}
static void
bgpq4_print_huawei_oaspath(FILE *f, struct bgpq_expander *b)
{
@@ -445,6 +482,42 @@ bgpq4_print_huawei_oaspath(FILE *f, struct bgpq_expander *b)
fprintf(f, ")$\n");
}
static void
bgpq4_print_huawei_xpl_oaspath(FILE *f, struct bgpq_expander *b)
{
int nc = 0, comma = 0;
struct asn_entry *asne, find, *res;
fprintf(f, "xpl as-path-list %s", b->name);
find.asn = b->asnumber;
if ((res = RB_FIND(asn_tree, &b->asnlist, &find)) != NULL) {
fprintf(f, "\n regular ^(_%u)*$", res->asn);
RB_REMOVE(asn_tree, &b->asnlist, res);
comma = 1;
}
RB_FOREACH(asne, asn_tree, &b->asnlist) {
if (!nc) {
fprintf(f,"%s\n regular ^(_[0-9]+)*_(%u",
comma ? "," : "", asne->asn);
comma = 1;
} else
fprintf(f,"|%u",asne->asn);
nc++;
if (nc == b->aswidth) {
fprintf(f,")$");
nc = 0;
}
}
if (nc)
fprintf(f,")$");
fprintf(f,"\nend-list\n");
}
static void
bgpq4_print_nokia_oaspath(FILE *f, struct bgpq_expander *b)
{
@@ -763,6 +836,9 @@ bgpq4_print_aspath(FILE *f, struct bgpq_expander *b)
case V_HUAWEI:
bgpq4_print_huawei_aspath(f, b);
break;
case V_HUAWEI_XPL:
bgpq4_print_huawei_xpl_aspath(f, b);
break;
default:
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
}
@@ -794,6 +870,9 @@ bgpq4_print_oaspath(FILE *f, struct bgpq_expander *b)
case V_HUAWEI:
bgpq4_print_huawei_oaspath(f, b);
break;
case V_HUAWEI_XPL:
bgpq4_print_huawei_xpl_oaspath(f, b);
break;
default:
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
}
@@ -973,6 +1052,43 @@ checkSon:
bgpq4_print_hprefix(n->son, ff);
}
static void
bgpq4_print_hprefixxpl(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) {
if (n->aggregateLow>n->prefix->masklen) {
fprintf(f,"%s %s ge %u le %u",
needscomma ? ",\n " : " ",
prefix, n->aggregateLow, n->aggregateHi);
} else {
fprintf(f,"%s %s le %u",
needscomma ? ",\n " : " ",
prefix, n->aggregateHi);
}
} else {
fprintf(f, "%s %s",
needscomma ? ",\n " : " ",
prefix);
}
needscomma = 1;
checkSon:
if (n->son)
bgpq4_print_hprefixxpl(n->son, ff);
}
static void
bgpq4_print_eprefix(struct sx_radix_node *n, void *ff)
{
@@ -1369,6 +1485,18 @@ bgpq4_print_huawei_prefixlist(FILE *f, struct bgpq_expander *b)
}
}
static void
bgpq4_print_huawei_xpl_prefixlist(FILE* f, struct bgpq_expander* b)
{
bname = b->name ? b->name : "NN";
fprintf(f, "no xpl %s-prefix-list %s\nxpl %s-prefix-list %s\n", b->family==AF_INET ? "ip" : "ipv6", bname, b->family==AF_INET ? "ip" : "ipv6", bname);
sx_radix_tree_foreach(b->tree, bgpq4_print_hprefixxpl, f);
fprintf(f, "\nend-list\n");
}
static void
bgpq4_print_arista_prefixlist(FILE *f, struct bgpq_expander *b)
{
@@ -1615,6 +1743,9 @@ bgpq4_print_prefixlist(FILE *f, struct bgpq_expander *b)
case V_HUAWEI:
bgpq4_print_huawei_prefixlist(f, b);
break;
case V_HUAWEI_XPL:
bgpq4_print_huawei_xpl_prefixlist(f, b);
break;
case V_MIKROTIK:
bgpq4_print_mikrotik_prefixlist(f, b);
break;