]> git.proxmox.com Git - mirror_frr.git/blobdiff - ospfd/ospf_lsa.c
zebra, lib: fix the ZEBRA_INTERFACE_VRF_UPDATE zapi message
[mirror_frr.git] / ospfd / ospf_lsa.c
index 502f23303640f4cd2b370eae68a647d86d5587e9..288ce43f79dae78b413d2be0c27d6ec6b8cddcce 100644 (file)
@@ -50,7 +50,7 @@
 #include "ospfd/ospf_ase.h"
 #include "ospfd/ospf_zebra.h"
 #include "ospfd/ospf_abr.h"
-
+#include "ospfd/ospf_errors.h"
 
 uint32_t get_metric(uint8_t *metric)
 {
@@ -167,6 +167,16 @@ struct ospf_lsa *ospf_lsa_new()
        return new;
 }
 
+struct ospf_lsa *ospf_lsa_new_and_data(size_t size)
+{
+       struct ospf_lsa *new;
+
+       new = ospf_lsa_new();
+       new->data = ospf_lsa_data_new(size);
+
+       return new;
+}
+
 /* Duplicate OSPF LSA. */
 struct ospf_lsa *ospf_lsa_dup(struct ospf_lsa *lsa)
 {
@@ -388,7 +398,8 @@ struct ospf_neighbor *ospf_nbr_lookup_ptop(struct ospf_interface *oi)
 
        /* PtoP link must have only 1 neighbor. */
        if (ospf_nbr_count(oi, 0) > 1)
-               zlog_warn("Point-to-Point link has more than 1 neighobrs.");
+               flog_warn(EC_OSPF_PTP_NEIGHBOR,
+                         "Point-to-Point link has more than 1 neighobrs.");
 
        return nbr;
 }
@@ -406,7 +417,7 @@ static uint16_t ospf_link_cost(struct ospf_interface *oi)
 }
 
 /* Set a link information. */
