]> git.puffer.fish Git - mirror/frr.git/commitdiff
ripd: retrofit the 'offset-list' command to the new northbound model
authorRenato Westphal <renato@opensourcerouting.org>
Wed, 9 May 2018 04:35:00 +0000 (01:35 -0300)
committerRenato Westphal <renato@opensourcerouting.org>
Sat, 27 Oct 2018 18:16:12 +0000 (16:16 -0200)
Remove the rip_offset_list_set() and rip_offset_list_unset() functions
since they set/unset multiple configuration options at the same time. The
northbound callbacks need to set/unset configuration options individually.

The frr-ripd YANG module models the "offset-list" command using a list
keyed by the 'interface' and 'direction' leafs. One important detail is
that the IFNAME parameter is optional, and when it's not present it means
we want to match all interfaces. This is modeled using an interface name
of '*' since key lists are mandatory by definition in YANG.

Signed-off-by: Renato Westphal <renato@opensourcerouting.org>
ripd/rip_cli.c
ripd/rip_cli.h
ripd/rip_northbound.c
ripd/rip_offset.c
ripd/ripd.c
ripd/ripd.h

index a22f3054a621f613b07f3d2f8226749b3892233d..10db5d967e3e0a832e54c74cb92284117b02e0d7 100644 (file)
@@ -385,6 +385,86 @@ void cli_show_rip_network_interface(struct vty *vty, struct lyd_node *dnode,
        vty_out(vty, " network %s\n", yang_dnode_get_string(dnode, NULL));
 }
 
+/*
+ * XPath: /frr-ripd:ripd/instance/offset-list
+ */
+DEFPY (rip_offset_list,
+       rip_offset_list_cmd,
+       "offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
+       "Modify RIP metric\n"
+       "Access-list name\n"
+       "For incoming updates\n"
+       "For outgoing updates\n"
+       "Metric value\n"
+       "Interface to match\n")
+{
+       char xpath_list[XPATH_MAXLEN];
+       struct cli_config_change changes[] = {
+               {
+                       .xpath = ".",
+                       .operation = NB_OP_CREATE,
+               },
+               {
+                       .xpath = "./access-list",
+                       .operation = NB_OP_MODIFY,
+                       .value = acl,
+               },
+               {
+                       .xpath = "./metric",
+                       .operation = NB_OP_MODIFY,
+                       .value = metric_str,
+               },
+       };
+
+       snprintf(xpath_list, sizeof(xpath_list),
+                "./offset-list[interface='%s'][direction='%s']",
+                ifname ? ifname : "*", direction);
+
+       return nb_cli_cfg_change(vty, xpath_list, changes, array_size(changes));
+}
+
+DEFPY (no_rip_offset_list,
+       no_rip_offset_list_cmd,
+       "no offset-list WORD$acl <in|out>$direction (0-16)$metric [IFNAME]",
+       NO_STR
+       "Modify RIP metric\n"
+       "Access-list name\n"
+       "For incoming updates\n"
+       "For outgoing updates\n"
+       "Metric value\n"
+       "Interface to match\n")
+{
+       char xpath_list[XPATH_MAXLEN];
+       struct cli_config_change changes[] = {
+               {
+                       .xpath = ".",
+                       .operation = NB_OP_DELETE,
+               },
+       };
+
+       snprintf(xpath_list, sizeof(xpath_list),
+                "./offset-list[interface='%s'][direction='%s']",
+                ifname ? ifname : "*", direction);
+
+       return nb_cli_cfg_change(vty, xpath_list, changes, array_size(changes));
+}
+
+void cli_show_rip_offset_list(struct vty *vty, struct lyd_node *dnode,
+                             bool show_defaults)
+{
+       const char *interface;
+
+       interface = yang_dnode_get_string(dnode, "./interface");
+
+       vty_out(vty, " offset-list %s %s %s",
+               yang_dnode_get_string(dnode, "./access-list"),
+               yang_dnode_get_string(dnode, "./direction"),
+               yang_dnode_get_string(dnode, "./metric"));
+       if (!strmatch(interface, "*"))
+               vty_out(vty, " %s", interface);
+       vty_out(vty, "\n");
+}
+
 void rip_cli_init(void)
 {
        install_element(CONFIG_NODE, &router_rip_cmd);
@@ -401,4 +481,6 @@ void rip_cli_init(void)
        install_element(RIP_NODE, &rip_neighbor_cmd);
        install_element(RIP_NODE, &rip_network_prefix_cmd);
        install_element(RIP_NODE, &rip_network_if_cmd);
+       install_element(RIP_NODE, &rip_offset_list_cmd);
+       install_element(RIP_NODE, &no_rip_offset_list_cmd);
 }
