]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_zebra.c
pimd: Add debug messages as to why a register packet is rejected.
[mirror_frr.git] / pimd / pim_zebra.c
index bda5dd6845e57a4fadba3cf0d033f7cd5314ed13..addccef82bee2aaaa885b5796ac6f915e1f2e3e1 100644 (file)
@@ -17,7 +17,6 @@
   Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
   MA 02110-1301 USA
   
-  $QuaggaId: $Format:%an, %ai, %h$ $
 */
 
 #include <zebra.h>
@@ -30,6 +29,8 @@
 #include "zclient.h"
 #include "stream.h"
 #include "network.h"
+#include "vty.h"
+#include "plist.h"
 
 #include "pimd.h"
 #include "pim_pim.h"
@@ -237,9 +238,7 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
     return 0;
 
   p = c->address;
-  if (p->family != AF_INET)
-    return 0;
-  
+
   if (PIM_DEBUG_ZEBRA) {
     char buf[BUFSIZ];
     prefix2str(p, buf, BUFSIZ);
@@ -253,6 +252,27 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
 #endif
   }
 
+  if (p->family != AF_INET)
+    {
+      struct pim_interface *pim_ifp = c->ifp->info;
+      struct listnode *cnode;
+      struct connected *conn;
+      int v4addrs = 0;
+
+      for (ALL_LIST_ELEMENTS_RO (c->ifp->connected, cnode, conn))
+        {
+          if (conn->address->family == AF_INET)
+           v4addrs++;
+        }
+      if (!v4addrs && pim_ifp) 
+       {
+         pim_ifp->primary_address = pim_find_primary_addr (c->ifp);
+         pim_if_addr_add_all (c->ifp);
+          pim_if_add_vif (c->ifp);
+       }
+      return 0;
+    }
+
   pim_rp_check_rp (old, p->u.prefix4);
 
   if (!CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)) {
@@ -279,6 +299,18 @@ static int pim_zebra_if_address_add(int command, struct zclient *zclient,
 
   pim_if_addr_add(c);
 
+  if (if_is_loopback (c->ifp))
+    {
+      struct listnode *ifnode;
+      struct interface *ifp;
+
+      for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), ifnode, ifp))
+        {
+         if (!if_is_loopback (ifp) && if_is_operative (ifp))
+           pim_if_addr_add_all (ifp);
+        }
+    }
+
   return 0;
 }
 
@@ -332,16 +364,25 @@ static void scan_upstream_rpf_cache()
 
   for (ALL_LIST_ELEMENTS(qpim_upstream_list, up_node, up_nextnode, up)) {
     struct in_addr      old_rpf_addr;
+    struct interface    *old_interface;
     enum pim_rpf_result rpf_result;
 
-    rpf_result = pim_rpf_update(up, &old_rpf_addr, NULL);
+    old_interface = up->rpf.source_nexthop.interface;
+    rpf_result = pim_rpf_update(up, &old_rpf_addr);
     if (rpf_result == PIM_RPF_FAILURE)
       continue;
 
     if (rpf_result == PIM_RPF_CHANGED) {
       
       if (up->join_state == PIM_UPSTREAM_JOINED) {
-       
+       /*
+         * If we come up real fast we can be here
+        * where the mroute has not been installed
+        * so install it.
+        */
+       if (up->channel_oil && !up->channel_oil->installed)
+          pim_mroute_add (up->channel_oil);
+
        /*
          RFC 4601: 4.5.7.  Sending (S,G) Join/Prune Messages
          
@@ -358,17 +399,13 @@ static void scan_upstream_rpf_cache()
 
     
        /* send Prune(S,G) to the old upstream neighbor */
-       pim_joinprune_send(up->rpf.source_nexthop.interface,
-                          old_rpf_addr,
-                          up->source_addr,
-                          up->group_addr,
-                          0 /* prune */);
+       pim_joinprune_send(old_interface, old_rpf_addr,
+                          &up->sg, 0 /* prune */);
        
        /* send Join(S,G) to the current upstream neighbor */
        pim_joinprune_send(up->rpf.source_nexthop.interface,
-                          up->rpf.rpf_addr,
-                          up->source_addr,
-                          up->group_addr,
+                          up->rpf.rpf_addr.u.prefix4,
+                          &up->sg,
                           1 /* join */);
 
        pim_upstream_join_timer_restart(up);
@@ -391,7 +428,7 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
   int input_iface_vif_index;
   int old_vif_index;
 
-  if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin))
+  if (!pim_rp_set_upstream_addr (&vif_source, c_oil->oil.mfcc_origin, c_oil->oil.mfcc_mcastgrp))
     return;
 
   input_iface_vif_index = fib_lookup_if_vif_index (vif_source);
@@ -428,8 +465,8 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
       zlog_debug("%s %s: (S,G)=(%s,%s) input interface changed from %s vif_index=%d to %s vif_index=%d",
                 __FILE__, __PRETTY_FUNCTION__,
                 source_str, group_str,
-                old_iif ? old_iif->name : "<old_iif?>", c_oil->oil.mfcc_parent,
-                new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+                old_iif->name, c_oil->oil.mfcc_parent,
+                new_iif->name, input_iface_vif_index);
     }
 
   /* new iif loops to existing oif ? */
