]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_zlookup.c
lib: Add LIB_ERR_SNMP
[mirror_frr.git] / pimd / pim_zlookup.c
index 5258377cca5082f9aa5e558d227e326427fd4dac..fb616e1b0dda8ea586c9993c3834516471a06c9a 100644 (file)
@@ -120,7 +120,7 @@ void zclient_lookup_free(void)
 
 void zclient_lookup_new(void)
 {
-       zlookup = zclient_new(master);
+       zlookup = zclient_new_notify(master, &zclient_options_default);
        if (!zlookup) {
                zlog_err("%s: zclient_new() failure", __PRETTY_FUNCTION__);
                return;
@@ -128,6 +128,7 @@ void zclient_lookup_new(void)
 
        zlookup->sock = -1;
        zlookup->t_connect = NULL;
+       zlookup->privs = &pimd_privs;
 
        zclient_lookup_sched_now(zlookup);
 
@@ -135,16 +136,16 @@ void zclient_lookup_new(void)
                    __PRETTY_FUNCTION__);
 }
 
-static int zclient_read_nexthop(struct zclient *zlookup,
+static int zclient_read_nexthop(struct pim_instance *pim,
+                               struct zclient *zlookup,
                                struct pim_zlookup_nexthop nexthop_tab[],
                                const int tab_size, struct in_addr addr)
 {
        int num_ifindex = 0;
        struct stream *s;
-       const uint16_t MIN_LEN = 10; /* getipv4=4 getc=1 getl=4 getc=1 */
        uint16_t length;
-       u_char marker;
-       u_char version;
+       uint8_t marker;
+       uint8_t version;
        vrf_id_t vrf_id;
        uint16_t command = 0;
        struct in_addr raddr;
@@ -153,10 +154,11 @@ static int zclient_read_nexthop(struct zclient *zlookup,
        int nexthop_num;
        int i, err;
 
-       if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+       if (PIM_DEBUG_PIM_NHT_DETAIL) {
                char addr_str[INET_ADDRSTRLEN];
                pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
-               zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str);
+               zlog_debug("%s: addr=%s(%s)", __PRETTY_FUNCTION__, addr_str,
+                          pim->vrf->name);
        }
 
        s = zlookup->ibuf;
@@ -166,19 +168,11 @@ static int zclient_read_nexthop(struct zclient *zlookup,
                err = zclient_read_header(s, zlookup->sock, &length, &marker,
                                          &version, &vrf_id, &command);
                if (err < 0) {
-                       zlog_err("%s %s: zclient_read_header() failed",
-                                __FILE__, __PRETTY_FUNCTION__);
+                       zlog_err("%s: zclient_read_header() failed",
+                                __PRETTY_FUNCTION__);
                        zclient_lookup_failed(zlookup);
                        return -1;
                }
-
-               if (length < MIN_LEN) {
-                       zlog_err(
-                               "%s %s: failure reading zclient lookup socket: len=%d < MIN_LEN=%d",
-                               __FILE__, __PRETTY_FUNCTION__, length, MIN_LEN);
-                       zclient_lookup_failed(zlookup);
-                       return -2;
-               }
        }
 
        raddr.s_addr = stream_get_ipv4(s);
@@ -188,8 +182,9 @@ static int zclient_read_nexthop(struct zclient *zlookup,
                char raddr_str[INET_ADDRSTRLEN];
                pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
                pim_inet4_dump("<raddr?>", raddr, raddr_str, sizeof(raddr_str));
-               zlog_warn("%s: address mismatch: addr=%s raddr=%s",
-                         __PRETTY_FUNCTION__, addr_str, raddr_str);
+               zlog_warn("%s: address mismatch: addr=%s(%s) raddr=%s",
+                         __PRETTY_FUNCTION__, addr_str, pim->vrf->name,
+                         raddr_str);
                /* warning only */
        }
 
@@ -198,8 +193,9 @@ static int zclient_read_nexthop(struct zclient *zlookup,
        nexthop_num = stream_getc(s);
 
        if (nexthop_num < 1) {
-               zlog_err("%s: socket %d bad nexthop_num=%d", __func__,
-                        zlookup->sock, nexthop_num);
+               if (PIM_DEBUG_PIM_NHT_DETAIL)
+                       zlog_debug("%s: socket %d bad nexthop_num=%d", __func__,
+                                  zlookup->sock, nexthop_num);
                return -6;
        }
 
@@ -214,29 +210,35 @@ static int zclient_read_nexthop(struct zclient *zlookup,
                        pim_inet4_dump("<addr?>", addr, addr_str,
                                       sizeof(addr_str));
                        zlog_warn(
-                               "%s %s: found too many nexthop ifindexes (%d > %d) for address %s",
-                               __FILE__, __PRETTY_FUNCTION__,
-                               (num_ifindex + 1), tab_size, addr_str);
+                               "%s: found too many nexthop ifindexes (%d > %d) for address %s(%s)",
+                               __PRETTY_FUNCTION__, (num_ifindex + 1),
+                               tab_size, addr_str, pim->vrf->name);
                        return num_ifindex;
                }
+               nexthop_tab[num_ifindex].protocol_distance = distance;
+               nexthop_tab[num_ifindex].route_metric = metric;
                switch (nexthop_type) {
                case NEXTHOP_TYPE_IFINDEX:
+                       nexthop_tab[num_ifindex].ifindex = stream_getl(s);
+                       /*
+                        * Connected route (i.e. no nexthop), use
+                        * address passed in as PIM nexthop.  This will
+                        * allow us to work in cases where we are
+                        * trying to find a route for this box.
+                        */
+                       nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
+                       nexthop_tab[num_ifindex].nexthop_addr.prefixlen =
+                               IPV4_MAX_BITLEN;
+                       nexthop_tab[num_ifindex].nexthop_addr.u.prefix4 =
+                               addr;
+                       ++num_ifindex;
+                       break;
                case NEXTHOP_TYPE_IPV4_IFINDEX:
                case NEXTHOP_TYPE_IPV4:
                        nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
-                       if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX
-                           || nexthop_type == NEXTHOP_TYPE_IPV4) {
-                               nexthop_tab[num_ifindex]
-                                       .nexthop_addr.u.prefix4.s_addr =
-                                       stream_get_ipv4(s);
-                       } else {
-                               nexthop_tab[num_ifindex]
-                                       .nexthop_addr.u.prefix4.s_addr =
-                                       PIM_NET_INADDR_ANY;
-                       }
+                       nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr =
+                               stream_get_ipv4(s);
                        nexthop_tab[num_ifindex].ifindex = stream_getl(s);
-                       nexthop_tab[num_ifindex].protocol_distance = distance;
-                       nexthop_tab[num_ifindex].route_metric = metric;
                        ++num_ifindex;
                        break;
                case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -256,17 +258,17 @@ static int zclient_read_nexthop(struct zclient *zlookup,
                         * If we are sending v6 secondary assume we receive v6
                         * secondary
                         */
-                       if (pimg->send_v6_secondary)
+                       if (pim->send_v6_secondary)
                                nbr = pim_neighbor_find_by_secondary(
                                        if_lookup_by_index(
                                                nexthop_tab[num_ifindex]
                                                        .ifindex,
-                                               VRF_DEFAULT),
+                                               vrf_id),
                                        &p);
                        else
                                nbr = pim_neighbor_find_if(if_lookup_by_index(
                                        nexthop_tab[num_ifindex].ifindex,
-                                       VRF_DEFAULT));
+                                       vrf_id));
                        if (nbr) {
                                nexthop_tab[num_ifindex].nexthop_addr.family =
                                        AF_INET;
@@ -283,9 +285,9 @@ static int zclient_read_nexthop(struct zclient *zlookup,
                                pim_inet4_dump("<addr?>", addr, addr_str,
                                               sizeof(addr_str));
                                zlog_warn(
-                                       "%s %s: found non-ifindex nexthop type=%d for address %s",
-                                       __FILE__, __PRETTY_FUNCTION__,
-                                       nexthop_type, addr_str);
+                                       "%s: found non-ifindex nexthop type=%d for address %s(%s)",
+                                       __PRETTY_FUNCTION__, nexthop_type,
+                                       addr_str, pim->vrf->name);
                        }
                        break;
                }