index 2a054059240a58e8926ae4764cabaf541dd25dcc..16ed784513f936891e9769e0efee315be112e857 100644 (file)
@@ -42,5 +42,7 @@ extern void cli_show_rip_network_prefix(struct vty *vty, struct lyd_node *dnode,
 extern void cli_show_rip_network_interface(struct vty *vty,
                                           struct lyd_node *dnode,
                                           bool show_defaults);
+extern void cli_show_rip_offset_list(struct vty *vty, struct lyd_node *dnode,
+                                    bool show_defaults);
 
 #endif /* _FRR_RIP_CLI_H_ */
index 498aa322cbc88a238bb34cd82e4f561b99c50757..bdad4004d349fca7ee42f6032b487faa7fa5635d 100644 (file)
@@ -370,14 +370,40 @@ static int ripd_instance_offset_list_create(enum nb_event event,
                                            const struct lyd_node *dnode,
                                            union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       const char *ifname;
+       struct rip_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       ifname = yang_dnode_get_string(dnode, "./interface");
+
+       offset = rip_offset_list_new(ifname);
+       yang_dnode_set_entry(dnode, offset);
+
        return NB_OK;
 }
 
 static int ripd_instance_offset_list_delete(enum nb_event event,
                                            const struct lyd_node *dnode)
 {
-       /* TODO: implement me. */
+       int direct;
+       struct rip_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "./direction");
+
+       offset = yang_dnode_get_entry(dnode);
+       if (offset->direct[direct].alist_name) {
+               free(offset->direct[direct].alist_name);
+               offset->direct[direct].alist_name = NULL;
+       }
+       if (offset->direct[RIP_OFFSET_LIST_IN].alist_name == NULL
+           && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL)
+               offset_list_del(offset);
+
        return NB_OK;
 }
 
@@ -389,7 +415,21 @@ ripd_instance_offset_list_access_list_modify(enum nb_event event,
                                             const struct lyd_node *dnode,
                                             union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int direct;
+       struct rip_offset_list *offset;
+       const char *alist_name;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "../direction");
+       alist_name = yang_dnode_get_string(dnode, NULL);
+
+       offset = yang_dnode_get_entry(dnode);
+       if (offset->direct[direct].alist_name)
+               free(offset->direct[direct].alist_name);
+       offset->direct[direct].alist_name = strdup(alist_name);
+
        return NB_OK;
 }
 
@@ -400,7 +440,19 @@ static int ripd_instance_offset_list_metric_modify(enum nb_event event,
                                                   const struct lyd_node *dnode,
                                                   union nb_resource *resource)
 {
-       /* TODO: implement me. */
+       int direct;
+       uint8_t metric;
+       struct rip_offset_list *offset;
+
+       if (event != NB_EV_APPLY)
+               return NB_OK;
+
+       direct = yang_dnode_get_enum(dnode, "../direction");
+       metric = yang_dnode_get_uint8(dnode, NULL);
+
+       offset = yang_dnode_get_entry(dnode);
+       offset->direct[direct].metric = metric;
+
        return NB_OK;
 }
 
@@ -916,6 +968,7 @@ const struct frr_yang_module_info frr_ripd_info = {
                        .xpath = "/frr-ripd:ripd/instance/offset-list",
                        .cbs.create = ripd_instance_offset_list_create,
                        .cbs.delete = ripd_instance_offset_list_delete,
+                       .cbs.cli_show = cli_show_rip_offset_list,
                },
                {
                        .xpath = "/frr-ripd:ripd/instance/offset-list/access-list",
index d2065a4bbbc72098385f0d2f19bb1b7cef4ca699..418ec3fc7b73aef8556f559856d61b9eb7c03e5d 100644 (file)
 
 #include "ripd/ripd.h"
 
-#define RIP_OFFSET_LIST_IN  0
-#define RIP_OFFSET_LIST_OUT 1
-#define RIP_OFFSET_LIST_MAX 2
-
-struct rip_offset_list {
-       char *ifname;
-
-       struct {
-               char *alist_name;
-               /* struct access_list *alist; */
-               int metric;
-       } direct[RIP_OFFSET_LIST_MAX];
-};
-
 static struct list *rip_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);
