diff options
Diffstat (limited to 'ospfd')
-rw-r--r-- | ospfd/ospf_ase.c | 4 | ||||
-rw-r--r-- | ospfd/ospf_flood.c | 8 | ||||
-rw-r--r-- | ospfd/ospf_interface.c | 17 | ||||
-rw-r--r-- | ospfd/ospf_lsa.c | 135 | ||||
-rw-r--r-- | ospfd/ospf_lsa.h | 4 | ||||
-rw-r--r-- | ospfd/ospf_packet.c | 29 | ||||
-rw-r--r-- | ospfd/ospf_zebra.c | 2 |
7 files changed, 140 insertions, 59 deletions
diff --git a/ospfd/ospf_ase.c b/ospfd/ospf_ase.c index b60aa071..8eb7025c 100644 --- a/ospfd/ospf_ase.c +++ b/ospfd/ospf_ase.c @@ -642,6 +642,10 @@ ospf_ase_calculate_timer (struct thread *t) foreach_lsa (NSSA_LSDB (area), NULL, 0, ospf_ase_calculate_route); } + /* kevinm: And add the NSSA routes in ospf_top */ + foreach_lsa(NSSA_LSDB (ospf_top), NULL, 0, + ospf_ase_calculate_route); + #endif /* HAVE_NSSA */ /* Compare old and new external routing table and install the diff --git a/ospfd/ospf_flood.c b/ospfd/ospf_flood.c index bd33c345..00a4c644 100644 --- a/ospfd/ospf_flood.c +++ b/ospfd/ospf_flood.c @@ -622,6 +622,7 @@ ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa) { listnode node; int lsa_ack_flag; + struct as_external_lsa *extlsa; lsa_ack_flag = 0; @@ -646,6 +647,7 @@ ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa) { int continue_flag = 0; struct ospf_area *area = getdata (node); + struct in_addr fwd; listnode if_node; switch (area->external_routing) @@ -657,11 +659,13 @@ ospf_flood_through_as (struct ospf_neighbor *inbr, struct ospf_lsa *lsa) case OSPF_AREA_NSSA: /* Sending Type 5 or 7 into NSSA area */ #ifdef HAVE_NSSA /* Type-7, flood NSSA area */ - if (lsa->data->type == OSPF_AS_NSSA_LSA) + if (lsa->data->type == OSPF_AS_NSSA_LSA && + area == lsa->area) { /* We will send it. */ continue_flag = 0; - else + } else { continue_flag = 1; /* Skip this NSSA area for Type-5's et al */ + } break; #endif /* HAVE_NSSA */ diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index ddae9800..f0300273 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -257,7 +257,22 @@ ospf_if_cleanup (struct ospf_interface *oi) oi->nbr_self = ospf_nbr_new (oi); oi->nbr_self->state = NSM_TwoWay; oi->nbr_self->priority = OSPF_IF_PARAM (oi, priority); - oi->nbr_self->options = OSPF_OPTION_E; + + switch (oi->area->external_routing) + { + case OSPF_AREA_DEFAULT: + SET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); + break; + case OSPF_AREA_STUB: + UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); + break; +#ifdef HAVE_NSSA + case OSPF_AREA_NSSA: + UNSET_FLAG (oi->nbr_self->options, OSPF_OPTION_E); + SET_FLAG (oi->nbr_self->options, OSPF_OPTION_NP); + break; +#endif /* HAVE_NSSA */ + } 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 a4495e97..c2fade2d 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -253,6 +253,15 @@ ospf_lsa_dup (struct ospf_lsa *lsa) new->retransmit_counter = 0; new->data = ospf_lsa_data_dup (lsa->data); + /* kevinm: Clear the refresh_list, otherwise there are going + to be problems when we try to remove the LSA from the + queue (which it's not a member of.) + XXX: Should we add the LSA to the refresh_list queue? */ + new->refresh_list = -1; + + if (IS_DEBUG_OSPF (lsa, LSA)) + zlog_info ("LSA: duplicated %p (new: %p)", lsa, new); + return new; } @@ -1420,12 +1429,14 @@ ospf_get_ip_from_ifp (struct ospf_interface *oi) /* Get 1st IP connection for Forward Addr */ struct in_addr -ospf_get_nssa_ip (void) +ospf_get_nssa_ip (struct ospf_area *area) { struct in_addr fwd; + struct in_addr best_default; listnode n1; fwd.s_addr = 0; + best_default.s_addr = 0; for (n1 = listhead (ospf_top->oiflist); n1; nextnode (n1)) @@ -1434,9 +1445,16 @@ ospf_get_nssa_ip (void) if (if_is_operative (oi->ifp)) if (oi->area->external_routing == OSPF_AREA_NSSA) - if (oi->address && oi->address->family == AF_INET) - return (oi->address->u.prefix4 ); + if (oi->address && oi->address->family == AF_INET) { + if (best_default.s_addr == 0) { + best_default = oi->address->u.prefix4; + } + if (oi->area == area) + return (oi->address->u.prefix4); + } } + if (best_default.s_addr != 0) + return best_default; return fwd; } @@ -1628,7 +1646,8 @@ void ospf_install_flood_nssa (struct ospf_lsa *lsa, struct external_info *ei) { struct ospf_lsa *new2; - struct as_external_lsa *extlsa; + struct as_external_lsa *extlsa, *newextlsa; + listnode node; /* NSSA Originate or Refresh (If anyNSSA) @@ -1645,54 +1664,61 @@ ospf_install_flood_nssa (struct ospf_lsa *lsa, struct external_info *ei) Later, ABR_TASK and P-bit will scan Type-7 LSDB and translate to Type-5's to non-NSSA Areas. (it will also attempt a re-install) */ - /* make lsa duplicate, lock=1 */ - new2 = ospf_lsa_dup(lsa); - - /* make type-7 */ - new2->data->type = OSPF_AS_NSSA_LSA; - - /* set P-bit if not ABR */ - if (! OSPF_IS_ABR) - { - SET_FLAG(new2->data->options, OSPF_OPTION_NP); - - /* set non-zero FWD ADDR - - draft-ietf-ospf-nssa-update-09.txt - - if the network between the NSSA AS boundary router and the - adjacent AS is advertised into OSPF as an internal OSPF route, - the forwarding address should be the next op address as is cu - currently done with type-5 LSAs. If the intervening network is - not adversited into OSPF as an internal OSPF route and the - type-7 LSA's P-bit is set a forwarding address should be - selected from one of the router's active OSPF inteface addresses - which belong to the NSSA. If no such addresses exist, then - no type-7 LSA's with the P-bit set should originate from this - router. */ + for (node = listhead (ospf_top->areas); node; nextnode (node)) { + + struct ospf_area *area = getdata (node); - extlsa = (struct as_external_lsa *)(lsa->data); + /* make lsa duplicate, lock=1 */ + new2 = ospf_lsa_dup(lsa); - if (extlsa->e[0].fwd_addr.s_addr == 0) - extlsa->e[0].fwd_addr = ospf_get_nssa_ip(); /* this NSSA area in ifp */ + /* make type-7 */ + new2->data->type = OSPF_AS_NSSA_LSA; - if (IS_DEBUG_OSPF_NSSA) - if (extlsa->e[0].fwd_addr.s_addr == 0) - { - zlog_info ("LSA[Type-7]: Could not build FWD-ADDR"); - ospf_lsa_discard(new2); - return; - } - } + /* set P-bit if not ABR */ + if (! OSPF_IS_ABR) + { + SET_FLAG(new2->data->options, OSPF_OPTION_NP); + + /* set non-zero FWD ADDR + + draft-ietf-ospf-nssa-update-09.txt + + if the network between the NSSA AS boundary router and the + adjacent AS is advertised into OSPF as an internal OSPF route, + the forwarding address should be the next op address as is cu + currently done with type-5 LSAs. If the intervening network is + not adversited into OSPF as an internal OSPF route and the + type-7 LSA's P-bit is set a forwarding address should be + selected from one of the router's active OSPF inteface addresses + which belong to the NSSA. If no such addresses exist, then + no type-7 LSA's with the P-bit set should originate from this + router. */ + + /* not updating lsa anymore, just new2 */ + extlsa = (struct as_external_lsa *)(new2->data); + + if (extlsa->e[0].fwd_addr.s_addr == 0) + /* this NSSA area in ifp */ + extlsa->e[0].fwd_addr = ospf_get_nssa_ip(area); + + if (IS_DEBUG_OSPF_NSSA) + if (extlsa->e[0].fwd_addr.s_addr == 0) + { + zlog_info ("LSA[Type-7]: Could not build FWD-ADDR"); + ospf_lsa_discard(new2); + return; + } + } - /* Re-calculate checksum. */ - ospf_lsa_checksum (new2->data); + /* Re-calculate checksum. */ + ospf_lsa_checksum (new2->data); - /* install also as Type-7 */ - ospf_lsa_install (NULL, new2); /* Remove Old, Lock New = 2 */ + /* install also as Type-7 */ + ospf_lsa_install (NULL, new2); /* Remove Old, Lock New = 2 */ - /* will send each copy, lock=2+n */ - ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */ + /* will send each copy, lock=2+n */ + ospf_flood_through_as (NULL, new2); /* all attached NSSA's, no AS/STUBs */ + } /* last send, lock=2 LSA is now permanent in Type-7 LSDB */ /* It has the same ID as it's Type-5 Counter-Part */ @@ -2257,6 +2283,13 @@ ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa) /* Set LSDB. */ switch (lsa->data->type) { + /* kevinm */ + case OSPF_AS_NSSA_LSA: + if (lsa->area) + lsdb = lsa->area->lsdb; + else + lsdb = ospf_top->lsdb; + break; case OSPF_AS_EXTERNAL_LSA: #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA: @@ -2370,6 +2403,9 @@ ospf_lsa_install (struct ospf_interface *oi, struct ospf_lsa *lsa) #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA: #endif /* HAVE_OPAQUE_LSA */ +#ifdef HAVE_NSSA + case OSPF_AS_NSSA_LSA: +#endif zlog_info ("LSA[%s]: Install %s", dump_lsa_key (new), LOOKUP (ospf_lsa_type_msg, new->data->type)); @@ -2579,6 +2615,9 @@ ospf_lsa_maxage_walker_remover (struct ospf_lsa *lsa, void *p_arg, int int_arg) #ifdef HAVE_OPAQUE_LSA case OSPF_OPAQUE_AS_LSA: #endif /* HAVE_OPAQUE_LSA */ +#ifdef HAVE_NSSA + case OSPF_AS_NSSA_LSA: +#endif ospf_ase_incremental_update (lsa, ospf_top); break; default: @@ -3260,6 +3299,8 @@ ospf_refresher_register_lsa (struct ospf *top, struct ospf_lsa *lsa) top->lsa_refresh_queue.qs[index] = list_new (); listnode_add (top->lsa_refresh_queue.qs[index], ospf_lsa_lock (lsa)); lsa->refresh_list = index; + if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) + zlog_info ("LSA[Refresh]: ospf_refresher_register_lsa(): setting refresh_list on lsa %p (slod %d)", lsa, index); } } @@ -3324,7 +3365,7 @@ ospf_lsa_refresh_walker (struct thread *t) next = node->next; if (IS_DEBUG_OSPF (lsa, LSA_REFRESH)) - zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p", lsa); + zlog_info ("LSA[Refresh]: ospf_lsa_refresh_walker(): refresh lsa %p (slot %d)", lsa, i); list_delete_node (refresh_list, node); ospf_lsa_unlock (lsa); diff --git a/ospfd/ospf_lsa.h b/ospfd/ospf_lsa.h index 02fbe704..4303bcd6 100644 --- a/ospfd/ospf_lsa.h +++ b/ospfd/ospf_lsa.h @@ -323,4 +323,8 @@ int is_prefix_default (struct prefix_ipv4 *); int metric_type (u_char); int metric_value (u_char); +#ifdef HAVE_NSSA +struct in_addr ospf_get_nssa_ip (struct ospf_area *); +#endif + #endif /* _ZEBRA_OSPF_LSA_H */ diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index d2338fff..ceb6d845 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -616,16 +616,22 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh, /* increment statistics. */ oi->hello_in++; + zlog_info ("Packet %s [Hello:RECV]: oi hello cnt %d", + inet_ntoa (ospfh->router_id), oi->hello_in); hello = (struct ospf_hello *) STREAM_PNT (s); /* If Hello is myself, silently discard. */ - if (IPV4_ADDR_SAME (&ospfh->router_id, &ospf_top->router_id)) + if (IPV4_ADDR_SAME (&ospfh->router_id, &ospf_top->router_id)) { + zlog_info ("Packet %s [Hello:RECV]: router_id matches our router id"); return; + } /* If incoming interface is passive one, ignore Hello. */ - if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) + if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) { + zlog_info ("Packet %s [HELLO:RECV]: oi is passive"); return; + } /* get neighbor prefix. */ p.family = AF_INET; @@ -2217,8 +2223,8 @@ ospf_read (struct thread *thread) /* IP Header dump. */ /* - if (ospf_debug_packet & OSPF_DEBUG_RECV) - ospf_ip_header_dump (ibuf); + if (ospf_debug_packet & OSPF_DEBUG_RECV)*/ + ospf_ip_header_dump (ibuf); /* */ /* Self-originated packet should be discarded silently. */ if (ospf_if_lookup_by_local_addr (NULL, iph->ip_src)) @@ -2265,8 +2271,8 @@ ospf_read (struct thread *thread) } /* Show debug receiving packet. */ - if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) - { + /* if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, RECV)) + {*/ if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL)) { zlog_info ("-----------------------------------------------------"); @@ -2281,7 +2287,7 @@ ospf_read (struct thread *thread) if (IS_DEBUG_OSPF_PACKET (ospfh->type - 1, DETAIL)) zlog_info ("-----------------------------------------------------"); - } + /* }*/ /* Some header verification. */ ret = ospf_verify_header (ibuf, oi, iph, ospfh); @@ -2453,7 +2459,11 @@ ospf_make_hello (struct ospf_interface *oi, struct stream *s) /* Add neighbor seen. */ for (rn = route_top (oi->nbrs); rn; rn = route_next (rn)) - if ((nbr = rn->info) != NULL) + if ((nbr = rn->info) != NULL) { + zlog_info("make_hello: nbr %s, state %d", + inet_ntoa(nbr->router_id), + nbr->state); + /* ignore 0.0.0.0 node. */ if (nbr->router_id.s_addr != 0) if (nbr->state != NSM_Attempt) @@ -2466,11 +2476,12 @@ ospf_make_hello (struct ospf_interface *oi, struct stream *s) if (nbr->d_router.s_addr != 0 && IPV4_ADDR_SAME (&nbr->d_router, &oi->address->u.prefix4) && IPV4_ADDR_SAME (&nbr->bd_router, &oi->address->u.prefix4)) - flag = 1; + flag = 0; stream_put_ipv4 (s, nbr->router_id.s_addr); length += 4; } + } /* Let neighbor generate BackupSeen. */ if (flag == 1) diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 72ffe76f..a8e1630e 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -66,6 +66,8 @@ ospf_interface_add (int command, struct zclient *zclient, zebra_size_t length) zlog_info ("Zebra: interface add %s index %d flags %ld metric %d mtu %d", ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); + assert(ifp->info); + if (!OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), type)) { SET_IF_PARAM (IF_DEF_PARAMS (ifp), type); |