@@ -294,51 +296,61 @@ static int zclient_read_nexthop(struct zclient *zlookup,
        return num_ifindex;
 }
 
-static int zclient_lookup_nexthop_once(struct pim_zlookup_nexthop nexthop_tab[],
+static int zclient_lookup_nexthop_once(struct pim_instance *pim,
+                                      struct pim_zlookup_nexthop nexthop_tab[],
                                       const int tab_size, struct in_addr addr)
 {
        struct stream *s;
        int ret;
 
-       if (PIM_DEBUG_PIM_TRACE_DETAIL) {
+       if (PIM_DEBUG_PIM_NHT_DETAIL) {
                char addr_str[INET_ADDRSTRLEN];
                pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
-               zlog_debug("%s: addr=%s", __PRETTY_FUNCTION__, addr_str);
+               zlog_debug("%s: addr=%s(%s)", __PRETTY_FUNCTION__, addr_str,
+                          pim->vrf->name);
        }
 
        /* Check socket. */
        if (zlookup->sock < 0) {
-               zlog_err("%s %s: zclient lookup socket is not connected",
-                        __FILE__, __PRETTY_FUNCTION__);
+               zlog_err("%s: zclient lookup socket is not connected",
+                        __PRETTY_FUNCTION__);
                zclient_lookup_failed(zlookup);
                return -1;
        }
 
+       if (pim->vrf->vrf_id == VRF_UNKNOWN) {
+               zlog_err(
+                       "%s: VRF: %s does not fully exist yet, delaying lookup",
+                       __PRETTY_FUNCTION__, pim->vrf->name);
+               return -1;
+       }
+
        s = zlookup->obuf;
        stream_reset(s);
-       zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, VRF_DEFAULT);
+       zclient_create_header(s, ZEBRA_IPV4_NEXTHOP_LOOKUP_MRIB, pim->vrf_id);
        stream_put_in_addr(s, &addr);
        stream_putw_at(s, 0, stream_get_endp(s));
 
        ret = writen(zlookup->sock, s->data, stream_get_endp(s));
        if (ret < 0) {
                zlog_err(
-                       "%s %s: writen() failure: %d writing to zclient lookup socket",
-                       __FILE__, __PRETTY_FUNCTION__, errno);
+                       "%s: writen() failure: %d writing to zclient lookup socket",
+                       __PRETTY_FUNCTION__, errno);
                zclient_lookup_failed(zlookup);
                return -2;
        }
        if (ret == 0) {
-               zlog_err("%s %s: connection closed on zclient lookup socket",
-                        __FILE__, __PRETTY_FUNCTION__);
+               zlog_err("%s: connection closed on zclient lookup socket",
+                        __PRETTY_FUNCTION__);
                zclient_lookup_failed(zlookup);
                return -3;
        }
 
-       return zclient_read_nexthop(zlookup, nexthop_tab, tab_size, addr);
+       return zclient_read_nexthop(pim, zlookup, nexthop_tab, tab_size, addr);
 }
 