-static char link_info_set(struct stream *s, struct in_addr id,
+static char link_info_set(struct stream **s, struct in_addr id,
                          struct in_addr data, uint8_t type, uint8_t tos,
                          uint16_t cost)
 {
@@ -415,11 +426,11 @@ static char link_info_set(struct stream *s, struct in_addr id,
         * more.
         * we try accomodate those here.
         */
-       if (STREAM_WRITEABLE(s) < OSPF_ROUTER_LSA_LINK_SIZE) {
+       if (STREAM_WRITEABLE(*s) < OSPF_ROUTER_LSA_LINK_SIZE) {
                size_t ret = OSPF_MAX_LSA_SIZE;
 
                /* Can we enlarge the stream still? */
-               if (STREAM_SIZE(s) == OSPF_MAX_LSA_SIZE) {
+               if (STREAM_SIZE(*s) == OSPF_MAX_LSA_SIZE) {
                        /* we futz the size here for simplicity, really we need
                         * to account
                         * for just:
@@ -431,30 +442,32 @@ static char link_info_set(struct stream *s, struct in_addr id,
                         *
                         * Simpler just to subtract OSPF_MAX_LSA_SIZE though.
                         */
-                       ret = stream_resize(
+                       ret = stream_resize_inplace(
                                s, OSPF_MAX_PACKET_SIZE - OSPF_MAX_LSA_SIZE);
                }
 
                if (ret == OSPF_MAX_LSA_SIZE) {
-                       zlog_warn(
+                       flog_warn(
+                               EC_OSPF_LSA_SIZE,
                                "%s: Out of space in LSA stream, left %zd, size %zd",
-                               __func__, STREAM_WRITEABLE(s), STREAM_SIZE(s));
+                               __func__, STREAM_WRITEABLE(*s),
+                               STREAM_SIZE(*s));
                        return 0;
                }
        }
 
        /* TOS based routing is not supported. */
-       stream_put_ipv4(s, id.s_addr);   /* Link ID. */
-       stream_put_ipv4(s, data.s_addr); /* Link Data. */
-       stream_putc(s, type);            /* Link Type. */
-       stream_putc(s, tos);             /* TOS = 0. */
-       stream_putw(s, cost);            /* Link Cost. */
+       stream_put_ipv4(*s, id.s_addr);   /* Link ID. */
+       stream_put_ipv4(*s, data.s_addr); /* Link Data. */
+       stream_putc(*s, type);            /* Link Type. */
+       stream_putc(*s, tos);             /* TOS = 0. */
+       stream_putw(*s, cost);            /* Link Cost. */
 
        return 1;
 }
 
 /* Describe Point-to-Point link (Section 12.4.1.1). */
-static int lsa_link_ptop_set(struct stream *s, struct ospf_interface *oi)
+static int lsa_link_ptop_set(struct stream **s, struct ospf_interface *oi)
 {
        int links = 0;
        struct ospf_neighbor *nbr;
@@ -500,7 +513,7 @@ static int lsa_link_ptop_set(struct stream *s, struct ospf_interface *oi)
 }
 
 /* Describe Broadcast Link. */
-static int lsa_link_broadcast_set(struct stream *s, struct ospf_interface *oi)
+static int lsa_link_broadcast_set(struct stream **s, struct ospf_interface *oi)
 {
        struct ospf_neighbor *dr;
        struct in_addr id, mask;
@@ -546,7 +559,7 @@ static int lsa_link_broadcast_set(struct stream *s, struct ospf_interface *oi)
        }
 }
 
-static int lsa_link_loopback_set(struct stream *s, struct ospf_interface *oi)
+static int lsa_link_loopback_set(struct stream **s, struct ospf_interface *oi)
 {
        struct in_addr id, mask;
 
@@ -560,7 +573,8 @@ static int lsa_link_loopback_set(struct stream *s, struct ospf_interface *oi)
 }
 
 /* Describe Virtual Link. */
-static int lsa_link_virtuallink_set(struct stream *s, struct ospf_interface *oi)
+static int lsa_link_virtuallink_set(struct stream **s,
+                                   struct ospf_interface *oi)
 {
        struct ospf_neighbor *nbr;
        uint16_t cost = ospf_link_cost(oi);
@@ -583,7 +597,7 @@ static int lsa_link_virtuallink_set(struct stream *s, struct ospf_interface *oi)
 12.4.1.4.*/
 /* from "edward rrr" <edward_rrr@hotmail.com>
    http://marc.theaimsgroup.com/?l=zebra&m=100739222210507&w=2 */
-static int lsa_link_ptomp_set(struct stream *s, struct ospf_interface *oi)
+static int lsa_link_ptomp_set(struct stream **s, struct ospf_interface *oi)
 {
        int links = 0;
        struct route_node *rn;
@@ -624,7 +638,7 @@ static int lsa_link_ptomp_set(struct stream *s, struct ospf_interface *oi)
 }
 
 /* Set router-LSA link information. */
-static int router_lsa_link_set(struct stream *s, struct ospf_area *area)
+static int router_lsa_link_set(struct stream **s, struct ospf_area *area)
 {
        struct listnode *node;
        struct ospf_interface *oi;
@@ -667,28 +681,28 @@ static int router_lsa_link_set(struct stream *s, struct ospf_area *area)
 }
 
 /* Set router-LSA body. */
-static void ospf_router_lsa_body_set(struct stream *s, struct ospf_area *area)
+static void ospf_router_lsa_body_set(struct stream **s, struct ospf_area *area)
 {
        unsigned long putp;
        uint16_t cnt;
 
        /* Set flags. */
-       stream_putc(s, router_lsa_flags(area));
+       stream_putc(*s, router_lsa_flags(area));
 
        /* Set Zero fields. */
-       stream_putc(s, 0);
+       stream_putc(*s, 0);
 
        /* Keep pointer to # links. */
-       putp = stream_get_endp(s);
+       putp = stream_get_endp(*s);
 
        /* Forward word */
-       stream_putw(s, 0);
+       stream_putw(*s, 0);
 
        /* Set all link information. */
        cnt = router_lsa_link_set(s, area);
 
        /* Set # of links here. */
-       stream_putw_at(s, putp, cnt);
+       stream_putw_at(*s, putp, cnt);
 }
 
 static int ospf_stub_router_timer(struct thread *t)
@@ -773,7 +787,7 @@ static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area)
                       OSPF_ROUTER_LSA, ospf->router_id, ospf->router_id);
 
        /* Set router-LSA body fields. */
-       ospf_router_lsa_body_set(s, area);
+       ospf_router_lsa_body_set(&s, area);
 
        /* Set length. */
        length = stream_get_endp(s);
@@ -781,17 +795,13 @@ static struct ospf_lsa *ospf_router_lsa_new(struct ospf_area *area)
        lsah->length = htons(length);
 
        /* Now, create OSPF LSA instance. */
-       if ((new = ospf_lsa_new()) == NULL) {
-               zlog_err("%s: Unable to create new lsa", __func__);
-               return NULL;
-       }
+       new = ospf_lsa_new_and_data(length);
 
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        new->vrf_id = area->ospf->vrf_id;
 
        /* Copy LSA data to store, discard stream. */
-       new->data = ospf_lsa_data_new(length);
        memcpy(new->data, lsah, length);
        stream_free(s);
 
@@ -997,17 +1007,13 @@ static struct ospf_lsa *ospf_network_lsa_new(struct ospf_interface *oi)
        lsah->length = htons(length);
 
        /* Create OSPF LSA instance. */
-       if ((new = ospf_lsa_new()) == NULL) {
-               zlog_err("%s: ospf_lsa_new returned NULL", __func__);
-               return NULL;
-       }
+       new = ospf_lsa_new_and_data(length);
 
        new->area = oi->area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        new->vrf_id = oi->ospf->vrf_id;
 
        /* Copy LSA to store. */
-       new->data = ospf_lsa_data_new(length);
        memcpy(new->data, lsah, length);
        stream_free(s);
 
@@ -1181,13 +1187,12 @@ static struct ospf_lsa *ospf_summary_lsa_new(struct ospf_area *area,
        lsah->length = htons(length);
 
        /* Create OSPF LSA instance. */
-       new = ospf_lsa_new();
+       new = ospf_lsa_new_and_data(length);
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        new->vrf_id = area->ospf->vrf_id;
 
        /* Copy LSA to store. */
-       new->data = ospf_lsa_data_new(length);
        memcpy(new->data, lsah, length);
        stream_free(s);
 
@@ -1323,13 +1328,12 @@ static struct ospf_lsa *ospf_summary_asbr_lsa_new(struct ospf_area *area,
        lsah->length = htons(length);
 
        /* Create OSPF LSA instance. */
-       new = ospf_lsa_new();
+       new = ospf_lsa_new_and_data(length);
        new->area = area;
        SET_FLAG(new->flags, OSPF_LSA_SELF | OSPF_LSA_SELF_CHECKED);
        new->vrf_id = area->ospf->vrf_id;
 
        /* Copy LSA to store. */
-       new->data = ospf_lsa_data_new(length);
        memcpy(new->data, lsah, length);
        stream_free(s);
 
@@ -1629,14 +1633,13 @@ static struct ospf_lsa *ospf_external_lsa_new(struct ospf *ospf,
        lsah->length = htons(length);
 
        /* Now, create OSPF LSA instance. */
-       new = ospf_lsa_new();
+       new = ospf_lsa_new_and_data(length);
        new->area = NULL;
        SET_FLAG(new->flags,
                 OSPF_LSA_SELF | OSPF_LSA_APPROVED | OSPF_LSA_SELF_CHECKED);
        new->vrf_id = ospf->vrf_id;
 
        /* Copy LSA data to store, discard stream. */
-       new->data = ospf_lsa_data_new(length);
        memcpy(new->data, lsah, length);
        stream_free(s);
 
@@ -1816,12 +1819,11 @@ struct ospf_lsa *ospf_translated_nssa_originate(struct ospf *ospf,
        }
 
        if ((new = ospf_lsa_install(ospf, NULL, new)) == NULL) {
-               if (IS_DEBUG_OSPF_NSSA)
-                       zlog_debug(
-                               "ospf_lsa_translated_nssa_originate(): "
-                               "Could not install LSA "
-                               "id %s",
-                               inet_ntoa(type7->data->id));
+               flog_warn(EC_OSPF_LSA_INSTALL_FAILURE,
+                         "ospf_lsa_translated_nssa_originate(): "
+                         "Could not install LSA "
+                         "id %s",
+                         inet_ntoa(type7->data->id));
                return NULL;
        }
 
@@ -1889,7 +1891,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): no Type-7 found for "
                                "Type-5 LSA Id %s",
-                               type5 ? inet_ntoa(type5->data->id) : "(null)");
+                               inet_ntoa(type5->data->id));
                return NULL;
        }
 
@@ -1899,7 +1901,7 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): No translated Type-5 "
                                "found for Type-7 with Id %s",
-                               type7 ? inet_ntoa(type7->data->id) : "(null)");
+                               inet_ntoa(type7->data->id));
                return NULL;
        }
 
