]> git.proxmox.com Git - mirror_frr.git/blobdiff - bgpd/bgp_clist.c
bgpd: Convert to network byte order before passing value to `community_del_val`
[mirror_frr.git] / bgpd / bgp_clist.c
index 7b64f349d2330d3a2f0396a4c5d8daf6c9d3d5bd..81ef03ec5827ab24a9c560bd6623f3c9a40f02c7 100644 (file)
@@ -27,6 +27,7 @@
 #include "filter.h"
 #include "stream.h"
 #include "jhash.h"
+#include "frrstr.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_community.h"
@@ -796,6 +797,7 @@ struct community *community_list_match_delete(struct community *com,
        /* Delete all of the communities we flagged for deletion */
        for (i = delete_index - 1; i >= 0; i--) {
                val = community_val_get(com, com_index_to_delete[i]);
+               val = htonl(val);
                community_del_val(com, &val);
        }
 
@@ -1000,6 +1002,33 @@ struct lcommunity *lcommunity_list_match_delete(struct lcommunity *lcom,
        return lcom;
 }
 
+/* Helper to check if every octet do not exceed UINT_MAX */
+static int lcommunity_list_valid(const char *community)
+{
+       int octets = 0;
+       char **splits;
+       int num;
+
+       frrstr_split(community, ":", &splits, &num);
+
+       for (int i = 0; i < num; i++) {
+               if (strtoul(splits[i], NULL, 10) > UINT_MAX)
+                       return 0;
+
+               if (strlen(splits[i]) == 0)
+                       return 0;
+
+               octets++;
+               XFREE(MTYPE_TMP, splits[i]);
+       }
+       XFREE(MTYPE_TMP, splits);
+
+       if (octets < 3)
+               return 0;
+
+       return 1;
+}
+
 /* Set lcommunity-list.  */
 int lcommunity_list_set(struct community_list_handler *ch, const char *name,
                        const char *str, int direct, int style)
@@ -1028,6 +1057,9 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name,
        }
 
        if (str) {
+               if (!lcommunity_list_valid(str))
+                       return COMMUNITY_LIST_ERR_MALFORMED_VAL;
+
                if (style == LARGE_COMMUNITY_LIST_STANDARD)
                        lcom = lcommunity_str2com(str);
                else
@@ -1049,8 +1081,10 @@ int lcommunity_list_set(struct community_list_handler *ch, const char *name,
        /* Do not put duplicated community entry.  */
        if (community_list_dup_check(list, entry))
                community_entry_free(entry);
-       else
+       else {
                community_list_entry_add(list, entry);
+               route_map_notify_dependencies(name, RMAP_EVENT_LLIST_ADDED);
+       }
 
        return 0;
 }
@@ -1075,6 +1109,7 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name,
        /* Delete all of entry belongs to this community-list.  */
        if (!str) {
                community_list_delete(cm, list);
+               route_map_notify_dependencies(name, RMAP_EVENT_LLIST_DELETED);
                return 0;
        }
 
@@ -1100,6 +1135,7 @@ int lcommunity_list_unset(struct community_list_handler *ch, const char *name,
                return COMMUNITY_LIST_ERR_CANT_FIND_LIST;
 
        community_list_entry_delete(cm, list, entry);
+       route_map_notify_dependencies(name, RMAP_EVENT_LLIST_DELETED);
 
        return 0;
 }