diff options
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/ospf_abr.c | 7 | ||||
| -rw-r--r-- | ospfd/ospf_api.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_apiserver.c | 4 | ||||
| -rw-r--r-- | ospfd/ospf_apiserver.h | 2 | ||||
| -rw-r--r-- | ospfd/ospf_asbr.c | 3 | ||||
| -rw-r--r-- | ospfd/ospf_ase.c | 8 | ||||
| -rw-r--r-- | ospfd/ospf_flood.c | 34 | ||||
| -rw-r--r-- | ospfd/ospf_flood.h | 1 | ||||
| -rw-r--r-- | ospfd/ospf_interface.c | 20 | ||||
| -rw-r--r-- | ospfd/ospf_interface.h | 6 | ||||
| -rw-r--r-- | ospfd/ospf_ism.c | 9 | ||||
| -rw-r--r-- | ospfd/ospf_lsa.c | 356 | ||||
| -rw-r--r-- | ospfd/ospf_lsa.h | 24 | ||||
| -rw-r--r-- | ospfd/ospf_lsdb.c | 15 | ||||
| -rw-r--r-- | ospfd/ospf_nsm.c | 33 | ||||
| -rw-r--r-- | ospfd/ospf_nsm.h | 2 | ||||
| -rw-r--r-- | ospfd/ospf_opaque.c | 17 | ||||
| -rw-r--r-- | ospfd/ospf_opaque.h | 4 | ||||
| -rw-r--r-- | ospfd/ospf_packet.c | 136 | ||||
| -rw-r--r-- | ospfd/ospf_packet.h | 1 | ||||
| -rw-r--r-- | ospfd/ospf_te.c | 6 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 14 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 15 | ||||
| -rw-r--r-- | ospfd/ospfd.h | 9 | 
24 files changed, 371 insertions, 357 deletions
| diff --git a/ospfd/ospf_abr.c b/ospfd/ospf_abr.c index d06a34ad..b7cc20dd 100644 --- a/ospfd/ospf_abr.c +++ b/ospfd/ospf_abr.c @@ -565,8 +565,7 @@ ospf_check_abr_status (struct ospf *ospf)        if (IS_DEBUG_OSPF_EVENT)  	zlog_debug ("ospf_check_abr_status(): new router flags: %x",new_flags);        ospf->flags = new_flags; -      OSPF_TIMER_ON (ospf->t_router_lsa_update, -		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY); +      ospf_router_lsa_update (ospf);      }  } @@ -751,7 +750,7 @@ ospf_abr_announce_network_to_area (struct prefix_ipv4 *p, u_int32_t cost,              zlog_debug ("ospf_abr_announce_network_to_area(): "                         "refreshing summary");            set_metric (old, cost); -          lsa = ospf_summary_lsa_refresh (area->ospf, old); +          lsa = ospf_lsa_refresh (area->ospf, old);            if (!lsa)              { @@ -1139,7 +1138,7 @@ ospf_abr_announce_rtr_to_area (struct prefix_ipv4 *p, u_int32_t cost,        if (old)   	{   	  set_metric (old, cost); -	  lsa = ospf_summary_asbr_lsa_refresh (area->ospf, old); +	  lsa = ospf_lsa_refresh (area->ospf, old);  	}        else  	lsa = ospf_summary_asbr_lsa_originate (p, cost, area); diff --git a/ospfd/ospf_api.c b/ospfd/ospf_api.c index 77383191..fc3b51dd 100644 --- a/ospfd/ospf_api.c +++ b/ospfd/ospf_api.c @@ -219,7 +219,7 @@ msg_print (struct msg *msg)  #else /* ORIGINAL_CODING */    /* API message common header part. */    zlog_debug -    ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%lu)", +    ("API-msg [%s]: type(%d),len(%d),seq(%lu),data(%p),size(%zd)",       ospf_api_typename (msg->hdr.msgtype), msg->hdr.msgtype,        ntohs (msg->hdr.msglen), (unsigned long) ntohl (msg->hdr.msgseq),       STREAM_DATA (msg->s), STREAM_SIZE (msg->s)); diff --git a/ospfd/ospf_apiserver.c b/ospfd/ospf_apiserver.c index 15fd2e5f..2a9003b7 100644 --- a/ospfd/ospf_apiserver.c +++ b/ospfd/ospf_apiserver.c @@ -1831,7 +1831,7 @@ ospf_apiserver_lsa11_originator (void *arg)  /* Periodically refresh opaque LSAs so that they do not expire in     other routers. */ -void +struct ospf_lsa *  ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)  {    struct ospf_apiserver *apiserv; @@ -1904,7 +1904,7 @@ ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa)      }  out: -  return; +  return new;  } diff --git a/ospfd/ospf_apiserver.h b/ospfd/ospf_apiserver.h index 9a8ae254..b60f56b4 100644 --- a/ospfd/ospf_apiserver.h +++ b/ospfd/ospf_apiserver.h @@ -180,7 +180,7 @@ extern void ospf_apiserver_config_write_router (struct vty *vty);  extern void ospf_apiserver_config_write_if (struct vty *vty, struct interface *ifp);  extern void ospf_apiserver_show_info (struct vty *vty, struct ospf_lsa *lsa);  extern int ospf_ospf_apiserver_lsa_originator (void *arg); -extern void ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa); +extern struct ospf_lsa *ospf_apiserver_lsa_refresher (struct ospf_lsa *lsa);  extern void ospf_apiserver_flush_opaque_lsa (struct ospf_apiserver *apiserv,  				      u_char lsa_type, u_char opaque_type); diff --git a/ospfd/ospf_asbr.c b/ospfd/ospf_asbr.c index 9d2aedb2..a23b4f2b 100644 --- a/ospfd/ospf_asbr.c +++ b/ospfd/ospf_asbr.c @@ -264,8 +264,7 @@ ospf_asbr_status_update (struct ospf *ospf, u_char status)    /* Transition from/to status ASBR, schedule timer. */    ospf_spf_calculate_schedule (ospf); -  OSPF_TIMER_ON (ospf->t_router_lsa_update, -		 ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY); +  ospf_router_lsa_update (ospf);  }  void diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index 7b7a798a..6a72e31d 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -450,7 +450,7 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa)    /* if there is a Intra/Inter area route to the N       do not install external route */ -  if (NULL != (rn = route_node_lookup (ospf->new_table, +  if ((rn = route_node_lookup (ospf->new_table,  			      (struct prefix *) &p)))      {        route_unlock_node(rn); @@ -462,7 +462,7 @@ ospf_ase_calculate_route (struct ospf *ospf, struct ospf_lsa * lsa)      }    /* Find a route to the same dest */    /* If there is no route, create new one. */ -  if (NULL != (rn = route_node_lookup (ospf->new_external_route, +  if ((rn = route_node_lookup (ospf->new_external_route,  			       (struct prefix *) &p)))        route_unlock_node(rn); @@ -717,7 +717,6 @@ ospf_ase_register_external_lsa (struct ospf_lsa *lsa, struct ospf *top)    /* We assume that if LSA is deleted from DB       is is also deleted from this RT */ -    listnode_add (lst, ospf_lsa_lock (lsa)); /* external_lsas lst */  } @@ -798,7 +797,8 @@ ospf_ase_incremental_update (struct ospf *ospf, struct ospf_lsa *lsa)      }    rn = route_node_lookup (ospf->external_lsas, (struct prefix *) &p); -  assert (rn && rn->info); +  assert (rn);  +  assert (rn->info);    lsas = rn->info;    route_unlock_node (rn); diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index f72087b5..2ebae89a 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -135,7 +135,7 @@ ospf_process_self_originated_lsa (struct ospf *ospf,        /* Originate a new instance and schedule flooding */        if (area->router_lsa_self)  	area->router_lsa_self->data->ls_seqnum = new->data->ls_seqnum; -      ospf_router_lsa_timer_add (area); +      ospf_router_lsa_update_area (area);        return;      case OSPF_NETWORK_LSA:  #ifdef HAVE_OPAQUE_LSA @@ -171,7 +171,7 @@ ospf_process_self_originated_lsa (struct ospf *ospf,              if (oi->network_lsa_self)  	      oi->network_lsa_self->data->ls_seqnum = new->data->ls_seqnum;              /* Schedule network-LSA origination. */ -            ospf_network_lsa_timer_add (oi); +            ospf_network_lsa_update (oi);              return;            }        break; @@ -992,3 +992,33 @@ ospf_lsa_flush_as (struct ospf *ospf, struct ospf_lsa *lsa)    ospf_flood_through_as (ospf, NULL, lsa);    ospf_lsa_maxage (ospf, lsa);  } + +void +ospf_lsa_flush (struct ospf *ospf, struct ospf_lsa *lsa) +{ +  lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); +   +  switch (lsa->data->type) +    { +      case OSPF_ROUTER_LSA: +      case OSPF_NETWORK_LSA: +      case OSPF_SUMMARY_LSA: +      case OSPF_ASBR_SUMMARY_LSA: +      case OSPF_AS_NSSA_LSA: +#ifdef HAVE_OPAQUE_LSA +      case OSPF_OPAQUE_LINK_LSA: +      case OSPF_OPAQUE_AREA_LSA: +#endif /* HAVE_OPAQUE_LSA */ +        ospf_lsa_flush_area (lsa, lsa->area); +        break; +      case OSPF_AS_EXTERNAL_LSA: +#ifdef HAVE_OPAQUE_LSA +      case OSPF_OPAQUE_AS_LSA: +#endif /* HAVE_OPAQUE_LSA */ +        ospf_lsa_flush_as (ospf, lsa); +        break; +      default: +        zlog_info ("%s: Unknown LSA type %u", __func__, lsa->data->type); +        break; +    } +} diff --git a/ospfd/ospf_flood.h b/ospfd/ospf_flood.h index 5382e8fe..1ab11b88 100644 --- a/ospfd/ospf_flood.h +++ b/ospfd/ospf_flood.h @@ -66,6 +66,7 @@ extern void ospf_flood_lsa_area (struct ospf_lsa *, struct ospf_area *);  extern void ospf_flood_lsa_as (struct ospf_lsa *);  extern void ospf_lsa_flush_area (struct ospf_lsa *, struct ospf_area *);  extern void ospf_lsa_flush_as (struct ospf *, struct ospf_lsa *); +extern void ospf_lsa_flush (struct ospf *, struct ospf_lsa *);  extern struct external_info *ospf_external_info_check (struct ospf_lsa *);  extern void ospf_lsdb_init (struct ospf_lsdb *); diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index afe3acf1..dc0787d5 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -97,7 +97,7 @@ ospf_if_recalculate_output_cost (struct interface *ifp)        if (oi->output_cost != newcost)  	{  	  oi->output_cost = newcost; -	  ospf_router_lsa_timer_add (oi->area); +	  ospf_router_lsa_update_area (oi->area);  	}      }  } @@ -219,9 +219,6 @@ ospf_if_new (struct ospf *ospf, struct interface *ifp, struct prefix *p)    ospf_add_to_if (ifp, oi);    listnode_add (ospf->oiflist, oi); -  /* Clear self-originated network-LSA. */ -  oi->network_lsa_self = NULL; -    /* Initialize neighbor list. */    oi->nbrs = route_table_init (); @@ -301,10 +298,6 @@ ospf_if_cleanup (struct ospf_interface *oi)    ospf_nbr_delete (oi->nbr_self);    oi->nbr_self = ospf_nbr_new (oi);    ospf_nbr_add_self (oi); -   -  ospf_lsa_unlock (&oi->network_lsa_self); -  oi->network_lsa_self = NULL; -  OSPF_TIMER_OFF (oi->t_network_lsa_self);  }  void @@ -335,6 +328,8 @@ ospf_if_free (struct ospf_interface *oi)    listnode_delete (oi->ospf->oiflist, oi);    listnode_delete (oi->area->oiflist, oi); +  thread_cancel_event (master, oi); +    memset (oi, 0, sizeof (*oi));    XFREE (MTYPE_OSPF_IF, oi);  } @@ -534,6 +529,8 @@ ospf_new_if_params (void)    oip->auth_crypt = list_new (); +  oip->network_lsa_seqnum = htonl(OSPF_INITIAL_SEQUENCE_NUMBER); +    return oip;  } @@ -572,7 +569,8 @@ ospf_free_if_params (struct interface *ifp, struct in_addr addr)        !OSPF_IF_PARAM_CONFIGURED (oip, type) &&        !OSPF_IF_PARAM_CONFIGURED (oip, auth_simple) &&        !OSPF_IF_PARAM_CONFIGURED (oip, auth_type) && -      listcount (oip->auth_crypt) == 0) +      listcount (oip->auth_crypt) == 0 && +      ntohl (oip->network_lsa_seqnum) != OSPF_INITIAL_SEQUENCE_NUMBER)      {        ospf_del_if_params (oip);        rn->info = NULL; @@ -1121,8 +1119,8 @@ ospf_vl_up_check (struct ospf_area *area, struct in_addr rid,               if (IS_DEBUG_OSPF (ism, ISM_EVENTS))                 zlog_debug ("ospf_vl_up_check: VL cost change,"                            " scheduling router lsa refresh"); -             if(ospf->backbone) -               ospf_router_lsa_timer_add (ospf->backbone); +             if (ospf->backbone) +               ospf_router_lsa_update_area (ospf->backbone);               else if (IS_DEBUG_OSPF (ism, ISM_EVENTS))                 zlog_debug ("ospf_vl_up_check: VL cost change, no backbone!");             } diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index ab0b7580..6db88773 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -73,6 +73,9 @@ struct ospf_if_params    DECLARE_IF_PARAM (struct list *, auth_crypt);    /* List of Auth cryptographic data. */    DECLARE_IF_PARAM (int, auth_type);               /* OSPF authentication type */ +   +  /* Other, non-configuration state */ +  u_int32_t network_lsa_seqnum;		/* Network LSA seqnum */  };  enum @@ -167,6 +170,7 @@ struct ospf_interface    /* Configured varables. */    struct ospf_if_params *params; +      u_int32_t crypt_seqnum;		/* Cryptographic Sequence Number */     u_int32_t output_cost;	        /* Acutual Interface Output Cost */ @@ -206,8 +210,6 @@ struct ospf_interface    struct thread *t_ls_ack;              /* timer */    struct thread *t_ls_ack_direct;       /* event */    struct thread *t_ls_upd_event;        /* event */ -  struct thread *t_network_lsa_self;    /* self-originated network-LSA -                                           reflesh thread. timer */  #ifdef HAVE_OPAQUE_LSA    struct thread *t_opaque_lsa_self;     /* Type-9 Opaque-LSAs */  #endif /* HAVE_OPAQUE_LSA */ diff --git a/ospfd/ospf_ism.c b/ospfd/ospf_ism.c index 3172587a..db53882d 100644 --- a/ospfd/ospf_ism.c +++ b/ospfd/ospf_ism.c @@ -578,20 +578,17 @@ ism_change_state (struct ospf_interface *oi, int state)      oi->area->act_ints++;    /* schedule router-LSA originate. */ -  ospf_router_lsa_timer_add (oi->area); +  ospf_router_lsa_update_area (oi->area);    /* Originate network-LSA. */    if (old_state != ISM_DR && state == ISM_DR) -    ospf_network_lsa_timer_add (oi); +    ospf_network_lsa_update (oi);    else if (old_state == ISM_DR && state != ISM_DR)      {        /* Free self originated network LSA. */        lsa = oi->network_lsa_self;        if (lsa) -	{ -	  ospf_lsa_flush_area (lsa, oi->area); -	  OSPF_TIMER_OFF (oi->t_network_lsa_self); -	} +        ospf_lsa_flush_area (lsa, oi->area);        ospf_lsa_unlock (&oi->network_lsa_self);        oi->network_lsa_self = NULL; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 2f50676e..d5959eb1 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -372,7 +372,7 @@ lsa_header_set (struct stream *s, u_char options,    lsah = (struct lsa_header *) STREAM_DATA (s); -  lsah->ls_age = htons (0); +  lsah->ls_age = htons (OSPF_LSA_INITIAL_AGE);    lsah->options = options;    lsah->type = type;    lsah->id = id; @@ -741,12 +741,12 @@ ospf_stub_router_timer (struct thread *t)    UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); -  ospf_router_lsa_timer_add (area); +  ospf_router_lsa_update_area (area);    return 0;  } -inline static void +static void  ospf_stub_router_check (struct ospf_area *area)  {    /* area must either be administratively configured to be stub @@ -885,6 +885,9 @@ ospf_router_lsa_refresh (struct ospf_lsa *lsa)    /* Delete LSA from neighbor retransmit-list. */    ospf_ls_retransmit_delete_nbr_area (area, lsa); +  /* Unregister LSA from refresh-list */ +  ospf_refresher_unregister_lsa (area->ospf, lsa); +      /* Create new router-LSA instance. */    if ( (new = ospf_router_lsa_new (area)) == NULL)      { @@ -910,20 +913,15 @@ ospf_router_lsa_refresh (struct ospf_lsa *lsa)    return NULL;  } -static int -ospf_router_lsa_timer (struct thread *t) +int +ospf_router_lsa_update_area (struct ospf_area *area)  { -  struct ospf_area *area; -    if (IS_DEBUG_OSPF_EVENT) -    zlog_debug ("Timer[router-LSA]: (router-LSA Refresh expire)"); - -  area = THREAD_ARG (t); -  area->t_router_lsa_self = NULL; +    zlog_debug ("[router-LSA]: (router-LSA area update)");    /* Now refresh router-LSA. */    if (area->router_lsa_self) -    ospf_router_lsa_refresh (area->router_lsa_self); +    ospf_lsa_refresh (area->ospf, area->router_lsa_self);    /* Newly originate router-LSA. */    else      ospf_router_lsa_originate (area); @@ -931,50 +929,15 @@ ospf_router_lsa_timer (struct thread *t)    return 0;  } -void -ospf_router_lsa_timer_add (struct ospf_area *area) -{ -  /* Keep area's self-originated router-LSA. */ -  struct ospf_lsa *lsa = area->router_lsa_self; - -  /* Cancel previously scheduled router-LSA timer. */ -  if (area->t_router_lsa_self) -    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) -      zlog_debug ("LSA[Type1]: Cancel previous router-LSA timer"); - -  OSPF_TIMER_OFF (area->t_router_lsa_self); - -  /* If router-LSA is originated previously, check the interval time. */ -  if (lsa) -    { -      int delay; -      if ((delay = ospf_lsa_refresh_delay (lsa)) > 0) -        { -	  OSPF_AREA_TIMER_ON (area->t_router_lsa_self, -			      ospf_router_lsa_timer, delay); -	  return; -        } -    } - -  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) -    zlog_debug ("LSA[Type1]: Scheduling router-LSA origination right away"); - -  /* Immediately refresh router-LSA. */ -  OSPF_AREA_TIMER_ON (area->t_router_lsa_self, ospf_router_lsa_timer, 0); -} -  int -ospf_router_lsa_update_timer (struct thread *thread) +ospf_router_lsa_update (struct ospf *ospf)  { -  struct ospf *ospf = THREAD_ARG (thread);    struct listnode *node, *nnode;    struct ospf_area *area;    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))      zlog_debug ("Timer[router-LSA Update]: (timer expire)"); -  ospf->t_router_lsa_update = NULL; -    for (ALL_LIST_ELEMENTS (ospf->areas, node, nnode, area))      {        struct ospf_lsa *lsa = area->router_lsa_self; @@ -999,19 +962,20 @@ ospf_router_lsa_update_timer (struct thread *thread)  	  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))  	    zlog_debug("LSA[Type%d:%s]: Refresh router-LSA for Area %s",  		      lsa->data->type, inet_ntoa (lsa->data->id), area_str); +          ospf_refresher_unregister_lsa (ospf, lsa);  	  ospf_lsa_flush_area (lsa, area);  	  ospf_lsa_unlock (&area->router_lsa_self);  	  area->router_lsa_self = NULL;  	  /* Refresh router-LSA, (not install) and flood through area. */ -	  ospf_router_lsa_timer_add (area); +	  ospf_router_lsa_update_area (area);  	}        else  	{  	  rl = (struct router_lsa *) lsa->data;  	  /* Refresh router-LSA, (not install) and flood through area. */  	  if (rl->flags != ospf->flags) -	    ospf_router_lsa_timer_add (area); +	    ospf_router_lsa_update_area (area);  	}      } @@ -1048,6 +1012,7 @@ ospf_network_lsa_new (struct ospf_interface *oi)    struct stream *s;    struct ospf_lsa *new;    struct lsa_header *lsah; +  struct ospf_if_params *oip;    int length;    /* If there are no neighbours on this network (the net is stub), @@ -1086,20 +1051,42 @@ ospf_network_lsa_new (struct ospf_interface *oi)    new->data = ospf_lsa_data_new (length);    memcpy (new->data, lsah, length);    stream_free (s); - +   +  /* Remember prior network LSA sequence numbers, even if we stop +   * originating one for this oi, to try avoid re-originating LSAs with a +   * prior sequence number, and thus speed up adjency forming & convergence. +   */ +  if ((oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4))) +    { +      new->data->ls_seqnum = oip->network_lsa_seqnum; +      new->data->ls_seqnum = lsa_seqnum_increment (new); +    } +  else +    { +      oip = ospf_get_if_params (oi->ifp, oi->address->u.prefix4); +      ospf_if_update_params (oi->ifp, oi->address->u.prefix4); +    } +  oip->network_lsa_seqnum = new->data->ls_seqnum; +      return new;  }  /* Originate network-LSA. */ -static struct ospf_lsa * -ospf_network_lsa_originate (struct ospf_interface *oi) +void +ospf_network_lsa_update (struct ospf_interface *oi)  {    struct ospf_lsa *new; - +   +  if (oi->network_lsa_self != NULL) +    { +      ospf_lsa_refresh (oi->ospf, oi->network_lsa_self); +      return; +    } +      /* Create new network-LSA instance. */    new = ospf_network_lsa_new (oi);    if (new == NULL) -    return NULL; +    return;    /* Install LSA to LSDB. */    new = ospf_lsa_install (oi->ospf, oi, new); @@ -1117,28 +1104,51 @@ ospf_network_lsa_originate (struct ospf_interface *oi)        ospf_lsa_header_dump (new->data);      } -  return new; +  return;  } -int -ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi) +static struct ospf_lsa * +ospf_network_lsa_refresh (struct ospf_lsa *lsa)  {    struct ospf_area *area = lsa->area; -  struct ospf_lsa *new; - +  struct ospf_lsa *new, *new2; +  struct ospf_if_params *oip; +  struct ospf_interface *oi; +      assert (lsa->data); - +   +  /* Retrieve the oi for the network LSA */ +  oi = ospf_if_lookup_by_local_addr (area->ospf, NULL, lsa->data->id); +  if (oi == NULL) +    { +      if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) +        { +          zlog_debug ("LSA[Type%d:%s]: network-LSA refresh: " +                      "no oi found, ick, ignoring.", +		      lsa->data->type, inet_ntoa (lsa->data->id)); +          ospf_lsa_header_dump (lsa->data); +        } +      return NULL; +    }    /* Delete LSA from neighbor retransmit-list. */    ospf_ls_retransmit_delete_nbr_area (area, lsa); +  /* Unregister LSA from refresh-list */ +  ospf_refresher_unregister_lsa (area->ospf, lsa); +      /* Create new network-LSA instance. */    new = ospf_network_lsa_new (oi);    if (new == NULL) -    return -1; -  new->data->ls_seqnum = lsa_seqnum_increment (lsa); - -  ospf_lsa_install (area->ospf, oi, new); +    return NULL; +   +  oip = ospf_lookup_if_params (oi->ifp, oi->address->u.prefix4); +  assert (oip != NULL); +  oip->network_lsa_seqnum = new->data->ls_seqnum = lsa_seqnum_increment (lsa); +  new2 = ospf_lsa_install (area->ospf, oi, new); +   +  assert (new2 == new); +      /* Flood LSA through aera. */    ospf_flood_through_area (area, NULL, new); @@ -1149,60 +1159,8 @@ ospf_network_lsa_refresh (struct ospf_lsa *lsa, struct ospf_interface *oi)        ospf_lsa_header_dump (new->data);      } -  return 0; -} - -static int -ospf_network_lsa_refresh_timer (struct thread *t) -{ -  struct ospf_interface *oi; - -  oi = THREAD_ARG (t); -  oi->t_network_lsa_self = NULL; - -  if (oi->network_lsa_self) -    /* Now refresh network-LSA. */ -    ospf_network_lsa_refresh (oi->network_lsa_self, oi); -  else -    /* Newly create network-LSA. */ -    ospf_network_lsa_originate (oi); - -  return 0; -} - -void -ospf_network_lsa_timer_add (struct ospf_interface *oi) -{ -  /* Keep interface's self-originated network-LSA. */ -  struct ospf_lsa *lsa = oi->network_lsa_self; - -  /* Cancel previously schedules network-LSA timer. */ -  if (oi->t_network_lsa_self) -    if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) -      zlog_debug ("LSA[Type2]: Cancel previous network-LSA timer"); -  OSPF_TIMER_OFF (oi->t_network_lsa_self); - -  /* If network-LSA is originated previously, check the interval time. */ -  if (lsa) -    { -      int delay; -      if ((delay = ospf_lsa_refresh_delay (lsa)) > 0) -        { -          oi->t_network_lsa_self = -            thread_add_timer (master, ospf_network_lsa_refresh_timer, -			      oi, delay); -          return; -        } -    } - -  if (IS_DEBUG_OSPF (lsa, LSA_GENERATE)) -    zlog_debug ("Scheduling network-LSA origination right away"); - -  /* Immediately refresh network-LSA. */ -  oi->t_network_lsa_self = -    thread_add_event (master, ospf_network_lsa_refresh_timer, oi, 0); +  return new;  } -  static void  stream_put_ospf_metric (struct stream *s, u_int32_t metric_value) @@ -1326,7 +1284,7 @@ ospf_summary_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,    return new;  } -struct ospf_lsa* +static struct ospf_lsa*  ospf_summary_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)  {    struct ospf_lsa *new; @@ -1473,7 +1431,7 @@ ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *p, u_int32_t metric,    return new;  } -struct ospf_lsa* +static struct ospf_lsa*  ospf_summary_asbr_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)  {    struct ospf_lsa *new; @@ -2299,6 +2257,7 @@ ospf_external_lsa_refresh_default (struct ospf *ospf)  	{  	  if (IS_DEBUG_OSPF_EVENT)  	    zlog_debug ("LSA[Type5:0.0.0.0]: Flush AS-external-LSA"); +          ospf_refresher_unregister_lsa (ospf, lsa);  	  ospf_lsa_flush_as (ospf, lsa);  	}      } @@ -2327,7 +2286,7 @@ ospf_external_lsa_refresh_type (struct ospf *ospf, u_char type, int force)  }  /* Refresh AS-external-LSA. */ -void +struct ospf_lsa *  ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,  			   struct external_info *ei, int force)  { @@ -2343,7 +2302,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,                     lsa->data->type, inet_ntoa (lsa->data->id));        ospf_external_lsa_flush (ospf, ei->type, &ei->p,  			       ei->ifindex /*, ei->nexthop */); -      return; +      return NULL;      }    if (!changed && !force) @@ -2351,7 +2310,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,        if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))          zlog_debug ("LSA[Type%d:%s]: Not refreshed, not changed/forced",                     lsa->data->type, inet_ntoa (lsa->data->id)); -      return; +      return NULL;      }    /* Delete LSA from neighbor retransmit-list. */ @@ -2367,7 +2326,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,        if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))  	zlog_debug ("LSA[Type%d:%s]: Could not be refreshed", lsa->data->type,  		   inet_ntoa (lsa->data->id)); -      return; +      return NULL;      }    new->data->ls_seqnum = lsa_seqnum_increment (lsa); @@ -2396,7 +2355,7 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,        ospf_lsa_header_dump (new->data);      } -  return; +  return new;  } @@ -2404,8 +2363,8 @@ ospf_external_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa,  /* Install router-LSA to an area. */  static struct ospf_lsa * -ospf_router_lsa_install (struct ospf *ospf, -			 struct ospf_lsa *new, int rt_recalc) +ospf_router_lsa_install (struct ospf *ospf, struct ospf_lsa *new, +                         int rt_recalc)  {    struct ospf_area *area = new->area; @@ -2424,15 +2383,11 @@ ospf_router_lsa_install (struct ospf *ospf,        if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))  	return new; /* ignore stale LSA */ -      /* Set router-LSA refresh timer. */ -      OSPF_TIMER_OFF (area->t_router_lsa_self); -      OSPF_AREA_TIMER_ON (area->t_router_lsa_self, -                          ospf_router_lsa_timer, OSPF_LS_REFRESH_TIME); -        /* Set self-originated router-LSA. */        ospf_lsa_unlock (&area->router_lsa_self);        area->router_lsa_self = ospf_lsa_lock (new); +      ospf_refresher_register_lsa (ospf, new);      }    if (rt_recalc)      ospf_spf_calculate_schedule (ospf); @@ -2465,15 +2420,9 @@ ospf_network_lsa_install (struct ospf *ospf,        if (CHECK_FLAG (new->flags, OSPF_LSA_RECEIVED))  	return new; /* ignore stale LSA */ -      /* Set LSRefresh timer. */ -      OSPF_TIMER_OFF (oi->t_network_lsa_self); - -      OSPF_INTERFACE_TIMER_ON (oi->t_network_lsa_self, -			       ospf_network_lsa_refresh_timer, -			       OSPF_LS_REFRESH_TIME); -        ospf_lsa_unlock (&oi->network_lsa_self);        oi->network_lsa_self = ospf_lsa_lock (new); +      ospf_refresher_register_lsa (ospf, new);      }    if (rt_recalc)      ospf_spf_calculate_schedule (ospf); @@ -2721,7 +2670,8 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,            if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))              {        	      zlog_debug ("ospf_lsa_install() Premature Aging " -		         "lsa 0x%lx", (u_long)lsa); +		         "lsa 0x%p, seqnum 0x%x", +		         lsa, ntohl(lsa->data->ls_seqnum));        	      ospf_lsa_header_dump (lsa->data);              }          } @@ -2826,7 +2776,7 @@ ospf_lsa_install (struct ospf *ospf, struct ospf_interface *oi,                     new->data->type,                      inet_ntoa (new->data->id),                      lsa); -      ospf_lsa_maxage (ospf, lsa); +      ospf_lsa_flush (ospf, lsa);      }    return new; @@ -2858,35 +2808,6 @@ ospf_check_nbr_status (struct ospf *ospf)  } -#ifdef ORIGINAL_CODING -/* This function flood the maxaged LSA to DR. */ -void -ospf_maxage_flood (struct ospf_lsa *lsa) -{ -  switch (lsa->data->type) -    { -    case OSPF_ROUTER_LSA: -    case OSPF_NETWORK_LSA: -    case OSPF_SUMMARY_LSA: -    case OSPF_ASBR_SUMMARY_LSA: -    case OSPF_AS_NSSA_LSA: -#ifdef HAVE_OPAQUE_LSA -    case OSPF_OPAQUE_LINK_LSA: -    case OSPF_OPAQUE_AREA_LSA: -#endif /* HAVE_OPAQUE_LSA */ -      ospf_flood_through_area (lsa->area, NULL, lsa); -      break; -    case OSPF_AS_EXTERNAL_LSA: -#ifdef HAVE_OPAQUE_LSA -    case OSPF_OPAQUE_AS_LSA: -#endif /* HAVE_OPAQUE_LSA */ -      ospf_flood_through_as (NULL, lsa); -      break; -    default: -      break; -    } -} -#endif /* ORIGINAL_CODING */  static int  ospf_maxage_lsa_remover (struct thread *thread) @@ -2911,7 +2832,11 @@ ospf_maxage_lsa_remover (struct thread *thread)              reschedule = 1;              continue;            } - +         +        /* TODO: maybe convert this function to a work-queue */ +        if (thread_should_yield (thread)) +          OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 0); +                    /* Remove LSA from the LSDB */          if (IS_LSA_SELF (lsa))            if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) @@ -2922,19 +2847,11 @@ ospf_maxage_lsa_remover (struct thread *thread)            zlog_debug ("LSA[Type%d:%s]: MaxAge LSA removed from list",                       lsa->data->type, inet_ntoa (lsa->data->id)); -	/* Flood max age LSA. */ -#ifdef ORIGINAL_CODING -	ospf_maxage_flood (lsa); -#else /* ORIGINAL_CODING */ -        ospf_flood_through (ospf, NULL, lsa); -#endif /* ORIGINAL_CODING */ - -	if (lsa->flags & OSPF_LSA_PREMATURE_AGE)   +	if (CHECK_FLAG (lsa->flags, OSPF_LSA_PREMATURE_AGE))            {              if (IS_DEBUG_OSPF (lsa, LSA_FLOODING)) -              zlog_debug ("originating new router lsa for lsa 0x%lx \n",  -                         (u_long)lsa); -            ospf_router_lsa_originate(lsa->area); +              zlog_debug ("originating new lsa for lsa 0x%p\n", lsa); +            ospf_lsa_refresh (ospf, lsa);            }  	/* Remove from lsdb. */ @@ -2953,7 +2870,8 @@ ospf_maxage_lsa_remover (struct thread *thread)          neighbor Link state retransmission lists and b) none of the router's          neighbors are in states Exchange or Loading. */    if (reschedule) -    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2); +    OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, +                   ospf->maxage_delay);    return 0;  } @@ -2971,6 +2889,11 @@ ospf_lsa_maxage_delete (struct ospf *ospf, struct ospf_lsa *lsa)      }  } +/* Add LSA onto the MaxAge list, and schedule for removal. + * This does *not* lead to the LSA being flooded, that must be taken + * care of elsewhere, see, e.g., ospf_lsa_flush* (which are callers of this + * function). + */  void  ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)  { @@ -2990,7 +2913,8 @@ ospf_lsa_maxage (struct ospf *ospf, struct ospf_lsa *lsa)    if (IS_DEBUG_OSPF (lsa, LSA_FLOODING))      zlog_debug ("LSA[%s]: MaxAge LSA remover scheduled.", dump_lsa_key (lsa)); -  OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, 2); +  OSPF_TIMER_ON (ospf->t_maxage, ospf_maxage_lsa_remover, +                 ospf->maxage_delay);  }  static int @@ -3035,6 +2959,10 @@ ospf_lsa_maxage_walker_remover (struct ospf *ospf, struct ospf_lsa *lsa)  	ospf_lsa_maxage (ospf, lsa);        } +  if (IS_LSA_MAXAGE (lsa) && !ospf_lsa_is_self_originated (ospf, lsa)) +    if (LS_AGE (lsa) > OSPF_LSA_MAXAGE + 30) +      printf ("Eek! Shouldn't happen!\n"); +    return 0;  } @@ -3353,6 +3281,7 @@ ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)    switch (lsa->data->type)      {  #ifdef HAVE_OPAQUE_LSA +    /* Opaque wants to be notified of flushes */      case OSPF_OPAQUE_LINK_LSA:      case OSPF_OPAQUE_AREA_LSA:      case OSPF_OPAQUE_AS_LSA: @@ -3360,7 +3289,8 @@ ospf_lsa_flush_schedule (struct ospf *ospf, struct ospf_lsa *lsa)        break;  #endif /* HAVE_OPAQUE_LSA */      default: -      ospf_lsa_maxage (ospf, lsa); +      ospf_refresher_unregister_lsa (ospf, lsa); +      ospf_lsa_flush (ospf, lsa);        break;      } @@ -3383,12 +3313,13 @@ ospf_flush_self_originated_lsas_now (struct ospf *ospf)        if ((lsa = area->router_lsa_self) != NULL)          {            if (IS_DEBUG_OSPF_EVENT) -            zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id)); - +            zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", +                        lsa->data->type, inet_ntoa (lsa->data->id)); +           +          ospf_refresher_unregister_lsa (ospf, lsa);            ospf_lsa_flush_area (lsa, area);            ospf_lsa_unlock (&area->router_lsa_self);            area->router_lsa_self = NULL; -          OSPF_TIMER_OFF (area->t_router_lsa_self);          }        for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi)) @@ -3398,12 +3329,13 @@ ospf_flush_self_originated_lsas_now (struct ospf *ospf)                 &&   oi->full_nbrs > 0)              {                if (IS_DEBUG_OSPF_EVENT) -                zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", lsa->data->type, inet_ntoa (lsa->data->id)); - +                zlog_debug ("LSA[Type%d:%s]: Schedule self-originated LSA to FLUSH", +                            lsa->data->type, inet_ntoa (lsa->data->id)); +               +              ospf_refresher_unregister_lsa (ospf, oi->network_lsa_self);                ospf_lsa_flush_area (oi->network_lsa_self, area);                ospf_lsa_unlock (&oi->network_lsa_self);                oi->network_lsa_self = NULL; -              OSPF_TIMER_OFF (oi->t_network_lsa_self);              }            if (oi->type != OSPF_IFTYPE_VIRTUALLINK @@ -3603,23 +3535,29 @@ ospf_schedule_lsa_flush_area (struct ospf_area *area, struct ospf_lsa *lsa)  /* LSA Refreshment functions. */ -static void +struct ospf_lsa *  ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)  {    struct external_info *ei; +  struct ospf_lsa *new = NULL; +  assert (CHECK_FLAG (lsa->flags, OSPF_LSA_SELF));    assert (IS_LSA_SELF (lsa)); +  assert (lsa->lock > 0);    switch (lsa->data->type)      {        /* Router and Network LSAs are processed differently. */      case OSPF_ROUTER_LSA: +      new = ospf_router_lsa_refresh (lsa); +      break;      case OSPF_NETWORK_LSA:  +      new = ospf_network_lsa_refresh (lsa);        break;      case OSPF_SUMMARY_LSA: -      ospf_summary_lsa_refresh (ospf, lsa); +      new = ospf_summary_lsa_refresh (ospf, lsa);        break;      case OSPF_ASBR_SUMMARY_LSA: -      ospf_summary_asbr_lsa_refresh (ospf, lsa); +      new = ospf_summary_asbr_lsa_refresh (ospf, lsa);        break;      case OSPF_AS_EXTERNAL_LSA:        /* Translated from NSSA Type-5s are refreshed when  @@ -3629,7 +3567,7 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)          break;        ei = ospf_external_info_check (lsa);        if (ei) -        ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE); +        new = ospf_external_lsa_refresh (ospf, lsa, ei, LSA_REFRESH_FORCE);        else          ospf_lsa_flush_as (ospf, lsa);        break; @@ -3637,12 +3575,13 @@ ospf_lsa_refresh (struct ospf *ospf, struct ospf_lsa *lsa)      case OSPF_OPAQUE_LINK_LSA:      case OSPF_OPAQUE_AREA_LSA:      case OSPF_OPAQUE_AS_LSA: -      ospf_opaque_lsa_refresh (lsa); +      new = ospf_opaque_lsa_refresh (lsa);        break;  #endif /* HAVE_OPAQUE_LSA */      default:        break;      } +  return new;  }  void @@ -3650,6 +3589,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)  {    u_int16_t index, current_index; +  assert (lsa->lock > 0);    assert (IS_LSA_SELF (lsa));    if (lsa->refresh_list < 0) @@ -3668,11 +3608,11 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)        if (delay < 0)  	delay = 0; -      current_index = ospf->lsa_refresh_queue.index + -	(quagga_time (NULL) - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY; +      current_index = ospf->lsa_refresh_queue.index + (quagga_time (NULL) +                - ospf->lsa_refresher_started)/OSPF_LSA_REFRESHER_GRANULARITY;        index = (current_index + delay/OSPF_LSA_REFRESHER_GRANULARITY) -	% (OSPF_LSA_REFRESHER_SLOTS); +	      % (OSPF_LSA_REFRESHER_SLOTS);        if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))  	zlog_debug ("LSA[Refresh]: lsa %s with age %d added to index %d", @@ -3684,7 +3624,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)        lsa->refresh_list = index;        if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))          zlog_debug ("LSA[Refresh:%s]: ospf_refresher_register_lsa(): " -                   "setting refresh_list on lsa %p (index %u)",  +                   "setting refresh_list on lsa %p (slod %d)",                      inet_ntoa (lsa->data->id), lsa, index);      }  } @@ -3692,6 +3632,7 @@ ospf_refresher_register_lsa (struct ospf *ospf, struct ospf_lsa *lsa)  void  ospf_refresher_unregister_lsa (struct ospf *ospf, struct ospf_lsa *lsa)  { +  assert (lsa->lock > 0);    assert (IS_LSA_SELF (lsa));    if (lsa->refresh_list >= 0)      { @@ -3728,8 +3669,9 @@ ospf_lsa_refresh_walker (struct thread *t)       modulus. */    ospf->lsa_refresh_queue.index =     ((unsigned long)(ospf->lsa_refresh_queue.index + -		    (quagga_time (NULL) - ospf->lsa_refresher_started) / -		    OSPF_LSA_REFRESHER_GRANULARITY)) % OSPF_LSA_REFRESHER_SLOTS; +		    (quagga_time (NULL) - ospf->lsa_refresher_started) +		    / OSPF_LSA_REFRESHER_GRANULARITY)) +		    % OSPF_LSA_REFRESHER_SLOTS;    if (IS_DEBUG_OSPF (lsa, LSA_REFRESH))      zlog_debug ("LSA[Refresh]: ospf_lsa_refresh_walker(): next index %d", @@ -3744,6 +3686,8 @@ ospf_lsa_refresh_walker (struct thread *t)        refresh_list = ospf->lsa_refresh_queue.qs [i]; +      assert (i >= 0); +        ospf->lsa_refresh_queue.qs [i] = NULL;        if (refresh_list) @@ -3755,8 +3699,8 @@ ospf_lsa_refresh_walker (struct thread *t)  		           "refresh lsa %p (slot %d)",   		           inet_ntoa (lsa->data->id), lsa, i); +	      assert (lsa->lock > 0);  	      list_delete_node (refresh_list, node); -	      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue */  	      lsa->refresh_list = -1;  	      listnode_add (lsa_to_refresh, lsa);  	    } @@ -3769,7 +3713,11 @@ ospf_lsa_refresh_walker (struct thread *t)    ospf->lsa_refresher_started = quagga_time (NULL);    for (ALL_LIST_ELEMENTS (lsa_to_refresh, node, nnode, lsa)) -    ospf_lsa_refresh (ospf, lsa); +    { +      ospf_lsa_refresh (ospf, lsa); +      assert (lsa->lock > 0); +      ospf_lsa_unlock (&lsa); /* lsa_refresh_queue & temp for lsa_to_refresh*/ +    }    list_delete (lsa_to_refresh); diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 6b2ba228..f364840f 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -115,11 +115,9 @@ struct ospf_lsa    /* Refreshement List or Queue */    int refresh_list; - -#ifdef HAVE_OPAQUE_LSA -  /* For Type-9 Opaque-LSAs, reference to ospf-interface is required. */ +   +  /* For Type-9 Opaque-LSAs */    struct ospf_interface *oi; -#endif /* HAVE_OPAQUE_LSA */  };  /* OSPF LSA Link Type. */ @@ -255,19 +253,16 @@ extern struct lsa_header *ospf_lsa_data_dup (struct lsa_header *);  extern void ospf_lsa_data_free (struct lsa_header *);  /* Prototype for various LSAs */ -extern int ospf_router_lsa_update_timer (struct thread *); -extern void ospf_router_lsa_timer_add (struct ospf_area *); +extern int ospf_router_lsa_update (struct ospf *); +extern int ospf_router_lsa_update_area (struct ospf_area *); -extern int ospf_network_lsa_refresh (struct ospf_lsa *, struct ospf_interface *); -extern void ospf_network_lsa_timer_add (struct ospf_interface *); +extern void ospf_network_lsa_update (struct ospf_interface *);  extern struct ospf_lsa *ospf_summary_lsa_originate (struct prefix_ipv4 *, u_int32_t,  					     struct ospf_area *);  extern struct ospf_lsa *ospf_summary_asbr_lsa_originate (struct prefix_ipv4 *,  						  u_int32_t,  						  struct ospf_area *); -extern struct ospf_lsa *ospf_summary_lsa_refresh (struct ospf *, struct ospf_lsa *); -extern struct ospf_lsa *ospf_summary_asbr_lsa_refresh (struct ospf *, struct ospf_lsa *);  extern struct ospf_lsa *ospf_lsa_install (struct ospf *,  				   struct ospf_interface *, struct ospf_lsa *); @@ -302,12 +297,15 @@ extern void ospf_lsa_maxage (struct ospf *, struct ospf_lsa *);  extern u_int32_t get_metric (u_char *);  extern int ospf_lsa_maxage_walker (struct thread *); - +extern struct ospf_lsa *ospf_lsa_refresh (struct ospf *, struct ospf_lsa *); +   extern void ospf_external_lsa_refresh_default (struct ospf *);  extern void ospf_external_lsa_refresh_type (struct ospf *, u_char, int); -extern void ospf_external_lsa_refresh (struct ospf *, struct ospf_lsa *, -				struct external_info *, int); +extern struct ospf_lsa *ospf_external_lsa_refresh (struct ospf *, +                                                   struct ospf_lsa *, +                                                   struct external_info *, +                                                   int);  extern struct in_addr ospf_lsa_unique_id (struct ospf *, struct ospf_lsdb *, u_char,  				   struct prefix_ipv4 *);  extern void ospf_schedule_lsa_flood_area (struct ospf_area *, struct ospf_lsa *); diff --git a/ospfd/ospf_lsdb.c b/ospfd/ospf_lsdb.c index c906f052..ea9a3528 100644 --- a/ospfd/ospf_lsdb.c +++ b/ospfd/ospf_lsdb.c @@ -120,7 +120,10 @@ ospf_lsdb_add (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)    /* nothing to do? */    if (rn->info && rn->info == lsa) -    return; +    { +      route_unlock_node (rn); +      return; +    }    /* purge old entry? */    if (rn->info) @@ -162,12 +165,13 @@ ospf_lsdb_delete (struct ospf_lsdb *lsdb, struct ospf_lsa *lsa)        return;      } +  assert (lsa->data->type < OSPF_MAX_LSA);    table = lsdb->type[lsa->data->type].db;    lsdb_prefix_set (&lp, lsa); -  rn = route_node_lookup (table, (struct prefix *) &lp); -  if (rn && (rn->info == lsa)) +  if ((rn = route_node_lookup (table, (struct prefix *) &lp)))      { -      ospf_lsdb_delete_entry (lsdb, rn); +      if (rn->info == lsa) +        ospf_lsdb_delete_entry (lsdb, rn);        route_unlock_node (rn); /* route_node_lookup */      }  } @@ -274,7 +278,8 @@ ospf_lsdb_lookup_by_id_next (struct ospf_lsdb *lsdb, u_char type,        rn = route_top (table);    else      { -      rn = route_node_get (table, (struct prefix *) &lp); +      if ((rn = route_node_lookup (table, (struct prefix *) &lp)) == NULL) +        return NULL;        rn = route_next (rn);      } diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 15fff349..cbc31716 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -162,7 +162,7 @@ nsm_should_adj (struct ospf_neighbor *nbr)  /* OSPF NSM functions. */  static int -nsm_hello_received (struct ospf_neighbor *nbr) +nsm_packet_received (struct ospf_neighbor *nbr)  {    /* Start or Restart Inactivity Timer. */    OSPF_NSM_TIMER_OFF (nbr->t_inactivity); @@ -216,7 +216,7 @@ ospf_db_summary_add (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)      {      case OSPF_OPAQUE_LINK_LSA:        /* Exclude type-9 LSAs that does not have the same "oi" with "nbr". */ -      if (lsa->oi != nbr->oi) +      if (nbr->oi && ospf_if_exists (lsa->oi) != nbr->oi)            return 0;        break;      case OSPF_OPAQUE_AREA_LSA: @@ -408,7 +408,7 @@ struct {    {      /* DependUpon: dummy state. */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { NULL,                    NSM_DependUpon }, /* HelloReceived     */ +    { NULL,                    NSM_DependUpon }, /* PacketReceived    */      { NULL,                    NSM_DependUpon }, /* Start             */      { NULL,                    NSM_DependUpon }, /* 2-WayReceived     */      { NULL,                    NSM_DependUpon }, /* NegotiationDone   */ @@ -425,7 +425,7 @@ struct {    {      /* Deleted: dummy state. */      { NULL,                    NSM_Deleted    }, /* NoEvent           */ -    { NULL,                    NSM_Deleted    }, /* HelloReceived     */ +    { NULL,                    NSM_Deleted    }, /* PacketReceived    */      { NULL,                    NSM_Deleted    }, /* Start             */      { NULL,                    NSM_Deleted    }, /* 2-WayReceived     */      { NULL,                    NSM_Deleted    }, /* NegotiationDone   */ @@ -442,7 +442,7 @@ struct {    {      /* Down: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_Init       }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_Init       }, /* PacketReceived    */      { nsm_start,               NSM_Attempt    }, /* Start             */      { NULL,                    NSM_Down       }, /* 2-WayReceived     */      { NULL,                    NSM_Down       }, /* NegotiationDone   */ @@ -459,7 +459,7 @@ struct {    {      /* Attempt: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_Init       }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_Init       }, /* PacketReceived    */      { NULL,                    NSM_Attempt    }, /* Start             */      { NULL,                    NSM_Attempt    }, /* 2-WayReceived     */      { NULL,                    NSM_Attempt    }, /* NegotiationDone   */ @@ -476,7 +476,7 @@ struct {    {      /* Init: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_Init       }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_Init      }, /* PacketReceived    */      { NULL,                    NSM_Init       }, /* Start             */      { nsm_twoway_received,     NSM_DependUpon }, /* 2-WayReceived     */      { NULL,                    NSM_Init       }, /* NegotiationDone   */ @@ -493,7 +493,7 @@ struct {    {      /* 2-Way: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_TwoWay     }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_TwoWay     }, /* HelloReceived     */      { NULL,                    NSM_TwoWay     }, /* Start             */      { NULL,                    NSM_TwoWay     }, /* 2-WayReceived     */      { NULL,                    NSM_TwoWay     }, /* NegotiationDone   */ @@ -510,7 +510,7 @@ struct {    {      /* ExStart: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_ExStart    }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_ExStart    }, /* PacaketReceived   */      { NULL,                    NSM_ExStart    }, /* Start             */      { NULL,                    NSM_ExStart    }, /* 2-WayReceived     */      { nsm_negotiation_done,    NSM_Exchange   }, /* NegotiationDone   */ @@ -527,7 +527,7 @@ struct {    {      /* Exchange: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_Exchange   }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_Exchange   }, /* PacketReceived    */      { NULL,                    NSM_Exchange   }, /* Start             */      { NULL,                    NSM_Exchange   }, /* 2-WayReceived     */      { NULL,                    NSM_Exchange   }, /* NegotiationDone   */ @@ -544,7 +544,7 @@ struct {    {      /* Loading: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_Loading    }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_Loading    }, /* PacketReceived    */      { NULL,                    NSM_Loading    }, /* Start             */      { NULL,                    NSM_Loading    }, /* 2-WayReceived     */      { NULL,                    NSM_Loading    }, /* NegotiationDone   */ @@ -560,7 +560,7 @@ struct {    },    { /* Full: */      { NULL,                    NSM_DependUpon }, /* NoEvent           */ -    { nsm_hello_received,      NSM_Full       }, /* HelloReceived     */ +    { nsm_packet_received,     NSM_Full       }, /* PacketReceived    */      { NULL,                    NSM_Full       }, /* Start             */      { NULL,                    NSM_Full       }, /* 2-WayReceived     */      { NULL,                    NSM_Full       }, /* NegotiationDone   */ @@ -579,7 +579,7 @@ struct {  static const char *ospf_nsm_event_str[] =  {    "NoEvent", -  "HelloReceived", +  "PacketReceived",    "Start",    "2-WayReceived",    "NegotiationDone", @@ -711,7 +711,7 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)  		 LOOKUP(ospf_nsm_state_msg, old_state),  		 LOOKUP(ospf_nsm_state_msg, state)); -      ospf_router_lsa_timer_add (oi->area); +      ospf_router_lsa_update_area (oi->area);        if (oi->type == OSPF_IFTYPE_VIRTUALLINK)  	{ @@ -719,7 +719,7 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)  	    ospf_area_lookup_by_area_id (oi->ospf, oi->vl_data->vl_area_id);  	  if (vl_area) -	    ospf_router_lsa_timer_add (vl_area); +	    ospf_router_lsa_update_area (vl_area);  	}        /* Originate network-LSA. */ @@ -730,10 +730,9 @@ nsm_change_state (struct ospf_neighbor *nbr, int state)  	      ospf_lsa_flush_area (oi->network_lsa_self, oi->area);  	      ospf_lsa_unlock (&oi->network_lsa_self);  	      oi->network_lsa_self = NULL; -	      OSPF_TIMER_OFF (oi->t_network_lsa_self);  	    }  	  else -	    ospf_network_lsa_timer_add (oi); +	    ospf_network_lsa_update (oi);  	}      } diff --git a/ospfd/ospf_nsm.h b/ospfd/ospf_nsm.h index 1121dae6..4f2ae808 100644 --- a/ospfd/ospf_nsm.h +++ b/ospfd/ospf_nsm.h @@ -39,7 +39,7 @@  /* OSPF Neighbor State Machine Event. */  #define NSM_NoEvent	        0 -#define NSM_HelloReceived	1 +#define NSM_PacketReceived	1 /* HelloReceived in the protocol */  #define NSM_Start		2  #define NSM_TwoWayReceived	3  #define NSM_NegotiationDone	4 diff --git a/ospfd/ospf_opaque.c b/ospfd/ospf_opaque.c index 0b6ac4cb..aa126e19 100644 --- a/ospfd/ospf_opaque.c +++ b/ospfd/ospf_opaque.c @@ -251,7 +251,7 @@ struct ospf_opaque_functab    void (* config_write_debug )(struct vty *vty);    void (* show_opaque_info   )(struct vty *vty, struct ospf_lsa *lsa);    int  (* lsa_originator)(void *arg); -  void (* lsa_refresher )(struct ospf_lsa *lsa); +  struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa);    int (* new_lsa_hook)(struct ospf_lsa *lsa);    int (* del_lsa_hook)(struct ospf_lsa *lsa);  }; @@ -354,7 +354,7 @@ ospf_register_opaque_functab (    void (* config_write_debug )(struct vty *vty),    void (* show_opaque_info   )(struct vty *vty, struct ospf_lsa *lsa),    int  (* lsa_originator)(void *arg), -  void (* lsa_refresher )(struct ospf_lsa *lsa), +  struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),    int (* new_lsa_hook)(struct ospf_lsa *lsa),    int (* del_lsa_hook)(struct ospf_lsa *lsa))  { @@ -1608,12 +1608,13 @@ out:    return new;  } -void +struct ospf_lsa *  ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)  {    struct ospf *ospf;    struct ospf_opaque_functab *functab; - +  struct ospf_lsa *new = NULL; +      ospf = ospf_lookup ();    if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL @@ -1630,12 +1631,12 @@ ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)          zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));        lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); -      ospf_lsa_maxage (ospf, lsa); +      ospf_lsa_flush (ospf, lsa);      }    else -    (* functab->lsa_refresher)(lsa); +    new = (* functab->lsa_refresher)(lsa); -  return; +  return new;  }  /*------------------------------------------------------------------------* @@ -2108,7 +2109,7 @@ ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)      zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));    /* This lsa will be flushed and removed eventually. */ -  ospf_lsa_maxage (lsa0->area->ospf, lsa); +  ospf_lsa_flush (lsa0->area->ospf, lsa);  out:    return; diff --git a/ospfd/ospf_opaque.h b/ospfd/ospf_opaque.h index f49fe460..22730645 100644 --- a/ospfd/ospf_opaque.h +++ b/ospfd/ospf_opaque.h @@ -120,7 +120,7 @@ ospf_register_opaque_functab (    void (* config_write_debug )(struct vty *vty),    void (* show_opaque_info   )(struct vty *vty, struct ospf_lsa *lsa),    int  (* lsa_originator)(void *arg), -  void (* lsa_refresher )(struct ospf_lsa *lsa), +  struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),    int (* new_lsa_hook)(struct ospf_lsa *lsa),    int (* del_lsa_hook)(struct ospf_lsa *lsa)  ); @@ -143,7 +143,7 @@ extern void ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi,  						int *init_delay);  extern struct ospf_lsa *ospf_opaque_lsa_install (struct ospf_lsa *,  						 int rt_recalc); -extern void ospf_opaque_lsa_refresh (struct ospf_lsa *lsa); +extern struct ospf_lsa *ospf_opaque_lsa_refresh (struct ospf_lsa *lsa);  extern void ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,  						  u_char lsa_type, diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 994d3629..b714c27d 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -125,6 +125,20 @@ ospf_fifo_push (struct ospf_fifo *fifo, struct ospf_packet *op)    fifo->count++;  } +/* Add new packet to head of fifo. */ +static void +ospf_fifo_push_head (struct ospf_fifo *fifo, struct ospf_packet *op) +{ +  op->next = fifo->head; +   +  if (fifo->tail == NULL) +    fifo->tail = op; +   +  fifo->head = op; +   +  fifo->count++; +} +  /* Delete first packet from fifo. */  struct ospf_packet *  ospf_fifo_pop (struct ospf_fifo *fifo) @@ -199,6 +213,27 @@ ospf_packet_add (struct ospf_interface *oi, struct ospf_packet *op)    /* ospf_fifo_debug (oi->obuf); */  } +static void +ospf_packet_add_top (struct ospf_interface *oi, struct ospf_packet *op) +{ +  if (!oi->obuf) +    { +      zlog_err("ospf_packet_add(interface %s in state %d [%s], packet type %s, " +	       "destination %s) called with NULL obuf, ignoring " +	       "(please report this bug)!\n", +	       IF_NAME(oi), oi->state, LOOKUP (ospf_ism_state_msg, oi->state), +	       ospf_packet_type_str[stream_getc_from(op->s, 1)], +	       inet_ntoa (op->dst)); +      return; +    } + +  /* Add packet to head of queue. */ +  ospf_fifo_push_head (oi->obuf, op); + +  /* Debug of packet fifo*/ +  /* ospf_fifo_debug (oi->obuf); */ +} +  void  ospf_packet_delete (struct ospf_interface *oi)  { @@ -231,7 +266,7 @@ ospf_packet_dup (struct ospf_packet *op)  }  /* XXX inline */ -static inline unsigned int +static unsigned int  ospf_packet_authspace (struct ospf_interface *oi)  {    int auth = 0; @@ -653,6 +688,13 @@ ospf_write (struct thread *thread)    iph.ip_tos = IPTOS_PREC_INTERNETCONTROL;    iph.ip_len = (iph.ip_hl << OSPF_WRITE_IPHL_SHIFT) + op->length; +#if defined(__DragonFly__) +  /* +   * DragonFly's raw socket expects ip_len/ip_off in network byte order. +   */ +  iph.ip_len = htons(iph.ip_len); +#endif +  #ifdef WANT_OSPF_WRITE_FRAGMENT    /* XXX-MT: not thread-safe at all..     * XXX: this presumes this is only programme sending OSPF packets  @@ -881,7 +923,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,    old_state = nbr->state;    /* Add event to thread. */ -  OSPF_NSM_EVENT_EXECUTE (nbr, NSM_HelloReceived); +  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived);    /*  RFC2328  Section 9.5.1        If the router is not eligible to become Designated Router, @@ -901,7 +943,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,    if (oi->type == OSPF_IFTYPE_NBMA &&        (old_state == NSM_Down || old_state == NSM_Attempt))      { -      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived); +      OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);        nbr->priority = hello->priority;        nbr->d_router = hello->d_router;        nbr->bd_router = hello->bd_router; @@ -911,12 +953,12 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh,    if (ospf_nbr_bidirectional (&oi->ospf->router_id, hello->neighbors,  			      size - OSPF_HELLO_MIN_SIZE))      { -      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_TwoWayReceived); +      OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_TwoWayReceived);        nbr->options |= hello->options;      }    else      { -      OSPF_NSM_EVENT_EXECUTE (nbr, NSM_OneWayReceived); +      OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_OneWayReceived);        /* Set neighbor information. */        nbr->priority = hello->priority;        nbr->d_router = hello->d_router; @@ -1191,6 +1233,9 @@ ospf_db_desc (struct ip *iph, struct ospf_header *ospfh,      }  #endif /* HAVE_OPAQUE_LSA */ +  /* Add event to thread. */ +  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); +    /* Process DD packet by neighbor status. */    switch (nbr->state)      { @@ -1412,6 +1457,9 @@ ospf_ls_req (struct ip *iph, struct ospf_header *ospfh,        return;      } +  /* Add event to thread. */ +  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); +    /* Neighbor State should be Exchange or later. */    if (nbr->state != NSM_Exchange &&        nbr->state != NSM_Loading && @@ -1649,6 +1697,9 @@ ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,        return;      } +  /* Add event to thread. */ +  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); +    /* Check neighbor state. */    if (nbr->state < NSM_Exchange)      { @@ -1951,7 +2002,7 @@ ospf_ls_upd (struct ip *iph, struct ospf_header *ospfh,  	      quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);  	      if (tv_cmp (tv_sub (now, current->tv_orig),  -			  int2tv (OSPF_MIN_LS_ARRIVAL)) > 0) +			  int2tv (OSPF_MIN_LS_ARRIVAL)) >= 0)  		/* Trap NSSA type later.*/  		ospf_ls_upd_send_lsa (nbr, current, OSPF_SEND_PACKET_DIRECT);  	      DISCARD_LSA (lsa, 8); @@ -1982,6 +2033,9 @@ ospf_ls_ack (struct ip *iph, struct ospf_header *ospfh,        return;      } +  /* Add event to thread. */ +  OSPF_NSM_EVENT_SCHEDULE (nbr, NSM_PacketReceived); +    if (nbr->state < NSM_Exchange)      {        zlog_warn ("Link State Acknowledgment: " @@ -2085,6 +2139,15 @@ ospf_recv_packet (int fd, struct interface **ifp, struct stream *ibuf)    ip_len = ip_len + (iph->ip_hl << 2);  #endif +#if defined(__DragonFly__) +  /* +   * in DragonFly's raw socket, ip_len/ip_off are read  +   * in network byte order. +   * As OpenBSD < 200311 adjust ip_len to strip IP header size! +   */ +  ip_len = ntohs(iph->ip_len) + (iph->ip_hl << 2); +#endif +    ifindex = getsockopt_ifindex (AF_INET, &msgh);    *ifp = if_lookup_by_index (ifindex); @@ -2150,7 +2213,7 @@ ospf_associate_packet_vl (struct ospf *ospf, struct interface *ifp,    return NULL;  } -static inline int +static int  ospf_check_area_id (struct ospf_interface *oi, struct ospf_header *ospfh)  {    /* Check match the Area ID of the receiving interface. */ @@ -2978,8 +3041,8 @@ ospf_make_ls_ack (struct ospf_interface *oi, struct list *ack, struct stream *s)    return length;  } -void -ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr) +static void +ospf_hello_send_sub (struct ospf_interface *oi, in_addr_t addr)  {    struct ospf_packet *op;    u_int16_t length = OSPF_HEADER_SIZE; @@ -2998,10 +3061,12 @@ ospf_hello_send_sub (struct ospf_interface *oi, struct in_addr *addr)    /* Set packet length. */    op->length = length; -  op->dst.s_addr = addr->s_addr; +  op->dst.s_addr = addr; -  /* Add packet to the interface output queue. */ -  ospf_packet_add (oi, op); +  /* Add packet to the top of the interface output queue, so that they +   * can't get delayed by things like long queues of LS Update packets +   */ +  ospf_packet_add_top (oi, op);    /* Hook thread to write packet. */    OSPF_ISM_WRITE_ON (oi->ospf); @@ -3032,7 +3097,7 @@ ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma)        && oi->state != ISM_DR && oi->state != ISM_Backup)      return; -  ospf_hello_send_sub (oi, &nbr_nbma->addr); +  ospf_hello_send_sub (oi, nbr_nbma->addr.s_addr);  }  int @@ -3071,7 +3136,7 @@ ospf_hello_reply_timer (struct thread *thread)      zlog (NULL, LOG_DEBUG, "NSM[%s:%s]: Timer (hello-reply timer expire)",  	  IF_NAME (nbr->oi), inet_ntoa (nbr->router_id)); -  ospf_hello_send_sub (nbr->oi, &nbr->address.u.prefix4); +  ospf_hello_send_sub (nbr->oi, nbr->address.u.prefix4.s_addr);    return 0;  } @@ -3080,27 +3145,10 @@ ospf_hello_reply_timer (struct thread *thread)  void  ospf_hello_send (struct ospf_interface *oi)  { -  struct ospf_packet *op; -  u_int16_t length = OSPF_HEADER_SIZE; -    /* If this is passive interface, do not send OSPF Hello. */    if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE)      return; -  op = ospf_packet_new (oi->ifp->mtu); - -  /* Prepare OSPF common header. */ -  ospf_make_header (OSPF_MSG_HELLO, oi, op->s); - -  /* Prepare OSPF Hello body. */ -  length += ospf_make_hello (oi, op->s); - -  /* Fill OSPF header. */ -  ospf_fill_header (oi, op->s, length); - -  /* Set packet length. */ -  op->length = length; -    if (oi->type == OSPF_IFTYPE_NBMA)      {        struct ospf_neighbor *nbr; @@ -3130,34 +3178,16 @@ ospf_hello_send (struct ospf_interface *oi)  		if (nbr->priority == 0 && oi->state == ISM_DROther)  		  continue;  		/* if oi->state == Waiting, send hello to all neighbors */ -		{ -		  struct ospf_packet *op_dup; - -		  op_dup = ospf_packet_dup(op); -		  op_dup->dst = nbr->address.u.prefix4; - -		  /* Add packet to the interface output queue. */ -		  ospf_packet_add (oi, op_dup); - -		  OSPF_ISM_WRITE_ON (oi->ospf); -		} - +		ospf_hello_send_sub (oi, nbr->address.u.prefix4.s_addr);  	      } -      ospf_packet_free (op);      }    else      {        /* Decide destination address. */        if (oi->type == OSPF_IFTYPE_VIRTUALLINK) -	op->dst.s_addr = oi->vl_data->peer_addr.s_addr; -      else  -	op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); - -      /* Add packet to the interface output queue. */ -      ospf_packet_add (oi, op); - -      /* Hook thread to write packet. */ -      OSPF_ISM_WRITE_ON (oi->ospf); +        ospf_hello_send_sub (oi, oi->vl_data->peer_addr.s_addr); +      else +        ospf_hello_send_sub (oi, htonl (OSPF_ALLSPFROUTERS));      }  } diff --git a/ospfd/ospf_packet.h b/ospfd/ospf_packet.h index 7b3d6866..9a472081 100644 --- a/ospfd/ospf_packet.h +++ b/ospfd/ospf_packet.h @@ -162,6 +162,5 @@ extern int ospf_ls_upd_timer (struct thread *);  extern int ospf_ls_ack_timer (struct thread *);  extern int ospf_poll_timer (struct thread *);  extern int ospf_hello_reply_timer (struct thread *); -extern void ospf_hello_send_sub (struct ospf_interface *, struct in_addr *);  #endif /* _ZEBRA_OSPF_PACKET_H */ diff --git a/ospfd/ospf_te.c b/ospfd/ospf_te.c index c5ec0ad8..24e81052 100644 --- a/ospfd/ospf_te.c +++ b/ospfd/ospf_te.c @@ -133,7 +133,7 @@ static void ospf_mpls_te_config_write_router (struct vty *vty);  static void ospf_mpls_te_config_write_if (struct vty *vty, struct interface *ifp);  static void ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa);  static int ospf_mpls_te_lsa_originate (void *arg); -static void ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa); +static struct ospf_lsa *ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);  static void ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, enum sched_opcode);  static void del_mpls_te_link (void *val); @@ -1009,7 +1009,7 @@ out:    return rc;  } -static void +static struct ospf_lsa *  ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)  {    struct mpls_te_link *lp; @@ -1070,7 +1070,7 @@ ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)      }  out: -  return; +  return new;  }  static void diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index f68adb2d..97c8e8d6 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -2913,7 +2913,13 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf,  		       inet_ntoa (nbr->address.u.prefix4), VTY_NEWLINE);  	    }  	} - +       +      /* Next network-LSA sequence number we'll use, if we're elected DR */ +      if (oi->params && ntohl (oi->params->network_lsa_seqnum) +                          != OSPF_INITIAL_SEQUENCE_NUMBER) +        vty_out (vty, "  Saved Network-LSA sequence number 0x%x%s", +                 ntohl (oi->params->network_lsa_seqnum), VTY_NEWLINE); +              vty_out (vty, "  Multicast group memberships:");        if (OI_MEMBER_CHECK(oi, MEMBER_ALLROUTERS)            || OI_MEMBER_CHECK(oi, MEMBER_DROUTERS)) @@ -7012,7 +7018,7 @@ DEFUN (ospf_max_metric_router_lsa_admin,        SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);        if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) -          ospf_router_lsa_timer_add (area); +          ospf_router_lsa_update_area (area);      }    return CMD_SUCCESS;  } @@ -7038,7 +7044,7 @@ DEFUN (no_ospf_max_metric_router_lsa_admin,            && !area->t_stub_router)          {            UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); -          ospf_router_lsa_timer_add (area); +          ospf_router_lsa_update_area (area);          }      }    return CMD_SUCCESS; @@ -7091,7 +7097,7 @@ DEFUN (no_ospf_max_metric_router_lsa_startup,        if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED))          {            UNSET_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED); -          ospf_router_lsa_timer_add (area); +          ospf_router_lsa_update_area (area);          }      }    return CMD_SUCCESS; diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index c250fe9e..e8405136 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -131,8 +131,8 @@ ospf_router_id_update (struct ospf *ospf)  	  ospf->external_origin = 0;  	} -      OSPF_TIMER_ON (ospf->t_router_lsa_update, -		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY); +      /* update router-lsa's for each area */ +      ospf_router_lsa_update (ospf);        /* update ospf_interface's */        for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) @@ -199,6 +199,7 @@ ospf_new (void)    new->spf_hold_multiplier = 1;    /* MaxAge init. */ +  new->maxage_delay = OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT;    new->maxage_lsa = list_new ();    new->t_maxage_walker =      thread_add_timer (master, ospf_lsa_maxage_walker, @@ -337,7 +338,7 @@ ospf_deferred_shutdown_check (struct ospf *ospf)            SET_FLAG (area->stub_router_state, OSPF_AREA_ADMIN_STUB_ROUTED);            if (!CHECK_FLAG (area->stub_router_state, OSPF_AREA_IS_STUB_ROUTED)) -              ospf_router_lsa_timer_add (area); +            ospf_router_lsa_update_area (area);          }        timeout = ospf->stub_router_shutdown_time;      } @@ -473,7 +474,6 @@ ospf_finish_final (struct ospf *ospf)    /* Cancel all timers. */    OSPF_TIMER_OFF (ospf->t_external_lsa); -  OSPF_TIMER_OFF (ospf->t_router_lsa_update);    OSPF_TIMER_OFF (ospf->t_spf_calc);    OSPF_TIMER_OFF (ospf->t_ase_calc);    OSPF_TIMER_OFF (ospf->t_maxage); @@ -631,7 +631,6 @@ ospf_area_free (struct ospf_area *area)      free (IMPORT_NAME (area));    /* Cancel timer. */ -  OSPF_TIMER_OFF (area->t_router_lsa_self);    OSPF_TIMER_OFF (area->t_stub_router);  #ifdef HAVE_OPAQUE_LSA    OSPF_TIMER_OFF (area->t_opaque_lsa_self); @@ -1041,7 +1040,7 @@ ospf_area_type_set (struct ospf_area *area, int type)        break;      } -  ospf_router_lsa_timer_add (area); +  ospf_router_lsa_update_area (area);    ospf_schedule_abr_task (area->ospf);  } @@ -1052,7 +1051,7 @@ ospf_area_shortcut_set (struct ospf *ospf, struct ospf_area *area, int mode)      return 0;    area->shortcut_configured = mode; -  ospf_router_lsa_timer_add (area); +  ospf_router_lsa_update_area (area);    ospf_schedule_abr_task (ospf);    ospf_area_check_free (ospf, area->area_id); @@ -1064,7 +1063,7 @@ int  ospf_area_shortcut_unset (struct ospf *ospf, struct ospf_area *area)  {    area->shortcut_configured = OSPF_SHORTCUT_DEFAULT; -  ospf_router_lsa_timer_add (area); +  ospf_router_lsa_update_area (area);    ospf_area_check_free (ospf, area->area_id);    ospf_schedule_abr_task (ospf); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 6eeaaf99..7a56d163 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -58,6 +58,7 @@  #endif  #define OSPF_MIN_LS_INTERVAL                     5  #define OSPF_MIN_LS_ARRIVAL                      1 +#define OSPF_LSA_INITIAL_AGE                     0	/* useful for debug */  #define OSPF_LSA_MAXAGE                       3600  #define OSPF_CHECK_AGE                         300  #define OSPF_LSA_MAXAGE_DIFF                   900 @@ -66,7 +67,6 @@  #define OSPF_INITIAL_SEQUENCE_NUMBER    0x80000001  #define OSPF_MAX_SEQUENCE_NUMBER        0x7fffffff -#define OSPF_LSA_MAXAGE_CHECK_INTERVAL          30  #define OSPF_NSSA_TRANS_STABLE_DEFAULT		40  #define OSPF_ALLSPFROUTERS              0xe0000005      /* 224.0.0.5 */ @@ -247,7 +247,6 @@ struct ospf    int redistribute;                     /* Num of redistributed protocols. */    /* Threads. */ -  struct thread *t_router_lsa_update;   /* router-LSA update timer. */    struct thread *t_abr_task;            /* ABR task timer. */    struct thread *t_asbr_check;          /* ASBR check timer. */    struct thread *t_distribute_update;   /* Distirbute list update timer. */ @@ -257,8 +256,13 @@ struct ospf  #ifdef HAVE_OPAQUE_LSA    struct thread *t_opaque_lsa_self;	/* Type-11 Opaque-LSAs origin event. */  #endif /* HAVE_OPAQUE_LSA */ + +#define OSFP_LSA_MAXAGE_REMOVE_DELAY_DEFAULT	60 +  unsigned int maxage_delay;		/* Delay on Maxage remover timer, sec */    struct thread *t_maxage;              /* MaxAge LSA remover timer. */ +#define OSPF_LSA_MAXAGE_CHECK_INTERVAL		30    struct thread *t_maxage_walker;       /* MaxAge LSA checking timer. */ +    struct thread *t_deferred_shutdown;	/* deferred/stub-router shutdown timer*/    struct thread *t_write; @@ -429,7 +433,6 @@ struct ospf_area    struct vertex *spf;    /* Threads. */ -  struct thread *t_router_lsa_self;/* Self-originated router-LSA timer. */    struct thread *t_stub_router;    /* Stub-router timer */  #ifdef HAVE_OPAQUE_LSA    struct thread *t_opaque_lsa_self;	/* Type-10 Opaque-LSAs origin. */ | 
