Diff for /embedaddon/quagga/isisd/isis_adjacency.c between versions 1.1 and 1.1.1.3

version 1.1, 2012/02/21 17:26:11 version 1.1.1.3, 2013/07/21 23:54:38
Line 36 Line 36
 #include "isisd/include-netbsd/iso.h"  #include "isisd/include-netbsd/iso.h"
 #include "isisd/isis_constants.h"  #include "isisd/isis_constants.h"
 #include "isisd/isis_common.h"  #include "isisd/isis_common.h"
   #include "isisd/isis_flags.h"
 #include "isisd/isisd.h"  #include "isisd/isisd.h"
 #include "isisd/isis_circuit.h"  #include "isisd/isis_circuit.h"
 #include "isisd/isis_adjacency.h"  #include "isisd/isis_adjacency.h"
Line 43 Line 44
 #include "isisd/isis_dr.h"  #include "isisd/isis_dr.h"
 #include "isisd/isis_dynhn.h"  #include "isisd/isis_dynhn.h"
 #include "isisd/isis_pdu.h"  #include "isisd/isis_pdu.h"
   #include "isisd/isis_tlv.h"
   #include "isisd/isis_lsp.h"
   #include "isisd/isis_spf.h"
   #include "isisd/isis_events.h"
   
 extern struct isis *isis;  extern struct isis *isis;
   
Line 73  isis_new_adj (u_char * id, u_char * snpa, int level, Line 78  isis_new_adj (u_char * id, u_char * snpa, int level,
     }      }
   
   if (snpa) {    if (snpa) {
  memcpy (adj->snpa, snpa, 6);    memcpy (adj->snpa, snpa, ETH_ALEN);
   } else {    } else {
      memset (adj->snpa, ' ', 6);    memset (adj->snpa, ' ', ETH_ALEN);
   }    }
   
   adj->circuit = circuit;    adj->circuit = circuit;
Line 125  isis_adj_lookup_snpa (u_char * ssnpa, struct list *adj Line 130  isis_adj_lookup_snpa (u_char * ssnpa, struct list *adj
 }  }
   
 void  void
isis_delete_adj (struct isis_adjacency *adj, struct list *adjdb)isis_delete_adj (void *arg)
 {  {
     struct isis_adjacency *adj = arg;
   
   if (!adj)    if (!adj)
     return;      return;
   /* When we recieve a NULL list, we will know its p2p. */  
   if (adjdb)  
     listnode_delete (adjdb, adj);  
   
  THREAD_OFF (adj->t_expire);  THREAD_TIMER_OFF (adj->t_expire);
   
     /* remove from SPF trees */
     spftree_area_adj_del (adj->circuit->area, adj);
   
     if (adj->area_addrs)
       list_delete (adj->area_addrs);
   if (adj->ipv4_addrs)    if (adj->ipv4_addrs)
     list_delete (adj->ipv4_addrs);      list_delete (adj->ipv4_addrs);
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   if (adj->ipv6_addrs)    if (adj->ipv6_addrs)
     list_delete (adj->ipv6_addrs);      list_delete (adj->ipv6_addrs);
 #endif  #endif
  
   XFREE (MTYPE_ISIS_ADJACENCY, adj);    XFREE (MTYPE_ISIS_ADJACENCY, adj);
   return;    return;
 }  }
   
   static const char *
   adj_state2string (int state)
   {
   
     switch (state)
       {
       case ISIS_ADJ_INITIALIZING:
         return "Initializing";
       case ISIS_ADJ_UP:
         return "Up";
       case ISIS_ADJ_DOWN:
         return "Down";
       default:
         return "Unknown";
       }
   
     return NULL;                  /* not reached */
   }
   
 void  void
isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state state,isis_adj_state_change (struct isis_adjacency *adj, enum isis_adj_state new_state,
                        const char *reason)                         const char *reason)
 {  {
   int old_state;    int old_state;
  int level = adj->level;  int level;
   struct isis_circuit *circuit;    struct isis_circuit *circuit;
   
   old_state = adj->adj_state;    old_state = adj->adj_state;
  adj->adj_state = state;  adj->adj_state = new_state;
   
   circuit = adj->circuit;    circuit = adj->circuit;
   
Line 163  isis_adj_state_change (struct isis_adjacency *adj, enu Line 191  isis_adj_state_change (struct isis_adjacency *adj, enu
     {      {
       zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",        zlog_debug ("ISIS-Adj (%s): Adjacency state change %d->%d: %s",
                  circuit->area->area_tag,                   circuit->area->area_tag,
                 old_state, state, reason ? reason : "unspecified");                 old_state, new_state, reason ? reason : "unspecified");
     }      }
   
     if (circuit->area->log_adj_changes)
       {
         const char *adj_name;
         struct isis_dynhn *dyn;
   
         dyn = dynhn_find_by_id (adj->sysid);
         if (dyn)
           adj_name = (const char *)dyn->name.name;
         else
           adj_name = adj->sysid ? sysid_print (adj->sysid) : "unknown";
   
         zlog_info ("%%ADJCHANGE: Adjacency to %s (%s) changed from %s to %s, %s",
                    adj_name,
                    adj->circuit->interface->name,
                    adj_state2string (old_state),
                    adj_state2string (new_state),
                    reason ? reason : "unspecified");
       }
   
   if (circuit->circ_type == CIRCUIT_T_BROADCAST)    if (circuit->circ_type == CIRCUIT_T_BROADCAST)
     {      {
      if (state == ISIS_ADJ_UP)      for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++)
        circuit->upadjcount[level - 1]++;      {
      if (state == ISIS_ADJ_DOWN)        if ((adj->level & level) == 0)
        {          continue;
          isis_delete_adj (adj, adj->circuit->u.bc.adjdb[level - 1]);        if (new_state == ISIS_ADJ_UP)
          circuit->upadjcount[level - 1]--;        {
        }          circuit->upadjcount[level - 1]++;
           isis_event_adjacency_state_change (adj, new_state);
           /* update counter & timers for debugging purposes */
           adj->last_flap = time (NULL);
           adj->flaps++;
         }
         else if (new_state == ISIS_ADJ_DOWN)
         {
           listnode_delete (circuit->u.bc.adjdb[level - 1], adj);
           circuit->upadjcount[level - 1]--;
           if (circuit->upadjcount[level - 1] == 0)
             {
               /* Clean lsp_queue when no adj is up. */
               if (circuit->lsp_queue)
                 list_delete_all_node (circuit->lsp_queue);
             }
           isis_event_adjacency_state_change (adj, new_state);
           isis_delete_adj (adj);
         }
   
      list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);        if (circuit->u.bc.lan_neighs[level - 1])
      isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],          {
                                 circuit->u.bc.lan_neighs[level - 1]);            list_delete_all_node (circuit->u.bc.lan_neighs[level - 1]);
             isis_adj_build_neigh_list (circuit->u.bc.adjdb[level - 1],
                                        circuit->u.bc.lan_neighs[level - 1]);
           }
 
         /* On adjacency state change send new pseudo LSP if we are the DR */
         if (circuit->u.bc.is_dr[level - 1])
           lsp_regenerate_schedule_pseudo (circuit, level);
       }
     }      }
  else if (state == ISIS_ADJ_UP)  else if (circuit->circ_type == CIRCUIT_T_P2P)
    {                           /* p2p interface */    {
      if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)      for (level = IS_LEVEL_1; level <= IS_LEVEL_2; level++)
        send_hello (circuit, 1);      {
         if ((adj->level & level) == 0)
           continue;
         if (new_state == ISIS_ADJ_UP)
         {
           circuit->upadjcount[level - 1]++;
           isis_event_adjacency_state_change (adj, new_state);
   
      /* update counter & timers for debugging purposes */          if (adj->sys_type == ISIS_SYSTYPE_UNKNOWN)
      adj->last_flap = time (NULL);            send_hello (circuit, level);
      adj->flaps++; 
   
      /* 7.3.17 - going up on P2P -> send CSNP */          /* update counter & timers for debugging purposes */
      /* FIXME: yup, I know its wrong... but i will do it! (for now) */          adj->last_flap = time (NULL);
      send_csnp (circuit, 1);          adj->flaps++;
      send_csnp (circuit, 2);
           /* 7.3.17 - going up on P2P -> send CSNP */
           /* FIXME: yup, I know its wrong... but i will do it! (for now) */
           send_csnp (circuit, level);
         }
         else if (new_state == ISIS_ADJ_DOWN)
         {
           if (adj->circuit->u.p2p.neighbor == adj)
             adj->circuit->u.p2p.neighbor = NULL;
           circuit->upadjcount[level - 1]--;
           if (circuit->upadjcount[level - 1] == 0)
             {
               /* Clean lsp_queue when no adj is up. */
               if (circuit->lsp_queue)
                 list_delete_all_node (circuit->lsp_queue);
             }
           isis_event_adjacency_state_change (adj, new_state);
           isis_delete_adj (adj);
         }
       }
     }      }
  else if (state == ISIS_ADJ_DOWN)
    {                           /* p2p interface */ 
      adj->circuit->u.p2p.neighbor = NULL; 
      isis_delete_adj (adj, NULL); 
    } 
   return;    return;
 }  }
   