-}
-
-static struct rip_offset_list *rip_offset_list_new(void)
-{
-       return XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list));
-}
-
-static void rip_offset_list_free(struct rip_offset_list *offset)
-{
-       XFREE(MTYPE_RIP_OFFSET_LIST, offset);
-}
-
-static struct rip_offset_list *rip_offset_list_lookup(const char *ifname)
-{
-       struct rip_offset_list *offset;
-       struct listnode *node, *nnode;
+#define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIP_OFFSET_LIST_IN].alist_name)
+#define OFFSET_LIST_IN_METRIC(O)  ((O)->direct[RIP_OFFSET_LIST_IN].metric)
 
-       for (ALL_LIST_ELEMENTS(rip_offset_list_master, node, nnode, offset)) {
-               if (strcmp_safe(offset->ifname, ifname) == 0)
-                       return offset;
-       }
-       return NULL;
-}
+#define OFFSET_LIST_OUT_NAME(O)  ((O)->direct[RIP_OFFSET_LIST_OUT].alist_name)
+#define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIP_OFFSET_LIST_OUT].metric)
 
-static struct rip_offset_list *rip_offset_list_get(const char *ifname)
+struct rip_offset_list *rip_offset_list_new(const char *ifname)
 {
        struct rip_offset_list *offset;
 
-       offset = rip_offset_list_lookup(ifname);
-       if (offset)
-               return offset;
-
-       offset = rip_offset_list_new();
-       if (ifname)
-               offset->ifname = strdup(ifname);
+       offset = XCALLOC(MTYPE_RIP_OFFSET_LIST, sizeof(struct rip_offset_list));
+       offset->ifname = strdup(ifname);
        listnode_add_sort(rip_offset_list_master, offset);
 
        return offset;
 }
 
-static int rip_offset_list_set(struct vty *vty, const char *alist,
-                              const char *direct_str, const char *metric_str,
-                              const char *ifname)
+void offset_list_del(struct rip_offset_list *offset)
 {
-       int direct;
-       int metric;
-       struct rip_offset_list *offset;
-
-       /* Check direction. */
-       if (strncmp(direct_str, "i", 1) == 0)
-               direct = RIP_OFFSET_LIST_IN;
-       else if (strncmp(direct_str, "o", 1) == 0)
-               direct = RIP_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 = rip_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;
+       listnode_delete(rip_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_RIP_OFFSET_LIST, offset);
 }
 
-static int rip_offset_list_unset(struct vty *vty, const char *alist,
-                                const char *direct_str, const char *metric_str,
-                                const char *ifname)
+struct rip_offset_list *rip_offset_list_lookup(const char *ifname)
 {
-       int direct;
-       int metric;
        struct rip_offset_list *offset;
+       struct listnode *node, *nnode;
 
-       /* Check direction. */
-       if (strncmp(direct_str, "i", 1) == 0)
-               direct = RIP_OFFSET_LIST_IN;
-       else if (strncmp(direct_str, "o", 1) == 0)
-               direct = RIP_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 = rip_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[RIP_OFFSET_LIST_IN].alist_name == NULL
-                   && offset->direct[RIP_OFFSET_LIST_OUT].alist_name == NULL) {
-                       listnode_delete(rip_offset_list_master, offset);
-                       if (offset->ifname)
-                               free(offset->ifname);
-                       rip_offset_list_free(offset);
-               }
-       } else {
-               vty_out(vty, "Can't find offset-list\n");
-               return CMD_WARNING_CONFIG_FAILED;
+       for (ALL_LIST_ELEMENTS(rip_offset_list_master, node, nnode, offset)) {
+               if (strcmp(offset->ifname, ifname) == 0)
+                       return offset;
        }
-       return CMD_SUCCESS;
+       return NULL;
 }
 
-#define OFFSET_LIST_IN_NAME(O)  ((O)->direct[RIP_OFFSET_LIST_IN].alist_name)
-#define OFFSET_LIST_IN_METRIC(O)  ((O)->direct[RIP_OFFSET_LIST_IN].metric)
-
-#define OFFSET_LIST_OUT_NAME(O)  ((O)->direct[RIP_OFFSET_LIST_OUT].alist_name)
-#define OFFSET_LIST_OUT_METRIC(O)  ((O)->direct[RIP_OFFSET_LIST_OUT].metric)
-
 /* If metric is modifed return 1. */
 int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp,
                             uint32_t *metric)
