summaryrefslogtreecommitdiff
path: root/lib/asn.c
diff options
context:
space:
mode:
authorPhilippe Guibert <philippe.guibert@6wind.com>2022-11-03 21:17:57 +0100
committerPhilippe Guibert <philippe.guibert@6wind.com>2023-02-10 10:27:23 +0100
commite55b08839914a3b94f361ee909ee63d265d07845 (patch)
tree258aa3c96dfaefebaca81283ed35a2c2b7456684 /lib/asn.c
parent8079a4138d61500117ebbffb250ceba0a894f9c0 (diff)
bgpd: add as-notation keyword to 'router bgp' vty command
A new keyword permits changing the BGP as-notation output: - [no] router bgp <> [vrf BLABLA] [as-notation [<dot|plain|dot+>]] At the BGP instance creation, the output will inherit the way the BGP instance is declared. For instance, the 'router bgp 1.1' command will configure the output in the dot format. However, if the client wants to choose an alternate output, he will have to add the extra command: 'router bgp 1.1 as-notation dot+'. Also, if the user wants to have plain format, even if the BGP instance is declared in dot format, the keyword can also be used for that. The as-notation output is only taken into account at the BGP instance creation. In the case where VPN instances are used, a separate instance may be dynamically created. In that case, the real as-notation format will be taken into acccount at the first configuration. Linking the as-notation format with the BGP instance makes sense, as the operators want to keep consistency of what they configure. One technical reason why to link the as-notation output with the BGP instance creation is that the as-path segment lists stored in the BGP updates use a string representation to handle aspath operations (by using regexp for instance). Changing on the fly the output needs to regenerate this string representation to the correct format. Linking the configuration to the BGP instance creation avoids refreshing the BGP updates. A similar mechanism is put in place in junos too. Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'lib/asn.c')
-rw-r--r--lib/asn.c43
1 files changed, 34 insertions, 9 deletions
diff --git a/lib/asn.c b/lib/asn.c
index 7a786866cb..502854ec95 100644
--- a/lib/asn.c
+++ b/lib/asn.c
@@ -23,18 +23,28 @@
static bool relax_as_zero;
+static const struct message asnotation_mode_msg[] = {
+ {ASNOTATION_PLAIN, "plain"},
+ {ASNOTATION_DOT, "dot"},
+ {ASNOTATION_DOTPLUS, "dot+"},
+ {ASNOTATION_UNDEFINED, "undefined"},
+ {0}
+};
+
/* converts a string into an Autonomous system number
* "1.1" => 65536
* "65500" => 65500
*/
static bool asn_str2asn_internal(const char *asstring, as_t *asn,
- const char **next, bool *partial)
+ const char **next, bool *partial,
+ enum asnotation_mode *mode)
{
uint32_t high = 0, low = 0;
uint64_t temp_val;
const char *p = asstring;
bool ret = false;
uint32_t digit;
+ enum asnotation_mode val = ASNOTATION_PLAIN;
if (!asstring)
goto end;
@@ -82,12 +92,13 @@ static bool asn_str2asn_internal(const char *asstring, as_t *asn,
*partial = true;
goto end;
}
- if (!asn) {
- ret = true;
- goto end;
- }
- *asn = (high << 16) + low;
+ if (asn)
+ *asn = (high << 16) + low;
ret = true;
+ if (high == 0)
+ val = ASNOTATION_DOTPLUS;
+ else
+ val = ASNOTATION_DOT;
goto end;
}
/* AS 0 is forbidden */
@@ -102,12 +113,14 @@ static bool asn_str2asn_internal(const char *asstring, as_t *asn,
end:
if (next)
*next = p;
+ if (mode)
+ *mode = val;
return ret;
}
bool asn_str2asn(const char *asstring, as_t *asn)
{
- return asn_str2asn_internal(asstring, asn, NULL, NULL);
+ return asn_str2asn_internal(asstring, asn, NULL, NULL, NULL);
}
const char *asn_asn2asplain(as_t asn)
@@ -124,7 +137,7 @@ const char *asn_str2asn_parse(const char *asstring, as_t *asn, bool *found_ptr)
const char **next = &p;
bool found;
- found = asn_str2asn_internal(asstring, asn, next, NULL);
+ found = asn_str2asn_internal(asstring, asn, next, NULL, NULL);
if (found_ptr)
*found_ptr = found;
return *next;
@@ -139,7 +152,7 @@ enum match_type asn_str2asn_match(const char *str)
{
bool found, partial = false;
- found = asn_str2asn_internal(str, NULL, NULL, &partial);
+ found = asn_str2asn_internal(str, NULL, NULL, &partial, NULL);
if (found && !partial)
return exact_match;
@@ -148,3 +161,15 @@ enum match_type asn_str2asn_match(const char *str)
return no_match;
}
+
+bool asn_str2asn_notation(const char *asstring, as_t *asn,
+ enum asnotation_mode *asnotation)
+{
+ return asn_str2asn_internal(asstring, asn, NULL, NULL, asnotation);
+}
+
+const char *asn_mode2str(enum asnotation_mode asnotation)
+{
+ return lookup_msg(asnotation_mode_msg, asnotation,
+ "Unrecognized AS notation mode");
+}