diff options
author | Joakim Tjernlund <Joakim.Tjernlund@transmode.se> | 2009-08-07 13:48:15 +0200 |
---|---|---|
committer | Donald Sharp <sharpd@cumulusnetwroks.com> | 2016-08-18 13:35:39 +0200 |
commit | 953cde65c5a35c8762f5858ace216b768814d01c (patch) | |
tree | acf13ca7ac43984b9215b0006d4d16fac2c281c3 /ospfd | |
parent | Revert "per-interface ospf enable and area set command." (diff) | |
download | frr-953cde65c5a35c8762f5858ace216b768814d01c.tar.xz frr-953cde65c5a35c8762f5858ace216b768814d01c.zip |
ospfd: Impl. per interface 'ip ospf area' command
Use with interface command:
interface ppp0
ip ospf area 0.0.0.0
This will enable OSPF on ppp0 with area 0.0.0.0
Remove with "no ip ospf area"
* ospf_vty.c: add "ip ospf area (A.B.C.D|<0-4294967295>)" interface command
* ospfd.c: (ospf_interface_{un,}set) new helper function to enable/disable
OSPF on a specific interface.
(ospf_if_update) 2 possible paths now to deal with interface updates.
Acked-by: Donald Sharp <sharpd@cumulusnetworks.com>
[DL: this restores the tree to deccaf9...]
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_interface.h | 2 | ||||
-rw-r--r-- | ospfd/ospf_vty.c | 27 | ||||
-rw-r--r-- | ospfd/ospfd.c | 184 | ||||
-rw-r--r-- | ospfd/ospfd.h | 5 |
4 files changed, 198 insertions, 20 deletions
diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 988493a21..7a74288bf 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -47,6 +47,8 @@ struct ospf_if_params DECLARE_IF_PARAM (u_int32_t, retransmit_interval); /* Retransmission Interval */ DECLARE_IF_PARAM (u_char, passive_interface); /* OSPF Interface is passive: no sending or receiving (no need to join multicast groups) */ DECLARE_IF_PARAM (u_char, priority); /* OSPF Interface priority */ + /* Enable OSPF on this interface with area if_area */ + DECLARE_IF_PARAM (struct in_addr, if_area); DECLARE_IF_PARAM (u_char, type); /* type of interface */ #define OSPF_IF_ACTIVE 0 #define OSPF_IF_PASSIVE 1 diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index ea76856af..3022a316c 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -543,6 +543,13 @@ DEFUN (ospf_network_area, return CMD_WARNING; } + if (ospf->if_ospf_cli_count > 0) + { + vty_out (vty, "Please remove all ip ospf area x.x.x.x commands first.%s", + VTY_NEWLINE); + return CMD_WARNING; + } + /* Get network prefix and Area ID. */ VTY_GET_IPV4_PREFIX ("network prefix", p, argv[0]); VTY_GET_OSPF_AREA_ID (area_id, format, argv[1]); @@ -9403,6 +9410,18 @@ config_write_interface (struct vty *vty) vty_out (vty, "%s", VTY_NEWLINE); } + /* Area print. */ + 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); + else + vty_out (vty, " ip ospf area %s%s", + inet_ntoa (params->if_area), VTY_NEWLINE); + + } + /* bfd print. */ ospf_bfd_write_config(vty, params); @@ -10133,6 +10152,14 @@ ospf_vty_if_init (void) install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_sec_addr_cmd); install_element (INTERFACE_NODE, &no_ip_ospf_transmit_delay_sec_cmd); + /* "ip ospf area" commands. */ + install_element (INTERFACE_NODE, &ip_ospf_area_cmd); + install_element (INTERFACE_NODE, &no_ip_ospf_area_cmd); + install_element (INTERFACE_NODE, &no_ip_ospf_area_val_cmd); + install_element (INTERFACE_NODE, &ip_ospf_instance_area_cmd); + install_element (INTERFACE_NODE, &no_ip_ospf_instance_area_cmd); + install_element (INTERFACE_NODE, &no_ip_ospf_instance_area_val_cmd); + /* These commands are compatibitliy for previous version. */ install_element (INTERFACE_NODE, &ospf_authentication_key_cmd); install_element (INTERFACE_NODE, &no_ospf_authentication_key_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index fb8490328..9d0e4b9e8 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -501,6 +501,7 @@ ospf_finish_final (struct ospf *ospf) struct route_node *rn; struct ospf_nbr_nbma *nbr_nbma; struct ospf_lsa *lsa; + struct interface *ifp; struct ospf_interface *oi; struct ospf_area *area; struct ospf_vl_data *vl_data; @@ -536,6 +537,16 @@ ospf_finish_final (struct ospf *ospf) list_delete (ospf->vlinks); + /* Remove any ospf interface config params */ + for (ALL_LIST_ELEMENTS_RO (vrf_iflist (VRF_DEFAULT), node, ifp)) + { + struct ospf_if_params *params; + + params = IF_DEF_PARAMS (ifp); + if (OSPF_IF_PARAM_CONFIGURED(params, if_area)) + UNSET_IF_PARAM (params, if_area); + } + /* Reset interface. */ for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) ospf_if_free (oi); @@ -838,6 +849,69 @@ 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) +{ + 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); + + /* 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; + + /* Add pseudo neighbor. */ + ospf_nbr_self_reset (oi, oi->ospf->router_id); + + ospf_area_add_if (oi->area, oi); + + return (oi); +} + +static void update_redistributed(struct ospf *ospf, int add_to_ospf) +{ + struct route_node *rn; + struct external_info *ei; + struct ospf_external *ext; + + if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT, 0)) + if ((ext = ospf_external_lookup(ZEBRA_ROUTE_CONNECT, 0)) && + EXTERNAL_INFO (ext)) + { + for (rn = route_top (EXTERNAL_INFO (ext)); + rn; rn = route_next (rn)) + { + if ((ei = rn->info) != NULL) + { + if (add_to_ospf) + { + if (ospf_external_info_find_lsa (ospf, &ei->p)) + if (!ospf_distribute_check_connected (ospf, ei)) + ospf_external_lsa_flush (ospf, ei->type, &ei->p, + ei->ifindex /*, ei->nexthop */); + } + else + { + if (!ospf_external_info_find_lsa (ospf, &ei->p)) + if (ospf_distribute_check_connected (ospf, ei)) + ospf_external_lsa_originate (ospf, ei); + } + } + } + } +} + /* Config network statement related functions. */ static struct ospf_network * @@ -867,7 +941,6 @@ ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p, struct ospf_network *network; struct ospf_area *area; struct route_node *rn; - struct external_info *ei; int ret = OSPF_AREA_ID_FORMAT_ADDRESS; rn = route_node_get (ospf->networks, (struct prefix *)p); @@ -885,15 +958,7 @@ ospf_network_set (struct ospf *ospf, struct prefix_ipv4 *p, ospf_network_run ((struct prefix *)p, area); /* Update connected redistribute. */ - if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) - if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)) - for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)); - rn; rn = route_next (rn)) - if ((ei = rn->info) != NULL) - if (ospf_external_info_find_lsa (ospf, &ei->p)) - if (!ospf_distribute_check_connected (ospf, ei)) - ospf_external_lsa_flush (ospf, ei->type, &ei->p, - ei->ifindex /*, ei->nexthop */); + update_redistributed(ospf, 1); /* interfaces possibly added */ ospf_area_check_free (ospf, area_id); @@ -906,7 +971,6 @@ 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; @@ -953,14 +1017,86 @@ ospf_network_unset (struct ospf *ospf, struct prefix_ipv4 *p, } /* Update connected redistribute. */ - if (ospf_is_type_redistributed (ZEBRA_ROUTE_CONNECT)) - if (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)) - for (rn = route_top (EXTERNAL_INFO (ZEBRA_ROUTE_CONNECT)); - rn; rn = route_next (rn)) - if ((ei = rn->info) != NULL) - if (!ospf_external_info_find_lsa (ospf, &ei->p)) - if (ospf_distribute_check_connected (ospf, ei)) - ospf_external_lsa_originate (ospf, ei); + update_redistributed(ospf, 0); /* interfaces possibly removed */ + ospf_area_check_free (ospf, area_id); + + return 1; +} + +int +ospf_interface_set (struct interface *ifp, struct in_addr area_id) +{ + struct ospf_area *area; + struct listnode *cnode; + struct connected *co; + struct ospf *ospf; + struct ospf_if_params *params; + struct ospf_interface *oi; + int ret = OSPF_AREA_ID_FORMAT_ADDRESS; + + 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, ret); + + 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; +} + +int +ospf_interface_unset (struct interface *ifp) +{ + 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; + + for (ALL_LIST_ELEMENTS (ospf->oiflist, node, nnode, oi)) + { + if (oi->type == OSPF_IFTYPE_VIRTUALLINK) + continue; + if (oi->ifp == ifp) ospf_if_free (oi); + } + + /* Update connected redistribute. */ + update_redistributed(ospf, 0); /* interfaces possibly removed */ + ospf_area_check_free (ospf, area_id); return 1; } @@ -1080,7 +1216,8 @@ 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 (); @@ -1096,6 +1233,13 @@ ospf_if_update (struct ospf *ospf, struct interface *ifp) area = ospf_area_get (ospf, network->area_id, network->format); 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); + } } void diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index 3d3c73156..5f0a7bf11 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -296,6 +296,9 @@ struct ospf /* Statistics for LSA used for new instantiation. */ u_int32_t rx_lsa_count; + /* Counter of "ip ospf area x.x.x.x" */ + u_int32_t if_ospf_cli_count; + struct route_table *distance_table; }; @@ -578,4 +581,6 @@ extern void ospf_snmp_init (void); extern void ospf_master_init (void); +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 */ |