@@ -1912,16 +1914,15 @@ struct ospf_lsa *ospf_translated_nssa_refresh(struct ospf *ospf,
                        zlog_debug(
                                "ospf_translated_nssa_refresh(): Could not translate "
                                "Type-7 for %s to Type-5",
-                               type7 ? inet_ntoa(type7->data->id) : "(null)");
+                               inet_ntoa(type7->data->id));
                return NULL;
        }
 
        if (!(new = ospf_lsa_install(ospf, NULL, new))) {
-               if (IS_DEBUG_OSPF_NSSA)
-                       zlog_debug(
-                               "ospf_translated_nssa_refresh(): Could not install "
-                               "translated LSA, Id %s",
-                               type7 ? inet_ntoa(type7->data->id) : "(null)");
+               flog_warn(
+                       EC_OSPF_LSA_INSTALL_FAILURE,
+                       "ospf_translated_nssa_refresh(): Could not install translated LSA, Id %s",
+                       inet_ntoa(type7->data->id));
                return NULL;
        }
 
@@ -2042,19 +2043,28 @@ int ospf_external_lsa_originate_timer(struct thread *thread)
        if (!ext_list)
                return 0;
 
-       for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext))
+       for (ALL_LIST_ELEMENTS_RO(ext_list, node, ext)) {
                /* Originate As-external-LSA from all type of distribute source.
                 */
-               if ((rt = ext->external_info))
-                       for (rn = route_top(rt); rn; rn = route_next(rn))
-                               if ((ei = rn->info) != NULL)
-                                       if (!is_prefix_default(
-                                                   (struct prefix_ipv4 *)&ei
-                                                           ->p))
-                                               if (!ospf_external_lsa_originate(
-                                                           ospf, ei))
-                                                       zlog_warn(
-                                                               "LSA: AS-external-LSA was not originated.");
+               rt = ext->external_info;
+               if (!rt)
+                       continue;
+
+               for (rn = route_top(rt); rn; rn = route_next(rn)) {
+                       ei = rn->info;
+
+                       if (!ei)
+                               continue;
+
+                       if (is_prefix_default((struct prefix_ipv4 *)&ei->p))
+                               continue;
+
+                       if (!ospf_external_lsa_originate(ospf, ei))
+                               flog_warn(
+                                       EC_OSPF_LSA_INSTALL_FAILURE,
+                                       "LSA: AS-external-LSA was not originated.");
+               }
+       }
 
        return 0;
 }
