]> git.proxmox.com Git - mirror_frr.git/commitdiff
zebra link state detection support
authorpaul <paul>
Fri, 13 Dec 2002 21:03:13 +0000 (21:03 +0000)
committerpaul <paul>
Fri, 13 Dec 2002 21:03:13 +0000 (21:03 +0000)
14 files changed:
bgpd/bgp_zebra.c
lib/if.c
lib/if.h
lib/zclient.c
ospfd/ospf_ase.c
ospfd/ospf_lsa.c
ospfd/ospf_vty.c
ospfd/ospf_zebra.c
ospfd/ospfd.c
ripd/rip_interface.c
ripd/ripd.c
zebra/interface.c
zebra/rt_netlink.c
zebra/zserv.c

index 3e5cdd2a139f9edff611418877096338453b2be3..aef888be59af23058e9e5c4eb40a840ffebf97ea 100644 (file)
@@ -208,7 +208,7 @@ bgp_interface_address_add (int command, struct zclient *zclient,
 
   bgp_if_update (ifc->ifp);
 
-  if (if_is_up (ifc->ifp))
+  if (if_is_operative (ifc->ifp))
     bgp_connected_add (ifc);
 
   return 0;
@@ -227,7 +227,7 @@ bgp_interface_address_delete (int command, struct zclient *zclient,
 
   bgp_if_update (ifc->ifp);
 
-  if (if_is_up (ifc->ifp))
+  if (if_is_operative (ifc->ifp))
     bgp_connected_delete (ifc);
 
   connected_free (ifc);
index 0934e40d941a2a4067ed4839e32c416dcdafd374..ce3595d398790189f3dacf4ce32bdc763c554f82 100644 (file)
--- a/lib/if.c
+++ b/lib/if.c
@@ -270,6 +270,22 @@ if_is_up (struct interface *ifp)
   return ifp->flags & IFF_UP;
 }
 
+/* Is interface running? */
+int
+if_is_running (struct interface *ifp)
+{
+  return ifp->flags & IFF_RUNNING;
+}
+
+/* Is the interface operative, eg. either UP & RUNNING
+   or UP & !ZEBRA_INTERFACE_LINK_DETECTION */
+int
+if_is_operative (struct interface *ifp)
+{
+  return ((ifp->flags & IFF_UP) &&
+         (ifp->flags & IFF_RUNNING || !CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)));
+}
+
 /* Is this loopback interface ? */
 int
 if_is_loopback (struct interface *ifp)
index 55337fc4f53b2f005217c4444b1796bbe5b505ba..554126fdedaca5f5fe8eb84dd2fb8457fa601ac7 100644 (file)
--- a/lib/if.h
+++ b/lib/if.h
@@ -85,6 +85,7 @@ struct interface
   u_char status;
 #define ZEBRA_INTERFACE_ACTIVE     (1 << 0)
 #define ZEBRA_INTERFACE_SUB        (1 << 1)
+#define ZEBRA_INTERFACE_LINKDETECTION (1 << 2)
   
   /* Interface flags. */
   unsigned long flags;
@@ -188,6 +189,8 @@ struct interface *if_lookup_address (struct in_addr);
 struct interface *if_get_by_name (char *);
 void if_delete (struct interface *);
 int if_is_up (struct interface *);
+int if_is_running (struct interface *);
+int if_is_operative (struct interface *);
 int if_is_loopback (struct interface *);
 int if_is_broadcast (struct interface *);
 int if_is_pointopoint (struct interface *);
index 5e37154696229dfe9aadf323e8a4ec774e34b855..c1b286f400184dcc4e616c0da0f402f5ff1e60b6 100644 (file)
@@ -564,6 +564,7 @@ zebra_interface_add_read (struct stream *s)
   ifp->ifindex = stream_getl (s);
 
   /* Read interface's value. */
