return NB_ERR_VALIDATION;
}
+/**
+ * Sets prefix list entry to blank value.
+ *
+ * \param[out] ple prefix list entry to modify.
+ */
+static void prefix_list_entry_set_empty(struct prefix_list_entry *ple)
+{
+ ple->any = false;
+ memset(&ple->prefix, 0, sizeof(ple->prefix));
+ ple->ge = 0;
+ ple->le = 0;
+}
+
/*
* XPath: /frr-filter:lib/access-list-legacy
*/
pl = nb_running_get_entry(args->dnode, NULL, true);
ple = prefix_list_entry_new();
ple->pl = pl;
- ple->any = 1;
ple->seq = yang_dnode_get_uint32(args->dnode, "./sequence");
+ prefix_list_entry_set_empty(ple);
nb_running_set_entry(args->dnode, ple);
return NB_OK;
ple = nb_running_unset_entry(args->dnode);
if (ple->installed)
- prefix_list_entry_delete(ple->pl, ple, 0);
+ prefix_list_entry_delete2(ple);
else
prefix_list_entry_free(ple);
prefix_list_entry_update_start(ple);
yang_dnode_get_prefix(&ple->prefix, args->dnode, NULL);
- ple->any = 0;
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
prefix_list_entry_update_start(ple);
memset(&ple->prefix, 0, sizeof(ple->prefix));
- ple->any = 1;
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
static int lib_prefix_list_entry_any_create(struct nb_cb_create_args *args)
{
struct prefix_list_entry *ple;
+ int type;
if (args->event != NB_EV_APPLY)
return NB_OK;
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
+ ple->any = true;
+
+ /* Fill prefix struct from scratch. */
memset(&ple->prefix, 0, sizeof(ple->prefix));
- ple->any = 1;
+
+ type = yang_dnode_get_enum(args->dnode, "../../type");
+ switch (type) {
+ case 0: /* ipv4 */
+ ple->prefix.family = AF_INET;
+ ple->ge = 0;
+ ple->le = IPV4_MAX_BITLEN;
+ break;
+ case 1: /* ipv6 */
+ ple->prefix.family = AF_INET6;
+ ple->ge = 0;
+ ple->le = IPV6_MAX_BITLEN;
+ break;
+ }
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
/* Start prefix entry update procedure. */
prefix_list_entry_update_start(ple);
- memset(&ple->prefix, 0, sizeof(ple->prefix));
- ple->any = 1;
+ prefix_list_entry_set_empty(ple);
/* Finish prefix entry update procedure. */
prefix_list_entry_update_finish(ple);
if (!ple->installed)
return;
+ prefix_list_trie_del(pl, ple);
+
/* List manipulation: shameless copy from `prefix_list_entry_delete`. */
if (ple->prev)
ple->prev->next = ple->next;
else
pl->tail = ple->prev;
- prefix_list_trie_del(pl, ple);
route_map_notify_pentry_dependencies(pl->name, ple,
RMAP_EVENT_PLIST_DELETED);
pl->count--;
+ route_map_notify_dependencies(pl->name, RMAP_EVENT_PLIST_DELETED);
+ if (pl->master->delete_hook)
+ (*pl->master->delete_hook)(pl);
+
+ if (pl->head || pl->tail || pl->desc)
+ pl->master->recent = pl;
+
ple->installed = false;
}
if (ple->installed)
return;
+ /*
+ * Check if the entry is installable:
+ * We can only install entry if at least the prefix is provided (IPv4
+ * or IPv6).
+ */
+ if (ple->prefix.family != AF_INET && ple->prefix.family != AF_INET6)
+ return;
+
/* List manipulation: shameless copy from `prefix_list_entry_add`. */
if (pl->tail && ple->seq > pl->tail->seq)
point = NULL;
ple->installed = true;
}
+/**
+ * Same as `prefix_list_entry_delete` but without `free()`ing the list if its
+ * empty.
+ *
+ * \param[in] ple prefix list entry.
+ */
+void prefix_list_entry_delete2(struct prefix_list_entry *ple)
+{
+ /* Does the boiler plate list removal and entry removal notification. */
+ prefix_list_entry_update_start(ple);
+
+ /* Effective `free()` memory. */
+ prefix_list_entry_free(ple);
+}
+
/* Return string of prefix_list_type. */
static const char *prefix_list_type_str(struct prefix_list_entry *pentry)
{