diff options
| author | Jafar Al-Gharaibeh <jafar@atcorp.com> | 2009-08-27 16:51:42 +0100 | 
|---|---|---|
| committer | Jafar Al-Gharaibeh <jafar@atcorp.com> | 2017-06-28 17:06:53 -0500 | 
| commit | 52c62ab89461fac53ef2bdfcc6946c735bfd9951 (patch) | |
| tree | 53051adfaa3f339ae9d621afa5a02a8247195242 | |
| parent | 8ea37652c714edcd913d5dc02a0bfc5968fdc45e (diff) | |
ospfd: Bring in some OSPF useful changes that were lost during Quagga fork
  Several changes were made from the original patch to resolve conflicts
  and also to fix various issues that were discovered during testing. Below
  is the original commit message minus a few parts that correspond to code
  that was dropped during bug fixing.
  Signed-off-by: Jafar Al-Gharaibeh <jafar@atcorp.com>
  ospfd: Extend 'ip ospf area' to take address argument + rationalise ospf enable
* ospfd.c: (general) Clean up the whole running of OSPF on interfaces.
  (add_ospf_interface) taking (struct interface *) arg is pointless here.
  (ospf_is_ready) new helper.
  (ospf_network_run_subnet) Put all the code for choosing whether to enable
  OSPF on a subnet, and if so which area configuration to use, here. If a
  subnet should not be enabled, ensure an existing oi is freed.
  (ospf_network_run_interface) Just call run_subnet for all subnets on an
  interface.
  (ospf_network_run) Just call run_interface for all interfaces.
  (ospf_if_update) Just call run_interface for the given interface.
  (ospf_network_unset) Just call run_subnet for existing ois.
  (ospf_update_interface_area) helper: update area on an oi, or create it.
  (ospf_interface_set) renamed to ospf_interface_area_set for clarity.
  Ensures OSPF is created, then into if_update.
  (ospf_interface_unset) renamed to ospf_interface_area_unset and collapses
  down to simple loop to call run_subnet for all ois.
* ospf_interface.h: add a more general OSPF_IF_PARAM_IS_SET, which does the
  right thing and takes default config into account.
* doc/ospfd.texi: add 'ip ospf area' command.
  Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
  This patch has been part of Quagga since October 2015
  Orignial Author:    Paul Jakma <paul@quagga.net>
  Date:      Thu Aug 27 16:51:42 2009 +0100