@@ -204,7 +92,7 @@ int rip_offset_list_apply_in(struct prefix_ipv4 *p, struct interface *ifp,
                return 0;
        }
        /* Look up offset-list without interface name. */
-       offset = rip_offset_list_lookup(NULL);
+       offset = rip_offset_list_lookup("*");
        if (offset && OFFSET_LIST_IN_NAME(offset)) {
                alist = access_list_lookup(AFI_IP, OFFSET_LIST_IN_NAME(offset));
 
@@ -242,7 +130,7 @@ int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp,
        }
 
        /* Look up offset-list without interface name. */
-       offset = rip_offset_list_lookup(NULL);
+       offset = rip_offset_list_lookup("*");
        if (offset && OFFSET_LIST_OUT_NAME(offset)) {
                alist = access_list_lookup(AFI_IP,
                                           OFFSET_LIST_OUT_NAME(offset));
@@ -258,95 +146,10 @@ int rip_offset_list_apply_out(struct prefix_ipv4 *p, struct interface *ifp,
        return 0;
 }
 
-DEFUN (rip_offset_list,
-       rip_offset_list_cmd,
-       "offset-list WORD <in|out> (0-16)",
-       "Modify RIP 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 rip_offset_list_set(vty, argv[idx_word]->arg,
-                                  argv[idx_in_out]->arg, argv[idx_number]->arg,
-                                  NULL);
-}
-
-DEFUN (rip_offset_list_ifname,
-       rip_offset_list_ifname_cmd,
-       "offset-list WORD <in|out> (0-16) IFNAME",
-       "Modify RIP 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 rip_offset_list_set(vty, argv[idx_word]->arg,
-                                  argv[idx_in_out]->arg, argv[idx_number]->arg,
-                                  argv[idx_ifname]->arg);
-}
-
-DEFUN (no_rip_offset_list,
-       no_rip_offset_list_cmd,
-       "no offset-list WORD <in|out> (0-16)",
-       NO_STR
-       "Modify RIP 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 rip_offset_list_unset(vty, argv[idx_word]->arg,
-                                    argv[idx_in_out]->arg,
-                                    argv[idx_number]->arg, NULL);
-}
-
-DEFUN (no_rip_offset_list_ifname,
-       no_rip_offset_list_ifname_cmd,
-       "no offset-list WORD <in|out> (0-16) IFNAME",
-       NO_STR
-       "Modify RIP 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 rip_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 rip_offset_list *o1,
                           struct rip_offset_list *o2)
 {
-       return strcmp_safe(o1->ifname, o2->ifname);
-}
-
-static void offset_list_del(struct rip_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);
-       rip_offset_list_free(offset);
+       return strcmp(o1->ifname, o2->ifname);
 }
 
 void rip_offset_init()
@@ -354,11 +157,6 @@ void rip_offset_init()
        rip_offset_list_master = list_new();
        rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
        rip_offset_list_master->del = (void (*)(void *))offset_list_del;
-
-       install_element(RIP_NODE, &rip_offset_list_cmd);
-       install_element(RIP_NODE, &rip_offset_list_ifname_cmd);
-       install_element(RIP_NODE, &no_rip_offset_list_cmd);
-       install_element(RIP_NODE, &no_rip_offset_list_ifname_cmd);
 }
 
 void rip_offset_clean()
@@ -369,43 +167,3 @@ void rip_offset_clean()
        rip_offset_list_master->cmp = (int (*)(void *, void *))offset_list_cmp;
        rip_offset_list_master->del = (void (*)(void *))offset_list_del;
 }
