]> git.proxmox.com Git - mirror_frr.git/blobdiff - ripngd/ripng_offset.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / ripngd / ripng_offset.c
index 82f8a7aa66c8fdec54f9173fe20dadce99d743a7..278df758924164116f9a21c7f48f0a4af5416cca 100644 (file)
 
 #include "ripngd/ripngd.h"
 
-#define RIPNG_OFFSET_LIST_IN  0
-#define RIPNG_OFFSET_LIST_OUT 1
-#define RIPNG_OFFSET_LIST_MAX 2
-
-struct ripng_offset_list {
-       char *ifname;
-
-       struct {
-               char *alist_name;
-               /* struct access_list *alist; */
-               int metric;
-       } direct[RIPNG_OFFSET_LIST_MAX];
-};
-
 static struct list *ripng_offset_list_master;
 
-static int strcmp_safe(const char *s1, const char *s2)
-{
-       if (s1 == NULL && s2 == NULL)
-               return 0;
-       if (s1 == NULL)
-               return -1;
-       if (s2 == NULL)
-               return 1;
-       return strcmp(s1, s2);
-}
+#define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
+#define OFFSET_LIST_IN_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
+
+#define OFFSET_LIST_OUT_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
+#define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
 
-static struct ripng_offset_list *ripng_offset_list_new(void)
+struct ripng_offset_list *ripng_offset_list_new(const char *ifname)
 {
        struct ripng_offset_list *new;
 
        new = XCALLOC(MTYPE_RIPNG_OFFSET_LIST,
                      sizeof(struct ripng_offset_list));
+       new->ifname = strdup(ifname);
+       listnode_add_sort(ripng_offset_list_master, new);
+
        return new;
 }
 
-static void ripng_offset_list_free(struct ripng_offset_list *offset)
+void ripng_offset_list_del(struct ripng_offset_list *offset)
 {
+       listnode_delete(ripng_offset_list_master, offset);
+       if (OFFSET_LIST_IN_NAME(offset))
+               free(OFFSET_LIST_IN_NAME(offset));
+       if (OFFSET_LIST_OUT_NAME(offset))
+               free(OFFSET_LIST_OUT_NAME(offset));
+       free(offset->ifname);
        XFREE(MTYPE_RIPNG_OFFSET_LIST, offset);
 }
 
-static struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname)
+struct ripng_offset_list *ripng_offset_list_lookup(const char *ifname)
 {
        struct ripng_offset_list *offset;
        struct listnode *node, *nnode;
 
        for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) {
-               if (strcmp_safe(offset->ifname, ifname) == 0)
+               if (strcmp(offset->ifname, ifname) == 0)
                        return offset;
        }
        return NULL;
 }
 
