]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: mtrace router code improvments and fixes 1931/head
authorMladen Sablic <mladen.sablic@gmail.com>
Mon, 19 Mar 2018 16:36:29 +0000 (17:36 +0100)
committerMladen Sablic <mladen.sablic@gmail.com>
Thu, 22 Mar 2018 21:05:28 +0000 (22:05 +0100)
Mtrace router code has been fixed for the case where no PIM
interface exists towards the source and next-hop is returned.

fwd_ttl is set to one, for correct reporting of mcast ttl.

Also, NO_MULTICAST error is returned when there is no PIM.

And prev_hop is set to source, for case when connected to source,
to help termination of hop-by-hop queries.

Dependency of logging on PIM, when sending mtrace packet, has been
removed.

Signed-off-by: Mladen Sablic <mladen.sablic@gmail.com>
pimd/pim_igmp_mtrace.c

index 5e2e316d850d0101d14d8d97727438ce0239c1e3..c60436f391909de62bd122cb327ff2ed2941792d 100644 (file)
 #include "pim_macro.h"
 #include "pim_igmp_mtrace.h"
 
+static struct in_addr mtrace_primary_address(struct interface *ifp)
+{
+       struct connected *ifc;
+       struct listnode *node;
+       struct in_addr any;
+       struct pim_interface *pim_ifp;
+
+       if (ifp->info) {
+               pim_ifp = ifp->info;
+               return pim_ifp->primary_address;
+       }
+
+       any.s_addr = INADDR_ANY;
+
+       for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+               struct prefix *p = ifc->address;
+
+               if (p->family != AF_INET)
+                       continue;
+
+               if (!CHECK_FLAG(ifc->flags, ZEBRA_IFA_SECONDARY))
+                       return p->u.prefix4;
+               /* in case no primary found, return a secondary */
+               any = p->u.prefix4;
+       }
+       return any;
+}
+
 static void mtrace_rsp_init(struct igmp_mtrace_rsp *mtrace_rspp)
 {
        mtrace_rspp->arrival = 0;
@@ -133,28 +161,29 @@ static int mtrace_send_packet(struct interface *ifp,
                              struct in_addr group_addr)
 {
        struct sockaddr_in to;
-       struct pim_interface *pim_ifp;
        socklen_t tolen;
        ssize_t sent;
        int ret;
        int fd;
-       char pim_str[INET_ADDRSTRLEN];
+       char if_str[INET_ADDRSTRLEN];
        char rsp_str[INET_ADDRSTRLEN];
        u_char ttl;
 
-       pim_ifp = ifp->info;
-
        memset(&to, 0, sizeof(to));
        to.sin_family = AF_INET;
        to.sin_addr = dst_addr;
        tolen = sizeof(to);
 
-       if (PIM_DEBUG_MTRACE)
-               zlog_debug("Sending mtrace packet to %s on %s",
-                          inet_ntop(AF_INET, &mtracep->rsp_addr, rsp_str,
-                                    sizeof(rsp_str)),
-                          inet_ntop(AF_INET, &pim_ifp->primary_address,
-                                    pim_str, sizeof(pim_str)));
+       if (PIM_DEBUG_MTRACE) {
+               struct in_addr if_addr;
+
+               if_addr = mtrace_primary_address(ifp);
+               zlog_debug(
+                       "Sending mtrace packet to %s on %s",
+                       inet_ntop(AF_INET, &mtracep->rsp_addr, rsp_str,
+                                 sizeof(rsp_str)),
+                       inet_ntop(AF_INET, &if_addr, if_str, sizeof(if_str)));
+       }
 
        fd = pim_socket_raw(IPPROTO_IGMP);
 
@@ -461,7 +490,6 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
        struct interface *ifp;
        struct interface *out_ifp;
        struct pim_interface *pim_ifp;
-       struct pim_interface *pim_out_ifp;
        struct pim_instance *pim;
        struct igmp_mtrace *mtracep;
        struct igmp_mtrace_rsp *rspp;
@@ -643,20 +671,27 @@ int igmp_mtrace_recv_qry_req(struct igmp_sock *igmp, struct ip *ip_hdr,
        }
 
        out_ifp = nexthop.interface;
-       pim_out_ifp = out_ifp->info;
 
-       rspp->incoming = pim_out_ifp->primary_address;
+       rspp->incoming = mtrace_primary_address(out_ifp);
        rspp->prev_hop = nh_addr;
        rspp->in_count = htonl(MTRACE_UNKNOWN_COUNT);
        rspp->total = htonl(MTRACE_UNKNOWN_COUNT);
        rspp->rtg_proto = MTRACE_RTG_PROTO_PIM;
+       rspp->fwd_ttl = 1;
        rspp->s = 1;
        rspp->src_mask = 32;
 
        if (nh_addr.s_addr == 0) {
+               /* no pim? */
+               if (!out_ifp->info) {
+                       rspp->fwd_code = MTRACE_FWD_CODE_NO_MULTICAST;
+                       return mtrace_send_response(pim, mtracep, mtrace_len);
+               }
                /* reached source? */
-               if (pim_if_connected_to_source(out_ifp, mtracep->src_addr))
+               if (pim_if_connected_to_source(out_ifp, mtracep->src_addr)) {
+                       rspp->prev_hop = mtracep->src_addr;
                        return mtrace_send_response(pim, mtracep, mtrace_len);
+               }
                /*
                 * 6.4 Forwarding Traceroute Requests:
                 * Previous-hop router not known