@@ -445,7 +482,7 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
        zlog_debug("%s %s: (S,G)=(%s,%s) new iif loops to existing oif: %s vif_index=%d",
                   __FILE__, __PRETTY_FUNCTION__,
                   source_str, group_str,
-                  new_iif ? new_iif->name : "<new_iif?>", input_iface_vif_index);
+                  new_iif->name, input_iface_vif_index);
       }
 
       del_oif(c_oil, new_iif, PIM_OIF_FLAG_PROTO_ANY);
@@ -455,7 +492,6 @@ pim_scan_individual_oil (struct channel_oil *c_oil)
     old_vif_index = c_oil->oil.mfcc_parent;
     c_oil->oil.mfcc_parent = input_iface_vif_index;
 
-    zlog_debug ("FF");
     /* update kernel multicast forwarding cache (MFC) */
     if (pim_mroute_add(c_oil))
       {
@@ -503,6 +539,7 @@ static int on_rpf_cache_refresh(struct thread *t)
   qpim_rpf_cache_refresh_last = pim_time_monotonic_sec();
   ++qpim_rpf_cache_refresh_events;
 
+  pim_rp_setup ();
   return 0;
 }
 
@@ -656,6 +693,7 @@ static int redist_read_ipv4_route(int command, struct zclient *zclient,
 
   sched_rpf_cache_refresh();
 
+  pim_rp_setup ();
   return 0;
 }
 
@@ -721,9 +759,7 @@ void pim_zebra_init(char *zebra_sock_path)
                __PRETTY_FUNCTION__);
   }
 
-  zassert(!qpim_zclient_lookup);
-  qpim_zclient_lookup = zclient_lookup_new();
-  zassert(qpim_zclient_lookup);
+  zclient_lookup_new();
 }
 
 void igmp_anysource_forward_start(struct igmp_group *group)
