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 *); |