]> git.proxmox.com Git - mirror_frr.git/commitdiff
ospf6d: Add CLI and logic for default-information originate command
authorYash Ranjan <ranjany@vmware.com>
Wed, 10 Feb 2021 04:53:46 +0000 (20:53 -0800)
committerYash Ranjan <ranjany@vmware.com>
Mon, 29 Mar 2021 13:37:10 +0000 (06:37 -0700)
Signed-off-by: Yash Ranjan <ranjany@vmware.com>
ospf6d/ospf6_asbr.c
ospf6d/ospf6_asbr.h
ospf6d/ospf6_top.c
ospf6d/ospf6_top.h
ospf6d/ospf6_zebra.c
ospf6d/ospf6_zebra.h
ospf6d/subdir.am

index 3497b2665699ceeb6e070800e0f13515f2c3b572..62ce74718bb6d81e6ce6f123434e0fd1d619178b 100644 (file)
@@ -57,6 +57,10 @@ static void ospf6_asbr_redistribute_set(int type, vrf_id_t vrf_id);
 static void ospf6_asbr_redistribute_unset(struct ospf6 *ospf6,
                                          struct ospf6_redist *red, int type);
 
+#ifndef VTYSH_EXTRACT_PL
+#include "ospf6d/ospf6_asbr_clippy.c"
+#endif
+
 unsigned char conf_debug_ospf6_asbr = 0;
 
 #define ZROUTE_NAME(x) zebra_route_string(x)
@@ -1150,7 +1154,8 @@ void ospf6_asbr_redistribute_add(int type, ifindex_t ifindex,
        if (!red)
                return;
 
-       if (!ospf6_zebra_is_redistribute(type, ospf6->vrf_id))
+       if ((type != DEFAULT_ROUTE)
+           && !ospf6_zebra_is_redistribute(type, ospf6->vrf_id))
                return;
 
        memset(&troute, 0, sizeof(troute));
@@ -1533,6 +1538,140 @@ static void ospf6_redistribute_show_config(struct vty *vty, struct ospf6 *ospf6,
                vty_out(vty, "Total %d routes\n", total);
 }
 
+static void ospf6_redistribute_default_set(struct ospf6 *ospf6, int originate)
+{
+       struct prefix_ipv6 p = {};
+       struct in6_addr nexthop = {};
+       int cur_originate = ospf6->default_originate;
+
+       p.family = AF_INET6;
+       p.prefixlen = 0;
+
+       ospf6->default_originate = originate;
+
+       switch (cur_originate) {
+       case DEFAULT_ORIGINATE_NONE:
+               break;
+       case DEFAULT_ORIGINATE_ZEBRA:
+               zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_DELETE,
+                                            zclient, AFI_IP6, ospf6->vrf_id);
+               ospf6_asbr_redistribute_remove(DEFAULT_ROUTE, 0,
+                                              (struct prefix *)&p, ospf6);
+
+               break;
+       case DEFAULT_ORIGINATE_ALWAYS:
+               ospf6_asbr_redistribute_remove(DEFAULT_ROUTE, 0,
+                                              (struct prefix *)&p, ospf6);
+               break;
+       }
+
+       switch (originate) {
+       case DEFAULT_ORIGINATE_NONE:
+               break;
+       case DEFAULT_ORIGINATE_ZEBRA:
+               zclient_redistribute_default(ZEBRA_REDISTRIBUTE_DEFAULT_ADD,
+                                            zclient, AFI_IP6, ospf6->vrf_id);
+
+               break;
+       case DEFAULT_ORIGINATE_ALWAYS:
+               ospf6_asbr_redistribute_add(DEFAULT_ROUTE, 0,
+                                           (struct prefix *)&p, 0, &nexthop, 0,
+                                           ospf6);
+               break;
+       }
+}
+
+/* Default Route originate. */
+DEFPY (ospf6_default_route_originate,
+       ospf6_default_route_originate_cmd,
+       "default-information originate [{always$always|metric (0-16777214)$mval|metric-type (1-2)$mtype|route-map WORD$rtmap}]",
+       "Control distribution of default route\n"
+       "Distribute a default route\n"
+       "Always advertise default route\n"
+       "OSPFv3 default metric\n"
+       "OSPFv3 metric\n"
+       "OSPFv3 metric type for default routes\n"
+       "Set OSPFv3 External Type 1/2 metrics\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+       int default_originate = DEFAULT_ORIGINATE_ZEBRA;
+       struct ospf6_redist *red;
+       bool sameRtmap = false;
+
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       int cur_originate = ospf6->default_originate;
+
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
+
+       red = ospf6_redist_add(ospf6, DEFAULT_ROUTE, 0);
+
+       if (always != NULL)
+               default_originate = DEFAULT_ORIGINATE_ALWAYS;
+
+       if (mval_str == NULL)
+               mval = -1;
+
+       if (mtype_str == NULL)
+               mtype = -1;
+
+       /* To check ,if user is providing same route map */
+       if ((rtmap == ROUTEMAP_NAME(red))
+           || (rtmap && ROUTEMAP_NAME(red)
+               && (strcmp(rtmap, ROUTEMAP_NAME(red)) == 0)))
+               sameRtmap = true;
+
+       /* Don't allow if the same lsa is aleardy originated. */
+       if ((sameRtmap) && (red->dmetric.type == mtype)
+           && (red->dmetric.value == mval)
+           && (cur_originate == default_originate))
+               return CMD_SUCCESS;
+
+       /* Updating Metric details */
+       red->dmetric.type = mtype;
+       red->dmetric.value = mval;
+
+       /* updating route map details */
+       if (rtmap)
+               ospf6_asbr_routemap_set(red, rtmap);
+       else
+               ospf6_asbr_routemap_unset(red);
+
+       ospf6_redistribute_default_set(ospf6, default_originate);
+       return CMD_SUCCESS;
+}
+
+DEFPY (no_ospf6_default_information_originate,
+       no_ospf6_default_information_originate_cmd,
+       "no default-information originate [{always|metric (0-16777214)|metric-type (1-2)|route-map WORD}]",
+       NO_STR
+       "Control distribution of default information\n"
+       "Distribute a default route\n"
+       "Always advertise default route\n"
+       "OSPFv3 default metric\n"
+       "OSPFv3 metric\n"
+       "OSPFv3 metric type for default routes\n"
+       "Set OSPFv3 External Type 1/2 metrics\n"
+       "Route map reference\n"
+       "Pointer to route-map entries\n")
+{
+       struct ospf6_redist *red;
+
+       VTY_DECLVAR_CONTEXT(ospf6, ospf6);
+
+       OSPF6_CMD_CHECK_RUNNING(ospf6);
+
+       red = ospf6_redist_lookup(ospf6, DEFAULT_ROUTE, 0);
+       if (!red)
+               return CMD_SUCCESS;
+
+       ospf6_asbr_routemap_unset(red);
+       ospf6_redist_del(ospf6, red, DEFAULT_ROUTE);
+
+       ospf6_redistribute_default_set(ospf6, DEFAULT_ORIGINATE_NONE);
+       return CMD_SUCCESS;
+}
 
 /* Routemap Functions */
 static enum route_map_cmd_result_t