Line 225  isis_adj_print (struct isis_adjacency *adj) Line 318  isis_adj_print (struct isis_adjacency *adj)
               snpa_print (adj->snpa), adj->level, adj->hold_time);                snpa_print (adj->snpa), adj->level, adj->hold_time);
   if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)    if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
     {      {
      zlog_debug ("IPv4 Addresses:");      zlog_debug ("IPv4 Address(es):");
   
       for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))        for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ipv4_addr))
         zlog_debug ("%s", inet_ntoa (*ipv4_addr));          zlog_debug ("%s", inet_ntoa (*ipv4_addr));
Line 234  isis_adj_print (struct isis_adjacency *adj) Line 327  isis_adj_print (struct isis_adjacency *adj)
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)    if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
     {      {
      zlog_debug ("IPv6 Addresses:");      zlog_debug ("IPv6 Address(es):");
       for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))        for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
         {          {
           inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);            inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
Line 251  int Line 344  int
 isis_adj_expire (struct thread *thread)  isis_adj_expire (struct thread *thread)
 {  {
   struct isis_adjacency *adj;    struct isis_adjacency *adj;
   int level;  
   
   /*    /*
    * Get the adjacency     * Get the adjacency
    */     */
   adj = THREAD_ARG (thread);    adj = THREAD_ARG (thread);
   assert (adj);    assert (adj);
   level = adj->level;  
   adj->t_expire = NULL;    adj->t_expire = NULL;
   
   /* trigger the adj expire event */    /* trigger the adj expire event */
Line 267  isis_adj_expire (struct thread *thread) Line 358  isis_adj_expire (struct thread *thread)
   return 0;    return 0;
 }  }
   
 static const char *  
 adj_state2string (int state)  
 {  
   
   switch (state)  
     {  
     case ISIS_ADJ_INITIALIZING:  
       return "Initializing";  
     case ISIS_ADJ_UP:  
       return "Up";  
     case ISIS_ADJ_DOWN:  
       return "Down";  
     default:  
       return "Unknown";  
     }  
   
   return NULL;                  /* not reached */  
 }  
   
 /*  /*
 * show clns/isis neighbor (detail) * show isis neighbor [detail]
  */   */
static voidvoid
isis_adj_print_vty2 (struct isis_adjacency *adj, struct vty *vty, char detail)isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty, char detail)
 {  {
   
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
   struct in6_addr *ipv6_addr;    struct in6_addr *ipv6_addr;
   u_char ip6[INET6_ADDRSTRLEN];    u_char ip6[INET6_ADDRSTRLEN];
Line 335  isis_adj_print_vty2 (struct isis_adjacency *adj, struc Line 406  isis_adj_print_vty2 (struct isis_adjacency *adj, struc
   if (detail == ISIS_UI_LEVEL_DETAIL)    if (detail == ISIS_UI_LEVEL_DETAIL)
     {      {
       level = adj->level;        level = adj->level;
         vty_out (vty, "%s", VTY_NEWLINE);
       if (adj->circuit)        if (adj->circuit)
        vty_out (vty, "%s    Interface: %s", VTY_NEWLINE, adj->circuit->interface->name);       /* interface name */        vty_out (vty, "    Interface: %s", adj->circuit->interface->name);
       else        else
        vty_out (vty, "NULL circuit!%s", VTY_NEWLINE);        vty_out (vty, "    Interface: NULL circuit");
       vty_out (vty, ", Level: %u", adj->level); /* level */        vty_out (vty, ", Level: %u", adj->level); /* level */
       vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));        vty_out (vty, ", State: %s", adj_state2string (adj->adj_state));
       now = time (NULL);        now = time (NULL);
Line 347  isis_adj_print_vty2 (struct isis_adjacency *adj, struc Line 419  isis_adj_print_vty2 (struct isis_adjacency *adj, struc
                  time2string (adj->last_upd + adj->hold_time - now));                   time2string (adj->last_upd + adj->hold_time - now));
       else        else
         vty_out (vty, ", Expires in %s", time2string (adj->hold_time));          vty_out (vty, ", Expires in %s", time2string (adj->hold_time));
      vty_out (vty, "%s    Adjacency flaps: %u", VTY_NEWLINE, adj->flaps);      vty_out (vty, "%s", VTY_NEWLINE);
       vty_out (vty, "    Adjacency flaps: %u", adj->flaps);
       vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));        vty_out (vty, ", Last: %s ago", time2string (now - adj->last_flap));
      vty_out (vty, "%s    Circuit type: %s",      vty_out (vty, "%s", VTY_NEWLINE);
               VTY_NEWLINE, circuit_t2string (adj->circuit_t));      vty_out (vty, "    Circuit type: %s", circuit_t2string (adj->circuit_t));
       vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));        vty_out (vty, ", Speaks: %s", nlpid2string (&adj->nlpids));
      vty_out (vty, "%s    SNPA: %s", VTY_NEWLINE, snpa_print (adj->snpa));      vty_out (vty, "%s", VTY_NEWLINE);
      dyn = dynhn_find_by_id (adj->lanid);      vty_out (vty, "    SNPA: %s", snpa_print (adj->snpa));
      if (dyn)      if (adj->circuit && (adj->circuit->circ_type == CIRCUIT_T_BROADCAST))
        vty_out (vty, ", LAN id: %s.%02x",      {
                 dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);        dyn = dynhn_find_by_id (adj->lanid);
      else        if (dyn)
        vty_out (vty, ", LAN id: %s.%02x",          vty_out (vty, ", LAN id: %s.%02x",
                 sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);              dyn->name.name, adj->lanid[ISIS_SYS_ID_LEN]);
         else
           vty_out (vty, ", LAN id: %s.%02x",
               sysid_print (adj->lanid), adj->lanid[ISIS_SYS_ID_LEN]);
   
      vty_out (vty, "%s    Priority: %u",        vty_out (vty, "%s", VTY_NEWLINE);
               VTY_NEWLINE, adj->prio[adj->level - 1]);        vty_out (vty, "    LAN Priority: %u", adj->prio[adj->level - 1]);
   
      vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago%s",        vty_out (vty, ", %s, DIS flaps: %u, Last: %s ago",
               isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].            isis_disflag2string (adj->dis_record[ISIS_LEVELS + level - 1].
                                    dis), adj->dischanges[level - 1],              dis), adj->dischanges[level - 1],
               time2string (now -            time2string (now -
                            (adj->dis_record[ISIS_LEVELS + level - 1].              (adj->dis_record[ISIS_LEVELS + level - 1].
                             last_dis_change)), VTY_NEWLINE);               last_dis_change)));
       }
       vty_out (vty, "%s", VTY_NEWLINE);
   
         if (adj->area_addrs && listcount (adj->area_addrs) > 0)
           {
             struct area_addr *area_addr;
             vty_out (vty, "    Area Address(es):%s", VTY_NEWLINE);
             for (ALL_LIST_ELEMENTS_RO (adj->area_addrs, node, area_addr))
               vty_out (vty, "      %s%s", isonet_print (area_addr->area_addr,
                        area_addr->addr_len), VTY_NEWLINE);
           }
       if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)        if (adj->ipv4_addrs && listcount (adj->ipv4_addrs) > 0)
         {          {
          vty_out (vty, "    IPv4 Addresses:%s", VTY_NEWLINE);          vty_out (vty, "    IPv4 Address(es):%s", VTY_NEWLINE);
           for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))            for (ALL_LIST_ELEMENTS_RO (adj->ipv4_addrs, node, ip_addr))
             vty_out (vty, "      %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);              vty_out (vty, "      %s%s", inet_ntoa (*ip_addr), VTY_NEWLINE);
         }          }
 #ifdef HAVE_IPV6  #ifdef HAVE_IPV6
       if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)        if (adj->ipv6_addrs && listcount (adj->ipv6_addrs) > 0)
         {          {
          vty_out (vty, "    IPv6 Addresses:%s", VTY_NEWLINE);          vty_out (vty, "    IPv6 Address(es):%s", VTY_NEWLINE);
           for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))            for (ALL_LIST_ELEMENTS_RO (adj->ipv6_addrs, node, ipv6_addr))
             {              {
               inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);                inet_ntop (AF_INET6, ipv6_addr, (char *)ip6, INET6_ADDRSTRLEN);
Line 391  isis_adj_print_vty2 (struct isis_adjacency *adj, struc Line 477  isis_adj_print_vty2 (struct isis_adjacency *adj, struc
       vty_out (vty, "%s", VTY_NEWLINE);        vty_out (vty, "%s", VTY_NEWLINE);
     }      }
   return;    return;
 }  
   
 void  
 isis_adj_print_vty (struct isis_adjacency *adj, struct vty *vty)  
 {  
   isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);  
 }  
   
 void  
 isis_adj_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)  
 {  
   isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);  
 }  
   
 void  
 isis_adj_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)  
 {  
   isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);  
 }  
   
 void  
 isis_adj_p2p_print_vty (struct isis_adjacency *adj, struct vty *vty)  
 {  
   isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_BRIEF);  
 }  
   
 void  
 isis_adj_p2p_print_vty_detail (struct isis_adjacency *adj, struct vty *vty)  
 {  
   isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_DETAIL);  
 }  
   
 void  
 isis_adj_p2p_print_vty_extensive (struct isis_adjacency *adj, struct vty *vty)  
 {  
   isis_adj_print_vty2 (adj, vty, ISIS_UI_LEVEL_EXTENSIVE);  
 }  
   
 void  
 isis_adjdb_iterate (struct list *adjdb, void (*func) (struct isis_adjacency *,  
                                                       void *), void *arg)  
 {  
   struct listnode *node, *nnode;  
   struct isis_adjacency *adj;  
   
   for (ALL_LIST_ELEMENTS (adjdb, node, nnode, adj))  
     (*func) (adj, arg);  
 }  }
   
 void  void

Removed from v.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>