From b5aeb4410ae3722a5f331850acbc84c39e3fcd9f Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Wed, 30 Aug 2006 18:47:37 +0000 Subject: [ospfd] Fix assertion in DB-exchange fix, hit by ogier-db-ex-opt commit 2006-08-28 Andy Gay * ospf_packet.c: (ospf_make_db_desc) Assert added with More-bit fixes does not hold up with addition of Ogier DB-Exchange optimisation, which can empty the db-summary list in between sent DD packets. Remove assert, update More-bit always when in Exchange. --- ospfd/ChangeLog | 8 ++++++++ ospfd/ospf_packet.c | 34 +++++++++++++--------------------- 2 files changed, 21 insertions(+), 21 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 0015ee6d..4da013a8 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,11 @@ +2006-08-28 Andy Gay + + * ospf_packet.c: (ospf_make_db_desc) Assert added with More-bit + fixes does not hold up with addition of Ogier DB-Exchange + optimisation, which can empty the db-summary list in between + sent DD packets. Remove assert, update More-bit always when + in Exchange. + 2006-08-27 J.J. Krabbendam * ospfd.c: (ospf_finish_final) default redistribute should be diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index d7a35645..91527395 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -2712,25 +2712,9 @@ ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr, /* Set DD Sequence Number. */ stream_putl (s, nbr->dd_seqnum); + /* shortcut unneeded walk of (empty) summary LSDBs */ if (ospf_db_summary_isempty (nbr)) - { - /* Sanity check: - * - * Must be here either: - * - Initial DBD (ospf_nsm.c) - * - M must be set - * or - * - finishing Exchange, and DB-Summary list empty - * - from ospf_db_desc_proc() - * - M must not be set - */ - if (nbr->state >= NSM_Exchange) - assert (!IS_SET_DD_M(nbr->dd_flags)); - else - assert (IS_SET_DD_M(nbr->dd_flags)); - - return length; - } + goto empty; /* Describe LSA Header from Database Summary List. */ lsdb = &nbr->db_sum; @@ -2785,9 +2769,17 @@ ospf_make_db_desc (struct ospf_interface *oi, struct ospf_neighbor *nbr, /* Update 'More' bit */ if (ospf_db_summary_isempty (nbr)) { - UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M); - /* Rewrite DD flags */ - stream_putc_at (s, pp, nbr->dd_flags); +empty: + if (nbr->state >= NSM_Exchange) + { + UNSET_FLAG (nbr->dd_flags, OSPF_DD_FLAG_M); + /* Rewrite DD flags */ + stream_putc_at (s, pp, nbr->dd_flags); + } + else + { + assert (IS_SET_DD_M(nbr->dd_flags)); + } } return length; } -- cgit v1.2.3 From ff7924f6c0437e2f3cc3710570414ae87a828724 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 4 Sep 2006 01:10:36 +0000 Subject: [bgpd] Add 'show ... neighbor .... prefix-counts' command 2006-09-03 Paul Jakma * bgp_route.c: Add 'show ... bgp ... prefix-count' commands, to provide detailed counts of prefixes for a peer. Informative, and should help pin down to pfxcnt drift problems. --- bgpd/ChangeLog | 7 ++ bgpd/bgp_route.c | 219 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 226 insertions(+) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index b27132c9..cb07c58d 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,10 @@ +2006-09-03 Paul Jakma + + * bgp_route.c: Add 'show ... bgp ... prefix-count' + commands, to provide detailed counts of prefixes for a peer. + Informative, and should help pin down to pfxcnt drift + problems. + 2006-08-27 Paul Jakma * bgp_advertise.c: (bgp_sync_delete) fix mtype in XFREE. diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5623cadc..40534a14 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8386,6 +8386,219 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, return peer; } +enum bgp_pcounts +{ + PCOUNT_ADJ_IN = 0, + PCOUNT_DAMPED, + PCOUNT_REMOVED, + PCOUNT_HISTORY, + PCOUNT_STALE, + PCOUNT_VALID, + PCOUNT_ALL, + PCOUNT_COUNTED, + PCOUNT_PFCNT, /* the figure we display to users */ + PCOUNT_MAX, +}; + +static const char *pcount_strs[] = +{ + [PCOUNT_ADJ_IN] = "Adj-in", + [PCOUNT_DAMPED] = "Damped", + [PCOUNT_REMOVED] = "Removed", + [PCOUNT_HISTORY] = "History", + [PCOUNT_STALE] = "Stale", + [PCOUNT_VALID] = "Valid", + [PCOUNT_ALL] = "All RIB", + [PCOUNT_COUNTED] = "PfxCt counted", + [PCOUNT_PFCNT] = "Useable", + [PCOUNT_MAX] = NULL, +}; + +static int +bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) +{ + struct bgp_node *rn; + struct bgp_info *ri; + unsigned int pcounts[PCOUNT_MAX], i; + + if (!peer || !peer->bgp || !peer->afc[afi][safi] + || !peer->bgp->rib[afi][safi]) + { + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + return CMD_WARNING; + } + + memset (&pcounts, 0, sizeof(pcounts)); + + for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; + rn = bgp_route_next (rn)) + { + struct bgp_adj_in *ain; + + for (ain = rn->adj_in; ain; ain = ain->next) + if (ain->peer == peer) + pcounts[PCOUNT_ADJ_IN]++; + +#define PFCNT_EXCLUDED (BGP_INFO_DAMPED|BGP_INFO_HISTORY|BGP_INFO_REMOVED|BGP_INFO_STALE) + for (ri = rn->info; ri; ri = ri->next) + { + char buf[SU_ADDRSTRLEN]; + + if (ri->peer != peer) + continue; + + pcounts[PCOUNT_ALL]++; + + if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)) + pcounts[PCOUNT_DAMPED]++; + if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) + pcounts[PCOUNT_HISTORY]++; + if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)) + pcounts[PCOUNT_REMOVED]++; + if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) + pcounts[PCOUNT_STALE]++; + if (CHECK_FLAG (ri->flags, BGP_INFO_VALID)) + pcounts[PCOUNT_VALID]++; + if (!CHECK_FLAG (ri->flags, PFCNT_EXCLUDED)) + pcounts[PCOUNT_PFCNT]++; + + if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED)) + { + pcounts[PCOUNT_COUNTED]++; + if (CHECK_FLAG (ri->flags, PFCNT_EXCLUDED)) + plog_warn (peer->log, + "%s [pcount] %s/%d is counted but flags 0x%x", + peer->host, + inet_ntop(rn->p.family, &rn->p.u.prefix, + buf, SU_ADDRSTRLEN), + rn->p.prefixlen, + ri->flags); + } + else + { + if (!CHECK_FLAG (ri->flags, PFCNT_EXCLUDED)) + plog_warn (peer->log, + "%s [pcount] %s/%d not counted but flags 0x%x", + peer->host, + inet_ntop(rn->p.family, &rn->p.u.prefix, + buf, SU_ADDRSTRLEN), + rn->p.prefixlen, + ri->flags); + } + } + } +#undef PFCNT_EXCLUDED + + vty_out (vty, "Prefix counts for %s, %s%s", + peer->host, afi_safi_print (afi, safi), VTY_NEWLINE); + vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE); + vty_out (vty, "%sCounts from RIB table walk:%s%s", + VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); + + for (i = 0; i < PCOUNT_MAX; i++) + vty_out (vty, "%20s: %-10d%s", pcount_strs[i], pcounts[i], VTY_NEWLINE); + + if (pcounts[PCOUNT_PFCNT] != peer->pcount[afi][safi]) + { + vty_out (vty, "%s [pcount] PfxCt drift!%s", + peer->host, VTY_NEWLINE); + vty_out (vty, "Please report this bug, with the above command output%s", + VTY_NEWLINE); + } + + return CMD_SUCCESS; +} + +DEFUN (show_ip_bgp_neighbor_prefix_counts, + show_ip_bgp_neighbor_prefix_counts_cmd, + "show ip bgp neighbors (A.B.C.D|X:X::X:X) prefix-counts", + SHOW_STR + IP_STR + BGP_STR + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Display detailed prefix count information\n") +{ + struct peer *peer; + + peer = peer_lookup_in_view (vty, NULL, argv[0]); + if (! peer) + return CMD_WARNING; + + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST); +} + +DEFUN (show_bgp_ipv6_neighbor_prefix_counts, + show_bgp_ipv6_neighbor_prefix_counts_cmd, + "show bgp ipv6 neighbors (A.B.C.D|X:X::X:X) prefix-counts", + SHOW_STR + BGP_STR + "Address family\n" + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Display detailed prefix count information\n") +{ + struct peer *peer; + + peer = peer_lookup_in_view (vty, NULL, argv[0]); + if (! peer) + return CMD_WARNING; + + return bgp_peer_counts (vty, peer, AFI_IP6, SAFI_UNICAST); +} + +DEFUN (show_ip_bgp_ipv4_neighbor_prefix_counts, + show_ip_bgp_ipv4_neighbor_prefix_counts_cmd, + "show ip bgp ipv4 (unicast|multicast) neighbors (A.B.C.D|X:X::X:X) prefix-counts", + SHOW_STR + IP_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Display detailed prefix count information\n") +{ + struct peer *peer; + + peer = peer_lookup_in_view (vty, NULL, argv[1]); + if (! peer) + return CMD_WARNING; + + if (strncmp (argv[0], "m", 1) == 0) + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MULTICAST); + + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_UNICAST); +} + +DEFUN (show_ip_bgp_vpnv4_neighbor_prefix_counts, + show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd, + "show ip bgp vpnv4 all neighbors (A.B.C.D|X:X::X:X) prefix-counts", + SHOW_STR + IP_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "Detailed information on TCP and BGP neighbor connections\n" + "Neighbor to display information about\n" + "Neighbor to display information about\n" + "Display detailed prefix count information\n") +{ + struct peer *peer; + + peer = peer_lookup_in_view (vty, NULL, argv[0]); + if (! peer) + return CMD_WARNING; + + return bgp_peer_counts (vty, peer, AFI_IP, SAFI_MPLS_VPN); +} + + static void show_adj_route (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi, int in) @@ -10666,7 +10879,13 @@ bgp_route_init () install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_cmd); install_element (ENABLE_NODE, &clear_ip_bgp_dampening_address_mask_cmd); + /* prefix count */ + install_element (ENABLE_NODE, &show_ip_bgp_neighbor_prefix_counts_cmd); + install_element (ENABLE_NODE, &show_ip_bgp_ipv4_neighbor_prefix_counts_cmd); + install_element (ENABLE_NODE, &show_ip_bgp_vpnv4_neighbor_prefix_counts_cmd); #ifdef HAVE_IPV6 + install_element (ENABLE_NODE, &show_bgp_ipv6_neighbor_prefix_counts_cmd); + /* New config IPv6 BGP commands. */ install_element (BGP_IPV6_NODE, &ipv6_bgp_network_cmd); install_element (BGP_IPV6_NODE, &ipv6_bgp_network_route_map_cmd); -- cgit v1.2.3 From 1a392d46db1917dfca2ddd06d7f0021396f8ecfa Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 7 Sep 2006 00:24:49 +0000 Subject: [bgpd] Handle pcount as flags are changed, fixing pcount issues 2006-09-06 Paul Jakma * (general) Squash any and all prefix-count issues by abstracting route flag changes, and maintaining count as and when flags are modified (rather than relying on explicit modifications of count being sprinkled in just the right places throughout the code). * bgp_route.c: (bgp_pcount_{dec,inc}rement) removed. (bgp_pcount_adjust) new, update prefix count as needed for a given route. (bgp_info_{uns,s}et_flag) set/unset a BGP_INFO route status flag, calling previous function when appropriate. (general) Update all set/unsets of flags to use previous. Remove pcount_{dec,inc}rement calls. No need to unset BGP_INFO_VALID in places where bgp_info_delete is called, it does that anyway. * bgp_{damp,nexthop}.c: Update to use bgp_info_{un,}set_flag. * bgp_route.h: Export bgp_info_{un,}set_flag. Add a 'meta' BGP_INFO flag, BGP_INFO_UNUSEABLE. Move BGP_INFO_HOLDDOWN macro to here from bgpd.h --- bgpd/ChangeLog | 21 +++++ bgpd/bgp_damp.c | 19 ++--- bgpd/bgp_nexthop.c | 4 +- bgpd/bgp_route.c | 219 +++++++++++++++++++++++++++-------------------------- bgpd/bgp_route.h | 13 ++++ bgpd/bgpd.h | 7 -- 6 files changed, 157 insertions(+), 126 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index cb07c58d..7de02cf5 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,24 @@ +2006-09-06 Paul Jakma + + * (general) Squash any and all prefix-count issues by + abstracting route flag changes, and maintaining count as and + when flags are modified (rather than relying on explicit + modifications of count being sprinkled in just the right + places throughout the code). + * bgp_route.c: (bgp_pcount_{dec,inc}rement) removed. + (bgp_pcount_adjust) new, update prefix count as + needed for a given route. + (bgp_info_{uns,s}et_flag) set/unset a BGP_INFO route status + flag, calling previous function when appropriate. + (general) Update all set/unsets of flags to use previous. + Remove pcount_{dec,inc}rement calls. + No need to unset BGP_INFO_VALID in places where + bgp_info_delete is called, it does that anyway. + * bgp_{damp,nexthop}.c: Update to use bgp_info_{un,}set_flag. + * bgp_route.h: Export bgp_info_{un,}set_flag. + Add a 'meta' BGP_INFO flag, BGP_INFO_UNUSEABLE. + Move BGP_INFO_HOLDDOWN macro to here from bgpd.h + 2006-09-03 Paul Jakma * bgp_route.c: Add 'show ... bgp ... prefix-count' diff --git a/bgpd/bgp_damp.c b/bgpd/bgp_damp.c index a2163a4f..8ba39b65 100644 --- a/bgpd/bgp_damp.c +++ b/bgpd/bgp_damp.c @@ -148,12 +148,12 @@ bgp_reuse_timer (struct thread *t) if (bdi->penalty < damp->reuse_limit) { /* Reuse the route. */ - UNSET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED); + bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_DAMPED); bdi->suppress_time = 0; if (bdi->lastrecord == BGP_RECORD_UPDATE) { - UNSET_FLAG (bdi->binfo->flags, BGP_INFO_HISTORY); + bgp_info_unset_flag (bdi->rn, bdi->binfo, BGP_INFO_HISTORY); bgp_aggregate_increment (bgp, &bdi->rn->p, bdi->binfo, bdi->afi, bdi->safi); bgp_process (bgp, bdi->rn, bdi->afi, bdi->safi); @@ -223,11 +223,13 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn, bdi->flap++; } + assert ((rn == bdi->rn) && (binfo == bdi->binfo)); + bdi->lastrecord = BGP_RECORD_WITHDRAW; bdi->t_updated = t_now; /* Make this route as historical status. */ - SET_FLAG (binfo->flags, BGP_INFO_HISTORY); + bgp_info_set_flag (rn, binfo, BGP_INFO_HISTORY); /* Remove the route from a reuse list if it is on one. */ if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED)) @@ -245,7 +247,7 @@ bgp_damp_withdraw (struct bgp_info *binfo, struct bgp_node *rn, insert into reuse_list. */ if (bdi->penalty >= damp->suppress_value) { - SET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED); + bgp_info_set_flag (rn, binfo, BGP_INFO_DAMPED); bdi->suppress_time = t_now; BGP_DAMP_LIST_DEL (damp, bdi); bgp_reuse_list_add (bdi); @@ -267,7 +269,7 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn, return BGP_DAMP_USED; t_now = time (NULL); - UNSET_FLAG (binfo->flags, BGP_INFO_HISTORY); + bgp_info_unset_flag (rn, binfo, BGP_INFO_HISTORY); bdi->lastrecord = BGP_RECORD_UPDATE; bdi->penalty = bgp_damp_decay (t_now - bdi->t_updated, bdi->penalty); @@ -278,7 +280,7 @@ bgp_damp_update (struct bgp_info *binfo, struct bgp_node *rn, else if (CHECK_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED) && (bdi->penalty < damp->reuse_limit) ) { - UNSET_FLAG (bdi->binfo->flags, BGP_INFO_DAMPED); + bgp_info_unset_flag (rn, binfo, BGP_INFO_DAMPED); bgp_reuse_list_delete (bdi); BGP_DAMP_LIST_ADD (damp, bdi); bdi->suppress_time = 0; @@ -311,7 +313,7 @@ bgp_damp_scan (struct bgp_info *binfo, afi_t afi, safi_t safi) if (t_diff >= damp->max_suppress_time) { - UNSET_FLAG (binfo->flags, BGP_INFO_DAMPED); + bgp_info_unset_flag (bdi->rn, binfo, BGP_INFO_DAMPED); bgp_reuse_list_delete (bdi); BGP_DAMP_LIST_ADD (damp, bdi); bdi->penalty = damp->reuse_limit; @@ -358,8 +360,7 @@ bgp_damp_info_free (struct bgp_damp_info *bdi, int withdraw) else BGP_DAMP_LIST_DEL (damp, bdi); - UNSET_FLAG (binfo->flags, BGP_INFO_DAMPED); - UNSET_FLAG (binfo->flags, BGP_INFO_HISTORY); + bgp_info_unset_flag (bdi->rn, binfo, BGP_INFO_HISTORY|BGP_INFO_DAMPED); if (bdi->lastrecord == BGP_RECORD_WITHDRAW && withdraw) bgp_info_delete (bdi->rn, binfo); diff --git a/bgpd/bgp_nexthop.c b/bgpd/bgp_nexthop.c index ea707ccb..bfc41a18 100644 --- a/bgpd/bgp_nexthop.c +++ b/bgpd/bgp_nexthop.c @@ -478,11 +478,11 @@ bgp_scan (afi_t afi, safi_t safi) { bgp_aggregate_decrement (bgp, &rn->p, bi, afi, SAFI_UNICAST); - UNSET_FLAG (bi->flags, BGP_INFO_VALID); + bgp_info_unset_flag (rn, bi, BGP_INFO_VALID); } else { - SET_FLAG (bi->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, bi, BGP_INFO_VALID); bgp_aggregate_increment (bgp, &rn->p, bi, afi, SAFI_UNICAST); } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 40534a14..ca7cbd10 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -187,12 +187,73 @@ bgp_info_reap (struct bgp_node *rn, struct bgp_info *ri) void bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri) { - /* leave info in place for now in place for now, - * bgp_process will reap it later. */ - SET_FLAG (ri->flags, BGP_INFO_REMOVED); + bgp_info_set_flag (rn, ri, BGP_INFO_REMOVED); + /* set of previous already took care of pcount */ UNSET_FLAG (ri->flags, BGP_INFO_VALID); } +/* Adjust pcount as required */ +static void +bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) +{ + /* Ignore 'pcount' for RS-client tables */ + if (rn->table->type != BGP_TABLE_MAIN + || ri->peer == ri->peer->bgp->peer_self) + return; + + if (BGP_INFO_HOLDDOWN (ri) + && CHECK_FLAG (ri->flags, BGP_INFO_COUNTED)) + { + + UNSET_FLAG (ri->flags, BGP_INFO_COUNTED); + + /* slight hack, but more robust against errors. */ + if (ri->peer->pcount[rn->table->afi][rn->table->safi]) + ri->peer->pcount[rn->table->afi][rn->table->safi]--; + else + { + zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s", + __func__, ri->peer->host); + zlog_backtrace (LOG_WARNING); + zlog_warn ("%s: Please report to Quagga bugzilla", __func__); + } + } + else if (!BGP_INFO_HOLDDOWN (ri) + && !CHECK_FLAG (ri->flags, BGP_INFO_COUNTED)) + { + SET_FLAG (ri->flags, BGP_INFO_COUNTED); + ri->peer->pcount[rn->table->afi][rn->table->safi]++; + } +} + + +/* Set/unset bgp_info flags, adjusting any other state as needed. + * This is here primarily to keep prefix-count in check. + */ +void +bgp_info_set_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag) +{ + SET_FLAG (ri->flags, flag); + + /* early bath if we know it's not a flag that changes useability state */ + if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE)) + return; + + bgp_pcount_adjust (rn, ri); +} + +void +bgp_info_unset_flag (struct bgp_node *rn, struct bgp_info *ri, u_int32_t flag) +{ + UNSET_FLAG (ri->flags, flag); + + /* early bath if we know it's not a flag that changes useability state */ + if (!CHECK_FLAG (flag, BGP_INFO_VALID|BGP_INFO_UNUSEABLE)) + return; + + bgp_pcount_adjust (rn, ri); +} + /* Get MED value. If MED value is missing and "bgp bestpath missing-as-worst" is specified, treat it as the worst value. */ static u_int32_t @@ -1144,15 +1205,15 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair * { if (bgp_info_cmp (bgp, ri2, new_select)) { - UNSET_FLAG (new_select->flags, BGP_INFO_DMED_SELECTED); + bgp_info_unset_flag (rn, new_select, BGP_INFO_DMED_SELECTED); new_select = ri2; } - SET_FLAG (ri2->flags, BGP_INFO_DMED_CHECK); + bgp_info_set_flag (rn, ri2, BGP_INFO_DMED_CHECK); } } - SET_FLAG (new_select->flags, BGP_INFO_DMED_CHECK); - SET_FLAG (new_select->flags, BGP_INFO_DMED_SELECTED); + bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_CHECK); + bgp_info_set_flag (rn, new_select, BGP_INFO_DMED_SELECTED); } /* Check old selected route and new selected route. */ @@ -1178,11 +1239,11 @@ bgp_best_selection (struct bgp *bgp, struct bgp_node *rn, struct bgp_info_pair * if (bgp_flag_check (bgp, BGP_FLAG_DETERMINISTIC_MED) && (! CHECK_FLAG (ri->flags, BGP_INFO_DMED_SELECTED))) { - UNSET_FLAG (ri->flags, BGP_INFO_DMED_CHECK); + bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK); continue; } - UNSET_FLAG (ri->flags, BGP_INFO_DMED_CHECK); - UNSET_FLAG (ri->flags, BGP_INFO_DMED_SELECTED); + bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_CHECK); + bgp_info_unset_flag (rn, ri, BGP_INFO_DMED_SELECTED); if (bgp_info_cmp (bgp, ri, new_select)) new_select = ri; @@ -1276,11 +1337,11 @@ bgp_process_rsclient (struct work_queue *wq, void *data) continue; if (old_select) - UNSET_FLAG (old_select->flags, BGP_INFO_SELECTED); + bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED); if (new_select) { - SET_FLAG (new_select->flags, BGP_INFO_SELECTED); - UNSET_FLAG (new_select->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED); + bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED); } bgp_process_announce_selected (rsclient, new_select, rn, &attr, @@ -1290,11 +1351,11 @@ bgp_process_rsclient (struct work_queue *wq, void *data) else { if (old_select) - UNSET_FLAG (old_select->flags, BGP_INFO_SELECTED); + bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED); if (new_select) { - SET_FLAG (new_select->flags, BGP_INFO_SELECTED); - UNSET_FLAG (new_select->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED); + bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED); } bgp_process_announce_selected (rsclient, new_select, rn, &attr, afi, safi); @@ -1342,11 +1403,11 @@ bgp_process_main (struct work_queue *wq, void *data) } if (old_select) - UNSET_FLAG (old_select->flags, BGP_INFO_SELECTED); + bgp_info_unset_flag (rn, old_select, BGP_INFO_SELECTED); if (new_select) { - SET_FLAG (new_select->flags, BGP_INFO_SELECTED); - UNSET_FLAG (new_select->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, new_select, BGP_INFO_SELECTED); + bgp_info_unset_flag (rn, new_select, BGP_INFO_ATTR_CHANGED); } @@ -1545,43 +1606,6 @@ bgp_maximum_prefix_overflow (struct peer *peer, afi_t afi, return 0; } -static void -bgp_pcount_increment (struct bgp_node *rn, struct bgp_info *ri, - afi_t afi, safi_t safi) -{ - assert (ri && rn); - - if (!CHECK_FLAG (ri->flags, BGP_INFO_COUNTED) - && rn->table->type == BGP_TABLE_MAIN) - { - SET_FLAG (ri->flags, BGP_INFO_COUNTED); - ri->peer->pcount[afi][safi]++; - } -} - -static void -bgp_pcount_decrement (struct bgp_node *rn, struct bgp_info *ri, - afi_t afi, safi_t safi) -{ - /* Ignore 'pcount' for RS-client tables */ - if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED) - && rn->table->type == BGP_TABLE_MAIN) - { - UNSET_FLAG (ri->flags, BGP_INFO_COUNTED); - - /* slight hack, but more robust against errors. */ - if (ri->peer->pcount[afi][safi]) - ri->peer->pcount[afi][safi]--; - else - { - zlog_warn ("%s: Asked to decrement 0 prefix count for peer %s", - __func__, ri->peer->host); - zlog_backtrace (LOG_WARNING); - zlog_warn ("%s: Please report to Quagga bugzilla", __func__); - } - } -} - /* Unconditionally remove the route from the RIB, without taking * damping into consideration (eg, because the session went down) */ @@ -1589,7 +1613,6 @@ static void bgp_rib_remove (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, afi_t afi, safi_t safi) { - bgp_pcount_decrement (rn, ri, afi, safi); bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); if (!CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) @@ -1612,7 +1635,6 @@ bgp_rib_withdraw (struct bgp_node *rn, struct bgp_info *ri, struct peer *peer, if ( (status = bgp_damp_withdraw (ri, rn, afi, safi, 0)) == BGP_DAMP_SUPPRESSED) { - bgp_pcount_decrement (rn, ri, afi, safi); bgp_aggregate_decrement (peer->bgp, &rn->p, ri, afi, safi); return; } @@ -1709,7 +1731,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, if (attrhash_cmp (ri->attr, attr_new)) { - UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED); if (BGP_DEBUG (update, UPDATE_IN)) zlog (peer->log, LOG_DEBUG, @@ -1732,7 +1754,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, p->prefixlen, rsclient->host); /* The attribute is changed. */ - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); /* Update to new attribute. */ bgp_attr_unintern (ri->attr); @@ -1742,7 +1764,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, if (safi == SAFI_MPLS_VPN) memcpy (ri->tag, tag, 3); - SET_FLAG (ri->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, ri, BGP_INFO_VALID); /* Process change. */ bgp_process (bgp, rn, afi, safi); @@ -1772,7 +1794,7 @@ bgp_update_rsclient (struct peer *rsclient, afi_t afi, safi_t safi, if (safi == SAFI_MPLS_VPN) memcpy (new->tag, tag, 3); - SET_FLAG (new->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, new, BGP_INFO_VALID); /* Register new BGP information. */ bgp_info_add (rn, new); @@ -1953,7 +1975,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* Same attribute comes in. */ if (attrhash_cmp (ri->attr, attr_new)) { - UNSET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_unset_flag (rn, ri, BGP_INFO_ATTR_CHANGED); if (CHECK_FLAG (bgp->af_flags[afi][safi], BGP_CONFIG_DAMPENING) && peer_sort (peer) == BGP_PEER_EBGP @@ -1965,8 +1987,6 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, inet_ntop(p->family, &p->u.prefix, buf, SU_ADDRSTRLEN), p->prefixlen); - bgp_pcount_increment (rn, ri, afi, safi); - if (bgp_damp_update (ri, rn, afi, safi) != BGP_DAMP_SUPPRESSED) { bgp_aggregate_increment (bgp, p, ri, afi, safi); @@ -1985,8 +2005,7 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* graceful restart STALE flag unset. */ if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) { - UNSET_FLAG (ri->flags, BGP_INFO_STALE); - bgp_pcount_increment (rn, ri, afi, safi); + bgp_info_unset_flag (rn, ri, BGP_INFO_STALE); bgp_process (bgp, rn, afi, safi); } } @@ -2005,15 +2024,14 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, /* graceful restart STALE flag unset. */ if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) - UNSET_FLAG (ri->flags, BGP_INFO_STALE); + bgp_info_unset_flag (rn, ri, BGP_INFO_STALE); /* The attribute is changed. */ - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); /* implicit withdraw, decrement aggregate and pcount here. * only if update is accepted, they'll increment below. */ - bgp_pcount_decrement (rn, ri, afi, safi); bgp_aggregate_decrement (bgp, p, ri, afi, safi); /* Update bgp route dampening information. */ @@ -2055,15 +2073,14 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))) { if (bgp_nexthop_lookup (afi, peer, ri, NULL, NULL)) - SET_FLAG (ri->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, ri, BGP_INFO_VALID); else - UNSET_FLAG (ri->flags, BGP_INFO_VALID); + bgp_info_unset_flag (rn, ri, BGP_INFO_VALID); } else - SET_FLAG (ri->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, ri, BGP_INFO_VALID); /* Process change. */ - bgp_pcount_increment (rn, ri, afi, safi); bgp_aggregate_increment (bgp, p, ri, afi, safi); bgp_process (bgp, rn, afi, safi); @@ -2100,15 +2117,14 @@ bgp_update_main (struct peer *peer, struct prefix *p, struct attr *attr, || CHECK_FLAG (peer->flags, PEER_FLAG_DISABLE_CONNECTED_CHECK))) { if (bgp_nexthop_lookup (afi, peer, new, NULL, NULL)) - SET_FLAG (new->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, new, BGP_INFO_VALID); else - UNSET_FLAG (new->flags, BGP_INFO_VALID); + bgp_info_unset_flag (rn, new, BGP_INFO_VALID); } else - SET_FLAG (new->flags, BGP_INFO_VALID); + bgp_info_set_flag (rn, new, BGP_INFO_VALID); /* Increment prefix */ - bgp_pcount_increment (rn, new, afi, safi); bgp_aggregate_increment (bgp, p, new, afi, safi); /* Register new BGP information. */ @@ -2475,13 +2491,8 @@ bgp_clear_route_node (struct work_queue *wq, void *data) if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT) && peer->nsf[afi][safi] && ! CHECK_FLAG (ri->flags, BGP_INFO_STALE) - && ! CHECK_FLAG (ri->flags, BGP_INFO_HISTORY) - && ! CHECK_FLAG (ri->flags, BGP_INFO_DAMPED) - && ! CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)) - { - bgp_pcount_decrement (rn, ri, afi, safi); - SET_FLAG (ri->flags, BGP_INFO_STALE); - } + && ! CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE)) + bgp_info_set_flag (rn, ri, BGP_INFO_STALE); else bgp_rib_remove (rn, ri, peer, afi, safi); break; @@ -2911,9 +2922,8 @@ bgp_static_withdraw_rsclient (struct bgp *bgp, struct peer *rsclient, /* Withdraw static BGP route from routing table. */ if (ri) { - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); bgp_info_delete (rn, ri); + bgp_process (bgp, rn, afi, safi); } /* Unlock bgp_node_lookup. */ @@ -3025,7 +3035,7 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, else { /* The attribute is changed. */ - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ bgp_attr_unintern (ri->attr); @@ -3132,7 +3142,7 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, else { /* The attribute is changed. */ - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ bgp_aggregate_decrement (bgp, p, ri, afi, safi); @@ -3242,9 +3252,8 @@ bgp_static_withdraw (struct bgp *bgp, struct prefix *p, afi_t afi, if (ri) { bgp_aggregate_decrement (bgp, p, ri, afi, safi); - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); bgp_info_delete (rn, ri); + bgp_process (bgp, rn, afi, safi); } /* Unlock bgp_node_lookup. */ @@ -3291,9 +3300,8 @@ bgp_static_withdraw_vpnv4 (struct bgp *bgp, struct prefix *p, u_int16_t afi, if (ri) { bgp_aggregate_decrement (bgp, p, ri, afi, safi); - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); bgp_info_delete (rn, ri); + bgp_process (bgp, rn, afi, safi); } /* Unlock bgp_node_lookup. */ @@ -4074,7 +4082,7 @@ bgp_aggregate_route (struct bgp *bgp, struct prefix *p, struct bgp_info *rinew, if (aggregate->summary_only) { ri->suppress++; - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); match++; } @@ -4277,7 +4285,7 @@ bgp_aggregate_add (struct bgp *bgp, struct prefix *p, afi_t afi, safi_t safi, if (aggregate->summary_only) { ri->suppress++; - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); match++; } /* as-set aggregate route generate origin, as path, @@ -4377,7 +4385,7 @@ bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi, if (ri->suppress == 0) { - SET_FLAG (ri->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); match++; } } @@ -4403,9 +4411,8 @@ bgp_aggregate_delete (struct bgp *bgp, struct prefix *p, afi_t afi, /* Withdraw static BGP route from routing table. */ if (ri) { - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, safi); bgp_info_delete (rn, ri); + bgp_process (bgp, rn, afi, safi); } /* Unlock bgp_node_lookup. */ @@ -4929,7 +4936,7 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, else { /* The attribute is changed. */ - SET_FLAG (bi->flags, BGP_INFO_ATTR_CHANGED); + bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST); @@ -4990,9 +4997,8 @@ bgp_redistribute_delete (struct prefix *p, u_char type) if (ri) { bgp_aggregate_decrement (bgp, p, ri, afi, SAFI_UNICAST); - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, SAFI_UNICAST); bgp_info_delete (rn, ri); + bgp_process (bgp, rn, afi, SAFI_UNICAST); } bgp_unlock_node (rn); } @@ -5019,9 +5025,8 @@ bgp_redistribute_withdraw (struct bgp *bgp, afi_t afi, int type) if (ri) { bgp_aggregate_decrement (bgp, &rn->p, ri, afi, SAFI_UNICAST); - UNSET_FLAG (ri->flags, BGP_INFO_VALID); - bgp_process (bgp, rn, afi, SAFI_UNICAST); bgp_info_delete (rn, ri); + bgp_process (bgp, rn, afi, SAFI_UNICAST); } } } @@ -8439,7 +8444,6 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) if (ain->peer == peer) pcounts[PCOUNT_ADJ_IN]++; -#define PFCNT_EXCLUDED (BGP_INFO_DAMPED|BGP_INFO_HISTORY|BGP_INFO_REMOVED|BGP_INFO_STALE) for (ri = rn->info; ri; ri = ri->next) { char buf[SU_ADDRSTRLEN]; @@ -8459,13 +8463,13 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) pcounts[PCOUNT_STALE]++; if (CHECK_FLAG (ri->flags, BGP_INFO_VALID)) pcounts[PCOUNT_VALID]++; - if (!CHECK_FLAG (ri->flags, PFCNT_EXCLUDED)) + if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE)) pcounts[PCOUNT_PFCNT]++; if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED)) { pcounts[PCOUNT_COUNTED]++; - if (CHECK_FLAG (ri->flags, PFCNT_EXCLUDED)) + if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE)) plog_warn (peer->log, "%s [pcount] %s/%d is counted but flags 0x%x", peer->host, @@ -8476,7 +8480,7 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) } else { - if (!CHECK_FLAG (ri->flags, PFCNT_EXCLUDED)) + if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE)) plog_warn (peer->log, "%s [pcount] %s/%d not counted but flags 0x%x", peer->host, @@ -8487,7 +8491,6 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) } } } -#undef PFCNT_EXCLUDED vty_out (vty, "Prefix counts for %s, %s%s", peer->host, afi_safi_print (afi, safi), VTY_NEWLINE); diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h index e5f3ae59..b0c2fccf 100644 --- a/bgpd/bgp_route.h +++ b/bgpd/bgp_route.h @@ -105,6 +105,17 @@ struct bgp_static u_char tag[3]; }; +/* Flags which indicate a route is unuseable in some form */ +#define BGP_INFO_UNUSEABLE \ + (BGP_INFO_HISTORY|BGP_INFO_DAMPED|BGP_INFO_REMOVED) +/* Macro to check BGP information is alive or not. Sadly, + * not equivalent to just checking previous, because of the + * sense of the additional VALID flag. + */ +#define BGP_INFO_HOLDDOWN(BI) \ + (! CHECK_FLAG ((BI)->flags, BGP_INFO_VALID) \ + || CHECK_FLAG ((BI)->flags, BGP_INFO_UNUSEABLE)) + #define DISTRIBUTE_IN_NAME(F) ((F)->dlist[FILTER_IN].name) #define DISTRIBUTE_IN(F) ((F)->dlist[FILTER_IN].alist) #define DISTRIBUTE_OUT_NAME(F) ((F)->dlist[FILTER_OUT].name) @@ -151,6 +162,8 @@ extern struct bgp_info *bgp_info_lock (struct bgp_info *); extern struct bgp_info *bgp_info_unlock (struct bgp_info *); extern void bgp_info_add (struct bgp_node *rn, struct bgp_info *ri); extern void bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri); +extern void bgp_info_set_flag (struct bgp_node *, struct bgp_info *, u_int32_t); +extern void bgp_info_unset_flag (struct bgp_node *, struct bgp_info *, u_int32_t); extern int bgp_nlri_sanity_check (struct peer *, int, u_char *, bgp_size_t); extern int bgp_nlri_parse (struct peer *, struct attr *, struct bgp_nlri *); diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index 9e2aa3e0..b8ae30ae 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -740,13 +740,6 @@ enum bgp_clear_type #define BGP_INPUT(P) ((P)->ibuf) #define BGP_INPUT_PNT(P) (STREAM_PNT(BGP_INPUT(P))) -/* Macro to check BGP information is alive or not. */ -#define BGP_INFO_HOLDDOWN(BI) \ - (! CHECK_FLAG ((BI)->flags, BGP_INFO_VALID) \ - || CHECK_FLAG ((BI)->flags, BGP_INFO_HISTORY) \ - || CHECK_FLAG ((BI)->flags, BGP_INFO_DAMPED) \ - || CHECK_FLAG ((BI)->flags, BGP_INFO_REMOVED)) - /* Count prefix size from mask length */ #define PSIZE(a) (((a) + 7) / (8)) -- cgit v1.2.3 From 3e557ae1ea7693d91b6df42c2529952d6a349911 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 11 Sep 2006 02:10:40 +0000 Subject: [ripd] bug #278: remove gratuitous use of mid-function declaration 2006-09-11 Paul Jakma * ripd.c: (rip_read) remove gratuitous use of mid-function declaration of vrecv, bug #278. --- ripd/ChangeLog | 5 +++++ ripd/ripd.c | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ripd/ChangeLog b/ripd/ChangeLog index 50f8dfd7..afae7e98 100644 --- a/ripd/ChangeLog +++ b/ripd/ChangeLog @@ -1,3 +1,8 @@ +2006-09-11 Paul Jakma + + * ripd.c: (rip_read) remove gratuitous use of mid-function + declaration of vrecv, bug #278. + 2006-06-29 Paul Jakma * rip_zebra: (general) convert redistribute commands to use diff --git a/ripd/ripd.c b/ripd/ripd.c index 518e4861..a1630f6c 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -1818,6 +1818,7 @@ rip_read (struct thread *t) struct rip_packet *packet; struct sockaddr_in from; int len; + int vrecv; socklen_t fromlen; struct interface *ifp; struct connected *ifc; @@ -1937,8 +1938,8 @@ rip_read (struct thread *t) } /* RIP Version check. RFC2453, 4.6 and 5.1 */ - int vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? - rip->version_recv : ri->ri_receive); + vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ? + rip->version_recv : ri->ri_receive); if ((packet->version == RIPv1) && !(vrecv & RIPv1)) { if (IS_RIP_DEBUG_PACKET) -- cgit v1.2.3 From b25ea4d085c858137ec28b1be9d6ab6c30a97303 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Mon, 11 Sep 2006 02:14:16 +0000 Subject: [ripd] bug #293: routemap set metric doesn't check for underflow correctly 2006-09-11 Paul Jakma * rip_routemap.c: (route_set_metric) underflow check needs to use signed, problem identified and diagnosed by Pavel Nikiforov in bug #293. --- ripd/ChangeLog | 3 +++ ripd/rip_routemap.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/ripd/ChangeLog b/ripd/ChangeLog index afae7e98..68813f14 100644 --- a/ripd/ChangeLog +++ b/ripd/ChangeLog @@ -2,6 +2,9 @@ * ripd.c: (rip_read) remove gratuitous use of mid-function declaration of vrecv, bug #278. + * rip_routemap.c: (route_set_metric) underflow check needs to + use signed, problem identified and diagnosed by Pavel + Nikiforov in bug #293. 2006-06-29 Paul Jakma diff --git a/ripd/rip_routemap.c b/ripd/rip_routemap.c index 9d6fd16e..cb87ea55 100644 --- a/ripd/rip_routemap.c +++ b/ripd/rip_routemap.c @@ -530,7 +530,7 @@ route_set_metric (void *rule, struct prefix *prefix, else if (mod->type == metric_absolute) rinfo->metric_out = mod->metric; - if (rinfo->metric_out < 1) + if ((signed int)rinfo->metric_out < 1) rinfo->metric_out = 1; if (rinfo->metric_out > RIP_METRIC_INFINITY) rinfo->metric_out = RIP_METRIC_INFINITY; -- cgit v1.2.3 From 9458b8191563eb5569f341172484a234ef2f743e Mon Sep 17 00:00:00 2001 From: Greg Troxel Date: Wed, 13 Sep 2006 12:13:08 +0000 Subject: 2006-09-13 Tom Everett * kernel_socket.c (rtm_type_str): ifdef RTM_OLD{ADD,DEL} to compile on systems that no longer define them. --- zebra/ChangeLog | 5 +++++ zebra/kernel_socket.c | 4 ++++ 2 files changed, 9 insertions(+) diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 62287d0b..0740e756 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -1,3 +1,8 @@ +2006-09-13 Tom Everett + + * kernel_socket.c (rtm_type_str): ifdef RTM_OLD{ADD,DEL} to + compile on systems that no longer define them. + 2006-08-06 Paul Jakma * interface.h: (ifstat_update_proc) declaration should match diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index bd4d9c4b..f384e979 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -136,8 +136,12 @@ struct message rtm_type_str[] = {RTM_REDIRECT, "RTM_REDIRECT"}, {RTM_MISS, "RTM_MISS"}, {RTM_LOCK, "RTM_LOCK"}, +#ifdef OLDADD {RTM_OLDADD, "RTM_OLDADD"}, +#endif /* RTM_OLDADD */ +#ifdef RTM_OLDDEL {RTM_OLDDEL, "RTM_OLDDEL"}, +#endif /* RTM_OLDDEL */ {RTM_RESOLVE, "RTM_RESOLVE"}, {RTM_NEWADDR, "RTM_NEWADDR"}, {RTM_DELADDR, "RTM_DELADDR"}, -- cgit v1.2.3 From 2815e61ffbbf9c362896f3912d925cf78e125ee1 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 14 Sep 2006 02:56:07 +0000 Subject: [bgpd] Add RIB reporting commands, show bgp ... statistics 2006-09-13 Paul Jakma * bgp_aspath.c: (aspath_highest) new, return highest ASN in an aspath. * bgp_route.c: (bgp_peer_count_walker) new, do the walk done in bgp_peer_counts as a thread. (bgp_peer_counts) move walk to previous and call it via thread_execute so this RIB walk shows up in thread stats. (bgp_table_stats) New, gather some statistics for a given RIB. (bgp_table_stats_walker) New, RIB walker thread for former. (bgp_table_stats_vty) Parsing front-end for 'show bgp ...', useful model for future rationalisation of 'show ... bgp'. (bgp_route_init) Add new RIB stats commands. --- bgpd/ChangeLog | 15 ++ bgpd/bgp_aspath.c | 20 +++ bgpd/bgp_aspath.h | 1 + bgpd/bgp_route.c | 437 ++++++++++++++++++++++++++++++++++++++++++++++++++---- 4 files changed, 447 insertions(+), 26 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 7de02cf5..482beeda 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,18 @@ +2006-09-13 Paul Jakma + + * bgp_aspath.c: (aspath_highest) new, return highest ASN in an + aspath. + * bgp_route.c: (bgp_peer_count_walker) new, do the walk done + in bgp_peer_counts as a thread. + (bgp_peer_counts) move walk to previous and call it via + thread_execute so this RIB walk shows up in thread stats. + (bgp_table_stats) New, gather some statistics for a given + RIB. + (bgp_table_stats_walker) New, RIB walker thread for former. + (bgp_table_stats_vty) Parsing front-end for 'show bgp ...', + useful model for future rationalisation of 'show ... bgp'. + (bgp_route_init) Add new RIB stats commands. + 2006-09-06 Paul Jakma * (general) Squash any and all prefix-count issues by diff --git a/bgpd/bgp_aspath.c b/bgpd/bgp_aspath.c index 317e9f8d..327406fa 100644 --- a/bgpd/bgp_aspath.c +++ b/bgpd/bgp_aspath.c @@ -434,6 +434,26 @@ aspath_size (struct aspath *aspath) return size; } +/* Return highest public ASN in path */ +as_t +aspath_highest (struct aspath *aspath) +{ + struct assegment *seg = aspath->segments; + as_t highest = 0; + unsigned int i; + + while (seg) + { + for (i = 0; i < seg->length; i++) + if (seg->as[i] > highest + && (seg->as[i] < BGP_PRIVATE_AS_MIN + || seg->as[i] > BGP_PRIVATE_AS_MAX)) + highest = seg->as[i]; + seg = seg->next; + } + return highest; +} + /* Convert aspath structure to string expression. */ static char * aspath_make_str_count (struct aspath *as) diff --git a/bgpd/bgp_aspath.h b/bgpd/bgp_aspath.h index bf23e5d6..5400c57c 100644 --- a/bgpd/bgp_aspath.h +++ b/bgpd/bgp_aspath.h @@ -87,6 +87,7 @@ extern unsigned long aspath_count (void); extern unsigned int aspath_count_hops (struct aspath *); extern unsigned int aspath_count_confeds (struct aspath *); extern unsigned int aspath_size (struct aspath *); +extern as_t aspath_highest (struct aspath *); extern void aspath_put (struct stream *, struct aspath *); /* For SNMP BGP4PATHATTRASPATHSEGMENT, might be useful for debug */ diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index ca7cbd10..2ce2ef4d 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8390,7 +8390,362 @@ peer_lookup_in_view (struct vty *vty, const char *view_name, return peer; } + +enum bgp_stats +{ + BGP_STATS_MAXBITLEN = 0, + BGP_STATS_RIB, + BGP_STATS_PREFIXES, + BGP_STATS_TOTPLEN, + BGP_STATS_UNAGGREGATEABLE, + BGP_STATS_MAX_AGGREGATEABLE, + BGP_STATS_AGGREGATES, + BGP_STATS_SPACE, + BGP_STATS_ASPATH_COUNT, + BGP_STATS_ASPATH_MAXHOPS, + BGP_STATS_ASPATH_TOTHOPS, + BGP_STATS_ASPATH_MAXSIZE, + BGP_STATS_ASPATH_TOTSIZE, + BGP_STATS_ASN_HIGHEST, + BGP_STATS_MAX, +}; + +static const char *table_stats_strs[] = +{ + [BGP_STATS_PREFIXES] = "Total Prefixes", + [BGP_STATS_TOTPLEN] = "Average prefix length", + [BGP_STATS_RIB] = "Total Advertisements", + [BGP_STATS_UNAGGREGATEABLE] = "Unaggregateable prefixes", + [BGP_STATS_MAX_AGGREGATEABLE] = "Maximum aggregateable prefixes", + [BGP_STATS_AGGREGATES] = "BGP Aggregate advertisements", + [BGP_STATS_SPACE] = "Address space advertised", + [BGP_STATS_ASPATH_COUNT] = "Advertisements with paths", + [BGP_STATS_ASPATH_MAXHOPS] = "Longest AS-Path (hops)", + [BGP_STATS_ASPATH_MAXSIZE] = "Largest AS-Path (bytes)", + [BGP_STATS_ASPATH_TOTHOPS] = "Average AS-Path length (hops)", + [BGP_STATS_ASPATH_TOTSIZE] = "Average AS-Path size (bytes)", + [BGP_STATS_ASN_HIGHEST] = "Highest public ASN", + [BGP_STATS_MAX] = NULL, +}; + +struct bgp_table_stats +{ + struct bgp_table *table; + unsigned long long counts[BGP_STATS_MAX]; +}; + +#if 0 +#define TALLY_SIGFIG 100000 +static unsigned long +ravg_tally (unsigned long count, unsigned long oldavg, unsigned long newval) +{ + unsigned long newtot = (count-1) * oldavg + (newval * TALLY_SIGFIG); + unsigned long res = (newtot * TALLY_SIGFIG) / count; + unsigned long ret = newtot / count; + + if ((res % TALLY_SIGFIG) > (TALLY_SIGFIG/2)) + return ret + 1; + else + return ret; +} +#endif + +static int +bgp_table_stats_walker (struct thread *t) +{ + struct bgp_node *rn; + struct bgp_node *top; + struct bgp_table_stats *ts = THREAD_ARG (t); + unsigned int space = 0; + + top = bgp_table_top (ts->table); + + switch (top->p.family) + { + case AF_INET: + space = IPV4_MAX_BITLEN; + break; + case AF_INET6: + space = IPV6_MAX_BITLEN; + break; + } + + ts->counts[BGP_STATS_MAXBITLEN] = space; + + for (rn = top; rn; rn = bgp_route_next (rn)) + { + struct bgp_info *ri; + struct bgp_node *prn = rn->parent; + unsigned int rinum = 0; + + if (rn == top) + continue; + + if (!rn->info) + continue; + + ts->counts[BGP_STATS_PREFIXES]++; + ts->counts[BGP_STATS_TOTPLEN] += rn->p.prefixlen; + +#if 0 + ts->counts[BGP_STATS_AVGPLEN] + = ravg_tally (ts->counts[BGP_STATS_PREFIXES], + ts->counts[BGP_STATS_AVGPLEN], + rn->p.prefixlen); +#endif + + /* check if the prefix is included by any other announcements */ + while (prn && !prn->info) + prn = prn->parent; + + if (prn == NULL || prn == top) + ts->counts[BGP_STATS_UNAGGREGATEABLE]++; + else if (prn->info) + ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; + + /* announced address space */ + if (space) + ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen); + + for (ri = rn->info; ri; ri = ri->next) + { + rinum++; + ts->counts[BGP_STATS_RIB]++; + + if (ri->attr && + (CHECK_FLAG (ri->attr->flag, + ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE)))) + ts->counts[BGP_STATS_AGGREGATES]++; + + /* as-path stats */ + if (ri->attr && ri->attr->aspath) + { + unsigned int hops = aspath_count_hops (ri->attr->aspath); + unsigned int size = aspath_size (ri->attr->aspath); + as_t highest = aspath_highest (ri->attr->aspath); + + ts->counts[BGP_STATS_ASPATH_COUNT]++; + + if (hops > ts->counts[BGP_STATS_ASPATH_MAXHOPS]) + ts->counts[BGP_STATS_ASPATH_MAXHOPS] = hops; + + if (size > ts->counts[BGP_STATS_ASPATH_MAXSIZE]) + ts->counts[BGP_STATS_ASPATH_MAXSIZE] = size; + + ts->counts[BGP_STATS_ASPATH_TOTHOPS] += hops; + ts->counts[BGP_STATS_ASPATH_TOTSIZE] += size; +#if 0 + ts->counts[BGP_STATS_ASPATH_AVGHOPS] + = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT], + ts->counts[BGP_STATS_ASPATH_AVGHOPS], + hops); + ts->counts[BGP_STATS_ASPATH_AVGSIZE] + = ravg_tally (ts->counts[BGP_STATS_ASPATH_COUNT], + ts->counts[BGP_STATS_ASPATH_AVGSIZE], + size); +#endif + if (highest > ts->counts[BGP_STATS_ASN_HIGHEST]) + ts->counts[BGP_STATS_ASN_HIGHEST] = highest; + } + } + } + return 0; +} + +static int +bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi) +{ + struct bgp_table_stats ts; + unsigned int i; + + if (!bgp->rib[afi][safi]) + { + vty_out (vty, "%% No RIB exist for the AFI/SAFI%s", VTY_NEWLINE); + return CMD_WARNING; + } + + memset (&ts, 0, sizeof (ts)); + ts.table = bgp->rib[afi][safi]; + thread_execute (bm->master, bgp_table_stats_walker, &ts, 0); + vty_out (vty, "BGP %s RIB statistics%s%s", + afi_safi_print (afi, safi), VTY_NEWLINE, VTY_NEWLINE); + + for (i = 0; i < BGP_STATS_MAX; i++) + { + if (!table_stats_strs[i]) + continue; + + switch (i) + { +#if 0 + case BGP_STATS_ASPATH_AVGHOPS: + case BGP_STATS_ASPATH_AVGSIZE: + case BGP_STATS_AVGPLEN: + vty_out (vty, "%-30s: ", table_stats_strs[i]); + vty_out (vty, "%12.2f", + (float)ts.counts[i] / (float)TALLY_SIGFIG); + break; +#endif + case BGP_STATS_ASPATH_TOTHOPS: + case BGP_STATS_ASPATH_TOTSIZE: + vty_out (vty, "%-30s: ", table_stats_strs[i]); + vty_out (vty, "%12.2f", + ts.counts[i] ? + (float)ts.counts[i] / + (float)ts.counts[BGP_STATS_ASPATH_COUNT] + : 0); + break; + case BGP_STATS_TOTPLEN: + vty_out (vty, "%-30s: ", table_stats_strs[i]); + vty_out (vty, "%12.2f", + ts.counts[i] ? + (float)ts.counts[i] / + (float)ts.counts[BGP_STATS_PREFIXES] + : 0); + break; + case BGP_STATS_SPACE: + vty_out (vty, "%-30s: ", table_stats_strs[i]); + vty_out (vty, "%12llu%s", ts.counts[i], VTY_NEWLINE); + if (ts.counts[BGP_STATS_MAXBITLEN] < 9) + break; + vty_out (vty, "%30s: ", "\% announced "); + vty_out (vty, "%12.2f%s", + 100 * (float)ts.counts[BGP_STATS_SPACE] / + (float)((u_int64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]), + VTY_NEWLINE); + vty_out (vty, "%30s: ", "/8 equivalent "); + vty_out (vty, "%12.2f%s", + (float)ts.counts[BGP_STATS_SPACE] / + (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 8)), + VTY_NEWLINE); + if (ts.counts[BGP_STATS_MAXBITLEN] < 25) + break; + vty_out (vty, "%30s: ", "/24 equivalent "); + vty_out (vty, "%12.2f", + (float)ts.counts[BGP_STATS_SPACE] / + (float)(1UL << (ts.counts[BGP_STATS_MAXBITLEN] - 24))); + break; + default: + vty_out (vty, "%-30s: ", table_stats_strs[i]); + vty_out (vty, "%12llu", ts.counts[i]); + } + + vty_out (vty, "%s", VTY_NEWLINE); + } + return CMD_SUCCESS; +} + +static int +bgp_table_stats_vty (struct vty *vty, const char *name, + const char *afi_str, const char *safi_str) +{ + struct bgp *bgp; + afi_t afi; + safi_t safi; + + if (name) + bgp = bgp_lookup_by_name (name); + else + bgp = bgp_get_default (); + + if (!bgp) + { + vty_out (vty, "%% No such BGP instance exist%s", VTY_NEWLINE); + return CMD_WARNING; + } + if (strncmp (afi_str, "ipv", 3) == 0) + { + if (strncmp (afi_str, "ipv4", 4) == 0) + afi = AFI_IP; + else if (strncmp (afi_str, "ipv6", 4) == 0) + afi = AFI_IP6; + else + { + vty_out (vty, "%% Invalid address family %s%s", + afi_str, VTY_NEWLINE); + return CMD_WARNING; + } + if (strncmp (safi_str, "m", 1) == 0) + safi = SAFI_MULTICAST; + else if (strncmp (safi_str, "u", 1) == 0) + safi = SAFI_UNICAST; + else if (strncmp (safi_str, "vpnv4", 5) == 0) + safi = BGP_SAFI_VPNV4; + else if (strncmp (safi_str, "vpnv6", 6) == 0) + safi = BGP_SAFI_VPNV6; + else + { + vty_out (vty, "%% Invalid subsequent address family %s%s", + safi_str, VTY_NEWLINE); + return CMD_WARNING; + } + } + else + { + vty_out (vty, "%% Invalid address family %s%s", + afi_str, VTY_NEWLINE); + return CMD_WARNING; + } + + if ((afi == AFI_IP && safi == BGP_SAFI_VPNV6) + || (afi == AFI_IP6 && safi == BGP_SAFI_VPNV4)) + { + vty_out (vty, "%% Invalid subsequent address family %s for %s%s", + afi_str, safi_str, VTY_NEWLINE); + return CMD_WARNING; + } + return bgp_table_stats (vty, bgp, afi, safi); +} + +DEFUN (show_bgp_statistics, + show_bgp_statistics_cmd, + "show bgp (ipv4|ipv6) (unicast|multicast) statistics", + SHOW_STR + BGP_STR + "Address family\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "BGP RIB advertisement statistics\n") +{ + return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]); +} + +ALIAS (show_bgp_statistics, + show_bgp_statistics_vpnv4_cmd, + "show bgp (ipv4) (vpnv4) statistics", + SHOW_STR + BGP_STR + "Address family\n" + "Address Family modifier\n" + "BGP RIB advertisement statistics\n") + +DEFUN (show_bgp_statistics_view, + show_bgp_statistics_view_cmd, + "show bgp view WORD (ipv4|ipv6) (unicast|multicast) statistics", + SHOW_STR + BGP_STR + "BGP view\n" + "Address family\n" + "Address family\n" + "Address Family modifier\n" + "Address Family modifier\n" + "BGP RIB advertisement statistics\n") +{ + return bgp_table_stats_vty (vty, NULL, argv[0], argv[1]); +} + +ALIAS (show_bgp_statistics_view, + show_bgp_statistics_view_vpnv4_cmd, + "show bgp view WORD (ipv4) (vpnv4) statistics", + SHOW_STR + BGP_STR + "BGP view\n" + "Address family\n" + "Address Family modifier\n" + "BGP RIB advertisement statistics\n") + enum bgp_pcounts { PCOUNT_ADJ_IN = 0, @@ -8419,30 +8774,28 @@ static const char *pcount_strs[] = [PCOUNT_MAX] = NULL, }; +struct peer_pcounts +{ + unsigned int count[PCOUNT_MAX]; + const struct peer *peer; + const struct bgp_table *table; +}; + static int -bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) +bgp_peer_count_walker (struct thread *t) { struct bgp_node *rn; - struct bgp_info *ri; - unsigned int pcounts[PCOUNT_MAX], i; - - if (!peer || !peer->bgp || !peer->afc[afi][safi] - || !peer->bgp->rib[afi][safi]) - { - vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); - return CMD_WARNING; - } - - memset (&pcounts, 0, sizeof(pcounts)); + struct peer_pcounts *pc = THREAD_ARG (t); + const struct peer *peer = pc->peer; - for (rn = bgp_table_top (peer->bgp->rib[afi][safi]); rn; - rn = bgp_route_next (rn)) + for (rn = bgp_table_top (pc->table); rn; rn = bgp_route_next (rn)) { struct bgp_adj_in *ain; + struct bgp_info *ri; for (ain = rn->adj_in; ain; ain = ain->next) if (ain->peer == peer) - pcounts[PCOUNT_ADJ_IN]++; + pc->count[PCOUNT_ADJ_IN]++; for (ri = rn->info; ri; ri = ri->next) { @@ -8451,24 +8804,24 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) if (ri->peer != peer) continue; - pcounts[PCOUNT_ALL]++; + pc->count[PCOUNT_ALL]++; if (CHECK_FLAG (ri->flags, BGP_INFO_DAMPED)) - pcounts[PCOUNT_DAMPED]++; + pc->count[PCOUNT_DAMPED]++; if (CHECK_FLAG (ri->flags, BGP_INFO_HISTORY)) - pcounts[PCOUNT_HISTORY]++; + pc->count[PCOUNT_HISTORY]++; if (CHECK_FLAG (ri->flags, BGP_INFO_REMOVED)) - pcounts[PCOUNT_REMOVED]++; + pc->count[PCOUNT_REMOVED]++; if (CHECK_FLAG (ri->flags, BGP_INFO_STALE)) - pcounts[PCOUNT_STALE]++; + pc->count[PCOUNT_STALE]++; if (CHECK_FLAG (ri->flags, BGP_INFO_VALID)) - pcounts[PCOUNT_VALID]++; + pc->count[PCOUNT_VALID]++; if (!CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE)) - pcounts[PCOUNT_PFCNT]++; + pc->count[PCOUNT_PFCNT]++; if (CHECK_FLAG (ri->flags, BGP_INFO_COUNTED)) { - pcounts[PCOUNT_COUNTED]++; + pc->count[PCOUNT_COUNTED]++; if (CHECK_FLAG (ri->flags, BGP_INFO_UNUSEABLE)) plog_warn (peer->log, "%s [pcount] %s/%d is counted but flags 0x%x", @@ -8491,7 +8844,32 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) } } } + return 0; +} +static int +bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) +{ + struct peer_pcounts pcounts = { .peer = peer }; + unsigned int i; + + if (!peer || !peer->bgp || !peer->afc[afi][safi] + || !peer->bgp->rib[afi][safi]) + { + vty_out (vty, "%% No such neighbor or address family%s", VTY_NEWLINE); + return CMD_WARNING; + } + + memset (&pcounts, 0, sizeof(pcounts)); + pcounts.peer = peer; + pcounts.table = peer->bgp->rib[afi][safi]; + + /* in-place call via thread subsystem so as to record execution time + * stats for the thread-walk (i.e. ensure this can't be blamed on + * on just vty_read()). + */ + thread_execute (bm->master, bgp_peer_count_walker, &pcounts, 0); + vty_out (vty, "Prefix counts for %s, %s%s", peer->host, afi_safi_print (afi, safi), VTY_NEWLINE); vty_out (vty, "PfxCt: %ld%s", peer->pcount[afi][safi], VTY_NEWLINE); @@ -8499,9 +8877,10 @@ bgp_peer_counts (struct vty *vty, struct peer *peer, afi_t afi, safi_t safi) VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE); for (i = 0; i < PCOUNT_MAX; i++) - vty_out (vty, "%20s: %-10d%s", pcount_strs[i], pcounts[i], VTY_NEWLINE); + vty_out (vty, "%20s: %-10d%s", + pcount_strs[i], pcounts.count[i], VTY_NEWLINE); - if (pcounts[PCOUNT_PFCNT] != peer->pcount[afi][safi]) + if (pcounts.count[PCOUNT_PFCNT] != peer->pcount[afi][safi]) { vty_out (vty, "%s [pcount] PfxCt drift!%s", peer->host, VTY_NEWLINE); @@ -11058,7 +11437,13 @@ bgp_route_init () install_element (ENABLE_NODE, &show_bgp_view_rsclient_cmd); install_element (ENABLE_NODE, &show_bgp_view_rsclient_route_cmd); install_element (ENABLE_NODE, &show_bgp_view_rsclient_prefix_cmd); - + + /* Statistics */ + install_element (ENABLE_NODE, &show_bgp_statistics_cmd); + install_element (ENABLE_NODE, &show_bgp_statistics_vpnv4_cmd); + install_element (ENABLE_NODE, &show_bgp_statistics_view_cmd); + install_element (ENABLE_NODE, &show_bgp_statistics_view_vpnv4_cmd); + /* old command */ install_element (VIEW_NODE, &show_ipv6_bgp_cmd); install_element (VIEW_NODE, &show_ipv6_bgp_route_cmd); -- cgit v1.2.3 From ca058a30b1ea57f83871ab4cf1c9a91ea4064d52 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 14 Sep 2006 02:58:49 +0000 Subject: [bgpd] Fix 0.99 shutdown regression, introduce Clearing and Deleted states 2006-09-14 Paul Jakma * (general) Fix some niggly issues around 'shutdown' and clearing by adding a Clearing FSM wait-state and a hidden 'Deleted' FSM state, to allow deleted peers to 'cool off' and hit 0 references. This introduces a slow memory leak of struct peer, however that's more a testament to the fragility of the reference counting than a bug in this patch, cleanup of reference counting to fix this is to follow. * bgpd.h: Add Clearing, Deleted states and Clearing_Completed and event. * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and Deleted. * bgp_fsm.h: Don't allow timer/event threads to set anything for Deleted peers. * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted needs to stop everything. (bgp_stop) Remove explicit fsm_change_status call, the general framework handles the transition. (bgp_start) Log a warning if a start is attempted on a peer that should stay down, trying to start a peer. (struct .. FSM) Add Clearing_Completed events, has little influence except when in state Clearing to signal wait-state can end. Add Clearing and Deleted states, former is a wait-state, latter is a placeholder state to allow peers to disappear quietly once refcounts settle. (bgp_event) Try reduce verbosity of FSM state-change debug, changes to same state are not interesting (Established->Established) Allow NULL action functions in FSM. * bgp_packet.c: (bgp_write) Use FSM events, rather than trying to twiddle directly with FSM state behind the back of FSM. (bgp_write_notify) ditto. (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else this patch crashes, now it leaks instead. * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed event, to end clearing. (bgp_clear_route) See extensive comments. * bgpd.c: (peer_free) should only be called while in Deleted, peer refcounting controls when peer_free is called. bgp_sync_delete should be here, not in peer_delete. (peer_delete) Initiate delete. Transition to Deleted state manually. When removing peer from indices that provide visibility of it, take great care to be idempotent wrt the reference counting of struct peer through those indices. Use bgp_timer_set, rather than replicating. Call to bgp_sync_delete isn't appropriate here, sync can be referenced while shutting down and finishing deletion. (peer_group_bind) Take care to be idempotent wrt list references indexing peers. --- bgpd/ChangeLog | 52 +++++++++++++++++++++++++++ bgpd/bgp_debug.c | 2 ++ bgpd/bgp_fsm.c | 104 +++++++++++++++++++++++++++++++++++++++++++----------- bgpd/bgp_fsm.h | 17 ++++++--- bgpd/bgp_packet.c | 27 +++----------- bgpd/bgp_route.c | 47 +++++++++++++++++------- bgpd/bgp_vty.c | 2 -- bgpd/bgpd.c | 85 +++++++++++++++++++++++++++++--------------- bgpd/bgpd.h | 8 +++-- 9 files changed, 251 insertions(+), 93 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 482beeda..02aaf3ab 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,55 @@ +2006-09-14 Paul Jakma + + * (general) Fix some niggly issues around 'shutdown' and clearing + by adding a Clearing FSM wait-state and a hidden 'Deleted' + FSM state, to allow deleted peers to 'cool off' and hit 0 + references. This introduces a slow memory leak of struct peer, + however that's more a testament to the fragility of the + reference counting than a bug in this patch, cleanup of + reference counting to fix this is to follow. + * bgpd.h: Add Clearing, Deleted states and Clearing_Completed + and event. + * bgp_debug.c: (bgp_status_msg[]) Add strings for Clearing and + Deleted. + * bgp_fsm.h: Don't allow timer/event threads to set anything + for Deleted peers. + * bgp_fsm.c: (bgp_timer_set) Add Clearing and Deleted. Deleted + needs to stop everything. + (bgp_stop) Remove explicit fsm_change_status call, the + general framework handles the transition. + (bgp_start) Log a warning if a start is attempted on a peer + that should stay down, trying to start a peer. + (struct .. FSM) Add Clearing_Completed + events, has little influence except when in state + Clearing to signal wait-state can end. + Add Clearing and Deleted states, former is a wait-state, + latter is a placeholder state to allow peers to disappear + quietly once refcounts settle. + (bgp_event) Try reduce verbosity of FSM state-change debug, + changes to same state are not interesting (Established->Established) + Allow NULL action functions in FSM. + * bgp_packet.c: (bgp_write) Use FSM events, rather than trying + to twiddle directly with FSM state behind the back of FSM. + (bgp_write_notify) ditto. + (bgp_read) Remove the vague ACCEPT_PEER peer_unlock, or else + this patch crashes, now it leaks instead. + * bgp_route.c: (bgp_clear_node_complete) Clearing_Completed + event, to end clearing. + (bgp_clear_route) See extensive comments. + * bgpd.c: (peer_free) should only be called while in Deleted, + peer refcounting controls when peer_free is called. + bgp_sync_delete should be here, not in peer_delete. + (peer_delete) Initiate delete. + Transition to Deleted state manually. + When removing peer from indices that provide visibility of it, + take great care to be idempotent wrt the reference counting + of struct peer through those indices. + Use bgp_timer_set, rather than replicating. + Call to bgp_sync_delete isn't appropriate here, sync can be + referenced while shutting down and finishing deletion. + (peer_group_bind) Take care to be idempotent wrt list references + indexing peers. + 2006-09-13 Paul Jakma * bgp_aspath.c: (aspath_highest) new, return highest ASN in an diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 1b398ee8..1e0fcd1f 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -62,6 +62,8 @@ struct message bgp_status_msg[] = { OpenSent, "OpenSent" }, { OpenConfirm, "OpenConfirm" }, { Established, "Established" }, + { Clearing, "Clearing" }, + { Deleted, "Deleted" }, }; int bgp_status_msg_max = BGP_STATUS_MAX; diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index 770a7911..bdb6517f 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -68,6 +68,11 @@ bgp_start_jitter (int time) return ((rand () % (time + 1)) - (time / 2)); } +/* Check if suppress start/restart of sessions to peer. */ +#define BGP_PEER_START_SUPPRESSED(P) \ + (CHECK_FLAG ((P)->flags, PEER_FLAG_SHUTDOWN) \ + || CHECK_FLAG ((P)->sflags, PEER_STATUS_PREFIX_OVERFLOW)) + /* Hook function called after bgp event is occered. And vty's neighbor command invoke this function after making neighbor structure. */ @@ -82,10 +87,7 @@ bgp_timer_set (struct peer *peer) /* First entry point of peer's finite state machine. In Idle status start timer is on unless peer is shutdown or peer is inactive. All other timer must be turned off */ - if (CHECK_FLAG (peer->flags, PEER_FLAG_SHUTDOWN) - || CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW) - || CHECK_FLAG (peer->sflags, PEER_STATUS_CLEARING) - || ! peer_active (peer)) + if (BGP_PEER_START_SUPPRESSED (peer) || ! peer_active (peer)) { BGP_TIMER_OFF (peer->t_start); } @@ -197,6 +199,17 @@ bgp_timer_set (struct peer *peer) } BGP_TIMER_OFF (peer->t_asorig); break; + case Deleted: + BGP_TIMER_OFF (peer->t_gr_restart); + BGP_TIMER_OFF (peer->t_gr_stale); + BGP_TIMER_OFF (peer->t_pmax_restart); + case Clearing: + BGP_TIMER_OFF (peer->t_start); + BGP_TIMER_OFF (peer->t_connect); + BGP_TIMER_OFF (peer->t_holdtime); + BGP_TIMER_OFF (peer->t_keepalive); + BGP_TIMER_OFF (peer->t_asorig); + BGP_TIMER_OFF (peer->t_routeadv); } } @@ -420,7 +433,6 @@ bgp_stop (struct peer *peer) if (peer->status == Established) { peer->dropped++; - bgp_fsm_change_status (peer, Idle); /* bgp log-neighbor-changes of neighbor Down */ if (bgp_flag_check (peer->bgp, BGP_FLAG_LOG_NEIGHBOR_CHANGES)) @@ -625,6 +637,14 @@ bgp_start (struct peer *peer) { int status; + if (BGP_PEER_START_SUPPRESSED (peer)) + { + if (BGP_DEBUG (fsm, FSM)) + plog_err (peer->log, "%s [FSM] Trying to start suppressed peer" + " - this is never supposed to happen!", peer->host); + return -1; + } + /* Scrub some information that might be left over from a previous, * session */ @@ -903,6 +923,7 @@ struct { {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */ {bgp_ignore, Idle}, /* Receive_UPDATE_message */ {bgp_ignore, Idle}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle}, /* Clearing_Completed */ }, { /* Connect */ @@ -919,6 +940,7 @@ struct { {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */ {bgp_ignore, Idle}, /* Receive_UPDATE_message */ {bgp_stop, Idle}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle}, /* Clearing_Completed */ }, { /* Active, */ @@ -935,6 +957,7 @@ struct { {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */ {bgp_ignore, Idle}, /* Receive_UPDATE_message */ {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle}, /* Clearing_Completed */ }, { /* OpenSent, */ @@ -951,6 +974,7 @@ struct { {bgp_ignore, Idle}, /* Receive_KEEPALIVE_message */ {bgp_ignore, Idle}, /* Receive_UPDATE_message */ {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle}, /* Clearing_Completed */ }, { /* OpenConfirm, */ @@ -967,22 +991,58 @@ struct { {bgp_establish, Established}, /* Receive_KEEPALIVE_message */ {bgp_ignore, Idle}, /* Receive_UPDATE_message */ {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle}, /* Clearing_Completed */ }, { /* Established, */ - {bgp_ignore, Established}, /* BGP_Start */ - {bgp_stop, Idle}, /* BGP_Stop */ - {bgp_stop, Idle}, /* TCP_connection_open */ - {bgp_stop, Idle}, /* TCP_connection_closed */ - {bgp_ignore, Idle}, /* TCP_connection_open_failed */ - {bgp_stop, Idle}, /* TCP_fatal_error */ - {bgp_ignore, Idle}, /* ConnectRetry_timer_expired */ - {bgp_fsm_holdtime_expire, Idle}, /* Hold_Timer_expired */ + {bgp_ignore, Established}, /* BGP_Start */ + {bgp_stop, Clearing}, /* BGP_Stop */ + {bgp_stop, Clearing}, /* TCP_connection_open */ + {bgp_stop, Clearing}, /* TCP_connection_closed */ + {bgp_ignore, Clearing}, /* TCP_connection_open_failed */ + {bgp_stop, Clearing}, /* TCP_fatal_error */ + {bgp_ignore, Clearing}, /* ConnectRetry_timer_expired */ + {bgp_fsm_holdtime_expire, Clearing}, /* Hold_Timer_expired */ {bgp_fsm_keepalive_expire, Established}, /* KeepAlive_timer_expired */ - {bgp_stop, Idle}, /* Receive_OPEN_message */ - {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */ - {bgp_fsm_update, Established}, /* Receive_UPDATE_message */ - {bgp_stop_with_error, Idle}, /* Receive_NOTIFICATION_message */ + {bgp_stop, Clearing}, /* Receive_OPEN_message */ + {bgp_fsm_keepalive, Established}, /* Receive_KEEPALIVE_message */ + {bgp_fsm_update, Established}, /* Receive_UPDATE_message */ + {bgp_stop_with_error, Clearing}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle}, /* Clearing_Completed */ + }, + { + /* Clearing, */ + {bgp_ignore, Clearing}, /* BGP_Start */ + {bgp_ignore, Clearing}, /* BGP_Stop */ + {bgp_ignore, Clearing}, /* TCP_connection_open */ + {bgp_ignore, Clearing}, /* TCP_connection_closed */ + {bgp_ignore, Clearing}, /* TCP_connection_open_failed */ + {bgp_ignore, Clearing}, /* TCP_fatal_error */ + {bgp_ignore, Clearing}, /* ConnectRetry_timer_expired */ + {bgp_ignore, Clearing}, /* Hold_Timer_expired */ + {bgp_ignore, Clearing}, /* KeepAlive_timer_expired */ + {bgp_ignore, Clearing}, /* Receive_OPEN_message */ + {bgp_ignore, Clearing}, /* Receive_KEEPALIVE_message */ + {bgp_ignore, Clearing}, /* Receive_UPDATE_message */ + {bgp_ignore, Clearing}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Idle }, /* Clearing_Completed */ + }, + { + /* Deleted, */ + {bgp_ignore, Deleted}, /* BGP_Start */ + {bgp_ignore, Deleted}, /* BGP_Stop */ + {bgp_ignore, Deleted}, /* TCP_connection_open */ + {bgp_ignore, Deleted}, /* TCP_connection_closed */ + {bgp_ignore, Deleted}, /* TCP_connection_open_failed */ + {bgp_ignore, Deleted}, /* TCP_fatal_error */ + {bgp_ignore, Deleted}, /* ConnectRetry_timer_expired */ + {bgp_ignore, Deleted}, /* Hold_Timer_expired */ + {bgp_ignore, Deleted}, /* KeepAlive_timer_expired */ + {bgp_ignore, Deleted}, /* Receive_OPEN_message */ + {bgp_ignore, Deleted}, /* Receive_KEEPALIVE_message */ + {bgp_ignore, Deleted}, /* Receive_UPDATE_message */ + {bgp_ignore, Deleted}, /* Receive_NOTIFICATION_message */ + {bgp_ignore, Deleted}, /* Clearing_Completed */ }, }; @@ -1001,14 +1061,15 @@ static const char *bgp_event_str[] = "Receive_OPEN_message", "Receive_KEEPALIVE_message", "Receive_UPDATE_message", - "Receive_NOTIFICATION_message" + "Receive_NOTIFICATION_message", + "Clearing_Completed", }; /* Execute event process. */ int bgp_event (struct thread *thread) { - int ret; + int ret = 0; int event; int next; struct peer *peer; @@ -1019,14 +1080,15 @@ bgp_event (struct thread *thread) /* Logging this event. */ next = FSM [peer->status -1][event - 1].next_state; - if (BGP_DEBUG (fsm, FSM)) + if (BGP_DEBUG (fsm, FSM) && peer->status != next) plog_debug (peer->log, "%s [FSM] %s (%s->%s)", peer->host, bgp_event_str[event], LOOKUP (bgp_status_msg, peer->status), LOOKUP (bgp_status_msg, next)); /* Call function. */ - ret = (*(FSM [peer->status - 1][event - 1].func))(peer); + if (FSM [peer->status -1][event - 1].func) + ret = (*(FSM [peer->status - 1][event - 1].func))(peer); /* When function do not want proceed next job return -1. */ if (ret >= 0) diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index e90f3b43..0a5d3715 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -43,7 +43,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #define BGP_WRITE_ON(T,F,V) \ do { \ - if (!T) \ + if (!(T) && (peer->status != Deleted)) \ { \ peer_lock (peer); \ THREAD_WRITE_ON(master,(T),(F),peer,(V)); \ @@ -61,7 +61,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #define BGP_TIMER_ON(T,F,V) \ do { \ - if (!T) \ + if (!(T) && (peer->status != Deleted)) \ { \ peer_lock (peer); \ THREAD_TIMER_ON(master,(T),(F),peer,(V)); \ @@ -79,8 +79,11 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA #define BGP_EVENT_ADD(P,E) \ do { \ - peer_lock (peer); /* bgp event reference */ \ - thread_add_event (master, bgp_event, (P), (E)); \ + if ((P)->status != Deleted) \ + { \ + peer_lock (peer); /* bgp event reference */ \ + thread_add_event (master, bgp_event, (P), (E)); \ + } \ } while (0) #define BGP_EVENT_DELETE(P) \ @@ -90,6 +93,12 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA thread_cancel_event (master, (P)); \ } while (0) +#define BGP_EVENT_FLUSH_ADD(P,E) \ + do { \ + BGP_EVENT_DELETE(P); \ + BGP_EVENT_ADD(P,E); \ + } while (0) + /* Prototypes. */ extern int bgp_event (struct thread *); extern int bgp_stop (struct peer *peer); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index 8b024a1c..da59d329 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -637,9 +637,7 @@ bgp_write (struct thread *thread) if (write_errno == EWOULDBLOCK || write_errno == EAGAIN) break; - BGP_EVENT_ADD (peer, BGP_Stop); - peer->status = Idle; - bgp_timer_set (peer); + BGP_EVENT_FLUSH_ADD (peer, TCP_fatal_error); return 0; } if (num != writenum) @@ -673,10 +671,8 @@ bgp_write (struct thread *thread) if (peer->v_start >= (60 * 2)) peer->v_start = (60 * 2); - BGP_EVENT_ADD (peer, BGP_Stop); - /*bgp_stop (peer);*/ - peer->status = Idle; - bgp_timer_set (peer); + /* Flush any existing events */ + BGP_EVENT_FLUSH_ADD (peer, BGP_Stop); return 0; case BGP_MSG_KEEPALIVE: peer->keepalive_out++; @@ -721,9 +717,7 @@ bgp_write_notify (struct peer *peer) ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s)); if (ret <= 0) { - BGP_EVENT_ADD (peer, BGP_Stop); - peer->status = Idle; - bgp_timer_set (peer); + BGP_EVENT_FLUSH_ADD (peer, TCP_fatal_error); return 0; } @@ -743,10 +737,7 @@ bgp_write_notify (struct peer *peer) if (peer->v_start >= (60 * 2)) peer->v_start = (60 * 2); - /* We don't call event manager at here for avoiding other events. */ - bgp_stop (peer); - peer->status = Idle; - bgp_timer_set (peer); + BGP_EVENT_FLUSH_ADD (peer, BGP_Stop); return 0; } @@ -2375,14 +2366,6 @@ bgp_read (struct thread *thread) if (BGP_DEBUG (events, EVENTS)) zlog_debug ("%s [Event] Accepting BGP peer delete", peer->host); peer_delete (peer); - /* we've lost track of a reference to ACCEPT_PEER somehow. It doesnt - * _seem_ to be the 'update realpeer with accept peer' hack, yet it - * *must* be.. Very very odd, but I give up trying to - * root cause this - ACCEPT_PEER is a dirty hack, it should be fixed - * instead, which would make root-causing this a moot point.. - * A hack because of a hack, appropriate. - */ - peer_unlock (peer); /* god knows what reference... ACCEPT_PEER sucks */ } return 0; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 2ce2ef4d..5dde41de 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -2527,11 +2527,10 @@ bgp_clear_node_complete (struct work_queue *wq) { struct peer *peer = wq->spec.data; - UNSET_FLAG (peer->sflags, PEER_STATUS_CLEARING); peer_unlock (peer); /* bgp_clear_node_complete */ /* Tickle FSM to start moving again */ - BGP_EVENT_ADD (peer, BGP_Start); + BGP_EVENT_ADD (peer, Clearing_Completed); } static void @@ -2593,9 +2592,10 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi) if (peer->clear_node_queue == NULL) bgp_clear_node_queue_init (peer); - /* bgp_fsm.c will not bring CLEARING sessions out of Idle this - * protects against peers which flap faster than we can we clear, - * which could lead to: + /* bgp_fsm.c keeps sessions in state Clearing, not transitioning to + * Idle until it receives a Clearing_Completed event. This protects + * against peers which flap faster than we can we clear, which could + * lead to: * * a) race with routes from the new session being installed before * clear_route_node visits the node (to delete the route of that @@ -2604,11 +2604,8 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi) * on the process_main queue. Fast-flapping could cause that queue * to grow and grow. */ - if (!CHECK_FLAG (peer->sflags, PEER_STATUS_CLEARING)) - { - SET_FLAG (peer->sflags, PEER_STATUS_CLEARING); - peer_lock (peer); /* bgp_clear_node_complete */ - } + if (!peer->clear_node_queue->thread) + peer_lock (peer); /* bgp_clear_node_complete */ if (safi != SAFI_MPLS_VPN) bgp_clear_route_table (peer, afi, safi, NULL, NULL); @@ -2624,11 +2621,37 @@ bgp_clear_route (struct peer *peer, afi_t afi, safi_t safi) bgp_clear_route_table (peer, afi, safi, NULL, rsclient); } - /* If no routes were cleared, nothing was added to workqueue, run the - * completion function now. + /* If no routes were cleared, nothing was added to workqueue, the + * completion function won't be run by workqueue code - call it here. + * + * Additionally, there is a presumption in FSM that clearing is only + * needed if peer state is Established - peers in pre-Established states + * shouldn't have any route-update state associated with them (in or out). + * + * We still get here from FSM through bgp_stop->clear_route_all in + * pre-Established though, so this is a useful sanity check to ensure + * the assumption above holds. + * + * At some future point, this check could be move to the top of the + * function, and do a quick early-return when state is + * pre-Established, avoiding above list and table scans. Once we're + * sure it is safe.. */ if (!peer->clear_node_queue->thread) bgp_clear_node_complete (peer->clear_node_queue); + else + { + /* clearing queue scheduled. Normal if in Established state + * (and about to transition out of it), but otherwise... + */ + if (peer->status != Established) + { + plog_err (peer->log, "%s [Error] State %s is not Established," + " but routes were cleared - bug!", + peer->host, LOOKUP (bgp_status_msg, peer->status)); + assert (peer->status == Established); + } + } } void diff --git a/bgpd/bgp_vty.c b/bgpd/bgp_vty.c index ec4b6c22..b108164f 100644 --- a/bgpd/bgp_vty.c +++ b/bgpd/bgp_vty.c @@ -6693,8 +6693,6 @@ bgp_show_summary (struct vty *vty, struct bgp *bgp, int afi, int safi) vty_out (vty, " Idle (Admin)"); else if (CHECK_FLAG (peer->sflags, PEER_STATUS_PREFIX_OVERFLOW)) vty_out (vty, " Idle (PfxCt)"); - else if (CHECK_FLAG (peer->sflags, PEER_STATUS_CLEARING)) - vty_out (vty, " Idle (Clrng)"); else vty_out (vty, " %-11s", LOOKUP(bgp_status_msg, peer->status)); } diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 8ed598d2..733b33a6 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -687,6 +687,15 @@ peer_sort (struct peer *peer) static inline void peer_free (struct peer *peer) { + assert (peer->status == Deleted); + + /* this /ought/ to have been done already through bgp_stop earlier, + * but just to be sure.. + */ + bgp_timer_set (peer); + BGP_READ_OFF (peer->t_read); + BGP_WRITE_OFF (peer->t_write); + if (peer->desc) XFREE (MTYPE_PEER_DESC, peer->desc); @@ -704,6 +713,7 @@ peer_free (struct peer *peer) if (peer->clear_node_queue) work_queue_free (peer->clear_node_queue); + bgp_sync_delete (peer); memset (peer, 0, sizeof (struct peer)); XFREE (MTYPE_BGP_PEER, peer); @@ -714,7 +724,8 @@ struct peer * peer_lock (struct peer *peer) { assert (peer && (peer->lock >= 0)); - + assert (peer->status != Deleted); + peer->lock++; return peer; @@ -761,18 +772,17 @@ peer_new () struct servent *sp; /* Allocate new peer. */ - peer = XMALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); - memset (peer, 0, sizeof (struct peer)); + peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); /* Set default value. */ peer->fd = -1; - peer->lock = 1; peer->v_start = BGP_INIT_START_TIMER; peer->v_connect = BGP_DEFAULT_CONNECT_RETRY; peer->v_asorig = BGP_DEFAULT_ASORIGINATE; peer->status = Idle; peer->ostatus = Idle; peer->weight = 0; + peer = peer_lock (peer); /* initial reference */ /* Set default flags. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) @@ -1139,7 +1149,17 @@ peer_nsf_stop (struct peer *peer) bgp_clear_route_all (peer); } -/* Delete peer from confguration. */ +/* Delete peer from confguration. + * + * The peer is moved to a dead-end "Deleted" neighbour-state, to allow + * it to "cool off" and refcounts to hit 0, at which state it is freed. + * + * This function /should/ take care to be idempotent, to guard against + * it being called multiple times through stray events that come in + * that happen to result in this function being called again. That + * said, getting here for a "Deleted" peer is a bug in the neighbour + * FSM. + */ int peer_delete (struct peer *peer) { @@ -1149,6 +1169,8 @@ peer_delete (struct peer *peer) struct bgp *bgp; struct bgp_filter *filter; + assert (peer->status != Deleted); + bgp = peer->bgp; if (CHECK_FLAG (peer->sflags, PEER_STATUS_NSF_WAIT)) @@ -1158,8 +1180,13 @@ peer_delete (struct peer *peer) relationship. */ if (peer->group) { - peer = peer_unlock (peer); /* peer-group reference */ - listnode_delete (peer->group->peer, peer); + struct listnode *pn; + + if ((pn = listnode_lookup (peer->group->peer, peer))) + { + peer = peer_unlock (peer); /* group->peer list reference */ + list_delete_node (peer->group->peer, pn); + } peer->group = NULL; } @@ -1169,29 +1196,25 @@ peer_delete (struct peer *peer) */ peer->last_reset = PEER_DOWN_NEIGHBOR_DELETE; bgp_stop (peer); - bgp_fsm_change_status (peer, Idle); /* stops all timers */ + bgp_fsm_change_status (peer, Deleted); + bgp_timer_set (peer); /* stops all timers for Deleted */ - /* Stop all timers - should already have been done in bgp_stop */ - BGP_TIMER_OFF (peer->t_start); - BGP_TIMER_OFF (peer->t_connect); - BGP_TIMER_OFF (peer->t_holdtime); - BGP_TIMER_OFF (peer->t_keepalive); - BGP_TIMER_OFF (peer->t_asorig); - BGP_TIMER_OFF (peer->t_routeadv); - BGP_TIMER_OFF (peer->t_pmax_restart); - BGP_TIMER_OFF (peer->t_gr_restart); - BGP_TIMER_OFF (peer->t_gr_stale); - /* Delete from all peer list. */ if (! CHECK_FLAG (peer->sflags, PEER_STATUS_GROUP)) { - peer_unlock (peer); /* bgp peer list reference */ - listnode_delete (bgp->peer, peer); + struct listnode *pn; + + if ((pn = listnode_lookup (bgp->peer, peer))) + { + peer_unlock (peer); /* bgp peer list reference */ + list_delete_node (bgp->peer, pn); + } - if (peer_rsclient_active (peer)) + if (peer_rsclient_active (peer) + && (pn = listnode_lookup (bgp->rsclient, peer))) { peer_unlock (peer); /* rsclient list reference */ - listnode_delete (bgp->rsclient, peer); + list_delete_node (bgp->rsclient, pn); } } @@ -1219,8 +1242,6 @@ peer_delete (struct peer *peer) sockunion_free (peer->su_remote); peer->su_local = peer->su_remote = NULL; - bgp_sync_delete (peer); - /* Free filter related memory. */ for (afi = AFI_IP; afi < AFI_MAX; afi++) for (safi = SAFI_UNICAST; safi < SAFI_MAX; safi++) @@ -1692,7 +1713,7 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, peer->group = group; peer->af_group[afi][safi] = 1; - peer = peer_lock (peer); /* peer-group group->peer reference */ + peer = peer_lock (peer); /* group->peer list reference */ listnode_add (group->peer, peer); peer_group2peer_config_copy (group, peer, afi, safi); @@ -1733,9 +1754,11 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, { peer->group = group; - peer = peer_lock (peer); /* peer-group group->peer reference */ + peer = peer_lock (peer); /* group->peer list reference */ listnode_add (group->peer, peer); } + else + assert (group && peer->group == group); if (first_member) { @@ -1759,13 +1782,16 @@ peer_group_bind (struct bgp *bgp, union sockunion *su, if (CHECK_FLAG(peer->af_flags[afi][safi], PEER_FLAG_RSERVER_CLIENT)) { + struct listnode *pn; + /* If it's not configured as RSERVER_CLIENT in any other address family, without being member of a peer_group, remove it from list bgp->rsclient.*/ - if (! peer_rsclient_active (peer)) + if (! peer_rsclient_active (peer) + && (pn = listnode_lookup (bgp->rsclient, peer))) { peer_unlock (peer); /* peer rsclient reference */ - listnode_delete (bgp->rsclient, peer); + list_delete_node (bgp->rsclient, pn); } bgp_table_finish (peer->rib[afi][safi]); @@ -1821,6 +1847,7 @@ peer_group_unbind (struct bgp *bgp, struct peer *peer, if (! peer_group_active (peer)) { + assert (listnode_lookup (group->peer, peer)); peer_unlock (peer); /* peer group list reference */ listnode_delete (group->peer, peer); peer->group = NULL; diff --git a/bgpd/bgpd.h b/bgpd/bgpd.h index b8ae30ae..8b180a43 100644 --- a/bgpd/bgpd.h +++ b/bgpd/bgpd.h @@ -386,7 +386,6 @@ struct peer #define PEER_STATUS_GROUP (1 << 4) /* peer-group conf */ #define PEER_STATUS_NSF_MODE (1 << 5) /* NSF aware peer */ #define PEER_STATUS_NSF_WAIT (1 << 6) /* wait comeback peer */ -#define PEER_STATUS_CLEARING (1 << 7) /* peers table being cleared */ /* Peer status af flags (reset in bgp_stop) */ u_int16_t af_sflags[AFI_MAX][SAFI_MAX]; @@ -662,7 +661,9 @@ struct bgp_nlri #define OpenSent 4 #define OpenConfirm 5 #define Established 6 -#define BGP_STATUS_MAX 7 +#define Clearing 7 +#define Deleted 8 +#define BGP_STATUS_MAX 9 /* BGP finite state machine events. */ #define BGP_Start 1 @@ -678,7 +679,8 @@ struct bgp_nlri #define Receive_KEEPALIVE_message 11 #define Receive_UPDATE_message 12 #define Receive_NOTIFICATION_message 13 -#define BGP_EVENTS_MAX 14 +#define Clearing_Completed 14 +#define BGP_EVENTS_MAX 15 /* BGP timers default value. */ #define BGP_INIT_START_TIMER 5 -- cgit v1.2.3 From 9fde6624fc480995449d8243fe85602d89927eb6 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 14 Sep 2006 03:02:02 +0000 Subject: [bgpd] simplify peer refcounts, squash slow peer leak 2006-09-14 Paul Jakma * (general) fix the peer refcount issue exposed by previous, by just removing refcounting of peer threads, which is mostly senseless as they're references leading from struct peer, which peer_free cancels anyway. No need to muck around.. * bgp_fsm.h: Just remove the refcounting from the various TIMER/READ/WRITE/EVENT ON/OFF/ADD macros. * bgp_fsm.c: (bgp_stop) use BGP_EVENT_FLUSH, no refcounts attached to events anymore. (bgp_event) remove peer_unlock, events not refcounted. * bgpd.c: (peer_free) flush events before free. --- bgpd/ChangeLog | 13 +++++++++++++ bgpd/bgp_fsm.c | 8 ++------ bgpd/bgp_fsm.h | 42 ++++++++++-------------------------------- bgpd/bgpd.c | 1 + 4 files changed, 26 insertions(+), 38 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 02aaf3ab..393b00d4 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,16 @@ +2006-09-14 Paul Jakma + + * (general) fix the peer refcount issue exposed by previous, by + just removing refcounting of peer threads, which is mostly + senseless as they're references leading from struct peer, + which peer_free cancels anyway. No need to muck around.. + * bgp_fsm.h: Just remove the refcounting from the various + TIMER/READ/WRITE/EVENT ON/OFF/ADD macros. + * bgp_fsm.c: (bgp_stop) use BGP_EVENT_FLUSH, no refcounts attached + to events anymore. + (bgp_event) remove peer_unlock, events not refcounted. + * bgpd.c: (peer_free) flush events before free. + 2006-09-14 Paul Jakma * (general) Fix some niggly issues around 'shutdown' and clearing diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index bdb6517f..cc2b2c3a 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -426,7 +426,6 @@ bgp_stop (struct peer *peer) { afi_t afi; safi_t safi; - unsigned int i; char orf_name[BUFSIZ]; /* Increment Dropped count. */ @@ -500,10 +499,8 @@ bgp_stop (struct peer *peer) BGP_TIMER_OFF (peer->t_asorig); BGP_TIMER_OFF (peer->t_routeadv); - /* Delete all existing events of the peer, - and corresponding peer ref-count */ - for (i = thread_cancel_event (master, peer); i > 0; i--) - peer_unlock (peer); /* thread event reference */ + /* Delete all existing events of the peer */ + BGP_EVENT_FLUSH (peer); /* Stream reset. */ peer->packet_size = 0; @@ -1101,6 +1098,5 @@ bgp_event (struct thread *thread) bgp_timer_set (peer); } - peer_unlock (peer); /* bgp-event peer reference */ return ret; } diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index 0a5d3715..c51bed37 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -25,77 +25,55 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA /* Macro for BGP read, write and timer thread. */ #define BGP_READ_ON(T,F,V) \ do { \ - if (!T) \ - { \ - peer_lock (peer); \ - THREAD_READ_ON(master,T,F,peer,V); \ - } \ + if (!(T) && (peer->status != Deleted)) \ + THREAD_READ_ON(master,T,F,peer,V); \ } while (0) #define BGP_READ_OFF(T) \ do { \ if (T) \ - { \ - peer_unlock (peer); \ - THREAD_READ_OFF(T); \ - } \ + THREAD_READ_OFF(T); \ } while (0) #define BGP_WRITE_ON(T,F,V) \ do { \ if (!(T) && (peer->status != Deleted)) \ - { \ - peer_lock (peer); \ - THREAD_WRITE_ON(master,(T),(F),peer,(V)); \ - } \ + THREAD_WRITE_ON(master,(T),(F),peer,(V)); \ } while (0) #define BGP_WRITE_OFF(T) \ do { \ if (T) \ - { \ - peer_unlock (peer); \ - THREAD_WRITE_OFF(T); \ - } \ + THREAD_WRITE_OFF(T); \ } while (0) #define BGP_TIMER_ON(T,F,V) \ do { \ if (!(T) && (peer->status != Deleted)) \ - { \ - peer_lock (peer); \ - THREAD_TIMER_ON(master,(T),(F),peer,(V)); \ - } \ + THREAD_TIMER_ON(master,(T),(F),peer,(V)); \ } while (0) #define BGP_TIMER_OFF(T) \ do { \ if (T) \ - { \ - peer_unlock (peer); \ - THREAD_TIMER_OFF(T); \ - } \ + THREAD_TIMER_OFF(T); \ } while (0) #define BGP_EVENT_ADD(P,E) \ do { \ if ((P)->status != Deleted) \ - { \ - peer_lock (peer); /* bgp event reference */ \ - thread_add_event (master, bgp_event, (P), (E)); \ - } \ + thread_add_event (master, bgp_event, (P), (E)); \ } while (0) -#define BGP_EVENT_DELETE(P) \ +#define BGP_EVENT_FLUSH(P) \ do { \ - peer_unlock (peer); /* bgp event peer reference */ \ assert (peer); \ thread_cancel_event (master, (P)); \ } while (0) #define BGP_EVENT_FLUSH_ADD(P,E) \ do { \ - BGP_EVENT_DELETE(P); \ + BGP_EVENT_FLUSH(P); \ BGP_EVENT_ADD(P,E); \ } while (0) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 733b33a6..89f82628 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -695,6 +695,7 @@ peer_free (struct peer *peer) bgp_timer_set (peer); BGP_READ_OFF (peer->t_read); BGP_WRITE_OFF (peer->t_write); + BGP_EVENT_FLUSH (peer); if (peer->desc) XFREE (MTYPE_PEER_DESC, peer->desc); -- cgit v1.2.3 From 8383a9bd2721dbd8fb1b657269a2cdc40b4226e1 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 14 Sep 2006 03:06:54 +0000 Subject: [bgpd] RIB statistics address space size shouldnt double count space 2006-09-14 Paul Jakma * bgp_route.c: (bgp_table_stats_walker) Address space announced should only count top-level unaggregateable prefixes, to avoid falling afoul of anti-dodgy-accounting regulations in various jurisdictions.. ;) --- bgpd/ChangeLog | 7 +++++++ bgpd/bgp_route.c | 11 ++++++----- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 393b00d4..e679f434 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,10 @@ +2006-09-14 Paul Jakma + + * bgp_route.c: (bgp_table_stats_walker) Address space announced + should only count top-level unaggregateable prefixes, to + avoid falling afoul of anti-dodgy-accounting regulations + in various jurisdictions.. ;) + 2006-09-14 Paul Jakma * (general) fix the peer refcount issue exposed by previous, by diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 5dde41de..7cf86438 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8522,14 +8522,15 @@ bgp_table_stats_walker (struct thread *t) prn = prn->parent; if (prn == NULL || prn == top) - ts->counts[BGP_STATS_UNAGGREGATEABLE]++; + { + ts->counts[BGP_STATS_UNAGGREGATEABLE]++; + /* announced address space */ + if (space) + ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen); + } else if (prn->info) ts->counts[BGP_STATS_MAX_AGGREGATEABLE]++; - /* announced address space */ - if (space) - ts->counts[BGP_STATS_SPACE] += 1 << (space - rn->p.prefixlen); - for (ri = rn->info; ri; ri = ri->next) { rinum++; -- cgit v1.2.3 From 09dd561eb444ab009103b2dde62db212eae7064a Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Thu, 14 Sep 2006 03:38:16 +0000 Subject: [bgpd] reduce the process queue hold time to something more sensible 2006-09-14 Paul Jakma * bgp_route.c: (bgp_process_queue_init) process queue hold time too high, adds extra memory load. Change to be much lower, until such time as it's made configurable. --- bgpd/ChangeLog | 3 +++ bgpd/bgp_route.c | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index e679f434..7f0130a9 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -4,6 +4,9 @@ should only count top-level unaggregateable prefixes, to avoid falling afoul of anti-dodgy-accounting regulations in various jurisdictions.. ;) + (bgp_process_queue_init) process queue hold time too high, + adds extra memory load. Change to be much lower, until such + time as it's made configurable. 2006-09-14 Paul Jakma diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7cf86438..cd28b4df 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -1474,7 +1474,7 @@ bgp_process_queue_init (void) bm->process_main_queue->spec.max_retries = bm->process_main_queue->spec.max_retries = 0; bm->process_rsclient_queue->spec.hold - = bm->process_main_queue->spec.hold = 500; + = bm->process_main_queue->spec.hold = 50; } void -- cgit v1.2.3 From 0cd1c32dc36ad650d6e21d44c3b289982d1f62a0 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 19 Sep 2006 18:51:53 +0000 Subject: [bgpd] Trivial fix of printf format/arg mismatch 2006-09-19 Andrew J. Schorr * bgpd.c: (peer_uptime) Fix printf format/arg mismatch in zlog_warn message (%ld/size_t -> %lu/u_long). --- bgpd/ChangeLog | 5 +++++ bgpd/bgpd.c | 3 +-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 7f0130a9..2294f89a 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,8 @@ +2006-09-19 Andrew J. Schorr + + * bgpd.c: (peer_uptime) Fix printf format/arg mismatch in + zlog_warn message (%ld/size_t -> %lu/u_long). + 2006-09-14 Paul Jakma * bgp_route.c: (bgp_table_stats_walker) Address space announced diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 89f82628..1ead13cf 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -4250,8 +4250,7 @@ peer_uptime (time_t uptime2, char *buf, size_t len) /* Check buffer length. */ if (len < BGP_UPTIME_LEN) { - /* XXX: warning: long int format, size_t arg (arg 2) */ - zlog_warn ("peer_uptime (): buffer shortage %ld", len); + zlog_warn ("peer_uptime (): buffer shortage %lu", (u_long)len); /* XXX: should return status instead of buf... */ snprintf (buf, len, " "); return buf; -- cgit v1.2.3 From 301e4fb0cfab692c9ec9cbd5fdcb50058547d7cf Mon Sep 17 00:00:00 2001 From: Greg Troxel Date: Wed, 20 Sep 2006 14:46:07 +0000 Subject: Add recent NetBSD/FreeBSD versions to list of what ought to work. Add Dragonfly. Clarify that the C99 requirement includes libraries and headers, not just compiler. --- INSTALL.quagga.txt | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/INSTALL.quagga.txt b/INSTALL.quagga.txt index b1bab82f..4ed9a67f 100644 --- a/INSTALL.quagga.txt +++ b/INSTALL.quagga.txt @@ -1,4 +1,4 @@ -# $Id: INSTALL.quagga.txt,v 1.11 2005/08/10 15:07:02 gdt Exp $ +# $Id$ -------------------------------------------------------------------------- Building and Installing Quagga from releases or snapshots: @@ -6,7 +6,8 @@ Building and Installing Quagga from releases or snapshots: The 'INSTALL' file contains generic instructions on how to use 'configure' scripts. -Quagga requires a C compiler supporting the C99 standard. +Quagga requires a C compiler (and associated header files and +libraries) supporting the C99 standard. Quagga requires a reasonable make. It is considered a bug if quagga does not compile with the system make on recent FreeBSD, NetBSD or @@ -20,11 +21,17 @@ following systems (where .x indicates the most recent release), or such systems "-current" versions. (Note that considering it a bug is not a guarantee of support, merely "we agree that it is broken".) + Dragonfly ? FreeBSD 4.x FreeBSD 5.x + FreeBSD 6.x + FreeBSD-current Linux [kernel/distribution information needed] NetBSD 1.6.x NetBSD 2.x + NetBSD 3.x + NetBSD 4.x + NetBSD-current OpenBSD ? [info needed on what should work] Solaris 9 Solaris 10 -- cgit v1.2.3 From 08c8367197cb847eb88942e5d7273cf3352d967f Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 25 Sep 2006 13:26:14 +0000 Subject: [ospfd] Improve some warning messages. 2006-09-25 Andrew J. Schorr * ospf_packet.c: (ospf_packet_dup, ospf_make_md5_digest) Fix zlog_warn messages to eliminate compiler warnings. (ospf_hello) Improve warning messages to show why we are complaining. --- ospfd/ChangeLog | 7 +++++++ ospfd/ospf_packet.c | 21 ++++++++++++++------- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 4da013a8..2046144e 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,10 @@ +2006-09-25 Andrew J. Schorr + + * ospf_packet.c: (ospf_packet_dup, ospf_make_md5_digest) + Fix zlog_warn messages to eliminate compiler warnings. + (ospf_hello) Improve warning messages to show why we + are complaining. + 2006-08-28 Andy Gay * ospf_packet.c: (ospf_make_db_desc) Assert added with More-bit diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index 91527395..ce90430d 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -216,8 +216,9 @@ ospf_packet_dup (struct ospf_packet *op) struct ospf_packet *new; if (stream_get_endp(op->s) != op->length) - zlog_warn ("ospf_packet_dup stream %ld ospf_packet %d size mismatch", - STREAM_SIZE(op->s), op->length); + /* XXX size_t */ + zlog_warn ("ospf_packet_dup stream %lu ospf_packet %u size mismatch", + (u_long)STREAM_SIZE(op->s), op->length); /* Reserve space for MD5 authentication that may be added later. */ new = ospf_packet_new (stream_get_endp(op->s) + OSPF_AUTH_MD5_SIZE); @@ -371,7 +372,9 @@ ospf_make_md5_digest (struct ospf_interface *oi, struct ospf_packet *op) op->length = ntohs (ospfh->length) + OSPF_AUTH_MD5_SIZE; if (stream_get_endp(op->s) != op->length) - zlog_warn("ospf_make_md5_digest: length mismatch stream %ld ospf_packet %d", stream_get_endp(op->s), op->length); + /* XXX size_t */ + zlog_warn("ospf_make_md5_digest: length mismatch stream %lu ospf_packet %u", + (u_long)stream_get_endp(op->s), op->length); return OSPF_AUTH_MD5_SIZE; } @@ -796,8 +799,10 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh, /* Compare Router Dead Interval. */ if (OSPF_IF_PARAM (oi, v_wait) != ntohl (hello->dead_interval)) { - zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch.", - inet_ntoa (ospfh->router_id)); + zlog_warn ("Packet %s [Hello:RECV]: RouterDeadInterval mismatch " + "(expected %u, but received %u).", + inet_ntoa(ospfh->router_id), + OSPF_IF_PARAM(oi, v_wait), ntohl(hello->dead_interval)); return; } @@ -806,8 +811,10 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh, { if (OSPF_IF_PARAM (oi, v_hello) != ntohs (hello->hello_interval)) { - zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch.", - inet_ntoa (ospfh->router_id)); + zlog_warn ("Packet %s [Hello:RECV]: HelloInterval mismatch " + "(expected %u, but received %u).", + inet_ntoa(ospfh->router_id), + OSPF_IF_PARAM(oi, v_hello), ntohs(hello->hello_interval)); return; } } -- cgit v1.2.3 From 965b83f9cc287ca36f5a4152c2ac39007c5bc6d8 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 26 Sep 2006 15:30:43 +0000 Subject: [snmp] Fix asn_build calls to pass correct variable sizes (fixes 64-bit issues) 2006-09-26 Pierre-Yves Ritschard * smux.c: (smux_open,smux_trap,smux_register) Fix various asn_build_* calls to pass the proper length in the final argument: use sizeof() instead of sizeof(), since there were several inconsistencies between the actual variable type and the size that was passed. This should fix some problems on 64-bit architectures where sizeof(int) != sizeof(long). --- lib/ChangeLog | 10 ++++++++++ lib/smux.c | 14 +++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 01f45ba5..00ba44e0 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,13 @@ +2006-09-26 Pierre-Yves Ritschard + + * smux.c: (smux_open,smux_trap,smux_register) Fix various + asn_build_* calls to pass the proper length in the final + argument: use sizeof() instead of sizeof(), + since there were several inconsistencies between the actual + variable type and the size that was passed. This should + fix some problems on 64-bit architectures where sizeof(int) + != sizeof(long). + 2006-08-25 Paul Jakma * thread.c: (general) Add support for monotonic clock, it may still diff --git a/lib/smux.c b/lib/smux.c index c9b7a880..1bec1209 100644 --- a/lib/smux.c +++ b/lib/smux.c @@ -963,7 +963,7 @@ smux_open (int sock) version = 0; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), - &version, sizeof (u_long)); + &version, sizeof (version)); /* SMUX connection oid. */ ptr = asn_build_objid (ptr, &len, @@ -1026,25 +1026,25 @@ smux_trap (oid *name, size_t namelen, ptr = asn_build_string (ptr, &len, (u_char) (ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_IPADDRESS), - (u_char *)&addr, sizeof (struct in_addr)); + (u_char *)&addr, sizeof (addr)); /* Generic trap integer. */ val = SNMP_TRAP_ENTERPRISESPECIFIC; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), - &val, sizeof (int)); + &val, sizeof (val)); /* Specific trap integer. */ val = sptrap; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), - &val, sizeof (int)); + &val, sizeof (val)); /* Timeticks timestamp. */ val = 0; ptr = asn_build_unsigned_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_TIMETICKS), - &val, sizeof (int)); + &val, sizeof (val)); /* Variables. */ h1 = ptr; @@ -1148,13 +1148,13 @@ smux_register (int sock) priority = -1; ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), - &priority, sizeof (u_long)); + &priority, sizeof (priority)); /* Operation. */ operation = 2; /* Register R/W */ ptr = asn_build_int (ptr, &len, (u_char)(ASN_UNIVERSAL | ASN_PRIMITIVE | ASN_INTEGER), - &operation, sizeof (u_long)); + &operation, sizeof (operation)); if (debug_smux) { -- cgit v1.2.3 From 98954844ae56d142e96341d5dff959ec5518111e Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 15 Oct 2006 23:33:50 +0000 Subject: [lib] Handle upgrade from SUNWzebra to Quagga for 'interface fooX:Y' commands 2006-10-14 Paul Jakma * if.c: (general) Handle upgrades from SUNWzebra, which tried to track each logical interface as a seperate struct interface, to Quagga, which assigns only one struct interface per ifindex. (if_sunwzebra_get) Try decompose a logical interface name (fooX:Y) to the 'primary' name (fooX), for Solaris. (interface_cmd) Use if_sunwzebra_get on Solaris. --- lib/ChangeLog | 10 ++++++++++ lib/if.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 56 insertions(+), 2 deletions(-) diff --git a/lib/ChangeLog b/lib/ChangeLog index 00ba44e0..f076e2f0 100644 --- a/lib/ChangeLog +++ b/lib/ChangeLog @@ -1,3 +1,13 @@ +2006-10-14 Paul Jakma + + * if.c: (general) Handle upgrades from SUNWzebra, which tried + to track each logical interface as a seperate struct + interface, to Quagga, which assigns only one struct interface + per ifindex. + (if_sunwzebra_get) Try decompose a logical interface name + (fooX:Y) to the 'primary' name (fooX), for Solaris. + (interface_cmd) Use if_sunwzebra_get on Solaris. + 2006-09-26 Pierre-Yves Ritschard * smux.c: (smux_open,smux_trap,smux_register) Fix various diff --git a/lib/if.c b/lib/if.c index c43d9564..4493cc74 100644 --- a/lib/if.c +++ b/lib/if.c @@ -501,9 +501,49 @@ DEFUN (no_interface_desc, return CMD_SUCCESS; } + +#ifdef SUNOS_5 +/* Need to handle upgrade from SUNWzebra to Quagga. SUNWzebra created + * a seperate struct interface for each logical interface, so config + * file may be full of 'interface fooX:Y'. Solaris however does not + * expose logical interfaces via PF_ROUTE, so trying to track logical + * interfaces can be fruitless, for that reason Quagga only tracks + * the primary IP interface. + * + * We try accomodate SUNWzebra by: + * - looking up the interface name, to see whether it exists, if so + * its useable + * - for protocol daemons, this could only because zebra told us of + * the interface + * - for zebra, only because it learnt from kernel + * - if not: + * - search the name to see if it contains a sub-ipif / logical interface + * seperator, the ':' char. If it does: + * - text up to that char must be the primary name - get that name. + * if not: + * - no idea, just get the name in its entirety. + */ +static struct interface * +if_sunwzebra_get (const char *name, size_t nlen) +{ + struct interface *ifp; + size_t seppos = 0; - -/* See also wrapper function zebra_interface() in zebra/interface.c */ + if ( (ifp = if_lookup_by_name_len(name, nlen)) != NULL) + return ifp; + + /* hunt the primary interface name... */ + while (seppos < nlen && name[seppos] != ':') + seppos++; + + /* Wont catch seperator as last char, e.g. 'foo0:' but thats invalid */ + if (seppos < nlen) + return if_get_by_name_len (name, seppos); + else + return if_get_by_name_len (name, nlen); +} +#endif /* SUNOS_5 */ + DEFUN (interface, interface_cmd, "interface IFNAME", @@ -521,7 +561,11 @@ DEFUN (interface, return CMD_WARNING; } +#ifdef SUNOS_5 + ifp = if_sunwzebra_get (argv[0], sl); +#else ifp = if_get_by_name_len(argv[0], sl); +#endif /* SUNOS_5 */ vty->index = ifp; vty->node = INTERFACE_NODE; -- cgit v1.2.3 From 876b8be0ab24721e8f94d47dde022563f76db992 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 15 Oct 2006 23:35:57 +0000 Subject: [daemon startup] Add --dry-run/-C argument to daemons, to check config file syntax 2006-10-04 Oliver Hookins * bgpd/bgp_main.c: Add configuration check option, with '-C' rather than '-c' for consistency between daemons. * isisd/isis_main.c: ditto * ospf6d/ospf6_main.c: ditto * ospfd/ospf_main.c: ditto * ripngd/ripng_main.c: ditto * vtysh/vtysh_main.c: ditto * ripd/rip_main.c: Change the config check option to '-C' and tidy up the code. * zebra/main.c: ditto 2006-10-04 Stergiakis Alexandros * ripd/rip_main.c: This trivial patch introduces a new command-line option '-c', which instructs zebra/ripd to check its configuration file for validity, print any error message, and then exit. This is useful when the configuration file is edited by hand or otherwise, and you simply want to validate it without any other effect. * zebra/main.c: ditto --- ChangeLog | 24 ++++++++++++++++++++++++ bgpd/bgp_main.c | 12 +++++++++++- isisd/isis_main.c | 12 +++++++++++- ospf6d/ospf6_main.c | 12 +++++++++++- ospfd/ospf_main.c | 12 +++++++++++- ripd/rip_main.c | 12 +++++++++++- ripngd/ripng_main.c | 12 +++++++++++- vtysh/vtysh_main.c | 12 +++++++++++- zebra/main.c | 14 ++++++++++++-- 9 files changed, 113 insertions(+), 9 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4763e5cb..053c413b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,27 @@ +2006-10-04 Oliver Hookins + + * bgpd/bgp_main.c: Add configuration check option, with + '-C' rather than '-c' for consistency between daemons. + * isisd/isis_main.c: ditto + * ospf6d/ospf6_main.c: ditto + * ospfd/ospf_main.c: ditto + * ripngd/ripng_main.c: ditto + * vtysh/vtysh_main.c: ditto + * ripd/rip_main.c: Change the config check option to + '-C' and tidy up the code. + * zebra/main.c: ditto + +2006-10-04 Stergiakis Alexandros + + * ripd/rip_main.c: This trivial patch introduces a new + command-line option '-c', which instructs zebra/ripd + to check its configuration file for validity, print + any error message, and then exit. This is useful when + the configuration file is edited by hand or otherwise, + and you simply want to validate it without any other + effect. + * zebra/main.c: ditto + 2006-08-27 Paul Jakma * configure.ac: Bump to 0.99.5 diff --git a/bgpd/bgp_main.c b/bgpd/bgp_main.c index 0baae3bf..ecfe62ef 100644 --- a/bgpd/bgp_main.c +++ b/bgpd/bgp_main.c @@ -50,6 +50,7 @@ struct option longopts[] = { "user", required_argument, NULL, 'u'}, { "group", required_argument, NULL, 'g'}, { "version", no_argument, NULL, 'v'}, + { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { 0 } }; @@ -141,6 +142,7 @@ redistribution between different routing protocols.\n\n\ -u, --user User to run as\n\ -g, --group Group to run as\n\ -v, --version Print program version\n\ +-C, --dryrun Check configuration for validity and exit\n\ -h, --help Display this help and exit\n\ \n\ Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); @@ -196,6 +198,7 @@ main (int argc, char **argv) char *p; int opt; int daemon_mode = 0; + int dryrun = 0; char *progname; struct thread thread; @@ -214,7 +217,7 @@ main (int argc, char **argv) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hp:A:P:rnu:g:v", longopts, 0); + opt = getopt_long (argc, argv, "df:i:hp:A:P:rnu:g:vC", longopts, 0); if (opt == EOF) break; @@ -265,6 +268,9 @@ main (int argc, char **argv) print_version (progname); exit (0); break; + case 'C': + dryrun = 1; + break; case 'h': usage (progname, 0); break; @@ -294,6 +300,10 @@ main (int argc, char **argv) /* Parse config file. */ vty_read_config (config_file, config_default); + /* Start execution only if not in dry-run mode */ + if(dryrun) + return(0); + /* Turn into daemon if daemon_mode is set. */ if (daemon_mode) daemon (0, 0); diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 6971874d..74fc6475 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -80,6 +80,7 @@ struct option longopts[] = { {"user", required_argument, NULL, 'u'}, {"group", required_argument, NULL, 'g'}, {"version", no_argument, NULL, 'v'}, + {"dryrun", no_argument, NULL, 'C'}, {"help", no_argument, NULL, 'h'}, {0} }; @@ -124,6 +125,7 @@ Daemon which manages IS-IS routing\n\n\ -u, --user User to run as\n\ -g, --group Group to run as\n\ -v, --version Print program version\n\ +-C, --dryrun Check configuration for validity and exit\n\ -h, --help Display this help and exit\n\ \n\ Report bugs to http://bugzilla.quagga.net\n", progname); @@ -213,6 +215,7 @@ main (int argc, char **argv, char **envp) struct thread thread; char *config_file = NULL; char *vty_addr = NULL; + int dryrun = 0; /* Get the programname without the preceding path. */ progname = ((p = strrchr (argv[0], '/')) ? ++p : argv[0]); @@ -233,7 +236,7 @@ main (int argc, char **argv, char **envp) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:v", longopts, 0); + opt = getopt_long (argc, argv, "df:i:hA:p:P:u:g:vC", longopts, 0); if (opt == EOF) break; @@ -278,6 +281,9 @@ main (int argc, char **argv, char **envp) print_version ("Zebra"); exit (0); break; + case 'C': + dryrun = 1; + break; case 'h': usage (0); break; @@ -312,6 +318,10 @@ main (int argc, char **argv, char **envp) vty_read_config (config_file, config_default); vty_read_config (config_file, config_default); + /* Start execution only if not in dry-run mode */ + if (dryrun) + return(0); + /* demonize */ if (daemon_mode) daemon (0, 0); diff --git a/ospf6d/ospf6_main.c b/ospf6d/ospf6_main.c index c40b46ed..8380bc89 100644 --- a/ospf6d/ospf6_main.c +++ b/ospf6d/ospf6_main.c @@ -77,6 +77,7 @@ struct option longopts[] = { "user", required_argument, NULL, 'u'}, { "group", required_argument, NULL, 'g'}, { "version", no_argument, NULL, 'v'}, + { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { 0 } }; @@ -114,6 +115,7 @@ Daemon which manages OSPF version 3.\n\n\ -u, --user User to run as\n\ -g, --group Group to run as\n\ -v, --version Print program version\n\ +-C, --dryrun Check configuration for validity and exit\n\ -h, --help Display this help and exit\n\ \n\ Report bugs to zebra@zebra.org\n", progname); @@ -184,6 +186,7 @@ main (int argc, char *argv[], char *envp[]) int vty_port = 0; char *config_file = NULL; struct thread thread; + int dryrun = 0; /* Set umask before anything for security */ umask (0027); @@ -194,7 +197,7 @@ main (int argc, char *argv[], char *envp[]) /* Command line argument treatment. */ while (1) { - opt = getopt_long (argc, argv, "df:i:hp:A:P:u:g:v", longopts, 0); + opt = getopt_long (argc, argv, "df:i:hp:A:P:u:g:vC", longopts, 0); if (opt == EOF) break; @@ -236,6 +239,9 @@ main (int argc, char *argv[], char *envp[]) print_version (progname); exit (0); break; + case 'C': + dryrun = 1; + break; case 'h': usage (progname, 0); break; @@ -271,6 +277,10 @@ main (int argc, char *argv[], char *envp[]) /* parse config file */ vty_read_config (config_file, config_default); + /* Start execution only if not in dry-run mode */ + if (dryrun) + return(0); + if (daemon_mode) daemon (0, 0); diff --git a/ospfd/ospf_main.c b/ospfd/ospf_main.c index c105f192..27a12dd0 100644 --- a/ospfd/ospf_main.c +++ b/ospfd/ospf_main.c @@ -81,6 +81,7 @@ struct option longopts[] = { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, { "log_mode", no_argument, NULL, 'l'}, + { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, @@ -122,6 +123,7 @@ Daemon which manages OSPF.\n\n\ -g, --group Group to run as\n\ -a. --apiserver Enable OSPF apiserver\n\ -v, --version Print program version\n\ +-C, --dryrun Check configuration for validity and exit\n\ -h, --help Display this help and exit\n\ \n\ Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); @@ -182,6 +184,7 @@ main (int argc, char **argv) char *config_file = NULL; char *progname; struct thread thread; + int dryrun = 0; /* Set umask before anything for security */ umask (0027); @@ -212,7 +215,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:av", longopts, 0); + opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:avC", longopts, 0); if (opt == EOF) break; @@ -259,6 +262,9 @@ main (int argc, char **argv) print_version (progname); exit (0); break; + case 'C': + dryrun = 1; + break; case 'h': usage (progname, 0); break; @@ -303,6 +309,10 @@ main (int argc, char **argv) /* Get configuration file. */ vty_read_config (config_file, config_default); + /* Start execution only if not in dry-run mode */ + if (dryrun) + return(0); + /* Change to the daemon program. */ if (daemon_mode) daemon (0, 0); diff --git a/ripd/rip_main.c b/ripd/rip_main.c index c9d564b7..dfcd6c26 100644 --- a/ripd/rip_main.c +++ b/ripd/rip_main.c @@ -42,6 +42,7 @@ static struct option longopts[] = { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, { "help", no_argument, NULL, 'h'}, + { "dryrun", no_argument, NULL, 'C'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, { "retain", no_argument, NULL, 'r'}, @@ -110,6 +111,7 @@ Daemon which manages RIP version 1 and 2.\n\n\ -i, --pid_file Set process identifier file name\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ +-C, --dryrun Check configuration for validity and exit\n\ -r, --retain When program terminates, retain added route by ripd.\n\ -u, --user User to run as\n\ -g, --group Group to run as\n\ @@ -185,6 +187,7 @@ main (int argc, char **argv) { char *p; int daemon_mode = 0; + int dryrun = 0; char *progname; struct thread thread; @@ -203,7 +206,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "df:i:hA:P:u:g:rv", longopts, 0); + opt = getopt_long (argc, argv, "df:i:hA:P:u:g:rvC", longopts, 0); if (opt == EOF) break; @@ -238,6 +241,9 @@ main (int argc, char **argv) case 'r': retain_mode = 1; break; + case 'C': + dryrun = 1; + break; case 'u': ripd_privs.user = optarg; break; @@ -280,6 +286,10 @@ main (int argc, char **argv) /* Get configuration file. */ vty_read_config (config_file, config_default); + /* Start execution only if not in dry-run mode */ + if(dryrun) + return (0); + /* Change to the daemon program. */ if (daemon_mode) daemon (0, 0); diff --git a/ripngd/ripng_main.c b/ripngd/ripng_main.c index e6276c1b..70553910 100644 --- a/ripngd/ripng_main.c +++ b/ripngd/ripng_main.c @@ -48,6 +48,7 @@ struct option longopts[] = { "config_file", required_argument, NULL, 'f'}, { "pid_file", required_argument, NULL, 'i'}, { "log_mode", no_argument, NULL, 'l'}, + { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, @@ -119,6 +120,7 @@ Daemon which manages RIPng.\n\n\ -u, --user User to run as\n\ -g, --group Group to run as\n\ -v, --version Print program version\n\ +-C, --dryrun Check configuration for validity and exit\n\ -h, --help Display this help and exit\n\ \n\ Report bugs to %s\n", progname, ZEBRA_BUG_ADDRESS); @@ -190,6 +192,7 @@ main (int argc, char **argv) int daemon_mode = 0; char *progname; struct thread thread; + int dryrun = 0; /* Set umask before anything for security */ umask (0027); @@ -204,7 +207,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:v", longopts, 0); + opt = getopt_long (argc, argv, "dlf:i:hA:P:u:g:vC", longopts, 0); if (opt == EOF) break; @@ -252,6 +255,9 @@ main (int argc, char **argv) print_version (progname); exit (0); break; + case 'C': + dryrun = 1; + break; case 'h': usage (progname, 0); break; @@ -281,6 +287,10 @@ main (int argc, char **argv) /* Get configuration file. */ vty_read_config (config_file, config_default); + /* Start execution only if not in dry-run mode */ + if(dryrun) + return(0); + /* Change to the daemon program. */ if (daemon_mode) daemon (0, 0); diff --git a/vtysh/vtysh_main.c b/vtysh/vtysh_main.c index 134bcf73..51f376c7 100644 --- a/vtysh/vtysh_main.c +++ b/vtysh/vtysh_main.c @@ -138,6 +138,7 @@ usage (int status) "-c, --command Execute argument as command\n" \ "-d, --daemon Connect only to the specified daemon\n" \ "-E, --echo Echo prompt and command in -c mode\n" \ + "-C, --dryrun Check configuration for validity and exit\n" \ "-h, --help Display this help and exit\n\n" \ "Note that multiple commands may be executed from the command\n" \ "line by passing multiple -c args, or by embedding linefeed\n" \ @@ -156,6 +157,7 @@ struct option longopts[] = { "command", required_argument, NULL, 'c'}, { "daemon", required_argument, NULL, 'd'}, { "echo", no_argument, NULL, 'E'}, + { "dryrun", no_argument, NULL, 'C'}, { "help", no_argument, NULL, 'h'}, { 0 } }; @@ -195,6 +197,7 @@ main (int argc, char **argv, char **env) { char *p; int opt; + int dryrun = 0; int boot_flag = 0; const char *daemon_name = NULL; struct cmd_rec { @@ -210,7 +213,7 @@ main (int argc, char **argv, char **env) /* Option handling. */ while (1) { - opt = getopt_long (argc, argv, "be:c:d:Eh", longopts, 0); + opt = getopt_long (argc, argv, "be:c:d:EhC", longopts, 0); if (opt == EOF) break; @@ -242,6 +245,9 @@ main (int argc, char **argv, char **env) case 'E': echo_command = 1; break; + case 'C': + dryrun = 1; + break; case 'h': usage (0); break; @@ -270,6 +276,10 @@ main (int argc, char **argv, char **env) /* Read vtysh configuration file before connecting to daemons. */ vtysh_read_config (config_default); + /* Start execution only if not in dry-run mode */ + if(dryrun) + return(0); + /* Make sure we pass authentication before proceeding. */ vtysh_auth (); diff --git a/zebra/main.c b/zebra/main.c index dbe1b537..ed45bd13 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -76,6 +76,7 @@ struct option longopts[] = { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, { "retain", no_argument, NULL, 'r'}, + { "dryrun", no_argument, NULL, 'C'}, #ifdef HAVE_NETLINK { "nl-bufsize", required_argument, NULL, 's'}, #endif /* HAVE_NETLINK */ @@ -131,6 +132,7 @@ usage (char *progname, int status) "-k, --keep_kernel Don't delete old routes which installed by "\ "zebra.\n"\ "-l, --log_mode Set verbose log mode flag\n"\ + "-C, --dryrun Check configuration for validity and exit\n"\ "-A, --vty_addr Set vty's bind address\n"\ "-P, --vty_port Set vty's port number\n"\ "-r, --retain When program terminates, retain added route "\ @@ -208,6 +210,7 @@ main (int argc, char **argv) char *p; char *vty_addr = NULL; int vty_port = ZEBRA_VTY_PORT; + int dryrun = 0; int batch_mode = 0; int daemon_mode = 0; char *config_file = NULL; @@ -228,9 +231,9 @@ main (int argc, char **argv) int opt; #ifdef HAVE_NETLINK - opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vs:", longopts, 0); + opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vs:C", longopts, 0); #else - opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:v", longopts, 0); + opt = getopt_long (argc, argv, "bdklf:i:hA:P:ru:g:vC", longopts, 0); #endif /* HAVE_NETLINK */ if (opt == EOF) @@ -248,6 +251,9 @@ main (int argc, char **argv) case 'k': keep_kernel_mode = 1; break; + case 'C': + dryrun = 1; + break; case 'l': /* log_mode = 1; */ break; @@ -345,6 +351,10 @@ main (int argc, char **argv) /* Configuration file read*/ vty_read_config (config_file, config_default); + /* Don't start execution if we are in dry-run mode */ + if (dryrun) + return(0); + /* Clean up rib. */ rib_weed_tables (); -- cgit v1.2.3 From dcdf399fbc7420d3edc230c9646f720825fcecda Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 15 Oct 2006 23:39:59 +0000 Subject: [bgpd] Bug #302 fixes. ClearingCompleted event gets flushed, leaving peers stuck in Clearing. 2006-10-14 Paul Jakma * bgp_fsm.h: Remove BGP_EVENT_FLUSH_ADD, dangerous and not needed. * bgp_fsm.c: (bgp_stop) Move BGP_EVENT_FLUSH to the top of the of the function, otherwise it could flush a ClearingCompleted event, bug #302. * bgp_packet.c: Replace all BGP_EVENT_FLUSH_ADD with BGP_EVENT_ADD, fixing bug #302. --- bgpd/ChangeLog | 10 ++++++++++ bgpd/bgp_fsm.c | 6 +++--- bgpd/bgp_fsm.h | 6 ------ bgpd/bgp_packet.c | 8 ++++---- 4 files changed, 17 insertions(+), 13 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 2294f89a..c33562da 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,13 @@ +2006-10-14 Paul Jakma + + * bgp_fsm.h: Remove BGP_EVENT_FLUSH_ADD, dangerous and not + needed. + * bgp_fsm.c: (bgp_stop) Move BGP_EVENT_FLUSH to the top of the + of the function, otherwise it could flush a ClearingCompleted + event, bug #302. + * bgp_packet.c: Replace all BGP_EVENT_FLUSH_ADD with + BGP_EVENT_ADD, fixing bug #302. + 2006-09-19 Andrew J. Schorr * bgpd.c: (peer_uptime) Fix printf format/arg mismatch in diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index cc2b2c3a..ef8dfea4 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -428,6 +428,9 @@ bgp_stop (struct peer *peer) safi_t safi; char orf_name[BUFSIZ]; + /* Delete all existing events of the peer */ + BGP_EVENT_FLUSH (peer); + /* Increment Dropped count. */ if (peer->status == Established) { @@ -499,9 +502,6 @@ bgp_stop (struct peer *peer) BGP_TIMER_OFF (peer->t_asorig); BGP_TIMER_OFF (peer->t_routeadv); - /* Delete all existing events of the peer */ - BGP_EVENT_FLUSH (peer); - /* Stream reset. */ peer->packet_size = 0; diff --git a/bgpd/bgp_fsm.h b/bgpd/bgp_fsm.h index c51bed37..a749f8ea 100644 --- a/bgpd/bgp_fsm.h +++ b/bgpd/bgp_fsm.h @@ -71,12 +71,6 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA thread_cancel_event (master, (P)); \ } while (0) -#define BGP_EVENT_FLUSH_ADD(P,E) \ - do { \ - BGP_EVENT_FLUSH(P); \ - BGP_EVENT_ADD(P,E); \ - } while (0) - /* Prototypes. */ extern int bgp_event (struct thread *); extern int bgp_stop (struct peer *peer); diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index da59d329..cf6d00f1 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -637,7 +637,7 @@ bgp_write (struct thread *thread) if (write_errno == EWOULDBLOCK || write_errno == EAGAIN) break; - BGP_EVENT_FLUSH_ADD (peer, TCP_fatal_error); + BGP_EVENT_ADD (peer, TCP_fatal_error); return 0; } if (num != writenum) @@ -672,7 +672,7 @@ bgp_write (struct thread *thread) peer->v_start = (60 * 2); /* Flush any existing events */ - BGP_EVENT_FLUSH_ADD (peer, BGP_Stop); + BGP_EVENT_ADD (peer, BGP_Stop); return 0; case BGP_MSG_KEEPALIVE: peer->keepalive_out++; @@ -717,7 +717,7 @@ bgp_write_notify (struct peer *peer) ret = writen (peer->fd, STREAM_DATA (s), stream_get_endp (s)); if (ret <= 0) { - BGP_EVENT_FLUSH_ADD (peer, TCP_fatal_error); + BGP_EVENT_ADD (peer, TCP_fatal_error); return 0; } @@ -737,7 +737,7 @@ bgp_write_notify (struct peer *peer) if (peer->v_start >= (60 * 2)) peer->v_start = (60 * 2); - BGP_EVENT_FLUSH_ADD (peer, BGP_Stop); + BGP_EVENT_ADD (peer, BGP_Stop); return 0; } -- cgit v1.2.3 From 53d9f67a18dc59fd688fce999cb35653010a54fb Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 15 Oct 2006 23:41:16 +0000 Subject: [bgpd] CID#73, potential crash in bgp statistics if called for AFI/SAFI with emtpy table 2006-10-15 Paul Jakma * bgp_route.c: (bgp_table_stats_walker) NULL deref if table is empty, bgp_table_top may return NULL, Coverity CID#73. --- bgpd/ChangeLog | 5 +++++ bgpd/bgp_route.c | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index c33562da..56107329 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,8 @@ +2006-10-15 Paul Jakma + + * bgp_route.c: (bgp_table_stats_walker) NULL deref if table is + empty, bgp_table_top may return NULL, Coverity CID#73. + 2006-10-14 Paul Jakma * bgp_fsm.h: Remove BGP_EVENT_FLUSH_ADD, dangerous and not diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index cd28b4df..7b369748 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8481,7 +8481,8 @@ bgp_table_stats_walker (struct thread *t) struct bgp_table_stats *ts = THREAD_ARG (t); unsigned int space = 0; - top = bgp_table_top (ts->table); + if (!(top = bgp_table_top (ts->table))) + return 0; switch (top->p.family) { -- cgit v1.2.3 From ed3ebfa36b45fe487015e1918e848f0ff4500bff Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 15 Oct 2006 23:50:16 +0000 Subject: [bgpd] Coverity CID #64: Needless NULL check, CID #64: Deref of potentially NULL pointer. 2006-10-15 Paul Jakma * bgp_packet.c: (bgp_update_packet) adv->rn can not be NULL, check is bogus - changed to assert(), CID#64. binfo is checked for NULL, but then dereferenced unconditionally, fix, CID #63. (bgp_withdraw_packet) Assert adv->rn is valid, as with bgp_update_packet(). --- bgpd/ChangeLog | 6 ++++++ bgpd/bgp_packet.c | 15 ++++++++++----- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 56107329..83f9d493 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -2,6 +2,12 @@ * bgp_route.c: (bgp_table_stats_walker) NULL deref if table is empty, bgp_table_top may return NULL, Coverity CID#73. + * bgp_packet.c: (bgp_update_packet) adv->rn can not be NULL, + check is bogus - changed to assert(), CID#64. + binfo is checked for NULL, but then dereferenced + unconditionally, fix, CID #63. + (bgp_withdraw_packet) Assert adv->rn is valid, as with + bgp_update_packet(). 2006-10-14 Paul Jakma diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c index cf6d00f1..9859e50b 100644 --- a/bgpd/bgp_packet.c +++ b/bgpd/bgp_packet.c @@ -158,14 +158,14 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi) while (adv) { - if (adv->rn) - rn = adv->rn; + assert (adv->rn); + rn = adv->rn; adj = adv->adj; if (adv->binfo) binfo = adv->binfo; /* When remaining space can't include NLRI and it's length. */ - if (rn && STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen)) + if (STREAM_REMAIN (s) <= BGP_NLRI_LENGTH + PSIZE (rn->p.prefixlen)) break; /* If packet is empty, set attribute. */ @@ -173,11 +173,15 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi) { struct prefix_rd *prd = NULL; u_char *tag = NULL; + struct peer *from = NULL; if (rn->prn) prd = (struct prefix_rd *) &rn->prn->p; if (binfo) - tag = binfo->tag; + { + tag = binfo->tag; + from = binfo->peer; + } bgp_packet_set_marker (s, BGP_MSG_UPDATE); stream_putw (s, 0); @@ -186,7 +190,7 @@ bgp_update_packet (struct peer *peer, afi_t afi, safi_t safi) total_attr_len = bgp_packet_attribute (NULL, peer, s, adv->baa->attr, &rn->p, afi, safi, - binfo->peer, prd, tag); + from, prd, tag); stream_putw_at (s, pos, total_attr_len); } @@ -288,6 +292,7 @@ bgp_withdraw_packet (struct peer *peer, afi_t afi, safi_t safi) while ((adv = FIFO_HEAD (&peer->sync[afi][safi]->withdraw)) != NULL) { + assert (adv->rn); adj = adv->adj; rn = adv->rn; -- cgit v1.2.3 From 6f58544db526b4dfb09d45f8507926b0ae5fe12b Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 22 Oct 2006 19:13:07 +0000 Subject: [bgpd] struct peer must have bgp field valid (redistribute crash) 2006-10-19 Paul Jakma * bgpd.c: (peer_new) bgp element of peer absolutely must be filled in, make peer_new() require it as argument and update all callers. Fixes a crash reported by Jan 'yanek' Bortl and Andrew Schorr where bgpd would crash in bgp_pcount_adjust trying to dereference the bgp member of bgp->peer_self, triggered through redistribution. * bgp_route.c: (bgp_pcount_adjust) assert sanity of arguments. --- bgpd/ChangeLog | 10 ++++++++++ bgpd/bgp_route.c | 3 +++ bgpd/bgpd.c | 21 ++++++++++++--------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 83f9d493..701627c8 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,13 @@ +2006-10-19 Paul Jakma + + * bgpd.c: (peer_new) bgp element of peer absolutely must be + filled in, make peer_new() require it as argument and update + all callers. Fixes a crash reported by Jan 'yanek' Bortl and + Andrew Schorr where bgpd would crash in bgp_pcount_adjust + trying to dereference the bgp member of bgp->peer_self, + triggered through redistribution. + * bgp_route.c: (bgp_pcount_adjust) assert sanity of arguments. + 2006-10-15 Paul Jakma * bgp_route.c: (bgp_table_stats_walker) NULL deref if table is diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7b369748..3584b21a 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -196,6 +196,9 @@ bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri) static void bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) { + assert (rn && rn->table); + assert (ri && ri->peer && ri->peer->bgp); + /* Ignore 'pcount' for RS-client tables */ if (rn->table->type != BGP_TABLE_MAIN || ri->peer == ri->peer->bgp->peer_self) diff --git a/bgpd/bgpd.c b/bgpd/bgpd.c index 1ead13cf..3f841078 100644 --- a/bgpd/bgpd.c +++ b/bgpd/bgpd.c @@ -765,13 +765,18 @@ peer_unlock (struct peer *peer) /* Allocate new peer object, implicitely locked. */ static struct peer * -peer_new () +peer_new (struct bgp *bgp) { afi_t afi; safi_t safi; struct peer *peer; struct servent *sp; - + + /* bgp argument is absolutely required */ + assert (bgp); + if (!bgp) + return NULL; + /* Allocate new peer. */ peer = XCALLOC (MTYPE_BGP_PEER, sizeof (struct peer)); @@ -783,6 +788,7 @@ peer_new () peer->status = Idle; peer->ostatus = Idle; peer->weight = 0; + peer->bgp = bgp; peer = peer_lock (peer); /* initial reference */ /* Set default flags. */ @@ -821,8 +827,7 @@ peer_create (union sockunion *su, struct bgp *bgp, as_t local_as, struct peer *peer; char buf[SU_ADDRSTRLEN]; - peer = peer_new (); - peer->bgp = bgp; + peer = peer_new (bgp); peer->su = *su; peer->local_as = local_as; peer->as = remote_as; @@ -868,8 +873,7 @@ peer_create_accept (struct bgp *bgp) { struct peer *peer; - peer = peer_new (); - peer->bgp = bgp; + peer = peer_new (bgp); peer = peer_lock (peer); /* bgp peer list reference */ listnode_add_sort (bgp->peer, peer); @@ -1344,11 +1348,10 @@ peer_group_get (struct bgp *bgp, const char *name) group->bgp = bgp; group->name = strdup (name); group->peer = list_new (); - group->conf = peer_new (); + group->conf = peer_new (bgp); if (! bgp_flag_check (bgp, BGP_FLAG_NO_DEFAULT_IPV4)) group->conf->afc[AFI_IP][SAFI_UNICAST] = 1; group->conf->host = strdup (name); - group->conf->bgp = bgp; group->conf->group = group; group->conf->as = 0; group->conf->ttl = 1; @@ -1883,7 +1886,7 @@ bgp_create (as_t *as, const char *name) if ( (bgp = XCALLOC (MTYPE_BGP, sizeof (struct bgp))) == NULL) return NULL; - bgp->peer_self = peer_new (); + bgp->peer_self = peer_new (bgp); bgp->peer_self->host = strdup ("Static announcement"); bgp->peer = list_new (); -- cgit v1.2.3 From 7ffa8fa2322fb759cf1f93730cde2cee3d4ad8ee Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Sun, 22 Oct 2006 20:07:53 +0000 Subject: [ospfd] Add passive-interface default support 2006-10-22 Yar Tikhiy * (general) Add support for passive-interface default (with minor edits by Paul Jakma). * ospf_interface.h: Add OSPF_IF_PASSIVE_STATUS macro, looking at configured value, or the global 'default' value, as required. * ospf_interface.c: (ospf_if_new_hook) Leave passive unconfigured per default, allowing global 'default' to take effect for unconfigured interfaces. * ospf_packet.c: (various) use OSPF_IF_PASSIVE_STATUS * ospf_vty.c: (ospf_passive_interface_default) new function, unset passive from all interfaces if default is enabled, as the per-iface settings become redundant. (ospf_passive_interface_update) new func, update passive setting taking global default into account. ({no,}ospf_passive_interface_addr_cmd) Add support for 'default' variant of command. (show_ip_ospf_interface_sub) Update to take global default into account when printing passive status. (ospf_config_write) ditto. * ospfd.c: (ospf_new) set global passive-interface default. * ospfd.h: (struct ospf) Add field for global passive-interface. --- ospfd/ChangeLog | 25 +++++++ ospfd/ospf_interface.c | 3 - ospfd/ospf_interface.h | 7 ++ ospfd/ospf_packet.c | 6 +- ospfd/ospf_vty.c | 191 ++++++++++++++++++++++++++++++++++++------------- ospfd/ospfd.c | 2 + ospfd/ospfd.h | 1 + 7 files changed, 181 insertions(+), 54 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 2046144e..8a215e6b 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,28 @@ +2006-10-22 Yar Tikhiy + + * (general) Add support for passive-interface default (with + minor edits by Paul Jakma). + * ospf_interface.h: Add OSPF_IF_PASSIVE_STATUS macro, looking + at configured value, or the global 'default' value, as + required. + * ospf_interface.c: (ospf_if_new_hook) Leave passive + unconfigured per default, allowing global 'default' to + take effect for unconfigured interfaces. + * ospf_packet.c: (various) use OSPF_IF_PASSIVE_STATUS + * ospf_vty.c: (ospf_passive_interface_default) new function, + unset passive from all interfaces if default is enabled, as + the per-iface settings become redundant. + (ospf_passive_interface_update) new func, update passive + setting taking global default into account. + ({no,}ospf_passive_interface_addr_cmd) Add support for + 'default' variant of command. + (show_ip_ospf_interface_sub) Update to take global + default into account when printing passive status. + (ospf_config_write) ditto. + * ospfd.c: (ospf_new) set global passive-interface default. + * ospfd.h: (struct ospf) Add field for global + passive-interface. + 2006-09-25 Andrew J. Schorr * ospf_packet.c: (ospf_packet_dup, ospf_make_md5_digest) diff --git a/ospfd/ospf_interface.c b/ospfd/ospf_interface.c index 31275f89..b6e34746 100644 --- a/ospfd/ospf_interface.c +++ b/ospfd/ospf_interface.c @@ -682,9 +682,6 @@ ospf_if_new_hook (struct interface *ifp) IF_DEF_PARAMS (ifp)->mtu_ignore = OSPF_MTU_IGNORE_DEFAULT; - SET_IF_PARAM (IF_DEF_PARAMS (ifp), passive_interface); - IF_DEF_PARAMS (ifp)->passive_interface = OSPF_IF_ACTIVE; - SET_IF_PARAM (IF_DEF_PARAMS (ifp), v_hello); IF_DEF_PARAMS (ifp)->v_hello = OSPF_HELLO_INTERVAL_DEFAULT; diff --git a/ospfd/ospf_interface.h b/ospfd/ospf_interface.h index 5a825ea5..79b178d8 100644 --- a/ospfd/ospf_interface.h +++ b/ospfd/ospf_interface.h @@ -50,6 +50,13 @@ struct ospf_if_params DECLARE_IF_PARAM (u_char, type); /* type of interface */ #define OSPF_IF_ACTIVE 0 #define OSPF_IF_PASSIVE 1 + +#define OSPF_IF_PASSIVE_STATUS(O) \ + (OSPF_IF_PARAM_CONFIGURED((O)->params, passive_interface) ? \ + (O)->params->passive_interface : \ + (OSPF_IF_PARAM_CONFIGURED(IF_DEF_PARAMS((O)->ifp), passive_interface) ? \ + IF_DEF_PARAMS((O)->ifp)->passive_interface : \ + (O)->ospf->passive_interface_default)) DECLARE_IF_PARAM (u_int32_t, v_hello); /* Hello Interval */ DECLARE_IF_PARAM (u_int32_t, v_wait); /* Router Dead Interval */ diff --git a/ospfd/ospf_packet.c b/ospfd/ospf_packet.c index ce90430d..2addc497 100644 --- a/ospfd/ospf_packet.c +++ b/ospfd/ospf_packet.c @@ -762,7 +762,7 @@ ospf_hello (struct ip *iph, struct ospf_header *ospfh, } /* If incoming interface is passive one, ignore Hello. */ - if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) { + if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) { char buf[3][INET_ADDRSTRLEN]; zlog_debug ("ignoring HELLO from router %s sent to %s, " "received on a passive interface, %s", @@ -2978,7 +2978,7 @@ ospf_poll_send (struct ospf_nbr_nbma *nbr_nbma) assert(oi); /* If this is passive interface, do not send OSPF Hello. */ - if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) + if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) return; if (oi->type != OSPF_IFTYPE_NBMA) @@ -3046,7 +3046,7 @@ ospf_hello_send (struct ospf_interface *oi) u_int16_t length = OSPF_HEADER_SIZE; /* If this is passive interface, do not send OSPF Hello. */ - if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_PASSIVE) + if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_PASSIVE) return; op = ospf_packet_new (oi->ifp->mtu); diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 04e1df46..0e3a77d8 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -249,39 +249,98 @@ ALIAS (no_ospf_router_id, NO_STR "router-id for the OSPF process\n") +static void +ospf_passive_interface_default (struct ospf *ospf) +{ + struct listnode *ln; + struct interface *ifp; + struct ospf_interface *oi; + + for (ALL_LIST_ELEMENTS_RO (om->iflist, ln, ifp)) + { + if (ifp && + OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), passive_interface)) + UNSET_IF_PARAM (IF_DEF_PARAMS (ifp), passive_interface); + } + for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, ln, oi)) + { + if (OSPF_IF_PARAM_CONFIGURED (oi->params, passive_interface)) + UNSET_IF_PARAM (oi->params, passive_interface); + } +} + +static void +ospf_passive_interface_update (struct ospf *ospf, struct interface *ifp, + struct in_addr addr, + struct ospf_if_params *params, u_char value) +{ + u_char dflt; + + params->passive_interface = value; + if (params != IF_DEF_PARAMS (ifp)) + { + if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), passive_interface)) + dflt = IF_DEF_PARAMS (ifp)->passive_interface; + else + dflt = ospf->passive_interface_default; + + if (value != dflt) + SET_IF_PARAM (params, passive_interface); + else + UNSET_IF_PARAM (params, passive_interface); + + ospf_free_if_params (ifp, addr); + ospf_if_update_params (ifp, addr); + } + else + { + if (value != ospf->passive_interface_default) + SET_IF_PARAM (params, passive_interface); + else + UNSET_IF_PARAM (params, passive_interface); + } +} + DEFUN (ospf_passive_interface, ospf_passive_interface_addr_cmd, "passive-interface IFNAME A.B.C.D", "Suppress routing updates on an interface\n" "Interface's name\n") { - struct interface *ifp; - struct in_addr addr; - int ret; - struct ospf_if_params *params; - struct route_node *rn; + struct interface *ifp; + struct in_addr addr; + int ret; + struct ospf_if_params *params; + struct route_node *rn; + struct ospf *ospf = vty->index; - ifp = if_get_by_name (argv[0]); + ifp = if_get_by_name (argv[0]); params = IF_DEF_PARAMS (ifp); - if (argc == 2) + if (argc == 0) { - ret = inet_aton(argv[1], &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); + ospf->passive_interface_default = OSPF_IF_PASSIVE; + ospf_passive_interface_default (ospf); } + else + { + if (argc == 2) + { + ret = inet_aton(argv[1], &addr); + if (!ret) + { + vty_out (vty, "Please specify interface address by A.B.C.D%s", + VTY_NEWLINE); + return CMD_WARNING; + } - SET_IF_PARAM (params, passive_interface); - params->passive_interface = OSPF_IF_PASSIVE; - + params = ospf_get_if_params (ifp, addr); + ospf_if_update_params (ifp, addr); + } + ospf_passive_interface_update (ospf, ifp, addr, params, OSPF_IF_PASSIVE); + } + /* XXX We should call ospf_if_set_multicast on exactly those * interfaces for which the passive property changed. It is too much * work to determine this set, so we do this for every interface. @@ -289,6 +348,7 @@ DEFUN (ospf_passive_interface, * record of joined groups to avoid systems calls if the desired * memberships match the current memership. */ + for (rn = route_top(IF_OIFS(ifp)); rn; rn = route_next (rn)) { struct ospf_interface *oi = rn->info; @@ -312,6 +372,12 @@ ALIAS (ospf_passive_interface, "Suppress routing updates on an interface\n" "Interface's name\n") +ALIAS (ospf_passive_interface, + ospf_passive_interface_default_cmd, + "passive-interface default", + "Suppress routing updates on an interface\n" + "Suppress routing updates on interfaces by default\n") + DEFUN (no_ospf_passive_interface, no_ospf_passive_interface_addr_cmd, "no passive-interface IFNAME A.B.C.D", @@ -324,33 +390,34 @@ DEFUN (no_ospf_passive_interface, struct ospf_if_params *params; int ret; struct route_node *rn; + struct ospf *ospf = vty->index; ifp = if_get_by_name (argv[0]); params = IF_DEF_PARAMS (ifp); - if (argc == 2) + if (argc == 0) { - ret = inet_aton(argv[1], &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D%s", - VTY_NEWLINE); - return CMD_WARNING; - } - - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; + ospf->passive_interface_default = OSPF_IF_ACTIVE; + ospf_passive_interface_default (ospf); } - - UNSET_IF_PARAM (params, passive_interface); - params->passive_interface = OSPF_IF_ACTIVE; - - if (params != IF_DEF_PARAMS (ifp)) + else { - ospf_free_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); + if (argc == 2) + { + ret = inet_aton(argv[1], &addr); + if (!ret) + { + vty_out (vty, "Please specify interface address by A.B.C.D%s", + VTY_NEWLINE); + return CMD_WARNING; + } + + params = ospf_lookup_if_params (ifp, addr); + if (params == NULL) + return CMD_SUCCESS; + } + ospf_passive_interface_update (ospf, ifp, addr, params, OSPF_IF_ACTIVE); } /* XXX We should call ospf_if_set_multicast on exactly those @@ -378,6 +445,13 @@ ALIAS (no_ospf_passive_interface, "Allow routing updates on an interface\n" "Interface's name\n") +ALIAS (no_ospf_passive_interface, + no_ospf_passive_interface_default_cmd, + "no passive-interface default", + NO_STR + "Allow routing updates on an interface\n" + "Allow routing updates on interfaces by default\n") + DEFUN (ospf_network_area, ospf_network_area_cmd, "network A.B.C.D/M area (A.B.C.D|<0-4294967295>)", @@ -2883,14 +2957,14 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, OSPF_IF_PARAM (oi, retransmit_interval), VTY_NEWLINE); - if (OSPF_IF_PARAM (oi, passive_interface) == OSPF_IF_ACTIVE) + if (OSPF_IF_PASSIVE_STATUS (oi) == OSPF_IF_ACTIVE) { char timebuf[OSPF_TIME_DUMP_SIZE]; vty_out (vty, " Hello due in %s%s", ospf_timer_dump (oi->t_hello, timebuf, sizeof(timebuf)), VTY_NEWLINE); } - else /* OSPF_IF_PASSIVE is set */ + else /* passive-interface is set */ vty_out (vty, " No Hellos (Passive interface)%s", VTY_NEWLINE); vty_out (vty, " Neighbor Count is %d, Adjacent neighbor count is %d%s", @@ -7868,17 +7942,36 @@ ospf_config_write (struct vty *vty) config_write_ospf_redistribute (vty, ospf); /* passive-interface print. */ + if (ospf->passive_interface_default == OSPF_IF_PASSIVE) + vty_out (vty, " passive-interface default%s", VTY_NEWLINE); + for (ALL_LIST_ELEMENTS_RO (om->iflist, node, ifp)) - if (IF_DEF_PARAMS (ifp)->passive_interface == OSPF_IF_PASSIVE) - vty_out (vty, " passive-interface %s%s", - ifp->name, VTY_NEWLINE); - + if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (ifp), passive_interface) + && IF_DEF_PARAMS (ifp)->passive_interface != + ospf->passive_interface_default) + { + vty_out (vty, " %spassive-interface %s%s", + IF_DEF_PARAMS (ifp)->passive_interface ? "" : "no ", + ifp->name, VTY_NEWLINE); + } for (ALL_LIST_ELEMENTS_RO (ospf->oiflist, node, oi)) - if (OSPF_IF_PARAM_CONFIGURED (oi->params, passive_interface) && - oi->params->passive_interface == OSPF_IF_PASSIVE) - vty_out (vty, " passive-interface %s %s%s", + { + if (!OSPF_IF_PARAM_CONFIGURED (oi->params, passive_interface)) + continue; + if (OSPF_IF_PARAM_CONFIGURED (IF_DEF_PARAMS (oi->ifp), + passive_interface)) + { + if (oi->params->passive_interface == IF_DEF_PARAMS (oi->ifp)->passive_interface) + continue; + } + else if (oi->params->passive_interface == ospf->passive_interface_default) + continue; + + vty_out (vty, " %spassive-interface %s %s%s", + oi->params->passive_interface ? "" : "no ", oi->ifp->name, inet_ntoa (oi->address->u.prefix4), VTY_NEWLINE); + } /* Network area print. */ config_write_network_area (vty, ospf); @@ -8199,8 +8292,10 @@ ospf_vty_init (void) /* "passive-interface" commands. */ install_element (OSPF_NODE, &ospf_passive_interface_addr_cmd); install_element (OSPF_NODE, &ospf_passive_interface_cmd); + install_element (OSPF_NODE, &ospf_passive_interface_default_cmd); install_element (OSPF_NODE, &no_ospf_passive_interface_addr_cmd); install_element (OSPF_NODE, &no_ospf_passive_interface_cmd); + install_element (OSPF_NODE, &no_ospf_passive_interface_default_cmd); /* "ospf abr-type" commands. */ install_element (OSPF_NODE, &ospf_abr_type_cmd); diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 8c151d98..8ef80cb3 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -167,6 +167,8 @@ ospf_new (void) new->default_originate = DEFAULT_ORIGINATE_NONE; + new->passive_interface_default = OSPF_IF_ACTIVE; + new->new_external_route = route_table_init (); new->old_external_route = route_table_init (); new->external_lsas = route_table_init (); diff --git a/ospfd/ospfd.h b/ospfd/ospfd.h index c15b4d39..ec9d9d6b 100644 --- a/ospfd/ospfd.h +++ b/ospfd/ospfd.h @@ -216,6 +216,7 @@ struct ospf struct ospf_area *backbone; /* Pointer to the Backbone Area. */ struct list *oiflist; /* ospf interfaces */ + u_char passive_interface_default; /* passive-interface default */ /* LSDB of AS-external-LSAs. */ struct ospf_lsdb *lsdb; -- cgit v1.2.3 From 8fb8a504e2c7c216b34c58e5658d84cb7dbe79b0 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 24 Oct 2006 19:04:26 +0000 Subject: [ospfd] Stop losing subsequent default-information originate 'always' info 2006-10-24 Andrew J. Schorr * ospf_zebra.c: (ospf_redistribute_default_set) Fix bug where a new value for ospf->default_originate was being ignored if a previous 'default-information originate' command had already been processed. --- ospfd/ChangeLog | 7 +++++++ ospfd/ospf_zebra.c | 22 ++++++---------------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 8a215e6b..d2b979aa 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,10 @@ +2006-10-24 Andrew J. Schorr + + * ospf_zebra.c: (ospf_redistribute_default_set) Fix bug where + a new value for ospf->default_originate was being ignored + if a previous 'default-information originate' command + had already been processed. + 2006-10-22 Yar Tikhiy * (general) Add support for passive-interface default (with diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index 5a722e05..aaee31e1 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -576,21 +576,15 @@ int ospf_redistribute_default_set (struct ospf *ospf, int originate, int mtype, int mvalue) { - int force = 0; + ospf->default_originate = originate; + ospf->dmetric[DEFAULT_ROUTE].type = mtype; + ospf->dmetric[DEFAULT_ROUTE].value = mvalue; if (ospf_is_type_redistributed (DEFAULT_ROUTE)) { - if (mtype != ospf->dmetric[DEFAULT_ROUTE].type) - { - ospf->dmetric[DEFAULT_ROUTE].type = mtype; - force = 1; - } - if (mvalue != ospf->dmetric[DEFAULT_ROUTE].value) - { - force = 1; - ospf->dmetric[DEFAULT_ROUTE].value = mvalue; - } - + /* if ospf->default_originate changes value, is calling + ospf_external_lsa_refresh_default sufficient to implement + the change? */ ospf_external_lsa_refresh_default (ospf); if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) @@ -601,10 +595,6 @@ ospf_redistribute_default_set (struct ospf *ospf, int originate, return CMD_SUCCESS; } - ospf->default_originate = originate; - ospf->dmetric[DEFAULT_ROUTE].type = mtype; - ospf->dmetric[DEFAULT_ROUTE].value = mvalue; - zclient_redistribute_default (ZEBRA_REDISTRIBUTE_DEFAULT_ADD, zclient); if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) -- cgit v1.2.3 From 56395af70588c8fda89bf5ef327df64b5efbeb67 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 27 Oct 2006 16:58:20 +0000 Subject: [bgpd] trivial: non C99 u_int.._t should be uint.._t 2006-10-27 Paul Jakma * bgp_route.c: (bgp_table_stats) oops, u_intXX_t should be uintXX_t --- bgpd/ChangeLog | 5 +++++ bgpd/bgp_route.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 701627c8..2b40456c 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,8 @@ +2006-10-27 Paul Jakma + + * bgp_route.c: (bgp_table_stats) oops, u_intXX_t should be + uintXX_t + 2006-10-19 Paul Jakma * bgpd.c: (peer_new) bgp element of peer absolutely must be diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3584b21a..3cae06e2 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8640,7 +8640,7 @@ bgp_table_stats (struct vty *vty, struct bgp *bgp, afi_t afi, safi_t safi) vty_out (vty, "%30s: ", "\% announced "); vty_out (vty, "%12.2f%s", 100 * (float)ts.counts[BGP_STATS_SPACE] / - (float)((u_int64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]), + (float)((uint64_t)1UL << ts.counts[BGP_STATS_MAXBITLEN]), VTY_NEWLINE); vty_out (vty, "%30s: ", "/8 equivalent "); vty_out (vty, "%12.2f%s", -- cgit v1.2.3 From 435408866187f3bc3c49b26f11bc83c374e55dd5 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 28 Nov 2006 16:36:39 +0000 Subject: [ospfd] Fix bug in passive-interface default commands. 2006-11-28 Andrew J. Schorr * ospf_vty.c: (ospf_passive_interface_default) Take additional 'newval' arg so we can update ospf->passive_interface_default inside this function. More importantly, we now call ospf_if_set_multicast on all ospf_interfaces. (ospf_passive_interface, no_ospf_passive_interface) Fix bug: for 'default' case, argv[0] is undefined, so we must test for (argc == 0) before using argv[0]. And since ospf_passive_interface_default now calls ospf_if_set_multicast as needed, we can just return after calling ospf_passive_interface_default. --- ospfd/ChangeLog | 13 +++++++++ ospfd/ospf_vty.c | 86 ++++++++++++++++++++++++++++---------------------------- 2 files changed, 56 insertions(+), 43 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index d2b979aa..42345bdb 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,16 @@ +2006-11-28 Andrew J. Schorr + + * ospf_vty.c: (ospf_passive_interface_default) Take additional + 'newval' arg so we can update ospf->passive_interface_default inside + this function. More importantly, we now call ospf_if_set_multicast + on all ospf_interfaces. + (ospf_passive_interface, no_ospf_passive_interface) Fix bug: + for 'default' case, argv[0] is undefined, so we must test for + (argc == 0) before using argv[0]. And since + ospf_passive_interface_default now calls ospf_if_set_multicast as + needed, we can just return after calling + ospf_passive_interface_default. + 2006-10-24 Andrew J. Schorr * ospf_zebra.c: (ospf_redistribute_default_set) Fix bug where diff --git a/ospfd/ospf_vty.c b/ospfd/ospf_vty.c index 0e3a77d8..d6da11dc 100644 --- a/ospfd/ospf_vty.c +++ b/ospfd/ospf_vty.c @@ -250,12 +250,14 @@ ALIAS (no_ospf_router_id, "router-id for the OSPF process\n") static void -ospf_passive_interface_default (struct ospf *ospf) +ospf_passive_interface_default (struct ospf *ospf, u_char newval) { struct listnode *ln; struct interface *ifp; struct ospf_interface *oi; + ospf->passive_interface_default = newval; + for (ALL_LIST_ELEMENTS_RO (om->iflist, ln, ifp)) { if (ifp && @@ -266,6 +268,8 @@ ospf_passive_interface_default (struct ospf *ospf) { if (OSPF_IF_PARAM_CONFIGURED (oi->params, passive_interface)) UNSET_IF_PARAM (oi->params, passive_interface); + /* update multicast memberships */ + ospf_if_set_multicast(oi); } } @@ -314,33 +318,31 @@ DEFUN (ospf_passive_interface, struct route_node *rn; struct ospf *ospf = vty->index; + if (argc == 0) + { + ospf_passive_interface_default (ospf, OSPF_IF_PASSIVE); + return CMD_SUCCESS; + } + ifp = if_get_by_name (argv[0]); params = IF_DEF_PARAMS (ifp); - if (argc == 0) - { - ospf->passive_interface_default = OSPF_IF_PASSIVE; - ospf_passive_interface_default (ospf); - } - else + if (argc == 2) { - if (argc == 2) - { - ret = inet_aton(argv[1], &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D%s", - VTY_NEWLINE); - return CMD_WARNING; - } + ret = inet_aton(argv[1], &addr); + if (!ret) + { + vty_out (vty, "Please specify interface address by A.B.C.D%s", + VTY_NEWLINE); + return CMD_WARNING; + } - params = ospf_get_if_params (ifp, addr); - ospf_if_update_params (ifp, addr); - } - ospf_passive_interface_update (ospf, ifp, addr, params, OSPF_IF_PASSIVE); + params = ospf_get_if_params (ifp, addr); + ospf_if_update_params (ifp, addr); } - + ospf_passive_interface_update (ospf, ifp, addr, params, OSPF_IF_PASSIVE); + /* XXX We should call ospf_if_set_multicast on exactly those * interfaces for which the passive property changed. It is too much * work to determine this set, so we do this for every interface. @@ -354,7 +356,7 @@ DEFUN (ospf_passive_interface, struct ospf_interface *oi = rn->info; if (oi && (OSPF_IF_PARAM(oi, passive_interface) == OSPF_IF_PASSIVE)) - ospf_if_set_multicast(oi); + ospf_if_set_multicast(oi); } /* * XXX It is not clear what state transitions the interface needs to @@ -391,34 +393,32 @@ DEFUN (no_ospf_passive_interface, int ret; struct route_node *rn; struct ospf *ospf = vty->index; + + if (argc == 0) + { + ospf_passive_interface_default (ospf, OSPF_IF_ACTIVE); + return CMD_SUCCESS; + } ifp = if_get_by_name (argv[0]); params = IF_DEF_PARAMS (ifp); - if (argc == 0) - { - ospf->passive_interface_default = OSPF_IF_ACTIVE; - ospf_passive_interface_default (ospf); - } - else + if (argc == 2) { - if (argc == 2) - { - ret = inet_aton(argv[1], &addr); - if (!ret) - { - vty_out (vty, "Please specify interface address by A.B.C.D%s", - VTY_NEWLINE); - return CMD_WARNING; - } + ret = inet_aton(argv[1], &addr); + if (!ret) + { + vty_out (vty, "Please specify interface address by A.B.C.D%s", + VTY_NEWLINE); + return CMD_WARNING; + } - params = ospf_lookup_if_params (ifp, addr); - if (params == NULL) - return CMD_SUCCESS; - } - ospf_passive_interface_update (ospf, ifp, addr, params, OSPF_IF_ACTIVE); + params = ospf_lookup_if_params (ifp, addr); + if (params == NULL) + return CMD_SUCCESS; } + ospf_passive_interface_update (ospf, ifp, addr, params, OSPF_IF_ACTIVE); /* XXX We should call ospf_if_set_multicast on exactly those * interfaces for which the passive property changed. It is too much @@ -2865,7 +2865,7 @@ show_ip_ospf_interface_sub (struct vty *vty, struct ospf *ospf, struct in_addr *dest; const char *dstr; - if ((ifp->flags & IFF_POINTOPOINT) + if ((ifp->flags & IFF_POINTOPOINT) || oi->type == OSPF_IFTYPE_VIRTUALLINK) dstr = "Peer"; else -- cgit v1.2.3 From 8d45210e7c9e221b519d975825cb83aea5ebe47e Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Tue, 28 Nov 2006 19:50:46 +0000 Subject: [bgpd] Fix bug where a deleted route that was quickly re-added was being lost 2006-11-28 Andrew J. Schorr * bgp_route.c: (bgp_info_restore) New function that undoes the effects of a previous call to bgp_info_delete. This is used when a route is deleted and quickly re-added before the deletion has been processed. (bgp_static_update_rsclient, bgp_static_update_main, bgp_redistribute_add) Check whether a pre-existing route has the BGP_INFO_REMOVED set, and, if so, we need to call bgp_info_restore to resurrect it. --- bgpd/ChangeLog | 11 +++++++++++ bgpd/bgp_route.c | 32 +++++++++++++++++++++++++++----- 2 files changed, 38 insertions(+), 5 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 2b40456c..c8629499 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,14 @@ +2006-11-28 Andrew J. Schorr + + * bgp_route.c: (bgp_info_restore) New function that undoes + the effects of a previous call to bgp_info_delete. This is + used when a route is deleted and quickly re-added before the + deletion has been processed. + (bgp_static_update_rsclient, bgp_static_update_main, + bgp_redistribute_add) Check whether a pre-existing route + has the BGP_INFO_REMOVED set, and, if so, we need to call + bgp_info_restore to resurrect it. + 2006-10-27 Paul Jakma * bgp_route.c: (bgp_table_stats) oops, u_intXX_t should be diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 3cae06e2..ce44842e 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -192,6 +192,17 @@ bgp_info_delete (struct bgp_node *rn, struct bgp_info *ri) UNSET_FLAG (ri->flags, BGP_INFO_VALID); } +/* undo the effects of a previous call to bgp_info_delete; typically + called when a route is deleted and then quickly re-added before the + deletion has been processed */ +static void +bgp_info_restore (struct bgp_node *rn, struct bgp_info *ri) +{ + bgp_info_unset_flag (rn, ri, BGP_INFO_REMOVED); + /* unset of previous already took care of pcount */ + SET_FLAG (ri->flags, BGP_INFO_VALID); +} + /* Adjust pcount as required */ static void bgp_pcount_adjust (struct bgp_node *rn, struct bgp_info *ri) @@ -3051,7 +3062,8 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, if (ri) { - if (attrhash_cmp (ri->attr, attr_new)) + if (attrhash_cmp (ri->attr, attr_new) && + !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) { bgp_unlock_node (rn); bgp_attr_unintern (attr_new); @@ -3064,6 +3076,8 @@ bgp_static_update_rsclient (struct peer *rsclient, struct prefix *p, bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ + if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) + bgp_info_restore(rn, ri); bgp_attr_unintern (ri->attr); ri->attr = attr_new; ri->uptime = time (NULL); @@ -3158,7 +3172,8 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, if (ri) { - if (attrhash_cmp (ri->attr, attr_new)) + if (attrhash_cmp (ri->attr, attr_new) && + !CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) { bgp_unlock_node (rn); bgp_attr_unintern (attr_new); @@ -3171,7 +3186,10 @@ bgp_static_update_main (struct bgp *bgp, struct prefix *p, bgp_info_set_flag (rn, ri, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ - bgp_aggregate_decrement (bgp, p, ri, afi, safi); + if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) + bgp_info_restore(rn, ri); + else + bgp_aggregate_decrement (bgp, p, ri, afi, safi); bgp_attr_unintern (ri->attr); ri->attr = attr_new; ri->uptime = time (NULL); @@ -4952,7 +4970,8 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, if (bi) { - if (attrhash_cmp (bi->attr, new_attr)) + if (attrhash_cmp (bi->attr, new_attr) && + !CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) { bgp_attr_unintern (new_attr); aspath_unintern (attr.aspath); @@ -4965,7 +4984,10 @@ bgp_redistribute_add (struct prefix *p, struct in_addr *nexthop, bgp_info_set_flag (bn, bi, BGP_INFO_ATTR_CHANGED); /* Rewrite BGP route information. */ - bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST); + if (CHECK_FLAG(bi->flags, BGP_INFO_REMOVED)) + bgp_info_restore(bn, bi); + else + bgp_aggregate_decrement (bgp, p, bi, afi, SAFI_UNICAST); bgp_attr_unintern (bi->attr); bi->attr = new_attr; bi->uptime = time (NULL); -- cgit v1.2.3 From 7f643ebf2bca2ef446cdf4f4a3e7b16958c18069 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 30 Nov 2006 16:17:02 +0000 Subject: [ospfd] Add debug messages for a few zebra messages that had been overlooked 2006-11-30 Andrew J. Schorr * ospf_zebra.c: (ospf_router_id_update_zebra, ospf_interface_address_add, ospf_interface_address_delete) If (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) is enabled, then add a debug message about what Zebra is telling us. (ospf_zebra_add_discard) Add a debug message matching the one already in ospf_zebra_delete_discard. --- ospfd/ChangeLog | 9 +++++++++ ospfd/ospf_zebra.c | 25 +++++++++++++++++++++++++ 2 files changed, 34 insertions(+) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index 42345bdb..a0ed9095 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,12 @@ +2006-11-30 Andrew J. Schorr + + * ospf_zebra.c: (ospf_router_id_update_zebra, + ospf_interface_address_add, ospf_interface_address_delete) + If (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) is enabled, then + add a debug message about what Zebra is telling us. + (ospf_zebra_add_discard) Add a debug message matching the one + already in ospf_zebra_delete_discard. + 2006-11-28 Andrew J. Schorr * ospf_vty.c: (ospf_passive_interface_default) Take additional diff --git a/ospfd/ospf_zebra.c b/ospfd/ospf_zebra.c index aaee31e1..bdd01424 100644 --- a/ospfd/ospf_zebra.c +++ b/ospfd/ospf_zebra.c @@ -65,6 +65,13 @@ ospf_router_id_update_zebra (int command, struct zclient *zclient, struct prefix router_id; zebra_router_id_update_read(zclient->ibuf,&router_id); + if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) + { + char buf[128]; + prefix2str(&router_id, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: router id update %s", buf); + } + router_id_zebra = router_id.u.prefix4; ospf = ospf_lookup (); @@ -256,6 +263,13 @@ ospf_interface_address_add (int command, struct zclient *zclient, if (c == NULL) return 0; + if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) + { + char buf[128]; + prefix2str(c->address, buf, sizeof(buf)); + zlog_debug("Zebra: interface %s address add %s", c->ifp->name, buf); + } + ospf = ospf_lookup (); if (ospf != NULL) ospf_if_update (ospf); @@ -283,6 +297,13 @@ ospf_interface_address_delete (int command, struct zclient *zclient, if (c == NULL) return 0; + if (IS_DEBUG_OSPF (zebra, ZEBRA_INTERFACE)) + { + char buf[128]; + prefix2str(c->address, buf, sizeof(buf)); + zlog_debug("Zebra: interface %s address delete %s", c->ifp->name, buf); + } + ifp = c->ifp; p = *c->address; p.prefixlen = IPV4_MAX_PREFIXLEN; @@ -470,6 +491,10 @@ ospf_zebra_add_discard (struct prefix_ipv4 *p) api.ifindex_num = 0; zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, p, &api); + + if (IS_DEBUG_OSPF (zebra, ZEBRA_REDISTRIBUTE)) + zlog_debug ("Zebra: Route add discard %s/%d", + inet_ntoa (p->prefix), p->prefixlen); } } -- cgit v1.2.3 From a39275d76d33e2b17b8f90441863ca030412a664 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Thu, 30 Nov 2006 16:36:57 +0000 Subject: [bgpd] Implement 'debug bgp zebra' to log all messages to and from zebra. 2006-11-30 Andrew J. Schorr * bgp_debug.h: Declare new bgp_debug_zebra conf and term flags, and define BGP_DEBUG_ZEBRA. * bgp_debug.c: Declare conf_bgp_debug_zebra and term_bgp_debug_zebra. (debug_bgp_zebra, no_debug_bgp_zebra, undebug_bgp_zebra) New functions to enable/disable bgp zebra debugging. (no_debug_bgp_all) Turn off zebra debugging. (show_debugging_bgp) Show whether zebra debugging is on. (bgp_config_write_debug) Add 'debug bgp zebra' if configured. (bgp_debug_init) Add new zebra debugging commands. * bgp_zebra.c: (bgp_router_id_update, bgp_interface_add, bgp_interface_delete, bgp_interface_up, bgp_interface_down, bgp_interface_address_add, bgp_interface_address_delete, zebra_read_ipv4, zebra_read_ipv6, bgp_zebra_announce, bgp_zebra_withdraw, bgp_redistribute_set, bgp_redistribute_unset) If zebra debugging is enabled, log an appropriate debug message. --- bgpd/ChangeLog | 18 +++++++ bgpd/bgp_debug.c | 59 +++++++++++++++++++++++ bgpd/bgp_debug.h | 3 ++ bgpd/bgp_zebra.c | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 4 files changed, 217 insertions(+), 6 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index c8629499..7ad200a1 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,21 @@ +2006-11-30 Andrew J. Schorr + + * bgp_debug.h: Declare new bgp_debug_zebra conf and term flags, + and define BGP_DEBUG_ZEBRA. + * bgp_debug.c: Declare conf_bgp_debug_zebra and term_bgp_debug_zebra. + (debug_bgp_zebra, no_debug_bgp_zebra, undebug_bgp_zebra) New + functions to enable/disable bgp zebra debugging. + (no_debug_bgp_all) Turn off zebra debugging. + (show_debugging_bgp) Show whether zebra debugging is on. + (bgp_config_write_debug) Add 'debug bgp zebra' if configured. + (bgp_debug_init) Add new zebra debugging commands. + * bgp_zebra.c: (bgp_router_id_update, bgp_interface_add, + bgp_interface_delete, bgp_interface_up, bgp_interface_down, + bgp_interface_address_add, bgp_interface_address_delete, + zebra_read_ipv4, zebra_read_ipv6, bgp_zebra_announce, + bgp_zebra_withdraw, bgp_redistribute_set, bgp_redistribute_unset) + If zebra debugging is enabled, log an appropriate debug message. + 2006-11-28 Andrew J. Schorr * bgp_route.c: (bgp_info_restore) New function that undoes diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c index 1e0fcd1f..1986b35b 100644 --- a/bgpd/bgp_debug.c +++ b/bgpd/bgp_debug.c @@ -43,6 +43,7 @@ unsigned long conf_bgp_debug_filter; unsigned long conf_bgp_debug_keepalive; unsigned long conf_bgp_debug_update; unsigned long conf_bgp_debug_normal; +unsigned long conf_bgp_debug_zebra; unsigned long term_bgp_debug_fsm; unsigned long term_bgp_debug_events; @@ -51,6 +52,7 @@ unsigned long term_bgp_debug_filter; unsigned long term_bgp_debug_keepalive; unsigned long term_bgp_debug_update; unsigned long term_bgp_debug_normal; +unsigned long term_bgp_debug_zebra; /* messages for BGP-4 status */ struct message bgp_status_msg[] = @@ -590,6 +592,49 @@ ALIAS (no_debug_bgp_normal, UNDEBUG_STR BGP_STR) +DEFUN (debug_bgp_zebra, + debug_bgp_zebra_cmd, + "debug bgp zebra", + DEBUG_STR + BGP_STR + "BGP Zebra messages\n") +{ + if (vty->node == CONFIG_NODE) + DEBUG_ON (zebra, ZEBRA); + else + { + TERM_DEBUG_ON (zebra, ZEBRA); + vty_out (vty, "BGP zebra debugging is on%s", VTY_NEWLINE); + } + return CMD_SUCCESS; +} + +DEFUN (no_debug_bgp_zebra, + no_debug_bgp_zebra_cmd, + "no debug bgp zebra", + NO_STR + DEBUG_STR + BGP_STR + "BGP Zebra messages\n") +{ + if (vty->node == CONFIG_NODE) + DEBUG_OFF (zebra, ZEBRA); + else + { + TERM_DEBUG_OFF (zebra, ZEBRA); + vty_out (vty, "BGP zebra debugging is off%s", VTY_NEWLINE); + } + return CMD_SUCCESS; +} + +ALIAS (no_debug_bgp_zebra, + undebug_bgp_zebra_cmd, + "undebug bgp zebra", + UNDEBUG_STR + DEBUG_STR + BGP_STR + "BGP Zebra messages\n") + DEFUN (no_debug_bgp_all, no_debug_bgp_all_cmd, "no debug all bgp", @@ -605,6 +650,7 @@ DEFUN (no_debug_bgp_all, TERM_DEBUG_OFF (update, UPDATE_OUT); TERM_DEBUG_OFF (fsm, FSM); TERM_DEBUG_OFF (filter, FILTER); + TERM_DEBUG_OFF (zebra, ZEBRA); vty_out (vty, "All possible debugging has been turned off%s", VTY_NEWLINE); return CMD_SUCCESS; @@ -642,6 +688,8 @@ DEFUN (show_debugging_bgp, vty_out (vty, " BGP fsm debugging is on%s", VTY_NEWLINE); if (BGP_DEBUG (filter, FILTER)) vty_out (vty, " BGP filter debugging is on%s", VTY_NEWLINE); + if (BGP_DEBUG (zebra, ZEBRA)) + vty_out (vty, " BGP zebra debugging is on%s", VTY_NEWLINE); vty_out (vty, "%s", VTY_NEWLINE); return CMD_SUCCESS; } @@ -697,6 +745,12 @@ bgp_config_write_debug (struct vty *vty) write++; } + if (CONF_BGP_DEBUG (zebra, ZEBRA)) + { + vty_out (vty, "debug bgp zebra%s", VTY_NEWLINE); + write++; + } + return write; } @@ -728,6 +782,8 @@ bgp_debug_init (void) install_element (CONFIG_NODE, &debug_bgp_update_direct_cmd); install_element (ENABLE_NODE, &debug_bgp_normal_cmd); install_element (CONFIG_NODE, &debug_bgp_normal_cmd); + install_element (ENABLE_NODE, &debug_bgp_zebra_cmd); + install_element (CONFIG_NODE, &debug_bgp_zebra_cmd); install_element (ENABLE_NODE, &no_debug_bgp_fsm_cmd); install_element (ENABLE_NODE, &undebug_bgp_fsm_cmd); @@ -747,6 +803,9 @@ bgp_debug_init (void) install_element (ENABLE_NODE, &no_debug_bgp_normal_cmd); install_element (ENABLE_NODE, &undebug_bgp_normal_cmd); install_element (CONFIG_NODE, &no_debug_bgp_normal_cmd); + install_element (ENABLE_NODE, &no_debug_bgp_zebra_cmd); + install_element (ENABLE_NODE, &undebug_bgp_zebra_cmd); + install_element (CONFIG_NODE, &no_debug_bgp_zebra_cmd); install_element (ENABLE_NODE, &no_debug_bgp_all_cmd); install_element (ENABLE_NODE, &undebug_bgp_all_cmd); } diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h index bc8acf93..eab95d09 100644 --- a/bgpd/bgp_debug.h +++ b/bgpd/bgp_debug.h @@ -63,6 +63,7 @@ extern unsigned long conf_bgp_debug_filter; extern unsigned long conf_bgp_debug_keepalive; extern unsigned long conf_bgp_debug_update; extern unsigned long conf_bgp_debug_normal; +extern unsigned long conf_bgp_debug_zebra; extern unsigned long term_bgp_debug_fsm; extern unsigned long term_bgp_debug_events; @@ -71,6 +72,7 @@ extern unsigned long term_bgp_debug_filter; extern unsigned long term_bgp_debug_keepalive; extern unsigned long term_bgp_debug_update; extern unsigned long term_bgp_debug_normal; +extern unsigned long term_bgp_debug_zebra; #define BGP_DEBUG_FSM 0x01 #define BGP_DEBUG_EVENTS 0x01 @@ -80,6 +82,7 @@ extern unsigned long term_bgp_debug_normal; #define BGP_DEBUG_UPDATE_IN 0x01 #define BGP_DEBUG_UPDATE_OUT 0x02 #define BGP_DEBUG_NORMAL 0x01 +#define BGP_DEBUG_ZEBRA 0x01 #define BGP_DEBUG_PACKET_SEND 0x01 #define BGP_DEBUG_PACKET_SEND_DETAIL 0x02 diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index 0cb9e0e2..301c15b0 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -36,6 +36,7 @@ Boston, MA 02111-1307, USA. */ #include "bgpd/bgp_nexthop.h" #include "bgpd/bgp_zebra.h" #include "bgpd/bgp_fsm.h" +#include "bgpd/bgp_debug.h" /* All information about zebra. */ static struct zclient *zclient = NULL; @@ -50,6 +51,14 @@ bgp_router_id_update (int command, struct zclient *zclient, zebra_size_t length) struct bgp *bgp; zebra_router_id_update_read(zclient->ibuf,&router_id); + + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[128]; + prefix2str(&router_id, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: router id update %s", buf); + } + router_id_zebra = router_id.u.prefix4; for (ALL_LIST_ELEMENTS (bm->bgp, node, nnode, bgp)) @@ -69,6 +78,9 @@ bgp_interface_add (int command, struct zclient *zclient, zebra_size_t length) ifp = zebra_interface_add_read (zclient->ibuf); + if (BGP_DEBUG(zebra, ZEBRA) && ifp) + zlog_debug("Zebra rcvd: interface add %s", ifp->name); + return 0; } @@ -83,6 +95,9 @@ bgp_interface_delete (int command, struct zclient *zclient, ifp = zebra_interface_state_read (s); ifp->ifindex = IFINDEX_INTERNAL; + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Zebra rcvd: interface delete %s", ifp->name); + return 0; } @@ -100,6 +115,9 @@ bgp_interface_up (int command, struct zclient *zclient, zebra_size_t length) if (! ifp) return 0; + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Zebra rcvd: interface %s up", ifp->name); + for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) bgp_connected_add (c); @@ -119,6 +137,9 @@ bgp_interface_down (int command, struct zclient *zclient, zebra_size_t length) if (! ifp) return 0; + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Zebra rcvd: interface %s down", ifp->name); + for (ALL_LIST_ELEMENTS (ifp->connected, node, nnode, c)) bgp_connected_delete (c); @@ -164,6 +185,14 @@ bgp_interface_address_add (int command, struct zclient *zclient, if (ifc == NULL) return 0; + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[128]; + prefix2str(ifc->address, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: interface %s address add %s", + ifc->ifp->name, buf); + } + if (if_is_operative (ifc->ifp)) bgp_connected_add (ifc); @@ -181,6 +210,14 @@ bgp_interface_address_delete (int command, struct zclient *zclient, if (ifc == NULL) return 0; + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[128]; + prefix2str(ifc->address, buf, sizeof(buf)); + zlog_debug("Zebra rcvd: interface %s address delete %s", + ifc->ifp->name, buf); + } + if (if_is_operative (ifc->ifp)) bgp_connected_delete (ifc); @@ -233,9 +270,34 @@ zebra_read_ipv4 (int command, struct zclient *zclient, zebra_size_t length) api.metric = 0; if (command == ZEBRA_IPV4_ROUTE_ADD) - bgp_redistribute_add ((struct prefix *)&p, &nexthop, api.metric, api.type); + { + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra rcvd: IPv4 route add %s %s/%d nexthop %s metric %u", + zebra_route_string(api.type), + inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), + p.prefixlen, + inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), + api.metric); + } + bgp_redistribute_add((struct prefix *)&p, &nexthop, api.metric, api.type); + } else - bgp_redistribute_delete ((struct prefix *)&p, api.type); + { + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra rcvd: IPv4 route delete %s %s/%d " + "nexthop %s metric %u", + zebra_route_string(api.type), + inet_ntop(AF_INET, &p.prefix, buf[0], sizeof(buf[0])), + p.prefixlen, + inet_ntop(AF_INET, &nexthop, buf[1], sizeof(buf[1])), + api.metric); + } + bgp_redistribute_delete((struct prefix *)&p, api.type); + } return 0; } @@ -291,9 +353,29 @@ zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) return 0; if (command == ZEBRA_IPV6_ROUTE_ADD) - bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type); + { + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[INET6_ADDRSTRLEN]; + zlog_debug("Zebra rcvd: IPv6 route add %s %s/%d metric %u", + zebra_route_string(api.type), + inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)), + p.prefixlen, api.metric); + } + bgp_redistribute_add ((struct prefix *)&p, NULL, api.metric, api.type); + } else - bgp_redistribute_delete ((struct prefix *) &p, api.type); + { + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[INET6_ADDRSTRLEN]; + zlog_debug("Zebra rcvd: IPv6 route delete %s %s/%d metric %u", + zebra_route_string(api.type), + inet_ntop(AF_INET6, &p.prefix, buf, sizeof(buf)), + p.prefixlen, api.metric); + } + bgp_redistribute_delete ((struct prefix *) &p, api.type); + } return 0; } @@ -640,6 +722,17 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp) SET_FLAG (api.message, ZAPI_MESSAGE_DISTANCE); api.distance = distance; } + + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra send: IPv4 route add %s/%d nexthop %s metric %u", + inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])), + api.metric); + } + zapi_ipv4_route (ZEBRA_IPV4_ROUTE_ADD, zclient, (struct prefix_ipv4 *) p, &api); } @@ -696,6 +789,16 @@ bgp_zebra_announce (struct prefix *p, struct bgp_info *info, struct bgp *bgp) SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[2][INET6_ADDRSTRLEN]; + zlog_debug("Zebra send: IPv6 route add %s/%d nexthop %s metric %u", + inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), + api.metric); + } + zapi_ipv6_route (ZEBRA_IPV6_ROUTE_ADD, zclient, (struct prefix_ipv6 *) p, &api); } @@ -744,6 +847,16 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info) SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[2][INET_ADDRSTRLEN]; + zlog_debug("Zebra send: IPv4 route delete %s/%d nexthop %s metric %u", + inet_ntop(AF_INET, &p->u.prefix4, buf[0], sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET, nexthop, buf[1], sizeof(buf[1])), + api.metric); + } + zapi_ipv4_route (ZEBRA_IPV4_ROUTE_DELETE, zclient, (struct prefix_ipv4 *) p, &api); } @@ -789,6 +902,16 @@ bgp_zebra_withdraw (struct prefix *p, struct bgp_info *info) SET_FLAG (api.message, ZAPI_MESSAGE_METRIC); api.metric = info->attr->med; + if (BGP_DEBUG(zebra, ZEBRA)) + { + char buf[2][INET6_ADDRSTRLEN]; + zlog_debug("Zebra send: IPv6 route delete %s/%d nexthop %s metric %u", + inet_ntop(AF_INET6, &p->u.prefix6, buf[0], sizeof(buf[0])), + p->prefixlen, + inet_ntop(AF_INET6, nexthop, buf[1], sizeof(buf[1])), + api.metric); + } + zapi_ipv6_route (ZEBRA_IPV6_ROUTE_DELETE, zclient, (struct prefix_ipv6 *) p, &api); } @@ -811,6 +934,9 @@ bgp_redistribute_set (struct bgp *bgp, afi_t afi, int type) /* Return if zebra connection is not established. */ if (zclient->sock < 0) return CMD_WARNING; + + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Zebra send: redistribute add %s", zebra_route_string(type)); /* Send distribute add message to zebra. */ zebra_redistribute_send (ZEBRA_REDISTRIBUTE_ADD, zclient, type); @@ -875,8 +1001,13 @@ bgp_redistribute_unset (struct bgp *bgp, afi_t afi, int type) if (bgp->redist[AFI_IP][type] == 0 && bgp->redist[AFI_IP6][type] == 0 && zclient->sock >= 0) - /* Send distribute delete message to zebra. */ - zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type); + { + /* Send distribute delete message to zebra. */ + if (BGP_DEBUG(zebra, ZEBRA)) + zlog_debug("Zebra send: redistribute delete %s", + zebra_route_string(type)); + zebra_redistribute_send (ZEBRA_REDISTRIBUTE_DELETE, zclient, type); + } /* Withdraw redistributed routes from current BGP's routing table. */ bgp_redistribute_withdraw (bgp, afi, type); -- cgit v1.2.3 From ed589c157781f92bcff0e0b1664c75b2dc6d6965 Mon Sep 17 00:00:00 2001 From: "Andrew J. Schorr" Date: Mon, 4 Dec 2006 18:26:37 +0000 Subject: [ospfd] Consider all connected addresses when creating ospf interfaces 2006-12-04 Andrew J. Schorr * ospfd.c: (ospf_network_run) Remove an offending 'break' statement. Previously, after creating a single ospf_interface on a given network interface, the code would skip to the next interface without considering other connected addresses on the interface. After removing the 'break', we now consider all connected addresses. --- ospfd/ChangeLog | 8 ++++++++ ospfd/ospfd.c | 2 -- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ospfd/ChangeLog b/ospfd/ChangeLog index a0ed9095..0a2b9994 100644 --- a/ospfd/ChangeLog +++ b/ospfd/ChangeLog @@ -1,3 +1,11 @@ +2006-12-04 Andrew J. Schorr + + * ospfd.c: (ospf_network_run) Remove an offending 'break' statement. + Previously, after creating a single ospf_interface on a given + network interface, the code would skip to the next interface + without considering other connected addresses on the interface. + After removing the 'break', we now consider all connected addresses. + 2006-11-30 Andrew J. Schorr * ospf_zebra.c: (ospf_router_id_update_zebra, diff --git a/ospfd/ospfd.c b/ospfd/ospfd.c index 8ef80cb3..dd5af5e9 100644 --- a/ospfd/ospfd.c +++ b/ospfd/ospfd.c @@ -896,8 +896,6 @@ ospf_network_run (struct ospf *ospf, struct prefix *p, struct ospf_area *area) if ((ospf->router_id.s_addr != 0) && if_is_operative (ifp)) ospf_if_up (oi); - - break; } } } -- cgit v1.2.3 From 95fdcd8a793d6c271996da221c4030d8ee277891 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 8 Dec 2006 00:31:22 +0000 Subject: [bgpd] Bug #302, bgpd can get stuck in state Clearing 2006-12-07 Paul Jakma * bgp_fsm.c: Bug #302 fix, diagnosis, suggestions and testing by Juergen Kammer . Fix follows from his suggested fix, just made in a slightly different way. (bgp_event) Transitions into Clearing always must call bgp_clear_route_all(). (bgp_stop) No need to clear routes here, BGP FSM should do it. --- bgpd/ChangeLog | 10 ++++++++++ bgpd/bgp_fsm.c | 13 ++++++++----- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/bgpd/ChangeLog b/bgpd/ChangeLog index 7ad200a1..97f78caa 100644 --- a/bgpd/ChangeLog +++ b/bgpd/ChangeLog @@ -1,3 +1,13 @@ +2006-12-07 Paul Jakma + + * bgp_fsm.c: Bug #302 fix, diagnosis, suggestions and testing + by Juergen Kammer . Fix follows from + his suggested fix, just made in a slightly different way. + (bgp_event) Transitions into Clearing always must call + bgp_clear_route_all(). + (bgp_stop) No need to clear routes here, BGP FSM should do + it. + 2006-11-30 Andrew J. Schorr * bgp_debug.h: Declare new bgp_debug_zebra conf and term flags, diff --git a/bgpd/bgp_fsm.c b/bgpd/bgp_fsm.c index ef8dfea4..d704c297 100644 --- a/bgpd/bgp_fsm.c +++ b/bgpd/bgp_fsm.c @@ -483,9 +483,6 @@ bgp_stop (struct peer *peer) /* Reset uptime. */ bgp_uptime_reset (peer); - /* Need of clear of peer. */ - bgp_clear_route_all (peer); - /* Reset peer synctime */ peer->synctime = 0; } @@ -1092,8 +1089,14 @@ bgp_event (struct thread *thread) { /* If status is changed. */ if (next != peer->status) - bgp_fsm_change_status (peer, next); - + { + /* Transition into Clearing must /always/ clear all routes.. */ + if (next == Clearing) + bgp_clear_route_all (peer); + + bgp_fsm_change_status (peer, next); + } + /* Make sure timer is set. */ bgp_timer_set (peer); } -- cgit v1.2.3 From 3c0755dc9772deccff2ba6e9dc0511a9af2b9d1b Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 8 Dec 2006 00:53:14 +0000 Subject: [zebra] Changes of nexthops of static routes didnt take effect 2006-12-08 Piotr Chytla * zebra_rib.c: (static_install_ipv{4,6}) Case where existing RIB is updated must explicitely rib_addqueue the route_node, to ensure the update actually takes effect. --- zebra/ChangeLog | 6 ++++++ zebra/zebra_rib.c | 22 ++++++++++++---------- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/zebra/ChangeLog b/zebra/ChangeLog index 0740e756..3ea4f57f 100644 --- a/zebra/ChangeLog +++ b/zebra/ChangeLog @@ -1,3 +1,9 @@ +2006-12-08 Piotr Chytla + + * zebra_rib.c: (static_install_ipv{4,6}) Case where existing + RIB is updated must explicitely rib_addqueue the route_node, + to ensure the update actually takes effect. + 2006-09-13 Tom Everett * kernel_socket.c (rtm_type_str): ifdef RTM_OLD{ADD,DEL} to diff --git a/zebra/zebra_rib.c b/zebra/zebra_rib.c index acad065a..02c73d12 100644 --- a/zebra/zebra_rib.c +++ b/zebra/zebra_rib.c @@ -1103,20 +1103,20 @@ rib_queue_init (struct zebra_t *zebra) * The queue length is bounded by the maximal size of the routing table, * as a route_node will not be requeued, if already queued. * - * RIBs are submitted via rib_addnode and rib_delnode, which set - * minimal state and then submit route_node to queue for best-path - * selection later. Order of add/delete state changes are preserved for - * any given RIB. + * RIBs are submitted via rib_addnode or rib_delnode which set minimal + * state, or static_install_ipv{4,6} (when an existing RIB is updated) + * and then submit route_node to queue for best-path selection later. + * Order of add/delete state changes are preserved for any given RIB. * * Deleted RIBs are reaped during best-path selection. * * rib_addnode * |-> rib_link or unset RIB_ENTRY_REMOVE |->Update kernel with - * |-> rib_addqueue | best RIB, if required - * | | - * |-> .......................... -> rib_process - * | | - * |-> rib_addqueue |-> rib_unlink + * |-------->| | best RIB, if required + * | | + * static_install->|->rib_addqueue...... -> rib_process + * | | + * |-------->| |-> rib_unlink * |-> set RIB_ENTRY_REMOVE | * rib_delnode (RIB freed) * @@ -1548,6 +1548,7 @@ static_install_ipv4 (struct prefix *p, struct static_ipv4 *si) nexthop_blackhole_add (rib); break; } + rib_queue_add (&zebrad, rn); } else { @@ -1704,7 +1705,7 @@ static_add_ipv4 (struct prefix *p, struct in_addr *gate, const char *ifname, } } - /* Distance chaged. */ + /* Distance changed. */ if (update) static_delete_ipv4 (p, gate, ifname, update->distance, vrf_id); @@ -2097,6 +2098,7 @@ static_install_ipv6 (struct prefix *p, struct static_ipv6 *si) nexthop_ipv6_ifname_add (rib, &si->ipv6, si->ifname); break; } + rib_queue_add (&zebrad, rn); } else { -- cgit v1.2.3 From 41b36e9013111a6da812ca000e3b978282bd27a9 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 8 Dec 2006 01:09:50 +0000 Subject: [isisd] Fix compiler warnings and allow v4-only compilation 2006-12-08 Hannes Gredler * isis_adjacency.c: (isis_new_adj) Allow NULL snpa argument. * isis_pdu.c: (various) Update calls to isis_new_adj() to pass NULL and use default. * (general) Add forward declarations where required. Fix up const char *'s. Allow V4-only compilation. --- isisd/ChangeLog | 9 +++++++++ isisd/isis_adjacency.c | 5 +++++ isisd/isis_circuit.c | 12 ++++++++++-- isisd/isis_lsp.c | 2 +- isisd/isis_main.c | 10 ++++++++++ isisd/isis_misc.c | 16 ++++++++-------- isisd/isis_misc.h | 5 ++--- isisd/isis_pdu.c | 6 +++--- isisd/isis_route.c | 9 ++++++++- isisd/isis_routemap.c | 8 ++++++++ isisd/isis_spf.c | 8 +++++--- isisd/isis_tlv.c | 5 +++++ isisd/isis_zebra.c | 6 ++++-- isisd/isisd.c | 25 ++++++++++++++++++++----- isisd/iso_checksum.c | 6 ------ isisd/topology/random.c | 12 +++++++++++- isisd/topology/spgrid.c | 9 +++++++++ 17 files changed, 118 insertions(+), 35 deletions(-) diff --git a/isisd/ChangeLog b/isisd/ChangeLog index 5e203c8c..8797af18 100644 --- a/isisd/ChangeLog +++ b/isisd/ChangeLog @@ -1,3 +1,12 @@ +2006-12-08 Hannes Gredler + + * isis_adjacency.c: (isis_new_adj) Allow NULL snpa argument. + * isis_pdu.c: (various) Update calls to isis_new_adj() to pass + NULL and use default. + * (general) Add forward declarations where required. + Fix up const char *'s. + Allow V4-only compilation. + 2006-01-17 Paul Jakma * isis_zebra.c: (isis_zebra_route_add_ipv4) fix for new diff --git a/isisd/isis_adjacency.c b/isisd/isis_adjacency.c index d8c7448e..aab8d1a3 100644 --- a/isisd/isis_adjacency.c +++ b/isisd/isis_adjacency.c @@ -72,7 +72,12 @@ isis_new_adj (u_char * id, u_char * snpa, int level, return NULL; } + if (snpa) { memcpy (adj->snpa, snpa, 6); + } else { + memset (adj->snpa, ' ', 6); + } + adj->circuit = circuit; adj->level = level; adj->flaps = 0; diff --git a/isisd/isis_circuit.c b/isisd/isis_circuit.c index 76145f02..6ef24a9a 100644 --- a/isisd/isis_circuit.c +++ b/isisd/isis_circuit.c @@ -57,6 +57,14 @@ extern struct thread_master *master; extern struct isis *isis; +/* + * Prototypes. + */ +void isis_circuit_down(struct isis_circuit *); +int isis_interface_config_write(struct vty *); +int isis_if_new_hook(struct interface *); +int isis_if_delete_hook(struct interface *); + struct isis_circuit * isis_circuit_new () { @@ -275,10 +283,10 @@ isis_circuit_del_addr (struct isis_circuit *circuit, { struct prefix_ipv4 *ipv4, *ip = NULL; struct listnode *node; - int found = 0; u_char buf[BUFSIZ]; #ifdef HAVE_IPV6 struct prefix_ipv6 *ipv6, *ip6 = NULL; + int found = 0; #endif /* HAVE_IPV6 */ memset (&buf, 0, BUFSIZ); @@ -944,7 +952,7 @@ DEFUN (isis_circuit_type, assert (circuit); - circuit_t = string2circuit_t ((u_char *)argv[0]); + circuit_t = string2circuit_t (argv[0]); if (!circuit_t) { diff --git a/isisd/isis_lsp.c b/isisd/isis_lsp.c index 63f2b6b9..1a4deb1b 100644 --- a/isisd/isis_lsp.c +++ b/isisd/isis_lsp.c @@ -727,10 +727,10 @@ lsp_print_detail (dnode_t * node, struct vty *vty, char dynhost) #ifdef HAVE_IPV6 struct ipv6_reachability *ipv6_reach; struct in6_addr in6; + u_char buff[BUFSIZ]; #endif u_char LSPid[255]; u_char hostname[255]; - u_char buff[BUFSIZ]; u_char ipv4_reach_prefix[20]; u_char ipv4_reach_mask[20]; u_char ipv4_address[20]; diff --git a/isisd/isis_main.c b/isisd/isis_main.c index 74fc6475..2411518d 100644 --- a/isisd/isis_main.c +++ b/isisd/isis_main.c @@ -107,6 +107,16 @@ int _argc; char **_argv; char **_envp; +/* + * Prototypes. + */ +void reload(void); +void sighup(void); +void sigint(void); +void sigterm(void); +void sigusr1(void); + + /* Help information display. */ static void usage (int status) diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index 384ebe0b..6b565bcb 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -99,15 +99,15 @@ isonet_print (u_char * from, int len) * extract dot from the dotted str, and insert all the number in a buff */ int -dotformat2buff (u_char * buff, u_char * dotted) +dotformat2buff (u_char * buff, const u_char * dotted) { int dotlen, len = 0; - u_char *pos = dotted; + const u_char *pos = dotted; u_char number[3]; int nextdotpos = 2; number[2] = '\0'; - dotlen = strlen ((char *)dotted); + dotlen = strlen(dotted); if (dotlen > 50) { /* this can't be an iso net, its too long */ @@ -165,7 +165,7 @@ sysid2buff (u_char * buff, const u_char * dotted) number[2] = '\0'; // surely not a sysid_string if not 14 length - if (strlen ((char *)dotted) != 14) + if (strlen (dotted) != 14) { return 0; } @@ -271,19 +271,19 @@ speaks (struct nlpids *nlpids, int family) * Returns 0 on error, IS-IS Circuit Type on ok */ int -string2circuit_t (u_char * str) +string2circuit_t (const u_char * str) { if (!str) return 0; - if (!strcmp ((char *)str, "level-1")) + if (!strcmp (str, "level-1")) return IS_LEVEL_1; - if (!strcmp ((char *)str, "level-2-only") || !strcmp ((char *)str, "level-2")) + if (!strcmp (str, "level-2-only") || !strcmp (str, "level-2")) return IS_LEVEL_2; - if (!strcmp ((char *)str, "level-1-2")) + if (!strcmp (str, "level-1-2")) return IS_LEVEL_1_AND_2; return 0; diff --git a/isisd/isis_misc.h b/isisd/isis_misc.h index 3b975895..d5003a8e 100644 --- a/isisd/isis_misc.h +++ b/isisd/isis_misc.h @@ -24,8 +24,7 @@ #ifndef _ZEBRA_ISIS_MISC_H #define _ZEBRA_ISIS_MISC_H -int dotformat2buff (u_char *, u_char *); -int string2circuit_t (u_char *); +int string2circuit_t (const u_char *); const char *circuit_t2string (int); const char *syst2string (int); struct in_addr newprefix2inaddr (u_char * prefix_start, @@ -34,7 +33,7 @@ struct in_addr newprefix2inaddr (u_char * prefix_start, * Converting input to memory stored format * return value of 0 indicates wrong input */ -int dotformat2buff (u_char *, u_char *); +int dotformat2buff (u_char *, const u_char *); int sysid2buff (u_char *, const u_char *); /* diff --git a/isisd/isis_pdu.c b/isisd/isis_pdu.c index 2dc82156..6fcc5ed5 100644 --- a/isisd/isis_pdu.c +++ b/isisd/isis_pdu.c @@ -335,7 +335,7 @@ process_p2p_hello (struct isis_circuit *circuit) adj = circuit->u.p2p.neighbor; if (!adj) { - adj = isis_new_adj (hdr->source_id, (u_char *) " ", 0, circuit); + adj = isis_new_adj (hdr->source_id, NULL, 0, circuit); if (adj == NULL) return ISIS_ERROR; circuit->u.p2p.neighbor = adj; @@ -1596,7 +1596,7 @@ process_is_hello (struct isis_circuit *circuit) if (!adj) { /* 8.2.2 */ - adj = isis_new_adj (sysid, (u_char *) " ", 0, circuit); + adj = isis_new_adj (sysid, NULL, 0, circuit); if (adj == NULL) return ISIS_ERROR; @@ -1612,7 +1612,7 @@ process_is_hello (struct isis_circuit *circuit) /* 8.2.2 a) 2) delete the adj */ XFREE (MTYPE_ISIS_ADJACENCY, adj); /* 8.2.2 a) 3) create a new adj */ - adj = isis_new_adj (sysid, (u_char *) " ", 0, circuit); + adj = isis_new_adj (sysid, NULL, 0, circuit); if (adj == NULL) return ISIS_ERROR; diff --git a/isisd/isis_route.c b/isisd/isis_route.c index c8f0aaba..1286486c 100644 --- a/isisd/isis_route.c +++ b/isisd/isis_route.c @@ -631,6 +631,8 @@ isis_route_validate_table (struct isis_area *area, struct route_table *table) if (drnode->info == rnode->info) drnode->info = NULL; } + +#ifdef HAVE_IPV6 if (rnode->p.family == AF_INET6) { drnode = route_node_get (area->route_table6[0], &rnode->p); @@ -640,6 +642,7 @@ isis_route_validate_table (struct isis_area *area, struct route_table *table) if (drnode->info == rnode->info) drnode->info = NULL; } +#endif isis_route_delete (&rnode->p, table); } @@ -667,8 +670,10 @@ isis_route_validate_merge (struct isis_area *area, int family) if (family == AF_INET) table = area->route_table[0]; +#ifdef HAVE_IPV6 else if (family == AF_INET6) table = area->route_table6[0]; +#endif for (rnode = route_top (table); rnode; rnode = route_next (rnode)) { @@ -680,8 +685,10 @@ isis_route_validate_merge (struct isis_area *area, int family) if (family == AF_INET) table = area->route_table[1]; +#ifdef HAVE_IPV6 else if (family == AF_INET6) table = area->route_table6[1]; +#endif for (rnode = route_top (table); rnode; rnode = route_next (rnode)) { @@ -719,8 +726,8 @@ isis_route_validate (struct thread *thread) isis_route_validate_merge (area, AF_INET); -#ifdef HAVE_IPV6 validate_ipv6: +#ifdef HAVE_IPV6 if (area->is_type == IS_LEVEL_1) { isis_route_validate_table (area, area->route_table6[0]); diff --git a/isisd/isis_routemap.c b/isisd/isis_routemap.c index 4235d882..cff0fa3f 100644 --- a/isisd/isis_routemap.c +++ b/isisd/isis_routemap.c @@ -49,6 +49,14 @@ extern struct isis *isis; +/* + * Prototypes. + */ +void isis_route_map_upd(const char *); +void isis_route_map_event(route_map_event_t, const char *); +void isis_route_map_init(void); + + void isis_route_map_upd (const char *name) { diff --git a/isisd/isis_spf.c b/isisd/isis_spf.c index 706ed16c..5d7e9da4 100644 --- a/isisd/isis_spf.c +++ b/isisd/isis_spf.c @@ -998,8 +998,10 @@ isis_run_spf (struct isis_area *area, int level, int family) /* Make all routes in current route table inactive. */ if (family == AF_INET) table = area->route_table[level - 1]; +#ifdef HAVE_IPV6 else if (family == AF_INET6) table = area->route_table6[level - 1]; +#endif for (rode = route_top (table); rode; rode = route_next (rode)) { @@ -1333,16 +1335,16 @@ isis_print_paths (struct vty *vty, struct list *paths) nh_dyn = dynhn_find_by_id (adj->sysid); vty_out (vty, "%-20s %-10u %-20s %-11s %-5s%s", (dyn != NULL) ? dyn->name.name : - (u_char *) rawlspid_print ((u_char *) vertex->N.id), + (const u_char *)rawlspid_print ((u_char *) vertex->N.id), vertex->d_N, (nh_dyn != NULL) ? nh_dyn->name.name : - (u_char *) rawlspid_print (adj->sysid), + (const u_char *)rawlspid_print (adj->sysid), adj->circuit->interface->name, snpa_print (adj->snpa), VTY_NEWLINE); } else { vty_out (vty, "%s %u %s", dyn ? dyn->name.name : - (u_char *) rawlspid_print (vertex->N.id), + (const u_char *) rawlspid_print (vertex->N.id), vertex->d_N, VTY_NEWLINE); } } diff --git a/isisd/isis_tlv.c b/isisd/isis_tlv.c index 7b99ab5d..94fa65ed 100644 --- a/isisd/isis_tlv.c +++ b/isisd/isis_tlv.c @@ -45,6 +45,11 @@ extern struct isis *isis; +/* + * Prototypes. + */ +int add_tlv (u_char, u_char, u_char *, struct stream *); + void free_tlv (void *val) { diff --git a/isisd/isis_zebra.c b/isisd/isis_zebra.c index 4631cc70..9ee5ffc5 100644 --- a/isisd/isis_zebra.c +++ b/isisd/isis_zebra.c @@ -72,7 +72,7 @@ isis_zebra_if_add (int command, struct zclient *zclient, zebra_size_t length) if (isis->debugs & DEBUG_ZEBRA) zlog_debug ("Zebra I/F add: %s index %d flags %ld metric %d mtu %d", - ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); + ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu); if (if_is_operative (ifp)) isis_csm_state_change (IF_UP_FROM_Z, circuit_scan_by_ifp (ifp), ifp); @@ -98,7 +98,7 @@ isis_zebra_if_del (int command, struct zclient *zclient, zebra_size_t length) if (isis->debugs & DEBUG_ZEBRA) zlog_debug ("Zebra I/F delete: %s index %d flags %ld metric %d mtu %d", - ifp->name, ifp->ifindex, ifp->flags, ifp->metric, ifp->mtu); + ifp->name, ifp->ifindex, (long)ifp->flags, ifp->metric, ifp->mtu); /* Cannot call if_delete because we should retain the pseudo interface @@ -571,12 +571,14 @@ isis_zebra_read_ipv4 (int command, struct zclient *zclient, return 0; } +#ifdef HAVE_IPV6 static int isis_zebra_read_ipv6 (int command, struct zclient *zclient, zebra_size_t length) { return 0; } +#endif #define ISIS_TYPE_IS_REDISTRIBUTED(T) \ T == ZEBRA_ROUTE_MAX ? zclient->default_information : zclient->redist[type] diff --git a/isisd/isisd.c b/isisd/isisd.c index c5c2153f..48ea47af 100644 --- a/isisd/isisd.c +++ b/isisd/isisd.c @@ -61,6 +61,21 @@ u_char DEFAULT_TOPOLOGY_BASEIS[6] = { 0xFE, 0xED, 0xFE, 0xED, 0x00, 0x00 }; struct isis *isis = NULL; extern struct thread_master *master; +/* + * Prototypes. + */ +void isis_new(unsigned long); +struct isis_area *isis_area_create(void); +int isis_area_get(struct vty *, const char *); +int isis_area_destroy(struct vty *, const char *); +int area_net_title(struct vty *, const u_char *); +int area_clear_net_title(struct vty *, const u_char *); +int show_clns_neigh(struct vty *, char); +void print_debug(struct vty *, int, int); +int isis_config_write(struct vty *); + + + void isis_new (unsigned long process_id) { @@ -217,7 +232,7 @@ isis_area_destroy (struct vty *vty, const char *area_tag) } int -area_net_title (struct vty *vty, u_char *net_title) +area_net_title (struct vty *vty, const u_char *net_title) { struct isis_area *area; struct area_addr *addr; @@ -311,7 +326,7 @@ area_net_title (struct vty *vty, u_char *net_title) } int -area_clear_net_title (struct vty *vty, u_char *net_title) +area_clear_net_title (struct vty *vty, const u_char *net_title) { struct isis_area *area; struct area_addr addr, *addrp = NULL; @@ -997,7 +1012,7 @@ DEFUN (net, "A Network Entity Title for this process (OSI only)\n" "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") { - return area_net_title (vty, (u_char *)argv[0]); + return area_net_title (vty, argv[0]); } /* @@ -1010,7 +1025,7 @@ DEFUN (no_net, "A Network Entity Title for this process (OSI only)\n" "XX.XXXX. ... .XXX.XX Network entity title (NET)\n") { - return area_clear_net_title (vty, (u_char *)argv[0]); + return area_clear_net_title (vty, argv[0]); } DEFUN (area_passwd, @@ -1182,7 +1197,7 @@ DEFUN (is_type, return CMD_WARNING; } - type = string2circuit_t ((u_char *)argv[0]); + type = string2circuit_t (argv[0]); if (!type) { vty_out (vty, "Unknown IS level %s", VTY_NEWLINE); diff --git a/isisd/iso_checksum.c b/isisd/iso_checksum.c index eabe281f..16f18e50 100644 --- a/isisd/iso_checksum.c +++ b/isisd/iso_checksum.c @@ -191,9 +191,3 @@ iso_csum_create (u_char * buffer, int len, u_int16_t n) /* return the checksum for user usage */ return checksum; } - -int -iso_csum_modify (u_char * buffer, int len, uint16_t * csum) -{ - return 0; -} diff --git a/isisd/topology/random.c b/isisd/topology/random.c index 6ee17a0a..c49c0820 100644 --- a/isisd/topology/random.c +++ b/isisd/topology/random.c @@ -10,7 +10,17 @@ #include #include -unsigned long timer() +/* + * Prototypes. + */ +unsigned long timer(void); +void init_rand(long); +double rand01(void); +double randg01(void); +long nrand(long); +void free_arc(void *); + +unsigned long timer () { struct tms hold; times(&hold); diff --git a/isisd/topology/spgrid.c b/isisd/topology/spgrid.c index a1aa6d77..611b6727 100644 --- a/isisd/topology/spgrid.c +++ b/isisd/topology/spgrid.c @@ -26,6 +26,15 @@ #define NODE( x, y ) (x*Y + y + 1) +/* + * Prototypes. + */ +void free_arc(void *); +void help(struct vty *); +void print_arc(struct vty *, struct list *, long, long, long); +void hhelp(struct vty *); +void usage(struct vty *); + const char *graph_type[] = { "double cycle", "cycle", -- cgit v1.2.3 From 43cd33a44e010f818633b7f144b5a0be352b41e7 Mon Sep 17 00:00:00 2001 From: Paul Jakma Date: Fri, 8 Dec 2006 21:27:08 +0000 Subject: [0.99] Bump version to 0.99.6 2006-12-08 Paul Jakma * configure.ac: Bump to 0.99.6 --- ChangeLog | 4 ++++ configure.ac | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 053c413b..98ebfe76 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,7 @@ +2006-12-08 Paul Jakma + + * configure.ac: Bump to 0.99.6 + 2006-10-04 Oliver Hookins * bgpd/bgp_main.c: Add configuration check option, with diff --git a/configure.ac b/configure.ac index 4f5956e0..99821109 100755 --- a/configure.ac +++ b/configure.ac @@ -8,7 +8,7 @@ ## $Id$ AC_PREREQ(2.53) -AC_INIT(Quagga, 0.99.5, [http://bugzilla.quagga.net]) +AC_INIT(Quagga, 0.99.6, [http://bugzilla.quagga.net]) AC_CONFIG_SRCDIR(lib/zebra.h) dnl ----------------------------------- -- cgit v1.2.3