-
-int config_write_rip_offset_list(struct vty *vty)
-{
-       struct listnode *node, *nnode;
-       struct rip_offset_list *offset;
-
-       for (ALL_LIST_ELEMENTS(rip_offset_list_master, node, nnode, offset)) {
-               if (!offset->ifname) {
-                       if (offset->direct[RIP_OFFSET_LIST_IN].alist_name)
-                               vty_out(vty, " offset-list %s in %d\n",
-                                       offset->direct[RIP_OFFSET_LIST_IN]
-                                               .alist_name,
-                                       offset->direct[RIP_OFFSET_LIST_IN]
-                                               .metric);
-                       if (offset->direct[RIP_OFFSET_LIST_OUT].alist_name)
-                               vty_out(vty, " offset-list %s out %d\n",
-                                       offset->direct[RIP_OFFSET_LIST_OUT]
-                                               .alist_name,
-                                       offset->direct[RIP_OFFSET_LIST_OUT]
-                                               .metric);
-               } else {
-                       if (offset->direct[RIP_OFFSET_LIST_IN].alist_name)
-                               vty_out(vty, " offset-list %s in %d %s\n",
-                                       offset->direct[RIP_OFFSET_LIST_IN]
-                                               .alist_name,
-                                       offset->direct[RIP_OFFSET_LIST_IN]
-                                               .metric,
-                                       offset->ifname);
-                       if (offset->direct[RIP_OFFSET_LIST_OUT].alist_name)
-                               vty_out(vty, " offset-list %s out %d %s\n",
-                                       offset->direct[RIP_OFFSET_LIST_OUT]
-                                               .alist_name,
-                                       offset->direct[RIP_OFFSET_LIST_OUT]
-                                               .metric,
-                                       offset->ifname);
-               }
-       }
-
-       return 0;
-}
index 027ad878bb3afb6d66f8011bcf628bfd185c722f..24bbf226b069be2b2bac9ac7d365f2a83e3b788d 100644 (file)
@@ -3412,9 +3412,6 @@ static int config_write_rip(struct vty *vty)
                /* Redistribute configuration. */
                config_write_rip_redistribute(vty, 1);
 
-               /* RIP offset-list configuration. */
-               config_write_rip_offset_list(vty);
-
                /* Distribute configuration. */
                write += config_write_distribute(vty);
 
index 9bd9f53f2263181a3b79a1f7d54dd1cd8f22e5c4..4378f75af4e512fb8acc92e747961e3ef2780314 100644 (file)
@@ -367,6 +367,20 @@ enum rip_event {
 /* Macro for timer turn off. */
 #define RIP_TIMER_OFF(X) THREAD_TIMER_OFF(X)
 
+#define RIP_OFFSET_LIST_IN  0
+#define RIP_OFFSET_LIST_OUT 1
+#define RIP_OFFSET_LIST_MAX 2
+
+struct rip_offset_list {
+       char *ifname;
+
+       struct {
+               char *alist_name;
+               /* struct access_list *alist; */
+               uint8_t metric;
+       } direct[RIP_OFFSET_LIST_MAX];
+};
+
 /* Prototypes. */
 extern void rip_init(void);
 extern void rip_reset(void);
@@ -382,7 +396,6 @@ extern void rip_route_map_reset(void);
 extern void rip_zclient_init(struct thread_master *);
 extern void rip_zclient_stop(void);
 extern void rip_zclient_reset(void);
-extern void rip_offset_init(void);
 extern int if_check_address(struct in_addr addr);
 extern int rip_create(int socket);
 
@@ -414,7 +427,6 @@ extern void rip_distribute_update_interface(struct interface *);
 extern void rip_if_rmap_update_interface(struct interface *);
 
 extern int config_write_rip_network(struct vty *, int);
-extern int config_write_rip_offset_list(struct vty *);
 extern int config_write_rip_redistribute(struct vty *, int);
 
 extern void rip_peer_init(void);
@@ -425,12 +437,6 @@ extern void rip_peer_display(struct vty *);
 extern struct rip_peer *rip_peer_lookup(struct in_addr *);
 extern struct rip_peer *rip_peer_lookup_next(struct in_addr *);
 
-extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *,
-                                   uint32_t *);
-extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
-                                    uint32_t *);
-extern void rip_offset_clean(void);
-
 extern void rip_info_free(struct rip_info *);
 extern struct rip_distance *rip_distance_new(void);
 extern void rip_distance_free(struct rip_distance *rdistance);
@@ -441,6 +447,16 @@ extern struct rip_info *rip_ecmp_add(struct rip_info *);
 extern struct rip_info *rip_ecmp_replace(struct rip_info *);
 extern struct rip_info *rip_ecmp_delete(struct rip_info *);
 
+extern struct rip_offset_list *rip_offset_list_new(const char *ifname);
+extern void offset_list_del(struct rip_offset_list *offset);
+extern struct rip_offset_list *rip_offset_list_lookup(const char *ifname);
+extern int rip_offset_list_apply_in(struct prefix_ipv4 *, struct interface *,
+                                   uint32_t *);
+extern int rip_offset_list_apply_out(struct prefix_ipv4 *, struct interface *,
+                                    uint32_t *);
+extern void rip_offset_init(void);
+extern void rip_offset_clean(void);
+
 /* There is only one rip strucutre. */
 extern struct rip *rip;