summaryrefslogtreecommitdiff
path: root/bgpd/bgp_clist.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_clist.c')
-rw-r--r--bgpd/bgp_clist.c39
1 files changed, 30 insertions, 9 deletions
diff --git a/bgpd/bgp_clist.c b/bgpd/bgp_clist.c
index 247d758f8c..6ac6cf56dd 100644
--- a/bgpd/bgp_clist.c
+++ b/bgpd/bgp_clist.c
@@ -1110,11 +1110,14 @@ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
}
/* Helper to check if every octet do not exceed UINT_MAX */
-static bool lcommunity_list_valid(const char *community)
+bool lcommunity_list_valid(const char *community, int style)
{
int octets;
char **splits, **communities;
+ char *endptr;
int num, num_communities;
+ regex_t *regres;
+ int invalid = 0;
frrstr_split(community, " ", &communities, &num_communities);
@@ -1123,25 +1126,43 @@ static bool lcommunity_list_valid(const char *community)
frrstr_split(communities[j], ":", &splits, &num);
for (int i = 0; i < num; i++) {
- if (strtoul(splits[i], NULL, 10) > UINT_MAX)
- return false;
-
if (strlen(splits[i]) == 0)
- return false;
+ /* There is no digit to check */
+ invalid++;
+
+ if (style == LARGE_COMMUNITY_LIST_STANDARD) {
+ if (*splits[i] == '-')
+ /* Must not be negative */
+ invalid++;
+ else if (strtoul(splits[i], &endptr, 10)
+ > UINT_MAX)
+ /* Larger than 4 octets */
+ invalid++;
+ else if (*endptr)
+ /* Not all characters were digits */
+ invalid++;
+ } else {
+ regres = bgp_regcomp(communities[j]);
+ if (!regres)
+ /* malformed regex */
+ invalid++;
+ else
+ bgp_regex_free(regres);
+ }
octets++;
XFREE(MTYPE_TMP, splits[i]);
}
XFREE(MTYPE_TMP, splits);
- if (octets < 3)
- return false;
+ if (octets != 3)
+ invalid++;
XFREE(MTYPE_TMP, communities[j]);
}
XFREE(MTYPE_TMP, communities);
- return true;
+ return (invalid > 0) ? false : true;
}
/* Set lcommunity-list. */
@@ -1176,7 +1197,7 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name,
}
if (str) {
- if (!lcommunity_list_valid(str))
+ if (!lcommunity_list_valid(str, style))
return COMMUNITY_LIST_ERR_MALFORMED_VAL;
if (style == LARGE_COMMUNITY_LIST_STANDARD)