diff options
Diffstat (limited to 'ospfd')
| -rw-r--r-- | ospfd/ospf_packet.c | 20 | ||||
| -rw-r--r-- | ospfd/ospf_route.c | 18 | ||||
| -rw-r--r-- | ospfd/ospf_route.h | 3 | ||||
| -rw-r--r-- | ospfd/ospf_snmp.c | 4 | ||||
| -rw-r--r-- | ospfd/ospf_spf.c | 20 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 2 | ||||
| -rw-r--r-- | ospfd/ospf_zebra.c | 15 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 221 | ||||
| -rw-r--r-- | ospfd/ospfd.h | 2 | 
9 files changed, 168 insertions, 137 deletions
diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index a778a50b..ed342e7f 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -3151,7 +3151,10 @@ ospf_db_desc_send (struct ospf_neighbor *nbr)    op->length = length;    /* Decide destination address. */ -  op->dst = nbr->address.u.prefix4; +  if (oi->type == OSPF_IFTYPE_POINTOPOINT)  +    op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); +  else +    op->dst = nbr->address.u.prefix4;    /* Add packet to the interface output queue. */    ospf_packet_add (oi, op); @@ -3210,7 +3213,10 @@ ospf_ls_req_send (struct ospf_neighbor *nbr)    op->length = length;    /* Decide destination address. */ -  op->dst = nbr->address.u.prefix4; +  if (oi->type == OSPF_IFTYPE_POINTOPOINT)  +    op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); +  else +    op->dst = nbr->address.u.prefix4;    /* Add packet to the interface output queue. */    ospf_packet_add (oi, op); @@ -3326,7 +3332,10 @@ ospf_ls_upd_queue_send (struct ospf_interface *oi, struct list *update,    op->length = length;    /* Decide destination address. */ -  op->dst.s_addr = addr.s_addr; +  if (oi->type == OSPF_IFTYPE_POINTOPOINT)  +    op->dst.s_addr = htonl (OSPF_ALLSPFROUTERS); +  else +    op->dst.s_addr = addr.s_addr;    /* Add packet to the interface output queue. */    ospf_packet_add (oi, op); @@ -3403,13 +3412,12 @@ ospf_ls_upd_send (struct ospf_neighbor *nbr, struct list *update, int flag)    /* Decide destination address. */    if (oi->type == OSPF_IFTYPE_VIRTUALLINK)      p.prefix = oi->vl_data->peer_addr; +  else if (oi->type == OSPF_IFTYPE_POINTOPOINT)  +     p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);    else if (flag == OSPF_SEND_PACKET_DIRECT)       p.prefix = nbr->address.u.prefix4;    else if (oi->state == ISM_DR || oi->state == ISM_Backup)       p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS); -  else if ((oi->type == OSPF_IFTYPE_POINTOPOINT)  -	   && (flag == OSPF_SEND_PACKET_INDIRECT)) -     p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);    else if (oi->type == OSPF_IFTYPE_POINTOMULTIPOINT)       p.prefix.s_addr = htonl (OSPF_ALLSPFROUTERS);    else diff --git a/ospfd/ospf_route.c b/ospfd/ospf_route.c index 3a1fa999..50fba750 100644 --- a/ospfd/ospf_route.c +++ b/ospfd/ospf_route.c @@ -481,7 +481,8 @@ ospf_intra_add_transit (struct route_table *rt, struct vertex *v,  /* RFC2328 16.1. second stage. */  void  ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link, -		     struct vertex *v, struct ospf_area *area) +		     struct vertex *v, struct ospf_area *area, +		     int parent_is_root)  {    u_int32_t cost;    struct route_node *rn; @@ -514,7 +515,20 @@ ospf_intra_add_stub (struct route_table *rt, struct router_lsa_link *link,    if (IS_DEBUG_OSPF_EVENT)      zlog_debug ("ospf_intra_add_stub(): calculated cost is %d + %d = %d",   	       v->distance, ntohs(link->m[0].metric), cost); - +   +  /* PtP links with /32 masks adds host routes to remote, directly +   * connected hosts, see RFC 2328, 12.4.1.1, Option 1. +   * Such routes can just be ignored for the sake of tidyness. +   */ +  if (parent_is_root && link->link_data.s_addr == 0xffffffff && +      ospf_if_lookup_by_local_addr (area->ospf, NULL, link->link_id)) +    { +      if (IS_DEBUG_OSPF_EVENT) +        zlog_debug ("%s: ignoring host route %s/32 to self.", +                    __func__, inet_ntoa (link->link_id)); +      return; +    } +      rn = route_node_get (rt, (struct prefix *) &p);    /* Lookup current routing table. */ diff --git a/ospfd/ospf_route.h b/ospfd/ospf_route.h index 351e014d..0d37436d 100644 --- a/ospfd/ospf_route.h +++ b/ospfd/ospf_route.h @@ -140,7 +140,8 @@ extern void ospf_intra_add_transit (struct route_table *, struct vertex *,  extern void ospf_intra_add_stub (struct route_table *,  				 struct router_lsa_link *, struct vertex *, -				 struct ospf_area *); +				 struct ospf_area *, +				 int parent_is_root);  extern int ospf_route_cmp (struct ospf *, struct ospf_route *,  			   struct ospf_route *); diff --git a/ospfd/ospf_snmp.c b/ospfd/ospf_snmp.c index 6e972605..e6ce1f01 100644 --- a/ospfd/ospf_snmp.c +++ b/ospfd/ospf_snmp.c @@ -27,10 +27,12 @@  #ifdef HAVE_SNMP  #ifdef HAVE_NETSNMP  #include <net-snmp/net-snmp-config.h> -#endif +#include <net-snmp/net-snmp-includes.h> +#else  #include <asn1.h>  #include <snmp.h>  #include <snmp_impl.h> +#endif  #include "if.h"  #include "log.h" diff --git a/ospfd/ospf_spf.c b/ospfd/ospf_spf.c index 23d45dd6..82f0fedd 100644 --- a/ospfd/ospf_spf.c +++ b/ospfd/ospf_spf.c @@ -946,7 +946,8 @@ ospf_spf_dump (struct vertex *v, int i)  /* Second stage of SPF calculation. */  static void  ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v, -                        struct route_table *rt) +                        struct route_table *rt, +                        int parent_is_root)  {    struct listnode *cnode, *cnnode;    struct vertex *child; @@ -981,7 +982,7 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,                  (l->m[0].tos_count * ROUTER_LSA_TOS_SIZE));            if (l->m[0].type == LSA_LINK_TYPE_STUB) -            ospf_intra_add_stub (rt, l, v, area); +            ospf_intra_add_stub (rt, l, v, area, parent_is_root);          }      } @@ -991,8 +992,17 @@ ospf_spf_process_stubs (struct ospf_area *area, struct vertex *v,      {        if (CHECK_FLAG (child->flags, OSPF_VERTEX_PROCESSED))          continue; - -      ospf_spf_process_stubs (area, child, rt); +       +      /* the first level of routers connected to the root +       * should have 'parent_is_root' set, including those  +       * connected via a network vertex. +       */ +      if (area->spf == v) +        parent_is_root = 1; +      else if (v->type == OSPF_VERTEX_ROUTER) +        parent_is_root = 0; +         +      ospf_spf_process_stubs (area, child, rt, parent_is_root);        SET_FLAG (child->flags, OSPF_VERTEX_PROCESSED);      } @@ -1179,7 +1189,7 @@ ospf_spf_calculate (struct ospf_area *area, struct route_table *new_table,      }    /* Second stage of SPF calculation procedure's  */ -  ospf_spf_process_stubs (area, area->spf, new_table); +  ospf_spf_process_stubs (area, area->spf, new_table, 0);    /* Free candidate queue. */    pqueue_delete (candidate); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 5307b413..11f12c5c 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -3093,7 +3093,7 @@ DEFUN (show_ip_ospf_neighbor_all,         "Neighbor list\n"         "include down status neighbor\n")  { -  struct ospf *ospf = vty->index; +  struct ospf *ospf = ospf_lookup ();    struct listnode *node;    struct ospf_interface *oi; diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index f302d28d..e27f1394 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -87,7 +87,6 @@ static int  ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)  {    struct interface *ifp; -  struct ospf *ospf;    ifp = zebra_interface_add_read (zclient->ibuf); @@ -103,9 +102,7 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length)        IF_DEF_PARAMS (ifp)->type = ospf_default_iftype(ifp);      } -  ospf = ospf_lookup (); -  if (ospf != NULL) -    ospf_if_update (ospf); +  ospf_if_update (NULL, ifp);  #ifdef HAVE_SNMP    ospf_snmp_if_update (ifp); @@ -255,7 +252,6 @@ static int  ospf_interface_address_add (int command, struct zclient *zclient,                              zebra_size_t length)  { -  struct ospf *ospf;    struct connected *c;    c = zebra_interface_address_read (command, zclient->ibuf); @@ -270,9 +266,7 @@ ospf_interface_address_add (int command, struct zclient *zclient,        zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf);      } -  ospf = ospf_lookup (); -  if (ospf != NULL) -    ospf_if_update (ospf); +  ospf_if_update (NULL, c->ifp);  #ifdef HAVE_SNMP    ospf_snmp_if_update (c->ifp); @@ -285,7 +279,6 @@ static int  ospf_interface_address_delete (int command, struct zclient *zclient,                                 zebra_size_t length)  { -  struct ospf *ospf;    struct connected *c;    struct interface *ifp;    struct ospf_interface *oi; @@ -327,10 +320,6 @@ ospf_interface_address_delete (int command, struct zclient *zclient,    connected_free (c); -  ospf = ospf_lookup (); -  if (ospf != NULL) -    ospf_if_update (ospf); -    return 0;  } diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index a4c4fac3..32580ccf 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -68,7 +68,9 @@ extern struct in_addr router_id_zebra;  static void ospf_remove_vls_through_area (struct ospf *, struct ospf_area *);  static void ospf_network_free (struct ospf *, struct ospf_network *);  static void ospf_area_free (struct ospf_area *); -static void ospf_network_run (struct ospf *, struct prefix *, struct ospf_area *); +static void ospf_network_run (struct prefix *, struct ospf_area *); +static void ospf_network_run_interface (struct prefix *, struct ospf_area *, +                                        struct interface *);  static void ospf_finish_final (struct ospf *);  #define OSPF_EXTERNAL_LSA_ORIGINATE_DELAY 1 @@ -78,6 +80,7 @@ ospf_router_id_update (struct ospf *ospf)  {    struct in_addr router_id, router_id_old;    struct ospf_interface *oi; +  struct interface *ifp;    struct listnode *node;    if (IS_DEBUG_OSPF_EVENT) @@ -130,7 +133,8 @@ ospf_router_id_update (struct ospf *ospf)  		     ospf_router_lsa_update_timer, OSPF_LSA_UPDATE_DELAY);        /* update ospf_interface's */ -      ospf_if_update (ospf); +      for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) +        ospf_if_update (ospf, ifp);      }  } @@ -745,7 +749,7 @@ ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p,    area = ospf_area_get (ospf, area_id, ret);    /* Run network config now. */ -  ospf_network_run (ospf, (struct prefix *)p, area); +  ospf_network_run ((struct prefix *)p, area);    /* Update connected redistribute. */    if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) @@ -770,6 +774,8 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,    struct route_node *rn;    struct ospf_network *network;    struct external_info *ei; +  struct listnode *node, *nnode; +  struct ospf_interface *oi;    rn = route_node_lookup (ospf->networks, (struct prefix *)p);    if (rn == NULL) @@ -783,7 +789,31 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,    rn->info = NULL;    route_unlock_node (rn); -  ospf_if_update (ospf); +  /* Find interfaces that not configured already.  */ +  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) +    { +      int found = 0; +      struct connected *co = oi->connected; +       +      if (oi->type == OSPF_IFTYPE_VIRTUALLINK) +        continue; +       +      for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) +        { +          if (rn->info == NULL) +            continue; +           +          if (ospf_network_match_iface(co,&rn->p)) +            { +              found = 1; +              route_unlock_node (rn); +              break; +            } +        } + +      if (found == 0) +        ospf_if_free (oi); +    }    /* Update connected redistribute. */    if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) @@ -857,73 +887,78 @@ ospf_network_match_iface(struct connected *co, struct prefix *net)  }  void -ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area) +ospf_network_run_interface (struct prefix *p, struct ospf_area *area, +                            struct interface *ifp)  { -  struct interface *ifp; +  struct listnode *cnode;    struct connected *co; +   +  if (memcmp (ifp->name, "VLINK", 5) == 0) +    return; +   +  /* if interface prefix is match specified prefix, +     then create socket and join multicast group. */ +  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) +    { +      struct prefix *addr; +       +      if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) +        continue; + +      addr = CONNECTED_ID(co); + +      if (p->family == co->address->family  +          && ! ospf_if_is_configured (area->ospf, &(addr->u.prefix4)) +          && ospf_network_match_iface(co,p)) +        { +           struct ospf_interface *oi; +             +            oi = ospf_if_new (area->ospf, ifp, co->address); +            oi->connected = co; +             +            oi->area = area; + +            oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); +            oi->output_cost = ospf_if_get_output_cost (oi); +             +            /* Add pseudo neighbor. */ +            ospf_nbr_add_self (oi); + +            /* Relate ospf interface to ospf instance. */ +            oi->ospf = area->ospf; + +            /* update network type as interface flag */ +            /* If network type is specified previously, +               skip network type setting. */ +            oi->type = IF_DEF_PARAMS (ifp)->type; +             +            ospf_area_add_if (oi->area, oi); +             +            /* if router_id is not configured, dont bring up +             * interfaces. +             * ospf_router_id_update() will call ospf_if_update +             * whenever r-id is configured instead. +             */ +            if ((area->ospf->router_id.s_addr != 0) +                && if_is_operative (ifp))  +              ospf_if_up (oi); +          } +    } +} + +void +ospf_network_run (struct prefix *p, struct ospf_area *area) +{ +  struct interface *ifp;    struct listnode *node;    /* Schedule Router ID Update. */ -  if (ospf->router_id.s_addr == 0) -    ospf_router_id_update (ospf); +  if (area->ospf->router_id.s_addr == 0) +    ospf_router_id_update (area->ospf);    /* Get target interface. */    for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) -    { -      struct listnode *cnode; -       -      if (memcmp (ifp->name, "VLINK", 5) == 0) -	continue; -	 -      /* if interface prefix is match specified prefix, -	 then create socket and join multicast group. */ -      for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) -	{ -	  struct prefix *addr; -	   -          if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) -            continue; - -	  addr = CONNECTED_ID(co); - -	  if (p->family == co->address->family  -	      && ! ospf_if_is_configured (ospf, &(addr->u.prefix4)) -	      && ospf_network_match_iface(co,p)) -	    { -	       struct ospf_interface *oi; -		 -		oi = ospf_if_new (ospf, ifp, co->address); -		oi->connected = co; -		 -		oi->area = area; - -		oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); -		oi->output_cost = ospf_if_get_output_cost (oi); -		 -		/* Add pseudo neighbor. */ -		ospf_nbr_add_self (oi); - -		/* Relate ospf interface to ospf instance. */ -		oi->ospf = ospf; - -		/* update network type as interface flag */ -		/* If network type is specified previously, -		   skip network type setting. */ -		oi->type = IF_DEF_PARAMS (ifp)->type; -		 -		ospf_area_add_if (oi->area, oi); -		 -		/* if router_id is not configured, dont bring up -		 * interfaces. -                 * ospf_router_id_update() will call ospf_if_update -                 * whenever r-id is configured instead. -                 */ -		if ((ospf->router_id.s_addr != 0) -		    && if_is_operative (ifp))  -		  ospf_if_up (oi); -	      } -	} -    } +    ospf_network_run_interface (p, area, ifp);  }  void @@ -954,55 +989,27 @@ ospf_ls_upd_queue_empty (struct ospf_interface *oi)  }  void -ospf_if_update (struct ospf *ospf) +ospf_if_update (struct ospf *ospf, struct interface *ifp)  {    struct route_node *rn; -  struct listnode *node, *nnode;    struct ospf_network *network;    struct ospf_area *area; -  struct ospf_interface *oi; +   +  if (!ospf) +    ospf = ospf_lookup (); -  if (ospf != NULL) -    { -      /* Router-ID must be configured. */ -      if (ospf->router_id.s_addr == 0) -        return; -       -      /* Find interfaces that not configured already.  */ -      for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) -	{ -	  int found = 0; -	  struct connected *co = oi->connected; -	   -	  if (oi->type == OSPF_IFTYPE_VIRTUALLINK) -	    continue; -	   -	  for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) -	    { -	      if (rn->info == NULL) -		continue; -	       -	      if (ospf_network_match_iface(co,&rn->p)) -		{ -		  found = 1; -		  route_unlock_node (rn); -		  break; -		} -	    } - -	  if (found == 0) -	    ospf_if_free (oi); -	} -	 -      /* Run each interface. */ -      for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) -	if (rn->info != NULL) -	  { -	    network = (struct ospf_network *) rn->info; -	    area = ospf_area_get (ospf, network->area_id, network->format); -	    ospf_network_run (ospf, &rn->p, area); -	  } -    } +  /* Router-ID must be configured. */ +  if (ospf->router_id.s_addr == 0) +    return; +   +  /* Run each netowrk for this interface. */ +  for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) +    if (rn->info != NULL) +      { +        network = (struct ospf_network *) rn->info; +        area = ospf_area_get (ospf, network->area_id, network->format); +        ospf_network_run_interface (&rn->p, area, ifp); +      }  }  void diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index b6187111..6a60e86f 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -588,7 +588,7 @@ extern int ospf_nbr_nbma_poll_interval_set (struct ospf *, struct in_addr,  extern int ospf_nbr_nbma_poll_interval_unset (struct ospf *, struct in_addr);  extern void ospf_prefix_list_update (struct prefix_list *);  extern void ospf_init (void); -extern void ospf_if_update (struct ospf *); +extern void ospf_if_update (struct ospf *, struct interface *);  extern void ospf_ls_upd_queue_empty (struct ospf_interface *);  extern void ospf_terminate (void);  extern void ospf_nbr_nbma_if_update (struct ospf *, struct ospf_interface *);  | 