@@ -2521,15 +2531,8 @@ void ospf_discard_from_db(struct ospf *ospf, struct ospf_lsdb *lsdb,
 {
        struct ospf_lsa *old;
 
-       if (!lsdb) {
-               zlog_warn("%s: Called with NULL lsdb!", __func__);
-               if (!lsa)
-                       zlog_warn("%s: and NULL LSA!", __func__);
-               else
-                       zlog_warn("LSA[Type%d:%s]: not associated with LSDB!",
-                                 lsa->data->type, inet_ntoa(lsa->data->id));
+       if (!lsdb)
                return;
-       }
 
        old = ospf_lsdb_lookup(lsdb, lsa);
 
@@ -2840,11 +2843,13 @@ static int ospf_maxage_lsa_remover(struct thread *thread)
                        if (lsa->lsdb) {
                                ospf_discard_from_db(ospf, lsa->lsdb, lsa);
                                ospf_lsdb_delete(lsa->lsdb, lsa);
-                       } else
-                               zlog_warn(
-                                       "%s: LSA[Type%d:%s]: No associated LSDB!",
-                                       __func__, lsa->data->type,
-                                       inet_ntoa(lsa->data->id));
+                       } else {
+                               if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+                                       zlog_debug(
+                                               "%s: LSA[Type%d:%s]: No associated LSDB!",
+                                               __func__, lsa->data->type,
+                                               inet_ntoa(lsa->data->id));
+                       }
                }
 
        /*    A MaxAge LSA must be removed immediately from the router's link
@@ -2912,24 +2917,17 @@ void ospf_lsa_maxage(struct ospf *ospf, struct ospf_lsa *lsa)
        lsa_prefix.prefixlen = sizeof(lsa_prefix.u.ptr) * CHAR_BIT;
        lsa_prefix.u.ptr = (uintptr_t)lsa;
 
-       if ((rn = route_node_get(ospf->maxage_lsa,
-                                (struct prefix *)&lsa_prefix))
-           != NULL) {
-               if (rn->info != NULL) {
-                       if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
-                               zlog_debug(
-                                       "LSA[%s]: found LSA (%p) in table for LSA %p %d",
-                                       dump_lsa_key(lsa), rn->info,
-                                       (void *)lsa, lsa_prefix.prefixlen);
-                       route_unlock_node(rn);
-               } else {
-                       rn->info = ospf_lsa_lock(lsa);
-                       SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
-               }
+       rn = route_node_get(ospf->maxage_lsa, (struct prefix *)&lsa_prefix);
+       if (rn->info != NULL) {
+               if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
+                       zlog_debug(
+                                  "LSA[%s]: found LSA (%p) in table for LSA %p %d",
+                                  dump_lsa_key(lsa), rn->info,
+                                  (void *)lsa, lsa_prefix.prefixlen);
+               route_unlock_node(rn);
        } else {
-               zlog_err("Unable to allocate memory for maxage lsa %s\n",
-                        dump_lsa_key(lsa));
-               assert(0);
+               rn->info = ospf_lsa_lock(lsa);
+               SET_FLAG(lsa->flags, OSPF_LSA_IN_MAXAGE);
        }
 
        if (IS_DEBUG_OSPF(lsa, LSA_FLOODING))
@@ -3635,7 +3633,7 @@ void ospf_refresher_unregister_lsa(struct ospf *ospf, struct ospf_lsa *lsa)
                        ospf->lsa_refresh_queue.qs[lsa->refresh_list];
                listnode_delete(refresh_list, lsa);
                if (!listcount(refresh_list)) {
-                       list_delete_and_null(&refresh_list);
+                       list_delete(&refresh_list);
                        ospf->lsa_refresh_queue.qs[lsa->refresh_list] = NULL;
                }
                ospf_lsa_unlock(&lsa); /* lsa_refresh_queue */
@@ -3704,7 +3702,7 @@ int ospf_lsa_refresh_walker(struct thread *t)
                                lsa->refresh_list = -1;
                                listnode_add(lsa_to_refresh, lsa);
                        }
-                       list_delete_and_null(&refresh_list);
+                       list_delete(&refresh_list);
                }
        }
 
@@ -3720,7 +3718,7 @@ int ospf_lsa_refresh_walker(struct thread *t)
                        &lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/
        }
 
-       list_delete_and_null(&lsa_to_refresh);
+       list_delete(&lsa_to_refresh);
 
        if (IS_DEBUG_OSPF(lsa, LSA_REFRESH))
                zlog_debug("LSA[Refresh]: ospf_lsa_refresh_walker(): end");