| -rw-r--r-- | doc/ospfd.texi | 18 | ||||
| -rw-r--r-- | ospfd/ospf_interface.h | 11 | ||||
| -rw-r--r-- | ospfd/ospf_vty.c | 80 | ||||
| -rw-r--r-- | ospfd/ospfd.c | 330 | ||||
| -rw-r--r-- | ospfd/ospfd.h | 5 | 
5 files changed, 263 insertions, 181 deletions
diff --git a/doc/ospfd.texi b/doc/ospfd.texi index 7ff78e67cf..cc33211510 100644 --- a/doc/ospfd.texi +++ b/doc/ospfd.texi @@ -223,6 +223,7 @@ OSPF domain.  @deffnx {OSPF Command} {network @var{a.b.c.d/m} area @var{<0-4294967295>}} {}  @deffnx {OSPF Command} {no network @var{a.b.c.d/m} area @var{a.b.c.d}} {}  @deffnx {OSPF Command} {no network @var{a.b.c.d/m} area @var{<0-4294967295>}} {} +@anchor{OSPF network command}  This command specifies the OSPF enabled interface(s).  If the interface has  an address from range 192.168.1.0/24 then the command below enables ospf  on this interface so router can provide network information to the other @@ -246,6 +247,10 @@ Currently, if a peer prefix has been configured,  then we test whether the prefix in the network command contains  the destination prefix.  Otherwise, we test whether the network command prefix  contains the local address prefix of the interface.  + +In some cases it may be more convenient to enable OSPF on a per +interface/subnet basis (@pxref{OSPF ip ospf area command}). +  @end deffn  @node OSPF area @@ -413,6 +418,19 @@ settings will override any per-area authentication setting.  @node OSPF interface  @section OSPF interface +@deffn {Interface Command} {ip ospf area @var{AREA} [@var{ADDR}]} {}  +@deffnx {Interface Command} {no ip ospf area [@var{ADDR}]} {} +@anchor{OSPF ip ospf area command} + +Enable OSPF on the interface, optionally restricted to just the IP address +given by @var{ADDR}, putting it in the @var{AREA} area. Per interface area +settings take precedence to network commands (@pxref{OSPF network command}). + +If you have a lot of interfaces, and/or a lot of subnets, then enabling OSPF +via this command may result in a slight performance improvement. + +@end deffn +  @deffn {Interface Command} {ip ospf authentication-key @var{AUTH_KEY}} {}  @deffnx {Interface Command} {no ip ospf authentication-key} {}  Set OSPF authentication key to a simple password.  After setting @var{AUTH_KEY}, diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 8455d217e0..afb2820109 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -31,8 +31,17 @@  #define IF_DEF_PARAMS(I) (IF_OSPF_IF_INFO (I)->def_params)  #define IF_OIFS(I)  (IF_OSPF_IF_INFO (I)->oifs)  #define IF_OIFS_PARAMS(I) (IF_OSPF_IF_INFO (I)->params) -			     + +/* Despite the name, this macro probably is for specialist use only */  #define OSPF_IF_PARAM_CONFIGURED(S, P) ((S) && (S)->P##__config) + +/* Test whether an OSPF interface parameter is set, generally, given some + * existing ospf interface + */ +#define OSPF_IF_PARAM_IS_SET(O,P) \ +      (OSPF_IF_PARAM_CONFIGURED ((O)->params, P) || \ +      OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp)->P)) +  #define OSPF_IF_PARAM(O, P) \          (OSPF_IF_PARAM_CONFIGURED ((O)->params, P)?\                          (O)->params->P:IF_DEF_PARAMS((O)->ifp)->P) diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index c831b13823..890a272b96 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -6967,26 +6967,31 @@ DEFUN_HIDDEN (no_ospf_transmit_delay,  DEFUN (ip_ospf_area,         ip_ospf_area_cmd, -       "ip ospf [(1-65535)] area <A.B.C.D|(0-4294967295)>", +       "ip ospf [(1-65535)] area <A.B.C.D|(0-4294967295)> [A.B.C.D]",         "IP Information\n"         "OSPF interface commands\n"         "Instance ID\n"         "Enable OSPF on this interface\n"         "OSPF area ID in IP address format\n" -       "OSPF area ID as a decimal value\n") +       "OSPF area ID as a decimal value\n" +       "Address of interface\n")  {    VTY_DECLVAR_CONTEXT(interface, ifp);    int idx = 0;    int format, ret;    struct in_addr area_id; -  struct ospf *ospf; +  struct in_addr addr;    struct ospf_if_params *params;    struct route_node *rn; +  struct ospf *ospf;    u_short instance = 0; +  char *areaid;    if (argv_find (argv, argc, "(1-65535)", &idx))      instance = strtol (argv[idx]->arg, NULL, 10); -  char *areaid = argv[argc - 1]->arg; + +  argv_find (argv, argc, "area", &idx); +  areaid = argv[idx + 1]->arg;    ospf = ospf_lookup_instance (instance);    if (ospf == NULL) @@ -6994,7 +6999,8 @@ DEFUN (ip_ospf_area,        params = IF_DEF_PARAMS (ifp);        if (OSPF_IF_PARAM_CONFIGURED(params, if_area))          { -          ospf_interface_unset (ifp); +	  UNSET_IF_PARAM (params, if_area); +          ospf_interface_area_unset (ifp);            ospf = ospf_lookup();            ospf->if_ospf_cli_count--;          } @@ -7023,6 +7029,21 @@ DEFUN (ip_ospf_area,        return CMD_WARNING;      } +  // Check if we have an address arg and proccess it +  if (argc == idx + 3) { +    VTY_GET_IPV4_ADDRESS("interface address", addr, argv[(idx+2)]->arg); +    // update/create address-level params +    params = ospf_get_if_params ((ifp), (addr)); +    if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) +      { +	vty_out (vty, +		 "Must remove previous area/address config before changing ospf area %s", +		 VTY_NEWLINE); +	return CMD_WARNING; +      } +    ospf_if_update_params ((ifp), (addr)); +  } +    for (rn = route_top (ospf->networks); rn; rn = route_next (rn))      {        if (rn->info != NULL) @@ -7033,7 +7054,9 @@ DEFUN (ip_ospf_area,      }    /* enable ospf on this interface with area_id */ -  ospf_interface_set (ifp, area_id); +  SET_IF_PARAM (params, if_area); +  params->if_area = area_id; +  ospf_interface_area_set (ifp);    ospf->if_ospf_cli_count++;    return CMD_SUCCESS; @@ -7041,35 +7064,56 @@ DEFUN (ip_ospf_area,  DEFUN (no_ip_ospf_area,         no_ip_ospf_area_cmd, -       "no ip ospf [(1-65535)] area [<A.B.C.D|(0-4294967295)>]", +       "no ip ospf [(1-65535)] area [<A.B.C.D|(0-4294967295)> [A.B.C.D]]",         NO_STR         "IP Information\n"         "OSPF interface commands\n"         "Instance ID\n"         "Disable OSPF on this interface\n"         "OSPF area ID in IP address format\n" -       "OSPF area ID as a decimal value\n") +       "OSPF area ID as a decimal value\n" +       "Address of interface\n")  {    VTY_DECLVAR_CONTEXT(interface, ifp);    int idx = 0;    struct ospf *ospf;    struct ospf_if_params *params;    u_short instance = 0; - +  struct in_addr addr; +      if (argv_find (argv, argc, "(1-65535)", &idx))      instance = strtol (argv[idx]->arg, NULL, 10);    if ((ospf = ospf_lookup_instance (instance)) == NULL)      return CMD_SUCCESS; -  params = IF_DEF_PARAMS (ifp); +  argv_find (argv, argc, "area", &idx); + +  // Check if we have an address arg and proccess it +  if (argc == idx + 3) { +    VTY_GET_IPV4_ADDRESS("interface address", addr, argv[(idx+2)]->arg); +    params = ospf_lookup_if_params (ifp, addr); +    if ((params) == NULL) +      return CMD_SUCCESS; +  } +  else +    params = IF_DEF_PARAMS (ifp); +    if (!OSPF_IF_PARAM_CONFIGURED(params, if_area))      { -      vty_out (vty, "Can't find specified interface area configuration.%s", VTY_NEWLINE); +      vty_out (vty, "Can't find specified interface area configuration.%s", +	       VTY_NEWLINE);        return CMD_WARNING; -    } +    }   -  ospf_interface_unset (ifp); +  UNSET_IF_PARAM (params, if_area); +  if (params != IF_DEF_PARAMS ((ifp))) +    { +      ospf_free_if_params ((ifp), (addr)); +      ospf_if_update_params ((ifp), (addr)); +    } +   +  ospf_interface_area_unset (ifp);    ospf->if_ospf_cli_count--;    return CMD_SUCCESS;  } @@ -8348,12 +8392,14 @@ config_write_interface (struct vty *vty)  	if (OSPF_IF_PARAM_CONFIGURED (params, if_area))  	  {  	    if (ospf->instance) -	      vty_out (vty, " ip ospf %d area %s%s", ospf->instance, -		       inet_ntoa (params->if_area), VTY_NEWLINE); +	      vty_out (vty, " ip ospf %d", ospf->instance);  	    else -	      vty_out (vty, " ip ospf area %s%s", -		       inet_ntoa (params->if_area), VTY_NEWLINE); +	      vty_out (vty, " ip ospf"); +	    vty_out (vty, " area %s", inet_ntoa (params->if_area)); +	    if (params != IF_DEF_PARAMS (ifp)) +	      vty_out (vty, " %s", inet_ntoa (rn->p.u.prefix4)); +            vty_out (vty, "%s", VTY_NEWLINE);  	  }  	/* bfd  print. */ diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 27cedc8705..67dfa22a5a 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -72,8 +72,10 @@ 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 prefix *, struct ospf_area *); -static void ospf_network_run_interface (struct prefix *, struct ospf_area *, -                                        struct interface *); +static void ospf_network_run_interface (struct ospf *, struct interface *,  +                                        struct prefix *, struct ospf_area *); +static void ospf_network_run_subnet (struct ospf *, struct connected *,  +                                     struct prefix *, struct ospf_area *);  static int ospf_network_match_iface (const struct connected *,  				     const struct prefix *);  static void ospf_finish_final (struct ospf *); @@ -331,6 +333,16 @@ ospf_lookup_instance (u_short instance)    return NULL;  } +static int +ospf_is_ready (struct ospf *ospf) +{ +  /* OSPF must be on and Router-ID must be configured. */ +  if (!ospf || ospf->router_id.s_addr == 0) +    return 0; +   +  return 1; +} +  static void  ospf_add (struct ospf *ospf)  { @@ -857,18 +869,19 @@ ospf_area_del_if (struct ospf_area *area, struct ospf_interface *oi)    listnode_delete (area->oiflist, oi);  } -static struct ospf_interface * -add_ospf_interface (struct interface *ifp, struct ospf_area *area, -                    struct connected *co) + + +static void +add_ospf_interface (struct connected *co, struct ospf_area *area)  {    struct ospf_interface *oi; -  oi = ospf_if_new (area->ospf, ifp, co->address); +  oi = ospf_if_new (area->ospf, co->ifp, co->address);    oi->connected = co;    oi->area = area; -  oi->params = ospf_lookup_if_params (ifp, oi->address->u.prefix4); +  oi->params = ospf_lookup_if_params (co->ifp, oi->address->u.prefix4);    oi->output_cost = ospf_if_get_output_cost (oi);    /* Relate ospf interface to ospf instance. */ @@ -877,14 +890,23 @@ add_ospf_interface (struct interface *ifp, struct ospf_area *area,    /* update network type as interface flag */    /* If network type is specified previously,       skip network type setting. */ -  oi->type = IF_DEF_PARAMS (ifp)->type; +  oi->type = IF_DEF_PARAMS (co->ifp)->type;    /* Add pseudo neighbor. */    ospf_nbr_self_reset (oi, oi->ospf->router_id);    ospf_area_add_if (oi->area, oi); -  return (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 (co->ifp))  +    ospf_if_up (oi); +  }  static void update_redistributed(struct ospf *ospf, int add_to_ospf) @@ -920,7 +942,6 @@ static void update_redistributed(struct ospf *ospf, int add_to_ospf)        }  } -  /* Config network statement related functions. */  static struct ospf_network *  ospf_network_new (struct in_addr area_id) @@ -999,30 +1020,7 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,    /* 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); -	  ospf_area_check_free (ospf, area_id); -	} +      ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);      }    /* Update connected redistribute. */ @@ -1032,81 +1030,48 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p,    return 1;  } -int -ospf_interface_set (struct interface *ifp, struct in_addr area_id) +/* Ensure there's an OSPF instance, as "ip ospf area" enabled OSPF means + * there might not be any 'router ospf' config. + * + * Otherwise, doesn't do anything different to ospf_if_update for now + */ +void +ospf_interface_area_set (struct interface *ifp)  { -  struct ospf_area *area; -  struct listnode *cnode; -  struct connected *co; -  struct ospf *ospf; -  struct ospf_if_params *params; -  struct ospf_interface *oi; - -  if ((ospf = ospf_lookup ()) == NULL) -    return 1; /* Ospf not ready yet */ - -  params = IF_DEF_PARAMS (ifp); - -  SET_IF_PARAM (params, if_area); -  params->if_area = area_id; - -  area = ospf_area_get (ospf, area_id); - -  for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) -    { -      if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) -        continue; - -      if (co->address->family == AF_INET) -        { -          oi = ospf_if_table_lookup(ifp, co->address); -          if (!oi) -            oi = add_ospf_interface(ifp, area, co); - -          /* 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); -        } -    } - -  /* Update connected redistribute. */ -  update_redistributed(ospf, 1); /* interface possibly added */ -  return 1; +  struct ospf *ospf = ospf_get(); +   +  ospf_if_update (ospf, ifp); +  /* if_update does a update_redistributed */ +   +  return;  } -int -ospf_interface_unset (struct interface *ifp) +void +ospf_interface_area_unset (struct interface *ifp)  { +  struct route_node *rn_oi;    struct ospf *ospf; -  struct ospf_if_params *params; -  struct listnode *node, *nnode; -  struct ospf_interface *oi; -  struct in_addr area_id;    ospf = ospf_lookup ();    if (!ospf) -    return 1; /* Ospf not ready yet */ - -  params = IF_DEF_PARAMS (ifp); -  UNSET_IF_PARAM (params, if_area); -  area_id = params->if_area; +    return; /* Ospf not ready yet */ -  for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) +  /* Find interfaces that may need to be removed. */ +  for (rn_oi = route_top (IF_OIFS (ifp)); rn_oi; rn_oi = route_next (rn_oi))      { +      struct ospf_interface *oi; + +      if ( (oi = rn_oi->info) == NULL) +	continue; +              if (oi->type == OSPF_IFTYPE_VIRTUALLINK) -        continue; -      if (oi->ifp == ifp) ospf_if_free (oi); +	continue; +       +      ospf_network_run_subnet (ospf, oi->connected, NULL, NULL);      }    /* Update connected redistribute. */    update_redistributed(ospf, 0); /* interfaces possibly removed */ -  ospf_area_check_free (ospf, area_id); - -  return 1;  }  /* Check whether interface matches given network @@ -1120,8 +1085,104 @@ ospf_network_match_iface(const struct connected *co, const struct prefix *net)  }  static void -ospf_network_run_interface (struct prefix *p, struct ospf_area *area, -                            struct interface *ifp) +ospf_update_interface_area (struct connected *co, struct ospf_area *area) +{ +  struct ospf_interface *oi = ospf_if_table_lookup (co->ifp, co->address); +   +  /* nothing to be done case */ +  if (oi && oi->area == area){ +    return; +  } +   +  if (oi)  +    ospf_if_free (oi); +   +  add_ospf_interface (co, area); +} + +/* Run OSPF for the given subnet, taking into account the following + * possible sources of area configuration, in the given order of preference: + * + * - Whether there is interface+address specific area configuration + * - Whether there is a default area for the interface + * - Whether there is an area given as a parameter. + * - If no specific network prefix/area is supplied, whether there's + *   a matching network configured. + */ +static void +ospf_network_run_subnet (struct ospf *ospf, struct connected *co, +                         struct prefix *p, struct ospf_area *given_area) +{ +  struct ospf_interface *oi; +  struct ospf_if_params *params; +  struct ospf_area *area = NULL; +  struct route_node *rn; +  int configed = 0; +   +  if (CHECK_FLAG(co->flags, ZEBRA_IFA_SECONDARY)) +    return; +   +  if (co->address->family != AF_INET) +    return; +   +  /* Try determine the appropriate area for this interface + address +   * Start by checking interface config  +   */ +  params = ospf_lookup_if_params (co->ifp, co->address->u.prefix4); +  if ( params && OSPF_IF_PARAM_CONFIGURED(params, if_area)) +    area = ospf_area_get (ospf, params->if_area); +  else{ +    params = IF_DEF_PARAMS (co->ifp); +    if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) +      area = ospf_area_get (ospf, params->if_area); +    } + +  /* If we've found an interface and/or addr specific area, then we're +   * done +   */ +  if (area) +    { +      ospf_update_interface_area (co, area); +      return; +    } +   +  /* Otherwise, only remaining possibility is a matching network statement */ +  if (p) +    { +      assert (given_area != NULL); +       +      /* Which either was supplied as a parameter.. (e.g. cause a new +       * network/area was just added).. +       */ +      if (p->family == co->address->family  +          && ospf_network_match_iface (co, p)) +        ospf_update_interface_area (co, given_area); +       +      return; +    } +   +  /* Else we have to search the existing network/area config to see +   * if any match.. +   */ +  for (rn = route_top (ospf->networks); rn; rn = route_next (rn)) +    if (rn->info != NULL +        && ospf_network_match_iface (co, &rn->p)) +      { +        struct ospf_network *network = (struct ospf_network *) rn->info; +        area = ospf_area_get (ospf, network->area_id); +        ospf_update_interface_area (co, area); +        configed = 1; +      } +   +  /* If the subnet isn't in any area, deconfigure */ +  if (!configed && (oi = ospf_if_table_lookup (co->ifp, co->address))) +    ospf_if_free (oi); +} + +static void +ospf_network_run_interface (struct ospf *ospf, struct interface *ifp, +                            struct prefix *p, +                            struct ospf_area *given_area)  {    struct listnode *cnode;    struct connected *co; @@ -1129,51 +1190,14 @@ ospf_network_run_interface (struct prefix *p, struct ospf_area *area,    if (memcmp (ifp->name, "VLINK", 5) == 0)      return; +  /* Network prefix without area is nonsensical */ +  if (p) +    assert (given_area != NULL); +      /* if interface prefix is match specified prefix,       then create socket and join multicast group. */    for (ALL_LIST_ELEMENTS_RO (ifp->connected, cnode, co)) -    { - -      if (CHECK_FLAG(co->flags,ZEBRA_IFA_SECONDARY)) -        continue; - -      if (p->family == co->address->family  -	  && ! ospf_if_table_lookup(ifp, co->address) -          && 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, oi->ospf->router_id); - -            /* 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); -          } -    } +    ospf_network_run_subnet (ospf, co, p, given_area);    }  static void @@ -1188,7 +1212,7 @@ ospf_network_run (struct prefix *p, struct ospf_area *area)    /* Get target interface. */    for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) -    ospf_network_run_interface (p, area, ifp); +    ospf_network_run_interface (area->ospf, ifp, p, area);  }  void @@ -1221,33 +1245,17 @@ ospf_ls_upd_queue_empty (struct ospf_interface *oi)  void  ospf_if_update (struct ospf *ospf, struct interface *ifp)  { -  struct route_node *rn; -  struct ospf_network *network; -  struct ospf_area *area; -  struct ospf_if_params *params; -    if (!ospf)      ospf = ospf_lookup (); -  /* OSPF must be on and Router-ID must be configured. */ -  if (!ospf || ospf->router_id.s_addr == 0) +  /* OSPF must be ready. */ +  if (!ospf_is_ready (ospf))      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); -        ospf_network_run_interface (&rn->p, area, ifp); -      } - -  /* create oif for any new co */ -  params = IF_DEF_PARAMS (ifp); -  if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) -    { -      ospf_interface_set (ifp, params->if_area); -    } +  ospf_network_run_interface (ospf, ifp, NULL, NULL); +   +  /* Update connected redistribute. */ +  update_redistributed(ospf, 1);  }  void diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 822a8039b0..b93f13728a 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -558,10 +558,11 @@ extern struct ospf_area *ospf_area_lookup_by_area_id (struct ospf *,  extern void ospf_area_add_if (struct ospf_area *, struct ospf_interface *);  extern void ospf_area_del_if (struct ospf_area *, struct ospf_interface *); +extern void ospf_interface_area_set (struct interface *); +extern void ospf_interface_area_unset (struct interface *); +  extern void ospf_route_map_init (void);  extern void ospf_master_init (struct thread_master *master); -extern int ospf_interface_set (struct interface *ifp, struct in_addr area_id); -extern int ospf_interface_unset (struct interface *ifp);  #endif /* _ZEBRA_OSPFD_H */  | 