-static struct ripng_offset_list *ripng_offset_list_get(const char *ifname)
-{
-       struct ripng_offset_list *offset;
-
-       offset = ripng_offset_list_lookup(ifname);
-       if (offset)
-               return offset;
-
-       offset = ripng_offset_list_new();
-       if (ifname)
-               offset->ifname = strdup(ifname);
-       listnode_add_sort(ripng_offset_list_master, offset);
-
-       return offset;
-}
-
-static int ripng_offset_list_set(struct vty *vty, const char *alist,
-                                const char *direct_str, const char *metric_str,
-                                const char *ifname)
-{
-       int direct;
-       int metric;
-       struct ripng_offset_list *offset;
-
-       /* Check direction. */
-       if (strncmp(direct_str, "i", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_IN;
-       else if (strncmp(direct_str, "o", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_OUT;
-       else {
-               vty_out(vty, "Invalid direction: %s\n", direct_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Check metric. */
-       metric = atoi(metric_str);
-       if (metric < 0 || metric > 16) {
-               vty_out(vty, "Invalid metric: %s\n", metric_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Get offset-list structure with interface name. */
-       offset = ripng_offset_list_get(ifname);
-
-       if (offset->direct[direct].alist_name)
-               free(offset->direct[direct].alist_name);
-       offset->direct[direct].alist_name = strdup(alist);
-       offset->direct[direct].metric = metric;
-
-       return CMD_SUCCESS;
-}
-
-static int ripng_offset_list_unset(struct vty *vty, const char *alist,
-                                  const char *direct_str,
-                                  const char *metric_str, const char *ifname)
-{
-       int direct;
-       int metric;
-       struct ripng_offset_list *offset;
-
-       /* Check direction. */
-       if (strncmp(direct_str, "i", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_IN;
-       else if (strncmp(direct_str, "o", 1) == 0)
-               direct = RIPNG_OFFSET_LIST_OUT;
-       else {
-               vty_out(vty, "Invalid direction: %s\n", direct_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Check metric. */
-       metric = atoi(metric_str);
-       if (metric < 0 || metric > 16) {
-               vty_out(vty, "Invalid metric: %s\n", metric_str);
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-
-       /* Get offset-list structure with interface name. */
-       offset = ripng_offset_list_lookup(ifname);
-
-       if (offset) {
-               if (offset->direct[direct].alist_name)
-                       free(offset->direct[direct].alist_name);
-               offset->direct[direct].alist_name = NULL;
-
-               if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name == NULL
-                   && offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name
-                              == NULL) {
-                       listnode_delete(ripng_offset_list_master, offset);
-                       if (offset->ifname)
-                               free(offset->ifname);
-                       ripng_offset_list_free(offset);
-               }
-       } else {
-               vty_out(vty, "Can't find offset-list\n");
-               return CMD_WARNING_CONFIG_FAILED;
-       }
-       return CMD_SUCCESS;
-}
-
-#define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].alist_name)
-#define OFFSET_LIST_IN_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_IN].metric)
-
-#define OFFSET_LIST_OUT_NAME(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
-#define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIPNG_OFFSET_LIST_OUT].metric)
-
 /* If metric is modifed return 1. */
 int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
-                              u_char *metric)
+                              uint8_t *metric)
 {
        struct ripng_offset_list *offset;
        struct access_list *alist;
@@ -214,7 +98,7 @@ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
                return 0;
        }
        /* Look up offset-list without interface name. */
-       offset = ripng_offset_list_lookup(NULL);
+       offset = ripng_offset_list_lookup("*");
        if (offset && OFFSET_LIST_IN_NAME(offset)) {
                alist = access_list_lookup(AFI_IP6,
                                           OFFSET_LIST_IN_NAME(offset));
@@ -232,7 +116,7 @@ int ripng_offset_list_apply_in(struct prefix_ipv6 *p, struct interface *ifp,
 
 /* If metric is modifed return 1. */
 int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
-                               u_char *metric)
+                               uint8_t *metric)
 {
        struct ripng_offset_list *offset;
        struct access_list *alist;
@@ -253,7 +137,7 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
        }
 
        /* Look up offset-list without interface name. */
-       offset = ripng_offset_list_lookup(NULL);
+       offset = ripng_offset_list_lookup("*");
        if (offset && OFFSET_LIST_OUT_NAME(offset)) {
                alist = access_list_lookup(AFI_IP6,
                                           OFFSET_LIST_OUT_NAME(offset));
@@ -269,95 +153,10 @@ int ripng_offset_list_apply_out(struct prefix_ipv6 *p, struct interface *ifp,
        return 0;
 }
 
-DEFUN (ripng_offset_list,
-       ripng_offset_list_cmd,
-       "offset-list WORD <in|out> (0-16)",
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n")
-{
-       int idx_word = 1;
-       int idx_in_out = 2;
-       int idx_number = 3;
-       return ripng_offset_list_set(vty, argv[idx_word]->arg,
-                                    argv[idx_in_out]->arg,
-                                    argv[idx_number]->arg, NULL);
-}
-
-DEFUN (ripng_offset_list_ifname,
-       ripng_offset_list_ifname_cmd,
-       "offset-list WORD <in|out> (0-16) IFNAME",
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n"
-       "Interface to match\n")
-{
-       int idx_word = 1;
-       int idx_in_out = 2;
-       int idx_number = 3;
-       int idx_ifname = 4;
-       return ripng_offset_list_set(
-               vty, argv[idx_word]->arg, argv[idx_in_out]->arg,
-               argv[idx_number]->arg, argv[idx_ifname]->arg);
-}
-
-DEFUN (no_ripng_offset_list,
-       no_ripng_offset_list_cmd,
-       "no offset-list WORD <in|out> (0-16)",
-       NO_STR
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n")
-{
-       int idx_word = 2;
-       int idx_in_out = 3;
-       int idx_number = 4;
-       return ripng_offset_list_unset(vty, argv[idx_word]->arg,
-                                      argv[idx_in_out]->arg,
-                                      argv[idx_number]->arg, NULL);
-}
-
-DEFUN (no_ripng_offset_list_ifname,
-       no_ripng_offset_list_ifname_cmd,
-       "no offset-list WORD <in|out> (0-16) IFNAME",
-       NO_STR
-       "Modify RIPng metric\n"
-       "Access-list name\n"
-       "For incoming updates\n"
-       "For outgoing updates\n"
-       "Metric value\n"
-       "Interface to match\n")
-{
-       int idx_word = 2;
-       int idx_in_out = 3;
-       int idx_number = 4;
-       int idx_ifname = 5;
-       return ripng_offset_list_unset(
-               vty, argv[idx_word]->arg, argv[idx_in_out]->arg,
-               argv[idx_number]->arg, argv[idx_ifname]->arg);
-}
-
 static int offset_list_cmp(struct ripng_offset_list *o1,
                           struct ripng_offset_list *o2)
 {
-       return strcmp_safe(o1->ifname, o2->ifname);
-}
-
-static void offset_list_del(struct ripng_offset_list *offset)
-{
-       if (OFFSET_LIST_IN_NAME(offset))
-               free(OFFSET_LIST_IN_NAME(offset));
-       if (OFFSET_LIST_OUT_NAME(offset))
-               free(OFFSET_LIST_OUT_NAME(offset));
-       if (offset->ifname)
-               free(offset->ifname);
-       ripng_offset_list_free(offset);
+       return strcmp(o1->ifname, o2->ifname);
 }
 
 void ripng_offset_init(void)
@@ -365,60 +164,15 @@ void ripng_offset_init(void)
        ripng_offset_list_master = list_new();
        ripng_offset_list_master->cmp =
                (int (*)(void *, void *))offset_list_cmp;
-       ripng_offset_list_master->del = (void (*)(void *))offset_list_del;
-
-       install_element(RIPNG_NODE, &ripng_offset_list_cmd);
-       install_element(RIPNG_NODE, &ripng_offset_list_ifname_cmd);
-       install_element(RIPNG_NODE, &no_ripng_offset_list_cmd);
-       install_element(RIPNG_NODE, &no_ripng_offset_list_ifname_cmd);
+       ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del;
 }
 
 void ripng_offset_clean(void)
 {
-       list_delete_and_null(&ripng_offset_list_master);
+       list_delete(&ripng_offset_list_master);
 
        ripng_offset_list_master = list_new();
        ripng_offset_list_master->cmp =
                (int (*)(void *, void *))offset_list_cmp;
-       ripng_offset_list_master->del = (void (*)(void *))offset_list_del;
-}
-
-int config_write_ripng_offset_list(struct vty *vty)
-{
-       struct listnode *node, *nnode;
-       struct ripng_offset_list *offset;
-
-       for (ALL_LIST_ELEMENTS(ripng_offset_list_master, node, nnode, offset)) {
-               if (!offset->ifname) {
-                       if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name)
-                               vty_out(vty, " offset-list %s in %d\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .metric);
-                       if (offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
-                               vty_out(vty, " offset-list %s out %d\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .metric);
-               } else {
-                       if (offset->direct[RIPNG_OFFSET_LIST_IN].alist_name)
-                               vty_out(vty, " offset-list %s in %d %s\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_IN]
-                                               .metric,
-                                       offset->ifname);
-                       if (offset->direct[RIPNG_OFFSET_LIST_OUT].alist_name)
-                               vty_out(vty, " offset-list %s out %d %s\n",
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .alist_name,
-                                       offset->direct[RIPNG_OFFSET_LIST_OUT]
-                                               .metric,
-                                       offset->ifname);
-               }
-       }
-
-       return 0;
+       ripng_offset_list_master->del = (void (*)(void *))ripng_offset_list_del;
 }