-int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
+int zclient_lookup_nexthop(struct pim_instance *pim,
+                          struct pim_zlookup_nexthop nexthop_tab[],
                           const int tab_size, struct in_addr addr,
                           int max_lookup)
 {
@@ -346,24 +358,24 @@ int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
        uint32_t route_metric = 0xFFFFFFFF;
        uint8_t protocol_distance = 0xFF;
 
-       qpim_nexthop_lookups++;
+       pim->nexthop_lookups++;
 
        for (lookup = 0; lookup < max_lookup; ++lookup) {
                int num_ifindex;
                int first_ifindex;
                struct prefix nexthop_addr;
 
-               num_ifindex = zclient_lookup_nexthop_once(nexthop_tab, tab_size,
-                                                         addr);
+               num_ifindex = zclient_lookup_nexthop_once(pim, nexthop_tab,
+                                                         tab_size, addr);
                if (num_ifindex < 1) {
-                       if (PIM_DEBUG_ZEBRA) {
+                       if (PIM_DEBUG_PIM_NHT) {
                                char addr_str[INET_ADDRSTRLEN];
                                pim_inet4_dump("<addr?>", addr, addr_str,
                                               sizeof(addr_str));
                                zlog_debug(
-                                       "%s %s: lookup=%d/%d: could not find nexthop ifindex for address %s",
-                                       __FILE__, __PRETTY_FUNCTION__, lookup,
-                                       max_lookup, addr_str);
+                                       "%s: lookup=%d/%d: could not find nexthop ifindex for address %s(%s)",
+                                       __PRETTY_FUNCTION__, lookup, max_lookup,
+                                       addr_str, pim->vrf->name);
                        }
                        return -1;
                }
@@ -393,16 +405,16 @@ int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
                        if (lookup > 0) {
                                /* Report non-recursive success after first
                                 * lookup */
-                               if (PIM_DEBUG_ZEBRA) {
+                               if (PIM_DEBUG_PIM_NHT) {
                                        char addr_str[INET_ADDRSTRLEN];
                                        pim_inet4_dump("<addr?>", addr,
                                                       addr_str,
                                                       sizeof(addr_str));
                                        zlog_debug(
-                                               "%s %s: lookup=%d/%d: found non-recursive ifindex=%d for address %s dist=%d met=%d",
-                                               __FILE__, __PRETTY_FUNCTION__,
-                                               lookup, max_lookup,
-                                               first_ifindex, addr_str,
+                                               "%s: lookup=%d/%d: found non-recursive ifindex=%d for address %s(%s) dist=%d met=%d",
+                                               __PRETTY_FUNCTION__, lookup,
+                                               max_lookup, first_ifindex,
+                                               addr_str, pim->vrf->name,
                                                nexthop_tab[0]
                                                        .protocol_distance,
                                                nexthop_tab[0].route_metric);
@@ -420,7 +432,7 @@ int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
                        return num_ifindex;
                }
 
-               if (PIM_DEBUG_ZEBRA) {
+               if (PIM_DEBUG_PIM_NHT) {
                        char addr_str[INET_ADDRSTRLEN];
                        char nexthop_str[PREFIX_STRLEN];
                        pim_inet4_dump("<addr?>", addr, addr_str,
@@ -428,9 +440,9 @@ int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
                        pim_addr_dump("<nexthop?>", &nexthop_addr, nexthop_str,
                                      sizeof(nexthop_str));
                        zlog_debug(
-                               "%s %s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s dist=%d met=%d",
-                               __FILE__, __PRETTY_FUNCTION__, lookup,
-                               max_lookup, nexthop_str, addr_str,
+                               "%s: lookup=%d/%d: zebra returned recursive nexthop %s for address %s(%s) dist=%d met=%d",
+                               __PRETTY_FUNCTION__, lookup, max_lookup,
+                               nexthop_str, addr_str, pim->vrf->name,
                                nexthop_tab[0].protocol_distance,
                                nexthop_tab[0].route_metric);
                }
@@ -440,13 +452,13 @@ int zclient_lookup_nexthop(struct pim_zlookup_nexthop nexthop_tab[],
 
        } /* for (max_lookup) */
 
-       if (PIM_DEBUG_ZEBRA) {
+       if (PIM_DEBUG_PIM_NHT) {
                char addr_str[INET_ADDRSTRLEN];
                pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
                zlog_warn(
-                       "%s %s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s",
-                       __FILE__, __PRETTY_FUNCTION__, lookup, max_lookup,
-                       addr_str);
+                       "%s: lookup=%d/%d: failure searching recursive nexthop ifindex for address %s(%s)",
+                       __PRETTY_FUNCTION__, lookup, max_lookup, addr_str,
+                       pim->vrf->name);
        }
 
        return -2;
@@ -471,7 +483,7 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
        int count = 0;
        int ret;
        struct interface *ifp =
-               pim_if_find_by_vif_index(c_oil->oil.mfcc_parent);
+               pim_if_find_by_vif_index(c_oil->pim, c_oil->oil.mfcc_parent);
 
        if (PIM_DEBUG_ZEBRA) {
                struct prefix_sg more;
@@ -479,15 +491,16 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
                more.src = c_oil->oil.mfcc_origin;
                more.grp = c_oil->oil.mfcc_mcastgrp;
                zlog_debug(
-                       "Sending Request for New Channel Oil Information(%s) VIIF %d",
-                       pim_str_sg_dump(&more), c_oil->oil.mfcc_parent);
+                       "Sending Request for New Channel Oil Information(%s) VIIF %d(%s)",
+                       pim_str_sg_dump(&more), c_oil->oil.mfcc_parent,
+                       c_oil->pim->vrf->name);
        }
 
        if (!ifp)
                return -1;
 
        stream_reset(s);
-       zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, VRF_DEFAULT);
+       zclient_create_header(s, ZEBRA_IPMR_ROUTE_STATS, c_oil->pim->vrf_id);
        stream_put_in_addr(s, &c_oil->oil.mfcc_origin);
        stream_put_in_addr(s, &c_oil->oil.mfcc_mcastgrp);
        stream_putl(s, ifp->ifindex);
@@ -497,8 +510,8 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
        ret = writen(zlookup->sock, s->data, count);
        if (ret <= 0) {
                zlog_err(
-                       "%s %s: writen() failure: %d writing to zclient lookup socket",
-                       __FILE__, __PRETTY_FUNCTION__, errno);
+                       "%s: writen() failure: %d writing to zclient lookup socket",
+                       __PRETTY_FUNCTION__, errno);
                return -1;
        }
 
@@ -508,15 +521,15 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
                int err;
                uint16_t length = 0;
                vrf_id_t vrf_id;
-               u_char marker;
-               u_char version;
+               uint8_t marker;
+               uint8_t version;
 
                stream_reset(s);
                err = zclient_read_header(s, zlookup->sock, &length, &marker,
                                          &version, &vrf_id, &command);
                if (err < 0) {
-                       zlog_err("%s %s: zclient_read_header() failed",
-                                __FILE__, __PRETTY_FUNCTION__);
+                       zlog_err("%s: zclient_read_header() failed",
+                                __PRETTY_FUNCTION__);
                        zclient_lookup_failed(zlookup);
                        return -1;
                }
@@ -526,18 +539,22 @@ int pim_zlookup_sg_statistics(struct channel_oil *c_oil)
        sg.grp.s_addr = stream_get_ipv4(s);
        if (sg.src.s_addr != c_oil->oil.mfcc_origin.s_addr
            || sg.grp.s_addr != c_oil->oil.mfcc_mcastgrp.s_addr) {
-               zlog_err("%s: Received wrong %s information",
-                        __PRETTY_FUNCTION__, pim_str_sg_dump(&sg));
+               if (PIM_DEBUG_ZEBRA) {
+                       struct prefix_sg more;
+
+                       more.src = c_oil->oil.mfcc_origin;
+                       more.grp = c_oil->oil.mfcc_mcastgrp;
+                       zlog_err(
+                               "%s: Received wrong %s(%s) information requested",
+                               __PRETTY_FUNCTION__, pim_str_sg_dump(&more),
+                               c_oil->pim->vrf->name);
+               }
                zclient_lookup_failed(zlookup);
                return -3;
        }
 
        stream_get(&lastused, s, sizeof(lastused));
-       ret = stream_getl(s);
-
-       if (PIM_DEBUG_ZEBRA)
-               zlog_debug("Received %lld for %s success: %d", lastused,
-                          pim_str_sg_dump(&sg), ret);
+       stream_getl(s);
 
        c_oil->cc.lastused = lastused;