+  ifp->status = stream_getc (s);
   ifp->flags = stream_getl (s);
   ifp->metric = stream_getl (s);
   ifp->mtu = stream_getl (s);
@@ -600,6 +601,7 @@ zebra_interface_state_read (struct stream *s)
   ifp->ifindex = stream_getl (s);
 
   /* Read interface's value. */
+  ifp->status = stream_getc (s);
   ifp->flags = stream_getl (s);
   ifp->metric = stream_getl (s);
   ifp->mtu = stream_getl (s);
index 9194c5662b49ee0844507b371903dd5ed2f51861..b60aa071db2684d3d1729618f0d6d02f47e87d80 100644 (file)
@@ -154,7 +154,7 @@ ospf_ase_forward_address_check (struct in_addr fwd_addr)
 
   for (ifn = listhead (ospf_top->oiflist); ifn; nextnode (ifn))
     if ((oi = getdata (ifn)) != NULL)
-      if (if_is_up (oi->ifp))
+      if (if_is_operative (oi->ifp))
        if (oi->type != OSPF_IFTYPE_VIRTUALLINK)
          if (IPV4_ADDR_SAME (&oi->address->u.prefix4, &fwd_addr))
            return 0;
index 6d7af0580f3225d7310f149fc79c62247989e3bd..a4495e97185fe994b1cfe14cfafa9efac81260b8 100644 (file)
@@ -640,7 +640,7 @@ router_lsa_link_set (struct stream *s, struct ospf_area *area)
       struct interface *ifp = oi->ifp;
 
       /* Check interface is up, OSPF is enable. */