@@ -2115,6 +2254,9 @@ void ospf6_asbr_init(void)
 
        install_element(VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
 
+       install_element(OSPF6_NODE, &ospf6_default_route_originate_cmd);
+       install_element(OSPF6_NODE,
+                       &no_ospf6_default_information_originate_cmd);
        install_element(OSPF6_NODE, &ospf6_redistribute_cmd);
        install_element(OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
        install_element(OSPF6_NODE, &no_ospf6_redistribute_cmd);
@@ -2176,6 +2318,39 @@ int config_write_ospf6_debug_asbr(struct vty *vty)
        return 0;
 }
 
+int ospf6_distribute_config_write(struct vty *vty, struct ospf6 *ospf6)
+{
+       struct ospf6_redist *red;
+
+       if (ospf6) {
+               /* default-route print. */
+               if (ospf6->default_originate != DEFAULT_ORIGINATE_NONE) {
+                       vty_out(vty, " default-information originate");
+                       if (ospf6->default_originate
+                           == DEFAULT_ORIGINATE_ALWAYS)
+                               vty_out(vty, " always");
+
+                       red = ospf6_redist_lookup(ospf6, DEFAULT_ROUTE, 0);
+                       if (red) {
+                               if (red->dmetric.value >= 0)
+                                       vty_out(vty, " metric %d",
+                                               red->dmetric.value);
+
+                               if (red->dmetric.type >= 0)
+                                       vty_out(vty, " metric-type %d",
+                                               red->dmetric.type);
+
+                               if (ROUTEMAP_NAME(red))
+                                       vty_out(vty, " route-map %s",
+                                               ROUTEMAP_NAME(red));
+                       }
+
+                       vty_out(vty, "\n");
+               }
+       }
+       return 0;
+}
+
 void install_element_ospf6_debug_asbr(void)
 {
        install_element(ENABLE_NODE, &debug_ospf6_asbr_cmd);
index e4a4455a5c4ae326febb693634b0dc1bee4e0aed..4774ac435a1bbc1e65ea316482cae79d07ebd50c 100644 (file)
@@ -98,6 +98,7 @@ extern void ospf6_asbr_send_externals_to_area(struct ospf6_area *);
 extern void ospf6_asbr_remove_externals_from_area(struct ospf6_area *oa);
 
 extern int config_write_ospf6_debug_asbr(struct vty *vty);
+extern int ospf6_distribute_config_write(struct vty *vty, struct ospf6 *ospf6);
 extern void install_element_ospf6_debug_asbr(void);
 extern void ospf6_asbr_update_route_ecmp_path(struct ospf6_route *old,
                                              struct ospf6_route *route,
index a38f1cbc4500a6e0240cc4213572daf771003483..8be84ec2b4fa715dbb0f2028478f855c74c3b358 100644 (file)
@@ -247,6 +247,7 @@ static struct ospf6 *ospf6_create(const char *name)
        o->spf_max_holdtime = OSPF_SPF_MAX_HOLDTIME_DEFAULT;
        o->spf_hold_multiplier = 1;
 
+       o->default_originate = DEFAULT_ORIGINATE_NONE;
        /* LSA timers value init */
        o->lsa_minarrival = OSPF_MIN_LS_ARRIVAL;
 
@@ -1329,6 +1330,7 @@ static int config_write_ospf6(struct vty *vty)
                ospf6_area_config_write(vty, ospf6);
                ospf6_spf_config_write(vty, ospf6);
                ospf6_distance_config_write(vty, ospf6);
+               ospf6_distribute_config_write(vty, ospf6);
 
                for (ALL_LIST_ELEMENTS_RO(ospf6->area_list, j, oa)) {
                        for (ALL_LIST_ELEMENTS_RO(oa->if_list, k, oi))
index 7980659e68d2681b024b86d61853c4161c64cfb8..eb683956e14f279ba98008f8ba3c7579cc3c87dc 100644 (file)
@@ -40,6 +40,15 @@ enum {
 
 struct ospf6_redist {
        uint8_t instance;
+
+       /* Redistribute metric info. */
+       struct {
+               int type;  /* External metric type (E1 or E2).  */
+               int value; /* Value for static metric (24-bit).
+                           * -1 means metric value is not set.
+                           */
+       } dmetric;
+
        /* For redistribute route map. */
        struct {
                char *name;
@@ -83,13 +92,16 @@ struct ospf6 {
        uint32_t external_id;
 
        /* OSPF6 redistribute configuration */
-       struct list *redist[ZEBRA_ROUTE_MAX];
+       struct list *redist[ZEBRA_ROUTE_MAX + 1];
 
        uint8_t flag;
 
        /* Configuration bitmask, refer to enum above */
        uint8_t config_flags;
-
+       int default_originate; /* Default information originate. */
+#define DEFAULT_ORIGINATE_NONE 0
+#define DEFAULT_ORIGINATE_ZEBRA 1
+#define DEFAULT_ORIGINATE_ALWAYS 2
        /* LSA timer parameters */
        unsigned int lsa_minarrival; /* LSA minimum arrival in milliseconds. */
 
index 8d5e0f0a393a5cb9e1bcb3cd40100931da1ac206..76e717287040779adcc2ad703b58a696f82ee71c 100644 (file)
@@ -172,12 +172,23 @@ static int ospf6_zebra_if_address_update_delete(ZAPI_CALLBACK_ARGS)
        return 0;
 }
 
+static int is_prefix_default(struct prefix_ipv6 *p)
+{
+       struct prefix_ipv6 q = {};
+
+       q.family = AF_INET6;
+       q.prefixlen = 0;
+
+       return prefix_same((struct prefix *)p, (struct prefix *)&q);
+}
+
 static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
 {
        struct zapi_route api;
        unsigned long ifindex;
        struct in6_addr *nexthop;
        struct ospf6 *ospf6;
+       struct prefix_ipv6 p;
 
        ospf6 = ospf6_lookup_by_vrf_id(vrf_id);
 
@@ -205,6 +216,10 @@ static int ospf6_zebra_read_route(ZAPI_CALLBACK_ARGS)
                        zebra_route_string(api.type), &api.prefix, nexthop,
                        ifindex, api.tag);
 
+       memcpy(&p, &api.prefix, sizeof(p));
+       if (is_prefix_default(&p))
+               api.type = DEFAULT_ROUTE;
+
        if (cmd == ZEBRA_REDISTRIBUTE_ROUTE_ADD)
                ospf6_asbr_redistribute_add(api.type, ifindex, &api.prefix,
                                            api.nexthop_num, nexthop, api.tag,
index 5f340924b9c522b791529bdede268fd62d8b38ca..a3ccc3d38db5287dcb228b94bee2860d27dd05ed 100644 (file)
@@ -23,6 +23,8 @@
 
 #include "zclient.h"
 
+#define DEFAULT_ROUTE ZEBRA_ROUTE_MAX
+
 /* Debug option */
 extern unsigned char conf_debug_ospf6_zebra;
 #define OSPF6_DEBUG_ZEBRA_SEND 0x01
index 82d880cca868a1b84bc6c9ebe213d49130f90dd1..dc173da9dc03dca1148cac7b7337a9145ff77841 100644 (file)
@@ -81,3 +81,7 @@ ospf6d_ospf6d_snmp_la_SOURCES = ospf6d/ospf6_snmp.c
 ospf6d_ospf6d_snmp_la_CFLAGS = $(WERROR) $(SNMP_CFLAGS) -std=gnu11
 ospf6d_ospf6d_snmp_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
 ospf6d_ospf6d_snmp_la_LIBADD = lib/libfrrsnmp.la
+
+clippy_scan += \
+       ospf6d/ospf6_asbr.c \
+       # end