]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Create special pimreg interface
authorDonald Sharp <sharpd@cumulusnetworks.com>
Thu, 29 Oct 2015 13:35:12 +0000 (06:35 -0700)
committerDonald Sharp <sharpd@cumulusnetwroks.com>
Thu, 26 May 2016 00:38:35 +0000 (20:38 -0400)
The linux kernel wants a pimreg vif device.  The pimd
code wants a 'struct interface *' for anything it works
with.  Since the pimreg vif device is not a real linux
device that zebra knows about.  Cheat by creating
a pimreg interface pointer and setup the code to
properly be able to handle the registration of the vif
device.

Signed-off-by: Donald Sharp <sharpd@cumulusnetworks.com>
pimd/pim_cmd.c
pimd/pim_iface.c
pimd/pim_iface.h
pimd/pim_oil.c

index a82c02de0fe6c5494c8401ad6eab3aa0d5287920..995f074aa1a42fe97eccfc7fe17b8818bbd4dc46 100644 (file)
@@ -3283,6 +3283,8 @@ DEFUN (interface_ip_pim_sm,
     return CMD_WARNING;
   }
 
+  pim_if_create_pimreg();
+
   return CMD_SUCCESS;
 }
 
index e9e1b491dc65a115ef611804977f10fc1aa85e4b..985a7588a7d76904a9fb601258c9f1a6f7186c12 100644 (file)
@@ -41,6 +41,8 @@
 #include "pim_time.h"
 #include "pim_ssmpingd.h"
 
+struct interface *pim_regiface = NULL;
+
 static void pim_if_igmp_join_del_all(struct interface *ifp);
 
 void pim_if_init()
@@ -145,8 +147,6 @@ struct pim_interface *pim_if_new(struct interface *ifp, int igmp, int pim)
 
   pim_sock_reset(ifp);
 
-  zassert(PIM_IF_TEST_PIM(pim_ifp->options) || PIM_IF_TEST_IGMP(pim_ifp->options));
-
   if (PIM_MROUTE_IS_ENABLED) {
     pim_if_add_vif(ifp);
   }
@@ -615,6 +615,7 @@ int pim_if_add_vif(struct interface *ifp)
 {
   struct pim_interface *pim_ifp = ifp->info;
   struct in_addr ifaddr;
+  unsigned char flags;
 
   zassert(pim_ifp);
 
@@ -640,14 +641,15 @@ int pim_if_add_vif(struct interface *ifp)
   }
 
   ifaddr = pim_ifp->primary_address;
-  if (PIM_INADDR_IS_ANY(ifaddr)) {
+  if (ifp->ifindex != PIM_OIF_PIM_REGISTER_VIF && PIM_INADDR_IS_ANY(ifaddr)) {
     zlog_warn("%s: could not get address for interface %s ifindex=%d",
              __PRETTY_FUNCTION__,
              ifp->name, ifp->ifindex);
     return -4;
   }
 
-  if (pim_mroute_add_vif(ifp->ifindex, ifaddr, 0)) {
+  flags = (ifp->ifindex == PIM_OIF_PIM_REGISTER_VIF) ? VIFF_REGISTER : 0;
+  if (pim_mroute_add_vif(ifp->ifindex, ifaddr, flags)) {
     /* pim_mroute_add_vif reported error */
     return -5;
   }
@@ -657,7 +659,8 @@ int pim_if_add_vif(struct interface *ifp)
   /*
     Update highest vif_index
    */
-  if (pim_ifp->mroute_vif_index > qpim_mroute_oif_highest_vif_index) {
+  if (pim_ifp->mroute_vif_index != PIM_OIF_PIM_REGISTER_VIF &&
+      pim_ifp->mroute_vif_index > qpim_mroute_oif_highest_vif_index) {
     qpim_mroute_oif_highest_vif_index = pim_ifp->mroute_vif_index;
   }
 
@@ -1197,3 +1200,18 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp)
     pim_ifchannel_update_assert_tracking_desired(ch);
   }
 }
+
+/*
+ * PIM wants to have an interface pointer for everything it does.
+ * The pimreg is a special interface that we have that is not
+ * quite an inteface but a VIF is created for it.
+ */
+void pim_if_create_pimreg (void)
+{
+  if (!pim_regiface) {
+    pim_regiface = if_create("pimreg", strlen("pimreg"));
+    pim_regiface->ifindex = PIM_OIF_PIM_REGISTER_VIF;
+
+    pim_if_new(pim_regiface, 0, 0);
+  }
+}
index 9c4e1a770ece6b2a437c0767995165dfe7db843e..6e824a7d3bd73744d7f1d613f53ee45888dd4d44 100644 (file)
@@ -107,6 +107,7 @@ struct pim_interface {
   uint32_t       pim_ifstat_hello_recvfail;
 };
 
+extern struct interface *pim_regiface;
 /*
   if default_holdtime is set (>= 0), use it;
   otherwise default_holdtime is 3.5 * hello_period
@@ -166,4 +167,5 @@ void pim_if_update_join_desired(struct pim_interface *pim_ifp);
 
 void pim_if_update_assert_tracking_desired(struct interface *ifp);
 
+void pim_if_create_pimreg(void);
 #endif /* PIM_IFACE_H */
index 20e3897e20360e8fbe74c06487190d561f5cefc3..7c03370fc43325bd2d145f6d47ffb3e813525509 100644 (file)
@@ -194,9 +194,6 @@ int pim_channel_add_oif(struct channel_oil *channel_oil,
   }
 #endif
 
-  zassert(qpim_mroute_oif_highest_vif_index < MAXVIFS);
-  zassert(pim_ifp->mroute_vif_index <= qpim_mroute_oif_highest_vif_index);
-
   /* Prevent single protocol from subscribing same interface to
      channel (S,G) multiple times */
   if (channel_oil->oif_flags[pim_ifp->mroute_vif_index] & proto_mask) {