-      if (if_is_up (ifp))
+      if (if_is_operative (ifp))
        {
          if (oi->state != ISM_Down)
            {
@@ -1391,7 +1391,7 @@ ospf_external_lsa_nexthop_get (struct in_addr nexthop)
     {
       struct ospf_interface *oi = getdata (n1);
 
-      if (if_is_up (oi->ifp))
+      if (if_is_operative (oi->ifp))
        if (oi->address->family == AF_INET)
          if (prefix_match (oi->address, &nh))
            return nexthop;
@@ -1412,7 +1412,7 @@ ospf_get_ip_from_ifp (struct ospf_interface *oi)
 
   fwd.s_addr = 0;
 
-  if (if_is_up (oi->ifp))
+  if (if_is_operative (oi->ifp))
     return oi->address->u.prefix4;
   
   return fwd;
@@ -1432,7 +1432,7 @@ ospf_get_nssa_ip (void)
     {
       struct ospf_interface *oi = getdata (n1);
 
-      if (if_is_up (oi->ifp))
+      if (if_is_operative (oi->ifp))
        if (oi->area->external_routing == OSPF_AREA_NSSA)
          if (oi->address && oi->address->family == AF_INET)
            return (oi->address->u.prefix4 );
index 73215fa5bf40c07035d0f038cace7ce010f55554..accf7a8c7e1b3a12bd4348259052e50795f21015 100644 (file)
@@ -2526,12 +2526,11 @@ show_ip_ospf_interface_sub (struct vty *vty, struct interface *ifp)
   oi_count = ospf_oi_count (ifp);
   
   /* Is interface up? */
-  if (if_is_up (ifp))
-    vty_out (vty, "%s is up, line protocol is up%s", ifp->name, VTY_NEWLINE);
-  else
-    {
-      vty_out (vty, "%s is down, line protocol is down%s", ifp->name,
-              VTY_NEWLINE);
+  if (if_is_operative (ifp)) {
+       vty_out (vty, "%s is up%s", ifp->name, VTY_NEWLINE);
+  } else
+       {
+               vty_out (vty, "%s is down%s", ifp->name, VTY_NEWLINE);
 
       
       if (oi_count == 0)
index 1ad31f29007206ccb7b1d90daf04be37ab3a40d6..72ffe76f4255808daf013d3f4db1b5953d9d8d86 100644 (file)
@@ -154,6 +154,7 @@ zebra_interface_if_set_value (struct stream *s, struct interface *ifp)
   ifp->ifindex = stream_getl (s);
 
   /* Read interface's value. */
+  ifp->status = stream_getc (s);
   ifp->flags = stream_getl (s);
   ifp->metric = stream_getl (s);
   ifp->mtu = stream_getl (s);
@@ -175,7 +176,7 @@ ospf_interface_state_up (int command, struct zclient *zclient,
     return 0;
 
   /* Interface is already up. */
-  if (if_is_up (ifp))
+  if (if_is_operative (ifp))
     {
       /* Temporarily keep ifp values. */
       memcpy (&if_tmp, ifp, sizeof (struct interface));
index e7de8eabf9694a9d9d196ca6474f5cb6d59d9958..e8bd360beab8a05892337e3f4c2161878b4f1957 100644 (file)
@@ -761,7 +761,7 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area)
 
                ospf_area_add_if (oi->area, oi);
 
-               if (if_is_up (ifp)) 
+               if (if_is_operative (ifp)) 
                  ospf_if_up (oi);
 
                break;
index 06d4416b5f1d8c858a67d5a27d6efaafe5a7b817..bdfca575a973097269eda47bb29558cc75171c2c 100644 (file)
@@ -248,7 +248,7 @@ rip_request_interface (struct interface *ifp)
     return;
 
   /* If interface is down, don't send RIP packet. */
-  if (! if_is_up (ifp))
+  if (! if_is_operative (ifp))
     return;
 
   /* Fetch RIP interface information. */
@@ -311,7 +311,7 @@ rip_multicast_join (struct interface *ifp, int sock)
 {
   listnode cnode;
 
-  if (if_is_up (ifp) && if_is_multicast (ifp))
+  if (if_is_operative (ifp) && if_is_multicast (ifp))
     {
       if (IS_RIP_DEBUG_EVENT)
        zlog_info ("multicast join at %s", ifp->name);
@@ -705,7 +705,7 @@ rip_if_down(struct interface *ifp)
              {
                /* All redistributed routes but static and system */
                if ((rinfo->ifindex == ifp->ifindex) &&
-                   (rinfo->type != ZEBRA_ROUTE_STATIC) &&
+                   /* (rinfo->type != ZEBRA_ROUTE_STATIC) && */
                    (rinfo->type != ZEBRA_ROUTE_SYSTEM))
                  rip_redistribute_delete (rinfo->type,rinfo->sub_type,
                                           (struct prefix_ipv4 *)&rp->p,
@@ -1008,7 +1008,7 @@ rip_enable_apply (struct interface *ifp)
   if (if_is_loopback (ifp))
     return;
 
-  if (! if_is_up (ifp))
+  if (! if_is_operative (ifp))
     return;
 
   ri = ifp->info;
index 3c55479d7ea5eff8cf6043ef7c3e640c6ad3ab63..c63bf1048953dae2fe18ec29d86bbffdc4c20b2e 100644 (file)
@@ -2231,7 +2231,7 @@ rip_update_process (int route_type)
       if (if_is_loopback (ifp))
        continue;
 
-      if (! if_is_up (ifp))
+      if (! if_is_operative (ifp))
        continue;
 
       /* Fetch RIP interface information. */
index 9846805b947761a0a2df995a59cc67f68629dddb..ac064992bd5fbf71375d0c694360923f27614933 100644 (file)
@@ -147,7 +147,7 @@ if_addr_wakeup (struct interface *ifp)
 
              zebra_interface_address_add_update (ifp, ifc);
 
-             if (if_is_up(ifp))
+             if (if_is_operative(ifp))
                connected_up_ipv4 (ifp, ifc);
            }
 #ifdef HAVE_IPV6
@@ -170,7 +170,7 @@ if_addr_wakeup (struct interface *ifp)
 
              zebra_interface_address_add_update (ifp, ifc);
 
-             if (if_is_up(ifp))
+             if (if_is_operative(ifp))
                connected_up_ipv6 (ifp, ifc);
            }
 #endif /* HAVE_IPV6 */
@@ -334,16 +334,16 @@ if_down (struct interface *ifp)
 void
 if_refresh (struct interface *ifp)
 {
-  if (if_is_up (ifp))
+  if (if_is_operative (ifp))
     {
       if_get_flags (ifp);
-      if (! if_is_up (ifp))
+      if (! if_is_operative (ifp))
        if_down (ifp);
     }
   else
     {
       if_get_flags (ifp);
-      if (if_is_up (ifp))
+      if (if_is_operative (ifp))
        if_up (ifp);
     }
 }
@@ -479,8 +479,22 @@ if_dump_vty (struct vty *vty, struct interface *ifp)
   struct connected *connected;
   listnode node;
 
-  vty_out (vty, "Interface %s%s", ifp->name,
-          VTY_NEWLINE);
+  vty_out (vty, "Interface %s is ", ifp->name);
+  if (if_is_up(ifp)) {
+    vty_out (vty, "up, line protocol ");
+    
+    if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION)) {
+      if (if_is_running(ifp))
+       vty_out (vty, "is up%s", VTY_NEWLINE);
+      else
+       vty_out (vty, "is down%s", VTY_NEWLINE);
+    } else {
+      vty_out (vty, "detection is disabled%s", VTY_NEWLINE);
+    }
+  } else {
+    vty_out (vty, "down%s", VTY_NEWLINE);
+  }
+
   if (ifp->desc)
     vty_out (vty, "  Description: %s%s", ifp->desc,
             VTY_NEWLINE);
@@ -790,6 +804,51 @@ DEFUN (no_multicast,
   return CMD_SUCCESS;
 }
 
+DEFUN (linkdetect,
+       linkdetect_cmd,
+       "link-detect",
+       "Enable link detection on interface\n")
+{
+  int ret;
+  struct interface *ifp;
+  int if_was_operative;
+  
+  ifp = (struct interface *) vty->index;
+  if_was_operative = if_is_operative(ifp);
+  SET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
+
+  /* When linkdetection is enabled, if might come down */
+  if (!if_is_operative(ifp) && if_was_operative) if_down(ifp);
+
+  /* FIXME: Will defer status change forwarding if interface
+     does not come down! */
+
+  return CMD_SUCCESS;
+}
+
+
+DEFUN (no_linkdetect,
+       no_linkdetect_cmd,
+       "no link-detect",
+       NO_STR
+       "Disable link detection on interface\n")
+{
+  int ret;
+  struct interface *ifp;
+  int if_was_operative;
+
+  ifp = (struct interface *) vty->index;
+  if_was_operative = if_is_operative(ifp);
+  UNSET_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION);
+  
+  /* Interface may come up after disabling link detection */
+  if (if_is_operative(ifp) && !if_was_operative) if_up(ifp);
+
+  /* FIXME: see linkdetect_cmd */
+
+  return CMD_SUCCESS;
+}
+
 DEFUN (shutdown_if,
        shutdown_if_cmd,
        "shutdown",
@@ -859,7 +918,7 @@ DEFUN (bandwidth_if,
   ifp->bandwidth = bandwidth;
 
   /* force protocols to recalculate routes due to cost change */
-  if (if_is_up (ifp))
+  if (if_is_operative (ifp))
     zebra_interface_up_update (ifp);
   
   return CMD_SUCCESS;
@@ -878,7 +937,7 @@ DEFUN (no_bandwidth_if,
   ifp->bandwidth = 0;
   
   /* force protocols to recalculate routes due to cost change */
-  if (if_is_up (ifp))
+  if (if_is_operative (ifp))
     zebra_interface_up_update (ifp);
 
   return CMD_SUCCESS;
@@ -971,7 +1030,7 @@ ip_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
       zebra_interface_address_add_update (ifp, ifc);
 
       /* If interface is up register connected route. */
-      if (if_is_up(ifp))
+      if (if_is_operative(ifp))
        connected_up_ipv4 (ifp, ifc);
     }
 
@@ -1179,7 +1238,7 @@ ipv6_address_install (struct vty *vty, struct interface *ifp, char *addr_str,
       zebra_interface_address_add_update (ifp, ifc);
 
       /* If interface is up register connected route. */
-      if (if_is_up(ifp))
+      if (if_is_operative(ifp))
        connected_up_ipv6 (ifp, ifc);
     }
 
@@ -1315,6 +1374,9 @@ if_config_write (struct vty *vty)
       if (ifp->bandwidth != 0)
        vty_out(vty, " bandwidth %u%s", ifp->bandwidth, VTY_NEWLINE); 
 
+      if (CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_LINKDETECTION))
+       vty_out(vty, " link-detect%s", VTY_NEWLINE);
+
       for (addrnode = listhead (ifp->connected); addrnode; nextnode (addrnode))
          {
            ifc = getdata (addrnode);
@@ -1377,6 +1439,8 @@ zebra_if_init ()
   install_element (INTERFACE_NODE, &no_interface_desc_cmd);
   install_element (INTERFACE_NODE, &multicast_cmd);
   install_element (INTERFACE_NODE, &no_multicast_cmd);
+  install_element (INTERFACE_NODE, &linkdetect_cmd);
+  install_element (INTERFACE_NODE, &no_linkdetect_cmd);
   install_element (INTERFACE_NODE, &shutdown_if_cmd);
   install_element (INTERFACE_NODE, &no_shutdown_if_cmd);
   install_element (INTERFACE_NODE, &bandwidth_if_cmd);
index baca1751bc58a8975714afcc8a52a3a548128cd0..fa4dc54f2ed5df802ce3c16157ebb8dae3c72e84 100644 (file)
@@ -787,16 +787,16 @@ netlink_link_change (struct sockaddr_nl *snl, struct nlmsghdr *h)
          ifp->mtu = *(int *)RTA_DATA (tb[IFLA_MTU]);
          ifp->metric = 1;
 
-         if (if_is_up (ifp))
+         if (if_is_operative (ifp))
            {
              ifp->flags = ifi->ifi_flags & 0x0000fffff;
-             if (! if_is_up (ifp))
+             if (! if_is_operative (ifp))
                if_down (ifp);
            }
          else
            {
              ifp->flags = ifi->ifi_flags & 0x0000fffff;
-             if (if_is_up (ifp))
+             if (if_is_operative (ifp))
                if_up (ifp);
            }
        }
index 47114ab33994ffb2f89fcca493be8964bd535959..d447d06500dedaf9deeed56276b2796dc8e635b1 100644 (file)
@@ -96,6 +96,7 @@ zsend_interface_add (struct zserv *client, struct interface *ifp)
   /* Interface information. */
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
+  stream_putc (s, ifp->status);
   stream_putl (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
@@ -134,6 +135,7 @@ zsend_interface_delete (struct zserv *client, struct interface *ifp)
   stream_putc (s, ZEBRA_INTERFACE_DELETE);
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
+  stream_putc (s, ifp->status);
   stream_putl (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
@@ -256,6 +258,7 @@ zsend_interface_up (struct zserv *client, struct interface *ifp)
   /* Interface information. */
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
+  stream_putc (s, ifp->status);
   stream_putl (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);
@@ -288,6 +291,7 @@ zsend_interface_down (struct zserv *client, struct interface *ifp)
   /* Interface information. */
   stream_put (s, ifp->name, INTERFACE_NAMSIZ);
   stream_putl (s, ifp->ifindex);
+  stream_putc (s, ifp->status);
   stream_putl (s, ifp->flags);
   stream_putl (s, ifp->metric);
   stream_putl (s, ifp->mtu);