]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: First Schwag at pim_register_stop
authorDonald Sharp <sharpd@cumulusnetwroks.com>
Fri, 15 Jul 2016 19:42:09 +0000 (15:42 -0400)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 22 Dec 2016 01:26:02 +0000 (20:26 -0500)
Implement the pim_register_stop state machine.  There are still a few
bugs still but this is enough to get us rolling a bit more.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_ifchannel.c
pimd/pim_ifchannel.h
pimd/pim_mroute.c
pimd/pim_pim.c
pimd/pim_register.c
pimd/pim_register.h
pimd/pim_upstream.c
pimd/pim_upstream.h

index d3855d5d7622791a3944891c19e19f758a62df24..15dd682a506ba5d32f2992f7b66abf19c727671c 100644 (file)
@@ -148,6 +148,7 @@ const char *pim_ifchannel_ifjoin_name(enum pim_ifjoin_state ifjoin_state)
 {
   switch (ifjoin_state) {
   case PIM_IFJOIN_NOINFO:        return "NOINFO";
+  case PIM_IFJOIN_JOIN_PIMREG:   return "REGT";
   case PIM_IFJOIN_JOIN:          return "JOIN";
   case PIM_IFJOIN_PRUNE_PENDING: return "PRUNEP";
   }
@@ -627,6 +628,8 @@ void pim_ifchannel_join_add(struct interface *ifp,
     THREAD_OFF(ch->t_ifjoin_prune_pending_timer);
     pim_ifchannel_ifjoin_switch(__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN);
     break;
+  case PIM_IFJOIN_JOIN_PIMREG:
+    zlog_warn("Received Incorrect new state");
   }
 
   zassert(!IFCHANNEL_NOINFO(ch));
@@ -660,6 +663,7 @@ void pim_ifchannel_prune(struct interface *ifp,
   switch (ch->ifjoin_state) {
   case PIM_IFJOIN_NOINFO:
   case PIM_IFJOIN_PRUNE_PENDING:
+  case PIM_IFJOIN_JOIN_PIMREG:
     /* nothing to do */
     break;
   case PIM_IFJOIN_JOIN:
index e6f1c2947c9fb5df59bfd2bdcd09b6142d97002d..5f488ddc0fd88f2eaa782f204a23fab36b5661c3 100644 (file)
@@ -37,7 +37,8 @@ enum pim_ifmembership {
 enum pim_ifjoin_state {
   PIM_IFJOIN_NOINFO,
   PIM_IFJOIN_JOIN,
-  PIM_IFJOIN_PRUNE_PENDING
+  PIM_IFJOIN_PRUNE_PENDING,
+  PIM_IFJOIN_JOIN_PIMREG,
 };
 
 enum pim_ifassert_state {
index 83a3b1045d98dcd676d2814d7aee923ae86f738c..c13f2cbba497986a50bbaecbd49c40172200dd0e 100644 (file)
@@ -36,6 +36,7 @@
 #include "pim_rp.h"
 #include "pim_oil.h"
 #include "pim_register.h"
+#include "pim_ifchannel.h"
 
 /* GLOBAL VARS */
 extern struct zebra_privs_t pimd_privs;
@@ -93,6 +94,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg
                        const char *src_str, const char *grp_str)
 {
   struct pim_interface *pim_ifp = ifp->info;
+  struct pim_ifchannel *ch;
   struct pim_upstream *up;
   struct pim_rpf *rpg;
 
@@ -149,8 +151,10 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg
     return 0;
   }
   up->channel_oil->cc.pktcnt++;
-
-  pim_channel_add_oif(up->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_SOURCE);
+  up->fhr = 1;
+  ch = pim_ifchannel_add (pim_regiface, msg->im_src, msg->im_dst);
+  pim_ifchannel_ifjoin_switch (__PRETTY_FUNCTION__, ch, PIM_IFJOIN_JOIN_PIMREG);
+  up->join_state = PIM_UPSTREAM_JOINED;
 
   return 0;
 }
index 60bba9e9ba7b86d5856c1efdd7d9f3ab87c6ce68..5f5b2dd5ece5b754daccb8ef3f26e60f5c209828 100644 (file)
@@ -224,7 +224,8 @@ int pim_pim_packet(struct interface *ifp, uint8_t *buf, size_t len)
                                pim_msg_len - PIM_MSG_HEADER_LEN);
       break;
     case PIM_MSG_TYPE_REG_STOP:
-      return pim_register_stop_recv ();
+      return pim_register_stop_recv (pim_msg + PIM_MSG_HEADER_LEN,
+                                    pim_msg_len - PIM_MSG_HEADER_LEN);
       break;
     case PIM_MSG_TYPE_JOIN_PRUNE:
       neigh = pim_neighbor_find(ifp, ip_hdr->ip_src);
index 2876dec83f0b90645eeffe0bfdf60485bf528fb3..c8d0174116e7b288dd757431d8ed0bb8223a91ad 100644 (file)
@@ -112,9 +112,41 @@ pim_register_stop_send (struct interface *ifp, struct in_addr source,
 }
 
 int
-pim_register_stop_recv (void)
+pim_register_stop_recv (uint8_t *buf, int buf_size)
 {
-  zlog_debug ("Received Register Stop");
+  struct pim_upstream *upstream = NULL;
+  struct prefix source;
+  struct prefix group;
+  int l;
+
+  if (PIM_DEBUG_PACKETS)
+    pim_pkt_dump ("Received Register Stop", buf, buf_size);
+
+  l = pim_parse_addr_group (&group, buf, buf_size);
+  buf += l;
+  buf_size -= l;
+  l = pim_parse_addr_ucast (&source, buf, buf_size);
+  upstream = pim_upstream_find (source.u.prefix4, group.u.prefix4);
+  if (!upstream)
+    {
+      return 0;
+    }
+
+  switch (upstream->join_state)
+    {
+    case PIM_UPSTREAM_NOTJOINED:
+    case PIM_UPSTREAM_PRUNE:
+      return 0;
+      break;
+    case PIM_UPSTREAM_JOINED:
+    case PIM_UPSTREAM_JOIN_PENDING:
+      upstream->join_state = PIM_UPSTREAM_PRUNE;
+      pim_upstream_start_register_stop_timer (upstream, 0);
+      pim_channel_del_oif (upstream->channel_oil, pim_regiface, PIM_OIF_FLAG_PROTO_PIM);
+      return 0;
+      break;
+    }
+
   return 0;
 }
 
@@ -313,11 +345,7 @@ pim_register_recv (struct interface *ifp,
        upstream->rpf.rpf_addr.s_addr = source.s_addr;
        upstream->channel_oil->oil.mfcc_origin = source;
        pim_scan_individual_oil (upstream->channel_oil);
-       pim_joinprune_send(upstream->rpf.source_nexthop.interface,
-                          upstream->rpf.source_nexthop.mrib_nexthop_addr,
-                          upstream->source_addr,
-                          upstream->group_addr,
-                          1);
+        pim_upstream_send_join (upstream);
 
        //decapsulate and forward the iner packet to
        //inherited_olist(S,G,rpt)
index 3de1557966ee2355c8611a1af4230a0f3fb7bc0c..8ab24b71372e8afd6b5d17cc6f29976754c34576 100644 (file)
@@ -35,7 +35,8 @@ void pim_register_send_test_packet_start (struct in_addr source,
                                          struct in_addr group,
                                          uint32_t pps);
 
-int pim_register_stop_recv (void);
+int pim_register_stop_recv (uint8_t *buf, int buf_size);
+
 int pim_register_recv (struct interface *ifp,
                       struct in_addr dest_addr,
                       struct in_addr src_addr,
index 87f6089b28750fe9468f3a072d3f30fe3f5bad6c..4f2c2d0eaa7c72188151a7b39e5778be5ea640e9 100644 (file)
@@ -82,25 +82,34 @@ void pim_upstream_delete(struct pim_upstream *up)
   pim_upstream_free(up);
 }
 
-static void send_join(struct pim_upstream *up)
+void
+pim_upstream_send_join (struct pim_upstream *up)
 {
-  zassert(up->join_state == PIM_UPSTREAM_JOINED);
-
-  
   if (PIM_DEBUG_PIM_TRACE) {
+    char src_str[100];
+    char grp_str[100];
+    char rpf_str[100];
+    pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
+    pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
+    pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
+    zlog_debug ("%s: RPF'(%s,%s)=%s(%s) for Interface %s", __PRETTY_FUNCTION__,
+               src_str, grp_str, rpf_str, pim_upstream_state2str (up),
+               up->rpf.source_nexthop.interface->name);
     if (PIM_INADDR_IS_ANY(up->rpf.rpf_addr)) {
-      char src_str[100];
-      char grp_str[100];
-      char rpf_str[100];
-      pim_inet4_dump("<src?>", up->source_addr, src_str, sizeof(src_str));
-      pim_inet4_dump("<grp?>", up->group_addr, grp_str, sizeof(grp_str));
-      pim_inet4_dump("<rpf?>", up->rpf.rpf_addr, rpf_str, sizeof(rpf_str));
-      zlog_warn("%s: can't send join upstream: RPF'(%s,%s)=%s",
-               __PRETTY_FUNCTION__,
-               src_str, grp_str, rpf_str);
+      zlog_debug("%s: can't send join upstream: RPF'(%s,%s)=%s",
+                __PRETTY_FUNCTION__,
+                src_str, grp_str, rpf_str);
       /* warning only */
     }
   }
+
+  /*
+   * In the case of a FHR we will not have anyone to send this to.
+   */
+  if (up->fhr)
+    return;
+
+  zassert(up->join_state == PIM_UPSTREAM_JOINED);
   
   /* send Join(S,G) to the current upstream neighbor */
   pim_joinprune_send(up->rpf.source_nexthop.interface,
@@ -118,7 +127,7 @@ static int on_join_timer(struct thread *t)
   up = THREAD_ARG(t);
   zassert(up);
 
-  send_join(up);
+  pim_upstream_send_join (up);
 
   up->t_join_timer = NULL;
   join_timer_start(up);
@@ -334,7 +343,7 @@ static void pim_upstream_switch(struct pim_upstream *up,
 
   if (new_state == PIM_UPSTREAM_JOINED) {
     forward_on(up);
-    send_join(up);
+    pim_upstream_send_join (up);
     join_timer_start(up);
   }
   else {
index 222e30b4baf157b57cadd3eff346bc288be49eb4..5e7d6114df7d8ffe096be81f6d457a29104a543e 100644 (file)
@@ -87,6 +87,7 @@ enum pim_upstream_sptbit {
   See RFC 4601: 4.5.7.  Sending (S,G) Join/Prune Message
 */
 struct pim_upstream {
+  int                      fhr;
   struct in_addr           upstream_addr;/* Who we are talking to */
   struct in_addr           source_addr;  /* (S,G) source key */
   struct in_addr           group_addr;   /* (S,G) group key */
@@ -152,5 +153,7 @@ int pim_upstream_switch_to_spt_desired (struct in_addr source, struct in_addr gr
 
 void pim_upstream_start_register_stop_timer (struct pim_upstream *up, int null_register);
 
+void pim_upstream_send_join (struct pim_upstream *up);
+
 const char *pim_upstream_state2str (struct pim_upstream *up);
 #endif /* PIM_UPSTREAM_H */