@@ -756,13 +792,13 @@ void igmp_anysource_forward_stop(struct igmp_group *group)
 
 static int fib_lookup_if_vif_index(struct in_addr addr)
 {
-  struct pim_zlookup_nexthop nexthop_tab[PIM_NEXTHOP_IFINDEX_TAB_SIZE];
+  struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
   int num_ifindex;
   int vif_index;
   ifindex_t first_ifindex;
 
-  num_ifindex = zclient_lookup_nexthop(qpim_zclient_lookup, nexthop_tab,
-                                      PIM_NEXTHOP_IFINDEX_TAB_SIZE, addr,
+  num_ifindex = zclient_lookup_nexthop(nexthop_tab,
+                                      MULTIPATH_NUM, addr,
                                       PIM_NEXTHOP_LOOKUP_MAX);
   if (num_ifindex < 1) {
     char addr_str[100];
@@ -951,16 +987,17 @@ static int del_oif(struct channel_oil *channel_oil,
 void igmp_source_forward_start(struct igmp_source *source)
 {
   struct igmp_group *group;
+  struct prefix_sg sg;
   int result;
 
+  memset (&sg, 0, sizeof (struct prefix_sg));
+  sg.src = source->source_addr;
+  sg.grp = source->source_group->group_addr;
+
   if (PIM_DEBUG_IGMP_TRACE) {
-    char source_str[100];
-    char group_str[100]; 
-    pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
-    pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
-    zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
+    zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
               __PRETTY_FUNCTION__,
-              source_str, group_str,
+              pim_str_sg_dump (&sg),
               source->source_group->group_igmp_sock->fd,
               source->source_group->group_igmp_sock->interface->name,
               IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
@@ -978,7 +1015,7 @@ void igmp_source_forward_start(struct igmp_source *source)
     struct in_addr vif_source;
     struct pim_interface *pim_oif;
 
-    if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr))
+    if (!pim_rp_set_upstream_addr (&vif_source, source->source_addr, sg.grp))
       return;
 
     int input_iface_vif_index = fib_lookup_if_vif_index(vif_source);
@@ -1013,13 +1050,9 @@ void igmp_source_forward_start(struct igmp_source *source)
     if (input_iface_vif_index == pim_oif->mroute_vif_index) {
       /* ignore request for looped MFC entry */
       if (PIM_DEBUG_IGMP_TRACE) {
-       char source_str[100];
-       char group_str[100]; 
-       pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
-       pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
-       zlog_debug("%s: ignoring request for looped MFC entry (S,G)=(%s,%s): igmp_sock=%d oif=%s vif_index=%d",
+       zlog_debug("%s: ignoring request for looped MFC entry (S,G)=%s: igmp_sock=%d oif=%s vif_index=%d",
                   __PRETTY_FUNCTION__,
-                  source_str, group_str,
+                  pim_str_sg_dump (&sg),
                   source->source_group->group_igmp_sock->fd,
                   source->source_group->group_igmp_sock->interface->name,
                   input_iface_vif_index);
@@ -1027,17 +1060,12 @@ void igmp_source_forward_start(struct igmp_source *source)
       return;
     }
 
-    source->source_channel_oil = pim_channel_oil_add(group->group_addr,
-                                                    source->source_addr,
+    source->source_channel_oil = pim_channel_oil_add(&sg,
                                                     input_iface_vif_index);
     if (!source->source_channel_oil) {
-      char group_str[100]; 
-      char source_str[100];
-      pim_inet4_dump("<group?>", group->group_addr, group_str, sizeof(group_str));
-      pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
-      zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
+      zlog_warn("%s %s: could not create OIL for channel (S,G)=%s",
                __FILE__, __PRETTY_FUNCTION__,
-               source_str, group_str);
+               pim_str_sg_dump (&sg));
       return;
     }
   }
@@ -1055,8 +1083,7 @@ void igmp_source_forward_start(struct igmp_source *source)
     Feed IGMPv3-gathered local membership information into PIM
     per-interface (S,G) state.
    */
-  pim_ifchannel_local_membership_add(group->group_igmp_sock->interface,
-                                    source->source_addr, group->group_addr);
+  pim_ifchannel_local_membership_add(group->group_igmp_sock->interface, &sg);
 
   IGMP_SOURCE_DO_FORWARDING(source->source_flags);
 }
@@ -1068,16 +1095,17 @@ void igmp_source_forward_start(struct igmp_source *source)
 void igmp_source_forward_stop(struct igmp_source *source)
 {
   struct igmp_group *group;
+  struct prefix_sg sg;
   int result;
 
+  memset (&sg, 0, sizeof (struct prefix_sg));
+  sg.src = source->source_addr;
+  sg.grp = source->source_group->group_addr;
+
   if (PIM_DEBUG_IGMP_TRACE) {
-    char source_str[100];
-    char group_str[100]; 
-    pim_inet4_dump("<source?>", source->source_addr, source_str, sizeof(source_str));
-    pim_inet4_dump("<group?>", source->source_group->group_addr, group_str, sizeof(group_str));
-    zlog_debug("%s: (S,G)=(%s,%s) igmp_sock=%d oif=%s fwd=%d",
+    zlog_debug("%s: (S,G)=%s igmp_sock=%d oif=%s fwd=%d",
               __PRETTY_FUNCTION__,
-              source_str, group_str,
+              pim_str_sg_dump (&sg),
               source->source_group->group_igmp_sock->fd,
               source->source_group->group_igmp_sock->interface->name,
               IGMP_SOURCE_TEST_FORWARDING(source->source_flags));
@@ -1116,7 +1144,7 @@ void igmp_source_forward_stop(struct igmp_source *source)
     per-interface (S,G) state.
    */
   pim_ifchannel_local_membership_del(group->group_igmp_sock->interface,
-                                    source->source_addr, group->group_addr);
+                                    &sg);
 
   IGMP_SOURCE_DONT_FORWARDING(source->source_flags);
 }
@@ -1130,8 +1158,8 @@ void pim_forward_start(struct pim_ifchannel *ch)
     char group_str[100]; 
     char upstream_str[100];
 
-    pim_inet4_dump("<source?>", ch->sg.u.sg.src, source_str, sizeof(source_str));
-    pim_inet4_dump("<group?>", ch->sg.u.sg.grp, group_str, sizeof(group_str));
+    pim_inet4_dump("<source?>", ch->sg.src, source_str, sizeof(source_str));
+    pim_inet4_dump("<group?>", ch->sg.grp, group_str, sizeof(group_str));
     pim_inet4_dump("<upstream?>", up->upstream_addr, upstream_str, sizeof(upstream_str));
     zlog_debug("%s: (S,G)=(%s,%s) oif=%s(%s)",
               __PRETTY_FUNCTION__,
@@ -1142,23 +1170,19 @@ void pim_forward_start(struct pim_ifchannel *ch)
     int input_iface_vif_index = fib_lookup_if_vif_index(up->upstream_addr);
     if (input_iface_vif_index < 1) {
       char source_str[100];
-      pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));
+      pim_inet4_dump("<source?>", up->sg.src, source_str, sizeof(source_str));
       zlog_warn("%s %s: could not find input interface for source %s",
                __FILE__, __PRETTY_FUNCTION__,
                source_str);
       return;
     }
 
-    up->channel_oil = pim_channel_oil_add(up->group_addr, up->source_addr,
+    up->channel_oil = pim_channel_oil_add(&up->sg,
                                          input_iface_vif_index);
     if (!up->channel_oil) {
-      char group_str[100]; 
-      char source_str[100];
-      pim_inet4_dump("<group?>", up->group_addr, group_str, sizeof(group_str));
-      pim_inet4_dump("<source?>", up->source_addr, source_str, sizeof(source_str));
-      zlog_warn("%s %s: could not create OIL for channel (S,G)=(%s,%s)",
+      zlog_warn("%s %s: could not create OIL for channel (S,G)=%s",
                __FILE__, __PRETTY_FUNCTION__,
-               source_str, group_str);
+               pim_str_sg_dump (&up->sg));
       return;
     }
   }
@@ -1173,23 +1197,15 @@ void pim_forward_stop(struct pim_ifchannel *ch)
   struct pim_upstream *up = ch->upstream;
 
   if (PIM_DEBUG_PIM_TRACE) {
-    char source_str[100];
-    char group_str[100]; 
-    pim_inet4_dump("<source?>", ch->sg.u.sg.src, source_str, sizeof(source_str));
-    pim_inet4_dump("<group?>", ch->sg.u.sg.grp, group_str, sizeof(group_str));
-    zlog_debug("%s: (S,G)=(%s,%s) oif=%s",
+    zlog_debug("%s: (S,G)=%s oif=%s",
               __PRETTY_FUNCTION__,
-              source_str, group_str, ch->interface->name);
+              pim_str_sg_dump (&ch->sg), ch->interface->name);
   }
 
   if (!up->channel_oil) {
-    char source_str[100];
-    char group_str[100]; 
-    pim_inet4_dump("<source?>", ch->sg.u.sg.src, source_str, sizeof(source_str));
-    pim_inet4_dump("<group?>", ch->sg.u.sg.grp, group_str, sizeof(group_str));
-    zlog_warn("%s: (S,G)=(%s,%s) oif=%s missing channel OIL",
-              __PRETTY_FUNCTION__,
-              source_str, group_str, ch->interface->name);
+    zlog_warn("%s: (S,G)=%s oif=%s missing channel OIL",
+             __PRETTY_FUNCTION__,
+             pim_str_sg_dump(&ch->sg), ch->interface->name);
 
     return;
   }